aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2014-06-25 12:33:34 +0000
committerWerner Koch <[email protected]>2014-06-30 17:40:44 +0000
commit955524f4359ba9e9de213f4067c38df9ae4808a8 (patch)
treead834d27966bf6303920a759701a78896806bca0
parentAdd CVE number (diff)
downloadgnupg-955524f4359ba9e9de213f4067c38df9ae4808a8.tar.gz
gnupg-955524f4359ba9e9de213f4067c38df9ae4808a8.zip
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").
-rw-r--r--g10/keyserver.c68
1 files changed, 45 insertions, 23 deletions
diff --git a/g10/keyserver.c b/g10/keyserver.c
index dca5e18bf..af174fbf7 100644
--- a/g10/keyserver.c
+++ b/g10/keyserver.c
@@ -960,13 +960,25 @@ direct_uri_map(const char *scheme,unsigned int is_direct)
#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
returns 0 if the key shall be imported. Note that this kind of
filter is not related to the iobuf filters. */
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];
byte fpr[MAX_FINGERPRINT_LEN];
size_t fpr_len = 0;
@@ -975,32 +987,40 @@ keyserver_retrieval_filter (PKT_public_key *pk, PKT_secret_key *sk, void *arg)
if (sk)
return G10ERR_GENERAL;
+ if (!ndesc)
+ return 0; /* Okay if no description given. */
+
fingerprint_from_pk (pk, fpr, &fpr_len);
keyid_from_pk (pk, keyid);
/* Compare requested and returned fingerprints if available. */
- if (desc->mode == KEYDB_SEARCH_MODE_FPR20)
- {
- if (fpr_len != 20 || memcmp (fpr, desc->u.fpr, 20))
- return G10ERR_GENERAL;
- }
- else if (desc->mode == KEYDB_SEARCH_MODE_FPR16)
+ for (n = 0; n < ndesc; n++)
{
- if (fpr_len != 16 || memcmp (fpr, desc->u.fpr, 16))
- return G10ERR_GENERAL;
- }
- else if (desc->mode == KEYDB_SEARCH_MODE_LONG_KID)
- {
- if (keyid[0] != desc->u.kid[0] || keyid[1] != desc->u.kid[1])
- return G10ERR_GENERAL;
- }
- else if (desc->mode == KEYDB_SEARCH_MODE_SHORT_KID)
- {
- if (keyid[1] != desc->u.kid[1])
- return G10ERR_GENERAL;
+ if (desc[n].mode == KEYDB_SEARCH_MODE_FPR20)
+ {
+ if (fpr_len == 20 && !memcmp (fpr, desc[n].u.fpr, 20))
+ return 0;
+ }
+ else if (desc[n].mode == KEYDB_SEARCH_MODE_FPR16)
+ {
+ if (fpr_len == 16 && !memcmp (fpr, desc[n].u.fpr, 16))
+ return 0;
+ }
+ else if (desc[n].mode == KEYDB_SEARCH_MODE_LONG_KID)
+ {
+ if (keyid[0] == desc[n].u.kid[0] && keyid[1] == desc[n].u.kid[1])
+ return 0;
+ }
+ else if (desc[n].mode == KEYDB_SEARCH_MODE_SHORT_KID)
+ {
+ 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:
{
void *stats_handle;
+ struct ks_retrieval_filter_arg_s filterarg;
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
keyserver. Keyservers should never accept or send them
but we better protect against rogue keyservers. */
-
+ filterarg.desc = desc;
+ filterarg.ndesc = count;
import_keys_stream (spawn->fromchild, stats_handle, fpr, fpr_len,
(opt.keyserver_options.import_options
| IMPORT_NO_SECKEY),
- keyserver_retrieval_filter, desc);
+ keyserver_retrieval_filter, &filterarg);
import_print_stats(stats_handle);
import_release_stats_handle(stats_handle);