[svn] GnuPG - r4740 - in trunk: . doc g10 tools

svn author wk cvs at cvs.gnupg.org
Tue Apr 8 13:04:19 CEST 2008


Author: wk
Date: 2008-04-08 13:04:16 +0200 (Tue, 08 Apr 2008)
New Revision: 4740

Modified:
   trunk/NEWS
   trunk/doc/ChangeLog
   trunk/doc/gpg.texi
   trunk/g10/ChangeLog
   trunk/g10/getkey.c
   trunk/g10/gpg.c
   trunk/g10/import.c
   trunk/g10/keydb.h
   trunk/g10/keyedit.c
   trunk/g10/keyserver.c
   trunk/g10/options.h
   trunk/g10/pkclist.c
   trunk/tools/ChangeLog
   trunk/tools/gpgconf-comp.c
Log:
Enhanced --auto-key-locate.


[The diff below has been truncated]

Modified: trunk/doc/ChangeLog
===================================================================
--- trunk/doc/ChangeLog	2008-04-07 19:55:44 UTC (rev 4739)
+++ trunk/doc/ChangeLog	2008-04-08 11:04:16 UTC (rev 4740)
@@ -1,3 +1,9 @@
+2008-04-08  Werner Koch  <wk at g10code.com>
+
+	* gpg.texi (GPG Configuration Options): Change subkeys.pgp.net to
+	keys.gnupg.net.  Describe --auto-key-locate mechanisms local and
+	nodefault.
+
 2008-04-03  Werner Koch  <wk at g10code.com>
 
 	* yat2m.c (proc_texi_cmd): Remove extra apostrophe from @samp and

Modified: trunk/g10/ChangeLog
===================================================================
--- trunk/g10/ChangeLog	2008-04-07 19:55:44 UTC (rev 4739)
+++ trunk/g10/ChangeLog	2008-04-08 11:04:16 UTC (rev 4740)
@@ -1,3 +1,20 @@
+2008-04-08  Werner Koch  <wk at g10code.com>
+
+	* options.h (opt): Add AKL_NODEFAULT and AKL_LOCAL.
+	* getkey.c (parse_auto_key_locate): Parse them.
+	(get_pubkey_byname): Implement them.  Add arg NO_AKL and use that
+	in all cases where a local key is expected.
+	* import.c (import_one): Fill in the fingerprint in all cases.
+	Use log_get_stream.
+	* keyserver.c (keyserver_import_pka): Set FPR to NULL on error.
+	Return G10ERR_NO_PUBKEY if no PKA info is available or no key URI
+	is given in the PKA record..
+	(keyserver_import_cert): Return G10ERR_NO_PUBKEY if a CERT record
+	was not found.
+
+	* getkey.c (get_pubkey_byname): Release FPR in the error case.
+	Continue with next mechanism on error.  Better diagnostics.
+
 2008-04-07  Werner Koch  <wk at g10code.com>
 
 	* keyserver.c (parse_keyserver_uri): Allow a default host name.
@@ -10121,7 +10138,7 @@
 
 
  Copyright 1998,1999,2000,2001,2002,2003,2004,2005,
-	   2006,2007 Free Software Foundation, Inc.
+	   2006,2007,2008 Free Software Foundation, Inc.
 
  This file is free software; as a special exception the author gives
  unlimited permission to copy and/or distribute it, with or without

Modified: trunk/tools/ChangeLog
===================================================================
--- trunk/tools/ChangeLog	2008-04-07 19:55:44 UTC (rev 4739)
+++ trunk/tools/ChangeLog	2008-04-08 11:04:16 UTC (rev 4740)
@@ -1,3 +1,7 @@
+2008-04-08  Werner Koch  <wk at g10code.com>
+
+	* gpgconf-comp.c (gc_options_gpg): Add --auto-key-locate.
+
 2008-03-26  Werner Koch  <wk at g10code.com>
 
 	* make-dns-cert.c: Include unistd.h.  Use config.h if requested.

Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2008-04-07 19:55:44 UTC (rev 4739)
+++ trunk/NEWS	2008-04-08 11:04:16 UTC (rev 4740)
@@ -1,8 +1,13 @@
 Noteworthy changes in version 2.0.10 (unreleased)
 -------------------------------------------------
 
