[git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.0-14-g50c8b6c

by Werner Koch cvs at cvs.gnupg.org
Mon Sep 18 15:45:39 CEST 2017


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU Privacy Guard".

The branch, STABLE-BRANCH-2-2 has been updated
       via  50c8b6c88f5d9f4b6c4e9c03aee31fe29afa94b8 (commit)
       via  7f7f5d06fa5aa3a3c5ab8d2e59ee76207bfdeaa0 (commit)
       via  a0035986a8615df056182bb9af775b8b7b22003d (commit)
       via  4e0696de897cac6a34d55a69d8889faf26f1a923 (commit)
      from  006ca124ed95845d43af8c14d7ab2bc085b47b4c (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 50c8b6c88f5d9f4b6c4e9c03aee31fe29afa94b8
Author: Werner Koch <wk at gnupg.org>
Date:   Mon Sep 18 15:37:21 2017 +0200

    wks: Create a new user id if provider wants mailbox-only.
    
    * tools/gpg-wks-client.c (get_key): Add arg 'exact'.
    (add_user_id): New.
    (command_send): Create new user id.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/doc/wks.texi b/doc/wks.texi
index f9b1a0c..029dbf0 100644
--- a/doc/wks.texi
+++ b/doc/wks.texi
@@ -78,7 +78,9 @@ the command is a properly formatted mail with all standard headers.
 This mail can be fed to @command{sendmail(8)} or any other tool to
 actually send that mail.  If @command{sendmail(8)} is installed the
 option @option{--send} can be used to directly send the created
-request.
+request.  If the provider request a 'mailbox-only' user id and no such
+user id is found, @command{gpg-wks-client} will try an additional user
+id.
 
 The @option{--receive} and @option{--read} commands are used to
 process confirmation mails as send from the service provider.  The
diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c
index 37b7560..73a8a1f 100644
--- a/tools/gpg-wks-client.c
+++ b/tools/gpg-wks-client.c
@@ -348,10 +348,13 @@ get_key_status_cb (void *opaque, const char *keyword, char *args)
 
 
 /* Get a key by fingerprint from gpg's keyring and make sure that the
- * mail address ADDRSPEC is included in the key.  The key is returned
- * as a new memory stream at R_KEY.  */
+ * mail address ADDRSPEC is included in the key.  If EXACT is set the
+ * returned user id must match Addrspec exactly and not just in the
+ * addr-spec (mailbox) part.  The key is returned as a new memory
+ * stream at R_KEY.  */
 static gpg_error_t
-get_key (estream_t *r_key, const char *fingerprint, const char *addrspec)
+get_key (estream_t *r_key, const char *fingerprint, const char *addrspec,
+         int exact)
 {
   gpg_error_t err;
   ccparray_t ccp;
@@ -376,7 +379,7 @@ get_key (estream_t *r_key, const char *fingerprint, const char *addrspec)
   es_fputs ("Content-Type: application/pgp-keys\n"
             "\n", key);
 
-  filterexp = es_bsprintf ("keep-uid=mbox = %s", addrspec);
+  filterexp = es_bsprintf ("keep-uid=%s=%s", exact? "uid":"mbox", addrspec);
   if (!filterexp)
     {
       err = gpg_error_from_syserror ();
@@ -435,6 +438,49 @@ get_key (estream_t *r_key, const char *fingerprint, const char *addrspec)
 }
 
 
+/* Add the user id UID to the key identified by FINGERPRINT.  */
+static gpg_error_t
+add_user_id (const char *fingerprint, const char *uid)
+{
+  gpg_error_t err;
+  ccparray_t ccp;
+  const char **argv = NULL;
+
+  ccparray_init (&ccp, 0);
+
+  ccparray_put (&ccp, "--no-options");
+  if (!opt.verbose)
+    ccparray_put (&ccp, "--quiet");
+  else if (opt.verbose > 1)
+    ccparray_put (&ccp, "--verbose");
+  ccparray_put (&ccp, "--batch");
+  ccparray_put (&ccp, "--always-trust");
+  ccparray_put (&ccp, "--quick-add-uid");
+  ccparray_put (&ccp, fingerprint);
+  ccparray_put (&ccp, uid);
+
+  ccparray_put (&ccp, NULL);
+  argv = ccparray_get (&ccp, NULL);
+  if (!argv)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+  err = gnupg_exec_tool_stream (opt.gpg_program, argv, NULL,
+                                NULL, NULL,
+                                NULL, NULL);
+  if (err)
+    {
+      log_error ("adding user id failed: %s\n", gpg_strerror (err));
+      goto leave;
+    }
+
+ leave:
+  xfree (argv);
+  return err;
+}
+
+
 

 struct decrypt_stream_parm_s
 {
@@ -721,7 +767,7 @@ command_send (const char *fingerprint, const char *userid)
       err = gpg_error (GPG_ERR_INV_USER_ID);
       goto leave;
     }
-  err = get_key (&key, fingerprint, addrspec);
+  err = get_key (&key, fingerprint, addrspec, 0);
   if (err)
     goto leave;
 
@@ -786,6 +832,9 @@ command_send (const char *fingerprint, const char *userid)
     {
       if (!uid->mbox)
         continue; /* Should not happen anyway.  */
+      if (policy.mailbox_only
+          && ascii_strcasecmp (uid->uid, uid->mbox))
+        continue; /* UID has more than just the mailbox.  */
       if (uid->created > thistime)
         {
           thistime = uid->created;
@@ -793,7 +842,7 @@ command_send (const char *fingerprint, const char *userid)
         }
     }
   if (!thisuid)
-    thisuid = uid;  /* This is the case for a missing timestamp.  */
+    thisuid = uidlist;  /* This is the case for a missing timestamp.  */
   if (opt.verbose)
     log_info ("submitting key with user id '%s'\n", thisuid->uid);
 
@@ -816,10 +865,22 @@ command_send (const char *fingerprint, const char *userid)
     }
 
   if (policy.mailbox_only
-      && ascii_strcasecmp (userid, addrspec))
+      && (!thisuid->mbox || ascii_strcasecmp (thisuid->uid, thisuid->mbox)))
     {
       log_info ("Warning: policy requires 'mailbox-only'"
-                " - creating new user id'\n");
+                " - adding user id '%s'\n", addrspec);
+      err = add_user_id (fingerprint, addrspec);
+      if (err)
+        goto leave;
+
+      /* Need to get the key again.  This time we request filtering
+       * for the full user id, so that we do not need check and filter
+       * the key again.  */
+      es_fclose (key);
+      key = NULL;
+      err = get_key (&key, fingerprint, addrspec, 1);
+      if (err)
+        goto leave;
     }
 
   /* Hack to support posteo but let them disable this by setting the

commit 7f7f5d06fa5aa3a3c5ab8d2e59ee76207bfdeaa0
Author: Werner Koch <wk at gnupg.org>
Date:   Mon Sep 18 12:52:20 2017 +0200

    wks: Send only the newest UID to the server.
    
    * tools/wks-util.c (list_key_status_cb): Rename to key_status_cb.
    (wks_filter_uid): New.
    (wks_list_key): Allow FPR to be NULL.  Return an error if no
    fingerprint was found.
    * tools/gpg-wks-server.c (process_new_key)
    (check_and_publish): Remove now useless extra check for FPR.
    * tools/gpg-wks-client.c (command_check): Ditto.
    (command_send): Filter out the newest uid.
    --
    
    This fixes the case of having several userids with all the the same
    mailbox.  Now we use the latest user id created.  This patch is also a
    prerequisite to automatically create a new user id for providers with
    the mailbox-only policy.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c
index 18a0edd..37b7560 100644
--- a/tools/gpg-wks-client.c
+++ b/tools/gpg-wks-client.c
@@ -644,10 +644,9 @@ command_check (char *userid)
 
   /* Look closer at the key.  */
   err = wks_list_key (key, &fpr, &mboxes);
