/* server.c - LDAP and Keyserver access server
* Copyright (C) 2002 Klarälvdalens Datakonsult AB
* Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2011, 2015 g10 Code GmbH
- * Copyright (C) 2014 Werner Koch
+ * Copyright (C) 2014, 2015, 2016 Werner Koch
*
* This file is part of GnuPG.
*
#include "dns-stuff.h"
#include "mbox-util.h"
#include "zb32.h"
+#include "server-help.h"
/* To avoid DoS attacks we limit the size of a certificate to
something reasonable. The DoS was actually only an issue back when
}
-/* Check whether the option NAME appears in LINE */
-static int
-has_option (const char *line, const char *name)
-{
- const char *s;
- int n = strlen (name);
-
- s = strstr (line, name);
- return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
-}
-
-/* Same as has_option but only considers options at the begin of the
- line. This is useful for commands which allow arbitrary strings on
- the line. */
-static int
-has_leading_option (const char *line, const char *name)
-{
- const char *s;
- int n;
-
- if (name[0] != '-' || name[1] != '-' || !name[2] || spacep (name+2))
- return 0;
- n = strlen (name);
- while ( *line == '-' && line[1] == '-' )
- {
- s = line;
- while (*line && !spacep (line))
- line++;
- if (n == (line - s) && !strncmp (s, name, n))
- return 1;
- while (spacep (line))
- line++;
- }
- return 0;
-}
-
-
-/* Same as has_option but does only test for the name of the option
- and ignores an argument, i.e. with NAME being "--hash" it would
- return a pointer for "--hash" as well as for "--hash=foo". If
- thhere is no such option NULL is returned. The pointer returned
- points right behind the option name, this may be an equal sign, Nul
- or a space. */
-/* static const char * */
-/* has_option_name (const char *line, const char *name) */
-/* { */
-/* const char *s; */
-/* int n = strlen (name); */
-
-/* s = strstr (line, name); */
-/* return (s && (s == line || spacep (s-1)) */
-/* && (!s[n] || spacep (s+n) || s[n] == '=')) ? (s+n) : NULL; */
-/* } */
-
-
-/* Skip over options. It is assumed that leading spaces have been
- removed (this is the case for lines passed to a handler from
- assuan). Blanks after the options are also removed. */
-static char *
-skip_options (char *line)
-{
- while ( *line == '-' && line[1] == '-' )
- {
- while (*line && !spacep (line))
- line++;
- while (spacep (line))
- line++;
- }
- return line;
-}
-
-
/* This fucntion returns true if a Tor server is running. The sattus
is cached for the current conenction. */
static int
" * Return the first record of any supported subtype\n"
" PGP Return the first record of subtype PGP (3)\n"
" IPGP Return the first record of subtype IPGP (6)\n"
- "If the content of a certifciate is available (PGP) it is returned\n"
+ "If the content of a certificate is available (PGP) it is returned\n"
"by data lines. Fingerprints and URLs are returned via status lines.\n"
"In --pka mode the fingerprint and if available an URL is returned.\n"
"In --dane mode the key is returned from RR type 61";
\f
+static const char hlp_wkd_get[] =
+ "WKD_GET <user_id>\n"
+ "\n"
+ "Return the key for <user_id> from a Web Key Directory.\n";
+static gpg_error_t
+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 sha1buf[20];
+ char *uri = NULL;
+ char *encodedhash = NULL;
+
+ line = skip_options (line);
+
+ mbox = mailbox_from_userid (line);
+ if (!mbox || !(domain = strchr (mbox, '@')))
+ {
+ err = set_error (GPG_ERR_INV_USER_ID, "no mailbox in user id");
+ goto leave;
+ }
+ *domain++ = 0;
+
+ gcry_md_hash_buffer (GCRY_MD_SHA1, sha1buf, mbox, strlen (mbox));
+ encodedhash = zb32_encode (sha1buf, 8*20);
+ if (!encodedhash)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+
+ uri = strconcat ("https://",
+ domain,
+ "/.well-known/openpgpkey/hu/",
+ encodedhash,
+ NULL);
+ if (!uri)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+
+ /* Setup an output stream and perform the get. */
+ {
+ estream_t outfp;
+
+ outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
+ if (!outfp)
+ err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
+ else
+ {
+ err = ks_action_fetch (ctrl, uri, outfp);
+ es_fclose (outfp);
+ }
+ }
+
+ leave:
+ xfree (uri);
+ xfree (encodedhash);
+ xfree (mbox);
+ return leave_cmd (ctx, err);
+}
+
+
+\f
static const char hlp_ldapserver[] =
"LDAPSERVER <data>\n"
"\n"
"Processing then takes place without further interaction; in\n"
"particular dirmngr tries to locate other required certificates by\n"
"its own mechanism which includes a local certificate store as well\n"
- "as a list of trusted root certifciates.\n"
+ "as a list of trusted root certificates.\n"
"\n"
"If the option --force-default-responder is given, only the default\n"
"OCSP responder will be used and any other methods of obtaining an\n"
/* No options for now. */
line = skip_options (line);
- err = ensure_keyserver (ctrl);
+ err = ensure_keyserver (ctrl); /* FIXME: Why do we needs this here? */
if (err)
goto leave;
const char * const help;
} table[] = {
{ "DNS_CERT", cmd_dns_cert, hlp_dns_cert },
+ { "WKD_GET", cmd_wkd_get, hlp_wkd_get },
{ "LDAPSERVER", cmd_ldapserver, hlp_ldapserver },
{ "ISVALID", cmd_isvalid, hlp_isvalid },
{ "CHECKCRL", cmd_checkcrl, hlp_checkcrl },
if (!hello_line)
{
- size_t n;
- const char *cfgname;
-
- cfgname = opt.config_filename? opt.config_filename : "[none]";
-
- n = (30 + strlen (opt.homedir) + strlen (cfgname)
- + strlen (hello) + 1);
- hello_line = xmalloc (n+1);
- snprintf (hello_line, n,
- "Home: %s\n"
- "Config: %s\n"
- "%s",
- opt.homedir,
- cfgname,
- hello);
- hello_line[n] = 0;
+ hello_line = xtryasprintf
+ ("Home: %s\n"
+ "Config: %s\n"
+ "%s",
+ gnupg_homedir (),
+ opt.config_filename? opt.config_filename : "[none]",
+ hello);
}
ctrl->server_local->assuan_ctx = ctx;