* keyedit.c (keyedit_menu, menu_set_keyserver_url): Allow passing
authorDavid Shaw <dshaw@jabberwocky.com>
Sat, 8 May 2004 13:51:14 +0000 (13:51 +0000)
committerDavid Shaw <dshaw@jabberwocky.com>
Sat, 8 May 2004 13:51:14 +0000 (13:51 +0000)
preferred keyserver on "keyserver" command line.  Sanity check keyserver
URL before accepting it.

* keyserver-internal.h, g10.c (main), keyserver.c (parse_keyserver_uri):
Add an option to require the scheme:// and change all callers.
(free_keyserver_spec): Make public.

g10/ChangeLog
g10/g10.c
g10/keyedit.c
g10/keyserver-internal.h
g10/keyserver.c

index 918798d..4e217e8 100644 (file)
@@ -1,3 +1,14 @@
+2004-05-08  David Shaw  <dshaw@jabberwocky.com>
+
+       * keyedit.c (keyedit_menu, menu_set_keyserver_url): Allow passing
+       preferred keyserver on "keyserver" command line.  Sanity check
+       keyserver URL before accepting it.
+
+       * keyserver-internal.h, g10.c (main), keyserver.c
+       (parse_keyserver_uri): Add an option to require the scheme:// and
+       change all callers.
+       (free_keyserver_spec): Make public.
+
 2004-05-07  Werner Koch  <wk@gnupg.org>
 
        * sign.c (write_plaintext_packet): Fixed the detection of too
index 438242e..6ced4f2 100644 (file)
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -2084,10 +2084,10 @@ main( int argc, char **argv )
 #endif /* __riscos__ */
             break;
          case oKeyServer:
