aboutsummaryrefslogtreecommitdiffstats
path: root/dirmngr/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'dirmngr/server.c')
-rw-r--r--dirmngr/server.c64
1 files changed, 56 insertions, 8 deletions
diff --git a/dirmngr/server.c b/dirmngr/server.c
index 272b95aa2..1b1e64b39 100644
--- a/dirmngr/server.c
+++ b/dirmngr/server.c
@@ -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 (ctrl, 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,