+ * New keyserver helper gpg2keys_kdns as generic DNS CERT lookup.  Run
+   with --help for a short description.  Requires the ADNS library.
 
+ * New mechanisms "local" and "nodefault" for --auto-key-locate [gpg].
+   Fixed a few problems with this option.
 
+
 Noteworthy changes in version 2.0.9 (2008-03-26)
 ------------------------------------------------
 

Modified: trunk/doc/gpg.texi
===================================================================
--- trunk/doc/gpg.texi	2008-04-07 19:55:44 UTC (rev 4739)
+++ trunk/doc/gpg.texi	2008-04-08 11:04:16 UTC (rev 4740)
@@ -1305,28 +1305,41 @@
 GnuPG can automatically locate and retrieve keys as needed using this
 option. This happens when encrypting to an email address (in the
 "user@@example.com" form), and there are no user@@example.com keys on
-the local keyring. This option takes any number of the following
-arguments, in the order they are to be tried:
+the local keyring.  This option takes any number of the following
+mechanisms, in the order they are to be tried:
 
 @table @asis
 
 @item cert
-locate a key using DNS CERT, as specified in rfc4398.
+Locate a key using DNS CERT, as specified in rfc4398.
 
 @item pka
-locate a key using DNS PKA.
+Locate a key using DNS PKA.
 
 @item ldap
