dirmngr: Add option --keyserver.
authorWerner Koch <wk@gnupg.org>
Mon, 5 Oct 2015 15:44:20 +0000 (17:44 +0200)
committerWerner Koch <wk@gnupg.org>
Mon, 5 Oct 2015 15:44:20 +0000 (17:44 +0200)
* dirmngr/dirmngr.c (oKeyServer): New.
(opts): Add "keyserver".
(parse_rereadable_options): Parse that options
(main): Add option to the gpgconf list.
* dirmngr/dirmngr.h (opt): Add field "keyserver".
* dirmngr/server.c (ensure_keyserver): New.
(make_keyserver_item): New.  Factored out from
(cmd_keyserver): here.  Call ensure_keyserver.
(cmd_ks_search): Call ensure_keyserver.
(cmd_ks_get): Ditto.
(cmd_ks_fetch): Ditto.
(cmd_ks_put): Ditto.
--

This option specifies the keyserver to be used if the client does not
set another keyserver.  We want to fade out the use of --keyserver in
gpg.conf in favor of specifying it here.

Signed-off-by: Werner Koch <wk@gnupg.org>
dirmngr/dirmngr.c
dirmngr/dirmngr.h
dirmngr/server.c
doc/dirmngr.texi

index 31833eb..847a65d 100644 (file)
@@ -141,6 +141,7 @@ enum cmd_and_opt_values {
   oHTTPWrapperProgram,
   oIgnoreCertExtension,
   oUseTor,
+  oKeyServer,
   aTest
 };
 
@@ -213,6 +214,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_i (oMaxReplies, "max-replies",
                 N_("|N|do not return more than N items in one query")),
 
+  ARGPARSE_s_s (oKeyServer, "keyserver", "@"),
   ARGPARSE_s_s (oHkpCaCert, "hkp-cacert",
                 N_("|FILE|use the CA certificates in FILE for HKP over TLS")),
 
@@ -520,7 +522,9 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
         }
       FREE_STRLIST (opt.ignored_cert_extensions);
       http_register_tls_ca (NULL);
-      /* We do not allow resetting of opt.use_tor at runtime.  */
+      xfree (opt.keyserver);
+      opt.keyserver = NULL;
+      /* Note: We do not allow resetting of opt.use_tor at runtime.  */
       return 1;
     }
 
@@ -585,6 +589,11 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
 
     case oUseTor: opt.use_tor = 1; break;
 
+    case oKeyServer:
+      xfree (opt.keyserver);
+      opt.keyserver = *pargs->r.ret_str? xtrystrdup (pargs->r.ret_str) : NULL;
+      break;
+
     default:
       return 0; /* Not handled. */
     }
@@ -1418,7 +1427,9 @@ main (int argc, char **argv)
       /* Note: The next one is to fix a typo in gpgconf - should be
          removed eventually. */
       es_printf ("ignore-ocsp-servic-url:%lu:\n", flags | GC_OPT_FLAG_NONE);
+
       es_printf ("use-tor:%lu:\n", flags | GC_OPT_FLAG_NONE);
+      es_printf ("keyserver:%lu:\n", flags | GC_OPT_FLAG_NONE);
     }
   cleanup ();
   return !!rc;
index a2db627..b2b94f9 100644 (file)
@@ -130,6 +130,8 @@ struct
                                        considered valid after thisUpdate. */
   unsigned int ocsp_current_period; /* Seconds a response is considered
                                        current after nextUpdate. */
+
+  char *keyserver;    /* Malloced string with the default keyserver.  */
 } opt;
 
 
index 694a881..5400a98 100644 (file)
@@ -1626,7 +1626,65 @@ cmd_validate (assuan_context_t ctx, char *line)
   return leave_cmd (ctx, err);
 }
 
+
 \f
+/* Parse an keyserver URI and store it in a new uri item which is
+   returned at R_ITEM.  On error return an error code.  */
+static gpg_error_t
+make_keyserver_item (const char *uri, uri_item_t *r_item)
+{
+  gpg_error_t err;
+  uri_item_t item;
+
+  *r_item = NULL;
+  item = xtrymalloc (sizeof *item + strlen (uri));
+  if (!item)
+    return gpg_error_from_syserror ();
+
+  item->next = NULL;
+  item->parsed_uri = NULL;
+  strcpy (item->uri, uri);
+
+#if USE_LDAP
+  if (ldap_uri_p (item->uri))
+    err = ldap_parse_uri (&item->parsed_uri, uri);
+  else
+#endif
+    {
+      err = http_parse_uri (&item->parsed_uri, uri, 1);
+    }
+
+  if (err)
+    xfree (item);
+  else
+    *r_item = item;
+  return err;
+}
+
+
+/* If no keyserver is stored in CTRL but a global keyserver has been
+   set, put that global keyserver into CTRL.  We need use this
+   function to help migrate from the old gpg based keyserver
+   configuration to the new dirmngr based configuration.  */
+static gpg_error_t
+ensure_keyserver (ctrl_t ctrl)
+{
+  gpg_error_t err;
+  uri_item_t item;
+
+  if (ctrl->server_local->keyservers)
+    return 0; /* Already set for this session.  */
+  if (!opt.keyserver)
+    return 0; /* No global option set.  */
+
+  err = make_keyserver_item (opt.keyserver, &item);
+  if (!err)
+    ctrl->server_local->keyservers = item;
+
+  return err;
+}
+
+
 static const char hlp_keyserver[] =
   "KEYSERVER [<options>] [<uri>|<host>]\n"
   "Options are:\n"
