[git] GnuPG - branch, master, updated. gnupg-2.1.17-47-g88dc3af

by Werner Koch cvs at cvs.gnupg.org
Sun Jan 8 18:45:54 CET 2017


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  88dc3af3d4ae1afe1d5e136bc4c38bc4e7d4cd10 (commit)
       via  714faea4fa7f30d42e9986358214a99aa8fa57b3 (commit)
       via  16078f3deea5b82ea26e2f01dbd3ef3a5ce25410 (commit)
       via  9fa94aa10778bbd680315e93b23175423e338c40 (commit)
      from  8d774904c8066d8c0f19cfffe2d568979bb8c470 (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 88dc3af3d4ae1afe1d5e136bc4c38bc4e7d4cd10
Author: Werner Koch <wk at gnupg.org>
Date:   Sun Jan 8 18:42:50 2017 +0100

    dirmngr: Implement experimental SRV record lookup for WKD.
    
    * dirmngr/server.c (cmd_wkd_get): Support SRV records.
    --
    
    This patch changes the way a WKD query is done.  Now we first look for
    a SRV record for service "openpgpkey" and port "tcp" under the
    to-be-queried domain.  If such a record was found and the target host
    matches the to-be-queried domain or is a suffix to that domain, that
    target host is used instead of the domain name.  The SRV record also
    allows to change the port and obviously can be used for
    load-balancing.
    
    For example a query for the submission address of example.org with the
    SRV record specification
    
    _openpgpkey._tcp        IN     SRV   0 0  0    wkd.foo.org.
                            IN     SRV   0 0  0    wkd.example.net.
                            IN     SRV   0 0  4711 wkd.example.org.
    
    (queried using the name "_openpgpkey._tcp.example.org") would fetch
    from this URL:
    
     https://wkd.example.org:4711/.well-known/openpgpkey/submission-address
    
    Note that the first two SRV records won't be used because foo.org and
    example.net do not match example.org.  We require that the target host
    is identical to the domain or be a subdomain of it.  This is so that
    an attacker modifying the SRV records needs to setup a server in a
    sub-domain of the actual domain and can't use an arbitrary domain.
    Whether this is a sufficient requirement is not clear and needs
    further discussion.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/dirmngr/server.c b/dirmngr/server.c
index 28c2cd4..c9c4ad4 100644
--- a/dirmngr/server.c
+++ b/dirmngr/server.c
@@ -826,13 +826,15 @@ cmd_wkd_get (assuan_context_t ctx, char *line)
   ctrl_t ctrl = assuan_get_pointer (ctx);
   gpg_error_t err = 0;
   char *mbox = NULL;
-  char *domain;     /* Points to mbox.  */
+  char *domainbuf = NULL;
+  char *domain;     /* Points to mbox or domainbuf.  */
   char sha1buf[20];
   char *uri = NULL;
   char *encodedhash = NULL;
   int opt_submission_addr;
   int opt_policy_flags;
   int no_log = 0;
+  char portstr[20] = { 0 };
 
   opt_submission_addr = has_option (line, "--submission-address");
   opt_policy_flags = has_option (line, "--policy-flags");
@@ -846,6 +848,50 @@ cmd_wkd_get (assuan_context_t ctx, char *line)
     }
   *domain++ = 0;
 
+  /* Check for SRV records.  */
+  if (1)
+    {
+      struct srventry *srvs;
+      unsigned int srvscount;
+      size_t domainlen, targetlen;
+      int i;
+
+      err = get_dns_srv (domain, "openpgpkey", NULL, &srvs, &srvscount);
+      if (err)
+        goto leave;
+
+      /* Find the first target which also ends in DOMAIN or is equal
+       * to DOMAIN.  */
+      domainlen = strlen (domain);
+      for (i = 0; i < srvscount; i++)
+        {
+          log_debug ("srv: trying '%s:%hu'\n", srvs[i].target, srvs[i].port);
+          targetlen = strlen (srvs[i].target);
+          if ((targetlen > domainlen + 1
+               && srvs[i].target[targetlen - domainlen - 1] == '.'
+               && !ascii_strcasecmp (srvs[i].target + targetlen - domainlen,
+                                     domain))
+              || (targetlen == domainlen
+                  && !ascii_strcasecmp (srvs[i].target, domain)))
+            {
+              /* found.  */
+              domainbuf = xtrystrdup (srvs[i].target);
+              if (!domainbuf)
+                {
+                  err = gpg_error_from_syserror ();
+                  xfree (srvs);
+                  goto leave;
+                }
+              domain = domainbuf;
+              if (srvs[i].port)
+                snprintf (portstr, sizeof portstr, ":%hu", srvs[i].port);
+              break;
+            }
+        }
+      xfree (srvs);
+      log_debug ("srv: got '%s%s'\n", domain, portstr);
+    }
+
   gcry_md_hash_buffer (GCRY_MD_SHA1, sha1buf, mbox, strlen (mbox));
   encodedhash = zb32_encode (sha1buf, 8*20);
   if (!encodedhash)