-locate a key using the PGP Universal method of checking
-"ldap://keys.(thedomain)".
+Locate a key using the PGP Universal method of checking
+ at samp{ldap://keys.(thedomain)}.
 
 @item keyserver
-locate a key using whatever keyserver is defined using the
+Locate a key using whatever keyserver is defined using the
 @option{--keyserver} option.
 
- at item (keyserver URL)
-In addition, a keyserver URL as used in the @option{--keyserver} option may be
-used here to query that particular keyserver.
+ at item keyserver-URL
+In addition, a keyserver URL as used in the @option{--keyserver} option
+may be used here to query that particular keyserver.
+
+ at item local
+Locate the key using the local keyrings.  This mechanism allows to
+select the order a local key lookup is done.  Thus using
+ at samp{--auto-key-locate local} is identical to
+ at option{--no-auto-key-locate}.
+
+ at item nodefault
+This flag disables the standard local key lookup, done before any of the
+mechanisms defined by the @option{--auto-key-locate} are tried.  The
+position of this mechanism in the list does not matter.  It is not
+required if @code{local} is also used.
+
 @end table
 
 @item --keyid-format @code{short|0xshort|long|0xlong}
@@ -1351,7 +1364,7 @@
 
 Most keyservers synchronize with each other, so there is generally no
 need to send keys to more than one server. The keyserver
- at code{hkp://subkeys.pgp.net} uses round robin DNS to give a different
+ at code{hkp://keys.gnupg.net} uses round robin DNS to give a different
 keyserver each time you use it.
 
 @item --keyserver-options @code{name=value1 }

Modified: trunk/g10/getkey.c
===================================================================
--- trunk/g10/getkey.c	2008-04-07 19:55:44 UTC (rev 4739)
+++ trunk/g10/getkey.c	2008-04-08 11:04:16 UTC (rev 4740)
@@ -1,6 +1,6 @@
 /* getkey.c -  Get a key from the database
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- *               2006, 2007 Free Software Foundation, Inc.
+ *               2006, 2007, 2008 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -912,64 +912,91 @@
 /* Find a public key from NAME and return the keyblock or the key.  If
    ret_kdb is not NULL, the KEYDB handle used to locate this keyblock
    is returned and the caller is responsible for closing it.  If a key
-   was not found and NAME is a valid RFC822 mailbox and --auto-key-locate
-   has been enabled, we try to import the key via the online mechanisms
-   defined by --auto-key-locate.  */
+   was not found (or if local search has been disabled) and NAME is a
+   valid RFC822 mailbox and --auto-key-locate has been enabled, we try
+   to import the key via the online mechanisms defined by
+   --auto-key-locate.  */
 int
 get_pubkey_byname (PKT_public_key *pk,
 		   const char *name, KBNODE *ret_keyblock,
-                   KEYDB_HANDLE *ret_kdbhd, int include_unusable )
+                   KEYDB_HANDLE *ret_kdbhd, int include_unusable, 
+                   int no_akl)
 {
   int rc;
   strlist_t namelist = NULL;
+  struct akl *akl;
+  int nodefault = 0;
 
-  add_to_strlist( &namelist, name );
+  /* Check whether we the default local search has been disabled.
+     This is the case if either the "nodefault" or the "local" keyword
+     are in the list of auto key locate mechanisms.  */
+  if (!no_akl)
+    {
+      for (akl=opt.auto_key_locate; akl; akl=akl->next)
+        if (akl->type == AKL_NODEFAULT || akl->type == AKL_LOCAL)
+          {
+            nodefault = 1;
+            break;
+          }
+    }
 
-  rc = key_byname( NULL, namelist, pk, NULL, 0,
-                   include_unusable, ret_keyblock, ret_kdbhd);
+  if (nodefault)
+    rc = G10ERR_NO_PUBKEY;
+  else
+    {
+      add_to_strlist (&namelist, name);
+      rc = key_byname (NULL, namelist, pk, NULL, 0,
+                       include_unusable, ret_keyblock, ret_kdbhd);
+    }
 
   /* If the requested name resembles a valid mailbox and automatic
      retrieval has been enabled, we try to import the key. */
 
-  if (rc == G10ERR_NO_PUBKEY && is_valid_mailbox(name))
+  if (rc == G10ERR_NO_PUBKEY && !no_akl && is_valid_mailbox(name))
     {
-      struct akl *akl;
-
-      for(akl=opt.auto_key_locate;akl;akl=akl->next)
+      for (akl=opt.auto_key_locate; akl; akl=akl->next)
 	{
-	  unsigned char *fpr=NULL;
+	  unsigned char *fpr = NULL;
 	  size_t fpr_len;
-
+          int did_key_byname = 0;
+          int no_fingerprint = 0;
+          const char *mechanism = "?";
+          
 	  switch(akl->type)
 	    {
+            case AKL_NODEFAULT:
+              /* This is a dummy mechanism.  */
+              mechanism = "None";
+              rc = G10ERR_NO_PUBKEY;
+              break;
+
+            case AKL_LOCAL:
+              mechanism = "Local";
+              did_key_byname = 1;
+              add_to_strlist (&namelist, name);
+              rc = key_byname (NULL, namelist, pk, NULL, 0,
+                               include_unusable, ret_keyblock, ret_kdbhd);
+              break;
+
 	    case AKL_CERT:
+              mechanism = "DNS CERT";
 	      glo_ctrl.in_auto_key_retrieve++;
 	      rc=keyserver_import_cert(name,&fpr,&fpr_len);
 	      glo_ctrl.in_auto_key_retrieve--;
-
-	      if(rc==0)
-		log_info(_("automatically retrieved `%s' via %s\n"),
-			 name,"DNS CERT");
 	      break;
 
 	    case AKL_PKA:
+              mechanism = "PKA";
 	      glo_ctrl.in_auto_key_retrieve++;
 	      rc=keyserver_import_pka(name,&fpr,&fpr_len);
 	      glo_ctrl.in_auto_key_retrieve--;
-
-	      if(rc==0)
-		log_info(_("automatically retrieved `%s' via %s\n"),
-			 name,"PKA");
 	      break;
 
 	    case AKL_LDAP:
+              mechanism = "LDAP";
 	      glo_ctrl.in_auto_key_retrieve++;
 	      rc=keyserver_import_ldap(name,&fpr,&fpr_len);
 	      glo_ctrl.in_auto_key_retrieve--;
-
-	      if(rc==0)
-		log_info(_("automatically retrieved `%s' via %s\n"),
-			 name,"LDAP");
 	      break;
 
 	    case AKL_KEYSERVER:
@@ -979,32 +1006,31 @@
 		 and getting a whole lot of keys back. */
 	      if(opt.keyserver)
 		{
+                  mechanism = opt.keyserver->uri;
 		  glo_ctrl.in_auto_key_retrieve++;
 		  rc=keyserver_import_name(name,&fpr,&fpr_len,opt.keyserver);
 		  glo_ctrl.in_auto_key_retrieve--;
-
-		  if(rc==0)
-		    log_info(_("automatically retrieved `%s' via %s\n"),
-			     name,opt.keyserver->uri);
 		}
+              else
+                {
+                  mechanism = "Unconfigured keyserver";
+                  rc = G10ERR_NO_PUBKEY;
+                }
 	      break;
 
 	    case AKL_SPEC:
 	      {
 		struct keyserver_spec *keyserver;
 
+                mechanism = akl->spec->uri;
 		keyserver=keyserver_match(akl->spec);
 		glo_ctrl.in_auto_key_retrieve++;
 		rc=keyserver_import_name(name,&fpr,&fpr_len,keyserver);
 		glo_ctrl.in_auto_key_retrieve--;
-
-		if(rc==0)
-		  log_info(_("automatically retrieved `%s' via %s\n"),
-			   name,akl->spec->uri);
 	      }
 	      break;
 	    }
-
+          
 	  /* Use the fingerprint of the key that we actually fetched.
 	     This helps prevent problems where the key that we fetched
 	     doesn't have the same name that we used to fetch it.  In
@@ -1027,14 +1053,29 @@
 		log_info("auto-key-locate found fingerprint %s\n",fpr_string);
 
 	      add_to_strlist( &namelist, fpr_string );
-
-	      xfree(fpr);
 	    }
+          else if (!rc && !fpr && !did_key_byname)
+            {
+              no_fingerprint = 1;
+              rc = G10ERR_NO_PUBKEY;
+            }
+          xfree (fpr);
+          fpr = NULL;
 
-	  rc = key_byname( NULL, namelist, pk, NULL, 0,
-			   include_unusable, ret_keyblock, ret_kdbhd);
-	  if(rc!=G10ERR_NO_PUBKEY)
-	    break;
+          if (!rc && !did_key_byname)
+            rc = key_byname (NULL, namelist, pk, NULL, 0,
+                             include_unusable, ret_keyblock, ret_kdbhd);
+	  if (!rc)
+            {
+              /* Key found.  */
+              log_info (_("automatically retrieved `%s' via %s\n"),
+                        name, mechanism);
+              break;  
+            }
+          if (rc != G10ERR_NO_PUBKEY || opt.verbose || no_fingerprint)
+            log_info (_("error retrieving `%s' via %s: %s\n"),
+                      name, mechanism, 
+                      no_fingerprint? _("No fingerprint"):g10_errstr(rc));
 	}
     }
 
@@ -2638,7 +2679,7 @@
     rc = 0;
     while (!(rc = keydb_search (ctx->kr_handle, ctx->items, ctx->nitems))) {
         /* If we are searching for the first key we have to make sure
-           that the next interation does not no an implicit reset.
+           that the next iteration does not do an implicit reset.
            This can be triggered by an empty key ring. */
         if (ctx->nitems && ctx->items->mode == KEYDB_SEARCH_MODE_FIRST)
             ctx->items->mode = KEYDB_SEARCH_MODE_NEXT;
@@ -2949,6 +2990,7 @@
     }
 }
 
+/* Returns false on error. */
 int
 parse_auto_key_locate(char *options)
 {
@@ -2964,7 +3006,11 @@
 
       akl=xmalloc_clear(sizeof(*akl));
 
-      if(ascii_strcasecmp(tok,"ldap")==0)
+      if(ascii_strcasecmp(tok,"nodefault")==0)
+	akl->type=AKL_NODEFAULT;
+      else if(ascii_strcasecmp(tok,"local")==0)
+	akl->type=AKL_LOCAL;
+      else if(ascii_strcasecmp(tok,"ldap")==0)
 	akl->type=AKL_LDAP;
       else if(ascii_strcasecmp(tok,"keyserver")==0)
 	akl->type=AKL_KEYSERVER;

Modified: trunk/g10/gpg.c
===================================================================
--- trunk/g10/gpg.c	2008-04-07 19:55:44 UTC (rev 4739)
+++ trunk/g10/gpg.c	2008-04-08 11:04:16 UTC (rev 4740)
@@ -704,6 +704,7 @@
        I'm returning the favor. */
     { oLocalUser, "sign-with", 2, "@" },
     { oRecipient, "user", 2, "@" },
+
     { oRequireCrossCert, "require-backsigs", 0, "@"},
     { oRequireCrossCert, "require-cross-certification", 0, "@"},
     { oNoRequireCrossCert, "no-require-backsigs", 0, "@"},
@@ -1549,6 +1550,8 @@
   printf ("reader-port:%lu:\n", GC_OPT_FLAG_NONE);
   printf ("default-key:%lu:\n", GC_OPT_FLAG_NONE);
   printf ("encrypt-to:%lu:\n", GC_OPT_FLAG_NONE);
+  printf ("auto-key-locate:%lu:\n", GC_OPT_FLAG_NONE);
+  printf ("allow-pka-lookup:%lu:\n", GC_OPT_FLAG_NONE);
 
   xfree (configfile_esc);
 }

Modified: trunk/g10/import.c
===================================================================
--- trunk/g10/import.c	2008-04-07 19:55:44 UTC (rev 4739)
+++ trunk/g10/import.c	2008-04-08 11:04:16 UTC (rev 4740)
@@ -682,7 +682,7 @@
  * Try to import one keyblock.	Return an error only in serious cases, but
  * never for an invalid keyblock.  It uses log_error to increase the
  * internal errorcount, so that invalid input can be detected by programs
- * which called g10.
+ * which called gpg.
  */
 static int
 import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
@@ -697,6 +697,7 @@
     int rc = 0;
     int new_key = 0;
     int mod_key = 0;
+    int same_key = 0;
     int non_self = 0;
 
     /* get the key and print some info about it */
@@ -715,12 +716,14 @@
 		  nbits_from_pk( pk ),
 		  pubkey_letter( pk->pubkey_algo ),
 		  keystr_from_pk(pk), datestr_from_pk(pk) );
