[git] GnuPG - branch, master, updated. gnupg-2.1.9-207-g28e2513

by Werner Koch cvs at cvs.gnupg.org
Wed Dec 2 12:31:50 CET 2015


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU Privacy Guard".

The branch, master has been updated
       via  28e2513721ff0cec920564d4087f3600cce8672e (commit)
       via  17ac843871d5f350f26edff0187f94ced923f534 (commit)
      from  10cca02c4c70eee993d4df0a1d20ae841992efe9 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 28e2513721ff0cec920564d4087f3600cce8672e
Author: Werner Koch <wk at gnupg.org>
Date:   Wed Dec 2 11:49:41 2015 +0100

    dirmngr: Switch to an onion address if Tor is running.
    
    * dirmngr/dirmngr.h (opt): Turn field 'keyserver' into an strlist.
    * dirmngr/dirmngr.c (parse_rereadable_options): Allow multiple
    --keyserver options.
    * dirmngr/server.c (server_local_s): Add field 'tor_state'.
    (release_uri_item_list): New.
    (release_ctrl_keyservers): Use it.
    (start_command_handler): Release list of keyservers.
    (is_tor_running): New.
    (cmd_getinfo): Re-implement "tor" subcommand using new fucntion.
    (ensure_keyserver): Rewrite.
    * g10/dirmngr-conf.skel: Add two keyserver options.
    --
    
    This feature is independent of --use-tor and automagically uses Tor if
    available.  The dirmngr.conf file needs to specify two keyservers to
    make this work.  For new installations this is done using the skeleton
    file.  This feature requires the Libassuan 2.4.2 to work.
    
    This patch also fixes a memory leak of opt.keyserver en passant.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c
index ccefc3c..97d2e15 100644
--- a/dirmngr/dirmngr.c
+++ b/dirmngr/dirmngr.c
@@ -541,8 +541,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
         }
       FREE_STRLIST (opt.ignored_cert_extensions);
       http_register_tls_ca (NULL);
-      xfree (opt.keyserver);
-      opt.keyserver = NULL;
+      FREE_STRLIST (opt.keyserver);
       /* Note: We do not allow resetting of opt.use_tor at runtime.  */
       return 1;
     }
@@ -622,8 +621,8 @@ 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;
+      if (*pargs->r.ret_str)
+        add_to_strlist (&opt.keyserver, pargs->r.ret_str);
       break;
 
     case oNameServer:
diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h
index b2b14cc..6078884 100644
--- a/dirmngr/dirmngr.h
+++ b/dirmngr/dirmngr.h
@@ -131,7 +131,7 @@ struct
   unsigned int ocsp_current_period; /* Seconds a response is considered
                                        current after nextUpdate. */
 
-  char *keyserver;    /* Malloced string with the default keyserver.  */
+  strlist_t keyserver;              /* List of default keyservers.  */
 } opt;
 
 
diff --git a/dirmngr/server.c b/dirmngr/server.c
index 32c265b..21cb2dc 100644
--- a/dirmngr/server.c
+++ b/dirmngr/server.c
@@ -91,6 +91,9 @@ struct server_local_s
   /* If this flag is set to true this dirmngr process will be
      terminated after the end of this session.  */
   int stopme;
+
+  /* State variable private to is_tor_running.  */
+  int tor_state;
 };
 
 
@@ -120,6 +123,18 @@ get_ldapservers_from_ctrl (ctrl_t ctrl)
     return NULL;
 }
 
+/* Release an uri_item_t list.  */
+static void
+release_uri_item_list (uri_item_t list)
+{
+  while (list)
+    {
+      uri_item_t tmp = list->next;
+      http_release_parsed_uri (list->parsed_uri);
+      xfree (list);
+      list = tmp;
+    }
+}
 
 /* Release all configured keyserver info from CTRL.  */
 void
@@ -128,13 +143,8 @@ release_ctrl_keyservers (ctrl_t ctrl)
   if (! ctrl->server_local)
     return;
 
-  while (ctrl->server_local->keyservers)
-    {
-      uri_item_t tmp = ctrl->server_local->keyservers->next;
-      http_release_parsed_uri (ctrl->server_local->keyservers->parsed_uri);
-      xfree (ctrl->server_local->keyservers);
-      ctrl->server_local->keyservers = tmp;
-    }
+  release_uri_item_list (ctrl->server_local->keyservers);
+  ctrl->server_local->keyservers = NULL;
 }
 
 
