mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-13 22:21:09 +02:00
gpg: Check for ambiguous or non-matching key specs.
* g10/gpg.c (check_user_ids): New function. (main): Check that any user id specifications passed to --local-user and --remote-user correspond to exactly 1 user. Check that any user id specifications passed to --default-key correspond to at most 1 user. Warn if any user id specifications passed to --local-user or --default-user are possible ambiguous (are not specified by long keyid or fingerprint). * g10/getkey.c (parse_def_secret_key): Don't warn about possible ambiguous key descriptions here. -- Signed-off-by: Neal H. Walfield <neal@g10code.com> GnuPG-bug-id: 1128 Debian-debug-id: 544490
This commit is contained in:
parent
f38bac8883
commit
e8c53fca95
@ -1142,15 +1142,6 @@ parse_def_secret_key (ctrl_t ctrl)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! (desc.mode == KEYDB_SEARCH_MODE_LONG_KID
|
|
||||||
|| desc.mode == KEYDB_SEARCH_MODE_FPR16
|
|
||||||
|| desc.mode == KEYDB_SEARCH_MODE_FPR20
|
|
||||||
|| desc.mode == KEYDB_SEARCH_MODE_FPR)
|
|
||||||
&& ! warned)
|
|
||||||
log_info (_("Warning: value '%s' for --default-key"
|
|
||||||
" should be a long keyid or a fingerprint.\n"),
|
|
||||||
t->d);
|
|
||||||
|
|
||||||
if (! hd)
|
if (! hd)
|
||||||
hd = keydb_new ();
|
hd = keydb_new ();
|
||||||
else
|
else
|
||||||
|
208
g10/gpg.c
208
g10/gpg.c
@ -2081,6 +2081,159 @@ get_default_configname (void)
|
|||||||
return configname;
|
return configname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gpg_error_t
|
||||||
|
check_user_ids (strlist_t *sp,
|
||||||
|
int warn_possibly_ambiguous,
|
||||||
|
int error_if_not_found)
|
||||||
|
{
|
||||||
|
strlist_t s = *sp;
|
||||||
|
strlist_t s2 = NULL;
|
||||||
|
strlist_t t;
|
||||||
|
|
||||||
|
gpg_error_t rc = 0;
|
||||||
|
gpg_error_t err;
|
||||||
|
|
||||||
|
KEYDB_HANDLE hd = NULL;
|
||||||
|
|
||||||
|
if (! s)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (t = s; t; t = t->next)
|
||||||
|
{
|
||||||
|
const char *option;
|
||||||
|
|
||||||
|
KEYDB_SEARCH_DESC desc;
|
||||||
|
KBNODE kb;
|
||||||
|
PKT_public_key *pk;
|
||||||
|
char fingerprint_bin[MAX_FINGERPRINT_LEN];
|
||||||
|
size_t fingerprint_bin_len = sizeof (fingerprint_bin);
|
||||||
|
char fingerprint[2 * MAX_FINGERPRINT_LEN + 1];
|
||||||
|
|
||||||
|
|
||||||
|
switch (t->flags >> 2)
|
||||||
|
{
|
||||||
|
case oDefaultKey: option = "--default-key"; break;
|
||||||
|
case oEncryptTo: option = "--encrypt-to"; break;
|
||||||
|
case oHiddenEncryptTo: option = "--hidden-encrypt-to"; break;
|
||||||
|
case oEncryptToDefaultKey: option = "--encrypt-to-default-key"; break;
|
||||||
|
case oRecipient: option = "--recipient"; break;
|
||||||
|
case oHiddenRecipient: option = "--hidden-recipient"; break;
|
||||||
|
case oLocalUser: option = "--local-user"; break;
|
||||||
|
default: log_bug ("Unsupport option: %d\n", t->flags >> 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
err = classify_user_id (t->d, &desc, 1);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
if (! rc)
|
||||||
|
rc = err;
|
||||||
|
|
||||||
|
log_error (_("Invalid value ('%s')."), t->d);
|
||||||
|
if (!opt.quiet)
|
||||||
|
log_info (_("(check argument of option '%s')\n"), option);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (warn_possibly_ambiguous
|
||||||
|
&& ! (desc.mode == KEYDB_SEARCH_MODE_LONG_KID
|
||||||
|
|| desc.mode == KEYDB_SEARCH_MODE_FPR16
|
||||||
|
|| desc.mode == KEYDB_SEARCH_MODE_FPR20
|
||||||
|
|| desc.mode == KEYDB_SEARCH_MODE_FPR))
|
||||||
|
log_info (_("Warning: value '%s' for %s"
|
||||||
|
" should be a long keyid or a fingerprint.\n"),
|
||||||
|
t->d, option);
|
||||||
|
|
||||||
|
if (! hd)
|
||||||
|
hd = keydb_new ();
|
||||||
|
else
|
||||||
|
keydb_search_reset (hd);
|
||||||
|
|
||||||
|
err = keydb_search (hd, &desc, 1, NULL);
|
||||||
|
if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
|
||||||
|
{
|
||||||
|
if (error_if_not_found)
|
||||||
|
{
|
||||||
|
if (! rc)
|
||||||
|
rc = err;
|
||||||
|
|
||||||
|
log_error (_("no such key corresponding to '%s'\n"), t->d);
|
||||||
|
if (!opt.quiet)
|
||||||
|
log_info (_("(check argument of option '%s')\n"), option);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
if (! rc)
|
||||||
|
rc = err;
|
||||||
|
|
||||||
|
log_error (_("error looking up '%s' in keyring: %s.\n"),
|
||||||
|
t->d, gpg_strerror (err));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = keydb_get_keyblock (hd, &kb);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
if (! rc)
|
||||||
|
rc = err;
|
||||||
|
|
||||||
|
log_error (_("error reading key block for '%s': %s\n"),
|
||||||
|
t->d, gpg_strerror (err));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pk = kb->pkt->pkt.public_key;
|
||||||
|
fingerprint_from_pk (pk, fingerprint_bin, &fingerprint_bin_len);
|
||||||
|
assert (fingerprint_bin_len == sizeof (fingerprint_bin));
|
||||||
|
bin2hex (fingerprint_bin, MAX_FINGERPRINT_LEN, fingerprint);
|
||||||
|
add_to_strlist (&s2, fingerprint);
|
||||||
|
s2->flags = s->flags;
|
||||||
|
|
||||||
|
release_kbnode (kb);
|
||||||
|
|
||||||
|
/* Continue the search. */
|
||||||
|
err = keydb_search (hd, &desc, 1, NULL);
|
||||||
|
if (! (gpg_err_code (err) == GPG_ERR_NOT_FOUND
|
||||||
|
|| gpg_err_code (err) == GPG_ERR_EOF))
|
||||||
|
{
|
||||||
|
char fingerprint_bin2[MAX_FINGERPRINT_LEN];
|
||||||
|
size_t fingerprint_bin2_len = sizeof (fingerprint_bin2);
|
||||||
|
char fingerprint2[2 * MAX_FINGERPRINT_LEN + 1];
|
||||||
|
|
||||||
|
log_error (_("Error: the key specification '%s' is ambiguous.\n"),
|
||||||
|
t->d);
|
||||||
|
if (!opt.quiet)
|
||||||
|
log_info (_("(check argument of option '%s')\n"), option);
|
||||||
|
|
||||||
|
err = keydb_get_keyblock (hd, &kb);
|
||||||
|
if (err)
|
||||||
|
log_error (_("error reading key block for '%s': %s.\n"),
|
||||||
|
t->d, gpg_strerror (err));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pk = kb->pkt->pkt.public_key;
|
||||||
|
fingerprint_from_pk (pk, fingerprint_bin2, &fingerprint_bin2_len);
|
||||||
|
assert (fingerprint_bin2_len == sizeof (fingerprint_bin2));
|
||||||
|
bin2hex (fingerprint_bin2, MAX_FINGERPRINT_LEN, fingerprint2);
|
||||||
|
|
||||||
|
log_error ("'%s' matches at least: %s and %s.\n",
|
||||||
|
t->d, fingerprint, fingerprint2);
|
||||||
|
|
||||||
|
release_kbnode (kb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
strlist_rev (&s2);
|
||||||
|
|
||||||
|
if (hd)
|
||||||
|
keydb_release (hd);
|
||||||
|
|
||||||
|
free_strlist (s);
|
||||||
|
*sp = s2;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
@ -2582,7 +2735,8 @@ main (int argc, char **argv)
|
|||||||
|
|
||||||
#endif /*!NO_TRUST_MODELS*/
|
#endif /*!NO_TRUST_MODELS*/
|
||||||
case oDefaultKey:
|
case oDefaultKey:
|
||||||
add_to_strlist (&opt.def_secret_key, pargs.r.ret_str);
|
sl = add_to_strlist (&opt.def_secret_key, pargs.r.ret_str);
|
||||||
|
sl->flags = (pargs.r_opt << 2);
|
||||||
break;
|
break;
|
||||||
case oDefRecipient:
|
case oDefRecipient:
|
||||||
if( *pargs.r.ret_str )
|
if( *pargs.r.ret_str )
|
||||||
@ -2774,22 +2928,23 @@ main (int argc, char **argv)
|
|||||||
case oNoEncryptTo: opt.no_encrypt_to = 1; break;
|
case oNoEncryptTo: opt.no_encrypt_to = 1; break;
|
||||||
case oEncryptTo: /* store the recipient in the second list */
|
case oEncryptTo: /* store the recipient in the second list */
|
||||||
sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
|
sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
|
||||||
sl->flags = 1;
|
sl->flags = (pargs.r_opt << 2) | 1;
|
||||||
break;
|
break;
|
||||||
case oHiddenEncryptTo: /* store the recipient in the second list */
|
case oHiddenEncryptTo: /* store the recipient in the second list */
|
||||||
sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
|
sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
|
||||||
sl->flags = 1|2;
|
sl->flags = (pargs.r_opt << 2) | 1|2;
|
||||||
break;
|
break;
|
||||||
case oEncryptToDefaultKey:
|
case oEncryptToDefaultKey:
|
||||||
opt.encrypt_to_default_key = 1;
|
opt.encrypt_to_default_key = 1;
|
||||||
break;
|
break;
|
||||||
case oRecipient: /* store the recipient */
|
case oRecipient: /* store the recipient */
|
||||||
add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
|
sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
|
||||||
|
sl->flags = (pargs.r_opt << 2);
|
||||||
any_explicit_recipient = 1;
|
any_explicit_recipient = 1;
|
||||||
break;
|
break;
|
||||||
case oHiddenRecipient: /* store the recipient with a flag */
|
case oHiddenRecipient: /* store the recipient with a flag */
|
||||||
sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
|
sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
|
||||||
sl->flags = 2;
|
sl->flags = (pargs.r_opt << 2) | 2;
|
||||||
any_explicit_recipient = 1;
|
any_explicit_recipient = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2832,7 +2987,8 @@ main (int argc, char **argv)
|
|||||||
case oAskCertLevel: opt.ask_cert_level = 1; break;
|
case oAskCertLevel: opt.ask_cert_level = 1; break;
|
||||||
case oNoAskCertLevel: opt.ask_cert_level = 0; break;
|
case oNoAskCertLevel: opt.ask_cert_level = 0; break;
|
||||||
case oLocalUser: /* store the local users */
|
case oLocalUser: /* store the local users */
|
||||||
add_to_strlist2( &locusr, pargs.r.ret_str, utf8_strings );
|
sl = add_to_strlist2( &locusr, pargs.r.ret_str, utf8_strings );
|
||||||
|
sl->flags = (pargs.r_opt << 2);
|
||||||
break;
|
break;
|
||||||
case oCompress:
|
case oCompress:
|
||||||
/* this is the -z command line option */
|
/* this is the -z command line option */
|
||||||
@ -3740,19 +3896,33 @@ main (int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt.encrypt_to_default_key)
|
{
|
||||||
{
|
int have_def_secret_key = opt.def_secret_key != NULL;
|
||||||
const char *default_key = parse_def_secret_key (ctrl);
|
|
||||||
if (default_key)
|
rc = check_user_ids (&locusr, 1, 1);
|
||||||
{
|
if (rc)
|
||||||
sl = add_to_strlist2 (&remusr, default_key, utf8_strings);
|
g10_exit (1);
|
||||||
sl->flags = 1;
|
rc = check_user_ids (&remusr, 0, 1);
|
||||||
}
|
if (rc)
|
||||||
else if (opt.def_secret_key)
|
g10_exit (1);
|
||||||
log_info (_("--encrypt-to-default-key specified, but no valid default keys specified.\n"));
|
rc = check_user_ids (&opt.def_secret_key, 1, 0);
|
||||||
else
|
if (rc)
|
||||||
log_info (_("--encrypt-to-default-key specified, but --default-key not specified.\n"));
|
g10_exit (1);
|
||||||
}
|
|
||||||
|
if (opt.encrypt_to_default_key)
|
||||||
|
{
|
||||||
|
const char *default_key = parse_def_secret_key (ctrl);
|
||||||
|
if (default_key)
|
||||||
|
{
|
||||||
|
sl = add_to_strlist2 (&remusr, default_key, utf8_strings);
|
||||||
|
sl->flags = (oEncryptToDefaultKey << 2) | 1;
|
||||||
|
}
|
||||||
|
else if (have_def_secret_key)
|
||||||
|
log_info (_("--encrypt-to-default-key specified, but no valid default keys specified.\n"));
|
||||||
|
else
|
||||||
|
log_info (_("--encrypt-to-default-key specified, but --default-key not specified.\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* The command dispatcher. */
|
/* The command dispatcher. */
|
||||||
switch( cmd )
|
switch( cmd )
|
||||||
|
Loading…
x
Reference in New Issue
Block a user