-	if( uidnode )
-	  print_utf8_string( stderr, uidnode->pkt->pkt.user_id->name,
+	if (uidnode)
+	  print_utf8_string (log_get_stream (),
+                             uidnode->pkt->pkt.user_id->name,
 			     uidnode->pkt->pkt.user_id->len );
 	log_printf ("\n");
       }
 
+
     if( !uidnode )
       {
 	log_error( _("key %s: no user ID\n"), keystr_from_pk(pk));
@@ -958,7 +961,8 @@
 	}
 	else
 	  {
-	    if (is_status_enabled ()) 
+            same_key = 1;
+            if (is_status_enabled ()) 
 	      print_import_ok (pk, NULL, 0);
 
 	    if( !opt.quiet )
@@ -975,6 +979,33 @@
     }
 
   leave:
+    if (mod_key || new_key || same_key)
+      {
+	/* A little explanation for this: we fill in the fingerprint
+	   when importing keys as it can be useful to know the
+	   fingerprint in certain keyserver-related cases (a keyserver
+	   asked for a particular name, but the key doesn't have that
+	   name).  However, in cases where we're importing more than
+	   one key at a time, we cannot know which key to fingerprint.
+	   In these cases, rather than guessing, we do not
+	   fingerprinting at all, and we must hope the user ID on the
+	   keys are useful.  Note that we need to do this for new
+	   keys, merged keys and even for unchanged keys.  This is
+	   required because for example the --auto-key-locate feature
+	   may import an already imported key and needs to know the
+	   fingerprint of the key in all cases.  */
+	if (fpr)
+	  {
+	    xfree (*fpr);
+            /* Note that we need to compare against 0 here because
+               COUNT gets only incremented after returning form this
+               function.  */
+	    if (stats->count == 0)
+	      *fpr = fingerprint_from_pk (pk, NULL, fpr_len);
+	    else
+	      *fpr = NULL;
+	  }
+      }
 
     /* Now that the key is definitely incorporated into the keydb, we
        need to check if a designated revocation is present or if the
@@ -988,24 +1019,6 @@
       }
     else if(new_key)
       {
-	/* A little explanation for this: we fill in the fingerprint
-	   when importing keys as it can be useful to know the
-	   fingerprint in certain keyserver-related cases (a keyserver
-	   asked for a particular name, but the key doesn't have that
-	   name).  However, in cases where we're importing more than
-	   one key at a time, we cannot know which key to fingerprint.
-	   In these cases, rather than guessing, we do not fingerpring
-	   at all, and we must hope the user ID on the keys are
-	   useful. */
-	if(fpr)
-	  {
-	    xfree(*fpr);
-	    if(stats->imported==1)
-	      *fpr=fingerprint_from_pk(pk,NULL,fpr_len);
-	    else
-	      *fpr=NULL;
-	  }
-
 	revocation_present(keyblock);
 	if(!from_sk && seckey_available(keyid)==0)
 	  check_prefs(keyblock);