@@ -335,6 +345,38 @@ skip_options (char *line)
 }
 
 
+/* This fucntion returns true if a Tor server is running.  The sattus
+   is cached for the current conenction.  */
+static int
+is_tor_running (ctrl_t ctrl)
+{
+#if ASSUAN_VERSION_NUMBER >= 0x020402
+  /* Check whether we can connect to the proxy.  We use a
+     special feature introduced with libassuan 2.4.2.  */
+
+  if (!ctrl || !ctrl->server_local)
+    return 0; /* Ooops.  */
+
+  if (!ctrl->server_local->tor_state)
+    {
+      assuan_fd_t sock;
+
+      sock = assuan_sock_connect_byname (NULL, 0, 0, NULL, ASSUAN_SOCK_TOR);
+      if (sock == ASSUAN_INVALID_FD)
+        ctrl->server_local->tor_state = -1; /* Not running.  */
+      else
+        {
+          assuan_sock_close (sock);
+          ctrl->server_local->tor_state = 1; /* Running.  */
+        }
+    }
+  return (ctrl->server_local->tor_state > 0);
+#else /* Libassuan < 2.4.2 */
+  return 0;  /* We don't know.  */
+#endif
+}
+
+
 /* Return an error if the assuan context does not belong to the owner
    of the process or to root.  On error FAILTEXT is set as Assuan
    error string.  */
@@ -1710,15 +1752,74 @@ ensure_keyserver (ctrl_t ctrl)
 {
   gpg_error_t err;
   uri_item_t item;
+  uri_item_t onion_items = NULL;
+  uri_item_t plain_items = NULL;
+  uri_item_t ui;
+  strlist_t sl;
 
   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;
+  for (sl = opt.keyserver; sl; sl = sl->next)
+    {
+      err = make_keyserver_item (sl->d, &item);
+      if (err)
+        goto leave;
+      if (item->parsed_uri->onion)
+        {
+          item->next = onion_items;
+          onion_items = item;
+        }
+      else
+        {
+          item->next = plain_items;
+          plain_items = item;
+        }
+    }
+
+  /* Decide which to use.  Note that the sesssion has no keyservers
+     yet set. */
+  if (onion_items && !onion_items->next && plain_items && !plain_items->next)
+    {
+      /* If there is just one onion and one plain keyserver given, we take
+         only one depending on whether Tor is running or not.  */
+      if (is_tor_running (ctrl))
+        {
+          ctrl->server_local->keyservers = onion_items;
+          onion_items = NULL;
+        }
+      else
+        {
+          ctrl->server_local->keyservers = plain_items;
+          plain_items = NULL;
+        }
+    }
+  else if (!is_tor_running (ctrl))
+    {
+      /* Tor is not running.  It does not make sense to add Onion
+         addresses.  */
+      ctrl->server_local->keyservers = plain_items;
+      plain_items = NULL;
+    }
+  else
+    {
+      /* In all other cases add all keyservers.  */
+      ctrl->server_local->keyservers = onion_items;
+      onion_items = NULL;
+      for (ui = ctrl->server_local->keyservers; ui && ui->next; ui = ui->next)
+        ;
+      if (ui)
+        ui->next = plain_items;
+      else
+        ctrl->server_local->keyservers = plain_items;
+      plain_items = NULL;
+    }
+
+ leave:
+  release_uri_item_list (onion_items);
+  release_uri_item_list (plain_items);
 
   return err;
 }
