[svn] gpgme - r1154 - in trunk: . gpgme

svn author marcus cvs at cvs.gnupg.org
Wed Feb 22 12:02:51 CET 2006


Author: marcus
Date: 2006-02-22 12:02:50 +0100 (Wed, 22 Feb 2006)
New Revision: 1154

Modified:
   trunk/TODO
   trunk/gpgme/ChangeLog
   trunk/gpgme/keylist.c
   trunk/gpgme/rungpg.c
Log:
2006-02-22  Marcus Brinkmann  <marcus at g10code.de>

	* rungpg.c (read_colon_line): Invoke colon preprocess handler if
	it is set.
	(colon_preprocessor_t): New type.
	(struct engine_gpg): New member colon.preprocess_fnc.
	(gpg_keylist_preprocess): New function.
	* keylist.c (keylist_colon_handler): Allow short key IDs.


Modified: trunk/TODO
===================================================================
--- trunk/TODO	2006-02-15 13:30:08 UTC (rev 1153)
+++ trunk/TODO	2006-02-22 11:02:50 UTC (rev 1154)
@@ -5,10 +5,7 @@
    The test is currently disabled there and in gpg/t-import.
 ** When gpg supports it, write binary subpackets directly,
    and parse SUBPACKET status lines.
-** External key listing for OpenPGP.
-   This probably requires changes at gpg.
 
-
 * ABI's to break:
 ** gpgme_edit_cb_t: Add "processed" return argument
    (see edit.c::command_handler).
@@ -81,7 +78,7 @@
    release everything properly at a reset and at an error.  Think hard
    about where to guarantee what (ie, what happens if start fails, are
    the fds unregistered immediately - i think so?)
-** Optimize the case where a data object has an underlying fd we can pass
+** Optimize the case where a data object has 0an underlying fd we can pass
    directly to the engine.  This will be automatic with socket I/O and
    descriptor passing.
 ** Move code common to all engines up from gpg to engine.

Modified: trunk/gpgme/ChangeLog
===================================================================
--- trunk/gpgme/ChangeLog	2006-02-15 13:30:08 UTC (rev 1153)
+++ trunk/gpgme/ChangeLog	2006-02-22 11:02:50 UTC (rev 1154)
@@ -1,3 +1,12 @@
+2006-02-22  Marcus Brinkmann  <marcus at g10code.de>
+
+	* rungpg.c (read_colon_line): Invoke colon preprocess handler if
+	it is set.
+	(colon_preprocessor_t): New type.
+	(struct engine_gpg): New member colon.preprocess_fnc.
+	(gpg_keylist_preprocess): New function.
+	* keylist.c (keylist_colon_handler): Allow short key IDs.
+
 2006-02-15  Marcus Brinkmann  <marcus at g10code.de>
 
 	* w32-io.c (create_writer): Make C->have_data a manually resetted

Modified: trunk/gpgme/keylist.c
===================================================================
--- trunk/gpgme/keylist.c	2006-02-15 13:30:08 UTC (rev 1153)
+++ trunk/gpgme/keylist.c	2006-02-22 11:02:50 UTC (rev 1154)
@@ -176,7 +176,8 @@
 
 	case 'd':
           /* Note that gpg 1.3 won't print that anymore but only uses
-             the capabilities field. */
+             the capabilities field.  However, it is still used for
+             external key listings.  */
 	  key->disabled = 1;
 	  break;
 
@@ -493,8 +494,9 @@
 	    subkey->pubkey_algo = i;
 	}
 
-      /* Field 5 has the long keyid.  */
-      if (fields >= 5 && strlen (field[4]) == DIM(subkey->_keyid) - 1)
+      /* Field 5 has the long keyid.  Allow short key IDs for the
+	 output of an external keyserver listing.  */
+      if (fields >= 5 && strlen (field[4]) <= DIM(subkey->_keyid) - 1)
 	strcpy (subkey->_keyid, field[4]);
 
       /* Field 6 has the timestamp (seconds).  */

Modified: trunk/gpgme/rungpg.c
===================================================================
--- trunk/gpgme/rungpg.c	2006-02-15 13:30:08 UTC (rev 1153)
+++ trunk/gpgme/rungpg.c	2006-02-22 11:02:50 UTC (rev 1154)
@@ -65,6 +65,8 @@
 };
 
 
+typedef gpgme_error_t (*colon_preprocessor_t) (char *line, char **rline);
+
 struct engine_gpg
 {
   char *file_name;
@@ -95,6 +97,7 @@
     engine_colon_line_handler_t fnc;  /* this indicate use of this structrue */
     void *fnc_value;
     void *tag;
+    colon_preprocessor_t preprocess_fnc;
   } colon;
 
   char **argv;  
