1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-01-08 12:44:23 +01:00

gpg: Don't error out if a key occurs multiple times in the keyring.

* g10/gpg.c (check_user_ids): Don't error out if a key occurs multiple
times in the keyring.  Instead, print a warning.  When printing out
fingerprint prints, use format_hexfingerprint to format them.

--
Signed-off-by: Neal H. Walfield <neal@g10code.com>
This commit is contained in:
Neal H. Walfield 2015-12-11 11:12:46 +01:00
parent d1a97585c5
commit 6dc37c5fb6

114
g10/gpg.c
View File

@ -2116,6 +2116,8 @@ check_user_ids (strlist_t *sp,
KEYDB_HANDLE hd = NULL; KEYDB_HANDLE hd = NULL;
char fingerprint_formatted[MAX_FORMATTED_FINGERPRINT_LEN + 1];
/* A quick check to avoid allocating a new strlist if we can skip /* A quick check to avoid allocating a new strlist if we can skip
all keys. Handles also the case of !SP. See below for details. */ all keys. Handles also the case of !SP. See below for details. */
for (t = s; t && (!(t->flags & PK_LIST_CONFIG) for (t = s; t && (!(t->flags & PK_LIST_CONFIG)
@ -2135,6 +2137,9 @@ check_user_ids (strlist_t *sp,
size_t fingerprint_bin_len = sizeof (fingerprint_bin); size_t fingerprint_bin_len = sizeof (fingerprint_bin);
/* We also potentially need a ! at the end. */ /* We also potentially need a ! at the end. */
char fingerprint[2 * MAX_FINGERPRINT_LEN + 1 + 1]; char fingerprint[2 * MAX_FINGERPRINT_LEN + 1 + 1];
int added = 0;
int dups = 0;
int ambiguous = 0;
/* If the key has been given on the command line and it has not /* If the key has been given on the command line and it has not
been given by one of the encrypt-to options, we skip the been given by one of the encrypt-to options, we skip the
@ -2271,41 +2276,58 @@ check_user_ids (strlist_t *sp,
i = strlen (fingerprint); i = strlen (fingerprint);
fingerprint[i] = '!'; fingerprint[i] = '!';
fingerprint[i + 1] = '\0'; fingerprint[i + 1] = '\0';
}
else add_to_strlist (&s2, fingerprint);
{ added = 1;
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); /* We need the primary key's fingerprint to detect dups so
always format it. */
fingerprint_from_pk (pk, fingerprint_bin, &fingerprint_bin_len);
assert (fingerprint_bin_len == sizeof (fingerprint_bin));
bin2hex (fingerprint_bin, MAX_FINGERPRINT_LEN, fingerprint);
if (! added)
add_to_strlist (&s2, fingerprint);
s2->flags = s->flags; s2->flags = s->flags;
release_kbnode (kb); release_kbnode (kb);
/* Continue the search. */ /* Continue the search. */
if (DBG_LOOKUP) if (DBG_LOOKUP)
log_debug ("%s: Check for duplicates for %s='%s'\n", log_debug ("%s: Checking if %s='%s' is ambiguous or there are dups\n",
__func__, option, t->d); __func__, option, t->d);
err = keydb_search (hd, &desc, 1, NULL); while (1)
if (! err)
/* Another result! */
{ {
char fingerprint_bin2[MAX_FINGERPRINT_LEN]; char fingerprint_bin2[MAX_FINGERPRINT_LEN];
size_t fingerprint_bin2_len = sizeof (fingerprint_bin2); size_t fingerprint_bin2_len = sizeof (fingerprint_bin2);
char fingerprint2[2 * MAX_FINGERPRINT_LEN + 1]; char fingerprint2[2 * MAX_FINGERPRINT_LEN + 1];
log_error (_("key specification '%s' is ambiguous\n"), t->d); err = keydb_search (hd, &desc, 1, NULL);
if (!opt.quiet) if (gpg_err_code (err) == GPG_ERR_NOT_FOUND
log_info (_("(check argument of option '%s')\n"), option); || gpg_err_code (err) == GPG_ERR_EOF)
/* Not found => not ambiguous. */
break;
else if (err)
/* An error (other than "not found"). */
{
log_error (_("error searching the keyring: %s\n"),
gpg_strerror (err));
if (! rc)
rc = err;
if (! rc) break;
rc = GPG_ERR_AMBIGUOUS_NAME; }
/* Another result! */
err = keydb_get_keyblock (hd, &kb); err = keydb_get_keyblock (hd, &kb);
if (err) if (err)
log_error (_("error reading keyblock: %s\n"), gpg_strerror (err)); {
log_error (_("error reading keyblock: %s\n"), gpg_strerror (err));
if (! rc)
rc = err;
}
else else
{ {
pk = kb->pkt->pkt.public_key; pk = kb->pkt->pkt.public_key;
@ -2313,25 +2335,53 @@ check_user_ids (strlist_t *sp,
assert (fingerprint_bin2_len == sizeof (fingerprint_bin2)); assert (fingerprint_bin2_len == sizeof (fingerprint_bin2));
bin2hex (fingerprint_bin2, MAX_FINGERPRINT_LEN, fingerprint2); bin2hex (fingerprint_bin2, MAX_FINGERPRINT_LEN, fingerprint2);
/* TRANSLATORS: The %s prints a key specification which if (strcmp (fingerprint, fingerprint2) == 0)
for example has been given at the command line. Two dups ++;
lines with fingerprints are printed after this message. */ else
log_info (_("'%s' matches at least:\n"), t->d); {
log_info (" %s\n", fingerprint); ambiguous ++;
log_info (" %s\n", fingerprint2);
if (! rc)
rc = GPG_ERR_AMBIGUOUS_NAME;
if (ambiguous == 1)
{
/* TRANSLATORS: The %s prints a key
specification which for example has been
given at the command line. Lines with
fingerprints are printed after this
message. */
log_error (_("key specification '%s' is ambiguous\n"),
t->d);
if (!opt.quiet)
log_info (_("(check argument of option '%s')\n"),
option);
log_info (_("'%s' matches at least:\n"), t->d);
log_info (" %s\n",
format_hexfingerprint
(fingerprint,
fingerprint_formatted,
sizeof fingerprint_formatted));
}
log_info (" %s\n",
format_hexfingerprint
(fingerprint2,
fingerprint_formatted,
sizeof fingerprint_formatted));
}
release_kbnode (kb); release_kbnode (kb);
} }
} }
else if (! (gpg_err_code (err) == GPG_ERR_NOT_FOUND
|| gpg_err_code (err) == GPG_ERR_EOF)) if (dups)
/* An error (other than "not found"). */ log_info (_("Warning: %s appears in the keyring %d times.\n"),
{ format_hexfingerprint (fingerprint,
log_error (_("error searching the keyring: %s\n"), fingerprint_formatted,
gpg_strerror (err)); sizeof fingerprint_formatted),
if (! rc) 1 + dups);
rc = err;
}
} }
strlist_rev (&s2); strlist_rev (&s2);