@@ -2093,6 +2194,7 @@ static const char hlp_getinfo[] =
 static gpg_error_t
 cmd_getinfo (assuan_context_t ctx, char *line)
 {
+  ctrl_t ctrl = assuan_get_pointer (ctx);
   gpg_error_t err;
 
   if (!strcmp (line, "version"))
@@ -2123,24 +2225,11 @@ cmd_getinfo (assuan_context_t ctx, char *line)
     {
       if (opt.use_tor)
         {
-#if ASSUAN_VERSION_NUMBER >= 0x020402
-          /* Check whether we can connect to the proxy.  We use a
-             special feature introduced with libassuan 2.4.2.  */
-          assuan_fd_t sock = assuan_sock_connect_byname (NULL, 0, 0, NULL,
-                                                         ASSUAN_SOCK_TOR);
-          if (sock == ASSUAN_INVALID_FD)
-            {
-              err = assuan_write_status
-                (ctx, "NO_TOR",
-                 errno == ECONNREFUSED? "Tor not running" : strerror (errno));
-            }
+          if (!is_tor_running (ctrl))
+            err = assuan_write_status (ctx, "NO_TOR", "Tor not running");
           else
-            {
-              assuan_sock_close (sock);
-              err = 0;
-            }
+            err = 0;
           if (!err)
-#endif /* Libassuan >= 2.4.2 */
             assuan_set_okay_line (ctx, "- Tor mode is enabled");
         }
       else
@@ -2398,6 +2487,7 @@ start_command_handler (assuan_fd_t fd)
         }
     }
 
+
 #if USE_LDAP
   ldap_wrapper_connection_cleanup (ctrl);
 
@@ -2405,6 +2495,8 @@ start_command_handler (assuan_fd_t fd)
 #endif /*USE_LDAP*/
   ctrl->server_local->ldapservers = NULL;
 
+  release_ctrl_keyservers (ctrl);
+
   ctrl->server_local->assuan_ctx = NULL;
   assuan_release (ctx);
 
diff --git a/doc/dirmngr.texi b/doc/dirmngr.texi
index 6a4d6d6..5b73d7b 100644
--- a/doc/dirmngr.texi
+++ b/doc/dirmngr.texi
@@ -263,6 +263,11 @@ 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.
 
+If exactly two keyservers are configured and only one is a Tor hidden
+service (.onion), Dirmngr selects the keyserver to use depending on
+whether Tor is locally running or not.  The check for a running Tor is
+done for each new connection.
+
 
 @item --nameserver @var{ipaddr}
 @opindex nameserver
diff --git a/g10/dirmngr-conf.skel b/g10/dirmngr-conf.skel
index 2ba5e4d..d5a02d9 100644
--- a/g10/dirmngr-conf.skel
+++ b/g10/dirmngr-conf.skel
@@ -49,7 +49,12 @@
 # servers via DNS round-robin.  hkp://keys.gnupg.net is an example of
 # such a "server", which spreads the load over a number of physical
 # servers.
+#
+# If exactly two keyservers are configured and only one is a Tor hidden
+# service, Dirmngr selects the keyserver to use depending on whether
+# Tor is locally running or not (on a per session base).
 
+keyserver hkp://dyh2j3qyrirn43iw.onion
 keyserver hkp://keys.gnupg.net
 
 # --hkp-cacert FILENAME

commit 17ac843871d5f350f26edff0187f94ced923f534
Author: Werner Koch <wk at gnupg.org>
Date:   Wed Dec 2 10:12:32 2015 +0100

    http: Enhance parser to detect .onion addresses.
    
    * dirmngr/http.h (parsed_uri_s): Add flag 'onion'.
    * dirmngr/http.c (do_parse_uri): Set that flag.
    * dirmngr/t-http.c (main): Print flags.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/dirmngr/http.c b/dirmngr/http.c
