[Pkg-gnupg-commit] [gnupg2] 47/116: dirmngr: Implement experimental SRV record lookup for WKD.

Daniel Kahn Gillmor dkg at fifthhorseman.net
Tue Jan 24 04:40:52 UTC 2017


This is an automated email from the git hooks/post-receive script.

dkg pushed a commit to branch master
in repository gnupg2.

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>
---
 dirmngr/server.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 51 insertions(+), 1 deletion(-)

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);
 }
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-gnupg/gnupg2.git



More information about the Pkg-gnupg-commit mailing list