[Pkg-gnupg-commit] [gnupg2] 70/124: gpg: New command --quick-set-primary-uid.
Daniel Kahn Gillmor
dkg at fifthhorseman.net
Wed Apr 5 15:55:34 UTC 2017
This is an automated email from the git hooks/post-receive script.
dkg pushed a commit to branch experimental
in repository gnupg2.
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>
---
doc/gpg.texi | 21 ++++--
g10/gpg.c | 20 +++++-
g10/keyedit.c | 225 ++++++++++++++++++++++++++++++++++++----------------------
g10/main.h | 2 +
4 files changed, 174 insertions(+), 94 deletions(-)
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 --*/
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-gnupg/gnupg2.git
More information about the Pkg-gnupg-commit
mailing list