Modified: trunk/g10/keydb.h
===================================================================
--- trunk/g10/keydb.h	2008-04-07 19:55:44 UTC (rev 4739)
+++ trunk/g10/keydb.h	2008-04-08 11:04:16 UTC (rev 4740)
@@ -223,7 +223,7 @@
 KBNODE get_pubkeyblock( u32 *keyid );
 int get_pubkey_byname( PKT_public_key *pk,  const char *name,
                        KBNODE *ret_keyblock, KEYDB_HANDLE *ret_kdbhd,
-		       int include_unusable );
+		       int include_unusable, int no_akl );
 int get_pubkey_bynames( GETKEY_CTX *rx, PKT_public_key *pk,
 			strlist_t names, KBNODE *ret_keyblock );
 int get_pubkey_next( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE *ret_keyblock );

Modified: trunk/g10/keyedit.c
===================================================================
--- trunk/g10/keyedit.c	2008-04-07 19:55:44 UTC (rev 4739)
+++ trunk/g10/keyedit.c	2008-04-08 11:04:16 UTC (rev 4740)
@@ -1544,7 +1544,7 @@
 #endif
 
     /* Get the public key */
-    rc = get_pubkey_byname (NULL, username, &keyblock, &kdbhd, 1);
+    rc = get_pubkey_byname (NULL, username, &keyblock, &kdbhd, 1, 1);
     if( rc )
 	goto leave;
     if( fix_keyblock( keyblock ) )
@@ -3396,7 +3396,7 @@
 	 GnuPG both can handle a designated revokation from a
 	 subkey. */
       revoker_pk->req_usage=PUBKEY_USAGE_CERT;
-      rc=get_pubkey_byname(revoker_pk,answer,NULL,NULL,1);
+      rc=get_pubkey_byname(revoker_pk,answer,NULL,NULL,1, 1);
       if(rc)
 	{
 	  log_error (_("key \"%s\" not found: %s\n"),answer,g10_errstr(rc));

Modified: trunk/g10/keyserver.c
===================================================================
--- trunk/g10/keyserver.c	2008-04-07 19:55:44 UTC (rev 4739)
+++ trunk/g10/keyserver.c	2008-04-08 11:04:16 UTC (rev 4740)
@@ -1,6 +1,6 @@
 /* keyserver.c - generic keyserver code
  * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006,
- *               2007 Free Software Foundation, Inc.
+ *               2007, 2008 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.




More information about the Gnupg-commits mailing list