@@ -1013,14 +1016,27 @@
 	    {
 	      /* (we require that the last line is terminated by a LF)
 		 and we skip empty lines.  Note: we use UTF8 encoding
-		 and escaping of special characters We require at
+		 and escaping of special characters.  We require at
 		 least one colon to cope with some other printed
 		 information.  */
 	      *p = 0;
 	      if (*buffer && strchr (buffer, ':'))
 		{
+		  char *line = NULL;
+
+		  if (gpg->colon.preprocess_fnc)
+		    {
+		      gpgme_error_t err;
+
+		      err = gpg->colon.preprocess_fnc (buffer, &line);
+		      if (err)
+			return err;
+		    }
+
 		  assert (gpg->colon.fnc);
-		  gpg->colon.fnc (gpg->colon.fnc_value, buffer);
+		  gpg->colon.fnc (gpg->colon.fnc_value, line ? line : buffer);
+		  if (line)
+		    free (line);
 		}
             
 	      /* To reuse the buffer for the next line we have to
@@ -1613,13 +1629,107 @@
 }
 
 
+/* The output for external keylistings in GnuPG is different from all
+   the other key listings.  We catch this here with a special
+   preprocessor that reformats the colon handler lines.  */
 static gpgme_error_t
+gpg_keylist_preprocess (char *line, char **r_line)
+{
+  enum
+    {
+      RT_NONE, RT_INFO, RT_PUB, RT_UID
+    }
+  rectype = RT_NONE;
+#define NR_FIELDS 16
+  char *field[NR_FIELDS];
+  int fields = 0;
+
+  *r_line = NULL;
+
+  while (line && fields < NR_FIELDS)
+    {
+      field[fields++] = line;
+      line = strchr (line, ':');
+      if (line)
+	*(line++) = '\0';
+    }
+
+  if (!strcmp (field[0], "info"))
+    rectype = RT_INFO;
+  else if (!strcmp (field[0], "pub"))
+    rectype = RT_PUB;
+  else if (!strcmp (field[0], "uid"))
+    rectype = RT_UID;
+  else 
+    rectype = RT_NONE;
+
+  switch (rectype)
+    {
+    case RT_INFO:
+      /* FIXME: Eventually, check the version number at least.  */
+      return 0;
+
+    case RT_PUB:
+      if (fields < 7)
+	return 0;
+
+      /* The format is:
+
+	 pub:<keyid>:<algo>:<keylen>:<creationdate>:<expirationdate>:<flags>
+
+	 as defined in 5.2. Machine Readable Indexes of the OpenPGP
+	 HTTP Keyserver Protocol (draft). 
+
+	 We want:
+	 pub:o<flags>:<keylen>:<algo>:<keyid>:<creatdate>:<expdate>::::::::
+      */
+
+      if (asprintf (r_line, "pub:o%s:%s:%s:%s:%s:%s::::::::",
+		    field[6], field[3], field[2], field[1],
+		    field[4], field[5]) < 0)
+	return gpg_error_from_errno (errno);
+      return 0;
+
+    case RT_UID:
+      /* The format is:
+
+         uid:<escaped uid string>:<creationdate>:<expirationdate>:<flags>
+
+	 as defined in 5.2. Machine Readable Indexes of the OpenPGP
+	 HTTP Keyserver Protocol (draft). 
+
+	 We want:
+	 uid:o<flags>::::<creatdate>:<expdate>:::<uid>:
+      */
+
+      if (asprintf (r_line, "uid:o%s::::%s:%s:::%s:",
+		    field[4], field[2], field[3], field[1]) < 0)
+	return gpg_error_from_errno (errno);
+      return 0;
+
+    case RT_NONE:
+      /* Unknown record.  */
+      break;
+    }
+  return 0;
+
+}
+
+
+static gpgme_error_t
 gpg_keylist (void *engine, const char *pattern, int secret_only,
 	     gpgme_keylist_mode_t mode)
 {
   engine_gpg_t gpg = engine;
   gpgme_error_t err;
 
+  if (mode & GPGME_KEYLIST_MODE_EXTERN)
+    {
+      if ((mode & GPGME_KEYLIST_MODE_LOCAL)
+	  || secret_only)
+	return gpg_error (GPG_ERR_NOT_SUPPORTED);
+    }
+  
   err = add_arg (gpg, "--with-colons");
   if (!err)
     err = add_arg (gpg, "--fixed-list-mode");
@@ -1635,10 +1745,20 @@
 	err = add_arg (gpg, "show-sig-subpackets=\"20,26\"");
     }
   if (!err)
-    err = add_arg (gpg, secret_only ? "--list-secret-keys"
-		   : ((mode & GPGME_KEYLIST_MODE_SIGS)
-		      ? "--check-sigs" : "--list-keys"));
-  
+    {
+      if (mode & GPGME_KEYLIST_MODE_EXTERN)
+	{
+	  err = add_arg (gpg, "--search-keys");
+	  gpg->colon.preprocess_fnc = gpg_keylist_preprocess;
+	}
+      else
+	{
+	  err = add_arg (gpg, secret_only ? "--list-secret-keys"
+			 : ((mode & GPGME_KEYLIST_MODE_SIGS)
+			    ? "--check-sigs" : "--list-keys"));
+	}
+    }
+
   /* Tell the gpg object about the data.  */
   if (!err)
     err = add_arg (gpg, "--");




More information about the Gnupg-commits mailing list