1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

gpg: New option --quick-set-expire.

* g10/gpg.c (aQuickSetExpire): New.
(opts): New option --quick-set-expire.
(main): Implement option.
* g10/keyedit.c (menu_expire): Add args FORCE_MAINKEY and
NEWEXPIRATION.  Change semantics of the return value.  Change caller.
(keyedit_quick_set_expire): New.
--

This patch partly solves
GnuPG-bug-id: 2701
This commit is contained in:
Werner Koch 2016-12-05 10:58:39 +01:00
parent fae4d06b0c
commit 41b3d0975d
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
5 changed files with 148 additions and 26 deletions

View File

@ -632,6 +632,12 @@ supplied passphrase is used for the new key and the agent does not ask
for it. To create a key without any protection @code{--passphrase ''} for it. To create a key without any protection @code{--passphrase ''}
may be used. may be used.
@item --quick-set-expire @code{fpr} @code{expire}
@opindex quick-set-expire
Directly set the expiration time of the primary key to @code{expire}.
To remove the expiration time @code{0} can be used.
@item --quick-addkey @code{fpr} [@code{algo} [@code{usage} [@code{expire}]]] @item --quick-addkey @code{fpr} [@code{algo} [@code{usage} [@code{expire}]]]
@opindex quick-addkey @opindex quick-addkey
Directly add a subkey to the key identified by the fingerprint Directly add a subkey to the key identified by the fingerprint

View File

