1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-06-13 00:09:51 +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:
Neal H. Walfield 2015-11-05 17:29:53 +01:00
parent f38bac8883
commit e8c53fca95
2 changed files with 189 additions and 28 deletions

View File

@ -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
View File

@ -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 )