mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-17 15:44:34 +02:00
gpg: Extend --quick-set-expire to allow subkey expiration setting.
* g10/keyedit.c (keyedit_quick_set_expire): Add new arg subkeyfprs. (menu_expire): Rename arg force_mainkey to unattended and allow unattended changing of subkey expiration. * g10/gpg.c (main): Extend --quick-set-expire. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
e888f7af65
commit
b55b72bb81
12
doc/gpg.texi
12
doc/gpg.texi
@ -663,10 +663,16 @@ 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}
|
@item --quick-set-expire @var{fpr} @var{expire} [*|@var{subfprs}]
|
||||||
@opindex quick-set-expire
|
@opindex quick-set-expire
|
||||||
Directly set the expiration time of the primary key to @code{expire}.
|
With two arguments given, directly set the expiration time of the
|
||||||
To remove the expiration time @code{0} can be used.
|
primary key identified by @var{fpr} to @var{expire}. To remove the
|
||||||
|
expiration time @code{0} can be used. With three arguments and the
|
||||||
|
third given as an asterisk, the expiration time of all non-revoked and
|
||||||
|
not yet expired subkeys are set to @var{expire}. With more than two
|
||||||
|
arguments and a list of fingerprints given for @var{subfprs}, all
|
||||||
|
non-revoked subkeys matching these fingerprints are set to
|
||||||
|
@var{expire}.
|
||||||
|
|
||||||
|
|
||||||
@item --quick-add-key @code{fpr} [@code{algo} [@code{usage} [@code{expire}]]]
|
@item --quick-add-key @code{fpr} [@code{algo} [@code{usage} [@code{expire}]]]
|
||||||
|
@ -4491,11 +4491,11 @@ main (int argc, char **argv)
|
|||||||
{
|
{
|
||||||
const char *x_fpr, *x_expire;
|
const char *x_fpr, *x_expire;
|
||||||
|
|
||||||
if (argc != 2)
|
if (argc < 2)
|
||||||
wrong_args ("--quick-set-exipre FINGERPRINT EXPIRE");
|
wrong_args ("--quick-set-exipre FINGERPRINT EXPIRE [SUBKEY-FPRS]");
|
||||||
x_fpr = *argv++; argc--;
|
x_fpr = *argv++; argc--;
|
||||||
x_expire = *argv++; argc--;
|
x_expire = *argv++; argc--;
|
||||||
keyedit_quick_set_expire (ctrl, x_fpr, x_expire);
|
keyedit_quick_set_expire (ctrl, x_fpr, x_expire, argv);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
125
g10/keyedit.c
125
g10/keyedit.c
@ -73,7 +73,7 @@ static int menu_clean (ctrl_t ctrl, kbnode_t 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 gpg_error_t menu_expire (ctrl_t ctrl, kbnode_t pub_keyblock,
|
static gpg_error_t menu_expire (ctrl_t ctrl, kbnode_t pub_keyblock,
|
||||||
int force_mainkey, u32 newexpiration);
|
int unattended, u32 newexpiration);
|
||||||
static int menu_changeusage (ctrl_t ctrl, kbnode_t keyblock);
|
static int menu_changeusage (ctrl_t ctrl, kbnode_t keyblock);
|
||||||
static int menu_backsign (ctrl_t ctrl, kbnode_t pub_keyblock);
|
static int menu_backsign (ctrl_t ctrl, kbnode_t pub_keyblock);
|
||||||
static int menu_set_primary_uid (ctrl_t ctrl, kbnode_t pub_keyblock);
|
static int menu_set_primary_uid (ctrl_t ctrl, kbnode_t pub_keyblock);
|
||||||
@ -2808,18 +2808,24 @@ keyedit_quick_addkey (ctrl_t ctrl, const char *fpr, const char *algostr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Unattended expiration setting function for the main key.
|
/* Unattended expiration setting function for the main key. If
|
||||||
*
|
* SUBKEYFPRS is not NULL and SUBKEYSFPRS[0] is neither NULL, it is
|
||||||
|
* expected to be an array of fingerprints for subkeys to change. It
|
||||||
|
* may also be an array which just one item "*" to indicate that all
|
||||||
|
* keys shall be set to that expiration date.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
keyedit_quick_set_expire (ctrl_t ctrl, const char *fpr, const char *expirestr)
|
keyedit_quick_set_expire (ctrl_t ctrl, const char *fpr, const char *expirestr,
|
||||||
|
char **subkeyfprs)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
kbnode_t keyblock;
|
kbnode_t keyblock, node;
|
||||||
KEYDB_HANDLE kdbhd;
|
KEYDB_HANDLE kdbhd;
|
||||||
int modified = 0;
|
int modified = 0;
|
||||||
PKT_public_key *pk;
|
PKT_public_key *pk;
|
||||||
u32 expire;
|
u32 expire;
|
||||||
|
int primary_only = 0;
|
||||||
|
int idx;
|
||||||
|
|
||||||
#ifdef HAVE_W32_SYSTEM
|
#ifdef HAVE_W32_SYSTEM
|
||||||
/* See keyedit_menu for why we need this. */
|
/* See keyedit_menu for why we need this. */
|
||||||
@ -2846,7 +2852,6 @@ keyedit_quick_set_expire (ctrl_t ctrl, const char *fpr, const char *expirestr)
|
|||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
expire = parse_expire_string (expirestr);
|
expire = parse_expire_string (expirestr);
|
||||||
if (expire == (u32)-1 )
|
if (expire == (u32)-1 )
|
||||||
{
|
{
|
||||||
@ -2857,8 +2862,78 @@ keyedit_quick_set_expire (ctrl_t ctrl, const char *fpr, const char *expirestr)
|
|||||||
if (expire)
|
if (expire)
|
||||||
expire += make_timestamp ();
|
expire += make_timestamp ();
|
||||||
|
|
||||||
|
/* Check whether a subkey's expiration time shall be changed or the
|
||||||
|
* expiration time of all keys. */
|
||||||
|
if (!subkeyfprs || !subkeyfprs[0])
|
||||||
|
primary_only = 1;
|
||||||
|
else if ( !strcmp (subkeyfprs[0], "*") && !subkeyfprs[1])
|
||||||
|
{
|
||||||
|
/* Change all subkeys keys which have not been revoked and are
|
||||||
|
* not yet expired. */
|
||||||
|
merge_keys_and_selfsig (ctrl, keyblock);
|
||||||
|
for (node = keyblock; node; node = node->next)
|
||||||
|
{
|
||||||
|
if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
|
||||||
|
&& (pk = node->pkt->pkt.public_key)
|
||||||
|
&& !pk->flags.revoked
|
||||||
|
&& !pk->has_expired)
|
||||||
|
node->flag |= NODFLG_SELKEY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Change specified subkeys. */
|
||||||
|
KEYDB_SEARCH_DESC desc;
|
||||||
|
byte fprbin[MAX_FINGERPRINT_LEN];
|
||||||
|
size_t fprlen;
|
||||||
|
|
||||||
|
err = 0;
|
||||||
|
merge_keys_and_selfsig (ctrl, keyblock);
|
||||||
|
for (idx=0; subkeyfprs[idx]; idx++)
|
||||||
|
{
|
||||||
|
int any = 0;
|
||||||
|
|
||||||
|
/* Parse the fingerprint. */
|
||||||
|
if (classify_user_id (subkeyfprs[idx], &desc, 1)
|
||||||
|
|| !(desc.mode == KEYDB_SEARCH_MODE_FPR
|
||||||
|
|| desc.mode == KEYDB_SEARCH_MODE_FPR20))
|
||||||
|
{
|
||||||
|
log_error (_("\"%s\" is not a proper fingerprint\n"),
|
||||||
|
subkeyfprs[idx] );
|
||||||
|
if (!err)
|
||||||
|
err = gpg_error (GPG_ERR_INV_NAME);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the flag for the matching non revoked subkey. */
|
||||||
|
for (node = keyblock; node; node = node->next)
|
||||||
|
{
|
||||||
|
if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
|
||||||
|
&& (pk = node->pkt->pkt.public_key)
|
||||||
|
&& !pk->flags.revoked )
|
||||||
|
{
|
||||||
|
fingerprint_from_pk (pk, fprbin, &fprlen);
|
||||||
|
if (fprlen == 20 && !memcmp (fprbin, desc.u.fpr, 20))
|
||||||
|
{
|
||||||
|
node->flag |= NODFLG_SELKEY;
|
||||||
|
any = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!any)
|
||||||
|
{
|
||||||
|
log_error (_("subkey \"%s\" not found\n"), subkeyfprs[idx]);
|
||||||
|
if (!err)
|
||||||
|
err = gpg_error (GPG_ERR_NOT_FOUND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set the new expiration date. */
|
/* Set the new expiration date. */
|
||||||
err = menu_expire (ctrl, keyblock, 1, expire);
|
err = menu_expire (ctrl, keyblock, primary_only? 1 : 2, expire);
|
||||||
if (gpg_err_code (err) == GPG_ERR_TRUE)
|
if (gpg_err_code (err) == GPG_ERR_TRUE)
|
||||||
modified = 1;
|
modified = 1;
|
||||||
else if (err)
|
else if (err)
|
||||||
@ -4283,30 +4358,34 @@ fail:
|
|||||||
|
|
||||||
|
|
||||||
/* With FORCE_MAINKEY cleared this function handles the interactive
|
/* With FORCE_MAINKEY cleared this function handles the interactive
|
||||||
* menu option "expire". With FORCE_MAINKEY set this functions only
|
* menu option "expire". With UNATTENDED set to 1 this function only
|
||||||
* sets the expiration date of the primary key to NEWEXPIRATION and
|
* sets the expiration date of the primary key to NEWEXPIRATION and
|
||||||
* avoid all interactivity. Retirns 0 if nothing was done,
|
* avoid all interactivity; with a value of 2 only the flagged subkeys
|
||||||
|
* are set to NEWEXPIRATION. Returns 0 if nothing was done,
|
||||||
* GPG_ERR_TRUE if the key was modified, or any other error code. */
|
* GPG_ERR_TRUE if the key was modified, or any other error code. */
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
menu_expire (ctrl_t ctrl, kbnode_t pub_keyblock,
|
menu_expire (ctrl_t ctrl, kbnode_t pub_keyblock,
|
||||||
int force_mainkey, u32 newexpiration)
|
int unattended, u32 newexpiration)
|
||||||
{
|
{
|
||||||
int signumber, rc;
|
int signumber, rc;
|
||||||
u32 expiredate;
|
u32 expiredate;
|
||||||
int mainkey = 0;
|
int only_mainkey; /* Set if only the mainkey is to be updated. */
|
||||||
PKT_public_key *main_pk, *sub_pk;
|
PKT_public_key *main_pk, *sub_pk;
|
||||||
PKT_user_id *uid;
|
PKT_user_id *uid;
|
||||||
kbnode_t node;
|
kbnode_t node;
|
||||||
u32 keyid[2];
|
u32 keyid[2];
|
||||||
|
|
||||||
if (force_mainkey)
|
if (unattended)
|
||||||
{
|
{
|
||||||
mainkey = 1;
|
only_mainkey = (unattended == 1);
|
||||||
expiredate = newexpiration;
|
expiredate = newexpiration;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int n1 = count_selected_keys (pub_keyblock);
|
int n1;
|
||||||
|
|
||||||
|
only_mainkey = 0;
|
||||||
|
n1 = count_selected_keys (pub_keyblock);
|
||||||
if (n1 > 1)
|
if (n1 > 1)
|
||||||
{
|
{
|
||||||
if (!cpr_get_answer_is_yes
|
if (!cpr_get_answer_is_yes
|
||||||
@ -4320,7 +4399,7 @@ menu_expire (ctrl_t ctrl, kbnode_t pub_keyblock,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
tty_printf (_("Changing expiration time for the primary key.\n"));
|
tty_printf (_("Changing expiration time for the primary key.\n"));
|
||||||
mainkey = 1;
|
only_mainkey = 1;
|
||||||
no_primary_warning (pub_keyblock);
|
no_primary_warning (pub_keyblock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4342,8 +4421,10 @@ menu_expire (ctrl_t ctrl, kbnode_t pub_keyblock,
|
|||||||
}
|
}
|
||||||
else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
||||||
{
|
{
|
||||||
if ((node->flag & NODFLG_SELKEY) && !force_mainkey)
|
if ((node->flag & NODFLG_SELKEY) && unattended != 1)
|
||||||
{
|
{
|
||||||
|
/* The flag is set and we do not want to set the
|
||||||
|
* expiration date only for the main key. */
|
||||||
sub_pk = node->pkt->pkt.public_key;
|
sub_pk = node->pkt->pkt.public_key;
|
||||||
sub_pk->expiredate = expiredate;
|
sub_pk->expiredate = expiredate;
|
||||||
}
|
}
|
||||||
@ -4353,14 +4434,14 @@ menu_expire (ctrl_t ctrl, kbnode_t pub_keyblock,
|
|||||||
else if (node->pkt->pkttype == PKT_USER_ID)
|
else if (node->pkt->pkttype == PKT_USER_ID)
|
||||||
uid = node->pkt->pkt.user_id;
|
uid = node->pkt->pkt.user_id;
|
||||||
else if (main_pk && node->pkt->pkttype == PKT_SIGNATURE
|
else if (main_pk && node->pkt->pkttype == PKT_SIGNATURE
|
||||||
&& (mainkey || sub_pk))
|
&& (only_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
|
&& ((only_mainkey && uid
|
||||||
&& uid->created && (sig->sig_class & ~3) == 0x10)
|
&& uid->created && (sig->sig_class & ~3) == 0x10)
|
||||||
|| (!mainkey && sig->sig_class == 0x18))
|
|| (!only_mainkey && sig->sig_class == 0x18))
|
||||||
&& sig->flags.chosen_selfsig)
|
&& sig->flags.chosen_selfsig)
|
||||||
{
|
{
|
||||||
/* This is a self-signature which is to be replaced. */
|
/* This is a self-signature which is to be replaced. */
|
||||||
@ -4369,15 +4450,15 @@ menu_expire (ctrl_t ctrl, kbnode_t pub_keyblock,
|
|||||||
|
|
||||||
signumber++;
|
signumber++;
|
||||||
|
|
||||||
if ((mainkey && main_pk->version < 4)
|
if ((only_mainkey && main_pk->version < 4)
|
||||||
|| (!mainkey && sub_pk->version < 4))
|
|| (!only_mainkey && sub_pk->version < 4))
|
||||||
{
|
{
|
||||||
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 gpg_error (GPG_ERR_LEGACY_KEY);
|
return gpg_error (GPG_ERR_LEGACY_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mainkey)
|
if (only_mainkey)
|
||||||
rc = update_keysig_packet (ctrl,
|
rc = update_keysig_packet (ctrl,
|
||||||
&newsig, sig, main_pk, uid, NULL,
|
&newsig, sig, main_pk, uid, NULL,
|
||||||
main_pk, keygen_add_key_expire,
|
main_pk, keygen_add_key_expire,
|
||||||
|
@ -46,7 +46,8 @@ void keyedit_quick_revuid (ctrl_t ctrl, const char *username,
|
|||||||
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,
|
void keyedit_quick_set_expire (ctrl_t ctrl,
|
||||||
const char *fpr, const char *expirestr);
|
const char *fpr, const char *expirestr,
|
||||||
|
char **subkeyfprs);
|
||||||
void keyedit_quick_set_primary (ctrl_t ctrl, const char *username,
|
void keyedit_quick_set_primary (ctrl_t ctrl, const char *username,
|
||||||
const char *primaryuid);
|
const char *primaryuid);
|
||||||
void show_basic_key_info (ctrl_t ctrl, kbnode_t keyblock);
|
void show_basic_key_info (ctrl_t ctrl, kbnode_t keyblock);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user