@ -1144,9 +1144,9 @@ print_status_exported (PKT_public_key *pk)
/* /*
* Receive a secret key from agent specified by HEXGRIP. * Receive a secret key from agent specified by HEXGRIP.
* *
* Since the key data from agant is encrypted, decrypt it by CIPHERHD. * Since the key data from the agent is encrypted, decrypt it using
* Then, parse the decrypted key data in transfer format, and put * CIPHERHD context. Then, parse the decrypted key data into transfer
* secret parameters into PK. * format, and put secret parameters into PK.
* *
* If CLEARTEXT is 0, store the secret key material * If CLEARTEXT is 0, store the secret key material
* passphrase-protected. Otherwise, store secret key material in the * passphrase-protected. Otherwise, store secret key material in the

View File

@ -123,6 +123,7 @@ enum cmd_and_opt_values
aQuickAddUid, aQuickAddUid,
aQuickAddKey, aQuickAddKey,
aQuickRevUid, aQuickRevUid,
aQuickSetExpire,
aListConfig, aListConfig,
aListGcryptConfig, aListGcryptConfig,
aGPGConfList, aGPGConfList,
@ -448,6 +449,8 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_c (aQuickAddKey, "quick-addkey", "@"), ARGPARSE_c (aQuickAddKey, "quick-addkey", "@"),
ARGPARSE_c (aQuickRevUid, "quick-revuid", ARGPARSE_c (aQuickRevUid, "quick-revuid",
N_("quickly revoke a user-id")), N_("quickly revoke a user-id")),
ARGPARSE_c (aQuickSetExpire, "quick-set-expire",
N_("quickly set a new expiration date")),
ARGPARSE_c (aFullKeygen, "full-gen-key" , ARGPARSE_c (aFullKeygen, "full-gen-key" ,
N_("full featured key pair generation")), N_("full featured key pair generation")),
ARGPARSE_c (aGenRevoke, "gen-revoke",N_("generate a revocation certificate")), ARGPARSE_c (aGenRevoke, "gen-revoke",N_("generate a revocation certificate")),
@ -2549,6 +2552,7 @@ main (int argc, char **argv)
case aQuickAddUid: case aQuickAddUid:
case aQuickAddKey: case aQuickAddKey:
case aQuickRevUid: case aQuickRevUid:
case aQuickSetExpire:
case aExportOwnerTrust: case aExportOwnerTrust:
case aImportOwnerTrust: case aImportOwnerTrust:
case aRebuildKeydbCaches: case aRebuildKeydbCaches:
@ -4384,6 +4388,18 @@ main (int argc, char **argv)
} }
break; break;
case aQuickSetExpire:
{
const char *x_fpr, *x_expire;
if (argc != 2)
wrong_args ("--quick-set-exipre FINGERPRINT EXPIRE");
x_fpr = *argv++; argc--;
x_expire = *argv++; argc--;
keyedit_quick_set_expire (ctrl, x_fpr, x_expire);
}
break;
case aFastImport: case aFastImport:
opt.import_options |= IMPORT_FAST; opt.import_options |= IMPORT_FAST;
case aImport: case aImport:

View File

@ -69,7 +69,8 @@ static int menu_delsig (KBNODE pub_keyblock);
static int menu_clean (KBNODE keyblock, int self_only); static int menu_clean (KBNODE keyblock, int self_only);
static void menu_delkey (KBNODE pub_keyblock); static void menu_delkey (KBNODE pub_keyblock);
static int menu_addrevoker (ctrl_t ctrl, kbnode_t pub_keyblock, int sensitive); static int menu_addrevoker (ctrl_t ctrl, kbnode_t pub_keyblock, int sensitive);
static int menu_expire (KBNODE pub_keyblock); static gpg_error_t menu_expire (kbnode_t pub_keyblock,
int force_mainkey, u32 newexpiration);
static int menu_changeusage (kbnode_t keyblock); static int menu_changeusage (kbnode_t keyblock);
static int menu_backsign (KBNODE pub_keyblock); static int menu_backsign (KBNODE pub_keyblock);
static int menu_set_primary_uid (KBNODE pub_keyblock); static int menu_set_primary_uid (KBNODE pub_keyblock);
@ -2599,7 +2600,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
break; break;
case cmdEXPIRE: case cmdEXPIRE:
if (menu_expire (keyblock)) if (gpg_err_code (menu_expire (keyblock, 0, 0)) == GPG_ERR_TRUE)
{ {
merge_keys_and_selfsig (keyblock); merge_keys_and_selfsig (keyblock);
run_subkey_warnings = 1; run_subkey_warnings = 1;
@ -3342,6 +3343,86 @@ keyedit_quick_addkey (ctrl_t ctrl, const char *fpr, const char *algostr,
} }
/* Unattended expiration setting function for the main key.
*
*/
void
keyedit_quick_set_expire (ctrl_t ctrl, const char *fpr, const char *expirestr)
{
gpg_error_t err;
kbnode_t keyblock;
KEYDB_HANDLE kdbhd;
int modified = 0;
PKT_public_key *pk;
u32 expire;
#ifdef HAVE_W32_SYSTEM
/* See keyedit_menu for why we need this. */
check_trustdb_stale (ctrl);
#endif
/* We require a fingerprint because only this uniquely identifies a
* key and may thus be used to select a key for unattended
* expiration setting. */
err = find_by_primary_fpr (ctrl, fpr, &keyblock, &kdbhd);
if (err)
goto leave;
if (fix_keyblock (&keyblock))
modified++;
pk = keyblock->pkt->pkt.public_key;
if (pk->flags.revoked)
{
if (!opt.verbose)
show_key_with_all_names (ctrl, es_stdout, keyblock, 0, 0, 0, 0, 0, 1);
log_error ("%s%s", _("Key is revoked."), "\n");
err = gpg_error (GPG_ERR_CERT_REVOKED);
goto leave;
}
expire = parse_expire_string (expirestr);
if (expire == (u32)-1 )
{
log_error (_("'%s' is not a valid expiration time\n"), expirestr);
err = gpg_error (GPG_ERR_INV_VALUE);
goto leave;
}
if (expire)
expire += make_timestamp ();
/* Set the new expiration date. */
err = menu_expire (keyblock, 1, expire);
if (gpg_err_code (err) == GPG_ERR_TRUE)
modified = 1;
else if (err)
goto leave;
es_fflush (es_stdout);
/* Store. */
if (modified)
{
err = keydb_update_keyblock (ctrl, kdbhd, keyblock);
if (err)
{
log_error (_("update failed: %s\n"), gpg_strerror (err));
goto leave;
}
if (update_trust)
revalidation_mark ();
}
else
log_info (_("Key not changed so no update needed.\n"));
leave:
release_kbnode (keyblock);
keydb_release (kdbhd);
if (err)
write_status_error ("set_expire", err);
}
static void static void
tty_print_notations (int indent, PKT_signature * sig) tty_print_notations (int indent, PKT_signature * sig)
@ -4736,36 +4817,50 @@ fail:
} }
static int /* With FORCE_MAINKEY cleared this function handles the interactive
menu_expire (KBNODE pub_keyblock) * menu option "expire". With FORCE_MAINKEY set this functions only
* sets the expiration date of the primary key to NEWEXPIRATION and
* avoid all interactivity. Retirns 0 if nothing was done,
* GPG_ERR_TRUE if the key was modified, or any other error code. */
static gpg_error_t
menu_expire (kbnode_t pub_keyblock, int force_mainkey, u32 newexpiration)
{ {
int n1, signumber, rc; int signumber, rc;
u32 expiredate; u32 expiredate;
int mainkey = 0; int mainkey = 0;
PKT_public_key *main_pk, *sub_pk; PKT_public_key *main_pk, *sub_pk;
PKT_user_id *uid; PKT_user_id *uid;
KBNODE node; kbnode_t node;
u32 keyid[2]; u32 keyid[2];
n1 = count_selected_keys (pub_keyblock); if (force_mainkey)
if (n1 > 1)
{ {
if (!cpr_get_answer_is_yes mainkey = 1;
("keyedit.expire_multiple_subkeys.okay", expiredate = newexpiration;
_("Are you sure you want to change the"
" expiration time for multiple subkeys? (y/N) ")))
return 0;
} }
else if (n1)
tty_printf (_("Changing expiration time for a subkey.\n"));
else else
{ {
tty_printf (_("Changing expiration time for the primary key.\n")); int n1 = count_selected_keys (pub_keyblock);
mainkey = 1; if (n1 > 1)
no_primary_warning (pub_keyblock); {
if (!cpr_get_answer_is_yes
("keyedit.expire_multiple_subkeys.okay",
_("Are you sure you want to change the"
" expiration time for multiple subkeys? (y/N) ")))
return gpg_error (GPG_ERR_CANCELED);;
}
else if (n1)
tty_printf (_("Changing expiration time for a subkey.\n"));
else
{
tty_printf (_("Changing expiration time for the primary key.\n"));
mainkey = 1;
no_primary_warning (pub_keyblock);
}
expiredate = ask_expiredate ();
} }
expiredate = ask_expiredate ();
/* Now we can actually change the self-signature(s) */ /* Now we can actually change the self-signature(s) */
main_pk = sub_pk = NULL; main_pk = sub_pk = NULL;
@ -4781,7 +4876,7 @@ menu_expire (KBNODE pub_keyblock)
} }
else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
{ {
if (node->flag & NODFLG_SELKEY) if ((node->flag & NODFLG_SELKEY) && !force_mainkey)
{ {
sub_pk = node->pkt->pkt.public_key; sub_pk = node->pkt->pkt.public_key;
sub_pk->expiredate = expiredate; sub_pk->expiredate = expiredate;
@ -4795,6 +4890,7 @@ menu_expire (KBNODE pub_keyblock)
&& (mainkey || sub_pk)) && (mainkey || sub_pk))
{ {
PKT_signature *sig = node->pkt->pkt.signature; PKT_signature *sig = node->pkt->pkt.signature;
if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
&& ((mainkey && uid && ((mainkey && uid
&& uid->created && (sig->sig_class & ~3) == 0x10) && uid->created && (sig->sig_class & ~3) == 0x10)
@ -4812,7 +4908,7 @@ menu_expire (KBNODE pub_keyblock)
{ {
log_info log_info
(_("You can't change the expiration date of a v3 key\n")); (_("You can't change the expiration date of a v3 key\n"));
return 0; return gpg_error (GPG_ERR_LEGACY_KEY);
} }
if (mainkey) if (mainkey)
@ -4827,7 +4923,9 @@ menu_expire (KBNODE pub_keyblock)
{ {
log_error ("make_keysig_packet failed: %s\n", log_error ("make_keysig_packet failed: %s\n",
gpg_strerror (rc)); gpg_strerror (rc));
return 0; if (gpg_err_code (rc) == GPG_ERR_TRUE)
rc = GPG_ERR_GENERAL;
return rc;
} }
/* Replace the packet. */ /* Replace the packet. */
@ -4843,7 +4941,7 @@ menu_expire (KBNODE pub_keyblock)
} }
update_trust = 1; update_trust = 1;
return 1; return gpg_error (GPG_ERR_TRUE);
} }

View File

@ -295,6 +295,8 @@ void keyedit_quick_revuid (ctrl_t ctrl, const char *username,
const char *uidtorev); const char *uidtorev);
void keyedit_quick_sign (ctrl_t ctrl, const char *fpr, void keyedit_quick_sign (ctrl_t ctrl, const char *fpr,
strlist_t uids, strlist_t locusr, int local); strlist_t uids, strlist_t locusr, int local);
void keyedit_quick_set_expire (ctrl_t ctrl,
const char *fpr, const char *expirestr);
void show_basic_key_info (KBNODE keyblock); void show_basic_key_info (KBNODE keyblock);
/*-- keygen.c --*/ /*-- keygen.c --*/