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>
35 #ifdef HAVE_W32_SYSTEM
37 # define WINVER 0x0500 /* Same as in common/sysutils.c */
39 # include <winsock2.h>
49 # include "ldapserver.h"
52 #include "certcache.h"
56 # include "ldap-wrapper.h"
58 #include "ks-action.h"
59 #include "ks-engine.h"
61 # include "ldap-parse-uri.h"
63 #include "dns-stuff.h"
64 #include "../common/mbox-util.h"
65 #include "../common/zb32.h"
66 #include "../common/server-help.h"
68 /* To avoid DoS attacks we limit the size of a certificate to
69 something reasonable. The DoS was actually only an issue back when
70 Dirmngr was a system service and not a user service. */
71 #define MAX_CERT_LENGTH (16*1024)
73 /* The limit for the CERTLIST inquiry. We allow for up to 20
74 * certificates but also take PEM encoding into account. */
75 #define MAX_CERTLIST_LENGTH ((MAX_CERT_LENGTH * 20 * 4)/3)
77 /* The same goes for OpenPGP keyblocks, but here we need to allow for
78 much longer blocks; a 200k keyblock is not too unusual for keys
79 with a lot of signatures (e.g. 0x5b0358a2). 9C31503C6D866396 even
80 has 770 KiB as of 2015-08-23. To avoid adding a runtime option we
81 now use 20MiB which should really be enough. Well, a key with
82 several pictures could be larger (the parser as a 18MiB limit for
83 attribute packets) but it won't be nice to the keyservers to send
84 them such large blobs. */
85 #define MAX_KEYBLOCK_LENGTH (20*1024*1024)
88 #define PARM_ERROR(t) assuan_set_error (ctx, \
89 gpg_error (GPG_ERR_ASS_PARAMETER), (t))
90 #define set_error(e,t) (ctx ? assuan_set_error (ctx, gpg_error (e), (t)) \
95 /* Control structure per connection. */
98 /* Data used to associate an Assuan context with local server data */
99 assuan_context_t assuan_ctx;
101 /* The session id (a counter). */
102 unsigned int session_id;
104 /* Per-session LDAP servers. */
105 ldap_server_t ldapservers;
107 /* Per-session list of keyservers. */
108 uri_item_t keyservers;
110 /* If this flag is set to true this dirmngr process will be
111 terminated after the end of this session. */
114 /* State variable private to is_tor_running. */
117 /* If the first both flags are set the assuan logging of data lines
118 * is suppressed. The count variable is used to show the number of
119 * non-logged bytes. */
120 size_t inhibit_data_logging_count;
121 unsigned int inhibit_data_logging : 1;
122 unsigned int inhibit_data_logging_now : 1;
126 /* Cookie definition for assuan data line output. */
127 static gpgrt_ssize_t data_line_cookie_write (void *cookie,
128 const void *buffer, size_t size);
129 static int data_line_cookie_close (void *cookie);
130 static es_cookie_io_functions_t data_line_cookie_functions =
133 data_line_cookie_write,
135 data_line_cookie_close
139 /* Local prototypes */
140 static const char *task_check_wkd_support (ctrl_t ctrl, const char *domain);
145 /* Accessor for the local ldapservers variable. */
147 get_ldapservers_from_ctrl (ctrl_t ctrl)
149 if (ctrl && ctrl->server_local)
150 return ctrl->server_local->ldapservers;
155 /* Release an uri_item_t list. */
157 release_uri_item_list (uri_item_t list)
161 uri_item_t tmp = list->next;
162 http_release_parsed_uri (list->parsed_uri);
168 /* Release all configured keyserver info from CTRL. */
170 release_ctrl_keyservers (ctrl_t ctrl)
172 if (! ctrl->server_local)
175 release_uri_item_list (ctrl->server_local->keyservers);
176 ctrl->server_local->keyservers = NULL;
181 /* Helper to print a message while leaving a command. */
183 leave_cmd (assuan_context_t ctx, gpg_error_t err)
187 const char *name = assuan_get_command_name (ctx);
190 if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT)
191 log_error ("command '%s' failed: %s\n", name,
194 log_error ("command '%s' failed: %s <%s>\n", name,
195 gpg_strerror (err), gpg_strsource (err));
201 /* This is a wrapper around assuan_send_data which makes debugging the
202 output in verbose mode easier. */
204 data_line_write (assuan_context_t ctx, const void *buffer_arg, size_t size)
206 ctrl_t ctrl = assuan_get_pointer (ctx);
207 const char *buffer = buffer_arg;
210 /* If we do not want logging, enable it here. */
211 if (ctrl && ctrl->server_local && ctrl->server_local->inhibit_data_logging)
212 ctrl->server_local->inhibit_data_logging_now = 1;
214 if (opt.verbose && buffer && size)
216 /* Ease reading of output by sending a physical line at each LF. */
223 p = memchr (buffer, '\n', nbytes);
224 n = p ? (p - buffer) + 1 : nbytes;
225 err = assuan_send_data (ctx, buffer, n);
228 gpg_err_set_errno (EIO);
233 if (nbytes && (err=assuan_send_data (ctx, NULL, 0))) /* Flush line. */
235 gpg_err_set_errno (EIO);
243 err = assuan_send_data (ctx, buffer, size);
246 gpg_err_set_errno (EIO); /* For use by data_line_cookie_write. */
252 if (ctrl && ctrl->server_local && ctrl->server_local->inhibit_data_logging)
254 ctrl->server_local->inhibit_data_logging_now = 0;
255 ctrl->server_local->inhibit_data_logging_count += size;
262 /* A write handler used by es_fopencookie to write assuan data
265 data_line_cookie_write (void *cookie, const void *buffer, size_t size)
267 assuan_context_t ctx = cookie;
269 if (data_line_write (ctx, buffer, size))
271 return (gpgrt_ssize_t)size;
276 data_line_cookie_close (void *cookie)
278 assuan_context_t ctx = cookie;
282 ctrl_t ctrl = assuan_get_pointer (ctx);
284 if (ctrl && ctrl->server_local
285 && ctrl->server_local->inhibit_data_logging
286 && ctrl->server_local->inhibit_data_logging_count)
287 log_debug ("(%zu bytes sent via D lines not shown)\n",
288 ctrl->server_local->inhibit_data_logging_count);
290 if (assuan_send_data (ctx, NULL, 0))
292 gpg_err_set_errno (EIO);
300 /* Copy the % and + escaped string S into the buffer D and replace the
301 escape sequences. Note, that it is sufficient to allocate the
302 target string D as long as the source string S, i.e.: strlen(s)+1.
303 Note further that if S contains an escaped binary Nul the resulting
304 string D will contain the 0 as well as all other characters but it
305 will be impossible to know whether this is the original EOS or a
308 strcpy_escaped_plus (char *d, const unsigned char *s)
312 if (*s == '%' && s[1] && s[2])
327 /* This function returns true if a Tor server is running. The status
328 * is cached for the current connection. */
330 is_tor_running (ctrl_t ctrl)
332 /* Check whether we can connect to the proxy. */
334 if (!ctrl || !ctrl->server_local)
335 return 0; /* Ooops. */
337 if (!ctrl->server_local->tor_state)
341 sock = assuan_sock_connect_byname (NULL, 0, 0, NULL, ASSUAN_SOCK_TOR);
342 if (sock == ASSUAN_INVALID_FD)
343 ctrl->server_local->tor_state = -1; /* Not running. */
346 assuan_sock_close (sock);
347 ctrl->server_local->tor_state = 1; /* Running. */
350 return (ctrl->server_local->tor_state > 0);
354 /* Return an error if the assuan context does not belong to the owner
355 of the process or to root. On error FAILTEXT is set as Assuan
358 check_owner_permission (assuan_context_t ctx, const char *failtext)
360 #ifdef HAVE_W32_SYSTEM
361 /* Under Windows the dirmngr is always run under the control of the
367 assuan_peercred_t cred;
369 ec = gpg_err_code (assuan_get_peercred (ctx, &cred));
370 if (!ec && cred->uid && cred->uid != getuid ())
373 return set_error (ec, failtext);
380 /* Common code for get_cert_local and get_issuer_cert_local. */
382 do_get_cert_local (ctrl_t ctrl, const char *name, const char *command)
384 unsigned char *value;
390 buf = name? strconcat (command, " ", name, NULL) : xtrystrdup (command);
392 rc = gpg_error_from_syserror ();
395 rc = assuan_inquire (ctrl->server_local->assuan_ctx, buf,
396 &value, &valuelen, MAX_CERT_LENGTH);
401 log_error (_("assuan_inquire(%s) failed: %s\n"),
402 command, gpg_strerror (rc));
412 rc = ksba_cert_new (&cert);
415 rc = ksba_cert_init_from_mem (cert, value, valuelen);
418 ksba_cert_release (cert);
428 /* Ask back to return a certificate for NAME, given as a regular gpgsm
429 * certificate identifier (e.g. fingerprint or one of the other
430 * methods). Alternatively, NULL may be used for NAME to return the
431 * current target certificate. Either return the certificate in a
432 * KSBA object or NULL if it is not available. */
434 get_cert_local (ctrl_t ctrl, const char *name)
436 if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
439 log_debug ("get_cert_local called w/o context\n");
442 return do_get_cert_local (ctrl, name, "SENDCERT");
447 /* Ask back to return the issuing certificate for NAME, given as a
448 * regular gpgsm certificate identifier (e.g. fingerprint or one
449 * of the other methods). Alternatively, NULL may be used for NAME to
450 * return the current target certificate. Either return the certificate
451 * in a KSBA object or NULL if it is not available. */
453 get_issuing_cert_local (ctrl_t ctrl, const char *name)
455 if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
458 log_debug ("get_issuing_cert_local called w/o context\n");
461 return do_get_cert_local (ctrl, name, "SENDISSUERCERT");
465 /* Ask back to return a certificate with subject NAME and a
466 * subjectKeyIdentifier of KEYID. */
468 get_cert_local_ski (ctrl_t ctrl, const char *name, ksba_sexp_t keyid)
470 unsigned char *value;
477 if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
480 log_debug ("get_cert_local_ski called w/o context\n");
485 log_debug ("get_cert_local_ski called with insufficient arguments\n");
489 hexkeyid = serial_hex (keyid);
492 log_debug ("serial_hex() failed\n");
496 buf = strconcat ("SENDCERT_SKI ", hexkeyid, " /", name, NULL);
499 log_error ("can't allocate enough memory: %s\n", strerror (errno));
505 rc = assuan_inquire (ctrl->server_local->assuan_ctx, buf,
506 &value, &valuelen, MAX_CERT_LENGTH);
510 log_error (_("assuan_inquire(%s) failed: %s\n"), "SENDCERT_SKI",
521 rc = ksba_cert_new (&cert);
524 rc = ksba_cert_init_from_mem (cert, value, valuelen);
527 ksba_cert_release (cert);
536 /* Ask the client via an inquiry to check the istrusted status of the
537 certificate specified by the hexified fingerprint HEXFPR. Returns
538 0 if the certificate is trusted by the client or an error code. */
540 get_istrusted_from_client (ctrl_t ctrl, const char *hexfpr)
542 unsigned char *value;
547 if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx
549 return gpg_error (GPG_ERR_INV_ARG);
551 snprintf (request, sizeof request, "ISTRUSTED %s", hexfpr);
552 rc = assuan_inquire (ctrl->server_local->assuan_ctx, request,
553 &value, &valuelen, 100);
556 log_error (_("assuan_inquire(%s) failed: %s\n"),
557 request, gpg_strerror (rc));
560 /* The expected data is: "1" or "1 cruft" (not a C-string). */
561 if (valuelen && *value == '1' && (valuelen == 1 || spacep (value+1)))
564 rc = gpg_error (GPG_ERR_NOT_TRUSTED);
572 /* Ask the client to return the certificate associated with the
573 current command. This is sometimes needed because the client usually
574 sends us just the cert ID, assuming that the request can be
575 satisfied from the cache, where the cert ID is used as key. */
577 inquire_cert_and_load_crl (assuan_context_t ctx)
579 ctrl_t ctrl = assuan_get_pointer (ctx);
581 unsigned char *value = NULL;
583 ksba_cert_t cert = NULL;
585 err = assuan_inquire( ctx, "SENDCERT", &value, &valuelen, 0);
590 /* FILE *fp = fopen ("foo.der", "r"); */
591 /* value = xmalloc (2000); */
592 /* valuelen = fread (value, 1, 2000, fp); */
596 if (!valuelen) /* No data returned; return a comprehensible error. */
597 return gpg_error (GPG_ERR_MISSING_CERT);
599 err = ksba_cert_new (&cert);
602 err = ksba_cert_init_from_mem (cert, value, valuelen);
605 xfree (value); value = NULL;
607 err = crl_cache_reload_crl (ctrl, cert);
610 ksba_cert_release (cert);
616 /* Handle OPTION commands. */
618 option_handler (assuan_context_t ctx, const char *key, const char *value)
620 ctrl_t ctrl = assuan_get_pointer (ctx);
623 if (!strcmp (key, "force-crl-refresh"))
625 int i = *value? atoi (value) : 0;
626 ctrl->force_crl_refresh = i;
628 else if (!strcmp (key, "audit-events"))
630 int i = *value? atoi (value) : 0;
631 ctrl->audit_events = i;
633 else if (!strcmp (key, "http-proxy"))
635 xfree (ctrl->http_proxy);
636 if (!*value || !strcmp (value, "none"))
637 ctrl->http_proxy = NULL;
638 else if (!(ctrl->http_proxy = xtrystrdup (value)))
639 err = gpg_error_from_syserror ();
641 else if (!strcmp (key, "honor-keyserver-url-used"))
643 /* Return an error if we are running in Tor mode. */
644 if (dirmngr_use_tor ())
645 err = gpg_error (GPG_ERR_FORBIDDEN);
647 else if (!strcmp (key, "http-crl"))
649 int i = *value? atoi (value) : 0;
650 ctrl->http_no_crl = !i;
653 err = gpg_error (GPG_ERR_UNKNOWN_OPTION);
660 static const char hlp_dns_cert[] =
661 "DNS_CERT <subtype> <name>\n"
662 "DNS_CERT --pka <user_id>\n"
663 "DNS_CERT --dane <user_id>\n"
665 "Return the CERT record for <name>. <subtype> is one of\n"
666 " * Return the first record of any supported subtype\n"
667 " PGP Return the first record of subtype PGP (3)\n"
668 " IPGP Return the first record of subtype IPGP (6)\n"
669 "If the content of a certificate is available (PGP) it is returned\n"
670 "by data lines. Fingerprints and URLs are returned via status lines.\n"
671 "In --pka mode the fingerprint and if available an URL is returned.\n"
672 "In --dane mode the key is returned from RR type 61";
674 cmd_dns_cert (assuan_context_t ctx, char *line)
676 ctrl_t ctrl = assuan_get_pointer (ctx);
678 int pka_mode, dane_mode;
680 char *namebuf = NULL;
681 char *encodedhash = NULL;
687 unsigned char *fpr = NULL;
691 pka_mode = has_option (line, "--pka");
692 dane_mode = has_option (line, "--dane");
693 line = skip_options (line);
695 if (pka_mode && dane_mode)
697 err = PARM_ERROR ("either --pka or --dane may be given");
701 if (pka_mode || dane_mode)
702 ; /* No need to parse here - we do this later. */
705 p = strchr (line, ' ');
708 err = PARM_ERROR ("missing arguments");
712 if (!strcmp (line, "*"))
713 certtype = DNS_CERTTYPE_ANY;
714 else if (!strcmp (line, "IPGP"))
715 certtype = DNS_CERTTYPE_IPGP;
716 else if (!strcmp (line, "PGP"))
717 certtype = DNS_CERTTYPE_PGP;
720 err = PARM_ERROR ("unknown subtype");
728 err = PARM_ERROR ("name missing");
733 if (pka_mode || dane_mode)
735 char *domain; /* Points to mbox. */
736 char hashbuf[32]; /* For SHA-1 and SHA-256. */
738 /* We lowercase ascii characters but the DANE I-D does not allow
739 this. FIXME: Check after the release of the RFC whether to
741 mbox = mailbox_from_userid (line, 0);
742 if (!mbox || !(domain = strchr (mbox, '@')))
744 err = set_error (GPG_ERR_INV_USER_ID, "no mailbox in user id");
751 gcry_md_hash_buffer (GCRY_MD_SHA1, hashbuf, mbox, strlen (mbox));
752 encodedhash = zb32_encode (hashbuf, 8*20);
755 err = gpg_error_from_syserror ();
758 namebuf = strconcat (encodedhash, "._pka.", domain, NULL);
761 err = gpg_error_from_syserror ();
765 certtype = DNS_CERTTYPE_IPGP;
769 /* Note: The hash is truncated to 28 bytes and we lowercase
770 the result only for aesthetic reasons. */
771 gcry_md_hash_buffer (GCRY_MD_SHA256, hashbuf, mbox, strlen (mbox));
772 encodedhash = bin2hex (hashbuf, 28, NULL);
775 err = gpg_error_from_syserror ();
778 ascii_strlwr (encodedhash);
779 namebuf = strconcat (encodedhash, "._openpgpkey.", domain, NULL);
782 err = gpg_error_from_syserror ();
786 certtype = DNS_CERTTYPE_RR61;
792 err = get_dns_cert (ctrl, name, certtype, &key, &keylen, &fpr, &fprlen, &url);
798 err = data_line_write (ctx, key, keylen);
807 tmpstr = bin2hex (fpr, fprlen, NULL);
809 err = gpg_error_from_syserror ();
812 err = assuan_write_status (ctx, "FPR", tmpstr);
821 err = assuan_write_status (ctx, "URL", url);
834 return leave_cmd (ctx, err);
839 /* Core of cmd_wkd_get and task_check_wkd_support. If CTX is NULL
840 * this function will not write anything to the assuan output. */
842 proc_wkd_get (ctrl_t ctrl, assuan_context_t ctx, char *line)
846 char *domainbuf = NULL;
847 char *domain; /* Points to mbox or domainbuf. This is used to
848 * connect to the host. */
849 char *domain_orig;/* Points to mbox. This is the used for the
850 * query; i.e. the domain part of the
854 char *encodedhash = NULL;
855 int opt_submission_addr;
856 int opt_policy_flags;
857 int is_wkd_query; /* True if this is a real WKD query. */
859 char portstr[20] = { 0 };
860 int subdomain_mode = 0;
862 opt_submission_addr = has_option (line, "--submission-address");
863 opt_policy_flags = has_option (line, "--policy-flags");
864 if (has_option (line, "--quick"))
865 ctrl->timeout = opt.connect_quick_timeout;
866 line = skip_options (line);
867 is_wkd_query = !(opt_policy_flags || opt_submission_addr);
869 mbox = mailbox_from_userid (line, 0);
870 if (!mbox || !(domain = strchr (mbox, '@')))
872 err = set_error (GPG_ERR_INV_USER_ID, "no mailbox in user id");
876 domain_orig = domain;
879 /* Let's check whether we already know that the domain does not
883 if (domaininfo_is_wkd_not_supported (domain_orig))
885 err = gpg_error (GPG_ERR_NO_DATA);
886 dirmngr_status_printf (ctrl, "NOTE", "wkd_cached_result %u", err);
892 /* First try the new "openpgp" subdomain. We check that the domain
893 * is valid because it is later used as an unescaped filename part
895 if (is_valid_domain_name (domain_orig))
897 dns_addrinfo_t aibuf;
899 domainbuf = strconcat ( "openpgpkey.", domain_orig, NULL);
902 err = gpg_error_from_syserror ();
906 /* FIXME: We should put a cache into dns-stuff because the same
907 * query (with a different port and socket type, though) will be
908 * done later by http function. */
909 err = resolve_dns_name (ctrl, domainbuf, 0, 0, 0, &aibuf, NULL);
916 else /* Got a subdomain. */
918 free_dns_addrinfo (aibuf);
924 /* Check for SRV records unless we have a subdomain. */
927 struct srventry *srvs;
928 unsigned int srvscount;
929 size_t domainlen, targetlen;
932 err = get_dns_srv (ctrl, domain, "openpgpkey", NULL, &srvs, &srvscount);
935 /* Ignore server failed becuase there are too many resolvers
936 * which do not work as expected. */
937 if (gpg_err_code (err) == GPG_ERR_SERVER_FAILED)
938 err = 0; /*(srvcount is guaranteed to be 0)*/
943 /* Check for rogue DNS names. */
944 for (i = 0; i < srvscount; i++)
946 if (!is_valid_domain_name (srvs[i].target))
948 err = gpg_error (GPG_ERR_DNS_ADDRESS);
949 log_error ("rogue openpgpkey SRV record for '%s'\n", domain);
955 /* Find the first target which also ends in DOMAIN or is equal
957 domainlen = strlen (domain);
958 for (i = 0; i < srvscount; i++)
961 log_debug ("srv: trying '%s:%hu'\n", srvs[i].target, srvs[i].port);
962 targetlen = strlen (srvs[i].target);
963 if ((targetlen > domainlen + 1
964 && srvs[i].target[targetlen - domainlen - 1] == '.'
965 && !ascii_strcasecmp (srvs[i].target + targetlen - domainlen,
967 || (targetlen == domainlen
968 && !ascii_strcasecmp (srvs[i].target, domain)))
971 domainbuf = xtrystrdup (srvs[i].target);
974 err = gpg_error_from_syserror ();
980 snprintf (portstr, sizeof portstr, ":%hu", srvs[i].port);
987 /* Prepare the hash of the local part. */
988 gcry_md_hash_buffer (GCRY_MD_SHA1, sha1buf, mbox, strlen (mbox));
989 encodedhash = zb32_encode (sha1buf, 8*20);
992 err = gpg_error_from_syserror ();
996 if (opt_submission_addr)
998 uri = strconcat ("https://",
1001 "/.well-known/openpgpkey/",
1002 subdomain_mode? domain_orig : "",
1003 subdomain_mode? "/" : "",
1004 "submission-address",
1007 else if (opt_policy_flags)
1009 uri = strconcat ("https://",
1012 "/.well-known/openpgpkey/",
1013 subdomain_mode? domain_orig : "",
1014 subdomain_mode? "/" : "",
1022 escapedmbox = http_escape_string (mbox, "%;?&=+#");
1025 uri = strconcat ("https://",
1028 "/.well-known/openpgpkey/",
1029 subdomain_mode? domain_orig : "",
1030 subdomain_mode? "/" : "",
1036 xfree (escapedmbox);
1040 err = dirmngr_status_printf (ctrl, "SOURCE", "https://%s%s",
1049 err = gpg_error_from_syserror ();
1053 /* Setup an output stream and perform the get. */
1057 outfp = ctx? es_fopencookie (ctx, "w", data_line_cookie_functions) : NULL;
1059 err = set_error (GPG_ERR_ASS_GENERAL,
1060 "error setting up a data stream");
1063 if (ctrl->server_local)
1066 ctrl->server_local->inhibit_data_logging = 1;
1067 ctrl->server_local->inhibit_data_logging_now = 0;
1068 ctrl->server_local->inhibit_data_logging_count = 0;
1070 err = ks_action_fetch (ctrl, uri, outfp);
1072 if (ctrl->server_local)
1073 ctrl->server_local->inhibit_data_logging = 0;
1075 /* Register the result under the domain name of MBOX. */
1076 switch (gpg_err_code (err))
1079 domaininfo_set_wkd_supported (domain_orig);
1082 case GPG_ERR_NO_NAME:
1083 /* There is no such domain. */
1084 domaininfo_set_no_name (domain_orig);
1087 case GPG_ERR_NO_DATA:
1088 if (is_wkd_query && ctrl->server_local)
1090 /* Mark that and schedule a check. */
1091 domaininfo_set_wkd_not_found (domain_orig);
1092 workqueue_add_task (task_check_wkd_support, domain_orig,
1093 ctrl->server_local->session_id, 1);
1095 else if (opt_policy_flags) /* No policy file - no support. */
1096 domaininfo_set_wkd_not_supported (domain_orig);
1100 /* Don't register other errors. */
1108 xfree (encodedhash);
1115 static const char hlp_wkd_get[] =
1116 "WKD_GET [--submission-address|--policy-flags] <user_id>\n"
1118 "Return the key or other info for <user_id>\n"
1119 "from the Web Key Directory.";
1121 cmd_wkd_get (assuan_context_t ctx, char *line)
1123 ctrl_t ctrl = assuan_get_pointer (ctx);
1126 err = proc_wkd_get (ctrl, ctx, line);
1128 return leave_cmd (ctx, err);
1132 /* A task to check whether DOMAIN supports WKD. This is done by
1133 * checking whether the policy flags file can be read. */
1135 task_check_wkd_support (ctrl_t ctrl, const char *domain)
1139 if (!ctrl || !domain)
1140 return "check_wkd_support";
1142 string = strconcat ("--policy-flags foo@", domain, NULL);
1144 log_error ("%s: %s\n", __func__, gpg_strerror (gpg_error_from_syserror ()));
1147 proc_wkd_get (ctrl, NULL, string);
1156 static const char hlp_ldapserver[] =
1157 "LDAPSERVER [--clear] <data>\n"
1159 "Add a new LDAP server to the list of configured LDAP servers.\n"
1160 "DATA is in the same format as expected in the configure file.\n"
1161 "An optional prefix \"ldap:\" is allowed. With no args all\n"
1162 "configured ldapservers are listed. Option --clear removes all\n"
1163 "servers configured in this session.";
1165 cmd_ldapserver (assuan_context_t ctx, char *line)
1168 ctrl_t ctrl = assuan_get_pointer (ctx);
1169 ldap_server_t server;
1170 ldap_server_t *last_next_p;
1173 clear_flag = has_option (line, "--clear");
1174 line = skip_options (line);
1175 while (spacep (line))
1181 ldapserver_list_free (ctrl->server_local->ldapservers);
1183 ctrl->server_local->ldapservers = NULL;
1186 if (!*line && clear_flag)
1187 return leave_cmd (ctx, 0);
1191 /* List all ldapservers. */
1192 struct ldapserver_iter ldapserver_iter;
1196 for (ldapserver_iter_begin (&ldapserver_iter, ctrl);
1197 !ldapserver_iter_end_p (&ldapserver_iter);
1198 ldapserver_iter_next (&ldapserver_iter))
1200 server = ldapserver_iter.server;
1202 snprintf (portstr, sizeof portstr, "%d", server->port);
1206 tmpstr = xtryasprintf ("ldap:%s:%s:%s:%s:%s:%s%s:",
1207 server->host? server->host : "",
1209 server->user? server->user : "",
1210 server->pass? "*****": "",
1211 server->base? server->base : "",
1212 server->starttls ? "starttls" :
1213 server->ldap_over_tls ? "ldaptls" : "none",
1214 server->ntds ? ",ntds" : "");
1216 return leave_cmd (ctx, gpg_error_from_syserror ());
1217 dirmngr_status (ctrl, "LDAPSERVER", tmpstr, NULL);
1220 return leave_cmd (ctx, 0);
1223 /* Skip an "ldap:" prefix unless it is a valid ldap url. */
1224 if (!strncmp (line, "ldap:", 5) && !(line[5] == '/' && line[6] == '/'))
1227 server = ldapserver_parse_one (line, NULL, 0);
1229 return leave_cmd (ctx, gpg_error (GPG_ERR_INV_ARG));
1231 last_next_p = &ctrl->server_local->ldapservers;
1232 while (*last_next_p)
1233 last_next_p = &(*last_next_p)->next;
1234 *last_next_p = server;
1235 return leave_cmd (ctx, 0);
1238 return leave_cmd (ctx, gpg_error (GPG_ERR_NOT_IMPLEMENTED));
1243 static const char hlp_isvalid[] =
1244 "ISVALID [--only-ocsp] [--force-default-responder]"
1245 " <certificate_id> [<certificate_fpr>]\n"
1247 "This command checks whether the certificate identified by the\n"
1248 "certificate_id is valid. This is done by consulting CRLs or\n"
1249 "whatever has been configured. Note, that the returned error codes\n"
1250 "are from gpg-error.h. The command may callback using the inquire\n"
1251 "function. See the manual for details.\n"
1253 "The CERTIFICATE_ID is a hex encoded string consisting of two parts,\n"
1254 "delimited by a single dot. The first part is the SHA-1 hash of the\n"
1255 "issuer name and the second part the serial number.\n"
1257 "If an OCSP check is desired CERTIFICATE_FPR with the hex encoded\n"
1258 "fingerprint of the certificate is required. In this case an OCSP\n"
1259 "request is done before consulting the CRL.\n"
1261 "If the option --only-ocsp is given, no fallback to a CRL check will\n"
1264 "If the option --force-default-responder is given, only the default\n"
1265 "OCSP responder will be used and any other methods of obtaining an\n"
1266 "OCSP responder URL won't be used.";
1268 cmd_isvalid (assuan_context_t ctx, char *line)
1270 ctrl_t ctrl = assuan_get_pointer (ctx);
1271 char *issuerhash, *serialno, *fpr;
1273 int did_inquire = 0;
1276 int force_default_responder;
1278 only_ocsp = has_option (line, "--only-ocsp");
1279 force_default_responder = has_option (line, "--force-default-responder");
1280 line = skip_options (line);
1282 /* We need to work on a copy of the line because that same Assuan
1283 * context may be used for an inquiry. That is because Assuan
1284 * reuses its line buffer. */
1285 issuerhash = xstrdup (line);
1287 serialno = strchr (issuerhash, '.');
1291 return leave_cmd (ctx, PARM_ERROR (_("serialno missing in cert ID")));
1294 if (strlen (issuerhash) != 40)
1297 return leave_cmd (ctx, PARM_ERROR ("cert ID is too short"));
1300 fpr = strchr (serialno, ' ');
1301 while (fpr && spacep (fpr))
1305 char *endp = strchr (fpr, ' ');
1308 if (strlen (fpr) != 40)
1311 return leave_cmd (ctx, PARM_ERROR ("fingerprint too short"));
1320 gnupg_isotime_t revoked_at;
1323 /* Note, that we currently ignore the supplied fingerprint FPR;
1324 * instead ocsp_isvalid does an inquire to ask for the cert.
1325 * The fingerprint may eventually be used to lookup the
1326 * certificate in a local cache. */
1327 if (!opt.allow_ocsp)
1328 err = gpg_error (GPG_ERR_NOT_SUPPORTED);
1330 err = ocsp_isvalid (ctrl, NULL, NULL, force_default_responder,
1331 revoked_at, &reason);
1333 if (gpg_err_code (err) == GPG_ERR_CERT_REVOKED)
1334 dirmngr_status_printf (ctrl, "REVOCATIONINFO", "%s %s",
1335 revoked_at, reason);
1337 if (gpg_err_code (err) == GPG_ERR_CONFIGURATION
1338 && gpg_err_source (err) == GPG_ERR_SOURCE_DIRMNGR)
1340 /* No default responder configured - fallback to CRL. */
1342 log_info ("falling back to CRL check\n");
1348 err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
1349 else if (opt.fake_crl && (err = fakecrl_isvalid (ctrl, issuerhash, serialno)))
1351 /* We already got the error code. */
1355 switch (crl_cache_isvalid (ctrl,
1356 issuerhash, serialno,
1357 ctrl->force_crl_refresh))
1359 case CRL_CACHE_VALID:
1362 case CRL_CACHE_INVALID:
1363 err = gpg_error (GPG_ERR_CERT_REVOKED);
1365 case CRL_CACHE_DONTKNOW:
1367 err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
1368 else if (!(err = inquire_cert_and_load_crl (ctx)))
1374 case CRL_CACHE_NOTTRUSTED:
1375 err = gpg_error (GPG_ERR_NOT_TRUSTED);
1377 case CRL_CACHE_CANTUSE:
1378 err = gpg_error (GPG_ERR_INV_CRL_OBJ);
1381 log_fatal ("crl_cache_isvalid returned invalid code\n");
1386 return leave_cmd (ctx, err);
1390 /* If the line contains a SHA-1 fingerprint as the first argument,
1391 return the FPR buffer on success. The function checks that the
1392 fingerprint consists of valid characters and prints and error
1393 message if it does not and returns NULL. Fingerprints are
1394 considered optional and thus no explicit error is returned. NULL is
1395 also returned if there is no fingerprint at all available.
1396 FPR must be a caller provided buffer of at least 20 bytes.
1398 Note that colons within the fingerprint are allowed to separate 2
1399 hex digits; this allows for easier cutting and pasting using the
1400 usual fingerprint rendering.
1402 static unsigned char *
1403 get_fingerprint_from_line (const char *line, unsigned char *fpr)
1408 for (s=line, i=0; *s && *s != ' '; s++ )
1410 if ( hexdigitp (s) && hexdigitp (s+1) )
1413 return NULL; /* Fingerprint too long. */
1414 fpr[i++] = xtoi_2 (s);
1417 else if ( *s != ':' )
1418 return NULL; /* Invalid. */
1421 return NULL; /* Fingerprint to short. */
1427 static const char hlp_checkcrl[] =
1428 "CHECKCRL [<fingerprint>]\n"
1430 "Check whether the certificate with FINGERPRINT (SHA-1 hash of the\n"
1431 "entire X.509 certificate blob) is valid or not by consulting the\n"
1432 "CRL responsible for this certificate. If the fingerprint has not\n"
1433 "been given or the certificate is not known, the function \n"
1434 "inquires the certificate using an\n"
1436 " INQUIRE TARGETCERT\n"
1438 "and the caller is expected to return the certificate for the\n"
1439 "request (which should match FINGERPRINT) as a binary blob.\n"
1440 "Processing then takes place without further interaction; in\n"
1441 "particular dirmngr tries to locate other required certificate by\n"
1442 "its own mechanism which includes a local certificate store as well\n"
1443 "as a list of trusted root certificates.\n"
1445 "The return value is the usual gpg-error code or 0 for ducesss;\n"
1446 "i.e. the certificate validity has been confirmed by a valid CRL.";
1448 cmd_checkcrl (assuan_context_t ctx, char *line)
1450 ctrl_t ctrl = assuan_get_pointer (ctx);
1452 unsigned char fprbuffer[20], *fpr;
1455 fpr = get_fingerprint_from_line (line, fprbuffer);
1456 cert = fpr? get_cert_byfpr (fpr) : NULL;
1460 /* We do not have this certificate yet or the fingerprint has
1461 not been given. Inquire it from the client. */
1462 unsigned char *value = NULL;
1465 err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1466 &value, &valuelen, MAX_CERT_LENGTH);
1469 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1473 if (!valuelen) /* No data returned; return a comprehensible error. */
1474 err = gpg_error (GPG_ERR_MISSING_CERT);
1477 err = ksba_cert_new (&cert);
1479 err = ksba_cert_init_from_mem (cert, value, valuelen);
1488 err = crl_cache_cert_isvalid (ctrl, cert, ctrl->force_crl_refresh);
1489 if (gpg_err_code (err) == GPG_ERR_NO_CRL_KNOWN)
1491 err = crl_cache_reload_crl (ctrl, cert);
1493 err = crl_cache_cert_isvalid (ctrl, cert, 0);
1497 ksba_cert_release (cert);
1498 return leave_cmd (ctx, err);
1502 static const char hlp_checkocsp[] =
1503 "CHECKOCSP [--force-default-responder] [<fingerprint>]\n"
1505 "Check whether the certificate with FINGERPRINT (SHA-1 hash of the\n"
1506 "entire X.509 certificate blob) is valid or not by asking an OCSP\n"
1507 "responder responsible for this certificate. The optional\n"
1508 "fingerprint may be used for a quick check in case an OCSP check has\n"
1509 "been done for this certificate recently (we always cache OCSP\n"
1510 "responses for a couple of minutes). If the fingerprint has not been\n"
1511 "given or there is no cached result, the function inquires the\n"
1512 "certificate using an\n"
1514 " INQUIRE TARGETCERT\n"
1516 "and the caller is expected to return the certificate for the\n"
1517 "request (which should match FINGERPRINT) as a binary blob.\n"
1518 "Processing then takes place without further interaction; in\n"
1519 "particular dirmngr tries to locate other required certificates by\n"
1520 "its own mechanism which includes a local certificate store as well\n"
1521 "as a list of trusted root certificates.\n"
1523 "If the option --force-default-responder is given, only the default\n"
1524 "OCSP responder will be used and any other methods of obtaining an\n"
1525 "OCSP responder URL won't be used.\n"
1527 "The return value is the usual gpg-error code or 0 for ducesss;\n"
1528 "i.e. the certificate validity has been confirmed by a valid CRL.";
1530 cmd_checkocsp (assuan_context_t ctx, char *line)
1532 ctrl_t ctrl = assuan_get_pointer (ctx);
1534 unsigned char fprbuffer[20], *fpr;
1536 int force_default_responder;
1537 gnupg_isotime_t revoked_at;
1540 force_default_responder = has_option (line, "--force-default-responder");
1541 line = skip_options (line);
1543 fpr = get_fingerprint_from_line (line, fprbuffer);
1544 cert = fpr? get_cert_byfpr (fpr) : NULL;
1548 /* We do not have this certificate yet or the fingerprint has
1549 not been given. Inquire it from the client. */
1550 unsigned char *value = NULL;
1553 err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1554 &value, &valuelen, MAX_CERT_LENGTH);
1557 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1561 if (!valuelen) /* No data returned; return a comprehensible error. */
1562 err = gpg_error (GPG_ERR_MISSING_CERT);
1565 err = ksba_cert_new (&cert);
1567 err = ksba_cert_init_from_mem (cert, value, valuelen);
1576 if (!opt.allow_ocsp)
1577 err = gpg_error (GPG_ERR_NOT_SUPPORTED);
1579 err = ocsp_isvalid (ctrl, cert, NULL, force_default_responder,
1580 revoked_at, &reason);
1582 if (gpg_err_code (err) == GPG_ERR_CERT_REVOKED)
1583 dirmngr_status_printf (ctrl, "REVOCATIONINFO", "%s %s",
1584 revoked_at, reason);
1588 ksba_cert_release (cert);
1589 return leave_cmd (ctx, err);
1595 lookup_cert_by_url (assuan_context_t ctx, const char *url)
1597 ctrl_t ctrl = assuan_get_pointer (ctx);
1598 gpg_error_t err = 0;
1599 unsigned char *value = NULL;
1602 /* Fetch single certificate given it's URL. */
1603 err = fetch_cert_by_url (ctrl, url, &value, &valuelen);
1606 log_error (_("fetch_cert_by_url failed: %s\n"), gpg_strerror (err));
1610 /* Send the data, flush the buffer and then send an END. */
1611 err = assuan_send_data (ctx, value, valuelen);
1613 err = assuan_send_data (ctx, NULL, 0);
1615 err = assuan_write_line (ctx, "END");
1618 log_error (_("error sending data: %s\n"), gpg_strerror (err));
1628 /* Send the certificate, flush the buffer and then send an END. */
1630 return_one_cert (void *opaque, ksba_cert_t cert)
1632 assuan_context_t ctx = opaque;
1634 const unsigned char *der;
1637 der = ksba_cert_get_image (cert, &derlen);
1639 err = gpg_error (GPG_ERR_INV_CERT_OBJ);
1642 err = assuan_send_data (ctx, der, derlen);
1644 err = assuan_send_data (ctx, NULL, 0);
1646 err = assuan_write_line (ctx, "END");
1649 log_error (_("error sending data: %s\n"), gpg_strerror (err));
1654 /* Lookup certificates from the internal cache or using the ldap
1657 lookup_cert_by_pattern (assuan_context_t ctx, char *line,
1658 int single, int cache_only)
1660 gpg_error_t err = 0;
1662 strlist_t sl, list = NULL;
1663 int truncated = 0, truncation_forced = 0;
1665 int local_count = 0;
1667 ctrl_t ctrl = assuan_get_pointer (ctx);
1668 unsigned char *value = NULL;
1670 struct ldapserver_iter ldapserver_iter;
1671 cert_fetch_context_t fetch_context;
1673 int any_no_data = 0;
1675 /* Break the line down into an STRLIST */
1676 for (p=line; *p; line = p)
1678 while (*p && *p != ' ')
1685 sl = xtrymalloc (sizeof *sl + strlen (line));
1688 err = gpg_error_from_errno (errno);
1691 memset (sl, 0, sizeof *sl);
1692 strcpy_escaped_plus (sl->d, line);
1698 /* First look through the internal cache. The certificates returned
1699 here are not counted towards the truncation limit. */
1700 if (single && !cache_only)
1701 ; /* Do not read from the local cache in this case. */
1704 for (sl=list; sl; sl = sl->next)
1706 err = get_certs_bypattern (sl->d, return_one_cert, ctx);
1712 if (gpg_err_code (err) == GPG_ERR_NO_DATA
1713 || gpg_err_code (err) == GPG_ERR_NOT_FOUND)
1719 else if (gpg_err_code (err) == GPG_ERR_INV_NAME && !cache_only)
1721 /* No real fault because the internal pattern lookup
1722 can't yet cope with all types of pattern. */
1730 /* Loop over all configured servers unless we want only the
1731 certificates from the cache. */
1733 for (ldapserver_iter_begin (&ldapserver_iter, ctrl);
1734 !cache_only && !ldapserver_iter_end_p (&ldapserver_iter)
1735 && ldapserver_iter.server->host && !truncation_forced;
1736 ldapserver_iter_next (&ldapserver_iter))
1738 ldap_server_t ldapserver = ldapserver_iter.server;
1741 log_debug ("cmd_lookup: trying %s:%d base=%s\n",
1742 ldapserver->host, ldapserver->port,
1743 ldapserver->base?ldapserver->base : "[default]");
1745 /* Fetch certificates matching pattern */
1746 err = start_cert_fetch (ctrl, &fetch_context, list, ldapserver);
1747 if ( gpg_err_code (err) == GPG_ERR_NO_DATA )
1750 log_debug ("cmd_lookup: no data\n");
1757 log_error (_("start_cert_fetch failed: %s\n"), gpg_strerror (err));
1761 /* Fetch the certificates for this query. */
1762 while (!truncation_forced)
1764 xfree (value); value = NULL;
1765 err = fetch_next_cert (fetch_context, &value, &valuelen);
1766 if (gpg_err_code (err) == GPG_ERR_NO_DATA )
1772 if (gpg_err_code (err) == GPG_ERR_TRUNCATED)
1778 if (gpg_err_code (err) == GPG_ERR_EOF)
1785 err = gpg_error (GPG_ERR_BUG);
1790 log_error (_("fetch_next_cert failed: %s\n"),
1791 gpg_strerror (err));
1792 end_cert_fetch (fetch_context);
1797 log_debug ("cmd_lookup: returning one cert%s\n",
1798 truncated? " (truncated)":"");
1800 /* Send the data, flush the buffer and then send an END line
1801 as a certificate delimiter. */
1802 err = assuan_send_data (ctx, value, valuelen);
1804 err = assuan_send_data (ctx, NULL, 0);
1806 err = assuan_write_line (ctx, "END");
1809 log_error (_("error sending data: %s\n"), gpg_strerror (err));
1810 end_cert_fetch (fetch_context);
1814 if (++count >= opt.max_replies )
1816 truncation_forced = 1;
1817 log_info (_("max_replies %d exceeded\n"), opt.max_replies );
1823 end_cert_fetch (fetch_context);
1828 if (truncated || truncation_forced)
1832 sprintf (str, "%d", count);
1833 assuan_write_status (ctx, "TRUNCATED", str);
1836 if (!err && !count && !local_count && any_no_data)
1837 err = gpg_error (GPG_ERR_NO_DATA);
1840 free_strlist (list);
1845 static const char hlp_lookup[] =
1846 "LOOKUP [--url] [--single] [--cache-only] <pattern>\n"
1848 "Lookup certificates matching PATTERN. With --url the pattern is\n"
1849 "expected to be one URL.\n"
1851 "If --url is not given: To allow for multiple patterns (which are ORed)\n"
1852 "quoting is required: Spaces are translated to \"+\" or \"%20\";\n"
1853 "obviously this requires that the usual escape quoting rules are applied.\n"
1855 "If --url is given no special escaping is required because URLs are\n"
1856 "already escaped this way.\n"
1858 "If --single is given the first and only the first match will be\n"
1859 "returned. If --cache-only is _not_ given, no local query will be\n"
1862 "If --cache-only is given no external lookup is done so that only\n"
1863 "certificates from the cache may get returned.";
1865 cmd_lookup (assuan_context_t ctx, char *line)
1868 int lookup_url, single, cache_only;
1870 lookup_url = has_leading_option (line, "--url");
1871 single = has_leading_option (line, "--single");
1872 cache_only = has_leading_option (line, "--cache-only");
1873 line = skip_options (line);
1875 if (lookup_url && cache_only)
1876 err = gpg_error (GPG_ERR_NOT_FOUND);
1877 else if (lookup_url && single)
1878 err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1879 else if (lookup_url)
1880 err = lookup_cert_by_url (ctx, line);
1882 err = lookup_cert_by_pattern (ctx, line, single, cache_only);
1884 return leave_cmd (ctx, err);
1888 static const char hlp_loadcrl[] =
1889 "LOADCRL [--url] <filename|url>\n"
1891 "Load the CRL in the file with name FILENAME into our cache. Note\n"
1892 "that FILENAME should be given with an absolute path because\n"
1893 "Dirmngrs cwd is not known. With --url the CRL is directly loaded\n"
1894 "from the given URL.\n"
1896 "This command is usually used by gpgsm using the invocation \"gpgsm\n"
1897 "--call-dirmngr loadcrl <filename>\". A direct invocation of Dirmngr\n"
1898 "is not useful because gpgsm might need to callback gpgsm to ask for\n"
1899 "the CA's certificate.";
1901 cmd_loadcrl (assuan_context_t ctx, char *line)
1903 ctrl_t ctrl = assuan_get_pointer (ctx);
1904 gpg_error_t err = 0;
1905 int use_url = has_leading_option (line, "--url");
1907 line = skip_options (line);
1911 ksba_reader_t reader;
1913 err = crl_fetch (ctrl, line, &reader);
1915 log_error (_("fetching CRL from '%s' failed: %s\n"),
1916 line, gpg_strerror (err));
1919 err = crl_cache_insert (ctrl, line, reader);
1921 log_error (_("processing CRL from '%s' failed: %s\n"),
1922 line, gpg_strerror (err));
1923 crl_close_reader (reader);
1930 buf = xtrymalloc (strlen (line)+1);
1932 err = gpg_error_from_syserror ();
1935 strcpy_escaped_plus (buf, line);
1936 err = crl_cache_load (ctrl, buf);
1941 return leave_cmd (ctx, err);
1945 static const char hlp_listcrls[] =
1948 "List the content of all CRLs in a readable format. This command is\n"
1949 "usually used by gpgsm using the invocation \"gpgsm --call-dirmngr\n"
1950 "listcrls\". It may also be used directly using \"dirmngr\n"
1953 cmd_listcrls (assuan_context_t ctx, char *line)
1960 fp = es_fopencookie (ctx, "w", data_line_cookie_functions);
1962 err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
1965 err = crl_cache_list (fp);
1968 return leave_cmd (ctx, err);
1972 static const char hlp_cachecert[] =
1975 "Put a certificate into the internal cache. This command might be\n"
1976 "useful if a client knows in advance certificates required for a\n"
1977 "test and wants to make sure they get added to the internal cache.\n"
1978 "It is also helpful for debugging. To get the actual certificate,\n"
1979 "this command immediately inquires it using\n"
1981 " INQUIRE TARGETCERT\n"
1983 "and the caller is expected to return the certificate for the\n"
1984 "request as a binary blob.";
1986 cmd_cachecert (assuan_context_t ctx, char *line)
1988 ctrl_t ctrl = assuan_get_pointer (ctx);
1990 ksba_cert_t cert = NULL;
1991 unsigned char *value = NULL;
1996 err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1997 &value, &valuelen, MAX_CERT_LENGTH);
2000 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
2004 if (!valuelen) /* No data returned; return a comprehensible error. */
2005 err = gpg_error (GPG_ERR_MISSING_CERT);
2008 err = ksba_cert_new (&cert);
2010 err = ksba_cert_init_from_mem (cert, value, valuelen);
2016 err = cache_cert (cert);
2019 ksba_cert_release (cert);
2020 return leave_cmd (ctx, err);
2024 static const char hlp_validate[] =
2025 "VALIDATE [--systrust] [--tls] [--no-crl]\n"
2027 "Validate a certificate using the certificate validation function\n"
2028 "used internally by dirmngr. This command is only useful for\n"
2029 "debugging. To get the actual certificate, this command immediately\n"
2030 "inquires it using\n"
2032 " INQUIRE TARGETCERT\n"
2034 "and the caller is expected to return the certificate for the\n"
2035 "request as a binary blob. The option --tls modifies this by asking\n"
2036 "for list of certificates with\n"
2038 " INQUIRE CERTLIST\n"
2040 "Here the first certificate is the target certificate, the remaining\n"
2041 "certificates are suggested intermediary certificates. All certificates\n"
2042 "need to be PEM encoded.\n"
2044 "The option --systrust changes the behaviour to include the system\n"
2045 "provided root certificates as trust anchors. The option --no-crl\n"
2048 cmd_validate (assuan_context_t ctx, char *line)
2050 ctrl_t ctrl = assuan_get_pointer (ctx);
2052 ksba_cert_t cert = NULL;
2053 certlist_t certlist = NULL;
2054 unsigned char *value = NULL;
2056 int systrust_mode, tls_mode, no_crl;
2058 systrust_mode = has_option (line, "--systrust");
2059 tls_mode = has_option (line, "--tls");
2060 no_crl = has_option (line, "--no-crl");
2061 line = skip_options (line);
2064 err = assuan_inquire (ctrl->server_local->assuan_ctx, "CERTLIST",
2065 &value, &valuelen, MAX_CERTLIST_LENGTH);
2067 err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
2068 &value, &valuelen, MAX_CERT_LENGTH);
2071 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
2075 if (!valuelen) /* No data returned; return a comprehensible error. */
2076 err = gpg_error (GPG_ERR_MISSING_CERT);
2081 fp = es_fopenmem_init (0, "rb", value, valuelen);
2083 err = gpg_error_from_syserror ();
2086 err = read_certlist_from_stream (&certlist, fp);
2088 if (!err && !certlist)
2089 err = gpg_error (GPG_ERR_MISSING_CERT);
2092 /* Extract the first certificate from the list. */
2093 cert = certlist->cert;
2094 ksba_cert_ref (cert);
2100 err = ksba_cert_new (&cert);
2102 err = ksba_cert_init_from_mem (cert, value, valuelen);
2110 /* If we have this certificate already in our cache, use the
2111 * cached version for validation because this will take care of
2112 * any cached results. We don't need to do this in tls mode
2113 * because this has already been done for certificate in a
2115 unsigned char fpr[20];
2116 ksba_cert_t tmpcert;
2118 cert_compute_fpr (cert, fpr);
2119 tmpcert = get_cert_byfpr (fpr);
2122 ksba_cert_release (cert);
2127 /* Quick hack to make verification work by inserting the supplied
2128 * certs into the cache. */
2129 if (tls_mode && certlist)
2133 for (cl = certlist->next; cl; cl = cl->next)
2134 cache_cert (cl->cert);
2137 err = validate_cert_chain (ctrl, cert, NULL,
2138 (VALIDATE_FLAG_TRUST_CONFIG
2139 | (tls_mode ? VALIDATE_FLAG_TLS : 0)
2140 | (systrust_mode ? VALIDATE_FLAG_TRUST_SYSTEM : 0)
2141 | (no_crl ? VALIDATE_FLAG_NOCRLCHECK : 0)),
2145 ksba_cert_release (cert);
2146 release_certlist (certlist);
2147 return leave_cmd (ctx, err);
2152 /* Parse an keyserver URI and store it in a new uri item which is
2153 returned at R_ITEM. On error return an error code. */
2155 make_keyserver_item (const char *uri, uri_item_t *r_item)
2157 /* We used to have DNS CNAME redirection from the URLs below to
2158 * sks-keyserver. pools. The idea was to allow for a quick way to
2159 * switch to a different set of pools. The problem with that
2160 * approach is that TLS needs to verify the hostname and - because
2161 * DNS is not secured - it can only check the user supplied hostname
2162 * and not a hostname from a CNAME RR. Thus the final server all
2163 * need to have certificates with the actual pool name as well as
2164 * for keys.gnupg.net - that would render the advantage of
2165 * keys.gnupg.net useless and so we better give up on this. Because
2166 * the keys.gnupg.net URL are still in widespread use we do a static
2169 if (!strcmp (uri, "hkps://keys.gnupg.net")
2170 || !strcmp (uri, "keys.gnupg.net"))
2171 uri = "hkps://keyserver.ubuntu.com";
2172 else if (!strcmp (uri, "https://keys.gnupg.net"))
2173 uri = "hkps://keyserver.ubuntu.com";
2174 else if (!strcmp (uri, "hkp://keys.gnupg.net"))
2175 uri = "hkp://keyserver.ubuntu.com";
2176 else if (!strcmp (uri, "http://keys.gnupg.net"))
2177 uri = "hkp://keyserver.ubuntu.com:80";
2178 else if (!strcmp (uri, "hkps://http-keys.gnupg.net")
2179 || !strcmp (uri, "http-keys.gnupg.net"))
2180 uri = "hkps://keyserver.ubuntu.com";
2181 else if (!strcmp (uri, "https://http-keys.gnupg.net"))
2182 uri = "hkps://keyserver.ubuntu.com";
2183 else if (!strcmp (uri, "hkp://http-keys.gnupg.net"))
2184 uri = "hkp://keyserver.ubuntu.com";
2185 else if (!strcmp (uri, "http://http-keys.gnupg.net"))
2186 uri = "hkp://keyserver.ubuntu.com:80";
2188 return ks_action_parse_uri (uri, r_item);
2192 /* If no keyserver is stored in CTRL but a global keyserver has been
2193 set, put that global keyserver into CTRL. We need use this
2194 function to help migrate from the old gpg based keyserver
2195 configuration to the new dirmngr based configuration. */
2197 ensure_keyserver (ctrl_t ctrl)
2201 uri_item_t onion_items = NULL;
2202 uri_item_t plain_items = NULL;
2206 if (ctrl->server_local->keyservers)
2207 return 0; /* Already set for this session. */
2210 /* No global option set. Fall back to default: */
2211 return make_keyserver_item (DIRMNGR_DEFAULT_KEYSERVER,
2212 &ctrl->server_local->keyservers);
2215 for (sl = opt.keyserver; sl; sl = sl->next)
2217 err = make_keyserver_item (sl->d, &item);
2220 if (item->parsed_uri->onion)
2222 item->next = onion_items;
2227 item->next = plain_items;
2232 /* Decide which to use. Note that the session has no keyservers
2234 if (onion_items && !onion_items->next && plain_items && !plain_items->next)
2236 /* If there is just one onion and one plain keyserver given, we take
2237 only one depending on whether Tor is running or not. */
2238 if (!dirmngr_never_use_tor_p () && is_tor_running (ctrl))
2240 ctrl->server_local->keyservers = onion_items;
2245 ctrl->server_local->keyservers = plain_items;
2249 else if (dirmngr_never_use_tor_p () || !is_tor_running (ctrl))
2251 /* Tor is not running. It does not make sense to add Onion
2253 ctrl->server_local->keyservers = plain_items;
2258 /* In all other cases add all keyservers. */
2259 ctrl->server_local->keyservers = onion_items;
2261 for (ui = ctrl->server_local->keyservers; ui && ui->next; ui = ui->next)
2264 ui->next = plain_items;
2266 ctrl->server_local->keyservers = plain_items;
2271 release_uri_item_list (onion_items);
2272 release_uri_item_list (plain_items);
2278 static const char hlp_keyserver[] =
2279 "KEYSERVER [<options>] [<uri>|<host>]\n"
2282 " --clear Remove all configured keyservers\n"
2283 " --resolve Resolve HKP host names and rotate\n"
2284 " --hosttable Print table of known hosts and pools\n"
2285 " --dead Mark <host> as dead\n"
2286 " --alive Mark <host> as alive\n"
2288 "If called without arguments list all configured keyserver URLs.\n"
2289 "If called with an URI add this as keyserver. Note that keyservers\n"
2290 "are configured on a per-session base. A default keyserver may already be\n"
2291 "present, thus the \"--clear\" option must be used to get full control.\n"
2292 "If \"--clear\" and an URI are used together the clear command is\n"
2293 "obviously executed first. A RESET command does not change the list\n"
2294 "of configured keyservers.";
2296 cmd_keyserver (assuan_context_t ctx, char *line)
2298 ctrl_t ctrl = assuan_get_pointer (ctx);
2299 gpg_error_t err = 0;
2300 int clear_flag, add_flag, help_flag, host_flag, resolve_flag;
2301 int dead_flag, alive_flag;
2302 uri_item_t item = NULL; /* gcc 4.4.5 is not able to detect that it
2303 is always initialized. */
2305 clear_flag = has_option (line, "--clear");
2306 help_flag = has_option (line, "--help");
2307 resolve_flag = has_option (line, "--resolve");
2308 host_flag = has_option (line, "--hosttable");
2309 dead_flag = has_option (line, "--dead");
2310 alive_flag = has_option (line, "--alive");
2311 line = skip_options (line);
2316 err = ks_action_help (ctrl, line);
2322 err = ensure_keyserver (ctrl);
2325 assuan_set_error (ctx, err,
2326 "Bad keyserver configuration in dirmngr.conf");
2329 err = ks_action_resolve (ctrl, ctrl->server_local->keyservers);
2334 if (alive_flag && dead_flag)
2336 err = set_error (GPG_ERR_ASS_PARAMETER, "no support for zombies");
2341 err = check_owner_permission (ctx, "no permission to use --dead");
2345 if (alive_flag || dead_flag)
2349 err = set_error (GPG_ERR_ASS_PARAMETER, "name of host missing");
2353 err = ks_hkp_mark_host (ctrl, line, alive_flag);
2360 err = ks_hkp_print_hosttable (ctrl);
2364 if (resolve_flag || host_flag || alive_flag || dead_flag)
2369 err = make_keyserver_item (line, &item);
2374 release_ctrl_keyservers (ctrl);
2377 item->next = ctrl->server_local->keyservers;
2378 ctrl->server_local->keyservers = item;
2381 if (!add_flag && !clear_flag && !help_flag)
2383 /* List configured keyservers. However, we first add a global
2387 err = ensure_keyserver (ctrl);
2390 assuan_set_error (ctx, err,
2391 "Bad keyserver configuration in dirmngr.conf");
2395 for (u=ctrl->server_local->keyservers; u; u = u->next)
2396 dirmngr_status (ctrl, "KEYSERVER", u->uri, NULL);
2401 return leave_cmd (ctx, err);
2406 static const char hlp_ks_search[] =
2407 "KS_SEARCH {<pattern>}\n"
2409 "Search the configured OpenPGP keyservers (see command KEYSERVER)\n"
2410 "for keys matching PATTERN";
2412 cmd_ks_search (assuan_context_t ctx, char *line)
2414 ctrl_t ctrl = assuan_get_pointer (ctx);
2420 if (has_option (line, "--quick"))
2421 ctrl->timeout = opt.connect_quick_timeout;
2422 line = skip_options (line);
2424 /* Break the line down into an strlist. Each pattern is
2425 percent-plus escaped. */
2427 for (p=line; *p; line = p)
2429 while (*p && *p != ' ')
2435 sl = xtrymalloc (sizeof *sl + strlen (line));
2438 err = gpg_error_from_syserror ();
2442 strcpy_escaped_plus (sl->d, line);
2448 err = ensure_keyserver (ctrl);
2452 /* Setup an output stream and perform the search. */
2453 outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
2455 err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2458 err = ks_action_search (ctrl, ctrl->server_local->keyservers,
2464 free_strlist (list);
2465 return leave_cmd (ctx, err);
2470 static const char hlp_ks_get[] =
2471 "KS_GET [--quick] [--newer=TIME] [--ldap] [--first|--next] {<pattern>}\n"
2473 "Get the keys matching PATTERN from the configured OpenPGP keyservers\n"
2474 "(see command KEYSERVER). Each pattern should be a keyid, a fingerprint,\n"
2475 "or an exact name indicated by the '=' prefix. Option --quick uses a\n"
2476 "shorter timeout; --ldap will use only ldap servers. With --first only\n"
2477 "the first item is returned; --next is used to return the next item\n"
2478 "Option --newer works only with certain LDAP servers.";
2480 cmd_ks_get (assuan_context_t ctx, char *line)
2482 ctrl_t ctrl = assuan_get_pointer (ctx);
2484 strlist_t list = NULL;
2489 unsigned int flags = 0;
2490 gnupg_isotime_t opt_newer;
2494 if (has_option (line, "--quick"))
2495 ctrl->timeout = opt.connect_quick_timeout;
2496 if (has_option (line, "--ldap"))
2497 flags |= KS_GET_FLAG_ONLY_LDAP;
2498 if (has_option (line, "--first"))
2499 flags |= KS_GET_FLAG_FIRST;
2500 if (has_option (line, "--next"))
2501 flags |= KS_GET_FLAG_NEXT;
2502 if ((s = option_value (line, "--newer"))
2503 && !string2isotime (opt_newer, s))
2505 err = set_error (GPG_ERR_SYNTAX, "invalid time format");
2508 line = skip_options (line);
2510 /* Break the line into a strlist. Each pattern is by
2511 definition percent-plus escaped. However we only support keyids
2512 and fingerprints and thus the client has no need to apply the
2514 for (p=line; *p; line = p)
2516 while (*p && *p != ' ')
2522 sl = xtrymalloc (sizeof *sl + strlen (line));
2525 err = gpg_error_from_syserror ();
2529 strcpy_escaped_plus (sl->d, line);
2535 if ((flags & KS_GET_FLAG_FIRST) && !(flags & KS_GET_FLAG_ONLY_LDAP))
2537 err = PARM_ERROR ("--first is only supported with --ldap");
2541 if (list && list->next && (flags & KS_GET_FLAG_FIRST))
2543 /* ks_action_get loops over the pattern and we can't easily keep
2545 err = PARM_ERROR ("Only one pattern allowed with --first");
2549 if (!list && (flags & KS_GET_FLAG_FIRST))
2551 /* Need to add a dummy pattern if no pattern is given. */
2552 if (!add_to_strlist_try (&list, ""))
2554 err = gpg_error_from_syserror ();
2560 if ((flags & KS_GET_FLAG_NEXT))
2562 if (list || (flags & ~KS_GET_FLAG_NEXT))
2564 err = PARM_ERROR ("No pattern or other options allowed with --next");
2567 /* Add a dummy pattern. */
2568 if (!add_to_strlist_try (&list, ""))
2570 err = gpg_error_from_syserror ();
2576 err = ensure_keyserver (ctrl);
2580 /* Setup an output stream and perform the get. */
2581 outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
2583 err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2586 ctrl->server_local->inhibit_data_logging = 1;
2587 ctrl->server_local->inhibit_data_logging_now = 0;
2588 ctrl->server_local->inhibit_data_logging_count = 0;
2589 err = ks_action_get (ctrl, ctrl->server_local->keyservers,
2590 list, flags, opt_newer, outfp);
2592 ctrl->server_local->inhibit_data_logging = 0;
2596 free_strlist (list);
2597 return leave_cmd (ctx, err);
2601 static const char hlp_ks_fetch[] =
2604 "Get the key(s) from URL.";
2606 cmd_ks_fetch (assuan_context_t ctx, char *line)
2608 ctrl_t ctrl = assuan_get_pointer (ctx);
2612 if (has_option (line, "--quick"))
2613 ctrl->timeout = opt.connect_quick_timeout;
2614 line = skip_options (line);
2616 err = ensure_keyserver (ctrl); /* FIXME: Why do we needs this here? */
2620 /* Setup an output stream and perform the get. */
2621 outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
2623 err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2626 ctrl->server_local->inhibit_data_logging = 1;
2627 ctrl->server_local->inhibit_data_logging_now = 0;
2628 ctrl->server_local->inhibit_data_logging_count = 0;
2629 err = ks_action_fetch (ctrl, line, outfp);
2631 ctrl->server_local->inhibit_data_logging = 0;
2635 return leave_cmd (ctx, err);
2640 static const char hlp_ks_put[] =
2643 "Send a key to the configured OpenPGP keyservers. The actual key material\n"
2644 "is then requested by Dirmngr using\n"
2646 " INQUIRE KEYBLOCK\n"
2648 "The client shall respond with a binary version of the keyblock (e.g.,\n"
2649 "the output of `gpg --export KEYID'). For LDAP\n"
2650 "keyservers Dirmngr may ask for meta information of the provided keyblock\n"
2653 " INQUIRE KEYBLOCK_INFO\n"
2655 "The client shall respond with a colon delimited info lines (the output\n"
2656 "of 'gpg --list-keys --with-colons KEYID').\n";
2658 cmd_ks_put (assuan_context_t ctx, char *line)
2660 ctrl_t ctrl = assuan_get_pointer (ctx);
2662 unsigned char *value = NULL;
2664 unsigned char *info = NULL;
2667 /* No options for now. */
2668 line = skip_options (line);
2670 err = ensure_keyserver (ctrl);
2674 /* Ask for the key material. */
2675 err = assuan_inquire (ctx, "KEYBLOCK",
2676 &value, &valuelen, MAX_KEYBLOCK_LENGTH);
2679 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
2683 if (!valuelen) /* No data returned; return a comprehensible error. */
2685 err = gpg_error (GPG_ERR_MISSING_CERT);
2689 /* Ask for the key meta data. */
2690 err = assuan_inquire (ctx, "KEYBLOCK_INFO",
2691 &info, &infolen, MAX_KEYBLOCK_LENGTH);
2694 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
2699 err = ks_action_put (ctrl, ctrl->server_local->keyservers,
2700 value, valuelen, info, infolen);
2705 return leave_cmd (ctx, err);
2710 static const char hlp_ad_query[] =
2711 "AD_QUERY [--first|--next] [--] <filter> \n"
2713 "Query properties from a Windows Active Directory.\n"
2716 " --rootdse - Query the root using serverless binding,\n"
2717 " --subst - Substitute variables in the filter\n"
2718 " --attr=<attribs> - Comma delimited list of attributes\n"
2720 " --help - List supported variables\n"
2722 "Extended filter syntax is allowed:\n"
2723 " ^[<base>][&<scope>]&[<filter>]\n"
2724 "Usual escaping rules apply. An ampersand in <base> must\n"
2725 "doubled. <scope> may be \"base\", \"one\", or \"sub\"."
2728 cmd_ad_query (assuan_context_t ctx, char *line)
2730 ctrl_t ctrl = assuan_get_pointer (ctx);
2732 unsigned int flags = 0;
2734 estream_t outfp = NULL;
2736 char **opt_attr = NULL;
2738 gnupg_isotime_t opt_newer;
2743 /* No options for now. */
2744 if (has_option (line, "--first"))
2745 flags |= KS_GET_FLAG_FIRST;
2746 if (has_option (line, "--next"))
2747 flags |= KS_GET_FLAG_NEXT;
2748 if (has_option (line, "--rootdse"))
2749 flags |= KS_GET_FLAG_ROOTDSE;
2750 if (has_option (line, "--subst"))
2751 flags |= KS_GET_FLAG_SUBST;
2752 if (has_option (line, "--help"))
2754 if ((s = option_value (line, "--newer"))
2755 && !string2isotime (opt_newer, s))
2757 err = set_error (GPG_ERR_SYNTAX, "invalid time format");
2760 err = get_option_value (line, "--attr", &p);
2765 opt_attr = strtokenize (p, ",");
2768 err = gpg_error_from_syserror ();
2774 line = skip_options (line);
2779 ks_ldap_help_variables (ctrl);
2784 if ((flags & KS_GET_FLAG_NEXT))
2786 if (*filter || (flags & ~KS_GET_FLAG_NEXT))
2788 err = PARM_ERROR ("No filter or other options allowed with --next");
2793 /* Setup an output stream and perform the get. */
2794 outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
2797 err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2801 ctrl->server_local->inhibit_data_logging = 1;
2802 ctrl->server_local->inhibit_data_logging_now = 0;
2803 ctrl->server_local->inhibit_data_logging_count = 0;
2805 err = ks_action_query (ctrl,
2806 (flags & KS_GET_FLAG_ROOTDSE)? NULL : "ldap:///",
2807 flags, filter, opt_attr, opt_newer, outfp);
2812 ctrl->server_local->inhibit_data_logging = 0;
2813 return leave_cmd (ctx, err);
2818 static const char hlp_loadswdb[] =
2819 "LOADSWDB [--force]\n"
2821 "Load and verify the swdb.lst from the Net.";
2823 cmd_loadswdb (assuan_context_t ctx, char *line)
2825 ctrl_t ctrl = assuan_get_pointer (ctx);
2828 err = dirmngr_load_swdb (ctrl, has_option (line, "--force"));
2830 return leave_cmd (ctx, err);
2835 static const char hlp_getinfo[] =
2838 "Multi purpose command to return certain information. \n"
2839 "Supported values of WHAT are:\n"
2841 "version - Return the version of the program\n"
2842 "pid - Return the process id of the server\n"
2843 "tor - Return OK if running in Tor mode\n"
2844 "dnsinfo - Return info about the DNS resolver\n"
2845 "socket_name - Return the name of the socket\n"
2846 "session_id - Return the current session_id\n"
2847 "workqueue - Inspect the work queue\n"
2848 "stats - Print stats\n"
2849 "getenv NAME - Return value of envvar NAME\n";
2851 cmd_getinfo (assuan_context_t ctx, char *line)
2853 ctrl_t ctrl = assuan_get_pointer (ctx);
2857 if (!strcmp (line, "version"))
2859 const char *s = VERSION;
2860 err = assuan_send_data (ctx, s, strlen (s));
2862 else if (!strcmp (line, "pid"))
2864 snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
2865 err = assuan_send_data (ctx, numbuf, strlen (numbuf));
2867 else if (!strcmp (line, "socket_name"))
2869 const char *s = dirmngr_get_current_socket_name ();
2870 err = assuan_send_data (ctx, s, strlen (s));
2872 else if (!strcmp (line, "session_id"))
2874 snprintf (numbuf, sizeof numbuf, "%u", ctrl->server_local->session_id);
2875 err = assuan_send_data (ctx, numbuf, strlen (numbuf));
2877 else if (!strcmp (line, "tor"))
2881 use_tor = dirmngr_use_tor ();
2884 if (!is_tor_running (ctrl))
2885 err = assuan_write_status (ctx, "NO_TOR", "Tor not running");
2889 assuan_set_okay_line (ctx, use_tor == 1 ? "- Tor mode is enabled"
2890 /**/ : "- Tor mode is enforced");
2893 err = set_error (GPG_ERR_FALSE, "Tor mode is NOT enabled");
2895 else if (!strcmp (line, "dnsinfo"))
2897 if (standard_resolver_p ())
2898 assuan_set_okay_line
2899 (ctx, "- Forced use of System resolver (w/o Tor support)");
2903 assuan_set_okay_line (ctx, (recursive_resolver_p ()
2904 ? "- Libdns recursive resolver"
2905 : "- Libdns stub resolver"));
2907 assuan_set_okay_line (ctx, "- System resolver (w/o Tor support)");
2912 else if (!strcmp (line, "workqueue"))
2914 workqueue_dump_queue (ctrl);
2917 else if (!strcmp (line, "stats"))
2919 cert_cache_print_stats (ctrl);
2920 domaininfo_print_stats (ctrl);
2923 else if (!strncmp (line, "getenv", 6)
2924 && (line[6] == ' ' || line[6] == '\t' || !line[6]))
2927 while (*line == ' ' || *line == '\t')
2930 err = gpg_error (GPG_ERR_MISSING_VALUE);
2933 const char *s = getenv (line);
2936 err = set_error (GPG_ERR_NOT_FOUND, "No such envvar");
2939 err = assuan_send_data (ctx, s, strlen (s));
2942 #ifdef HAVE_W32_SYSTEM
2943 else if (!strcmp (line, "sid"))
2948 mysid = w32_get_user_sid ();
2951 err = set_error (GPG_ERR_NOT_FOUND, "Error getting my SID");
2955 if (!ConvertSidToStringSid (mysid, &sidstr))
2957 err = set_error (GPG_ERR_BUG, "Error converting SID to a string");
2960 err = assuan_send_data (ctx, sidstr, strlen (sidstr));
2963 #endif /*HAVE_W32_SYSTEM*/
2965 err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
2968 return leave_cmd (ctx, err);
2973 static const char hlp_killdirmngr[] =
2976 "This command allows a user - given sufficient permissions -\n"
2977 "to kill this dirmngr process.\n";
2979 cmd_killdirmngr (assuan_context_t ctx, char *line)
2981 ctrl_t ctrl = assuan_get_pointer (ctx);
2985 ctrl->server_local->stopme = 1;
2986 assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
2991 static const char hlp_reloaddirmngr[] =
2994 "This command is an alternative to SIGHUP\n"
2995 "to reload the configuration.";
2997 cmd_reloaddirmngr (assuan_context_t ctx, char *line)
3002 dirmngr_sighup_action ();
3007 static const char hlp_flushcrls[] =
3010 "Remove all cached CRLs from memory and\n"
3013 cmd_flushcrls (assuan_context_t ctx, char *line)
3017 return leave_cmd (ctx, crl_cache_flush () ? GPG_ERR_GENERAL : 0);
3022 /* Tell the assuan library about our commands. */
3024 register_commands (assuan_context_t ctx)
3028 assuan_handler_t handler;
3029 const char * const help;
3031 { "DNS_CERT", cmd_dns_cert, hlp_dns_cert },
3032 { "WKD_GET", cmd_wkd_get, hlp_wkd_get },
3033 { "LDAPSERVER", cmd_ldapserver, hlp_ldapserver },
3034 { "ISVALID", cmd_isvalid, hlp_isvalid },
3035 { "CHECKCRL", cmd_checkcrl, hlp_checkcrl },
3036 { "CHECKOCSP", cmd_checkocsp, hlp_checkocsp },
3037 { "LOOKUP", cmd_lookup, hlp_lookup },
3038 { "LOADCRL", cmd_loadcrl, hlp_loadcrl },
3039 { "LISTCRLS", cmd_listcrls, hlp_listcrls },
3040 { "CACHECERT", cmd_cachecert, hlp_cachecert },
3041 { "VALIDATE", cmd_validate, hlp_validate },
3042 { "KEYSERVER", cmd_keyserver, hlp_keyserver },
3043 { "KS_SEARCH", cmd_ks_search, hlp_ks_search },
3044 { "KS_GET", cmd_ks_get, hlp_ks_get },
3045 { "KS_FETCH", cmd_ks_fetch, hlp_ks_fetch },
3046 { "KS_PUT", cmd_ks_put, hlp_ks_put },
3047 { "AD_QUERY", cmd_ad_query, hlp_ad_query },
3048 { "GETINFO", cmd_getinfo, hlp_getinfo },
3049 { "LOADSWDB", cmd_loadswdb, hlp_loadswdb },
3050 { "KILLDIRMNGR",cmd_killdirmngr,hlp_killdirmngr },
3051 { "RELOADDIRMNGR",cmd_reloaddirmngr,hlp_reloaddirmngr },
3052 { "FLUSHCRLS", cmd_flushcrls, hlp_flushcrls },
3057 for (i=j=0; table[i].name; i++)
3059 rc = assuan_register_command (ctx, table[i].name, table[i].handler,
3068 /* Note that we do not reset the list of configured keyservers. */
3070 reset_notify (assuan_context_t ctx, char *line)
3072 ctrl_t ctrl = assuan_get_pointer (ctx);
3076 ldapserver_list_free (ctrl->server_local->ldapservers);
3078 ctrl->server_local->ldapservers = NULL;
3083 /* This function is called by our assuan log handler to test whether a
3084 * log message shall really be printed. The function must return
3085 * false to inhibit the logging of MSG. CAT gives the requested log
3086 * category. MSG might be NULL. */
3088 dirmngr_assuan_log_monitor (assuan_context_t ctx, unsigned int cat,
3091 ctrl_t ctrl = assuan_get_pointer (ctx);
3096 if (!ctrl || !ctrl->server_local)
3097 return 1; /* Can't decide - allow logging. */
3099 if (!ctrl->server_local->inhibit_data_logging)
3100 return 1; /* Not requested - allow logging. */
3102 /* Disallow logging if *_now is true. */
3103 return !ctrl->server_local->inhibit_data_logging_now;
3107 /* Startup the server and run the main command loop. With FD = -1,
3108 * use stdin/stdout. SESSION_ID is either 0 or a unique number
3109 * identifying a session. */
3111 start_command_handler (assuan_fd_t fd, unsigned int session_id)
3113 static const char hello[] = "Dirmngr " VERSION " at your service";
3114 static char *hello_line;
3116 assuan_context_t ctx;
3119 ctrl = xtrycalloc (1, sizeof *ctrl);
3121 ctrl->server_local = xtrycalloc (1, sizeof *ctrl->server_local);
3122 if (!ctrl || !ctrl->server_local)
3124 log_error (_("can't allocate control structure: %s\n"),
3130 dirmngr_init_default_ctrl (ctrl);
3132 rc = assuan_new (&ctx);
3135 log_error (_("failed to allocate assuan context: %s\n"),
3140 if (fd == ASSUAN_INVALID_FD)
3142 assuan_fd_t filedes[2];
3144 filedes[0] = assuan_fdopen (0);
3145 filedes[1] = assuan_fdopen (1);
3146 rc = assuan_init_pipe_server (ctx, filedes);
3150 rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED);
3155 assuan_release (ctx);
3156 log_error (_("failed to initialize the server: %s\n"),
3161 rc = register_commands (ctx);
3164 log_error (_("failed to the register commands with Assuan: %s\n"),
3172 hello_line = xtryasprintf
3177 opt.config_filename? opt.config_filename : "[none]",
3181 ctrl->server_local->assuan_ctx = ctx;
3182 assuan_set_pointer (ctx, ctrl);
3184 assuan_set_hello_line (ctx, hello_line);
3185 assuan_register_option_handler (ctx, option_handler);
3186 assuan_register_reset_notify (ctx, reset_notify);
3188 ctrl->server_local->session_id = session_id;
3192 rc = assuan_accept (ctx);
3197 log_info (_("Assuan accept problem: %s\n"), gpg_strerror (rc));
3201 #ifndef HAVE_W32_SYSTEM
3204 assuan_peercred_t peercred;
3206 if (!assuan_get_peercred (ctx, &peercred))
3207 log_info ("connection from process %ld (%ld:%ld)\n",
3208 (long)peercred->pid, (long)peercred->uid,
3209 (long)peercred->gid);
3213 rc = assuan_process (ctx);
3216 log_info (_("Assuan processing failed: %s\n"), gpg_strerror (rc));
3223 ldap_wrapper_connection_cleanup (ctrl);
3225 ldapserver_list_free (ctrl->server_local->ldapservers);
3227 ctrl->server_local->ldapservers = NULL;
3229 release_ctrl_keyservers (ctrl);
3231 ctrl->server_local->assuan_ctx = NULL;
3232 assuan_release (ctx);
3234 if (ctrl->server_local->stopme)
3238 log_error ("oops: connection control structure still referenced (%d)\n",
3243 ks_ldap_free_state (ctrl->ks_get_state);
3244 ctrl->ks_get_state = NULL;
3246 release_ctrl_ocsp_certs (ctrl);
3247 xfree (ctrl->server_local);
3248 dirmngr_deinit_default_ctrl (ctrl);
3254 /* Send a status line back to the client. KEYWORD is the status
3255 keyword, the optional string arguments are blank separated added to
3256 the line, the last argument must be a NULL. */
3258 dirmngr_status (ctrl_t ctrl, const char *keyword, ...)
3260 gpg_error_t err = 0;
3262 assuan_context_t ctx;
3264 va_start (arg_ptr, keyword);
3266 if (ctrl->server_local && (ctx = ctrl->server_local->assuan_ctx))
3268 err = vprint_assuan_status_strings (ctx, keyword, arg_ptr);
3276 /* Print a help status line. The function splits text at LFs. */
3278 dirmngr_status_help (ctrl_t ctrl, const char *text)
3280 gpg_error_t err = 0;
3281 assuan_context_t ctx;
3283 if (ctrl->server_local && (ctx = ctrl->server_local->assuan_ctx))
3292 for ( ; *text && *text != '\n' && n < DIM (buf)-2; n++)
3297 err = assuan_write_status (ctx, "#", buf);
3299 while (!err && *text);
3306 /* Print a help status line using a printf like format. The function
3307 * splits text at LFs. With CTRL beeing NULL, the function behaves
3310 dirmngr_status_helpf (ctrl_t ctrl, const char *format, ...)
3316 va_start (arg_ptr, format);
3319 buf = es_vbsprintf (format, arg_ptr);
3320 err = buf? 0 : gpg_error_from_syserror ();
3322 err = dirmngr_status_help (ctrl, buf);
3327 log_logv (GPGRT_LOGLVL_INFO, format, arg_ptr);
3335 /* This function is similar to print_assuan_status but takes a CTRL
3336 * arg instead of an assuan context as first argument. */
3338 dirmngr_status_printf (ctrl_t ctrl, const char *keyword,
3339 const char *format, ...)
3343 assuan_context_t ctx;
3345 if (!ctrl || !ctrl->server_local || !(ctx = ctrl->server_local->assuan_ctx))
3348 va_start (arg_ptr, format);
3349 err = vprint_assuan_status (ctx, keyword, format, arg_ptr);
3355 /* Send a tick progress indicator back. Fixme: This is only done for
3356 the currently active channel. */
3358 dirmngr_tick (ctrl_t ctrl)
3360 static time_t next_tick = 0;
3361 gpg_error_t err = 0;
3362 time_t now = time (NULL);
3366 next_tick = now + 1;
3368 else if ( now > next_tick )
3372 err = dirmngr_status (ctrl, "PROGRESS", "tick", "? 0 0", NULL);
3375 /* Take this as in indication for a cancel request. */
3376 err = gpg_error (GPG_ERR_CANCELED);
3381 next_tick = now + 1;