[git] GnuPG - branch, master, updated. gnupg-2.1.19-70-g74c1f30

by Werner Koch cvs at cvs.gnupg.org
Tue Mar 21 15:14:52 CET 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, master has been updated
       via  74c1f30ad6616186f0ab9dbaf34db6c17b1e40c4 (commit)
      from  483c1288a8f86dc6bf93d0d3f2865ecc246aecba (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 74c1f30ad6616186f0ab9dbaf34db6c17b1e40c4
Author: Werner Koch <wk at gnupg.org>
Date:   Tue Mar 21 14:47:21 2017 +0100

    gpg: New command --quick-set-primary-uid.
    
    * g10/gpg.c (aQuickSetPrimaryUid): New const.
    (opts): New command --quick-set-primary-uid.
    (main): Implement it.
    * g10/keyedit.c (keyedit_quick_adduid): Factor some code out to ...
    (quick_find_keyblock): new func.
    (keyedit_quick_revuid): Use quick_find_keyblock.
    (keyedit_quick_set_primary): New.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/doc/gpg.texi b/doc/gpg.texi
index 0e107ec..37e1ff1 100644
--- a/doc/gpg.texi
+++ b/doc/gpg.texi
@@ -1096,19 +1096,28 @@ on its form are applied.
 
 @item --quick-revoke-uid  @var{user-id} @var{user-id-to-revoke}
 @opindex quick-revoke-uid
-This command revokes a User ID on an existing key.  It cannot be used
-to revoke the last User ID on key (some non-revoked User ID must
+This command revokes a user ID on an existing key.  It cannot be used
+to revoke the last user ID on key (some non-revoked user ID must
 remain), with revocation reason ``User ID is no longer valid''.  If
 you want to specify a different revocation reason, or to supply
 supplementary revocation text, you should use the interactive
 sub-command @code{revuid} of @option{--edit-key}.
 
- at item --change-passphrase @var{user_id}
+ at item --quick-set-primary-uid  @var{user-id} @var{primary-user-id}
+ at opindex quick-set-primary-uid
+This command sets or updates the primary user ID flag on an existing
+key.  @var{user-id} specifies the key and @var{primary-user-id} the
+user ID which shall be flagged as the primary user ID.  The primary
+user ID flag is removed from all other user ids and the timestamp of
+all affected self-signatures is set one second ahead.
+
+
+ at item --change-passphrase @var{user-id}
 @opindex change-passphrase
- at itemx --passwd @var{user_id}
+ at itemx --passwd @var{user-id}
 @opindex passwd
 Change the passphrase of the secret key belonging to the certificate
-specified as @var{user_id}.  This is a shortcut for the sub-command
+specified as @var{user-id}.  This is a shortcut for the sub-command
 @code{passwd} of the edit key menu.
 
 @end table
@@ -1767,7 +1776,7 @@ when verifying signatures made by keys that are not on the local
 keyring.
 
 If the method "wkd" is included in the list of methods given to
- at option{auto-key-locate}, the Signer's User ID is part of the
+ at option{auto-key-locate}, the signer's user ID is part of the
 signature, and the option @option{--disable-signer-uid} is not used,
 the "wkd" method may also be used to retrieve a key.
 
diff --git a/g10/gpg.c b/g10/gpg.c
index eeda60f..b3d606b 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -1,7 +1,7 @@
 /* gpg.c - The GnuPG utility (main for gpg)
  * Copyright (C) 1998-2011 Free Software Foundation, Inc.
- * Copyright (C) 1997-2016 Werner Koch
- * Copyright (C) 2015-2016 g10 Code GmbH
+ * Copyright (C) 1997-2017 Werner Koch
+ * Copyright (C) 2015-2017 g10 Code GmbH
  *
  * This file is part of GnuPG.
  *
@@ -124,6 +124,7 @@ enum cmd_and_opt_values
     aQuickAddKey,
     aQuickRevUid,
     aQuickSetExpire,
+    aQuickSetPrimaryUid,
     aListConfig,
     aListGcryptConfig,
     aGPGConfList,
@@ -460,6 +461,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_c (aQuickRevUid,  "quick-revuid", "@"),
   ARGPARSE_c (aQuickSetExpire,  "quick-set-expire",
               N_("quickly set a new expiration date")),
+  ARGPARSE_c (aQuickSetPrimaryUid,  "quick-set-primary-uid", "@"),
   ARGPARSE_c (aFullKeygen,  "full-generate-key" ,
               N_("full featured key pair generation")),
   ARGPARSE_c (aFullKeygen,  "full-gen-key", "@"),
@@ -2581,6 +2583,7 @@ main (int argc, char **argv)
 	  case aQuickAddKey:
 	  case aQuickRevUid:
 	  case aQuickSetExpire:
+	  case aQuickSetPrimaryUid:
 	  case aExportOwnerTrust:
 	  case aImportOwnerTrust:
           case aRebuildKeydbCaches:
@@ -4002,6 +4005,7 @@ main (int argc, char **argv)
       case aQuickAddUid:
       case aQuickAddKey:
       case aQuickRevUid:
+      case aQuickSetPrimaryUid:
       case aFullKeygen:
       case aKeygen:
       case aImport:
@@ -4445,6 +4449,18 @@ main (int argc, char **argv)
         }
 	break;
 
+      case aQuickSetPrimaryUid:
+        {
+          const char *uid, *primaryuid;
+
+          if (argc != 2)
+            wrong_args ("--quick-set-primary-uid USER-ID PRIMARY-USER-ID");
+          uid = *argv++; argc--;
+          primaryuid = *argv++; argc--;
+          keyedit_quick_set_primary (ctrl, uid, primaryuid);
+        }
+	break;
+
       case aFastImport:
         opt.import_options |= IMPORT_FAST;
       case aImport:
diff --git a/g10/keyedit.c b/g10/keyedit.c
index 2b0f45e..9a7fe13 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -1,6 +1,6 @@
 /* keyedit.c - Edit properties of a key
  * Copyright (C) 1998-2010 Free Software Foundation, Inc.
- * Copyright (C) 1998-2016 Werner Koch
+ * Copyright (C) 1998-2017 Werner Koch
  * Copyright (C) 2015, 2016 g10 Code GmbH
  *
  * This file is part of GnuPG.
@@ -2860,36 +2860,28 @@ leave:
 }
 
 
-/* Unattended adding of a new keyid.  USERNAME specifies the
-   key. NEWUID is the new user id to add to the key.  */
-void
-keyedit_quick_adduid (ctrl_t ctrl, const char *username, const char *newuid)
+/* Helper for quick commands to find the keyblock for USERNAME.
+ * Returns on success the key database handle at R_KDBHD and the
+ * keyblock at R_KEYBLOCK.  */
+static gpg_error_t
+quick_find_keyblock (ctrl_t ctrl, const char *username,
+                     KEYDB_HANDLE *r_kdbhd, kbnode_t *r_keyblock)
 {
   gpg_error_t err;
   KEYDB_HANDLE kdbhd = NULL;
-  KEYDB_SEARCH_DESC desc;
   kbnode_t keyblock = NULL;
+  KEYDB_SEARCH_DESC desc;
   kbnode_t node;
-  char *uidstring = NULL;
 
-  uidstring = xstrdup (newuid);
-  trim_spaces (uidstring);
-  if (!*uidstring)
-    {
-      log_error ("%s\n", gpg_strerror (GPG_ERR_INV_USER_ID));
-      goto leave;
-    }
-
-#ifdef HAVE_W32_SYSTEM
-  /* See keyedit_menu for why we need this.  */
-  check_trustdb_stale (ctrl);
-#endif
+  *r_kdbhd = NULL;
+  *r_keyblock = NULL;
 
   /* Search the key; we don't want the whole getkey stuff here.  */
   kdbhd = keydb_new ();
   if (!kdbhd)
     {
       /* Note that keydb_new has already used log_error.  */
+      err = gpg_error_from_syserror ();
       goto leave;
     }
 
@@ -2917,24 +2909,65 @@ keyedit_quick_adduid (ctrl_t ctrl, const char *username, const char *newuid)
 
       if (!err)
         {
-          /* We require the secret primary key to add a UID.  */
+          /* We require the secret primary key to set the primary UID.  */
           node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
-          if (!node)
-            BUG ();
+          log_assert (node);
           err = agent_probe_secret_key (ctrl, node->pkt->pkt.public_key);
         }
     }
+  else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
+    err = gpg_error (GPG_ERR_NO_PUBKEY);
+
   if (err)
     {
-      log_error (_("secret key \"%s\" not found: %s\n"),
+      log_error (_("key \"%s\" not found: %s\n"),
                  username, gpg_strerror (err));
       goto leave;
     }
 
   fix_keyblock (&keyblock);
-
   merge_keys_and_selfsig (keyblock);
 
+  *r_keyblock = keyblock;
+  keyblock = NULL;
+  *r_kdbhd = kdbhd;
+  kdbhd = NULL;
+
+ leave:
+  release_kbnode (keyblock);
+  keydb_release (kdbhd);
+  return err;
+}
+
+
+/* Unattended adding of a new keyid.  USERNAME specifies the
+   key. NEWUID is the new user id to add to the key.  */
+void
+keyedit_quick_adduid (ctrl_t ctrl, const char *username, const char *newuid)
+{
+  gpg_error_t err;
+  KEYDB_HANDLE kdbhd = NULL;
+  kbnode_t keyblock = NULL;
+  char *uidstring = NULL;
+
+  uidstring = xstrdup (newuid);
+  trim_spaces (uidstring);
+  if (!*uidstring)
+    {
+      log_error ("%s\n", gpg_strerror (GPG_ERR_INV_USER_ID));
+      goto leave;
+    }
+
+#ifdef HAVE_W32_SYSTEM
+  /* See keyedit_menu for why we need this.  */
+  check_trustdb_stale (ctrl);
+#endif
+
+  /* Search the key; we don't want the whole getkey stuff here.  */
+  err = quick_find_keyblock (ctrl, username, &kdbhd, &keyblock);
+  if (err)
+    goto leave;
+
   if (menu_adduid (ctrl, keyblock, 0, NULL, uidstring))
     {
       err = keydb_update_keyblock (ctrl, kdbhd, keyblock);
@@ -2954,6 +2987,7 @@ keyedit_quick_adduid (ctrl_t ctrl, const char *username, const char *newuid)
   keydb_release (kdbhd);
 }
 
+
 /* Unattended revocation of a keyid.  USERNAME specifies the
    key. UIDTOREV is the user id revoke from the key.  */
 void
@@ -2961,7 +2995,6 @@ keyedit_quick_revuid (ctrl_t ctrl, const char *username, const char *uidtorev)
 {
   gpg_error_t err;
   KEYDB_HANDLE kdbhd = NULL;
-  KEYDB_SEARCH_DESC desc;
   kbnode_t keyblock = NULL;
   kbnode_t node;
   int modified = 0;
@@ -2974,65 +3007,20 @@ keyedit_quick_revuid (ctrl_t ctrl, const char *username, const char *uidtorev)
 #endif
 
   /* Search the key; we don't want the whole getkey stuff here.  */
-  kdbhd = keydb_new ();
-  if (!kdbhd)
-    {
-      /* Note that keydb_new has already used log_error.  */
-      goto leave;
-    }
-
-  err = classify_user_id (username, &desc, 1);
-  if (!err)
-    err = keydb_search (kdbhd, &desc, 1, NULL);
-  if (!err)
-    {
-      err = keydb_get_keyblock (kdbhd, &keyblock);
-      if (err)
-        {
-          log_error (_("error reading keyblock: %s\n"), gpg_strerror (err));
-          goto leave;
-        }
-      /* Now with the keyblock retrieved, search again to detect an
-         ambiguous specification.  We need to save the found state so
-         that we can do an update later.  */
-      keydb_push_found_state (kdbhd);
-      err = keydb_search (kdbhd, &desc, 1, NULL);
-      if (!err)
-        err = gpg_error (GPG_ERR_AMBIGUOUS_NAME);
-      else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
-        err = 0;
-      keydb_pop_found_state (kdbhd);
-
-      if (!err)
-        {
-          /* We require the secret primary key to revoke a UID.  */
-          node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
-          if (!node)
-            BUG ();
-          err = agent_probe_secret_key (ctrl, node->pkt->pkt.public_key);
-        }
-    }
+  err = quick_find_keyblock (ctrl, username, &kdbhd, &keyblock);
   if (err)
-    {
-      log_error (_("secret key \"%s\" not found: %s\n"),
-                 username, gpg_strerror (err));
-      goto leave;
-    }
-
-  fix_keyblock (&keyblock);
-  merge_keys_and_selfsig (keyblock);
+    goto leave;
 
   /* Too make sure that we do not revoke the last valid UID, we first
      count how many valid UIDs there are.  */
   valid_uids = 0;
   for (node = keyblock; node; node = node->next)
-    valid_uids +=
-      node->pkt->pkttype == PKT_USER_ID
-      && ! node->pkt->pkt.user_id->flags.revoked
-      && ! node->pkt->pkt.user_id->flags.expired;
+    valid_uids += (node->pkt->pkttype == PKT_USER_ID
+                   && !node->pkt->pkt.user_id->flags.revoked
+                   && !node->pkt->pkt.user_id->flags.expired);
 
+  /* Find the right UID. */
   revlen = strlen (uidtorev);
-  /* find the right UID */
   for (node = keyblock; node; node = node->next)
     {
       if (node->pkt->pkttype == PKT_USER_ID
@@ -3046,7 +3034,8 @@ keyedit_quick_revuid (ctrl_t ctrl, const char *username, const char *uidtorev)
               && ! node->pkt->pkt.user_id->flags.revoked
               && ! node->pkt->pkt.user_id->flags.expired)
             {
-              log_error (_("Cannot revoke the last valid user ID.\n"));
+              log_error (_("cannot revoke the last valid user ID.\n"));
+              err = gpg_error (GPG_ERR_INV_USER_ID);
               goto leave;
             }
 
@@ -3054,11 +3043,7 @@ keyedit_quick_revuid (ctrl_t ctrl, const char *username, const char *uidtorev)
           err = core_revuid (ctrl, keyblock, node, reason, &modified);
           release_revocation_reason_info (reason);
           if (err)
-            {
-              log_error (_("User ID revocation failed: %s\n"),
-                         gpg_strerror (err));
-              goto leave;
-            }
+            goto leave;
           err = keydb_update_keyblock (ctrl, kdbhd, keyblock);
           if (err)
             {
@@ -3066,13 +3051,81 @@ keyedit_quick_revuid (ctrl_t ctrl, const char *username, const char *uidtorev)
               goto leave;
             }
 
-          if (update_trust)
-            revalidation_mark ();
+          revalidation_mark ();
           goto leave;
         }
     }
+  err = gpg_error (GPG_ERR_NO_USER_ID);
 
-  log_error (_("User ID revocation failed: %s\n"), gpg_strerror (GPG_ERR_NOT_FOUND));
+
+ leave:
+  if (err)
+    log_error (_("revoking the user ID failed: %s\n"), gpg_strerror (err));
+  release_kbnode (keyblock);
+  keydb_release (kdbhd);
+}
+
+
+/* Unattended setting of the primary uid.  USERNAME specifies the key.
+   PRIMARYUID is the user id which shall be primary.  */
+void
+keyedit_quick_set_primary (ctrl_t ctrl, const char *username,
+                           const char *primaryuid)
+{
+  gpg_error_t err;
+  KEYDB_HANDLE kdbhd = NULL;
+  kbnode_t keyblock = NULL;
+  kbnode_t node;
+  size_t primaryuidlen;
+  int any;
+
+#ifdef HAVE_W32_SYSTEM
+  /* See keyedit_menu for why we need this.  */
+  check_trustdb_stale (ctrl);
+#endif
+
+  err = quick_find_keyblock (ctrl, username, &kdbhd, &keyblock);
+  if (err)
+    goto leave;
+
+  /* Find and mark the UID - we mark only the first valid one. */
+  primaryuidlen = strlen (primaryuid);
+  any = 0;
+  for (node = keyblock; node; node = node->next)
+    {
+      if (node->pkt->pkttype == PKT_USER_ID
+          && !any
+          && !node->pkt->pkt.user_id->flags.revoked
+          && !node->pkt->pkt.user_id->flags.expired
+          && primaryuidlen == node->pkt->pkt.user_id->len
+          && !memcmp (node->pkt->pkt.user_id->name, primaryuid, primaryuidlen))
+        {
+          node->flag |= NODFLG_SELUID;
+          any = 1;
+        }
+      else
+        node->flag &= ~NODFLG_SELUID;
+    }
+
+  if (!any)
+    err = gpg_error (GPG_ERR_NO_USER_ID);
+  else if (menu_set_primary_uid (keyblock))
+    {
+      merge_keys_and_selfsig (keyblock);
+      err = keydb_update_keyblock (ctrl, kdbhd, keyblock);
+      if (err)
+        {
+          log_error (_("update failed: %s\n"), gpg_strerror (err));
+          goto leave;
+        }
+      revalidation_mark ();
+    }
+  else
+    err = gpg_error (GPG_ERR_GENERAL);
+
+  if (err)
+    log_error (_("setting the primary user ID failed: %s\n"),
+               gpg_strerror (err));
 
  leave:
   release_kbnode (keyblock);
@@ -5205,7 +5258,7 @@ change_primary_uid_cb (PKT_signature * sig, void *opaque)
 
 /*
  * Set the primary uid flag for the selected UID.  We will also reset
- * all other primary uid flags.  For this to work with have to update
+ * all other primary uid flags.  For this to work we have to update
  * all the signature timestamps.  If we would do this with the current
  * time, we lose quite a lot of information, so we use a kludge to
  * do this: Just increment the timestamp by one second which is
diff --git a/g10/main.h b/g10/main.h
index c9c3454..32d323b 100644
--- a/g10/main.h
+++ b/g10/main.h
@@ -300,6 +300,8 @@ void keyedit_quick_sign (ctrl_t ctrl, const char *fpr,
                          strlist_t uids, strlist_t locusr, int local);
 void keyedit_quick_set_expire (ctrl_t ctrl,
                                const char *fpr, const char *expirestr);
+void keyedit_quick_set_primary (ctrl_t ctrl, const char *username,
+                                const char *primaryuid);
 void show_basic_key_info (KBNODE keyblock);
 
 /*-- keygen.c --*/

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

Summary of changes:
 doc/gpg.texi  |  21 ++++--
 g10/gpg.c     |  20 +++++-
 g10/keyedit.c | 225 ++++++++++++++++++++++++++++++++++++----------------------
 g10/main.h    |   2 +
 4 files changed, 174 insertions(+), 94 deletions(-)


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




More information about the Gnupg-commits mailing list