-           opt.keyserver=parse_keyserver_uri(pargs.r.ret_str,
+           opt.keyserver=parse_keyserver_uri(pargs.r.ret_str,0,
                                              configname,configlineno);
            if(!opt.keyserver)
-             log_error(_("could not parse keyserver URI\n"));
+             log_error(_("could not parse keyserver URL\n"));
            break;
          case oKeyServerOptions:
            if(!parse_keyserver_options(pargs.r.ret_str))
index 0381dc7..8ab2276 100644 (file)
@@ -41,6 +41,7 @@
 #include "ttyio.h"
 #include "status.h"
 #include "i18n.h"
+#include "keyserver-internal.h"
 
 static void show_prefs( PKT_user_id *uid, int verbose );
 static void show_key_with_all_names( KBNODE keyblock, int only_marked,
@@ -55,7 +56,8 @@ static int menu_addrevoker( KBNODE pub_keyblock,
 static int menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock );
 static int menu_set_primary_uid( KBNODE pub_keyblock, KBNODE sec_keyblock );
 static int menu_set_preferences( KBNODE pub_keyblock, KBNODE sec_keyblock );
-static int menu_set_keyserver_url (KBNODE pub_keyblock, KBNODE sec_keyblock );
+static int menu_set_keyserver_url (const char *url,
+                                  KBNODE pub_keyblock, KBNODE sec_keyblock );
 static int menu_select_uid( KBNODE keyblock, int idx );
 static int menu_select_key( KBNODE keyblock, int idx );
 static int count_uids( KBNODE keyblock );
@@ -1607,11 +1609,13 @@ keyedit_menu( const char *username, STRLIST locusr,
            break;
 
          case cmdPREFKS:
-           if( menu_set_keyserver_url ( keyblock, sec_keyblock ) ) {
+           if( menu_set_keyserver_url ( *arg_string?arg_string:NULL,
+                                        keyblock, sec_keyblock ) )
+             {
                merge_keys_and_selfsig( keyblock );
                modified = 1;
                redisplay = 1;
-           }
+             }
            break;
 
          case cmdNOP:
@@ -3173,96 +3177,120 @@ menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock )
 
 
 static int
-menu_set_keyserver_url (KBNODE pub_keyblock, KBNODE sec_keyblock )
+menu_set_keyserver_url (const char *url,
+                       KBNODE pub_keyblock, KBNODE sec_keyblock )
 {
-    PKT_secret_key *sk;    /* copy of the main sk */
-    PKT_public_key *main_pk;
-    PKT_user_id *uid;
-    KBNODE node;
-    u32 keyid[2];
-    int selected, select_all;
-    int modified = 0;
-    char *answer;
+  PKT_secret_key *sk;    /* copy of the main sk */
+  PKT_public_key *main_pk;
+  PKT_user_id *uid;
+  KBNODE node;
+  u32 keyid[2];
+  int selected, select_all;
+  int modified = 0;
+  char *answer;
+  struct keyserver_spec *keyserver;
 
-    no_primary_warning(pub_keyblock);
+  no_primary_warning(pub_keyblock);
 
-    answer=cpr_get_utf8("keyedit.add_keyserver",
-                       _("Enter your preferred keyserver URL: "));
-    if(answer[0]=='\0' || answer[0]=='\004')
-      {
-       m_free(answer);
-       return 0;
-      }
+  if(url)
+    answer=m_strdup(url);
+  else
+    {
+      answer=cpr_get_utf8("keyedit.add_keyserver",
+                         _("Enter your preferred keyserver URL: "));
+      if(answer[0]=='\0' || answer[0]=='\004')
+       {
+         m_free(answer);
+         return 0;
+       }
+    }
 
-    select_all = !count_selected_uids (pub_keyblock);
+  /* Sanity check the format */
+  keyserver=parse_keyserver_uri(answer,1,NULL,0);
+  m_free(answer);
+  if(!keyserver)
+    {
+      log_info(_("could not parse keyserver URL\n"));
+      return 0;
+    }
 
-    node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
-    sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
+  select_all = !count_selected_uids (pub_keyblock);
 
-    /* Now we can actually change the self signature(s) */
-    main_pk = NULL;
-    uid = NULL;
-    selected = 0;
-    for ( node=pub_keyblock; node; node = node->next ) {
-       if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
-            break; /* ready */
+  node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
+  sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
 
-       if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
-           main_pk = node->pkt->pkt.public_key;
-           keyid_from_pk( main_pk, keyid );
-       }
-       else if ( node->pkt->pkttype == PKT_USER_ID ) {
-           uid = node->pkt->pkt.user_id;
-                   selected = select_all || (node->flag & NODFLG_SELUID);
-        }
-       else if ( main_pk && uid && selected
-                  && node->pkt->pkttype == PKT_SIGNATURE ) {
-           PKT_signature *sig = node->pkt->pkt.signature;
-           if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
-                && (uid && (sig->sig_class&~3) == 0x10) ) {
-             if( sig->version < 4 ) {
-               char *user=utf8_to_native(uid->name,strlen(uid->name),0);
+  /* Now we can actually change the self signature(s) */
+  main_pk = NULL;
+  uid = NULL;
+  selected = 0;
+  for ( node=pub_keyblock; node; node = node->next )
+    {
+      if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
+       break; /* ready */
 
-               log_info(_("skipping v3 self-signature on user id \"%s\"\n"),
-                        user);
-               m_free(user);
-             }
-             else {
-               /* This is a selfsignature which is to be replaced 
-                 * We have to ignore v3 signatures because they are
-                 * not able to carry the preferences */
-               PKT_signature *newsig;
-               PACKET *newpkt;
-                int rc;
+      if ( node->pkt->pkttype == PKT_PUBLIC_KEY )
+       {
+         main_pk = node->pkt->pkt.public_key;
+         keyid_from_pk( main_pk, keyid );
+       }
+      else if ( node->pkt->pkttype == PKT_USER_ID )
+       {
+         uid = node->pkt->pkt.user_id;
+         selected = select_all || (node->flag & NODFLG_SELUID);
+       }
+      else if ( main_pk && uid && selected
+               && node->pkt->pkttype == PKT_SIGNATURE )
+       {
+         PKT_signature *sig = node->pkt->pkt.signature;
+         if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
+              && (uid && (sig->sig_class&~3) == 0x10) )
+           {
+             if( sig->version < 4 )
+               {
+                 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
 
-                rc = update_keysig_packet (&newsig, sig,
-                                           main_pk, uid, NULL,
-                                           sk,
-                                           keygen_add_keyserver_url,
-                                           answer );
-                if( rc ) {
-                    log_error ("update_keysig_packet failed: %s\n",
-                               g10_errstr(rc));
-                   m_free(answer);
-                   free_secret_key( sk );
-                    return 0;
-                }
-                /* replace the packet */
-                newpkt = m_alloc_clear( sizeof *newpkt );
-                newpkt->pkttype = PKT_SIGNATURE;
-                newpkt->pkt.signature = newsig;
-                free_packet( node->pkt );
-                m_free( node->pkt );
-                node->pkt = newpkt;
-                modified = 1;
-             }
-            }
+                 log_info(_("skipping v3 self-signature on user id \"%s\"\n"),
+                          user);
+                 m_free(user);
+               }
+             else
+               {
+                 /* This is a selfsignature which is to be replaced 
+                  * We have to ignore v3 signatures because they are
+                  * not able to carry the preferences */
+                 PKT_signature *newsig;
+                 PACKET *newpkt;
+                 int rc;
+
+                 rc = update_keysig_packet (&newsig, sig,
+                                            main_pk, uid, NULL,
+                                            sk,
+                                            keygen_add_keyserver_url,
+                                            keyserver->uri );
+                 if( rc )
+                   {
+                     log_error ("update_keysig_packet failed: %s\n",
+                                g10_errstr(rc));
+                     free_keyserver_spec(keyserver);
+                     free_secret_key( sk );
+                     return 0;
+                   }
+                 /* replace the packet */
+                 newpkt = m_alloc_clear( sizeof *newpkt );
+                 newpkt->pkttype = PKT_SIGNATURE;
+                 newpkt->pkt.signature = newsig;
+                 free_packet( node->pkt );
+                 m_free( node->pkt );
+                 node->pkt = newpkt;
+                 modified = 1;
+               }
+           }
        }
     }
 
-    m_free(answer);
-    free_secret_key( sk );
-    return modified;
+  free_keyserver_spec(keyserver);
+  free_secret_key( sk );
+  return modified;
 }
 
 
index 42b7804..9450bbb 100644 (file)
@@ -9,7 +9,8 @@
 #include "types.h"
 
 int parse_keyserver_options(char *options);
-struct keyserver_spec *parse_keyserver_uri(char *uri,
+void free_keyserver_spec(struct keyserver_spec *keyserver);
+struct keyserver_spec *parse_keyserver_uri(char *uri,int require_scheme,
                                           const char *configname,
                                           unsigned int configlineno);
 int keyserver_export(STRLIST users);
index 8b71a63..7cf7824 100644 (file)
@@ -135,7 +135,7 @@ parse_keyserver_options(char *options)
   return ret;
 }
 
-static void
+void
 free_keyserver_spec(struct keyserver_spec *keyserver)
 {
   m_free(keyserver->uri);
@@ -146,7 +146,8 @@ free_keyserver_spec(struct keyserver_spec *keyserver)
 }
 
 struct keyserver_spec *
-parse_keyserver_uri(char *uri,const char *configname,unsigned int configlineno)
+parse_keyserver_uri(char *uri,int require_scheme,
+                   const char *configname,unsigned int configlineno)
 {
   int assume_hkp=0;
   struct keyserver_spec *keyserver;
@@ -163,6 +164,9 @@ parse_keyserver_uri(char *uri,const char *configname,unsigned int configlineno)
   scheme=strsep(&uri,":");
   if(uri==NULL)
     {
+      if(require_scheme)
+       return NULL;
+
       /* Assume HKP if there is no scheme */
       assume_hkp=1;
       uri=scheme;
@@ -1361,9 +1365,11 @@ keyidlist(STRLIST users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
                      dupe[plen]='\0';
 
                      /* Make up a keyserver structure and do an
-                        import for this key. */
+                        import for this key.  Note that a preferred
+                        keyserver without a scheme:// will be
+                        interpreted as hkp:// */
 
-                     keyserver=parse_keyserver_uri(dupe,NULL,0);
+                     keyserver=parse_keyserver_uri(dupe,0,NULL,0);
                      m_free(dupe);
 
                      if(keyserver)