gpg: Fix regression due to the keyserver import filter.
authorWerner Koch <wk@gnupg.org>
Wed, 6 Aug 2014 15:11:21 +0000 (17:11 +0200)
committerWerner Koch <wk@gnupg.org>
Wed, 6 Aug 2014 15:11:21 +0000 (17:11 +0200)
* g10/keyserver.c (keyserver_retrieval_filter): Change args.  Rewrite
to take subpakets in account.
* g10/import.c (import_one, import_secret_one): Pass keyblock to
filter.
--

GnuPG-bug-id: 1680

g10/import.c
g10/keyserver.c
g10/main.h

index fbe6b37..1bf4090 100644 (file)
@@ -799,7 +799,7 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
        return 0;
       }
 
-    if (filter && filter (pk, NULL, filter_arg))
+    if (filter && filter (keyblock, filter_arg))
       {
         log_error (_("key %s: %s\n"), keystr_from_pk(pk),
                    _("rejected by import filter"));
@@ -1201,7 +1201,7 @@ import_secret_one (const char *fname, KBNODE keyblock,
     keyid_from_sk( sk, keyid );
     uidnode = find_next_kbnode( keyblock, PKT_USER_ID );
 
-    if (filter && filter (NULL, sk, filter_arg)) {
+    if (filter && filter (keyblock, filter_arg)) {
         log_error (_("secret key %s: %s\n"), keystr_from_sk(sk),
                    _("rejected by import filter"));
         return 0;
index aa41536..af00401 100644 (file)
@@ -994,52 +994,68 @@ struct ks_retrieval_filter_arg_s
    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 *opaque)
+keyserver_retrieval_filter (kbnode_t keyblock, void *opaque)
 {
   struct ks_retrieval_filter_arg_s *arg = opaque;
   KEYDB_SEARCH_DESC *desc = arg->desc;
   int ndesc = arg->ndesc;
+  kbnode_t node;
+  PKT_public_key *pk;
   int n;
   u32 keyid[2];
   byte fpr[MAX_FINGERPRINT_LEN];
   size_t fpr_len = 0;
 
-  /* Secret keys are not expected from a keyserver.  Do not import.  */
-  if (sk)
-    return G10ERR_GENERAL;
+  /* Secret keys are not expected from a keyserver.  We do not
+     care about secret subkeys because the import code takes care
+     of skipping them.  Not allowing an import of a public key
+     with a secret subkey would make it too easy to inhibit the
+     downloading of a public key.  Recall that keyservers do only
+     limited checks.  */
+  node = find_kbnode (keyblock, PKT_SECRET_KEY);
+  if (node)
+    return G10ERR_GENERAL;   /* Do not import. */
 
   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. */
-  for (n = 0; n < ndesc; n++)
+  /* Loop over all key packets.  */
+  for (node = keyblock; node; node = node->next)
     {
-      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 (node->pkt->pkttype != PKT_PUBLIC_KEY
+          && node->pkt->pkttype != PKT_PUBLIC_SUBKEY)
+        continue;
+
+      pk = node->pkt->pkt.public_key;
+      fingerprint_from_pk (pk, fpr, &fpr_len);
+      keyid_from_pk (pk, keyid);
+
+      /* Compare requested and returned fingerprints if available. */
+      for (n = 0; n < ndesc; n++)
         {
-          if (keyid[1] == desc[n].u.kid[1])
-            return 0;
+          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 /* No keyid or fingerprint - can't check.  */
+            return 0; /* allow import.  */
         }
-      else
-        return 0;
     }
 
   return G10ERR_GENERAL;
index 6a0de00..9904820 100644 (file)
@@ -261,8 +261,7 @@ gcry_mpi_t encode_md_value( PKT_public_key *pk, PKT_secret_key *sk,
 
 /*-- import.c --*/
 
-typedef int (*import_filter_t)(PKT_public_key *pk, PKT_secret_key *sk,
-                               void *arg);
+typedef int (*import_filter_t)(kbnode_t keyblock, void *arg);
 
 int parse_import_options(char *str,unsigned int *options,int noisy);
 void import_keys( char **fnames, int nnames,