-  if (err || !fpr)
+  if (err)
     {
-      log_error ("error parsing key: %s\n",
-                 err? gpg_strerror (err) : "no fingerprint found");
+      log_error ("error parsing key: %s\n", gpg_strerror (err));
       err = gpg_error (GPG_ERR_NO_PUBKEY);
       goto leave;
     }
@@ -700,6 +699,9 @@ command_send (const char *fingerprint, const char *userid)
   int no_encrypt = 0;
   int posteo_hack = 0;
   const char *domain;
+  uidinfo_list_t uidlist = NULL;
+  uidinfo_list_t uid, thisuid;
+  time_t thistime;
 
   memset (&policy, 0, sizeof policy);
 
@@ -769,6 +771,57 @@ command_send (const char *fingerprint, const char *userid)
   if (policy.auth_submit)
     log_info ("no confirmation required for '%s'\n", addrspec);
 
+  /* In case the key has several uids with the same addr-spec we will
+   * use the newest one.  */
+  err = wks_list_key (key, NULL, &uidlist);
+  if (err)
+    {
+      log_error ("error parsing key: %s\n",gpg_strerror (err));
+      err = gpg_error (GPG_ERR_NO_PUBKEY);
+      goto leave;
+    }
+  thistime = 0;
+  thisuid = NULL;
+  for (uid = uidlist; uid; uid = uid->next)
+    {
+      if (!uid->mbox)
+        continue; /* Should not happen anyway.  */
+      if (uid->created > thistime)
+        {
+          thistime = uid->created;
+          thisuid = uid;
+        }
+    }
+  if (!thisuid)
+    thisuid = uid;  /* This is the case for a missing timestamp.  */
+  if (opt.verbose)
+    log_info ("submitting key with user id '%s'\n", thisuid->uid);
+
+  /* If we have more than one user id we need to filter the key to
+   * include only THISUID.  */
+  if (uidlist->next)
+    {
+      estream_t newkey;
+
+      es_rewind (key);
+      err = wks_filter_uid (&newkey, key, thisuid->uid);
+      if (err)
+        {
+          log_error ("error filtering key: %s\n", gpg_strerror (err));
+          err = gpg_error (GPG_ERR_NO_PUBKEY);
+          goto leave;
+        }
+      es_fclose (key);
+      key = newkey;
+    }
+
+  if (policy.mailbox_only
+      && ascii_strcasecmp (userid, addrspec))
+    {
+      log_info ("Warning: policy requires 'mailbox-only'"
+                " - creating new user id'\n");
+    }
+
   /* Hack to support posteo but let them disable this by setting the
    * new policy-version flag.  */
   if (policy.protocol_version < 3
@@ -885,6 +938,7 @@ command_send (const char *fingerprint, const char *userid)
  leave:
   mime_maker_release (mime);
   xfree (submission_to);
+  free_uidinfo_list (uidlist);
   es_fclose (keyenc);
   es_fclose (key);
   xfree (addrspec);
diff --git a/tools/gpg-wks-server.c b/tools/gpg-wks-server.c
index f7aadba..7e3f050 100644
--- a/tools/gpg-wks-server.c
+++ b/tools/gpg-wks-server.c
@@ -1105,12 +1105,7 @@ process_new_key (server_ctx_t ctx, estream_t key)
   err = wks_list_key (key, &ctx->fpr, &ctx->mboxes);
   if (err)
     goto leave;
-  if (!ctx->fpr)
-    {
-      log_error ("error parsing key (no fingerprint)\n");
-      err = gpg_error (GPG_ERR_NO_PUBKEY);
-      goto leave;
-    }
+  log_assert (ctx->fpr);
   log_info ("fingerprint: %s\n", ctx->fpr);
   for (sl = ctx->mboxes; sl; sl = sl->next)
     {
@@ -1358,12 +1353,7 @@ check_and_publish (server_ctx_t ctx, const char *address, const char *nonce)
   err = wks_list_key (key, &ctx->fpr, &ctx->mboxes);
   if (err)
     goto leave;
-  if (!ctx->fpr)
-    {
-      log_error ("error parsing key (no fingerprint)\n");
-      err = gpg_error (GPG_ERR_NO_PUBKEY);
-      goto leave;
-    }
+  log_assert (ctx->fpr);
   log_info ("fingerprint: %s\n", ctx->fpr);
   for (sl = ctx->mboxes; sl; sl = sl->next)
     if (sl->mbox)
diff --git a/tools/gpg-wks.h b/tools/gpg-wks.h
index cb89fd5..ece7add 100644
--- a/tools/gpg-wks.h
+++ b/tools/gpg-wks.h
@@ -87,6 +87,8 @@ void wks_write_status (int no, const char *format, ...) GPGRT_ATTR_PRINTF(2,3);
 void free_uidinfo_list (uidinfo_list_t list);
 gpg_error_t wks_list_key (estream_t key, char **r_fpr,
                           uidinfo_list_t *r_mboxes);
+gpg_error_t wks_filter_uid (estream_t *r_newkey, estream_t key,
+                            const char *uid);
 gpg_error_t wks_send_mime (mime_maker_t mime);
 gpg_error_t wks_parse_policy (policy_flags_t flags, estream_t stream,
                               int ignore_unknown);
diff --git a/tools/wks-util.c b/tools/wks-util.c
index 8fc0a2e..889ca36 100644
--- a/tools/wks-util.c
+++ b/tools/wks-util.c
@@ -133,9 +133,9 @@ free_uidinfo_list (uidinfo_list_t list)
 
 
 

-/* Helper for wks_list_key.  */
+/* Helper for wks_list_key and wks_filter_uid.  */
 static void
-list_key_status_cb (void *opaque, const char *keyword, char *args)
+key_status_cb (void *opaque, const char *keyword, char *args)
 {
   (void)opaque;
 
@@ -146,7 +146,8 @@ list_key_status_cb (void *opaque, const char *keyword, char *args)
 
 /* Run gpg on KEY and store the primary fingerprint at R_FPR and the
  * list of mailboxes at R_MBOXES.  Returns 0 on success; on error NULL
- * is stored at R_FPR and R_MBOXES and an error code is returned.  */
+ * is stored at R_FPR and R_MBOXES and an error code is returned.
+ * R_FPR may be NULL if the fingerprint is not needed.  */
 gpg_error_t
 wks_list_key (estream_t key, char **r_fpr, uidinfo_list_t *r_mboxes)
 {
@@ -164,7 +165,8 @@ wks_list_key (estream_t key, char **r_fpr, uidinfo_list_t *r_mboxes)
   char *fpr = NULL;
   uidinfo_list_t mboxes = NULL;
 
-  *r_fpr = NULL;
+  if (r_fpr)
+    *r_fpr = NULL;
   *r_mboxes = NULL;
 
   /* Open a memory stream.  */
@@ -200,7 +202,7 @@ wks_list_key (estream_t key, char **r_fpr, uidinfo_list_t *r_mboxes)
     }
   err = gnupg_exec_tool_stream (opt.gpg_program, argv, key,
                                 NULL, listing,
-                                list_key_status_cb, NULL);
+                                key_status_cb, NULL);
   if (err)
     {
       log_error ("import failed: %s\n", gpg_strerror (err));
@@ -289,8 +291,17 @@ wks_list_key (estream_t key, char **r_fpr, uidinfo_list_t *r_mboxes)
       goto leave;
     }
 
-  *r_fpr = fpr;
-  fpr = NULL;
+  if (!fpr)
+    {
+      err = gpg_error (GPG_ERR_NO_PUBKEY);
+      goto leave;
+    }
+
+  if (r_fpr)
+    {
+      *r_fpr = fpr;
+      fpr = NULL;
+    }
   *r_mboxes = mboxes;
   mboxes = NULL;
 
@@ -305,6 +316,85 @@ wks_list_key (estream_t key, char **r_fpr, uidinfo_list_t *r_mboxes)
 }
 
 
+/* Run gpg as a filter on KEY and write the output to a new stream
+ * stored at R_NEWKEY.  The new key will containn only the user id
+ * UID.  Returns 0 on success.  Only one key is expected in KEY. */
+gpg_error_t
+wks_filter_uid (estream_t *r_newkey, estream_t key, const char *uid)
+{
+  gpg_error_t err;
+  ccparray_t ccp;
+  const char **argv = NULL;
+  estream_t newkey;
+  char *filterexp = NULL;
+
+  *r_newkey = NULL;
+
+  /* Open a memory stream.  */
+  newkey = es_fopenmem (0, "w+b");
+  if (!newkey)
+    {
+      err = gpg_error_from_syserror ();
+      log_error ("error allocating memory buffer: %s\n", gpg_strerror (err));
+      return err;
+    }
+
+  /* Prefix the key with the MIME content type.  */
+  es_fputs ("Content-Type: application/pgp-keys\n"
+            "\n", newkey);
+
+  filterexp = es_bsprintf ("keep-uid=uid=%s", uid);
+  if (!filterexp)
+    {
+      err = gpg_error_from_syserror ();
+      log_error ("error allocating memory buffer: %s\n", gpg_strerror (err));
+      goto leave;
+    }
+
+  ccparray_init (&ccp, 0);
+
+  ccparray_put (&ccp, "--no-options");
+  if (!opt.verbose)
+    ccparray_put (&ccp, "--quiet");
+  else if (opt.verbose > 1)
+    ccparray_put (&ccp, "--verbose");
+  ccparray_put (&ccp, "--batch");
+  ccparray_put (&ccp, "--status-fd=2");
+  ccparray_put (&ccp, "--always-trust");
+  ccparray_put (&ccp, "--armor");
+  ccparray_put (&ccp, "--import-options=import-export");
+  ccparray_put (&ccp, "--import-filter");
+  ccparray_put (&ccp, filterexp);
+  ccparray_put (&ccp, "--import");
+
+  ccparray_put (&ccp, NULL);
+  argv = ccparray_get (&ccp, NULL);
+  if (!argv)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+  err = gnupg_exec_tool_stream (opt.gpg_program, argv, key,
+                                NULL, newkey,
+                                key_status_cb, NULL);
+  if (err)
+    {
+      log_error ("import/export failed: %s\n", gpg_strerror (err));
+      goto leave;
+    }
+
+  es_rewind (newkey);
+  *r_newkey = newkey;
+  newkey = NULL;
+
+ leave:
+  xfree (filterexp);
+  xfree (argv);
+  es_fclose (newkey);
+  return err;
+}
+
+
 /* Helper to write mail to the output(s).  */
 gpg_error_t
 wks_send_mime (mime_maker_t mime)

commit a0035986a8615df056182bb9af775b8b7b22003d
Author: Werner Koch <wk at gnupg.org>
Date:   Mon Sep 18 11:31:36 2017 +0200

    wks: Print the UID creation time with gpg-wks-client --check.
    
    * tools/gpg-wks.h (uidinfo_list_s): Add field 'created'.
    * tools/wks-util.c (append_to_uidinfo_list): Add arf 'created'.
    (wks_list_key): Pass timestamp to append_to_uidinfo_list.
    * tools/gpg-wks-client.c (command_check): Print UID creation time.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c
index 6b83de8..18a0edd 100644
--- a/tools/gpg-wks-client.c
+++ b/tools/gpg-wks-client.c
@@ -662,6 +662,7 @@ command_check (char *userid)
       if (opt.verbose)
         {
           log_info ("    user-id: %s\n", sl->uid);
+          log_info ("    created: %s\n", asctimestamp (sl->created));
           if (sl->mbox)
             log_info ("  addr-spec: %s\n", sl->mbox);
         }
diff --git a/tools/gpg-wks.h b/tools/gpg-wks.h
index 7fc8d9a..cb89fd5 100644
--- a/tools/gpg-wks.h
+++ b/tools/gpg-wks.h
@@ -73,6 +73,7 @@ typedef struct policy_flags_s *policy_flags_t;
 struct uidinfo_list_s
 {
   struct uidinfo_list_s *next;
+  time_t created; /* Time the userid was created.  */
   char *mbox;  /* NULL or the malloced mailbox from UID.  */
   char uid[1];
 };
diff --git a/tools/wks-util.c b/tools/wks-util.c
index bc076a7..8fc0a2e 100644
--- a/tools/wks-util.c
+++ b/tools/wks-util.c
@@ -94,7 +94,7 @@ wks_write_status (int no, const char *format, ...)
 /* Append UID to LIST and return the new item.  On success LIST is
  * updated.  On error ERRNO is set and NULL returned. */
 static uidinfo_list_t
-append_to_uidinfo_list (uidinfo_list_t *list, const char *uid)
+append_to_uidinfo_list (uidinfo_list_t *list, const char *uid, time_t created)
 {
   uidinfo_list_t r, sl;
 
@@ -103,6 +103,7 @@ append_to_uidinfo_list (uidinfo_list_t *list, const char *uid)
     return NULL;
 
   strcpy (sl->uid, uid);
+  sl->created = created;
   sl->mbox = mailbox_from_userid (uid);
   sl->next = NULL;
   if (!*list)
@@ -273,7 +274,8 @@ wks_list_key (estream_t key, char **r_fpr, uidinfo_list_t *r_mboxes)
       else if (!strcmp (fields[0], "uid") && nfields > 9)
         {
           /* Fixme: Unescape fields[9] */
-          if (!append_to_uidinfo_list (&mboxes, fields[9]))
+          if (!append_to_uidinfo_list (&mboxes, fields[9],
+                                       parse_timestamp (fields[5], NULL)))
             {
               err = gpg_error_from_syserror ();
               goto leave;

commit 4e0696de897cac6a34d55a69d8889faf26f1a923
Author: Werner Koch <wk at gnupg.org>
Date:   Mon Sep 18 11:16:07 2017 +0200

    wks: Use dedicated type to convey user ids.
    
    * tools/gpg-wks.h (uidinfo_list_s, uidinfo_list_t): New.
    * tools/wks-util.c (append_to_uidinfo_list): New.
    (free_uidinfo_list): New.
    (wks_list_key): Change arg r_mboxes to uidinfo_list_t.  Use
    append_to_uidinfo_list.
    * tools/gpg-wks-server.c (sserver_ctx_s): Replace strlist_t by
    uidinfo_list_t.
    (process_new_key): Ditto.
    (check_and_publish): Ditto.
    (command_receive_cb): Replace free_strlist by free_uidinfo_list.
    * tools/gpg-wks-client.c (command_check): Replace strlist_t by
    uidinfo_list_t.  Also print user id in verbose mode.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c
index e703640..6b83de8 100644
--- a/tools/gpg-wks-client.c
+++ b/tools/gpg-wks-client.c
@@ -119,7 +119,7 @@ const char *fake_submission_addr;
 static void wrong_args (const char *text) GPGRT_ATTR_NORETURN;
 static gpg_error_t command_supported (char *userid);
 static gpg_error_t command_check (char *userid);
-static gpg_error_t command_send (const char *fingerprint, char *userid);
+static gpg_error_t command_send (const char *fingerprint, const char *userid);
 static gpg_error_t encrypt_response (estream_t *r_output, estream_t input,
                                      const char *addrspec,
                                      const char *fingerprint);
@@ -597,8 +597,8 @@ command_check (char *userid)
   char *addrspec = NULL;
   estream_t key = NULL;
   char *fpr = NULL;
-  strlist_t mboxes = NULL;
-  strlist_t sl;
+  uidinfo_list_t mboxes = NULL;
+  uidinfo_list_t sl;
   int found = 0;
 
   addrspec = mailbox_from_userid (userid);
@@ -657,10 +657,14 @@ command_check (char *userid)
 
   for (sl = mboxes; sl; sl = sl->next)
     {
-      if (!strcmp (sl->d, addrspec))
+      if (sl->mbox && !strcmp (sl->mbox, addrspec))
         found = 1;
       if (opt.verbose)
-        log_info ("  addr-spec: %s\n", sl->d);
+        {
+          log_info ("    user-id: %s\n", sl->uid);
+          if (sl->mbox)
+            log_info ("  addr-spec: %s\n", sl->mbox);
+        }
     }
   if (!found)
     {
@@ -671,7 +675,7 @@ command_check (char *userid)
 
  leave:
   xfree (fpr);
-  free_strlist (mboxes);
+  free_uidinfo_list (mboxes);
   es_fclose (key);
   xfree (addrspec);
   return err;
@@ -682,7 +686,7 @@ command_check (char *userid)
 /* Locate the key by fingerprint and userid and send a publication
  * request.  */
 static gpg_error_t
-command_send (const char *fingerprint, char *userid)
+command_send (const char *fingerprint, const char *userid)
 {
   gpg_error_t err;
   KEYDB_SEARCH_DESC desc;
@@ -706,6 +710,7 @@ command_send (const char *fingerprint, char *userid)
       err = gpg_error (GPG_ERR_INV_NAME);
       goto leave;
     }
+
   addrspec = mailbox_from_userid (userid);
   if (!addrspec)
     {
diff --git a/tools/gpg-wks-server.c b/tools/gpg-wks-server.c
index 1633a20..f7aadba 100644
--- a/tools/gpg-wks-server.c
+++ b/tools/gpg-wks-server.c
@@ -127,7 +127,7 @@ static struct debug_flags_s debug_flags [] =
 struct server_ctx_s
 {
   char *fpr;
-  strlist_t mboxes;  /* List of addr-specs taken from the UIDs.  */
+  uidinfo_list_t mboxes;  /* List with addr-specs taken from the UIDs.  */
   unsigned int draft_version_2:1; /* Client supports the draft 2.  */
 };
 typedef struct server_ctx_s *server_ctx_t;
@@ -1092,7 +1092,7 @@ static gpg_error_t
 process_new_key (server_ctx_t ctx, estream_t key)
 {
   gpg_error_t err;
-  strlist_t sl;
+  uidinfo_list_t sl;
   const char *s;
   char *dname = NULL;
   char *nonce = NULL;
@@ -1101,7 +1101,7 @@ process_new_key (server_ctx_t ctx, estream_t key)
 
   /* First figure out the user id from the key.  */
   xfree (ctx->fpr);
-  free_strlist (ctx->mboxes);
+  free_uidinfo_list (ctx->mboxes);
   err = wks_list_key (key, &ctx->fpr, &ctx->mboxes);
   if (err)
     goto leave;
@@ -1114,14 +1114,17 @@ process_new_key (server_ctx_t ctx, estream_t key)
   log_info ("fingerprint: %s\n", ctx->fpr);
   for (sl = ctx->mboxes; sl; sl = sl->next)
     {
-      log_info ("  addr-spec: %s\n", sl->d);
+      if (sl->mbox)
+        log_info ("  addr-spec: %s\n", sl->mbox);
     }
 
   /* Walk over all user ids and send confirmation requests for those
    * we support.  */
   for (sl = ctx->mboxes; sl; sl = sl->next)
     {
-      s = strchr (sl->d, '@');
+      if (!sl->mbox)
+        continue;
+      s = strchr (sl->mbox, '@');
       log_assert (s && s[1]);
       xfree (dname);
       dname = make_filename_try (opt.directory, s+1, NULL);
@@ -1133,26 +1136,26 @@ process_new_key (server_ctx_t ctx, estream_t key)
 
       if (access (dname, W_OK))
         {
-          log_info ("skipping address '%s': Domain not configured\n", sl->d);
+          log_info ("skipping address '%s': Domain not configured\n", sl->mbox);
           continue;
         }
-      if (get_policy_flags (&policybuf, sl->d))
+      if (get_policy_flags (&policybuf, sl->mbox))
         {
-          log_info ("skipping address '%s': Bad policy flags\n", sl->d);
+          log_info ("skipping address '%s': Bad policy flags\n", sl->mbox);
           continue;
         }
 
       if (policybuf.auth_submit)
         {
           /* Bypass the confirmation stuff and publish the key as is.  */
-          log_info ("publishing address '%s'\n", sl->d);
+          log_info ("publishing address '%s'\n", sl->mbox);
           /* FIXME: We need to make sure that we do this only for the
            * address in the mail.  */
           log_debug ("auth-submit not yet working!\n");
         }
       else
         {
-          log_info ("storing address '%s'\n", sl->d);
+          log_info ("storing address '%s'\n", sl->mbox);
 
           xfree (nonce);
           xfree (fname);
@@ -1160,7 +1163,7 @@ process_new_key (server_ctx_t ctx, estream_t key)
           if (err)
             goto leave;
 
-          err = send_confirmation_request (ctx, sl->d, nonce, fname);
+          err = send_confirmation_request (ctx, sl->mbox, nonce, fname);
           if (err)
             goto leave;
         }
@@ -1313,7 +1316,7 @@ check_and_publish (server_ctx_t ctx, const char *address, const char *nonce)
   char *hash = NULL;
   const char *domain;
   const char *s;
-  strlist_t sl;
+  uidinfo_list_t sl;
   char shaxbuf[32]; /* Used for SHA-1 and SHA-256 */
 
   /* FIXME: There is a bug in name-value.c which adds white space for
@@ -1351,7 +1354,7 @@ check_and_publish (server_ctx_t ctx, const char *address, const char *nonce)
 
   /* We need to get the fingerprint from the key.  */
   xfree (ctx->fpr);
-  free_strlist (ctx->mboxes);
+  free_uidinfo_list (ctx->mboxes);
   err = wks_list_key (key, &ctx->fpr, &ctx->mboxes);
   if (err)
     goto leave;
@@ -1363,13 +1366,14 @@ check_and_publish (server_ctx_t ctx, const char *address, const char *nonce)
     }
   log_info ("fingerprint: %s\n", ctx->fpr);
   for (sl = ctx->mboxes; sl; sl = sl->next)
-    log_info ("  addr-spec: %s\n", sl->d);
+    if (sl->mbox)
+      log_info ("  addr-spec: %s\n", sl->mbox);
 
   /* Check that the key has 'address' as a user id.  We use
    * case-insensitive matching because the client is expected to
    * return the address verbatim.  */
   for (sl = ctx->mboxes; sl; sl = sl->next)
-    if (!strcmp (sl->d, address))
+    if (sl->mbox && !strcmp (sl->mbox, address))
       break;
   if (!sl)
     {
@@ -1565,7 +1569,7 @@ command_receive_cb (void *opaque, const char *mediatype,
     }
 
   xfree (ctx.fpr);
-  free_strlist (ctx.mboxes);
+  free_uidinfo_list (ctx.mboxes);
 
   return err;
 }
diff --git a/tools/gpg-wks.h b/tools/gpg-wks.h
index caea98e..7fc8d9a 100644
--- a/tools/gpg-wks.h
+++ b/tools/gpg-wks.h
@@ -69,11 +69,23 @@ struct policy_flags_s
 typedef struct policy_flags_s *policy_flags_t;
 
 
+/* An object to convey user ids of a key.  */
+struct uidinfo_list_s
+{
+  struct uidinfo_list_s *next;
+  char *mbox;  /* NULL or the malloced mailbox from UID.  */
+  char uid[1];
+};
+typedef struct uidinfo_list_s *uidinfo_list_t;
+
+
 
 /*-- wks-util.c --*/
 void wks_set_status_fd (int fd);
 void wks_write_status (int no, const char *format, ...) GPGRT_ATTR_PRINTF(2,3);
-gpg_error_t wks_list_key (estream_t key, char **r_fpr, strlist_t *r_mboxes);
+void free_uidinfo_list (uidinfo_list_t list);
+gpg_error_t wks_list_key (estream_t key, char **r_fpr,
+                          uidinfo_list_t *r_mboxes);
 gpg_error_t wks_send_mime (mime_maker_t mime);
 gpg_error_t wks_parse_policy (policy_flags_t flags, estream_t stream,
                               int ignore_unknown);
diff --git a/tools/wks-util.c b/tools/wks-util.c
index 45237b2..bc076a7 100644
--- a/tools/wks-util.c
+++ b/tools/wks-util.c
@@ -90,6 +90,48 @@ wks_write_status (int no, const char *format, ...)
 
 
 

+
+/* Append UID to LIST and return the new item.  On success LIST is
+ * updated.  On error ERRNO is set and NULL returned. */
+static uidinfo_list_t
+append_to_uidinfo_list (uidinfo_list_t *list, const char *uid)
+{
+  uidinfo_list_t r, sl;
+
+  sl = xtrymalloc (sizeof *sl + strlen (uid));
+  if (!sl)
+    return NULL;
+
+  strcpy (sl->uid, uid);
+  sl->mbox = mailbox_from_userid (uid);
+  sl->next = NULL;
+  if (!*list)
+    *list = sl;
+  else
+    {
+      for (r = *list; r->next; r = r->next )
+        ;
+      r->next = sl;
+    }
+  return sl;
+}
+
+
+/* Free the list of uid infos at LIST.  */
+void
+free_uidinfo_list (uidinfo_list_t list)
+{
+  while (list)
+    {
+      uidinfo_list_t tmp = list->next;
+      xfree (list->mbox);
+      xfree (list);
+      list = tmp;
+    }
+}
+
+
+

 /* Helper for wks_list_key.  */
 static void
 list_key_status_cb (void *opaque, const char *keyword, char *args)
@@ -105,7 +147,7 @@ list_key_status_cb (void *opaque, const char *keyword, char *args)
  * list of mailboxes at R_MBOXES.  Returns 0 on success; on error NULL
  * is stored at R_FPR and R_MBOXES and an error code is returned.  */
 gpg_error_t
-wks_list_key (estream_t key, char **r_fpr, strlist_t *r_mboxes)
+wks_list_key (estream_t key, char **r_fpr, uidinfo_list_t *r_mboxes)
 {
   gpg_error_t err;
   ccparray_t ccp;
@@ -118,9 +160,8 @@ wks_list_key (estream_t key, char **r_fpr, strlist_t *r_mboxes)
   char **fields = NULL;
   int nfields;
   int lnr;
-  char *mbox = NULL;
   char *fpr = NULL;
-  strlist_t mboxes = NULL;
+  uidinfo_list_t mboxes = NULL;
 
   *r_fpr = NULL;
   *r_mboxes = NULL;
@@ -232,9 +273,7 @@ wks_list_key (estream_t key, char **r_fpr, strlist_t *r_mboxes)
       else if (!strcmp (fields[0], "uid") && nfields > 9)
         {
           /* Fixme: Unescape fields[9] */
-          xfree (mbox);
-          mbox = mailbox_from_userid (fields[9]);
-          if (mbox && !append_to_strlist_try (&mboxes, mbox))
+          if (!append_to_uidinfo_list (&mboxes, fields[9]))
             {
               err = gpg_error_from_syserror ();
               goto leave;
@@ -255,8 +294,7 @@ wks_list_key (estream_t key, char **r_fpr, strlist_t *r_mboxes)
 
  leave:
   xfree (fpr);
-  xfree (mboxes);
-  xfree (mbox);
+  free_uidinfo_list (mboxes);
   xfree (fields);
   es_free (line);
   xfree (argv);

-----------------------------------------------------------------------

Summary of changes:
 doc/wks.texi           |   4 +-
 tools/gpg-wks-client.c | 151 +++++++++++++++++++++++++++++++++++++++++-----
 tools/gpg-wks-server.c |  50 +++++++---------
 tools/gpg-wks.h        |  17 +++++-
 tools/wks-util.c       | 160 ++++++++++++++++++++++++++++++++++++++++++++-----
 5 files changed, 322 insertions(+), 60 deletions(-)


hooks/post-receive
-- 
The GNU Privacy Guard
http://git.gnupg.org




More information about the Gnupg-commits mailing list