* keyserver.c (keyserver_import_pka): New. Moved from
authorDavid Shaw <dshaw@jabberwocky.com>
Fri, 23 Dec 2005 22:17:11 +0000 (22:17 +0000)
committerDavid Shaw <dshaw@jabberwocky.com>
Fri, 23 Dec 2005 22:17:11 +0000 (22:17 +0000)
getkey.c:get_pubkey_byname which was getting crowded.

* keyserver.c (keyserver_import_cert): Import a key found in DNS via CERT
records.  Can handle both the PGP (actual key) and IPGP (URL) CERT types.

* getkey.c (get_pubkey_byname): Call them both here.

* options.h, keyserver.c (parse_keyserver_options): Add
"auto-cert-retrieve" option with optional max size argument.

g10/ChangeLog
g10/getkey.c
g10/gpgv.c
g10/keyserver-internal.h
g10/keyserver.c
g10/options.h

index 7b9db0a..43f1221 100644 (file)
@@ -1,6 +1,18 @@
 2005-12-23  David Shaw  <dshaw@jabberwocky.com>
 
-       * gpgv.c: Stub.
+       * keyserver.c (keyserver_import_pka): New.  Moved from
+       getkey.c:get_pubkey_byname which was getting crowded.
+
+       * keyserver.c (keyserver_import_cert): Import a key found in DNS
+       via CERT records.  Can handle both the PGP (actual key) and IPGP
+       (URL) CERT types.
+
+       * getkey.c (get_pubkey_byname): Call them both here.
+
+       * options.h, keyserver.c (parse_keyserver_options): Add
+       "auto-cert-retrieve" option with optional max size argument.
+
+       * gpgv.c: Stubs.
 
        * keyserver-internal.h, keyserver.c (keyserver_spawn,
        keyserver_work, keygerver_getname): New keyserver_getname function
index ebd1345..d247b3b 100644 (file)
@@ -905,7 +905,7 @@ get_pubkey_byname (PKT_public_key *pk,
                    KEYDB_HANDLE *ret_kdbhd, int include_unusable )
 {
   int rc;
-  int tried_ks=0, tried_pka=0;
+  int tried_cert=0, tried_pka=0, tried_ks=0;
   STRLIST namelist = NULL;
 
   add_to_strlist( &namelist, name );
@@ -915,6 +915,25 @@ get_pubkey_byname (PKT_public_key *pk,
 
   if (rc == G10ERR_NO_PUBKEY && is_valid_mailbox(name))
     {
+      int res;
+
+      if(!tried_cert
+        && (opt.keyserver_options.options&KEYSERVER_AUTO_CERT_RETRIEVE))
+       {
+         tried_cert=1;
+
+         glo_ctrl.in_auto_key_retrieve++;
+         res=keyserver_import_cert(name);
+         glo_ctrl.in_auto_key_retrieve--;
+
+         if(res==0)
+           {
+             log_info(_("Automatically retrieved `%s' via %s\n"),
+                      name,"DNS CERT");
+             goto retry;
+           }
+       }
+
       if(!tried_pka
         && opt.allow_pka_lookup
         && (opt.keyserver_options.options&KEYSERVER_AUTO_PKA_RETRIEVE))
@@ -922,28 +941,19 @@ get_pubkey_byname (PKT_public_key *pk,
          /* If the requested name resembles a valid mailbox and
             automatic retrieval via PKA records has been enabled, we
             try to import the key via the URI and try again. */
-         unsigned char fpr[MAX_FINGERPRINT_LEN];
-         char *uri;
-         struct keyserver_spec *spec;
-         int try=1;
 
          tried_pka=1;
-      
-         uri = get_pka_info (name, fpr);
-         if (uri)
+
+         glo_ctrl.in_auto_key_retrieve++;
+         res=keyserver_import_pka(name);
+         glo_ctrl.in_auto_key_retrieve--;
+
+         if(res==0)
            {
-             spec = parse_keyserver_uri (uri, 0, NULL, 0);
-             if (spec)
-               {
-                 glo_ctrl.in_auto_key_retrieve++;
-                 try=keyserver_import_fprint (fpr, 20, spec);
-                 glo_ctrl.in_auto_key_retrieve--;
-                 free_keyserver_spec (spec);
-               }
-             xfree (uri);
+             log_info(_("Automatically retrieved `%s' via %s\n"),
+                      name,"PKA");
+             goto retry;
            }
-         if (try==0)
-           goto retry;
        }
 
       /* Try keyserver last as it is likely to be the slowest.
@@ -952,12 +962,21 @@ get_pubkey_byname (PKT_public_key *pk,
         with searching for something like "john" and getting a lot of
         keys back. */
       if(!tried_ks
+        && opt.keyserver
         && (opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE))
        {
          tried_ks=1;
 
-         if(keyserver_getname(name)==0)
-           goto retry;
+         glo_ctrl.in_auto_key_retrieve++;
+         res=keyserver_import_name(name);
+         glo_ctrl.in_auto_key_retrieve--;
+
+         if(res==0)
+           {
+             log_info(_("Automatically retrieved `%s' via %s\n"),
+                      name,opt.keyserver->uri);
+             goto retry;
+           }
        }
     }
 
index bd5820d..dbff483 100644 (file)
@@ -270,7 +270,7 @@ get_ownertrust (PKT_public_key *pk)
 }
 
 
-/* Stub:
+/* Stubs:
  * Because we only work with trusted keys, it does not make sense to
  * get them from a keyserver
  */
@@ -280,19 +280,14 @@ keyserver_import_keyid( u32 *keyid, void *dummy )
     return -1;
 }
 
