dirmngr: Support the new WKD draft with the openpgpkey subdomain.

* dirmngr/server.c (proc_wkd_get): Implement new openpgpkey subdomain
method.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2018-11-13 11:35:39 +01:00
parent b3a70b67f3
commit 914fa3be22
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
3 changed files with 68 additions and 19 deletions

View File

@ -1056,16 +1056,17 @@ resolve_name_standard (ctrl_t ctrl, const char *name, unsigned short port,
/* This a wrapper around getaddrinfo with slightly different semantics. /* This a wrapper around getaddrinfo with slightly different semantics.
NAME is the name to resolve. * NAME is the name to resolve.
PORT is the requested port or 0. * PORT is the requested port or 0.
WANT_FAMILY is either 0 (AF_UNSPEC), AF_INET6, or AF_INET4. * WANT_FAMILY is either 0 (AF_UNSPEC), AF_INET6, or AF_INET4.
WANT_SOCKETTYPE is either SOCK_STREAM or SOCK_DGRAM. * WANT_SOCKETTYPE is either 0 for any socket type
* or SOCK_STREAM or SOCK_DGRAM.
On success the result is stored in a linked list with the head *
stored at the address R_AI; the caller must call gpg_addrinfo_free * On success the result is stored in a linked list with the head
on this. If R_CANONNAME is not NULL the official name of the host * stored at the address R_AI; the caller must call free_dns_addrinfo
is stored there as a malloced string; if that name is not available * on this. If R_CANONNAME is not NULL the official name of the host
NULL is stored. */ * is stored there as a malloced string; if that name is not available
* NULL is stored. */
gpg_error_t gpg_error_t
resolve_dns_name (ctrl_t ctrl, const char *name, unsigned short port, resolve_dns_name (ctrl_t ctrl, const char *name, unsigned short port,
int want_family, int want_socktype, int want_family, int want_socktype,

View File

@ -119,7 +119,7 @@ domaininfo_print_stats (void)
} }
/* Return true if DOMAIN definitely does not support WKD. Noet that /* Return true if DOMAIN definitely does not support WKD. Note that
* DOMAIN is expected to be lowercase. */ * DOMAIN is expected to be lowercase. */
int int
domaininfo_is_wkd_not_supported (const char *domain) domaininfo_is_wkd_not_supported (const char *domain)

View File

@ -837,8 +837,11 @@ proc_wkd_get (ctrl_t ctrl, assuan_context_t ctx, char *line)
gpg_error_t err = 0; gpg_error_t err = 0;
char *mbox = NULL; char *mbox = NULL;
char *domainbuf = NULL; char *domainbuf = NULL;
char *domain; /* Points to mbox or domainbuf. */ char *domain; /* Points to mbox or domainbuf. This is used to
char *domain_orig;/* Points to mbox. */ * 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 sha1buf[20];
char *uri = NULL; char *uri = NULL;
char *encodedhash = 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 is_wkd_query; /* True if this is a real WKD query. */
int no_log = 0; int no_log = 0;
char portstr[20] = { 0 }; char portstr[20] = { 0 };
int subdomain_mode = 0;
opt_submission_addr = has_option (line, "--submission-address"); opt_submission_addr = has_option (line, "--submission-address");
opt_policy_flags = has_option (line, "--policy-flags"); 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++ = 0;
domain_orig = domain; 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. */ * support WKD. */
if (is_wkd_query) 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; struct srventry *srvs;
unsigned int srvscount; unsigned int srvscount;
@ -931,6 +969,7 @@ proc_wkd_get (ctrl_t ctrl, assuan_context_t ctx, char *line)
xfree (srvs); xfree (srvs);
} }
/* Prepare the hash of the local part. */
gcry_md_hash_buffer (GCRY_MD_SHA1, sha1buf, mbox, strlen (mbox)); gcry_md_hash_buffer (GCRY_MD_SHA1, sha1buf, mbox, strlen (mbox));
encodedhash = zb32_encode (sha1buf, 8*20); encodedhash = zb32_encode (sha1buf, 8*20);
if (!encodedhash) if (!encodedhash)
@ -944,7 +983,10 @@ proc_wkd_get (ctrl_t ctrl, assuan_context_t ctx, char *line)
uri = strconcat ("https://", uri = strconcat ("https://",
domain, domain,
portstr, portstr,
"/.well-known/openpgpkey/submission-address", "/.well-known/openpgpkey/",
subdomain_mode? domain_orig : "",
subdomain_mode? "/" : "",
"submission-address",
NULL); NULL);
} }
else if (opt_policy_flags) else if (opt_policy_flags)
@ -952,7 +994,10 @@ proc_wkd_get (ctrl_t ctrl, assuan_context_t ctx, char *line)
uri = strconcat ("https://", uri = strconcat ("https://",
domain, domain,
portstr, portstr,
"/.well-known/openpgpkey/policy", "/.well-known/openpgpkey/",
subdomain_mode? domain_orig : "",
subdomain_mode? "/" : "",
"policy",
NULL); NULL);
} }
else else
@ -965,7 +1010,10 @@ proc_wkd_get (ctrl_t ctrl, assuan_context_t ctx, char *line)
uri = strconcat ("https://", uri = strconcat ("https://",
domain, domain,
portstr, portstr,
"/.well-known/openpgpkey/hu/", "/.well-known/openpgpkey/",
subdomain_mode? domain_orig : "",
subdomain_mode? "/" : "",
"hu/",
encodedhash, encodedhash,
"?l=", "?l=",
escapedmbox, escapedmbox,