1 /* server.c - LDAP and Keyserver access server
2 * Copyright (C) 2002 Klarälvdalens Datakonsult AB
3 * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2011, 2015 g10 Code GmbH
4 * Copyright (C) 2014, 2015, 2016 Werner Koch
5 * Copyright (C) 2016 Bundesamt für Sicherheit in der Informationstechnik
7 * This file is part of GnuPG.
9 * GnuPG is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
14 * GnuPG is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, see <https://www.gnu.org/licenses/>.
22 * SPDX-License-Identifier: GPL-3.0+
31 #include <sys/types.h>
42 # include "ldapserver.h"
45 #include "certcache.h"
49 # include "ldap-wrapper.h"
51 #include "ks-action.h"
52 #include "ks-engine.h" /* (ks_hkp_print_hosttable) */
54 # include "ldap-parse-uri.h"
56 #include "dns-stuff.h"
57 #include "../common/mbox-util.h"
58 #include "../common/zb32.h"
59 #include "../common/server-help.h"
61 /* To avoid DoS attacks we limit the size of a certificate to
62 something reasonable. The DoS was actually only an issue back when
63 Dirmngr was a system service and not a user service. */
64 #define MAX_CERT_LENGTH (16*1024)
66 /* The limit for the CERTLIST inquiry. We allow for up to 20
67 * certificates but also take PEM encoding into account. */
68 #define MAX_CERTLIST_LENGTH ((MAX_CERT_LENGTH * 20 * 4)/3)
70 /* The same goes for OpenPGP keyblocks, but here we need to allow for
71 much longer blocks; a 200k keyblock is not too unusual for keys
72 with a lot of signatures (e.g. 0x5b0358a2). 9C31503C6D866396 even
73 has 770 KiB as of 2015-08-23. To avoid adding a runtime option we
74 now use 20MiB which should really be enough. Well, a key with
75 several pictures could be larger (the parser as a 18MiB limit for
76 attribute packets) but it won't be nice to the keyservers to send
77 them such large blobs. */
78 #define MAX_KEYBLOCK_LENGTH (20*1024*1024)
81 #define PARM_ERROR(t) assuan_set_error (ctx, \
82 gpg_error (GPG_ERR_ASS_PARAMETER), (t))
83 #define set_error(e,t) (ctx ? assuan_set_error (ctx, gpg_error (e), (t)) \
88 /* Control structure per connection. */
91 /* Data used to associate an Assuan context with local server data */
92 assuan_context_t assuan_ctx;
94 /* The session id (a counter). */
95 unsigned int session_id;
97 /* Per-session LDAP servers. */
98 ldap_server_t ldapservers;
100 /* Per-session list of keyservers. */
101 uri_item_t keyservers;
103 /* If this flag is set to true this dirmngr process will be
104 terminated after the end of this session. */
107 /* State variable private to is_tor_running. */
110 /* If the first both flags are set the assuan logging of data lines
111 * is suppressed. The count variable is used to show the number of
112 * non-logged bytes. */
113 size_t inhibit_data_logging_count;
114 unsigned int inhibit_data_logging : 1;
115 unsigned int inhibit_data_logging_now : 1;
119 /* Cookie definition for assuan data line output. */
120 static gpgrt_ssize_t data_line_cookie_write (void *cookie,
121 const void *buffer, size_t size);
122 static int data_line_cookie_close (void *cookie);
123 static es_cookie_io_functions_t data_line_cookie_functions =
126 data_line_cookie_write,
128 data_line_cookie_close
132 /* Local prototypes */
133 static const char *task_check_wkd_support (ctrl_t ctrl, const char *domain);
138 /* Accessor for the local ldapservers variable. */
140 get_ldapservers_from_ctrl (ctrl_t ctrl)
142 if (ctrl && ctrl->server_local)
143 return ctrl->server_local->ldapservers;
148 /* Release an uri_item_t list. */
150 release_uri_item_list (uri_item_t list)
154 uri_item_t tmp = list->next;
155 http_release_parsed_uri (list->parsed_uri);
161 /* Release all configured keyserver info from CTRL. */
163 release_ctrl_keyservers (ctrl_t ctrl)
165 if (! ctrl->server_local)
168 release_uri_item_list (ctrl->server_local->keyservers);
169 ctrl->server_local->keyservers = NULL;
174 /* Helper to print a message while leaving a command. */
176 leave_cmd (assuan_context_t ctx, gpg_error_t err)
180 const char *name = assuan_get_command_name (ctx);
183 if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT)
184 log_error ("command '%s' failed: %s\n", name,
187 log_error ("command '%s' failed: %s <%s>\n", name,
188 gpg_strerror (err), gpg_strsource (err));
194 /* This is a wrapper around assuan_send_data which makes debugging the
195 output in verbose mode easier. */
197 data_line_write (assuan_context_t ctx, const void *buffer_arg, size_t size)
199 ctrl_t ctrl = assuan_get_pointer (ctx);
200 const char *buffer = buffer_arg;
203 /* If we do not want logging, enable it here. */
204 if (ctrl && ctrl->server_local && ctrl->server_local->inhibit_data_logging)
205 ctrl->server_local->inhibit_data_logging_now = 1;
207 if (opt.verbose && buffer && size)
209 /* Ease reading of output by sending a physical line at each LF. */
216 p = memchr (buffer, '\n', nbytes);
217 n = p ? (p - buffer) + 1 : nbytes;
218 err = assuan_send_data (ctx, buffer, n);
221 gpg_err_set_errno (EIO);
226 if (nbytes && (err=assuan_send_data (ctx, NULL, 0))) /* Flush line. */
228 gpg_err_set_errno (EIO);
236 err = assuan_send_data (ctx, buffer, size);
239 gpg_err_set_errno (EIO); /* For use by data_line_cookie_write. */
245 if (ctrl && ctrl->server_local && ctrl->server_local->inhibit_data_logging)
247 ctrl->server_local->inhibit_data_logging_now = 0;
248 ctrl->server_local->inhibit_data_logging_count += size;
255 /* A write handler used by es_fopencookie to write assuan data
258 data_line_cookie_write (void *cookie, const void *buffer, size_t size)
260 assuan_context_t ctx = cookie;
262 if (data_line_write (ctx, buffer, size))
264 return (gpgrt_ssize_t)size;
269 data_line_cookie_close (void *cookie)
271 assuan_context_t ctx = cookie;
275 ctrl_t ctrl = assuan_get_pointer (ctx);
277 if (ctrl && ctrl->server_local
278 && ctrl->server_local->inhibit_data_logging
279 && ctrl->server_local->inhibit_data_logging_count)
280 log_debug ("(%zu bytes sent via D lines not shown)\n",
281 ctrl->server_local->inhibit_data_logging_count);
283 if (assuan_send_data (ctx, NULL, 0))
285 gpg_err_set_errno (EIO);
293 /* Copy the % and + escaped string S into the buffer D and replace the
294 escape sequences. Note, that it is sufficient to allocate the
295 target string D as long as the source string S, i.e.: strlen(s)+1.
296 Note further that if S contains an escaped binary Nul the resulting
297 string D will contain the 0 as well as all other characters but it
298 will be impossible to know whether this is the original EOS or a
301 strcpy_escaped_plus (char *d, const unsigned char *s)
305 if (*s == '%' && s[1] && s[2])
320 /* This function returns true if a Tor server is running. The status
321 * is cached for the current connection. */
323 is_tor_running (ctrl_t ctrl)
325 /* Check whether we can connect to the proxy. */
327 if (!ctrl || !ctrl->server_local)
328 return 0; /* Ooops. */
330 if (!ctrl->server_local->tor_state)
334 sock = assuan_sock_connect_byname (NULL, 0, 0, NULL, ASSUAN_SOCK_TOR);
335 if (sock == ASSUAN_INVALID_FD)
336 ctrl->server_local->tor_state = -1; /* Not running. */
339 assuan_sock_close (sock);
340 ctrl->server_local->tor_state = 1; /* Running. */
343 return (ctrl->server_local->tor_state > 0);
347 /* Return an error if the assuan context does not belong to the owner
348 of the process or to root. On error FAILTEXT is set as Assuan
351 check_owner_permission (assuan_context_t ctx, const char *failtext)
353 #ifdef HAVE_W32_SYSTEM
354 /* Under Windows the dirmngr is always run under the control of the
360 assuan_peercred_t cred;
362 ec = gpg_err_code (assuan_get_peercred (ctx, &cred));
363 if (!ec && cred->uid && cred->uid != getuid ())
366 return set_error (ec, failtext);
373 /* Common code for get_cert_local and get_issuer_cert_local. */
375 do_get_cert_local (ctrl_t ctrl, const char *name, const char *command)
377 unsigned char *value;
383 buf = name? strconcat (command, " ", name, NULL) : xtrystrdup (command);
385 rc = gpg_error_from_syserror ();
388 rc = assuan_inquire (ctrl->server_local->assuan_ctx, buf,
389 &value, &valuelen, MAX_CERT_LENGTH);
394 log_error (_("assuan_inquire(%s) failed: %s\n"),
395 command, gpg_strerror (rc));
405 rc = ksba_cert_new (&cert);
408 rc = ksba_cert_init_from_mem (cert, value, valuelen);
411 ksba_cert_release (cert);
421 /* Ask back to return a certificate for NAME, given as a regular gpgsm
422 * certificate identifier (e.g. fingerprint or one of the other
423 * methods). Alternatively, NULL may be used for NAME to return the
424 * current target certificate. Either return the certificate in a
425 * KSBA object or NULL if it is not available. */
427 get_cert_local (ctrl_t ctrl, const char *name)
429 if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
432 log_debug ("get_cert_local called w/o context\n");
435 return do_get_cert_local (ctrl, name, "SENDCERT");
440 /* Ask back to return the issuing certificate for NAME, given as a
441 * regular gpgsm certificate identifier (e.g. fingerprint or one
442 * of the other methods). Alternatively, NULL may be used for NAME to
443 * return the current target certificate. Either return the certificate
444 * in a KSBA object or NULL if it is not available. */
446 get_issuing_cert_local (ctrl_t ctrl, const char *name)
448 if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
451 log_debug ("get_issuing_cert_local called w/o context\n");
454 return do_get_cert_local (ctrl, name, "SENDISSUERCERT");
458 /* Ask back to return a certificate with subject NAME and a
459 * subjectKeyIdentifier of KEYID. */
461 get_cert_local_ski (ctrl_t ctrl, const char *name, ksba_sexp_t keyid)
463 unsigned char *value;
470 if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
473 log_debug ("get_cert_local_ski called w/o context\n");
478 log_debug ("get_cert_local_ski called with insufficient arguments\n");
482 hexkeyid = serial_hex (keyid);
485 log_debug ("serial_hex() failed\n");
489 buf = strconcat ("SENDCERT_SKI ", hexkeyid, " /", name, NULL);
492 log_error ("can't allocate enough memory: %s\n", strerror (errno));
498 rc = assuan_inquire (ctrl->server_local->assuan_ctx, buf,
499 &value, &valuelen, MAX_CERT_LENGTH);
503 log_error (_("assuan_inquire(%s) failed: %s\n"), "SENDCERT_SKI",
514 rc = ksba_cert_new (&cert);
517 rc = ksba_cert_init_from_mem (cert, value, valuelen);
520 ksba_cert_release (cert);
529 /* Ask the client via an inquiry to check the istrusted status of the
530 certificate specified by the hexified fingerprint HEXFPR. Returns
531 0 if the certificate is trusted by the client or an error code. */
533 get_istrusted_from_client (ctrl_t ctrl, const char *hexfpr)
535 unsigned char *value;
540 if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx
542 return gpg_error (GPG_ERR_INV_ARG);
544 snprintf (request, sizeof request, "ISTRUSTED %s", hexfpr);
545 rc = assuan_inquire (ctrl->server_local->assuan_ctx, request,
546 &value, &valuelen, 100);
549 log_error (_("assuan_inquire(%s) failed: %s\n"),
550 request, gpg_strerror (rc));
553 /* The expected data is: "1" or "1 cruft" (not a C-string). */
554 if (valuelen && *value == '1' && (valuelen == 1 || spacep (value+1)))
557 rc = gpg_error (GPG_ERR_NOT_TRUSTED);
565 /* Ask the client to return the certificate associated with the
566 current command. This is sometimes needed because the client usually
567 sends us just the cert ID, assuming that the request can be
568 satisfied from the cache, where the cert ID is used as key. */
570 inquire_cert_and_load_crl (assuan_context_t ctx)
572 ctrl_t ctrl = assuan_get_pointer (ctx);
574 unsigned char *value = NULL;
576 ksba_cert_t cert = NULL;
578 err = assuan_inquire( ctx, "SENDCERT", &value, &valuelen, 0);
583 /* FILE *fp = fopen ("foo.der", "r"); */
584 /* value = xmalloc (2000); */
585 /* valuelen = fread (value, 1, 2000, fp); */
589 if (!valuelen) /* No data returned; return a comprehensible error. */
590 return gpg_error (GPG_ERR_MISSING_CERT);
592 err = ksba_cert_new (&cert);
595 err = ksba_cert_init_from_mem (cert, value, valuelen);
598 xfree (value); value = NULL;
600 err = crl_cache_reload_crl (ctrl, cert);
603 ksba_cert_release (cert);
609 /* Handle OPTION commands. */
611 option_handler (assuan_context_t ctx, const char *key, const char *value)
613 ctrl_t ctrl = assuan_get_pointer (ctx);
616 if (!strcmp (key, "force-crl-refresh"))
618 int i = *value? atoi (value) : 0;
619 ctrl->force_crl_refresh = i;
621 else if (!strcmp (key, "audit-events"))
623 int i = *value? atoi (value) : 0;
624 ctrl->audit_events = i;
626 else if (!strcmp (key, "http-proxy"))
628 xfree (ctrl->http_proxy);
629 if (!*value || !strcmp (value, "none"))
630 ctrl->http_proxy = NULL;
631 else if (!(ctrl->http_proxy = xtrystrdup (value)))
632 err = gpg_error_from_syserror ();
634 else if (!strcmp (key, "honor-keyserver-url-used"))
636 /* Return an error if we are running in Tor mode. */
637 if (dirmngr_use_tor ())
638 err = gpg_error (GPG_ERR_FORBIDDEN);
640 else if (!strcmp (key, "http-crl"))
642 int i = *value? atoi (value) : 0;
643 ctrl->http_no_crl = !i;
646 err = gpg_error (GPG_ERR_UNKNOWN_OPTION);
653 static const char hlp_dns_cert[] =
654 "DNS_CERT <subtype> <name>\n"
655 "DNS_CERT --pka <user_id>\n"
656 "DNS_CERT --dane <user_id>\n"
658 "Return the CERT record for <name>. <subtype> is one of\n"
659 " * Return the first record of any supported subtype\n"
660 " PGP Return the first record of subtype PGP (3)\n"
661 " IPGP Return the first record of subtype IPGP (6)\n"
662 "If the content of a certificate is available (PGP) it is returned\n"
663 "by data lines. Fingerprints and URLs are returned via status lines.\n"
664 "In --pka mode the fingerprint and if available an URL is returned.\n"
665 "In --dane mode the key is returned from RR type 61";
667 cmd_dns_cert (assuan_context_t ctx, char *line)
669 /* ctrl_t ctrl = assuan_get_pointer (ctx); */
671 int pka_mode, dane_mode;
673 char *namebuf = NULL;
674 char *encodedhash = NULL;
680 unsigned char *fpr = NULL;
684 pka_mode = has_option (line, "--pka");
685 dane_mode = has_option (line, "--dane");
686 line = skip_options (line);
688 if (pka_mode && dane_mode)
690 err = PARM_ERROR ("either --pka or --dane may be given");
694 if (pka_mode || dane_mode)
695 ; /* No need to parse here - we do this later. */
698 p = strchr (line, ' ');
701 err = PARM_ERROR ("missing arguments");
705 if (!strcmp (line, "*"))
706 certtype = DNS_CERTTYPE_ANY;
707 else if (!strcmp (line, "IPGP"))
708 certtype = DNS_CERTTYPE_IPGP;
709 else if (!strcmp (line, "PGP"))
710 certtype = DNS_CERTTYPE_PGP;
713 err = PARM_ERROR ("unknown subtype");
721 err = PARM_ERROR ("name missing");
726 if (pka_mode || dane_mode)
728 char *domain; /* Points to mbox. */
729 char hashbuf[32]; /* For SHA-1 and SHA-256. */
731 /* We lowercase ascii characters but the DANE I-D does not allow
732 this. FIXME: Check after the release of the RFC whether to
734 mbox = mailbox_from_userid (line);
735 if (!mbox || !(domain = strchr (mbox, '@')))
737 err = set_error (GPG_ERR_INV_USER_ID, "no mailbox in user id");
744 gcry_md_hash_buffer (GCRY_MD_SHA1, hashbuf, mbox, strlen (mbox));
745 encodedhash = zb32_encode (hashbuf, 8*20);
748 err = gpg_error_from_syserror ();
751 namebuf = strconcat (encodedhash, "._pka.", domain, NULL);
754 err = gpg_error_from_syserror ();
758 certtype = DNS_CERTTYPE_IPGP;
762 /* Note: The hash is truncated to 28 bytes and we lowercase
763 the result only for aesthetic reasons. */
764 gcry_md_hash_buffer (GCRY_MD_SHA256, hashbuf, mbox, strlen (mbox));
765 encodedhash = bin2hex (hashbuf, 28, NULL);
768 err = gpg_error_from_syserror ();
771 ascii_strlwr (encodedhash);
772 namebuf = strconcat (encodedhash, "._openpgpkey.", domain, NULL);
775 err = gpg_error_from_syserror ();
779 certtype = DNS_CERTTYPE_RR61;
785 err = get_dns_cert (name, certtype, &key, &keylen, &fpr, &fprlen, &url);
791 err = data_line_write (ctx, key, keylen);
800 tmpstr = bin2hex (fpr, fprlen, NULL);
802 err = gpg_error_from_syserror ();
805 err = assuan_write_status (ctx, "FPR", tmpstr);
814 err = assuan_write_status (ctx, "URL", url);
827 return leave_cmd (ctx, err);
832 /* Core of cmd_wkd_get and task_check_wkd_support. If CTX is NULL
833 * this function will not write anything to the assuan output. */
835 proc_wkd_get (ctrl_t ctrl, assuan_context_t ctx, char *line)
839 char *domainbuf = NULL;
840 char *domain; /* Points to mbox or domainbuf. */
841 char *domain_orig;/* Points to mbox. */
844 char *encodedhash = NULL;
845 int opt_submission_addr;
846 int opt_policy_flags;
847 int is_wkd_query; /* True if this is a real WKD query. */
849 char portstr[20] = { 0 };
851 opt_submission_addr = has_option (line, "--submission-address");
852 opt_policy_flags = has_option (line, "--policy-flags");
853 if (has_option (line, "--quick"))
854 ctrl->timeout = opt.connect_quick_timeout;
855 line = skip_options (line);
856 is_wkd_query = !(opt_policy_flags || opt_submission_addr);
858 mbox = mailbox_from_userid (line);
859 if (!mbox || !(domain = strchr (mbox, '@')))
861 err = set_error (GPG_ERR_INV_USER_ID, "no mailbox in user id");
865 domain_orig = domain;
867 /* First check whether we already know that the domain does not
871 if (domaininfo_is_wkd_not_supported (domain_orig))
873 err = gpg_error (GPG_ERR_NO_DATA);
878 /* Check for SRV records. */
881 struct srventry *srvs;
882 unsigned int srvscount;
883 size_t domainlen, targetlen;
886 err = get_dns_srv (domain, "openpgpkey", NULL, &srvs, &srvscount);
890 /* Find the first target which also ends in DOMAIN or is equal
892 domainlen = strlen (domain);
893 for (i = 0; i < srvscount; i++)
896 log_debug ("srv: trying '%s:%hu'\n", srvs[i].target, srvs[i].port);
897 targetlen = strlen (srvs[i].target);
898 if ((targetlen > domainlen + 1
899 && srvs[i].target[targetlen - domainlen - 1] == '.'
900 && !ascii_strcasecmp (srvs[i].target + targetlen - domainlen,
902 || (targetlen == domainlen
903 && !ascii_strcasecmp (srvs[i].target, domain)))
906 domainbuf = xtrystrdup (srvs[i].target);
909 err = gpg_error_from_syserror ();
915 snprintf (portstr, sizeof portstr, ":%hu", srvs[i].port);
922 gcry_md_hash_buffer (GCRY_MD_SHA1, sha1buf, mbox, strlen (mbox));
923 encodedhash = zb32_encode (sha1buf, 8*20);
926 err = gpg_error_from_syserror ();
930 if (opt_submission_addr)
932 uri = strconcat ("https://",
935 "/.well-known/openpgpkey/submission-address",
938 else if (opt_policy_flags)
940 uri = strconcat ("https://",
943 "/.well-known/openpgpkey/policy",
948 uri = strconcat ("https://",
951 "/.well-known/openpgpkey/hu/",
957 err = dirmngr_status_printf (ctrl, "SOURCE", "https://%s%s",
965 err = gpg_error_from_syserror ();
969 /* Setup an output stream and perform the get. */
973 outfp = ctx? es_fopencookie (ctx, "w", data_line_cookie_functions) : NULL;
975 err = set_error (GPG_ERR_ASS_GENERAL,
976 "error setting up a data stream");
979 if (ctrl->server_local)
982 ctrl->server_local->inhibit_data_logging = 1;
983 ctrl->server_local->inhibit_data_logging_now = 0;
984 ctrl->server_local->inhibit_data_logging_count = 0;
986 err = ks_action_fetch (ctrl, uri, outfp);
988 if (ctrl->server_local)
989 ctrl->server_local->inhibit_data_logging = 0;
991 /* Register the result under the domain name of MBOX. */
992 switch (gpg_err_code (err))
995 domaininfo_set_wkd_supported (domain_orig);
998 case GPG_ERR_NO_NAME:
999 /* There is no such domain. */
1000 domaininfo_set_no_name (domain_orig);
1003 case GPG_ERR_NO_DATA:
1004 if (is_wkd_query && ctrl->server_local)
1006 /* Mark that and schedule a check. */
1007 domaininfo_set_wkd_not_found (domain_orig);
1008 workqueue_add_task (task_check_wkd_support, domain_orig,
1009 ctrl->server_local->session_id, 1);
1011 else if (opt_policy_flags) /* No policy file - no support. */
1012 domaininfo_set_wkd_not_supported (domain_orig);
1016 /* Don't register other errors. */
1024 xfree (encodedhash);
1031 static const char hlp_wkd_get[] =
1032 "WKD_GET [--submission-address|--policy-flags] <user_id>\n"
1034 "Return the key or other info for <user_id>\n"
1035 "from the Web Key Directory.";
1037 cmd_wkd_get (assuan_context_t ctx, char *line)
1039 ctrl_t ctrl = assuan_get_pointer (ctx);
1042 err = proc_wkd_get (ctrl, ctx, line);
1044 return leave_cmd (ctx, err);
1048 /* A task to check whether DOMAIN supports WKD. This is done by
1049 * checking whether the policy flags file can be read. */
1051 task_check_wkd_support (ctrl_t ctrl, const char *domain)
1055 if (!ctrl || !domain)
1056 return "check_wkd_support";
1058 string = strconcat ("--policy-flags foo@", domain, NULL);
1060 log_error ("%s: %s\n", __func__, gpg_strerror (gpg_error_from_syserror ()));
1063 proc_wkd_get (ctrl, NULL, string);
1072 static const char hlp_ldapserver[] =
1073 "LDAPSERVER <data>\n"
1075 "Add a new LDAP server to the list of configured LDAP servers.\n"
1076 "DATA is in the same format as expected in the configure file.";
1078 cmd_ldapserver (assuan_context_t ctx, char *line)
1081 ctrl_t ctrl = assuan_get_pointer (ctx);
1082 ldap_server_t server;
1083 ldap_server_t *last_next_p;
1085 while (spacep (line))
1088 return leave_cmd (ctx, PARM_ERROR (_("ldapserver missing")));
1090 server = ldapserver_parse_one (line, "", 0);
1092 return leave_cmd (ctx, gpg_error (GPG_ERR_INV_ARG));
1094 last_next_p = &ctrl->server_local->ldapservers;
1095 while (*last_next_p)
1096 last_next_p = &(*last_next_p)->next;
1097 *last_next_p = server;
1098 return leave_cmd (ctx, 0);
1101 return leave_cmd (ctx, gpg_error (GPG_ERR_NOT_IMPLEMENTED));
1106 static const char hlp_isvalid[] =
1107 "ISVALID [--only-ocsp] [--force-default-responder]"
1108 " <certificate_id>|<certificate_fpr>\n"
1110 "This command checks whether the certificate identified by the\n"
1111 "certificate_id is valid. This is done by consulting CRLs or\n"
1112 "whatever has been configured. Note, that the returned error codes\n"
1113 "are from gpg-error.h. The command may callback using the inquire\n"
1114 "function. See the manual for details.\n"
1116 "The CERTIFICATE_ID is a hex encoded string consisting of two parts,\n"
1117 "delimited by a single dot. The first part is the SHA-1 hash of the\n"
1118 "issuer name and the second part the serial number.\n"
1120 "Alternatively the certificate's fingerprint may be given in which\n"
1121 "case an OCSP request is done before consulting the CRL.\n"
1123 "If the option --only-ocsp is given, no fallback to a CRL check will\n"
1126 "If the option --force-default-responder is given, only the default\n"
1127 "OCSP responder will be used and any other methods of obtaining an\n"
1128 "OCSP responder URL won't be used.";
1130 cmd_isvalid (assuan_context_t ctx, char *line)
1132 ctrl_t ctrl = assuan_get_pointer (ctx);
1133 char *issuerhash, *serialno;
1135 int did_inquire = 0;
1138 int force_default_responder;
1140 only_ocsp = has_option (line, "--only-ocsp");
1141 force_default_responder = has_option (line, "--force-default-responder");
1142 line = skip_options (line);
1144 issuerhash = xstrdup (line); /* We need to work on a copy of the
1145 line because that same Assuan
1146 context may be used for an inquiry.
1147 That is because Assuan reuses its
1151 serialno = strchr (issuerhash, '.');
1156 char *endp = strchr (issuerhash, ' ');
1159 if (strlen (issuerhash) != 40)
1162 return leave_cmd (ctx, PARM_ERROR (_("serialno missing in cert ID")));
1171 /* Note, that we ignore the given issuer hash and instead rely
1172 on the current certificate semantics used with this
1174 if (!opt.allow_ocsp)
1175 err = gpg_error (GPG_ERR_NOT_SUPPORTED);
1177 err = ocsp_isvalid (ctrl, NULL, NULL, force_default_responder);
1178 /* Fixme: If we got no ocsp response and --only-ocsp is not used
1179 we should fall back to CRL mode. Thus we need to clear
1180 OCSP_MODE, get the issuerhash and the serialno from the
1181 current certificate and jump to again. */
1184 err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
1187 switch (crl_cache_isvalid (ctrl,
1188 issuerhash, serialno,
1189 ctrl->force_crl_refresh))
1191 case CRL_CACHE_VALID:
1194 case CRL_CACHE_INVALID:
1195 err = gpg_error (GPG_ERR_CERT_REVOKED);
1197 case CRL_CACHE_DONTKNOW:
1199 err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
1200 else if (!(err = inquire_cert_and_load_crl (ctx)))
1206 case CRL_CACHE_CANTUSE:
1207 err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
1210 log_fatal ("crl_cache_isvalid returned invalid code\n");
1215 return leave_cmd (ctx, err);
1219 /* If the line contains a SHA-1 fingerprint as the first argument,
1220 return the FPR vuffer on success. The function checks that the
1221 fingerprint consists of valid characters and prints and error
1222 message if it does not and returns NULL. Fingerprints are
1223 considered optional and thus no explicit error is returned. NULL is
1224 also returned if there is no fingerprint at all available.
1225 FPR must be a caller provided buffer of at least 20 bytes.
1227 Note that colons within the fingerprint are allowed to separate 2
1228 hex digits; this allows for easier cutting and pasting using the
1229 usual fingerprint rendering.
1231 static unsigned char *
1232 get_fingerprint_from_line (const char *line, unsigned char *fpr)
1237 for (s=line, i=0; *s && *s != ' '; s++ )
1239 if ( hexdigitp (s) && hexdigitp (s+1) )
1242 return NULL; /* Fingerprint too long. */
1243 fpr[i++] = xtoi_2 (s);
1246 else if ( *s != ':' )
1247 return NULL; /* Invalid. */
1250 return NULL; /* Fingerprint to short. */
1256 static const char hlp_checkcrl[] =
1257 "CHECKCRL [<fingerprint>]\n"
1259 "Check whether the certificate with FINGERPRINT (SHA-1 hash of the\n"
1260 "entire X.509 certificate blob) is valid or not by consulting the\n"
1261 "CRL responsible for this certificate. If the fingerprint has not\n"
1262 "been given or the certificate is not known, the function \n"
1263 "inquires the certificate using an\n"
1265 " INQUIRE TARGETCERT\n"
1267 "and the caller is expected to return the certificate for the\n"
1268 "request (which should match FINGERPRINT) as a binary blob.\n"
1269 "Processing then takes place without further interaction; in\n"
1270 "particular dirmngr tries to locate other required certificate by\n"
1271 "its own mechanism which includes a local certificate store as well\n"
1272 "as a list of trusted root certificates.\n"
1274 "The return value is the usual gpg-error code or 0 for ducesss;\n"
1275 "i.e. the certificate validity has been confirmed by a valid CRL.";
1277 cmd_checkcrl (assuan_context_t ctx, char *line)
1279 ctrl_t ctrl = assuan_get_pointer (ctx);
1281 unsigned char fprbuffer[20], *fpr;
1284 fpr = get_fingerprint_from_line (line, fprbuffer);
1285 cert = fpr? get_cert_byfpr (fpr) : NULL;
1289 /* We do not have this certificate yet or the fingerprint has
1290 not been given. Inquire it from the client. */
1291 unsigned char *value = NULL;
1294 err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1295 &value, &valuelen, MAX_CERT_LENGTH);
1298 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1302 if (!valuelen) /* No data returned; return a comprehensible error. */
1303 err = gpg_error (GPG_ERR_MISSING_CERT);
1306 err = ksba_cert_new (&cert);
1308 err = ksba_cert_init_from_mem (cert, value, valuelen);
1317 err = crl_cache_cert_isvalid (ctrl, cert, ctrl->force_crl_refresh);
1318 if (gpg_err_code (err) == GPG_ERR_NO_CRL_KNOWN)
1320 err = crl_cache_reload_crl (ctrl, cert);
1322 err = crl_cache_cert_isvalid (ctrl, cert, 0);
1326 ksba_cert_release (cert);
1327 return leave_cmd (ctx, err);
1331 static const char hlp_checkocsp[] =
1332 "CHECKOCSP [--force-default-responder] [<fingerprint>]\n"
1334 "Check whether the certificate with FINGERPRINT (SHA-1 hash of the\n"
1335 "entire X.509 certificate blob) is valid or not by asking an OCSP\n"
1336 "responder responsible for this certificate. The optional\n"
1337 "fingerprint may be used for a quick check in case an OCSP check has\n"
1338 "been done for this certificate recently (we always cache OCSP\n"
1339 "responses for a couple of minutes). If the fingerprint has not been\n"
1340 "given or there is no cached result, the function inquires the\n"
1341 "certificate using an\n"
1343 " INQUIRE TARGETCERT\n"
1345 "and the caller is expected to return the certificate for the\n"
1346 "request (which should match FINGERPRINT) as a binary blob.\n"
1347 "Processing then takes place without further interaction; in\n"
1348 "particular dirmngr tries to locate other required certificates by\n"
1349 "its own mechanism which includes a local certificate store as well\n"
1350 "as a list of trusted root certificates.\n"
1352 "If the option --force-default-responder is given, only the default\n"
1353 "OCSP responder will be used and any other methods of obtaining an\n"
1354 "OCSP responder URL won't be used.\n"
1356 "The return value is the usual gpg-error code or 0 for ducesss;\n"
1357 "i.e. the certificate validity has been confirmed by a valid CRL.";
1359 cmd_checkocsp (assuan_context_t ctx, char *line)
1361 ctrl_t ctrl = assuan_get_pointer (ctx);
1363 unsigned char fprbuffer[20], *fpr;
1365 int force_default_responder;
1367 force_default_responder = has_option (line, "--force-default-responder");
1368 line = skip_options (line);
1370 fpr = get_fingerprint_from_line (line, fprbuffer);
1371 cert = fpr? get_cert_byfpr (fpr) : NULL;
1375 /* We do not have this certificate yet or the fingerprint has
1376 not been given. Inquire it from the client. */
1377 unsigned char *value = NULL;
1380 err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1381 &value, &valuelen, MAX_CERT_LENGTH);
1384 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1388 if (!valuelen) /* No data returned; return a comprehensible error. */
1389 err = gpg_error (GPG_ERR_MISSING_CERT);
1392 err = ksba_cert_new (&cert);
1394 err = ksba_cert_init_from_mem (cert, value, valuelen);
1403 if (!opt.allow_ocsp)
1404 err = gpg_error (GPG_ERR_NOT_SUPPORTED);
1406 err = ocsp_isvalid (ctrl, cert, NULL, force_default_responder);
1409 ksba_cert_release (cert);
1410 return leave_cmd (ctx, err);
1416 lookup_cert_by_url (assuan_context_t ctx, const char *url)
1418 ctrl_t ctrl = assuan_get_pointer (ctx);
1419 gpg_error_t err = 0;
1420 unsigned char *value = NULL;
1423 /* Fetch single certificate given it's URL. */
1424 err = fetch_cert_by_url (ctrl, url, &value, &valuelen);
1427 log_error (_("fetch_cert_by_url failed: %s\n"), gpg_strerror (err));
1431 /* Send the data, flush the buffer and then send an END. */
1432 err = assuan_send_data (ctx, value, valuelen);
1434 err = assuan_send_data (ctx, NULL, 0);
1436 err = assuan_write_line (ctx, "END");
1439 log_error (_("error sending data: %s\n"), gpg_strerror (err));
1449 /* Send the certificate, flush the buffer and then send an END. */
1451 return_one_cert (void *opaque, ksba_cert_t cert)
1453 assuan_context_t ctx = opaque;
1455 const unsigned char *der;
1458 der = ksba_cert_get_image (cert, &derlen);
1460 err = gpg_error (GPG_ERR_INV_CERT_OBJ);
1463 err = assuan_send_data (ctx, der, derlen);
1465 err = assuan_send_data (ctx, NULL, 0);
1467 err = assuan_write_line (ctx, "END");
1470 log_error (_("error sending data: %s\n"), gpg_strerror (err));
1475 /* Lookup certificates from the internal cache or using the ldap
1478 lookup_cert_by_pattern (assuan_context_t ctx, char *line,
1479 int single, int cache_only)
1481 gpg_error_t err = 0;
1483 strlist_t sl, list = NULL;
1484 int truncated = 0, truncation_forced = 0;
1486 int local_count = 0;
1488 ctrl_t ctrl = assuan_get_pointer (ctx);
1489 unsigned char *value = NULL;
1491 struct ldapserver_iter ldapserver_iter;
1492 cert_fetch_context_t fetch_context;
1494 int any_no_data = 0;
1496 /* Break the line down into an STRLIST */
1497 for (p=line; *p; line = p)
1499 while (*p && *p != ' ')
1506 sl = xtrymalloc (sizeof *sl + strlen (line));
1509 err = gpg_error_from_errno (errno);
1512 memset (sl, 0, sizeof *sl);
1513 strcpy_escaped_plus (sl->d, line);
1519 /* First look through the internal cache. The certificates returned
1520 here are not counted towards the truncation limit. */
1521 if (single && !cache_only)
1522 ; /* Do not read from the local cache in this case. */
1525 for (sl=list; sl; sl = sl->next)
1527 err = get_certs_bypattern (sl->d, return_one_cert, ctx);
1533 if (gpg_err_code (err) == GPG_ERR_NO_DATA)
1539 else if (gpg_err_code (err) == GPG_ERR_INV_NAME && !cache_only)
1541 /* No real fault because the internal pattern lookup
1542 can't yet cope with all types of pattern. */
1550 /* Loop over all configured servers unless we want only the
1551 certificates from the cache. */
1553 for (ldapserver_iter_begin (&ldapserver_iter, ctrl);
1554 !cache_only && !ldapserver_iter_end_p (&ldapserver_iter)
1555 && ldapserver_iter.server->host && !truncation_forced;
1556 ldapserver_iter_next (&ldapserver_iter))
1558 ldap_server_t ldapserver = ldapserver_iter.server;
1561 log_debug ("cmd_lookup: trying %s:%d base=%s\n",
1562 ldapserver->host, ldapserver->port,
1563 ldapserver->base?ldapserver->base : "[default]");
1565 /* Fetch certificates matching pattern */
1566 err = start_cert_fetch (ctrl, &fetch_context, list, ldapserver);
1567 if ( gpg_err_code (err) == GPG_ERR_NO_DATA )
1570 log_debug ("cmd_lookup: no data\n");
1577 log_error (_("start_cert_fetch failed: %s\n"), gpg_strerror (err));
1581 /* Fetch the certificates for this query. */
1582 while (!truncation_forced)
1584 xfree (value); value = NULL;
1585 err = fetch_next_cert (fetch_context, &value, &valuelen);
1586 if (gpg_err_code (err) == GPG_ERR_NO_DATA )
1592 if (gpg_err_code (err) == GPG_ERR_TRUNCATED)
1598 if (gpg_err_code (err) == GPG_ERR_EOF)
1605 err = gpg_error (GPG_ERR_BUG);
1610 log_error (_("fetch_next_cert failed: %s\n"),
1611 gpg_strerror (err));
1612 end_cert_fetch (fetch_context);
1617 log_debug ("cmd_lookup: returning one cert%s\n",
1618 truncated? " (truncated)":"");
1620 /* Send the data, flush the buffer and then send an END line
1621 as a certificate delimiter. */
1622 err = assuan_send_data (ctx, value, valuelen);
1624 err = assuan_send_data (ctx, NULL, 0);
1626 err = assuan_write_line (ctx, "END");
1629 log_error (_("error sending data: %s\n"), gpg_strerror (err));
1630 end_cert_fetch (fetch_context);
1634 if (++count >= opt.max_replies )
1636 truncation_forced = 1;
1637 log_info (_("max_replies %d exceeded\n"), opt.max_replies );
1643 end_cert_fetch (fetch_context);
1648 if (truncated || truncation_forced)
1652 sprintf (str, "%d", count);
1653 assuan_write_status (ctx, "TRUNCATED", str);
1656 if (!err && !count && !local_count && any_no_data)
1657 err = gpg_error (GPG_ERR_NO_DATA);
1660 free_strlist (list);
1665 static const char hlp_lookup[] =
1666 "LOOKUP [--url] [--single] [--cache-only] <pattern>\n"
1668 "Lookup certificates matching PATTERN. With --url the pattern is\n"
1669 "expected to be one URL.\n"
1671 "If --url is not given: To allow for multiple patterns (which are ORed)\n"
1672 "quoting is required: Spaces are translated to \"+\" or \"%20\";\n"
1673 "obviously this requires that the usual escape quoting rules are applied.\n"
1675 "If --url is given no special escaping is required because URLs are\n"
1676 "already escaped this way.\n"
1678 "If --single is given the first and only the first match will be\n"
1679 "returned. If --cache-only is _not_ given, no local query will be\n"
1682 "If --cache-only is given no external lookup is done so that only\n"
1683 "certificates from the cache may get returned.";
1685 cmd_lookup (assuan_context_t ctx, char *line)
1688 int lookup_url, single, cache_only;
1690 lookup_url = has_leading_option (line, "--url");
1691 single = has_leading_option (line, "--single");
1692 cache_only = has_leading_option (line, "--cache-only");
1693 line = skip_options (line);
1695 if (lookup_url && cache_only)
1696 err = gpg_error (GPG_ERR_NOT_FOUND);
1697 else if (lookup_url && single)
1698 err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1699 else if (lookup_url)
1700 err = lookup_cert_by_url (ctx, line);
1702 err = lookup_cert_by_pattern (ctx, line, single, cache_only);
1704 return leave_cmd (ctx, err);
1708 static const char hlp_loadcrl[] =
1709 "LOADCRL [--url] <filename|url>\n"
1711 "Load the CRL in the file with name FILENAME into our cache. Note\n"
1712 "that FILENAME should be given with an absolute path because\n"
1713 "Dirmngrs cwd is not known. With --url the CRL is directly loaded\n"
1714 "from the given URL.\n"
1716 "This command is usually used by gpgsm using the invocation \"gpgsm\n"
1717 "--call-dirmngr loadcrl <filename>\". A direct invocation of Dirmngr\n"
1718 "is not useful because gpgsm might need to callback gpgsm to ask for\n"
1719 "the CA's certificate.";
1721 cmd_loadcrl (assuan_context_t ctx, char *line)
1723 ctrl_t ctrl = assuan_get_pointer (ctx);
1724 gpg_error_t err = 0;
1725 int use_url = has_leading_option (line, "--url");
1727 line = skip_options (line);
1731 ksba_reader_t reader;
1733 err = crl_fetch (ctrl, line, &reader);
1735 log_error (_("fetching CRL from '%s' failed: %s\n"),
1736 line, gpg_strerror (err));
1739 err = crl_cache_insert (ctrl, line, reader);
1741 log_error (_("processing CRL from '%s' failed: %s\n"),
1742 line, gpg_strerror (err));
1743 crl_close_reader (reader);
1750 buf = xtrymalloc (strlen (line)+1);
1752 err = gpg_error_from_syserror ();
1755 strcpy_escaped_plus (buf, line);
1756 err = crl_cache_load (ctrl, buf);
1761 return leave_cmd (ctx, err);
1765 static const char hlp_listcrls[] =
1768 "List the content of all CRLs in a readable format. This command is\n"
1769 "usually used by gpgsm using the invocation \"gpgsm --call-dirmngr\n"
1770 "listcrls\". It may also be used directly using \"dirmngr\n"
1773 cmd_listcrls (assuan_context_t ctx, char *line)
1780 fp = es_fopencookie (ctx, "w", data_line_cookie_functions);
1782 err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
1785 err = crl_cache_list (fp);
1788 return leave_cmd (ctx, err);
1792 static const char hlp_cachecert[] =
1795 "Put a certificate into the internal cache. This command might be\n"
1796 "useful if a client knows in advance certificates required for a\n"
1797 "test and wants to make sure they get added to the internal cache.\n"
1798 "It is also helpful for debugging. To get the actual certificate,\n"
1799 "this command immediately inquires it using\n"
1801 " INQUIRE TARGETCERT\n"
1803 "and the caller is expected to return the certificate for the\n"
1804 "request as a binary blob.";
1806 cmd_cachecert (assuan_context_t ctx, char *line)
1808 ctrl_t ctrl = assuan_get_pointer (ctx);
1810 ksba_cert_t cert = NULL;
1811 unsigned char *value = NULL;
1816 err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1817 &value, &valuelen, MAX_CERT_LENGTH);
1820 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1824 if (!valuelen) /* No data returned; return a comprehensible error. */
1825 err = gpg_error (GPG_ERR_MISSING_CERT);
1828 err = ksba_cert_new (&cert);
1830 err = ksba_cert_init_from_mem (cert, value, valuelen);
1836 err = cache_cert (cert);
1839 ksba_cert_release (cert);
1840 return leave_cmd (ctx, err);
1844 static const char hlp_validate[] =
1845 "VALIDATE [--systrust] [--tls] [--no-crl]\n"
1847 "Validate a certificate using the certificate validation function\n"
1848 "used internally by dirmngr. This command is only useful for\n"
1849 "debugging. To get the actual certificate, this command immediately\n"
1850 "inquires it using\n"
1852 " INQUIRE TARGETCERT\n"
1854 "and the caller is expected to return the certificate for the\n"
1855 "request as a binary blob. The option --tls modifies this by asking\n"
1856 "for list of certificates with\n"
1858 " INQUIRE CERTLIST\n"
1860 "Here the first certificate is the target certificate, the remaining\n"
1861 "certificates are suggested intermediary certificates. All certifciates\n"
1862 "need to be PEM encoded.\n"
1864 "The option --systrust changes the behaviour to include the system\n"
1865 "provided root certificates as trust anchors. The option --no-crl\n"
1868 cmd_validate (assuan_context_t ctx, char *line)
1870 ctrl_t ctrl = assuan_get_pointer (ctx);
1872 ksba_cert_t cert = NULL;
1873 certlist_t certlist = NULL;
1874 unsigned char *value = NULL;
1876 int systrust_mode, tls_mode, no_crl;
1878 systrust_mode = has_option (line, "--systrust");
1879 tls_mode = has_option (line, "--tls");
1880 no_crl = has_option (line, "--no-crl");
1881 line = skip_options (line);
1884 err = assuan_inquire (ctrl->server_local->assuan_ctx, "CERTLIST",
1885 &value, &valuelen, MAX_CERTLIST_LENGTH);
1887 err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1888 &value, &valuelen, MAX_CERT_LENGTH);
1891 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1895 if (!valuelen) /* No data returned; return a comprehensible error. */
1896 err = gpg_error (GPG_ERR_MISSING_CERT);
1901 fp = es_fopenmem_init (0, "rb", value, valuelen);
1903 err = gpg_error_from_syserror ();
1906 err = read_certlist_from_stream (&certlist, fp);
1908 if (!err && !certlist)
1909 err = gpg_error (GPG_ERR_MISSING_CERT);
1912 /* Extraxt the first certificate from the list. */
1913 cert = certlist->cert;
1914 ksba_cert_ref (cert);
1920 err = ksba_cert_new (&cert);
1922 err = ksba_cert_init_from_mem (cert, value, valuelen);
1930 /* If we have this certificate already in our cache, use the
1931 * cached version for validation because this will take care of
1932 * any cached results. We don't need to do this in tls mode
1933 * because this has already been done for certificate in a
1935 unsigned char fpr[20];
1936 ksba_cert_t tmpcert;
1938 cert_compute_fpr (cert, fpr);
1939 tmpcert = get_cert_byfpr (fpr);
1942 ksba_cert_release (cert);
1947 /* Quick hack to make verification work by inserting the supplied
1948 * certs into the cache. */
1949 if (tls_mode && certlist)
1953 for (cl = certlist->next; cl; cl = cl->next)
1954 cache_cert (cl->cert);
1957 err = validate_cert_chain (ctrl, cert, NULL,
1958 (VALIDATE_FLAG_TRUST_CONFIG
1959 | (tls_mode ? VALIDATE_FLAG_TLS : 0)
1960 | (systrust_mode ? VALIDATE_FLAG_TRUST_SYSTEM : 0)
1961 | (no_crl ? VALIDATE_FLAG_NOCRLCHECK : 0)),
1965 ksba_cert_release (cert);
1966 release_certlist (certlist);
1967 return leave_cmd (ctx, err);
1972 /* Parse an keyserver URI and store it in a new uri item which is
1973 returned at R_ITEM. On error return an error code. */
1975 make_keyserver_item (const char *uri, uri_item_t *r_item)
1981 item = xtrymalloc (sizeof *item + strlen (uri));
1983 return gpg_error_from_syserror ();
1986 item->parsed_uri = NULL;
1987 strcpy (item->uri, uri);
1990 if (ldap_uri_p (item->uri))
1991 err = ldap_parse_uri (&item->parsed_uri, uri);
1995 err = http_parse_uri (&item->parsed_uri, uri, 1);
2006 /* If no keyserver is stored in CTRL but a global keyserver has been
2007 set, put that global keyserver into CTRL. We need use this
2008 function to help migrate from the old gpg based keyserver
2009 configuration to the new dirmngr based configuration. */
2011 ensure_keyserver (ctrl_t ctrl)
2015 uri_item_t onion_items = NULL;
2016 uri_item_t plain_items = NULL;
2020 if (ctrl->server_local->keyservers)
2021 return 0; /* Already set for this session. */
2024 /* No global option set. Fall back to default: */
2025 return make_keyserver_item (DIRMNGR_DEFAULT_KEYSERVER,
2026 &ctrl->server_local->keyservers);
2029 for (sl = opt.keyserver; sl; sl = sl->next)
2031 err = make_keyserver_item (sl->d, &item);
2034 if (item->parsed_uri->onion)
2036 item->next = onion_items;
2041 item->next = plain_items;
2046 /* Decide which to use. Note that the session has no keyservers
2048 if (onion_items && !onion_items->next && plain_items && !plain_items->next)
2050 /* If there is just one onion and one plain keyserver given, we take
2051 only one depending on whether Tor is running or not. */
2052 if (is_tor_running (ctrl))
2054 ctrl->server_local->keyservers = onion_items;
2059 ctrl->server_local->keyservers = plain_items;
2063 else if (!is_tor_running (ctrl))
2065 /* Tor is not running. It does not make sense to add Onion
2067 ctrl->server_local->keyservers = plain_items;
2072 /* In all other cases add all keyservers. */
2073 ctrl->server_local->keyservers = onion_items;
2075 for (ui = ctrl->server_local->keyservers; ui && ui->next; ui = ui->next)
2078 ui->next = plain_items;
2080 ctrl->server_local->keyservers = plain_items;
2085 release_uri_item_list (onion_items);
2086 release_uri_item_list (plain_items);
2092 static const char hlp_keyserver[] =
2093 "KEYSERVER [<options>] [<uri>|<host>]\n"
2096 " --clear Remove all configured keyservers\n"
2097 " --resolve Resolve HKP host names and rotate\n"
2098 " --hosttable Print table of known hosts and pools\n"
2099 " --dead Mark <host> as dead\n"
2100 " --alive Mark <host> as alive\n"
2102 "If called without arguments list all configured keyserver URLs.\n"
2103 "If called with an URI add this as keyserver. Note that keyservers\n"
2104 "are configured on a per-session base. A default keyserver may already be\n"
2105 "present, thus the \"--clear\" option must be used to get full control.\n"
2106 "If \"--clear\" and an URI are used together the clear command is\n"
2107 "obviously executed first. A RESET command does not change the list\n"
2108 "of configured keyservers.";
2110 cmd_keyserver (assuan_context_t ctx, char *line)
2112 ctrl_t ctrl = assuan_get_pointer (ctx);
2113 gpg_error_t err = 0;
2114 int clear_flag, add_flag, help_flag, host_flag, resolve_flag;
2115 int dead_flag, alive_flag;
2116 uri_item_t item = NULL; /* gcc 4.4.5 is not able to detect that it
2117 is always initialized. */
2119 clear_flag = has_option (line, "--clear");
2120 help_flag = has_option (line, "--help");
2121 resolve_flag = has_option (line, "--resolve");
2122 host_flag = has_option (line, "--hosttable");
2123 dead_flag = has_option (line, "--dead");
2124 alive_flag = has_option (line, "--alive");
2125 line = skip_options (line);
2130 err = ks_action_help (ctrl, line);
2136 err = ensure_keyserver (ctrl);
2139 assuan_set_error (ctx, err,
2140 "Bad keyserver configuration in dirmngr.conf");
2143 err = ks_action_resolve (ctrl, ctrl->server_local->keyservers);
2148 if (alive_flag && dead_flag)
2150 err = set_error (GPG_ERR_ASS_PARAMETER, "no support for zombies");
2155 err = check_owner_permission (ctx, "no permission to use --dead");
2159 if (alive_flag || dead_flag)
2163 err = set_error (GPG_ERR_ASS_PARAMETER, "name of host missing");
2167 err = ks_hkp_mark_host (ctrl, line, alive_flag);
2174 err = ks_hkp_print_hosttable (ctrl);
2178 if (resolve_flag || host_flag || alive_flag || dead_flag)
2183 err = make_keyserver_item (line, &item);
2188 release_ctrl_keyservers (ctrl);
2191 item->next = ctrl->server_local->keyservers;
2192 ctrl->server_local->keyservers = item;
2195 if (!add_flag && !clear_flag && !help_flag)
2197 /* List configured keyservers. However, we first add a global
2201 err = ensure_keyserver (ctrl);
2204 assuan_set_error (ctx, err,
2205 "Bad keyserver configuration in dirmngr.conf");
2209 for (u=ctrl->server_local->keyservers; u; u = u->next)
2210 dirmngr_status (ctrl, "KEYSERVER", u->uri, NULL);
2215 return leave_cmd (ctx, err);
2220 static const char hlp_ks_search[] =
2221 "KS_SEARCH {<pattern>}\n"
2223 "Search the configured OpenPGP keyservers (see command KEYSERVER)\n"
2224 "for keys matching PATTERN";
2226 cmd_ks_search (assuan_context_t ctx, char *line)
2228 ctrl_t ctrl = assuan_get_pointer (ctx);
2234 if (has_option (line, "--quick"))
2235 ctrl->timeout = opt.connect_quick_timeout;
2236 line = skip_options (line);
2238 /* Break the line down into an strlist. Each pattern is
2239 percent-plus escaped. */
2241 for (p=line; *p; line = p)
2243 while (*p && *p != ' ')
2249 sl = xtrymalloc (sizeof *sl + strlen (line));
2252 err = gpg_error_from_syserror ();
2256 strcpy_escaped_plus (sl->d, line);
2262 err = ensure_keyserver (ctrl);
2266 /* Setup an output stream and perform the search. */
2267 outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
2269 err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2272 err = ks_action_search (ctrl, ctrl->server_local->keyservers,
2278 free_strlist (list);
2279 return leave_cmd (ctx, err);
2284 static const char hlp_ks_get[] =
2285 "KS_GET {<pattern>}\n"
2287 "Get the keys matching PATTERN from the configured OpenPGP keyservers\n"
2288 "(see command KEYSERVER). Each pattern should be a keyid, a fingerprint,\n"
2289 "or an exact name indicated by the '=' prefix.";
2291 cmd_ks_get (assuan_context_t ctx, char *line)
2293 ctrl_t ctrl = assuan_get_pointer (ctx);
2299 if (has_option (line, "--quick"))
2300 ctrl->timeout = opt.connect_quick_timeout;
2301 line = skip_options (line);
2303 /* Break the line into a strlist. Each pattern is by
2304 definition percent-plus escaped. However we only support keyids
2305 and fingerprints and thus the client has no need to apply the
2308 for (p=line; *p; line = p)
2310 while (*p && *p != ' ')
2316 sl = xtrymalloc (sizeof *sl + strlen (line));
2319 err = gpg_error_from_syserror ();
2323 strcpy_escaped_plus (sl->d, line);
2329 err = ensure_keyserver (ctrl);
2333 /* Setup an output stream and perform the get. */
2334 outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
2336 err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2339 ctrl->server_local->inhibit_data_logging = 1;
2340 ctrl->server_local->inhibit_data_logging_now = 0;
2341 ctrl->server_local->inhibit_data_logging_count = 0;
2342 err = ks_action_get (ctrl, ctrl->server_local->keyservers, list, outfp);
2344 ctrl->server_local->inhibit_data_logging = 0;
2348 free_strlist (list);
2349 return leave_cmd (ctx, err);
2353 static const char hlp_ks_fetch[] =
2356 "Get the key(s) from URL.";
2358 cmd_ks_fetch (assuan_context_t ctx, char *line)
2360 ctrl_t ctrl = assuan_get_pointer (ctx);
2364 if (has_option (line, "--quick"))
2365 ctrl->timeout = opt.connect_quick_timeout;
2366 line = skip_options (line);
2368 err = ensure_keyserver (ctrl); /* FIXME: Why do we needs this here? */
2372 /* Setup an output stream and perform the get. */
2373 outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
2375 err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2378 ctrl->server_local->inhibit_data_logging = 1;
2379 ctrl->server_local->inhibit_data_logging_now = 0;
2380 ctrl->server_local->inhibit_data_logging_count = 0;
2381 err = ks_action_fetch (ctrl, line, outfp);
2383 ctrl->server_local->inhibit_data_logging = 0;
2387 return leave_cmd (ctx, err);
2392 static const char hlp_ks_put[] =
2395 "Send a key to the configured OpenPGP keyservers. The actual key material\n"
2396 "is then requested by Dirmngr using\n"
2398 " INQUIRE KEYBLOCK\n"
2400 "The client shall respond with a binary version of the keyblock (e.g.,\n"
2401 "the output of `gpg --export KEYID'). For LDAP\n"
2402 "keyservers Dirmngr may ask for meta information of the provided keyblock\n"
2405 " INQUIRE KEYBLOCK_INFO\n"
2407 "The client shall respond with a colon delimited info lines (the output\n"
2408 "of 'for x in keys sigs; do gpg --list-$x --with-colons KEYID; done').\n";
2410 cmd_ks_put (assuan_context_t ctx, char *line)
2412 ctrl_t ctrl = assuan_get_pointer (ctx);
2414 unsigned char *value = NULL;
2416 unsigned char *info = NULL;
2419 /* No options for now. */
2420 line = skip_options (line);
2422 err = ensure_keyserver (ctrl);
2426 /* Ask for the key material. */
2427 err = assuan_inquire (ctx, "KEYBLOCK",
2428 &value, &valuelen, MAX_KEYBLOCK_LENGTH);
2431 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
2435 if (!valuelen) /* No data returned; return a comprehensible error. */
2437 err = gpg_error (GPG_ERR_MISSING_CERT);
2441 /* Ask for the key meta data. Not actually needed for HKP servers
2442 but we do it anyway to test the client implementation. */
2443 err = assuan_inquire (ctx, "KEYBLOCK_INFO",
2444 &info, &infolen, MAX_KEYBLOCK_LENGTH);
2447 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
2452 err = ks_action_put (ctrl, ctrl->server_local->keyservers,
2453 value, valuelen, info, infolen);
2458 return leave_cmd (ctx, err);
2463 static const char hlp_loadswdb[] =
2464 "LOADSWDB [--force]\n"
2466 "Load and verify the swdb.lst from the Net.";
2468 cmd_loadswdb (assuan_context_t ctx, char *line)
2470 ctrl_t ctrl = assuan_get_pointer (ctx);
2473 err = dirmngr_load_swdb (ctrl, has_option (line, "--force"));
2475 return leave_cmd (ctx, err);
2480 static const char hlp_getinfo[] =
2483 "Multi purpose command to return certain information. \n"
2484 "Supported values of WHAT are:\n"
2486 "version - Return the version of the program.\n"
2487 "pid - Return the process id of the server.\n"
2488 "tor - Return OK if running in Tor mode\n"
2489 "dnsinfo - Return info about the DNS resolver\n"
2490 "socket_name - Return the name of the socket.\n"
2491 "session_id - Return the current session_id.\n"
2492 "workqueue - Inspect the work queue\n";
2494 cmd_getinfo (assuan_context_t ctx, char *line)
2496 ctrl_t ctrl = assuan_get_pointer (ctx);
2500 if (!strcmp (line, "version"))
2502 const char *s = VERSION;
2503 err = assuan_send_data (ctx, s, strlen (s));
2505 else if (!strcmp (line, "pid"))
2507 snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
2508 err = assuan_send_data (ctx, numbuf, strlen (numbuf));
2510 else if (!strcmp (line, "socket_name"))
2512 const char *s = dirmngr_get_current_socket_name ();
2513 err = assuan_send_data (ctx, s, strlen (s));
2515 else if (!strcmp (line, "session_id"))
2517 snprintf (numbuf, sizeof numbuf, "%u", ctrl->server_local->session_id);
2518 err = assuan_send_data (ctx, numbuf, strlen (numbuf));
2520 else if (!strcmp (line, "tor"))
2524 use_tor = dirmngr_use_tor ();
2527 if (!is_tor_running (ctrl))
2528 err = assuan_write_status (ctx, "NO_TOR", "Tor not running");
2532 assuan_set_okay_line (ctx, use_tor == 1 ? "- Tor mode is enabled"
2533 /**/ : "- Tor mode is enforced");
2536 err = set_error (GPG_ERR_FALSE, "Tor mode is NOT enabled");
2538 else if (!strcmp (line, "dnsinfo"))
2540 if (standard_resolver_p ())
2541 assuan_set_okay_line
2542 (ctx, "- Forced use of System resolver (w/o Tor support)");
2546 assuan_set_okay_line (ctx, (recursive_resolver_p ()
2547 ? "- Libdns recursive resolver"
2548 : "- Libdns stub resolver"));
2550 assuan_set_okay_line (ctx, "- System resolver (w/o Tor support)");
2555 else if (!strcmp (line, "workqueue"))
2557 workqueue_dump_queue (ctrl);
2561 err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
2563 return leave_cmd (ctx, err);
2568 static const char hlp_killdirmngr[] =
2571 "This command allows a user - given sufficient permissions -\n"
2572 "to kill this dirmngr process.\n";
2574 cmd_killdirmngr (assuan_context_t ctx, char *line)
2576 ctrl_t ctrl = assuan_get_pointer (ctx);
2580 ctrl->server_local->stopme = 1;
2581 assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
2582 return gpg_error (GPG_ERR_EOF);
2586 static const char hlp_reloaddirmngr[] =
2589 "This command is an alternative to SIGHUP\n"
2590 "to reload the configuration.";
2592 cmd_reloaddirmngr (assuan_context_t ctx, char *line)
2597 dirmngr_sighup_action ();
2603 /* Tell the assuan library about our commands. */
2605 register_commands (assuan_context_t ctx)
2609 assuan_handler_t handler;
2610 const char * const help;
2612 { "DNS_CERT", cmd_dns_cert, hlp_dns_cert },
2613 { "WKD_GET", cmd_wkd_get, hlp_wkd_get },
2614 { "LDAPSERVER", cmd_ldapserver, hlp_ldapserver },
2615 { "ISVALID", cmd_isvalid, hlp_isvalid },
2616 { "CHECKCRL", cmd_checkcrl, hlp_checkcrl },
2617 { "CHECKOCSP", cmd_checkocsp, hlp_checkocsp },
2618 { "LOOKUP", cmd_lookup, hlp_lookup },
2619 { "LOADCRL", cmd_loadcrl, hlp_loadcrl },
2620 { "LISTCRLS", cmd_listcrls, hlp_listcrls },
2621 { "CACHECERT", cmd_cachecert, hlp_cachecert },
2622 { "VALIDATE", cmd_validate, hlp_validate },
2623 { "KEYSERVER", cmd_keyserver, hlp_keyserver },
2624 { "KS_SEARCH", cmd_ks_search, hlp_ks_search },
2625 { "KS_GET", cmd_ks_get, hlp_ks_get },
2626 { "KS_FETCH", cmd_ks_fetch, hlp_ks_fetch },
2627 { "KS_PUT", cmd_ks_put, hlp_ks_put },
2628 { "GETINFO", cmd_getinfo, hlp_getinfo },
2629 { "LOADSWDB", cmd_loadswdb, hlp_loadswdb },
2630 { "KILLDIRMNGR",cmd_killdirmngr,hlp_killdirmngr },
2631 { "RELOADDIRMNGR",cmd_reloaddirmngr,hlp_reloaddirmngr },
2636 for (i=j=0; table[i].name; i++)
2638 rc = assuan_register_command (ctx, table[i].name, table[i].handler,
2647 /* Note that we do not reset the list of configured keyservers. */
2649 reset_notify (assuan_context_t ctx, char *line)
2651 ctrl_t ctrl = assuan_get_pointer (ctx);
2655 ldapserver_list_free (ctrl->server_local->ldapservers);
2657 ctrl->server_local->ldapservers = NULL;
2662 /* This function is called by our assuan log handler to test whether a
2663 * log message shall really be printed. The function must return
2664 * false to inhibit the logging of MSG. CAT gives the requested log
2665 * category. MSG might be NULL. */
2667 dirmngr_assuan_log_monitor (assuan_context_t ctx, unsigned int cat,
2670 ctrl_t ctrl = assuan_get_pointer (ctx);
2675 if (!ctrl || !ctrl->server_local)
2676 return 1; /* Can't decide - allow logging. */
2678 if (!ctrl->server_local->inhibit_data_logging)
2679 return 1; /* Not requested - allow logging. */
2681 /* Disallow logging if *_now is true. */
2682 return !ctrl->server_local->inhibit_data_logging_now;
2686 /* Startup the server and run the main command loop. With FD = -1,
2687 * use stdin/stdout. SESSION_ID is either 0 or a unique number
2688 * identifying a session. */
2690 start_command_handler (assuan_fd_t fd, unsigned int session_id)
2692 static const char hello[] = "Dirmngr " VERSION " at your service";
2693 static char *hello_line;
2695 assuan_context_t ctx;
2698 ctrl = xtrycalloc (1, sizeof *ctrl);
2700 ctrl->server_local = xtrycalloc (1, sizeof *ctrl->server_local);
2701 if (!ctrl || !ctrl->server_local)
2703 log_error (_("can't allocate control structure: %s\n"),
2709 dirmngr_init_default_ctrl (ctrl);
2711 rc = assuan_new (&ctx);
2714 log_error (_("failed to allocate assuan context: %s\n"),
2719 if (fd == ASSUAN_INVALID_FD)
2721 assuan_fd_t filedes[2];
2723 filedes[0] = assuan_fdopen (0);
2724 filedes[1] = assuan_fdopen (1);
2725 rc = assuan_init_pipe_server (ctx, filedes);
2729 rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED);
2734 assuan_release (ctx);
2735 log_error (_("failed to initialize the server: %s\n"),
2740 rc = register_commands (ctx);
2743 log_error (_("failed to the register commands with Assuan: %s\n"),
2751 hello_line = xtryasprintf
2756 opt.config_filename? opt.config_filename : "[none]",
2760 ctrl->server_local->assuan_ctx = ctx;
2761 assuan_set_pointer (ctx, ctrl);
2763 assuan_set_hello_line (ctx, hello_line);
2764 assuan_register_option_handler (ctx, option_handler);
2765 assuan_register_reset_notify (ctx, reset_notify);
2767 ctrl->server_local->session_id = session_id;
2771 rc = assuan_accept (ctx);
2776 log_info (_("Assuan accept problem: %s\n"), gpg_strerror (rc));
2780 #ifndef HAVE_W32_SYSTEM
2783 assuan_peercred_t peercred;
2785 if (!assuan_get_peercred (ctx, &peercred))
2786 log_info ("connection from process %ld (%ld:%ld)\n",
2787 (long)peercred->pid, (long)peercred->uid,
2788 (long)peercred->gid);
2792 rc = assuan_process (ctx);
2795 log_info (_("Assuan processing failed: %s\n"), gpg_strerror (rc));
2802 ldap_wrapper_connection_cleanup (ctrl);
2804 ldapserver_list_free (ctrl->server_local->ldapservers);
2806 ctrl->server_local->ldapservers = NULL;
2808 release_ctrl_keyservers (ctrl);
2810 ctrl->server_local->assuan_ctx = NULL;
2811 assuan_release (ctx);
2813 if (ctrl->server_local->stopme)
2817 log_error ("oops: connection control structure still referenced (%d)\n",
2821 release_ctrl_ocsp_certs (ctrl);
2822 xfree (ctrl->server_local);
2823 dirmngr_deinit_default_ctrl (ctrl);
2829 /* Send a status line back to the client. KEYWORD is the status
2830 keyword, the optional string arguments are blank separated added to
2831 the line, the last argument must be a NULL. */
2833 dirmngr_status (ctrl_t ctrl, const char *keyword, ...)
2835 gpg_error_t err = 0;
2837 assuan_context_t ctx;
2839 va_start (arg_ptr, keyword);
2841 if (ctrl->server_local && (ctx = ctrl->server_local->assuan_ctx))
2843 err = vprint_assuan_status_strings (ctx, keyword, arg_ptr);
2851 /* Print a help status line. The function splits text at LFs. */
2853 dirmngr_status_help (ctrl_t ctrl, const char *text)
2855 gpg_error_t err = 0;
2856 assuan_context_t ctx;
2858 if (ctrl->server_local && (ctx = ctrl->server_local->assuan_ctx))
2867 for ( ; *text && *text != '\n' && n < DIM (buf)-2; n++)
2872 err = assuan_write_status (ctx, "#", buf);
2874 while (!err && *text);
2881 /* Print a help status line using a printf like format. The function
2882 * splits text at LFs. */
2884 dirmngr_status_helpf (ctrl_t ctrl, const char *format, ...)
2890 va_start (arg_ptr, format);
2891 buf = es_vbsprintf (format, arg_ptr);
2892 err = buf? 0 : gpg_error_from_syserror ();
2895 err = dirmngr_status_help (ctrl, buf);
2901 /* This function is similar to print_assuan_status but takes a CTRL
2902 * arg instead of an assuan context as first argument. */
2904 dirmngr_status_printf (ctrl_t ctrl, const char *keyword,
2905 const char *format, ...)
2909 assuan_context_t ctx;
2911 if (!ctrl->server_local || !(ctx = ctrl->server_local->assuan_ctx))
2914 va_start (arg_ptr, format);
2915 err = vprint_assuan_status (ctx, keyword, format, arg_ptr);
2921 /* Send a tick progress indicator back. Fixme: This is only done for
2922 the currently active channel. */
2924 dirmngr_tick (ctrl_t ctrl)
2926 static time_t next_tick = 0;
2927 gpg_error_t err = 0;
2928 time_t now = time (NULL);
2932 next_tick = now + 1;
2934 else if ( now > next_tick )
2938 err = dirmngr_status (ctrl, "PROGRESS", "tick", "? 0 0", NULL);
2941 /* Take this as in indication for a cancel request. */
2942 err = gpg_error (GPG_ERR_CANCELED);
2947 next_tick = now + 1;