-/* Stub:
- * Because we only work with trusted keys, it does not make sense to
- * get them from a keyserver
- */
 int
-keyserver_import_fprint (const byte *fprint, size_t fprint_len,
-                         struct keyserver_spec *keyserver)
-{
-    return -1;
-}
+keyserver_import_cert(const char *name) { return -1; }
+
+int
+keyserver_import_pka(const char *name) { return -1; }
 
 int
-keyserver_getname(const char *name) { return -1; }
+keyserver_import_name(const char *name) { return -1; }
 
 /* Stub:
  * No encryption here but mainproc links to these functions.
index 3d2f465..1f98317 100644 (file)
@@ -41,6 +41,8 @@ int keyserver_import_keyid(u32 *keyid,struct keyserver_spec *keyserver);
 int keyserver_refresh(STRLIST users);
 int keyserver_search(STRLIST tokens);
 int keyserver_fetch(STRLIST urilist);
-int keyserver_getname(const char *name);
+int keyserver_import_cert(const char *name);
+int keyserver_import_pka(const char *name);
+int keyserver_import_name(const char *name);
 
 #endif /* !_KEYSERVER_INTERNAL_H_ */
index 7b6bdae..95d8d8d 100644 (file)
@@ -86,6 +86,8 @@ static struct parse_options keyserver_opts[]=
     {"auto-key-retrieve",KEYSERVER_AUTO_KEY_RETRIEVE,NULL,
      N_("automatically retrieve keys when verifying signatures")},
     {"auto-pka-retrieve",KEYSERVER_AUTO_PKA_RETRIEVE,NULL,
+     N_("automatically retrieve keys from PKA records")},
+    {"auto-cert-retrieve",KEYSERVER_AUTO_CERT_RETRIEVE,NULL,
      N_("automatically retrieve keys from DNS")},
     {"try-dns-srv",KEYSERVER_TRY_DNS_SRV,NULL,
      NULL},
@@ -98,11 +100,19 @@ static int keyserver_work(enum ks_action action,STRLIST list,
                          KEYDB_SEARCH_DESC *desc,int count,
                          struct keyserver_spec *keyserver);
 
+/* Reasonable guess */
+#define DEFAULT_MAX_CERT_SIZE 16384
+
+static size_t max_cert_size=DEFAULT_MAX_CERT_SIZE;
+
 int
 parse_keyserver_options(char *options)
 {
   int ret=1;
   char *tok;
+  char *max_cert;
+
+  keyserver_opts[7].value=&max_cert;
 
   while((tok=optsep(&options)))
     {
@@ -163,6 +173,15 @@ parse_keyserver_options(char *options)
        }
     }
 
+  if(opt.keyserver_options.options&KEYSERVER_AUTO_CERT_RETRIEVE)
+    {
+      if(max_cert)
+       max_cert_size=strtoul(max_cert,(char **)NULL,10);
+
+      if(max_cert_size==0)
+       max_cert_size=DEFAULT_MAX_CERT_SIZE;
+    }
+
   return ret;
 }
 
@@ -1895,8 +1914,86 @@ keyserver_fetch(STRLIST urilist)
   return 0;
 }
 
+/* Import key in a CERT or pointed to by a CERT */
+int
+keyserver_import_cert(const char *name)
+{
+  char *domain,*look,*url;
+  IOBUF key;
+  int type,rc=-1;
+
+  look=xstrdup(name);
+
+  domain=strrchr(look,'@');
+  if(domain)
+    *domain='.';
+
+  type=get_cert(look,max_cert_size,&key,&url);
+  if(type==1)
+    {
+      int armor_status=opt.no_armor;
+
+      /* CERTs are always in binary format */
+      opt.no_armor=1;
+
+      rc=import_keys_stream(key,NULL,opt.keyserver_options.import_options);
+
+      opt.no_armor=armor_status;
+
+      iobuf_close(key);
+    }
+  else if(type==2)
+    {
+      struct keyserver_spec *spec;
+
+      spec=parse_keyserver_uri(url,1,NULL,0);
+      if(spec)
+       {
+         STRLIST list=NULL;
+
+         add_to_strlist(&list,url);
+
+         rc=keyserver_fetch(list);
+
+         free_strlist(list);
+         free_keyserver_spec(spec);
+       }
+
+      xfree(url);
+    }
+
+  xfree(look);
+
+  return rc;
+}
+
+/* Import key pointed to by a PKA record */
+int
+keyserver_import_pka(const char *name)
+{
+  unsigned char fpr[MAX_FINGERPRINT_LEN];
+  char *uri;
+  int rc=-1;
+      
+  uri = get_pka_info (name, fpr);
+  if (uri)
+    {
+      struct keyserver_spec *spec;
+      spec = parse_keyserver_uri (uri, 0, NULL, 0);
+      if (spec)
+       {
+         rc=keyserver_import_fprint (fpr, 20, spec);
+         free_keyserver_spec (spec);
+       }
+      xfree (uri);
+    }
+
+  return rc;
+}
+
+/* Import all keys that match name */
 int
-keyserver_getname(const char *name)
+keyserver_import_name(const char *name)
 {
   STRLIST list=NULL;
   int rc;
index 3d425bb..af5c6f7 100644 (file)
@@ -312,5 +312,6 @@ struct {
 #define KEYSERVER_TRY_DNS_SRV            (1<<6)
 #define KEYSERVER_HONOR_KEYSERVER_URL    (1<<7)
 #define KEYSERVER_AUTO_PKA_RETRIEVE      (1<<8)
+#define KEYSERVER_AUTO_CERT_RETRIEVE     (1<<9)
 
 #endif /*G10_OPTIONS_H*/