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

Make screening of keyserver result work with multi-key commands.

* g10/keyserver.c (ks_retrieval_filter_arg_s): new.
(keyserver_retrieval_filter): Use new struct and check all
descriptions.
(keyserver_spawn): Pass filter arg suing the new struct.
--

This is a fix for commit 52303043.

The old code did only work for a single key.  It failed as soon as
several keys are specified ("gpg --refresh-keys" or "gpg --recv-key A
B C").
This commit is contained in:
Werner Koch 2014-06-25 14:33:34 +02:00
parent 574b9ed28d
commit 955524f435

View File

@ -960,13 +960,25 @@ direct_uri_map(const char *scheme,unsigned int is_direct)
#define KEYSERVER_ARGS_NOKEEP " -o \"%o\" \"%i\"" #define KEYSERVER_ARGS_NOKEEP " -o \"%o\" \"%i\""
/* Structure to convey the arg to keyserver_retrieval_filter. */
struct ks_retrieval_filter_arg_s
{
KEYDB_SEARCH_DESC *desc;
int ndesc;
};
/* Check whether a key matches the search description. The filter /* Check whether a key matches the search description. The filter
returns 0 if the key shall be imported. Note that this kind of returns 0 if the key shall be imported. Note that this kind of
filter is not related to the iobuf filters. */ filter is not related to the iobuf filters. */
static int static int
keyserver_retrieval_filter (PKT_public_key *pk, PKT_secret_key *sk, void *arg) keyserver_retrieval_filter (PKT_public_key *pk, PKT_secret_key *sk,
void *opaque)
{ {
KEYDB_SEARCH_DESC *desc = arg; struct ks_retrieval_filter_arg_s *arg = opaque;
KEYDB_SEARCH_DESC *desc = arg->desc;
int ndesc = arg->ndesc;
int n;
u32 keyid[2]; u32 keyid[2];
byte fpr[MAX_FINGERPRINT_LEN]; byte fpr[MAX_FINGERPRINT_LEN];
size_t fpr_len = 0; size_t fpr_len = 0;
@ -975,32 +987,40 @@ keyserver_retrieval_filter (PKT_public_key *pk, PKT_secret_key *sk, void *arg)
if (sk) if (sk)
return G10ERR_GENERAL; return G10ERR_GENERAL;
if (!ndesc)
return 0; /* Okay if no description given. */
fingerprint_from_pk (pk, fpr, &fpr_len); fingerprint_from_pk (pk, fpr, &fpr_len);
keyid_from_pk (pk, keyid); keyid_from_pk (pk, keyid);
/* Compare requested and returned fingerprints if available. */ /* Compare requested and returned fingerprints if available. */
if (desc->mode == KEYDB_SEARCH_MODE_FPR20) for (n = 0; n < ndesc; n++)
{ {
if (fpr_len != 20 || memcmp (fpr, desc->u.fpr, 20)) if (desc[n].mode == KEYDB_SEARCH_MODE_FPR20)
return G10ERR_GENERAL; {
} if (fpr_len == 20 && !memcmp (fpr, desc[n].u.fpr, 20))
else if (desc->mode == KEYDB_SEARCH_MODE_FPR16) return 0;
{ }
if (fpr_len != 16 || memcmp (fpr, desc->u.fpr, 16)) else if (desc[n].mode == KEYDB_SEARCH_MODE_FPR16)
return G10ERR_GENERAL; {
} if (fpr_len == 16 && !memcmp (fpr, desc[n].u.fpr, 16))
else if (desc->mode == KEYDB_SEARCH_MODE_LONG_KID) return 0;
{ }
if (keyid[0] != desc->u.kid[0] || keyid[1] != desc->u.kid[1]) else if (desc[n].mode == KEYDB_SEARCH_MODE_LONG_KID)
return G10ERR_GENERAL; {
} if (keyid[0] == desc[n].u.kid[0] && keyid[1] == desc[n].u.kid[1])
else if (desc->mode == KEYDB_SEARCH_MODE_SHORT_KID) return 0;
{ }
if (keyid[1] != desc->u.kid[1]) else if (desc[n].mode == KEYDB_SEARCH_MODE_SHORT_KID)
return G10ERR_GENERAL; {
if (keyid[1] == desc[n].u.kid[1])
return 0;
}
else
return 0;
} }
return 0; return G10ERR_GENERAL;
} }
@ -1540,6 +1560,7 @@ keyserver_spawn(enum ks_action action,STRLIST list,KEYDB_SEARCH_DESC *desc,
case KS_GETNAME: case KS_GETNAME:
{ {
void *stats_handle; void *stats_handle;
struct ks_retrieval_filter_arg_s filterarg;
stats_handle=import_new_stats_handle(); stats_handle=import_new_stats_handle();
@ -1552,11 +1573,12 @@ keyserver_spawn(enum ks_action action,STRLIST list,KEYDB_SEARCH_DESC *desc,
that we don't allow the import of secret keys from a that we don't allow the import of secret keys from a
keyserver. Keyservers should never accept or send them keyserver. Keyservers should never accept or send them
but we better protect against rogue keyservers. */ but we better protect against rogue keyservers. */
filterarg.desc = desc;
filterarg.ndesc = count;
import_keys_stream (spawn->fromchild, stats_handle, fpr, fpr_len, import_keys_stream (spawn->fromchild, stats_handle, fpr, fpr_len,
(opt.keyserver_options.import_options (opt.keyserver_options.import_options
| IMPORT_NO_SECKEY), | IMPORT_NO_SECKEY),
keyserver_retrieval_filter, desc); keyserver_retrieval_filter, &filterarg);
import_print_stats(stats_handle); import_print_stats(stats_handle);
import_release_stats_handle(stats_handle); import_release_stats_handle(stats_handle);