@@ -858,6 +904,7 @@ cmd_wkd_get (assuan_context_t ctx, char *line)
     {
       uri = strconcat ("https://",
                        domain,
+                       portstr,
                        "/.well-known/openpgpkey/submission-address",
                        NULL);
     }
@@ -865,6 +912,7 @@ cmd_wkd_get (assuan_context_t ctx, char *line)
     {
       uri = strconcat ("https://",
                        domain,
+                       portstr,
                        "/.well-known/openpgpkey/policy",
                        NULL);
     }
@@ -872,6 +920,7 @@ cmd_wkd_get (assuan_context_t ctx, char *line)
     {
       uri = strconcat ("https://",
                        domain,
+                       portstr,
                        "/.well-known/openpgpkey/hu/",
                        encodedhash,
                        NULL);
@@ -907,6 +956,7 @@ cmd_wkd_get (assuan_context_t ctx, char *line)
   xfree (uri);
   xfree (encodedhash);
   xfree (mbox);
+  xfree (domainbuf);
   return leave_cmd (ctx, err);
 }
 

commit 714faea4fa7f30d42e9986358214a99aa8fa57b3
Author: Werner Koch <wk at gnupg.org>
Date:   Sun Jan 8 18:07:18 2017 +0100

    dirmngr: Improve debug output for TLS.
    
    * dirmngr/misc.c (dump_cert): Also print SubjectAltNames.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/dirmngr/misc.c b/dirmngr/misc.c
index ac3856e..2ee6d82 100644
--- a/dirmngr/misc.c
+++ b/dirmngr/misc.c
@@ -296,6 +296,7 @@ dump_cert (const char *text, ksba_cert_t cert)
   ksba_sexp_t sexp;
   char *p;
   ksba_isotime_t t;
+  int idx;
 
   log_debug ("BEGIN Certificate '%s':\n", text? text:"");
   if (cert)
@@ -326,6 +327,13 @@ dump_cert (const char *text, ksba_cert_t cert)
       dump_string (p);
       ksba_free (p);
       log_printf ("\n");
+      for (idx=1; (p = ksba_cert_get_subject (cert, idx)); idx++)
+        {
+          log_debug ("        aka: ");
+          dump_string (p);
+          ksba_free (p);
+          log_printf ("\n");
+        }
 
       log_debug ("  hash algo: %s\n", ksba_cert_get_digest_algo (cert));
 

commit 16078f3deea5b82ea26e2f01dbd3ef3a5ce25410
Author: Werner Koch <wk at gnupg.org>
Date:   Sun Jan 8 18:04:59 2017 +0100

    dirmngr: Change internal SRV lookup API.
    
    * dirmngr/dns-stuff.c (get_dns_srv): Add args SERVICE and PROTO.
    * dirmngr/http.c (connect_server): Simplify SRV lookup.
    * dirmngr/ks-engine-hkp.c (map_host): Ditto.
    * dirmngr/t-dns-stuff.c (main): Adjust for changed get_dns_srv.
    --
    
    This new API is more convenient because it includes commonly used
    code.  Note that right now http.c's SRV record code is not used.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
index 028b065..a8713eb 100644
--- a/dirmngr/dns-stuff.c
+++ b/dirmngr/dns-stuff.c
@@ -1740,17 +1740,37 @@ getsrv_standard (const char *name,
 }
 
 
-/* Note that we do not return NONAME but simply store 0 at R_COUNT.  */
+/* Query a SRV record for SERVICE and PROTO for NAME.  If SERVICE is
+ * NULL, NAME is expected to contain the full query name.  Note that
+ * we do not return NONAME but simply store 0 at R_COUNT.  On error an
+ * error code is returned and 0 stored at R_COUNT.  */
 gpg_error_t