@@ -1671,7 +1729,9 @@ cmd_keyserver (assuan_context_t ctx, char *line)
 
   if (resolve_flag)
     {
-      err = ks_action_resolve (ctrl, ctrl->server_local->keyservers);
+      err = ensure_keyserver (ctrl);
+      if (!err)
+        err = ks_action_resolve (ctrl, ctrl->server_local->keyservers);
       if (err)
         goto leave;
     }
@@ -1711,29 +1771,9 @@ cmd_keyserver (assuan_context_t ctx, char *line)
 
   if (add_flag)
     {
-      item = xtrymalloc (sizeof *item + strlen (line));
-      if (!item)
-        {
-          err = gpg_error_from_syserror ();
-          goto leave;
-        }
-      item->next = NULL;
-      item->parsed_uri = NULL;
-      strcpy (item->uri, line);
-
-#if USE_LDAP
-      if (ldap_uri_p (item->uri))
-       err = ldap_parse_uri (&item->parsed_uri, line);
-      else
-#endif
-       {
-         err = http_parse_uri (&item->parsed_uri, line, 1);
-       }
+      err = make_keyserver_item (line, &item);
       if (err)
-        {
-          xfree (item);
-          goto leave;
-        }
+        goto leave;
     }
   if (clear_flag)
     release_ctrl_keyservers (ctrl);
@@ -1743,10 +1783,20 @@ cmd_keyserver (assuan_context_t ctx, char *line)
       ctrl->server_local->keyservers = item;
     }
 
-  if (!add_flag && !clear_flag && !help_flag) /* List configured keyservers.  */
+  if (!add_flag && !clear_flag && !help_flag)
     {
+      /* List configured keyservers.  However, we first add a global
+         keyserver. */
       uri_item_t u;
 
+      err = ensure_keyserver (ctrl);
+      if (err)
+        {
+          assuan_set_error (ctx, err,
+                            "Bad keyserver configuration in dirmngr.conf");
+          goto leave;
+        }
+
       for (u=ctrl->server_local->keyservers; u; u = u->next)
         dirmngr_status (ctrl, "KEYSERVER", u->uri, NULL);
     }
@@ -1799,6 +1849,10 @@ cmd_ks_search (assuan_context_t ctx, char *line)
         }
     }
 
+  err = ensure_keyserver (ctrl);
+  if (err)
+    goto leave;
+
   /* Setup an output stream and perform the search.  */
   outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
   if (!outfp)
@@ -1861,6 +1915,10 @@ cmd_ks_get (assuan_context_t ctx, char *line)
         }
     }
 
+  err = ensure_keyserver (ctrl);
+  if (err)
+    goto leave;
+
   /* Setup an output stream and perform the get.  */
   outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
   if (!outfp)
@@ -1891,6 +1949,10 @@ cmd_ks_fetch (assuan_context_t ctx, char *line)
   /* No options for now.  */
   line = skip_options (line);
 
+  err = ensure_keyserver (ctrl);
+  if (err)
+    goto leave;
+
   /* Setup an output stream and perform the get.  */
   outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
   if (!outfp)
@@ -1901,6 +1963,7 @@ cmd_ks_fetch (assuan_context_t ctx, char *line)
       es_fclose (outfp);
     }
 
+ leave:
   return leave_cmd (ctx, err);
 }
 
@@ -1936,6 +1999,10 @@ cmd_ks_put (assuan_context_t ctx, char *line)
   /* No options for now.  */
   line = skip_options (line);
 
+  err = ensure_keyserver (ctrl);
+  if (err)
+    goto leave;
+
   /* Ask for the key material.  */
   err = assuan_inquire (ctx, "KEYBLOCK",
                         &value, &valuelen, MAX_KEYBLOCK_LENGTH);
index 7757acf..a5bcc73 100644 (file)
@@ -242,6 +242,25 @@ This options is not yet functional!  It will eventually switch GnuPG
 into a TOR mode to route all network access via TOR (an anonymity
 network).
 
+@item --keyserver @code{name}
+@opindex keyserver
+Use @code{name} as your keyserver.  This is the server that @command{gpg}
+communicates with to receive keys, send keys, and search for
+keys.  The format of the @code{name} is a URI:
+`scheme:[//]keyservername[:port]' The scheme is the type of keyserver:
+"hkp" for the HTTP (or compatible) keyservers, "ldap" for the LDAP
+keyservers, or "mailto" for the Graff email keyserver. Note that your
+particular installation of GnuPG may have other keyserver types
+available as well. Keyserver schemes are case-insensitive. After the
+keyserver name, optional keyserver configuration options may be
+provided. These are the same as the global @option{--keyserver-options}
+from below, but apply only to this particular keyserver.
+
+Most keyservers synchronize with each other, so there is generally no
+need to send keys to more than one server. The keyserver
+@code{hkp://keys.gnupg.net} uses round robin DNS to give a different
+keyserver each time you use it.
+
 @item --disable-ldap
 @opindex disable-ldap
 Entirely disables the use of LDAP.