index d623f7e..6427951 100644
--- a/dirmngr/http.c
+++ b/dirmngr/http.c
@@ -1086,6 +1086,7 @@ do_parse_uri (parsed_uri_t uri, int only_local_part,
   uri->is_http = 0;
   uri->opaque = 0;
   uri->v6lit = 0;
+  uri->onion = 0;
 
   /* A quick validity check. */
   if (strspn (p, VALID_URI_CHARS) != n)
@@ -1172,49 +1173,54 @@ do_parse_uri (parsed_uri_t uri, int only_local_part,
         {
           uri->opaque = 1;
           uri->path = p;
+          if (is_onion_address (uri->path))
+            uri->onion = 1;
           return 0;
         }
 
     } /* End global URI part. */
 
-  /* Parse the pathname part */
-  if (!p || !*p)
-    return 0;  /* We don't have a path.  Okay. */
-
-  /* TODO: Here we have to check params. */
-
-  /* Do we have a query part? */
-  if ((p2 = strchr (p, '?')))
-    *p2++ = 0;
-
-  uri->path = p;
-  if ((n = remove_escapes (p)) < 0)
-    return GPG_ERR_BAD_URI;
-  if (n != strlen (p))
-    return GPG_ERR_BAD_URI;	/* Path includes a Nul. */
-  p = p2 ? p2 : NULL;
-
-  if (!p || !*p)
-    return 0; /* We don't have a query string.  Okay. */
-
-  /* Now parse the query string. */
-  tail = &uri->query;
-  for (;;)
+  /* Parse the pathname part if any.  */
+  if (p && *p)
     {
-      uri_tuple_t elem;
+      /* TODO: Here we have to check params. */
 
-      if ((p2 = strchr (p, '&')))
-	*p2++ = 0;
-      if (!(elem = parse_tuple (p)))
-	return GPG_ERR_BAD_URI;
-      *tail = elem;
-      tail = &elem->next;
+      /* Do we have a query part? */
+      if ((p2 = strchr (p, '?')))
+        *p2++ = 0;
 
-      if (!p2)
-	break; /* Ready. */
-      p = p2;
+      uri->path = p;
+      if ((n = remove_escapes (p)) < 0)
+        return GPG_ERR_BAD_URI;
+      if (n != strlen (p))
+        return GPG_ERR_BAD_URI;	/* Path includes a Nul. */
+      p = p2 ? p2 : NULL;
+
+      /* Parse a query string if any.  */
+      if (p && *p)
+        {
+          tail = &uri->query;
+          for (;;)
+            {
+              uri_tuple_t elem;
+
+              if ((p2 = strchr (p, '&')))
+                *p2++ = 0;
+              if (!(elem = parse_tuple (p)))
+                return GPG_ERR_BAD_URI;
+              *tail = elem;
+              tail = &elem->next;
+
+              if (!p2)
+                break; /* Ready. */
+              p = p2;
+            }
+        }
     }
 
+  if (is_onion_address (uri->host))
+    uri->onion = 1;
+
   return 0;
 }
 
diff --git a/dirmngr/http.h b/dirmngr/http.h
index 73a423c..64f55e1 100644
--- a/dirmngr/http.h
+++ b/dirmngr/http.h
@@ -52,6 +52,7 @@ struct parsed_uri_s
   unsigned int use_tls:1; /* Whether TLS should be used. */
   unsigned int opaque:1;/* Unknown scheme; PATH has the rest.  */
   unsigned int v6lit:1; /* Host was given as a literal v6 address.  */
+  unsigned int onion:1; /* .onion address given.  */
   char *auth;           /* username/password for basic auth.  */
   char *host; 	        /* Host (converted to lowercase). */
   unsigned short port;  /* Port (always set if the host is set). */
diff --git a/dirmngr/t-http.c b/dirmngr/t-http.c
index 35858f6..63662a2 100644
--- a/dirmngr/t-http.c
+++ b/dirmngr/t-http.c
@@ -323,6 +323,11 @@ main (int argc, char **argv)
             }
           putchar ('\n');
         }
+      printf ("Flags :%s%s%s%s\n",
+              uri->is_http? " http":"",
+              uri->opaque?  " opaque":"",
+              uri->v6lit?   " v6lit":"",
+              uri->onion?   " onion":"");
       printf ("TLS   : %s\n",
               uri->use_tls? "yes":
               (my_http_flags&HTTP_FLAG_FORCE_TLS)? "forced" : "no");

-----------------------------------------------------------------------

Summary of changes:
 dirmngr/dirmngr.c     |   7 ++-
 dirmngr/dirmngr.h     |   2 +-
 dirmngr/http.c        |  72 +++++++++++++------------
 dirmngr/http.h        |   1 +
 dirmngr/server.c      | 144 +++++++++++++++++++++++++++++++++++++++++---------
 dirmngr/t-http.c      |   5 ++
 doc/dirmngr.texi      |   5 ++
 g10/dirmngr-conf.skel |   5 ++
 8 files changed, 177 insertions(+), 64 deletions(-)


hooks/post-receive
-- 
The GNU Privacy Guard
http://git.gnupg.org




More information about the Gnupg-commits mailing list