-get_dns_srv (const char *name, struct srventry **list, unsigned int *r_count)
+get_dns_srv (const char *name, const char *service, const char *proto,
+             struct srventry **list, unsigned int *r_count)
 {
   gpg_error_t err;
+  char *namebuffer = NULL;
   unsigned int srvcount;
   int i;
 
   *list = NULL;
   *r_count = 0;
   srvcount = 0;
+
+  /* If SERVICE is given construct the query from it and PROTO.  */
+  if (service)
+    {
+      namebuffer = xtryasprintf ("_%s._%s.%s",
+                                 service, proto? proto:"tcp", name);
+      if (!namebuffer)
+        {
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
+      name = namebuffer;
+    }
+
+
 #ifdef USE_LIBDNS
   if (!standard_resolver)
     {
@@ -1852,6 +1872,7 @@ get_dns_srv (const char *name, struct srventry **list, unsigned int *r_count)
     }
   if (!err)
     *r_count = srvcount;
+  xfree (namebuffer);
   return err;
 }
 
diff --git a/dirmngr/dns-stuff.h b/dirmngr/dns-stuff.h
index eb7fe72..d68dd17 100644
--- a/dirmngr/dns-stuff.h
+++ b/dirmngr/dns-stuff.h
@@ -153,6 +153,7 @@ gpg_error_t get_dns_cert (const char *name, int want_certtype,
 
 /* Return an array of SRV records.  */
 gpg_error_t get_dns_srv (const char *name,
+                         const char *service, const char *proto,
                          struct srventry **list, unsigned int *r_count);
 
 
diff --git a/dirmngr/http.c b/dirmngr/http.c
index 14d60df..7a02804 100644
--- a/dirmngr/http.c
+++ b/dirmngr/http.c
@@ -2362,29 +2362,11 @@ connect_server (const char *server, unsigned short port,
   /* Do the SRV thing */
   if (srvtag)
     {
-      /* We're using SRV, so append the tags. */
-      if (1 + strlen (srvtag) + 6 + strlen (server) + 1
-          <= DIMof (struct srventry, target))
-	{
-	  char *srvname = xtrymalloc (DIMof (struct srventry, target));
-
-          if (!srvname) /* Out of core */
-            {
-              serverlist = NULL;
-              srvcount = 0;
-            }
-          else
-            {
-              stpcpy (stpcpy (stpcpy (stpcpy (srvname,"_"), srvtag),
-                              "._tcp."), server);
-              err = get_dns_srv (srvname, &serverlist, &srvcount);
-              if (err)
-                log_info ("getting SRV '%s' failed: %s\n",
-                          srvname, gpg_strerror (err));
-              xfree (srvname);
-              /* Note that on error SRVCOUNT is zero.  */
-            }
-	}
+      err = get_dns_srv (server, srvtag, NULL, &serverlist, &srvcount);
+      if (err)
+        log_info ("getting '%s' SRV for '%s' failed: %s\n",
+                  srvtag, server, gpg_strerror (err));
+      /* Note that on error SRVCOUNT is zero.  */
     }
 
   if (!serverlist)
diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c
index a6c22f8..283e805 100644
--- a/dirmngr/ks-engine-hkp.c
+++ b/dirmngr/ks-engine-hkp.c
@@ -426,7 +426,6 @@ map_host (ctrl_t ctrl, const char *name, int force_reselect,
       int refidx;
       int is_pool = 0;
       char *cname;
-      char *srvrecord;
       struct srventry *srvs;
       unsigned int srvscount;
 
@@ -448,16 +447,7 @@ map_host (ctrl_t ctrl, const char *name, int force_reselect,
       if (!is_ip_address (name))
         {
           /* Check for SRV records.  */
-          srvrecord = xtryasprintf ("_hkp._tcp.%s", name);
-          if (srvrecord == NULL)
-            {
-              err = gpg_error_from_syserror ();
-              xfree (reftbl);
-              return err;
-            }
-
-          err = get_dns_srv (srvrecord, &srvs, &srvscount);
-          xfree (srvrecord);
+          err = get_dns_srv (name, "hkp", NULL, &srvs, &srvscount);
           if (err)
             {
               xfree (reftbl);
diff --git a/dirmngr/t-dns-stuff.c b/dirmngr/t-dns-stuff.c
index bc4ca9a..23c0c6a 100644
--- a/dirmngr/t-dns-stuff.c
+++ b/dirmngr/t-dns-stuff.c
@@ -235,7 +235,7 @@ main (int argc, char **argv)
       int i;
 
       err = get_dns_srv (name? name : "_hkp._tcp.wwwkeys.pgp.net",
-                         &srv, &count);
+                         NULL, NULL, &srv, &count);
       if (err)
         printf ("get_dns_srv failed: %s <%s>\n",
                 gpg_strerror (err), gpg_strsource (err));

commit 9fa94aa10778bbd680315e93b23175423e338c40
Author: Werner Koch <wk at gnupg.org>
Date:   Sun Jan 8 18:00:38 2017 +0100

    dirmngr: Strip root zone suffix from libdns SRV results.
    
    * dirmngr/dns-stuff.c (getsrv_libdns): Strip trailing dot from the
    target.
    --
    
    See-also: b200e636ab20d2aa93d9f71f3789db5a04af0a56
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
index e32e1e3..028b065 100644
--- a/dirmngr/dns-stuff.c
+++ b/dirmngr/dns-stuff.c
@@ -1591,6 +1591,10 @@ getsrv_libdns (const char *name, struct srventry **list, unsigned int *r_count)
       srv->weight   = dsrv.weight;
       srv->port     = dsrv.port;
       mem2str (srv->target, dsrv.target, sizeof srv->target);
+      /* Libdns appends the root zone part which is problematic for
+       * most other functions - strip it.  */
+      if (*srv->target && (srv->target)[strlen (srv->target)-1] == '.')
+        (srv->target)[strlen (srv->target)-1] = 0;
     }
 
   *r_count = srvcount;

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

Summary of changes:
 dirmngr/dns-stuff.c     | 29 +++++++++++++++++++++++++--
 dirmngr/dns-stuff.h     |  1 +
 dirmngr/http.c          | 28 +++++---------------------
 dirmngr/ks-engine-hkp.c | 12 +-----------
 dirmngr/misc.c          |  8 ++++++++
 dirmngr/server.c        | 52 ++++++++++++++++++++++++++++++++++++++++++++++++-
 dirmngr/t-dns-stuff.c   |  2 +-
 7 files changed, 94 insertions(+), 38 deletions(-)


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




More information about the Gnupg-commits mailing list