mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
gpg: New command --quick-adduid.
* g10/keygen.c (ask_user_id): Factor some code out to ... (uid_already_in_keyblock): new. (generate_user_id): Add arg UIDSTR. Fix leaked P. * g10/keyedit.c (menu_adduid): Add new arg uidstring. Adjust caller. (keyedit_quick_adduid): New. * g10/gpg.c (aQuickAddUid): New. (opts): Add command --quick-adduid. (main): Implement that. -- GnuPG-bug-id: 1956 Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
3c439c0447
commit
64e809b791
12
doc/gpg.texi
12
doc/gpg.texi
@ -568,7 +568,7 @@ This section explains the main commands for key management
|
||||
@ifset gpgtwoone
|
||||
@item --quick-gen-key @code{user-id}
|
||||
@opindex quick-gen-key
|
||||
This is simple command to generate a standard key with one user id.
|
||||
This is a simple command to generate a standard key with one user id.
|
||||
In contrast to @option{--gen-key} the key is generated directly
|
||||
without the need to answer a bunch of prompts. Unless the option
|
||||
@option{--yes} is given, the key creation will be canceled if the
|
||||
@ -945,6 +945,16 @@ Its intended use is to help unattended key signing by utilizing a list
|
||||
of verified fingerprints.
|
||||
@end ifset
|
||||
|
||||
@ifset gpgtwoone
|
||||
@item --quick-adduid @var{user-id} @var{new-user-id}
|
||||
@opindex quick-adduid
|
||||
This command adds a new user id to an existing key. In contrast to
|
||||
the interactive sub-command @code{adduid} of @option{--edit-key} the
|
||||
@var{new-user-id} is added verbatim with only leading and trailing
|
||||
white space removed, it is expected to be UTF-8 encoded, and no checks
|
||||
on its form are applied.
|
||||
@end ifset
|
||||
|
||||
@item --passwd @var{user_id}
|
||||
@opindex passwd
|
||||
Change the passphrase of the secret key belonging to the certificate
|
||||
|
17
g10/gpg.c
17
g10/gpg.c
@ -116,6 +116,7 @@ enum cmd_and_opt_values
|
||||
aLSignKey,
|
||||
aQuickSignKey,
|
||||
aQuickLSignKey,
|
||||
aQuickAddUid,
|
||||
aListConfig,
|
||||
aListGcryptConfig,
|
||||
aGPGConfList,
|
||||
@ -414,6 +415,8 @@ static ARGPARSE_OPTS opts[] = {
|
||||
N_("generate a new key pair")),
|
||||
ARGPARSE_c (aQuickKeygen, "quick-gen-key" ,
|
||||
N_("quickly generate a new key pair")),
|
||||
ARGPARSE_c (aQuickAddUid, "quick-adduid",
|
||||
N_("quickly add a new user-id")),
|
||||
ARGPARSE_c (aFullKeygen, "full-gen-key" ,
|
||||
N_("full featured key pair generation")),
|
||||
ARGPARSE_c (aGenRevoke, "gen-revoke",N_("generate a revocation certificate")),
|
||||
@ -2327,6 +2330,7 @@ main (int argc, char **argv)
|
||||
case aLSignKey:
|
||||
case aStore:
|
||||
case aQuickKeygen:
|
||||
case aQuickAddUid:
|
||||
case aExportOwnerTrust:
|
||||
case aImportOwnerTrust:
|
||||
case aRebuildKeydbCaches:
|
||||
@ -3604,6 +3608,7 @@ main (int argc, char **argv)
|
||||
case aDeleteSecretKeys:
|
||||
case aDeleteSecretAndPublicKeys:
|
||||
case aQuickKeygen:
|
||||
case aQuickAddUid:
|
||||
case aFullKeygen:
|
||||
case aKeygen:
|
||||
case aImport:
|
||||
@ -3924,6 +3929,18 @@ main (int argc, char **argv)
|
||||
}
|
||||
break;
|
||||
|
||||
case aQuickAddUid:
|
||||
{
|
||||
const char *uid, *newuid;
|
||||
|
||||
if (argc != 2)
|
||||
wrong_args ("--quick-adduid USER-ID NEW-USER-ID");
|
||||
uid = *argv++; argc--;
|
||||
newuid = *argv++; argc--;
|
||||
keyedit_quick_adduid (ctrl, uid, newuid);
|
||||
}
|
||||
break;
|
||||
|
||||
case aFastImport:
|
||||
opt.import_options |= IMPORT_FAST;
|
||||
case aImport:
|
||||
|
118
g10/keyedit.c
118
g10/keyedit.c
@ -1,7 +1,6 @@
|
||||
/* keyedit.c - keyedit stuff
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
|
||||
* 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2013, 2014 Werner Koch
|
||||
/* keyedit.c - Edit properties of a key
|
||||
* Copyright (C) 1998-2010 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998-2015 Werner Koch
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -59,7 +58,8 @@ static void show_key_with_all_names (estream_t fp,
|
||||
int nowarn);
|
||||
static void show_key_and_fingerprint (KBNODE keyblock);
|
||||
static void subkey_expire_warning (kbnode_t keyblock);
|
||||
static int menu_adduid (KBNODE keyblock, int photo, const char *photo_name);
|
||||
static int menu_adduid (KBNODE keyblock, int photo, const char *photo_name,
|
||||
const char *uidstr);
|
||||
static void menu_deluid (KBNODE pub_keyblock);
|
||||
static int menu_delsig (KBNODE pub_keyblock);
|
||||
static int menu_clean (KBNODE keyblock, int self_only);
|
||||
@ -1757,7 +1757,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
|
||||
photo = 1;
|
||||
/* fall through */
|
||||
case cmdADDUID:
|
||||
if (menu_adduid (keyblock, photo, arg_string))
|
||||
if (menu_adduid (keyblock, photo, arg_string, NULL))
|
||||
{
|
||||
update_trust = 1;
|
||||
redisplay = 1;
|
||||
@ -2288,6 +2288,93 @@ 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)
|
||||
{
|
||||
gpg_error_t err;
|
||||
KEYDB_HANDLE kdbhd = NULL;
|
||||
KEYDB_SEARCH_DESC desc;
|
||||
kbnode_t keyblock = NULL;
|
||||
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 ();
|
||||
#endif
|
||||
|
||||
/* Search the key; we don't want the whole getkey stuff here. */
|
||||
kdbhd = keydb_new ();
|
||||
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 add a UID. */
|
||||
node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
|
||||
if (!node)
|
||||
BUG ();
|
||||
err = agent_probe_secret_key (ctrl, node->pkt->pkt.public_key);
|
||||
}
|
||||
}
|
||||
if (err)
|
||||
{
|
||||
log_error (_("secret key \"%s\" not found: %s\n"),
|
||||
username, gpg_strerror (err));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
fix_keyblock (&keyblock);
|
||||
|
||||
if (menu_adduid (keyblock, 0, NULL, uidstring))
|
||||
{
|
||||
err = keydb_update_keyblock (kdbhd, keyblock);
|
||||
if (err)
|
||||
{
|
||||
log_error (_("update failed: %s\n"), gpg_strerror (err));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (update_trust)
|
||||
revalidation_mark ();
|
||||
}
|
||||
|
||||
leave:
|
||||
xfree (uidstring);
|
||||
release_kbnode (keyblock);
|
||||
keydb_release (kdbhd);
|
||||
}
|
||||
|
||||
|
||||
/* Unattended key signing function. If the key specifified by FPR is
|
||||
availabale and FPR is the primary fingerprint all user ids of the
|
||||
user ids of the key are signed using the default signing key. If
|
||||
@ -3225,11 +3312,15 @@ subkey_expire_warning (kbnode_t keyblock)
|
||||
|
||||
|
||||
/*
|
||||
* Ask for a new user id, add the self-signature and update the keyblock.
|
||||
* Return true if there is a new user id
|
||||
* Ask for a new user id, add the self-signature, and update the
|
||||
* keyblock. If UIDSTRING is not NULL the user ID is generated
|
||||
* unattended using that string. UIDSTRING is expected to be utf-8
|
||||
* encoded and white space trimmed. Returns true if there is a new
|
||||
* user id.
|
||||
*/
|
||||
static int
|
||||
menu_adduid (KBNODE pub_keyblock, int photo, const char *photo_name)
|
||||
menu_adduid (kbnode_t pub_keyblock, int photo, const char *photo_name,
|
||||
const char *uidstring)
|
||||
{
|
||||
PKT_user_id *uid;
|
||||
PKT_public_key *pk = NULL;
|
||||
@ -3239,6 +3330,9 @@ menu_adduid (KBNODE pub_keyblock, int photo, const char *photo_name)
|
||||
KBNODE pub_where = NULL;
|
||||
gpg_error_t err;
|
||||
|
||||
if (photo && uidstring)
|
||||
return 0; /* Not allowed. */
|
||||
|
||||
for (node = pub_keyblock; node; pub_where = node, node = node->next)
|
||||
{
|
||||
if (node->pkt->pkttype == PKT_PUBLIC_KEY)
|
||||
@ -3291,9 +3385,13 @@ menu_adduid (KBNODE pub_keyblock, int photo, const char *photo_name)
|
||||
uid = generate_photo_id (pk, photo_name);
|
||||
}
|
||||
else
|
||||
uid = generate_user_id (pub_keyblock);
|
||||
uid = generate_user_id (pub_keyblock, uidstring);
|
||||
if (!uid)
|
||||
{
|
||||
if (uidstring)
|
||||
log_error ("%s", _("Such a user ID already exists on this key!\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = make_keysig_packet (&sig, pk, uid, NULL, pk, 0x13, 0, 0, 0,
|
||||
keygen_add_std_prefs, pk, NULL);
|
||||
|
54
g10/keygen.c
54
g10/keygen.c
@ -2446,6 +2446,24 @@ uid_from_string (const char *string)
|
||||
}
|
||||
|
||||
|
||||
/* Return true if the user id UID already exists in the keyblock. */
|
||||
static int
|
||||
uid_already_in_keyblock (kbnode_t keyblock, const char *uid)
|
||||
{
|
||||
PKT_user_id *uidpkt = uid_from_string (uid);
|
||||
kbnode_t node;
|
||||
int result = 0;
|
||||
|
||||
for (node=keyblock; node && !result; node=node->next)
|
||||
if (!is_deleted_kbnode (node)
|
||||
&& node->pkt->pkttype == PKT_USER_ID
|
||||
&& !cmp_user_ids (uidpkt, node->pkt->pkt.user_id))
|
||||
result = 1;
|
||||
free_user_id (uidpkt);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* Ask for a user ID. With a MODE of 1 an extra help prompt is
|
||||
printed for use during a new key creation. If KEYBLOCK is not NULL
|
||||
the function prevents the creation of an already existing user
|
||||
@ -2583,17 +2601,11 @@ ask_user_id (int mode, int full, KBNODE keyblock)
|
||||
|
||||
if (!fail && keyblock)
|
||||
{
|
||||
PKT_user_id *uidpkt = uid_from_string (uid);
|
||||
KBNODE node;
|
||||
|
||||
for (node=keyblock; node && !fail; node=node->next)
|
||||
if (!is_deleted_kbnode (node)
|
||||
&& node->pkt->pkttype == PKT_USER_ID
|
||||
&& !cmp_user_ids (uidpkt, node->pkt->pkt.user_id))
|
||||
fail = 1;
|
||||
if (fail)
|
||||
if (uid_already_in_keyblock (keyblock, uid))
|
||||
{
|
||||
tty_printf (_("Such a user ID already exists on this key!\n"));
|
||||
free_user_id (uidpkt);
|
||||
fail = 1;
|
||||
}
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
@ -2767,16 +2779,32 @@ do_create (int algo, unsigned int nbits, const char *curve, KBNODE pub_root,
|
||||
|
||||
/* Generate a new user id packet or return NULL if canceled. If
|
||||
KEYBLOCK is not NULL the function prevents the creation of an
|
||||
already existing user ID. */
|
||||
already existing user ID. If UIDSTR is not NULL the user is not
|
||||
asked but UIDSTR is used to create the user id packet; if the user
|
||||
id already exists NULL is returned. UIDSTR is expected to be utf-8
|
||||
encoded and should have already been checked for a valid length
|
||||
etc. */
|
||||
PKT_user_id *
|
||||
generate_user_id (KBNODE keyblock)
|
||||
generate_user_id (KBNODE keyblock, const char *uidstr)
|
||||
{
|
||||
PKT_user_id *uid;
|
||||
char *p;
|
||||
|
||||
if (uidstr)
|
||||
{
|
||||
if (uid_already_in_keyblock (keyblock, uidstr))
|
||||
return NULL; /* Already exists. */
|
||||
uid = uid_from_string (uidstr);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = ask_user_id (1, 1, keyblock);
|
||||
if (!p)
|
||||
return NULL; /* Canceled. */
|
||||
return uid_from_string (p);
|
||||
uid = uid_from_string (p);
|
||||
xfree (p);
|
||||
}
|
||||
return uid;
|
||||
}
|
||||
|
||||
|
||||
|
@ -247,6 +247,8 @@ gpg_error_t delete_keys (strlist_t names, int secret, int allow_both);
|
||||
void keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
|
||||
strlist_t commands, int quiet, int seckey_check );
|
||||
void keyedit_passwd (ctrl_t ctrl, const char *username);
|
||||
void keyedit_quick_adduid (ctrl_t ctrl, const char *username,
|
||||
const char *newuid);
|
||||
void keyedit_quick_sign (ctrl_t ctrl, const char *fpr,
|
||||
strlist_t uids, strlist_t locusr, int local);
|
||||
void show_basic_key_info (KBNODE keyblock);
|
||||
|
@ -544,6 +544,6 @@ int update_keysig_packet( PKT_signature **ret_sig,
|
||||
void *opaque );
|
||||
|
||||
/*-- keygen.c --*/
|
||||
PKT_user_id *generate_user_id (KBNODE keyblock);
|
||||
PKT_user_id *generate_user_id (kbnode_t keyblock, const char *uidstr);
|
||||
|
||||
#endif /*G10_PACKET_H*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user