dirmngr: Support the new WKD draft with the openpgpkey subdomain.
authorWerner Koch <wk@gnupg.org>
Wed, 3 Jul 2019 13:29:41 +0000 (15:29 +0200)
committerDaniel Kahn Gillmor <dkg@fifthhorseman.net>
Fri, 1 Jul 2022 16:06:43 +0000 (17:06 +0100)
* dirmngr/server.c (proc_wkd_get): Implement new openpgpkey subdomain
method.

--
Also includes actual backport fix from
2c6d94702a676de9fadaaf003b9c80dc76c02f92

GnuPG-bug-id: 4590
Signed-off-by: Werner Koch <wk@gnupg.org>
(cherry picked from commit 914fa3be22bf8848a97a7dd405a040d6ef31e2fd)
(cherry picked from commit 458973f502b9a43ecf29e804a2c0c86e78f5927a)

Gbp-Pq: Topic from-2.2.17
Gbp-Pq: Name dirmngr-Support-the-new-WKD-draft-with-the-openpgpkey-sub.patch

dirmngr/server.c

index 272b95aa20d41e3f31d7287654ba7d8ea9302346..5e8ea5e8dfaeec7aedd1822ac7739c650b2f6387 100644 (file)
@@ -837,8 +837,11 @@ proc_wkd_get (ctrl_t ctrl, assuan_context_t ctx, char *line)
   gpg_error_t err = 0;
   char *mbox = NULL;
   char *domainbuf = NULL;
-  char *domain;     /* Points to mbox or domainbuf.  */
-  char *domain_orig;/* Points to mbox.  */
+  char *domain;     /* Points to mbox or domainbuf.  This is used to
+                     * connect to the host.  */
+  char *domain_orig;/* Points to mbox.  This is the used for the
+                     * query; i.e. the domain part of the
+                     * addrspec.  */
   char sha1buf[20];
   char *uri = NULL;
   char *encodedhash = NULL;
@@ -847,6 +850,7 @@ proc_wkd_get (ctrl_t ctrl, assuan_context_t ctx, char *line)
   int is_wkd_query;   /* True if this is a real WKD query.  */
   int no_log = 0;
   char portstr[20] = { 0 };
+  int subdomain_mode = 0;
 
   opt_submission_addr = has_option (line, "--submission-address");
   opt_policy_flags = has_option (line, "--policy-flags");
@@ -864,7 +868,8 @@ proc_wkd_get (ctrl_t ctrl, assuan_context_t ctx, char *line)
   *domain++ = 0;
   domain_orig = domain;
 
-  /* First check whether we already know that the domain does not
+
+  /* Let's check whether we already know that the domain does not
    * support WKD.  */
   if (is_wkd_query)
     {
@@ -875,8 +880,41 @@ proc_wkd_get (ctrl_t ctrl, assuan_context_t ctx, char *line)
         }
     }
 
-  /* Check for SRV records.  */
-  if (1)
+
+  /* First try the new "openpgp" subdomain.  We check that the domain
+   * is valid because it is later used as an unescaped filename part
+   * of the URI.  */
+  if (is_valid_domain_name (domain_orig))
+    {
+      dns_addrinfo_t aibuf;
+
+      domainbuf = strconcat ( "openpgpkey.", domain_orig, NULL);
+      if (!domainbuf)
+        {
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
+
+      /* FIXME: We should put a cache into dns-stuff because the same
+       * query (with a different port and socket type, though) will be
+       * done later by http function.  */
+      err = resolve_dns_name (domainbuf, 0, 0, 0, &aibuf, NULL);
+      if (err)
+        {
+          err = 0;
+          xfree (domainbuf);
+          domainbuf = NULL;
+        }
+      else /* Got a subdomain. */
+        {
+          free_dns_addrinfo (aibuf);
+          subdomain_mode = 1;
+          domain = domainbuf;
+        }
+    }
+
+  /* Check for SRV records unless we have a subdomain. */
+  if (!subdomain_mode)
     {
       struct srventry *srvs;
       unsigned int srvscount;
@@ -931,6 +969,7 @@ proc_wkd_get (ctrl_t ctrl, assuan_context_t ctx, char *line)
       xfree (srvs);
     }
 
+  /* Prepare the hash of the local part.  */
   gcry_md_hash_buffer (GCRY_MD_SHA1, sha1buf, mbox, strlen (mbox));
   encodedhash = zb32_encode (sha1buf, 8*20);
   if (!encodedhash)
@@ -944,7 +983,10 @@ proc_wkd_get (ctrl_t ctrl, assuan_context_t ctx, char *line)
       uri = strconcat ("https://",
                        domain,
                        portstr,
-                       "/.well-known/openpgpkey/submission-address",
+                       "/.well-known/openpgpkey/",
+                       subdomain_mode? domain_orig : "",
+                       subdomain_mode? "/" : "",
+                       "submission-address",
                        NULL);
     }
   else if (opt_policy_flags)
@@ -952,7 +994,10 @@ proc_wkd_get (ctrl_t ctrl, assuan_context_t ctx, char *line)
       uri = strconcat ("https://",
                        domain,
                        portstr,
-                       "/.well-known/openpgpkey/policy",
+                       "/.well-known/openpgpkey/",
+                       subdomain_mode? domain_orig : "",
+                       subdomain_mode? "/" : "",
+                       "policy",
                        NULL);
     }
   else
@@ -965,7 +1010,10 @@ proc_wkd_get (ctrl_t ctrl, assuan_context_t ctx, char *line)
           uri = strconcat ("https://",
                            domain,
                            portstr,
-                           "/.well-known/openpgpkey/hu/",
+                           "/.well-known/openpgpkey/",
+                           subdomain_mode? domain_orig : "",
+                           subdomain_mode? "/" : "",
+                           "hu/",
                            encodedhash,
                            "?l=",
                            escapedmbox,