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 * This file is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as
11 * published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
14 * This file 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 Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, see <https://www.gnu.org/licenses/>.
22 * This file is part of GnuPG.
24 * GnuPG is free software; you can redistribute it and/or modify
25 * it under the terms of the GNU General Public License as published by
26 * the Free Software Foundation; either version 3 of the License, or
27 * (at your option) any later version.
29 * GnuPG is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
34 * You should have received a copy of the GNU General Public License
35 * along with this program; if not, see <https://www.gnu.org/licenses/>.
44 #include <sys/types.h>
55 # include "ldapserver.h"
58 #include "certcache.h"
62 # include "ldap-wrapper.h"
64 #include "ks-action.h"
65 #include "ks-engine.h" /* (ks_hkp_print_hosttable) */
67 # include "ldap-parse-uri.h"
69 #include "dns-stuff.h"
70 #include "../common/mbox-util.h"
71 #include "../common/zb32.h"
72 #include "../common/server-help.h"
74 /* To avoid DoS attacks we limit the size of a certificate to
75 something reasonable. The DoS was actually only an issue back when
76 Dirmngr was a system service and not a user service. */
77 #define MAX_CERT_LENGTH (16*1024)
79 /* The limit for the CERTLIST inquiry. We allow for up to 20
80 * certificates but also take PEM encoding into account. */
81 #define MAX_CERTLIST_LENGTH ((MAX_CERT_LENGTH * 20 * 4)/3)
83 /* The same goes for OpenPGP keyblocks, but here we need to allow for
84 much longer blocks; a 200k keyblock is not too unusual for keys
85 with a lot of signatures (e.g. 0x5b0358a2). 9C31503C6D866396 even
86 has 770 KiB as of 2015-08-23. To avoid adding a runtime option we
87 now use 20MiB which should really be enough. Well, a key with
88 several pictures could be larger (the parser as a 18MiB limit for
89 attribute packets) but it won't be nice to the keyservers to send
90 them such large blobs. */
91 #define MAX_KEYBLOCK_LENGTH (20*1024*1024)
94 #define PARM_ERROR(t) assuan_set_error (ctx, \
95 gpg_error (GPG_ERR_ASS_PARAMETER), (t))
96 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
100 /* Control structure per connection. */
101 struct server_local_s
103 /* Data used to associate an Assuan context with local server data */
104 assuan_context_t assuan_ctx;
106 /* Per-session LDAP servers. */
107 ldap_server_t ldapservers;
109 /* Per-session list of keyservers. */
110 uri_item_t keyservers;
112 /* If this flag is set to true this dirmngr process will be
113 terminated after the end of this session. */
116 /* State variable private to is_tor_running. */
119 /* If the first both flags are set the assuan logging of data lines
120 * is suppressed. The count variable is used to show the number of
121 * non-logged bytes. */
122 size_t inhibit_data_logging_count;
123 unsigned int inhibit_data_logging : 1;
124 unsigned int inhibit_data_logging_now : 1;
128 /* Cookie definition for assuan data line output. */
129 static gpgrt_ssize_t data_line_cookie_write (void *cookie,
130 const void *buffer, size_t size);
131 static int data_line_cookie_close (void *cookie);
132 static es_cookie_io_functions_t data_line_cookie_functions =
135 data_line_cookie_write,
137 data_line_cookie_close
144 /* Accessor for the local ldapservers variable. */
146 get_ldapservers_from_ctrl (ctrl_t ctrl)
148 if (ctrl && ctrl->server_local)
149 return ctrl->server_local->ldapservers;
154 /* Release an uri_item_t list. */
156 release_uri_item_list (uri_item_t list)
160 uri_item_t tmp = list->next;
161 http_release_parsed_uri (list->parsed_uri);
167 /* Release all configured keyserver info from CTRL. */
169 release_ctrl_keyservers (ctrl_t ctrl)
171 if (! ctrl->server_local)
174 release_uri_item_list (ctrl->server_local->keyservers);
175 ctrl->server_local->keyservers = NULL;
180 /* Helper to print a message while leaving a command. */
182 leave_cmd (assuan_context_t ctx, gpg_error_t err)
186 const char *name = assuan_get_command_name (ctx);
189 if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT)
190 log_error ("command '%s' failed: %s\n", name,
193 log_error ("command '%s' failed: %s <%s>\n", name,
194 gpg_strerror (err), gpg_strsource (err));
200 /* This is a wrapper around assuan_send_data which makes debugging the
201 output in verbose mode easier. */
203 data_line_write (assuan_context_t ctx, const void *buffer_arg, size_t size)
205 ctrl_t ctrl = assuan_get_pointer (ctx);
206 const char *buffer = buffer_arg;
209 /* If we do not want logging, enable it here. */
210 if (ctrl && ctrl->server_local && ctrl->server_local->inhibit_data_logging)
211 ctrl->server_local->inhibit_data_logging_now = 1;
213 if (opt.verbose && buffer && size)
215 /* Ease reading of output by sending a physical line at each LF. */
222 p = memchr (buffer, '\n', nbytes);
223 n = p ? (p - buffer) + 1 : nbytes;
224 err = assuan_send_data (ctx, buffer, n);
227 gpg_err_set_errno (EIO);
232 if (nbytes && (err=assuan_send_data (ctx, NULL, 0))) /* Flush line. */
234 gpg_err_set_errno (EIO);
242 err = assuan_send_data (ctx, buffer, size);
245 gpg_err_set_errno (EIO); /* For use by data_line_cookie_write. */
251 if (ctrl && ctrl->server_local && ctrl->server_local->inhibit_data_logging)
253 ctrl->server_local->inhibit_data_logging_now = 0;
254 ctrl->server_local->inhibit_data_logging_count += size;
261 /* A write handler used by es_fopencookie to write assuan data
264 data_line_cookie_write (void *cookie, const void *buffer, size_t size)
266 assuan_context_t ctx = cookie;
268 if (data_line_write (ctx, buffer, size))
270 return (gpgrt_ssize_t)size;
275 data_line_cookie_close (void *cookie)
277 assuan_context_t ctx = cookie;
281 ctrl_t ctrl = assuan_get_pointer (ctx);
283 if (ctrl && ctrl->server_local
284 && ctrl->server_local->inhibit_data_logging
285 && ctrl->server_local->inhibit_data_logging_count)
286 log_debug ("(%zu bytes sent via D lines not shown)\n",
287 ctrl->server_local->inhibit_data_logging_count);
289 if (assuan_send_data (ctx, NULL, 0))
291 gpg_err_set_errno (EIO);
299 /* Copy the % and + escaped string S into the buffer D and replace the
300 escape sequences. Note, that it is sufficient to allocate the
301 target string D as long as the source string S, i.e.: strlen(s)+1.
302 Note further that if S contains an escaped binary Nul the resulting
303 string D will contain the 0 as well as all other characters but it
304 will be impossible to know whether this is the original EOS or a
307 strcpy_escaped_plus (char *d, const unsigned char *s)
311 if (*s == '%' && s[1] && s[2])
326 /* This function returns true if a Tor server is running. The sattus
327 is cached for the current connection. */
329 is_tor_running (ctrl_t ctrl)
331 /* Check whether we can connect to the proxy. */
333 if (!ctrl || !ctrl->server_local)
334 return 0; /* Ooops. */
336 if (!ctrl->server_local->tor_state)
340 sock = assuan_sock_connect_byname (NULL, 0, 0, NULL, ASSUAN_SOCK_TOR);
341 if (sock == ASSUAN_INVALID_FD)
342 ctrl->server_local->tor_state = -1; /* Not running. */
345 assuan_sock_close (sock);
346 ctrl->server_local->tor_state = 1; /* Running. */
349 return (ctrl->server_local->tor_state > 0);
353 /* Return an error if the assuan context does not belong to the owner
354 of the process or to root. On error FAILTEXT is set as Assuan
357 check_owner_permission (assuan_context_t ctx, const char *failtext)
359 #ifdef HAVE_W32_SYSTEM
360 /* Under Windows the dirmngr is always run under the control of the
366 assuan_peercred_t cred;
368 ec = gpg_err_code (assuan_get_peercred (ctx, &cred));
369 if (!ec && cred->uid && cred->uid != getuid ())
372 return set_error (ec, failtext);
379 /* Common code for get_cert_local and get_issuer_cert_local. */
381 do_get_cert_local (ctrl_t ctrl, const char *name, const char *command)
383 unsigned char *value;
389 buf = name? strconcat (command, " ", name, NULL) : xtrystrdup (command);
391 rc = gpg_error_from_syserror ();
394 rc = assuan_inquire (ctrl->server_local->assuan_ctx, buf,
395 &value, &valuelen, MAX_CERT_LENGTH);
400 log_error (_("assuan_inquire(%s) failed: %s\n"),
401 command, gpg_strerror (rc));
411 rc = ksba_cert_new (&cert);
414 rc = ksba_cert_init_from_mem (cert, value, valuelen);
417 ksba_cert_release (cert);
427 /* Ask back to return a certificate for NAME, given as a regular gpgsm
428 * certificate identifier (e.g. fingerprint or one of the other
429 * methods). Alternatively, NULL may be used for NAME to return the
430 * current target certificate. Either return the certificate in a
431 * KSBA object or NULL if it is not available. */
433 get_cert_local (ctrl_t ctrl, const char *name)
435 if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
438 log_debug ("get_cert_local called w/o context\n");
441 return do_get_cert_local (ctrl, name, "SENDCERT");
446 /* Ask back to return the issuing certificate for NAME, given as a
447 * regular gpgsm certificate identifier (e.g. fingerprint or one
448 * of the other methods). Alternatively, NULL may be used for NAME to
449 * return the current target certificate. Either return the certificate
450 * in a KSBA object or NULL if it is not available. */
452 get_issuing_cert_local (ctrl_t ctrl, const char *name)
454 if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
457 log_debug ("get_issuing_cert_local called w/o context\n");
460 return do_get_cert_local (ctrl, name, "SENDISSUERCERT");
464 /* Ask back to return a certificate with subject NAME and a
465 * subjectKeyIdentifier of KEYID. */
467 get_cert_local_ski (ctrl_t ctrl, const char *name, ksba_sexp_t keyid)
469 unsigned char *value;
476 if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
479 log_debug ("get_cert_local_ski called w/o context\n");
484 log_debug ("get_cert_local_ski called with insufficient arguments\n");
488 hexkeyid = serial_hex (keyid);
491 log_debug ("serial_hex() failed\n");
495 buf = strconcat ("SENDCERT_SKI ", hexkeyid, " /", name, NULL);
498 log_error ("can't allocate enough memory: %s\n", strerror (errno));
504 rc = assuan_inquire (ctrl->server_local->assuan_ctx, buf,
505 &value, &valuelen, MAX_CERT_LENGTH);
509 log_error (_("assuan_inquire(%s) failed: %s\n"), "SENDCERT_SKI",
520 rc = ksba_cert_new (&cert);
523 rc = ksba_cert_init_from_mem (cert, value, valuelen);
526 ksba_cert_release (cert);
535 /* Ask the client via an inquiry to check the istrusted status of the
536 certificate specified by the hexified fingerprint HEXFPR. Returns
537 0 if the certificate is trusted by the client or an error code. */
539 get_istrusted_from_client (ctrl_t ctrl, const char *hexfpr)
541 unsigned char *value;
546 if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx
548 return gpg_error (GPG_ERR_INV_ARG);
550 snprintf (request, sizeof request, "ISTRUSTED %s", hexfpr);
551 rc = assuan_inquire (ctrl->server_local->assuan_ctx, request,
552 &value, &valuelen, 100);
555 log_error (_("assuan_inquire(%s) failed: %s\n"),
556 request, gpg_strerror (rc));
559 /* The expected data is: "1" or "1 cruft" (not a C-string). */
560 if (valuelen && *value == '1' && (valuelen == 1 || spacep (value+1)))
563 rc = gpg_error (GPG_ERR_NOT_TRUSTED);
571 /* Ask the client to return the certificate associated with the
572 current command. This is sometimes needed because the client usually
573 sends us just the cert ID, assuming that the request can be
574 satisfied from the cache, where the cert ID is used as key. */
576 inquire_cert_and_load_crl (assuan_context_t ctx)
578 ctrl_t ctrl = assuan_get_pointer (ctx);
580 unsigned char *value = NULL;
582 ksba_cert_t cert = NULL;
584 err = assuan_inquire( ctx, "SENDCERT", &value, &valuelen, 0);
589 /* FILE *fp = fopen ("foo.der", "r"); */
590 /* value = xmalloc (2000); */
591 /* valuelen = fread (value, 1, 2000, fp); */
595 if (!valuelen) /* No data returned; return a comprehensible error. */
596 return gpg_error (GPG_ERR_MISSING_CERT);
598 err = ksba_cert_new (&cert);
601 err = ksba_cert_init_from_mem (cert, value, valuelen);
604 xfree (value); value = NULL;
606 err = crl_cache_reload_crl (ctrl, cert);
609 ksba_cert_release (cert);
615 /* Handle OPTION commands. */
617 option_handler (assuan_context_t ctx, const char *key, const char *value)
619 ctrl_t ctrl = assuan_get_pointer (ctx);
622 if (!strcmp (key, "force-crl-refresh"))
624 int i = *value? atoi (value) : 0;
625 ctrl->force_crl_refresh = i;
627 else if (!strcmp (key, "audit-events"))
629 int i = *value? atoi (value) : 0;
630 ctrl->audit_events = i;
632 else if (!strcmp (key, "http-proxy"))
634 xfree (ctrl->http_proxy);
635 if (!*value || !strcmp (value, "none"))
636 ctrl->http_proxy = NULL;
637 else if (!(ctrl->http_proxy = xtrystrdup (value)))
638 err = gpg_error_from_syserror ();
640 else if (!strcmp (key, "honor-keyserver-url-used"))
642 /* Return an error if we are running in Tor mode. */
643 if (dirmngr_use_tor ())
644 err = gpg_error (GPG_ERR_FORBIDDEN);
646 else if (!strcmp (key, "http-crl"))
648 int i = *value? atoi (value) : 0;
649 ctrl->http_no_crl = !i;
652 err = gpg_error (GPG_ERR_UNKNOWN_OPTION);
659 static const char hlp_dns_cert[] =
660 "DNS_CERT <subtype> <name>\n"
661 "DNS_CERT --pka <user_id>\n"
662 "DNS_CERT --dane <user_id>\n"
664 "Return the CERT record for <name>. <subtype> is one of\n"
665 " * Return the first record of any supported subtype\n"
666 " PGP Return the first record of subtype PGP (3)\n"
667 " IPGP Return the first record of subtype IPGP (6)\n"
668 "If the content of a certificate is available (PGP) it is returned\n"
669 "by data lines. Fingerprints and URLs are returned via status lines.\n"
670 "In --pka mode the fingerprint and if available an URL is returned.\n"
671 "In --dane mode the key is returned from RR type 61";
673 cmd_dns_cert (assuan_context_t ctx, char *line)
675 /* ctrl_t ctrl = assuan_get_pointer (ctx); */
677 int pka_mode, dane_mode;
679 char *namebuf = NULL;
680 char *encodedhash = NULL;
686 unsigned char *fpr = NULL;
690 pka_mode = has_option (line, "--pka");
691 dane_mode = has_option (line, "--dane");
692 line = skip_options (line);
694 if (pka_mode && dane_mode)
696 err = PARM_ERROR ("either --pka or --dane may be given");
700 if (pka_mode || dane_mode)
701 ; /* No need to parse here - we do this later. */
704 p = strchr (line, ' ');
707 err = PARM_ERROR ("missing arguments");
711 if (!strcmp (line, "*"))
712 certtype = DNS_CERTTYPE_ANY;
713 else if (!strcmp (line, "IPGP"))
714 certtype = DNS_CERTTYPE_IPGP;
715 else if (!strcmp (line, "PGP"))
716 certtype = DNS_CERTTYPE_PGP;
719 err = PARM_ERROR ("unknown subtype");
727 err = PARM_ERROR ("name missing");
732 if (pka_mode || dane_mode)
734 char *domain; /* Points to mbox. */
735 char hashbuf[32]; /* For SHA-1 and SHA-256. */
737 /* We lowercase ascii characters but the DANE I-D does not allow
738 this. FIXME: Check after the release of the RFC whether to
740 mbox = mailbox_from_userid (line);
741 if (!mbox || !(domain = strchr (mbox, '@')))
743 err = set_error (GPG_ERR_INV_USER_ID, "no mailbox in user id");
750 gcry_md_hash_buffer (GCRY_MD_SHA1, hashbuf, mbox, strlen (mbox));
751 encodedhash = zb32_encode (hashbuf, 8*20);
754 err = gpg_error_from_syserror ();
757 namebuf = strconcat (encodedhash, "._pka.", domain, NULL);
760 err = gpg_error_from_syserror ();
764 certtype = DNS_CERTTYPE_IPGP;
768 /* Note: The hash is truncated to 28 bytes and we lowercase
769 the result only for aesthetic reasons. */
770 gcry_md_hash_buffer (GCRY_MD_SHA256, hashbuf, mbox, strlen (mbox));
771 encodedhash = bin2hex (hashbuf, 28, NULL);
774 err = gpg_error_from_syserror ();
777 ascii_strlwr (encodedhash);
778 namebuf = strconcat (encodedhash, "._openpgpkey.", domain, NULL);
781 err = gpg_error_from_syserror ();
785 certtype = DNS_CERTTYPE_RR61;
791 err = get_dns_cert (name, certtype, &key, &keylen, &fpr, &fprlen, &url);
797 err = data_line_write (ctx, key, keylen);
806 tmpstr = bin2hex (fpr, fprlen, NULL);
808 err = gpg_error_from_syserror ();
811 err = assuan_write_status (ctx, "FPR", tmpstr);
820 err = assuan_write_status (ctx, "URL", url);
833 return leave_cmd (ctx, err);
838 static const char hlp_wkd_get[] =
839 "WKD_GET [--submission-address|--policy-flags] <user_id>\n"
841 "Return the key or other info for <user_id>\n"
842 "from the Web Key Directory.";
844 cmd_wkd_get (assuan_context_t ctx, char *line)
846 ctrl_t ctrl = assuan_get_pointer (ctx);
849 char *domainbuf = NULL;
850 char *domain; /* Points to mbox or domainbuf. */
853 char *encodedhash = NULL;
854 int opt_submission_addr;
855 int opt_policy_flags;
857 char portstr[20] = { 0 };
859 opt_submission_addr = has_option (line, "--submission-address");
860 opt_policy_flags = has_option (line, "--policy-flags");
861 if (has_option (line, "--quick"))
862 ctrl->timeout = opt.connect_quick_timeout;
863 line = skip_options (line);
865 mbox = mailbox_from_userid (line);
866 if (!mbox || !(domain = strchr (mbox, '@')))
868 err = set_error (GPG_ERR_INV_USER_ID, "no mailbox in user id");
873 /* Check for SRV records. */
876 struct srventry *srvs;
877 unsigned int srvscount;
878 size_t domainlen, targetlen;
881 err = get_dns_srv (domain, "openpgpkey", NULL, &srvs, &srvscount);
885 /* Find the first target which also ends in DOMAIN or is equal
887 domainlen = strlen (domain);
888 for (i = 0; i < srvscount; i++)
890 log_debug ("srv: trying '%s:%hu'\n", srvs[i].target, srvs[i].port);
891 targetlen = strlen (srvs[i].target);
892 if ((targetlen > domainlen + 1
893 && srvs[i].target[targetlen - domainlen - 1] == '.'
894 && !ascii_strcasecmp (srvs[i].target + targetlen - domainlen,
896 || (targetlen == domainlen
897 && !ascii_strcasecmp (srvs[i].target, domain)))
900 domainbuf = xtrystrdup (srvs[i].target);
903 err = gpg_error_from_syserror ();
909 snprintf (portstr, sizeof portstr, ":%hu", srvs[i].port);
914 log_debug ("srv: got '%s%s'\n", domain, portstr);
917 gcry_md_hash_buffer (GCRY_MD_SHA1, sha1buf, mbox, strlen (mbox));
918 encodedhash = zb32_encode (sha1buf, 8*20);
921 err = gpg_error_from_syserror ();
925 if (opt_submission_addr)
927 uri = strconcat ("https://",
930 "/.well-known/openpgpkey/submission-address",
933 else if (opt_policy_flags)
935 uri = strconcat ("https://",
938 "/.well-known/openpgpkey/policy",
943 uri = strconcat ("https://",
946 "/.well-known/openpgpkey/hu/",
953 err = gpg_error_from_syserror ();
957 /* Setup an output stream and perform the get. */
961 outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
963 err = set_error (GPG_ERR_ASS_GENERAL,
964 "error setting up a data stream");
968 ctrl->server_local->inhibit_data_logging = 1;
969 ctrl->server_local->inhibit_data_logging_now = 0;
970 ctrl->server_local->inhibit_data_logging_count = 0;
971 err = ks_action_fetch (ctrl, uri, outfp);
973 ctrl->server_local->inhibit_data_logging = 0;
982 return leave_cmd (ctx, err);
987 static const char hlp_ldapserver[] =
988 "LDAPSERVER <data>\n"
990 "Add a new LDAP server to the list of configured LDAP servers.\n"
991 "DATA is in the same format as expected in the configure file.";
993 cmd_ldapserver (assuan_context_t ctx, char *line)
996 ctrl_t ctrl = assuan_get_pointer (ctx);
997 ldap_server_t server;
998 ldap_server_t *last_next_p;
1000 while (spacep (line))
1003 return leave_cmd (ctx, PARM_ERROR (_("ldapserver missing")));
1005 server = ldapserver_parse_one (line, "", 0);
1007 return leave_cmd (ctx, gpg_error (GPG_ERR_INV_ARG));
1009 last_next_p = &ctrl->server_local->ldapservers;
1010 while (*last_next_p)
1011 last_next_p = &(*last_next_p)->next;
1012 *last_next_p = server;
1013 return leave_cmd (ctx, 0);
1016 return leave_cmd (ctx, gpg_error (GPG_ERR_NOT_IMPLEMENTED));
1021 static const char hlp_isvalid[] =
1022 "ISVALID [--only-ocsp] [--force-default-responder]"
1023 " <certificate_id>|<certificate_fpr>\n"
1025 "This command checks whether the certificate identified by the\n"
1026 "certificate_id is valid. This is done by consulting CRLs or\n"
1027 "whatever has been configured. Note, that the returned error codes\n"
1028 "are from gpg-error.h. The command may callback using the inquire\n"
1029 "function. See the manual for details.\n"
1031 "The CERTIFICATE_ID is a hex encoded string consisting of two parts,\n"
1032 "delimited by a single dot. The first part is the SHA-1 hash of the\n"
1033 "issuer name and the second part the serial number.\n"
1035 "Alternatively the certificate's fingerprint may be given in which\n"
1036 "case an OCSP request is done before consulting the CRL.\n"
1038 "If the option --only-ocsp is given, no fallback to a CRL check will\n"
1041 "If the option --force-default-responder is given, only the default\n"
1042 "OCSP responder will be used and any other methods of obtaining an\n"
1043 "OCSP responder URL won't be used.";
1045 cmd_isvalid (assuan_context_t ctx, char *line)
1047 ctrl_t ctrl = assuan_get_pointer (ctx);
1048 char *issuerhash, *serialno;
1050 int did_inquire = 0;
1053 int force_default_responder;
1055 only_ocsp = has_option (line, "--only-ocsp");
1056 force_default_responder = has_option (line, "--force-default-responder");
1057 line = skip_options (line);
1059 issuerhash = xstrdup (line); /* We need to work on a copy of the
1060 line because that same Assuan
1061 context may be used for an inquiry.
1062 That is because Assuan reuses its
1066 serialno = strchr (issuerhash, '.');
1071 char *endp = strchr (issuerhash, ' ');
1074 if (strlen (issuerhash) != 40)
1077 return leave_cmd (ctx, PARM_ERROR (_("serialno missing in cert ID")));
1086 /* Note, that we ignore the given issuer hash and instead rely
1087 on the current certificate semantics used with this
1089 if (!opt.allow_ocsp)
1090 err = gpg_error (GPG_ERR_NOT_SUPPORTED);
1092 err = ocsp_isvalid (ctrl, NULL, NULL, force_default_responder);
1093 /* Fixme: If we got no ocsp response and --only-ocsp is not used
1094 we should fall back to CRL mode. Thus we need to clear
1095 OCSP_MODE, get the issuerhash and the serialno from the
1096 current certificate and jump to again. */
1099 err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
1102 switch (crl_cache_isvalid (ctrl,
1103 issuerhash, serialno,
1104 ctrl->force_crl_refresh))
1106 case CRL_CACHE_VALID:
1109 case CRL_CACHE_INVALID:
1110 err = gpg_error (GPG_ERR_CERT_REVOKED);
1112 case CRL_CACHE_DONTKNOW:
1114 err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
1115 else if (!(err = inquire_cert_and_load_crl (ctx)))
1121 case CRL_CACHE_CANTUSE:
1122 err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
1125 log_fatal ("crl_cache_isvalid returned invalid code\n");
1130 return leave_cmd (ctx, err);
1134 /* If the line contains a SHA-1 fingerprint as the first argument,
1135 return the FPR vuffer on success. The function checks that the
1136 fingerprint consists of valid characters and prints and error
1137 message if it does not and returns NULL. Fingerprints are
1138 considered optional and thus no explicit error is returned. NULL is
1139 also returned if there is no fingerprint at all available.
1140 FPR must be a caller provided buffer of at least 20 bytes.
1142 Note that colons within the fingerprint are allowed to separate 2
1143 hex digits; this allows for easier cutting and pasting using the
1144 usual fingerprint rendering.
1146 static unsigned char *
1147 get_fingerprint_from_line (const char *line, unsigned char *fpr)
1152 for (s=line, i=0; *s && *s != ' '; s++ )
1154 if ( hexdigitp (s) && hexdigitp (s+1) )
1157 return NULL; /* Fingerprint too long. */
1158 fpr[i++] = xtoi_2 (s);
1161 else if ( *s != ':' )
1162 return NULL; /* Invalid. */
1165 return NULL; /* Fingerprint to short. */
1171 static const char hlp_checkcrl[] =
1172 "CHECKCRL [<fingerprint>]\n"
1174 "Check whether the certificate with FINGERPRINT (SHA-1 hash of the\n"
1175 "entire X.509 certificate blob) is valid or not by consulting the\n"
1176 "CRL responsible for this certificate. If the fingerprint has not\n"
1177 "been given or the certificate is not known, the function \n"
1178 "inquires the certificate using an\n"
1180 " INQUIRE TARGETCERT\n"
1182 "and the caller is expected to return the certificate for the\n"
1183 "request (which should match FINGERPRINT) as a binary blob.\n"
1184 "Processing then takes place without further interaction; in\n"
1185 "particular dirmngr tries to locate other required certificate by\n"
1186 "its own mechanism which includes a local certificate store as well\n"
1187 "as a list of trusted root certificates.\n"
1189 "The return value is the usual gpg-error code or 0 for ducesss;\n"
1190 "i.e. the certificate validity has been confirmed by a valid CRL.";
1192 cmd_checkcrl (assuan_context_t ctx, char *line)
1194 ctrl_t ctrl = assuan_get_pointer (ctx);
1196 unsigned char fprbuffer[20], *fpr;
1199 fpr = get_fingerprint_from_line (line, fprbuffer);
1200 cert = fpr? get_cert_byfpr (fpr) : NULL;
1204 /* We do not have this certificate yet or the fingerprint has
1205 not been given. Inquire it from the client. */
1206 unsigned char *value = NULL;
1209 err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1210 &value, &valuelen, MAX_CERT_LENGTH);
1213 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1217 if (!valuelen) /* No data returned; return a comprehensible error. */
1218 err = gpg_error (GPG_ERR_MISSING_CERT);
1221 err = ksba_cert_new (&cert);
1223 err = ksba_cert_init_from_mem (cert, value, valuelen);
1232 err = crl_cache_cert_isvalid (ctrl, cert, ctrl->force_crl_refresh);
1233 if (gpg_err_code (err) == GPG_ERR_NO_CRL_KNOWN)
1235 err = crl_cache_reload_crl (ctrl, cert);
1237 err = crl_cache_cert_isvalid (ctrl, cert, 0);
1241 ksba_cert_release (cert);
1242 return leave_cmd (ctx, err);
1246 static const char hlp_checkocsp[] =
1247 "CHECKOCSP [--force-default-responder] [<fingerprint>]\n"
1249 "Check whether the certificate with FINGERPRINT (SHA-1 hash of the\n"
1250 "entire X.509 certificate blob) is valid or not by asking an OCSP\n"
1251 "responder responsible for this certificate. The optional\n"
1252 "fingerprint may be used for a quick check in case an OCSP check has\n"
1253 "been done for this certificate recently (we always cache OCSP\n"
1254 "responses for a couple of minutes). If the fingerprint has not been\n"
1255 "given or there is no cached result, the function inquires the\n"
1256 "certificate using an\n"
1258 " INQUIRE TARGETCERT\n"
1260 "and the caller is expected to return the certificate for the\n"
1261 "request (which should match FINGERPRINT) as a binary blob.\n"
1262 "Processing then takes place without further interaction; in\n"
1263 "particular dirmngr tries to locate other required certificates by\n"
1264 "its own mechanism which includes a local certificate store as well\n"
1265 "as a list of trusted root certificates.\n"
1267 "If the option --force-default-responder is given, only the default\n"
1268 "OCSP responder will be used and any other methods of obtaining an\n"
1269 "OCSP responder URL won't be used.\n"
1271 "The return value is the usual gpg-error code or 0 for ducesss;\n"
1272 "i.e. the certificate validity has been confirmed by a valid CRL.";
1274 cmd_checkocsp (assuan_context_t ctx, char *line)
1276 ctrl_t ctrl = assuan_get_pointer (ctx);
1278 unsigned char fprbuffer[20], *fpr;
1280 int force_default_responder;
1282 force_default_responder = has_option (line, "--force-default-responder");
1283 line = skip_options (line);
1285 fpr = get_fingerprint_from_line (line, fprbuffer);
1286 cert = fpr? get_cert_byfpr (fpr) : NULL;
1290 /* We do not have this certificate yet or the fingerprint has
1291 not been given. Inquire it from the client. */
1292 unsigned char *value = NULL;
1295 err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1296 &value, &valuelen, MAX_CERT_LENGTH);
1299 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1303 if (!valuelen) /* No data returned; return a comprehensible error. */
1304 err = gpg_error (GPG_ERR_MISSING_CERT);
1307 err = ksba_cert_new (&cert);
1309 err = ksba_cert_init_from_mem (cert, value, valuelen);
1318 if (!opt.allow_ocsp)
1319 err = gpg_error (GPG_ERR_NOT_SUPPORTED);
1321 err = ocsp_isvalid (ctrl, cert, NULL, force_default_responder);
1324 ksba_cert_release (cert);
1325 return leave_cmd (ctx, err);
1331 lookup_cert_by_url (assuan_context_t ctx, const char *url)
1333 ctrl_t ctrl = assuan_get_pointer (ctx);
1334 gpg_error_t err = 0;
1335 unsigned char *value = NULL;
1338 /* Fetch single certificate given it's URL. */
1339 err = fetch_cert_by_url (ctrl, url, &value, &valuelen);
1342 log_error (_("fetch_cert_by_url failed: %s\n"), gpg_strerror (err));
1346 /* Send the data, flush the buffer and then send an END. */
1347 err = assuan_send_data (ctx, value, valuelen);
1349 err = assuan_send_data (ctx, NULL, 0);
1351 err = assuan_write_line (ctx, "END");
1354 log_error (_("error sending data: %s\n"), gpg_strerror (err));
1364 /* Send the certificate, flush the buffer and then send an END. */
1366 return_one_cert (void *opaque, ksba_cert_t cert)
1368 assuan_context_t ctx = opaque;
1370 const unsigned char *der;
1373 der = ksba_cert_get_image (cert, &derlen);
1375 err = gpg_error (GPG_ERR_INV_CERT_OBJ);
1378 err = assuan_send_data (ctx, der, derlen);
1380 err = assuan_send_data (ctx, NULL, 0);
1382 err = assuan_write_line (ctx, "END");
1385 log_error (_("error sending data: %s\n"), gpg_strerror (err));
1390 /* Lookup certificates from the internal cache or using the ldap
1393 lookup_cert_by_pattern (assuan_context_t ctx, char *line,
1394 int single, int cache_only)
1396 gpg_error_t err = 0;
1398 strlist_t sl, list = NULL;
1399 int truncated = 0, truncation_forced = 0;
1401 int local_count = 0;
1403 ctrl_t ctrl = assuan_get_pointer (ctx);
1404 unsigned char *value = NULL;
1406 struct ldapserver_iter ldapserver_iter;
1407 cert_fetch_context_t fetch_context;
1409 int any_no_data = 0;
1411 /* Break the line down into an STRLIST */
1412 for (p=line; *p; line = p)
1414 while (*p && *p != ' ')
1421 sl = xtrymalloc (sizeof *sl + strlen (line));
1424 err = gpg_error_from_errno (errno);
1427 memset (sl, 0, sizeof *sl);
1428 strcpy_escaped_plus (sl->d, line);
1434 /* First look through the internal cache. The certificates returned
1435 here are not counted towards the truncation limit. */
1436 if (single && !cache_only)
1437 ; /* Do not read from the local cache in this case. */
1440 for (sl=list; sl; sl = sl->next)
1442 err = get_certs_bypattern (sl->d, return_one_cert, ctx);
1448 if (gpg_err_code (err) == GPG_ERR_NO_DATA)
1454 else if (gpg_err_code (err) == GPG_ERR_INV_NAME && !cache_only)
1456 /* No real fault because the internal pattern lookup
1457 can't yet cope with all types of pattern. */
1465 /* Loop over all configured servers unless we want only the
1466 certificates from the cache. */
1468 for (ldapserver_iter_begin (&ldapserver_iter, ctrl);
1469 !cache_only && !ldapserver_iter_end_p (&ldapserver_iter)
1470 && ldapserver_iter.server->host && !truncation_forced;
1471 ldapserver_iter_next (&ldapserver_iter))
1473 ldap_server_t ldapserver = ldapserver_iter.server;
1476 log_debug ("cmd_lookup: trying %s:%d base=%s\n",
1477 ldapserver->host, ldapserver->port,
1478 ldapserver->base?ldapserver->base : "[default]");
1480 /* Fetch certificates matching pattern */
1481 err = start_cert_fetch (ctrl, &fetch_context, list, ldapserver);
1482 if ( gpg_err_code (err) == GPG_ERR_NO_DATA )
1485 log_debug ("cmd_lookup: no data\n");
1492 log_error (_("start_cert_fetch failed: %s\n"), gpg_strerror (err));
1496 /* Fetch the certificates for this query. */
1497 while (!truncation_forced)
1499 xfree (value); value = NULL;
1500 err = fetch_next_cert (fetch_context, &value, &valuelen);
1501 if (gpg_err_code (err) == GPG_ERR_NO_DATA )
1507 if (gpg_err_code (err) == GPG_ERR_TRUNCATED)
1513 if (gpg_err_code (err) == GPG_ERR_EOF)
1520 err = gpg_error (GPG_ERR_BUG);
1525 log_error (_("fetch_next_cert failed: %s\n"),
1526 gpg_strerror (err));
1527 end_cert_fetch (fetch_context);
1532 log_debug ("cmd_lookup: returning one cert%s\n",
1533 truncated? " (truncated)":"");
1535 /* Send the data, flush the buffer and then send an END line
1536 as a certificate delimiter. */
1537 err = assuan_send_data (ctx, value, valuelen);
1539 err = assuan_send_data (ctx, NULL, 0);
1541 err = assuan_write_line (ctx, "END");
1544 log_error (_("error sending data: %s\n"), gpg_strerror (err));
1545 end_cert_fetch (fetch_context);
1549 if (++count >= opt.max_replies )
1551 truncation_forced = 1;
1552 log_info (_("max_replies %d exceeded\n"), opt.max_replies );
1558 end_cert_fetch (fetch_context);
1563 if (truncated || truncation_forced)
1567 sprintf (str, "%d", count);
1568 assuan_write_status (ctx, "TRUNCATED", str);
1571 if (!err && !count && !local_count && any_no_data)
1572 err = gpg_error (GPG_ERR_NO_DATA);
1575 free_strlist (list);
1580 static const char hlp_lookup[] =
1581 "LOOKUP [--url] [--single] [--cache-only] <pattern>\n"
1583 "Lookup certificates matching PATTERN. With --url the pattern is\n"
1584 "expected to be one URL.\n"
1586 "If --url is not given: To allow for multiple patterns (which are ORed)\n"
1587 "quoting is required: Spaces are translated to \"+\" or \"%20\";\n"
1588 "obviously this requires that the usual escape quoting rules are applied.\n"
1590 "If --url is given no special escaping is required because URLs are\n"
1591 "already escaped this way.\n"
1593 "If --single is given the first and only the first match will be\n"
1594 "returned. If --cache-only is _not_ given, no local query will be\n"
1597 "If --cache-only is given no external lookup is done so that only\n"
1598 "certificates from the cache may get returned.";
1600 cmd_lookup (assuan_context_t ctx, char *line)
1603 int lookup_url, single, cache_only;
1605 lookup_url = has_leading_option (line, "--url");
1606 single = has_leading_option (line, "--single");
1607 cache_only = has_leading_option (line, "--cache-only");
1608 line = skip_options (line);
1610 if (lookup_url && cache_only)
1611 err = gpg_error (GPG_ERR_NOT_FOUND);
1612 else if (lookup_url && single)
1613 err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1614 else if (lookup_url)
1615 err = lookup_cert_by_url (ctx, line);
1617 err = lookup_cert_by_pattern (ctx, line, single, cache_only);
1619 return leave_cmd (ctx, err);
1623 static const char hlp_loadcrl[] =
1624 "LOADCRL [--url] <filename|url>\n"
1626 "Load the CRL in the file with name FILENAME into our cache. Note\n"
1627 "that FILENAME should be given with an absolute path because\n"
1628 "Dirmngrs cwd is not known. With --url the CRL is directly loaded\n"
1629 "from the given URL.\n"
1631 "This command is usually used by gpgsm using the invocation \"gpgsm\n"
1632 "--call-dirmngr loadcrl <filename>\". A direct invocation of Dirmngr\n"
1633 "is not useful because gpgsm might need to callback gpgsm to ask for\n"
1634 "the CA's certificate.";
1636 cmd_loadcrl (assuan_context_t ctx, char *line)
1638 ctrl_t ctrl = assuan_get_pointer (ctx);
1639 gpg_error_t err = 0;
1640 int use_url = has_leading_option (line, "--url");
1642 line = skip_options (line);
1646 ksba_reader_t reader;
1648 err = crl_fetch (ctrl, line, &reader);
1650 log_error (_("fetching CRL from '%s' failed: %s\n"),
1651 line, gpg_strerror (err));
1654 err = crl_cache_insert (ctrl, line, reader);
1656 log_error (_("processing CRL from '%s' failed: %s\n"),
1657 line, gpg_strerror (err));
1658 crl_close_reader (reader);
1665 buf = xtrymalloc (strlen (line)+1);
1667 err = gpg_error_from_syserror ();
1670 strcpy_escaped_plus (buf, line);
1671 err = crl_cache_load (ctrl, buf);
1676 return leave_cmd (ctx, err);
1680 static const char hlp_listcrls[] =
1683 "List the content of all CRLs in a readable format. This command is\n"
1684 "usually used by gpgsm using the invocation \"gpgsm --call-dirmngr\n"
1685 "listcrls\". It may also be used directly using \"dirmngr\n"
1688 cmd_listcrls (assuan_context_t ctx, char *line)
1695 fp = es_fopencookie (ctx, "w", data_line_cookie_functions);
1697 err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
1700 err = crl_cache_list (fp);
1703 return leave_cmd (ctx, err);
1707 static const char hlp_cachecert[] =
1710 "Put a certificate into the internal cache. This command might be\n"
1711 "useful if a client knows in advance certificates required for a\n"
1712 "test and wants to make sure they get added to the internal cache.\n"
1713 "It is also helpful for debugging. To get the actual certificate,\n"
1714 "this command immediately inquires it using\n"
1716 " INQUIRE TARGETCERT\n"
1718 "and the caller is expected to return the certificate for the\n"
1719 "request as a binary blob.";
1721 cmd_cachecert (assuan_context_t ctx, char *line)
1723 ctrl_t ctrl = assuan_get_pointer (ctx);
1725 ksba_cert_t cert = NULL;
1726 unsigned char *value = NULL;
1731 err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1732 &value, &valuelen, MAX_CERT_LENGTH);
1735 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1739 if (!valuelen) /* No data returned; return a comprehensible error. */
1740 err = gpg_error (GPG_ERR_MISSING_CERT);
1743 err = ksba_cert_new (&cert);
1745 err = ksba_cert_init_from_mem (cert, value, valuelen);
1751 err = cache_cert (cert);
1754 ksba_cert_release (cert);
1755 return leave_cmd (ctx, err);
1759 static const char hlp_validate[] =
1760 "VALIDATE [--systrust] [--tls] [--no-crl]\n"
1762 "Validate a certificate using the certificate validation function\n"
1763 "used internally by dirmngr. This command is only useful for\n"
1764 "debugging. To get the actual certificate, this command immediately\n"
1765 "inquires it using\n"
1767 " INQUIRE TARGETCERT\n"
1769 "and the caller is expected to return the certificate for the\n"
1770 "request as a binary blob. The option --tls modifies this by asking\n"
1771 "for list of certificates with\n"
1773 " INQUIRE CERTLIST\n"
1775 "Here the first certificate is the target certificate, the remaining\n"
1776 "certificates are suggested intermediary certificates. All certifciates\n"
1777 "need to be PEM encoded.\n"
1779 "The option --systrust changes the behaviour to include the system\n"
1780 "provided root certificates as trust anchors. The option --no-crl\n"
1783 cmd_validate (assuan_context_t ctx, char *line)
1785 ctrl_t ctrl = assuan_get_pointer (ctx);
1787 ksba_cert_t cert = NULL;
1788 certlist_t certlist = NULL;
1789 unsigned char *value = NULL;
1791 int systrust_mode, tls_mode, no_crl;
1793 systrust_mode = has_option (line, "--systrust");
1794 tls_mode = has_option (line, "--tls");
1795 no_crl = has_option (line, "--no-crl");
1796 line = skip_options (line);
1799 err = assuan_inquire (ctrl->server_local->assuan_ctx, "CERTLIST",
1800 &value, &valuelen, MAX_CERTLIST_LENGTH);
1802 err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1803 &value, &valuelen, MAX_CERT_LENGTH);
1806 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1810 if (!valuelen) /* No data returned; return a comprehensible error. */
1811 err = gpg_error (GPG_ERR_MISSING_CERT);
1816 fp = es_fopenmem_init (0, "rb", value, valuelen);
1818 err = gpg_error_from_syserror ();
1821 err = read_certlist_from_stream (&certlist, fp);
1823 if (!err && !certlist)
1824 err = gpg_error (GPG_ERR_MISSING_CERT);
1827 /* Extraxt the first certificate from the list. */
1828 cert = certlist->cert;
1829 ksba_cert_ref (cert);
1835 err = ksba_cert_new (&cert);
1837 err = ksba_cert_init_from_mem (cert, value, valuelen);
1845 /* If we have this certificate already in our cache, use the
1846 * cached version for validation because this will take care of
1847 * any cached results. We don't need to do this in tls mode
1848 * because this has already been done for certificate in a
1850 unsigned char fpr[20];
1851 ksba_cert_t tmpcert;
1853 cert_compute_fpr (cert, fpr);
1854 tmpcert = get_cert_byfpr (fpr);
1857 ksba_cert_release (cert);
1862 /* Quick hack to make verification work by inserting the supplied
1863 * certs into the cache. */
1864 if (tls_mode && certlist)
1868 for (cl = certlist->next; cl; cl = cl->next)
1869 cache_cert (cl->cert);
1872 err = validate_cert_chain (ctrl, cert, NULL,
1873 (VALIDATE_FLAG_TRUST_CONFIG
1874 | (tls_mode ? VALIDATE_FLAG_TLS : 0)
1875 | (systrust_mode ? VALIDATE_FLAG_TRUST_SYSTEM : 0)
1876 | (no_crl ? VALIDATE_FLAG_NOCRLCHECK : 0)),
1880 ksba_cert_release (cert);
1881 release_certlist (certlist);
1882 return leave_cmd (ctx, err);
1887 /* Parse an keyserver URI and store it in a new uri item which is
1888 returned at R_ITEM. On error return an error code. */
1890 make_keyserver_item (const char *uri, uri_item_t *r_item)
1896 item = xtrymalloc (sizeof *item + strlen (uri));
1898 return gpg_error_from_syserror ();
1901 item->parsed_uri = NULL;
1902 strcpy (item->uri, uri);
1905 if (ldap_uri_p (item->uri))
1906 err = ldap_parse_uri (&item->parsed_uri, uri);
1910 err = http_parse_uri (&item->parsed_uri, uri, 1);
1921 /* If no keyserver is stored in CTRL but a global keyserver has been
1922 set, put that global keyserver into CTRL. We need use this
1923 function to help migrate from the old gpg based keyserver
1924 configuration to the new dirmngr based configuration. */
1926 ensure_keyserver (ctrl_t ctrl)
1930 uri_item_t onion_items = NULL;
1931 uri_item_t plain_items = NULL;
1935 if (ctrl->server_local->keyservers)
1936 return 0; /* Already set for this session. */
1939 /* No global option set. Fall back to default: */
1940 return make_keyserver_item (DIRMNGR_DEFAULT_KEYSERVER,
1941 &ctrl->server_local->keyservers);
1944 for (sl = opt.keyserver; sl; sl = sl->next)
1946 err = make_keyserver_item (sl->d, &item);
1949 if (item->parsed_uri->onion)
1951 item->next = onion_items;
1956 item->next = plain_items;
1961 /* Decide which to use. Note that the session has no keyservers
1963 if (onion_items && !onion_items->next && plain_items && !plain_items->next)
1965 /* If there is just one onion and one plain keyserver given, we take
1966 only one depending on whether Tor is running or not. */
1967 if (is_tor_running (ctrl))
1969 ctrl->server_local->keyservers = onion_items;
1974 ctrl->server_local->keyservers = plain_items;
1978 else if (!is_tor_running (ctrl))
1980 /* Tor is not running. It does not make sense to add Onion
1982 ctrl->server_local->keyservers = plain_items;
1987 /* In all other cases add all keyservers. */
1988 ctrl->server_local->keyservers = onion_items;
1990 for (ui = ctrl->server_local->keyservers; ui && ui->next; ui = ui->next)
1993 ui->next = plain_items;
1995 ctrl->server_local->keyservers = plain_items;
2000 release_uri_item_list (onion_items);
2001 release_uri_item_list (plain_items);
2007 static const char hlp_keyserver[] =
2008 "KEYSERVER [<options>] [<uri>|<host>]\n"
2011 " --clear Remove all configured keyservers\n"
2012 " --resolve Resolve HKP host names and rotate\n"
2013 " --hosttable Print table of known hosts and pools\n"
2014 " --dead Mark <host> as dead\n"
2015 " --alive Mark <host> as alive\n"
2017 "If called without arguments list all configured keyserver URLs.\n"
2018 "If called with an URI add this as keyserver. Note that keyservers\n"
2019 "are configured on a per-session base. A default keyserver may already be\n"
2020 "present, thus the \"--clear\" option must be used to get full control.\n"
2021 "If \"--clear\" and an URI are used together the clear command is\n"
2022 "obviously executed first. A RESET command does not change the list\n"
2023 "of configured keyservers.";
2025 cmd_keyserver (assuan_context_t ctx, char *line)
2027 ctrl_t ctrl = assuan_get_pointer (ctx);
2028 gpg_error_t err = 0;
2029 int clear_flag, add_flag, help_flag, host_flag, resolve_flag;
2030 int dead_flag, alive_flag;
2031 uri_item_t item = NULL; /* gcc 4.4.5 is not able to detect that it
2032 is always initialized. */
2034 clear_flag = has_option (line, "--clear");
2035 help_flag = has_option (line, "--help");
2036 resolve_flag = has_option (line, "--resolve");
2037 host_flag = has_option (line, "--hosttable");
2038 dead_flag = has_option (line, "--dead");
2039 alive_flag = has_option (line, "--alive");
2040 line = skip_options (line);
2045 err = ks_action_help (ctrl, line);
2051 err = ensure_keyserver (ctrl);
2053 err = ks_action_resolve (ctrl, ctrl->server_local->keyservers);
2058 if (alive_flag && dead_flag)
2060 err = set_error (GPG_ERR_ASS_PARAMETER, "no support for zombies");
2065 err = check_owner_permission (ctx, "no permission to use --dead");
2069 if (alive_flag || dead_flag)
2073 err = set_error (GPG_ERR_ASS_PARAMETER, "name of host missing");
2077 err = ks_hkp_mark_host (ctrl, line, alive_flag);
2084 err = ks_hkp_print_hosttable (ctrl);
2088 if (resolve_flag || host_flag || alive_flag || dead_flag)
2093 err = make_keyserver_item (line, &item);
2098 release_ctrl_keyservers (ctrl);
2101 item->next = ctrl->server_local->keyservers;
2102 ctrl->server_local->keyservers = item;
2105 if (!add_flag && !clear_flag && !help_flag)
2107 /* List configured keyservers. However, we first add a global
2111 err = ensure_keyserver (ctrl);
2114 assuan_set_error (ctx, err,
2115 "Bad keyserver configuration in dirmngr.conf");
2119 for (u=ctrl->server_local->keyservers; u; u = u->next)
2120 dirmngr_status (ctrl, "KEYSERVER", u->uri, NULL);
2125 return leave_cmd (ctx, err);
2130 static const char hlp_ks_search[] =
2131 "KS_SEARCH {<pattern>}\n"
2133 "Search the configured OpenPGP keyservers (see command KEYSERVER)\n"
2134 "for keys matching PATTERN";
2136 cmd_ks_search (assuan_context_t ctx, char *line)
2138 ctrl_t ctrl = assuan_get_pointer (ctx);
2144 if (has_option (line, "--quick"))
2145 ctrl->timeout = opt.connect_quick_timeout;
2146 line = skip_options (line);
2148 /* Break the line down into an strlist. Each pattern is
2149 percent-plus escaped. */
2151 for (p=line; *p; line = p)
2153 while (*p && *p != ' ')
2159 sl = xtrymalloc (sizeof *sl + strlen (line));
2162 err = gpg_error_from_syserror ();
2166 strcpy_escaped_plus (sl->d, line);
2172 err = ensure_keyserver (ctrl);
2176 /* Setup an output stream and perform the search. */
2177 outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
2179 err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2182 err = ks_action_search (ctrl, ctrl->server_local->keyservers,
2188 free_strlist (list);
2189 return leave_cmd (ctx, err);
2194 static const char hlp_ks_get[] =
2195 "KS_GET {<pattern>}\n"
2197 "Get the keys matching PATTERN from the configured OpenPGP keyservers\n"
2198 "(see command KEYSERVER). Each pattern should be a keyid, a fingerprint,\n"
2199 "or an exact name indicated by the '=' prefix.";
2201 cmd_ks_get (assuan_context_t ctx, char *line)
2203 ctrl_t ctrl = assuan_get_pointer (ctx);
2209 if (has_option (line, "--quick"))
2210 ctrl->timeout = opt.connect_quick_timeout;
2211 line = skip_options (line);
2213 /* Break the line into a strlist. Each pattern is by
2214 definition percent-plus escaped. However we only support keyids
2215 and fingerprints and thus the client has no need to apply the
2218 for (p=line; *p; line = p)
2220 while (*p && *p != ' ')
2226 sl = xtrymalloc (sizeof *sl + strlen (line));
2229 err = gpg_error_from_syserror ();
2233 strcpy_escaped_plus (sl->d, line);
2239 err = ensure_keyserver (ctrl);
2243 /* Setup an output stream and perform the get. */
2244 outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
2246 err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2249 ctrl->server_local->inhibit_data_logging = 1;
2250 ctrl->server_local->inhibit_data_logging_now = 0;
2251 ctrl->server_local->inhibit_data_logging_count = 0;
2252 err = ks_action_get (ctrl, ctrl->server_local->keyservers, list, outfp);
2254 ctrl->server_local->inhibit_data_logging = 0;
2258 free_strlist (list);
2259 return leave_cmd (ctx, err);
2263 static const char hlp_ks_fetch[] =
2266 "Get the key(s) from URL.";
2268 cmd_ks_fetch (assuan_context_t ctx, char *line)
2270 ctrl_t ctrl = assuan_get_pointer (ctx);
2274 if (has_option (line, "--quick"))
2275 ctrl->timeout = opt.connect_quick_timeout;
2276 line = skip_options (line);
2278 err = ensure_keyserver (ctrl); /* FIXME: Why do we needs this here? */
2282 /* Setup an output stream and perform the get. */
2283 outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
2285 err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2288 ctrl->server_local->inhibit_data_logging = 1;
2289 ctrl->server_local->inhibit_data_logging_now = 0;
2290 ctrl->server_local->inhibit_data_logging_count = 0;
2291 err = ks_action_fetch (ctrl, line, outfp);
2293 ctrl->server_local->inhibit_data_logging = 0;
2297 return leave_cmd (ctx, err);
2302 static const char hlp_ks_put[] =
2305 "Send a key to the configured OpenPGP keyservers. The actual key material\n"
2306 "is then requested by Dirmngr using\n"
2308 " INQUIRE KEYBLOCK\n"
2310 "The client shall respond with a binary version of the keyblock (e.g.,\n"
2311 "the output of `gpg --export KEYID'). For LDAP\n"
2312 "keyservers Dirmngr may ask for meta information of the provided keyblock\n"
2315 " INQUIRE KEYBLOCK_INFO\n"
2317 "The client shall respond with a colon delimited info lines (the output\n"
2318 "of 'for x in keys sigs; do gpg --list-$x --with-colons KEYID; done').\n";
2320 cmd_ks_put (assuan_context_t ctx, char *line)
2322 ctrl_t ctrl = assuan_get_pointer (ctx);
2324 unsigned char *value = NULL;
2326 unsigned char *info = NULL;
2329 /* No options for now. */
2330 line = skip_options (line);
2332 err = ensure_keyserver (ctrl);
2336 /* Ask for the key material. */
2337 err = assuan_inquire (ctx, "KEYBLOCK",
2338 &value, &valuelen, MAX_KEYBLOCK_LENGTH);
2341 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
2345 if (!valuelen) /* No data returned; return a comprehensible error. */
2347 err = gpg_error (GPG_ERR_MISSING_CERT);
2351 /* Ask for the key meta data. Not actually needed for HKP servers
2352 but we do it anyway to test the client implementation. */
2353 err = assuan_inquire (ctx, "KEYBLOCK_INFO",
2354 &info, &infolen, MAX_KEYBLOCK_LENGTH);
2357 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
2362 err = ks_action_put (ctrl, ctrl->server_local->keyservers,
2363 value, valuelen, info, infolen);
2368 return leave_cmd (ctx, err);
2373 static const char hlp_loadswdb[] =
2374 "LOADSWDB [--force]\n"
2376 "Load and verify the swdb.lst from the Net.";
2378 cmd_loadswdb (assuan_context_t ctx, char *line)
2380 ctrl_t ctrl = assuan_get_pointer (ctx);
2383 err = dirmngr_load_swdb (ctrl, has_option (line, "--force"));
2385 return leave_cmd (ctx, err);
2390 static const char hlp_getinfo[] =
2393 "Multi purpose command to return certain information. \n"
2394 "Supported values of WHAT are:\n"
2396 "version - Return the version of the program.\n"
2397 "pid - Return the process id of the server.\n"
2398 "tor - Return OK if running in Tor mode\n"
2399 "dnsinfo - Return info about the DNS resolver\n"
2400 "socket_name - Return the name of the socket.\n";
2402 cmd_getinfo (assuan_context_t ctx, char *line)
2404 ctrl_t ctrl = assuan_get_pointer (ctx);
2407 if (!strcmp (line, "version"))
2409 const char *s = VERSION;
2410 err = assuan_send_data (ctx, s, strlen (s));
2412 else if (!strcmp (line, "pid"))
2416 snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
2417 err = assuan_send_data (ctx, numbuf, strlen (numbuf));
2419 else if (!strcmp (line, "socket_name"))
2421 const char *s = dirmngr_get_current_socket_name ();
2422 err = assuan_send_data (ctx, s, strlen (s));
2424 else if (!strcmp (line, "tor"))
2428 use_tor = dirmngr_use_tor ();
2431 if (!is_tor_running (ctrl))
2432 err = assuan_write_status (ctx, "NO_TOR", "Tor not running");
2436 assuan_set_okay_line (ctx, use_tor == 1 ? "- Tor mode is enabled"
2437 /**/ : "- Tor mode is enforced");
2440 err = set_error (GPG_ERR_FALSE, "Tor mode is NOT enabled");
2442 else if (!strcmp (line, "dnsinfo"))
2444 if (standard_resolver_p ())
2445 assuan_set_okay_line
2446 (ctx, "- Forced use of System resolver (w/o Tor support)");
2450 assuan_set_okay_line (ctx, (recursive_resolver_p ()
2451 ? "- Libdns recursive resolver"
2452 : "- Libdns stub resolver"));
2454 assuan_set_okay_line (ctx, "- System resolver (w/o Tor support)");
2460 err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
2462 return leave_cmd (ctx, err);
2467 static const char hlp_killdirmngr[] =
2470 "This command allows a user - given sufficient permissions -\n"
2471 "to kill this dirmngr process.\n";
2473 cmd_killdirmngr (assuan_context_t ctx, char *line)
2475 ctrl_t ctrl = assuan_get_pointer (ctx);
2479 ctrl->server_local->stopme = 1;
2480 assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
2481 return gpg_error (GPG_ERR_EOF);
2485 static const char hlp_reloaddirmngr[] =
2488 "This command is an alternative to SIGHUP\n"
2489 "to reload the configuration.";
2491 cmd_reloaddirmngr (assuan_context_t ctx, char *line)
2496 dirmngr_sighup_action ();
2502 /* Tell the assuan library about our commands. */
2504 register_commands (assuan_context_t ctx)
2508 assuan_handler_t handler;
2509 const char * const help;
2511 { "DNS_CERT", cmd_dns_cert, hlp_dns_cert },
2512 { "WKD_GET", cmd_wkd_get, hlp_wkd_get },
2513 { "LDAPSERVER", cmd_ldapserver, hlp_ldapserver },
2514 { "ISVALID", cmd_isvalid, hlp_isvalid },
2515 { "CHECKCRL", cmd_checkcrl, hlp_checkcrl },
2516 { "CHECKOCSP", cmd_checkocsp, hlp_checkocsp },
2517 { "LOOKUP", cmd_lookup, hlp_lookup },
2518 { "LOADCRL", cmd_loadcrl, hlp_loadcrl },
2519 { "LISTCRLS", cmd_listcrls, hlp_listcrls },
2520 { "CACHECERT", cmd_cachecert, hlp_cachecert },
2521 { "VALIDATE", cmd_validate, hlp_validate },
2522 { "KEYSERVER", cmd_keyserver, hlp_keyserver },
2523 { "KS_SEARCH", cmd_ks_search, hlp_ks_search },
2524 { "KS_GET", cmd_ks_get, hlp_ks_get },
2525 { "KS_FETCH", cmd_ks_fetch, hlp_ks_fetch },
2526 { "KS_PUT", cmd_ks_put, hlp_ks_put },
2527 { "GETINFO", cmd_getinfo, hlp_getinfo },
2528 { "LOADSWDB", cmd_loadswdb, hlp_loadswdb },
2529 { "KILLDIRMNGR",cmd_killdirmngr,hlp_killdirmngr },
2530 { "RELOADDIRMNGR",cmd_reloaddirmngr,hlp_reloaddirmngr },
2535 for (i=j=0; table[i].name; i++)
2537 rc = assuan_register_command (ctx, table[i].name, table[i].handler,
2546 /* Note that we do not reset the list of configured keyservers. */
2548 reset_notify (assuan_context_t ctx, char *line)
2550 ctrl_t ctrl = assuan_get_pointer (ctx);
2554 ldapserver_list_free (ctrl->server_local->ldapservers);
2556 ctrl->server_local->ldapservers = NULL;
2561 /* This function is called by our assuan log handler to test whether a
2562 * log message shall really be printed. The function must return
2563 * false to inhibit the logging of MSG. CAT gives the requested log
2564 * category. MSG might be NULL. */
2566 dirmngr_assuan_log_monitor (assuan_context_t ctx, unsigned int cat,
2569 ctrl_t ctrl = assuan_get_pointer (ctx);
2574 if (!ctrl || !ctrl->server_local)
2575 return 1; /* Can't decide - allow logging. */
2577 if (!ctrl->server_local->inhibit_data_logging)
2578 return 1; /* Not requested - allow logging. */
2580 /* Disallow logging if *_now is true. */
2581 return !ctrl->server_local->inhibit_data_logging_now;
2585 /* Startup the server and run the main command loop. With FD = -1,
2586 use stdin/stdout. */
2588 start_command_handler (assuan_fd_t fd)
2590 static const char hello[] = "Dirmngr " VERSION " at your service";
2591 static char *hello_line;
2593 assuan_context_t ctx;
2596 ctrl = xtrycalloc (1, sizeof *ctrl);
2598 ctrl->server_local = xtrycalloc (1, sizeof *ctrl->server_local);
2599 if (!ctrl || !ctrl->server_local)
2601 log_error (_("can't allocate control structure: %s\n"),
2607 dirmngr_init_default_ctrl (ctrl);
2609 rc = assuan_new (&ctx);
2612 log_error (_("failed to allocate assuan context: %s\n"),
2617 if (fd == ASSUAN_INVALID_FD)
2619 assuan_fd_t filedes[2];
2621 filedes[0] = assuan_fdopen (0);
2622 filedes[1] = assuan_fdopen (1);
2623 rc = assuan_init_pipe_server (ctx, filedes);
2627 rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED);
2632 assuan_release (ctx);
2633 log_error (_("failed to initialize the server: %s\n"),
2638 rc = register_commands (ctx);
2641 log_error (_("failed to the register commands with Assuan: %s\n"),
2649 hello_line = xtryasprintf
2654 opt.config_filename? opt.config_filename : "[none]",
2658 ctrl->server_local->assuan_ctx = ctx;
2659 assuan_set_pointer (ctx, ctrl);
2661 assuan_set_hello_line (ctx, hello_line);
2662 assuan_register_option_handler (ctx, option_handler);
2663 assuan_register_reset_notify (ctx, reset_notify);
2667 rc = assuan_accept (ctx);
2672 log_info (_("Assuan accept problem: %s\n"), gpg_strerror (rc));
2676 #ifndef HAVE_W32_SYSTEM
2679 assuan_peercred_t peercred;
2681 if (!assuan_get_peercred (ctx, &peercred))
2682 log_info ("connection from process %ld (%ld:%ld)\n",
2683 (long)peercred->pid, (long)peercred->uid,
2684 (long)peercred->gid);
2688 rc = assuan_process (ctx);
2691 log_info (_("Assuan processing failed: %s\n"), gpg_strerror (rc));
2698 ldap_wrapper_connection_cleanup (ctrl);
2700 ldapserver_list_free (ctrl->server_local->ldapservers);
2702 ctrl->server_local->ldapservers = NULL;
2704 release_ctrl_keyservers (ctrl);
2706 ctrl->server_local->assuan_ctx = NULL;
2707 assuan_release (ctx);
2709 if (ctrl->server_local->stopme)
2713 log_error ("oops: connection control structure still referenced (%d)\n",
2717 release_ctrl_ocsp_certs (ctrl);
2718 xfree (ctrl->server_local);
2719 dirmngr_deinit_default_ctrl (ctrl);
2725 /* Send a status line back to the client. KEYWORD is the status
2726 keyword, the optional string arguments are blank separated added to
2727 the line, the last argument must be a NULL. */
2729 dirmngr_status (ctrl_t ctrl, const char *keyword, ...)
2731 gpg_error_t err = 0;
2735 va_start (arg_ptr, keyword);
2737 if (ctrl->server_local)
2739 assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2745 while ( (text = va_arg (arg_ptr, const char *)) )
2752 for ( ; *text && n < DIM (buf)-2; n++)
2756 err = assuan_write_status (ctx, keyword, buf);
2764 /* Print a help status line. TEXTLEN gives the length of the text
2765 from TEXT to be printed. The function splits text at LFs. */
2767 dirmngr_status_help (ctrl_t ctrl, const char *text)
2769 gpg_error_t err = 0;
2771 if (ctrl->server_local)
2773 assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2781 for ( ; *text && *text != '\n' && n < DIM (buf)-2; n++)
2786 err = assuan_write_status (ctx, "#", buf);
2788 while (!err && *text);
2794 /* Send a tick progress indicator back. Fixme: This is only done for
2795 the currently active channel. */
2797 dirmngr_tick (ctrl_t ctrl)
2799 static time_t next_tick = 0;
2800 gpg_error_t err = 0;
2801 time_t now = time (NULL);
2805 next_tick = now + 1;
2807 else if ( now > next_tick )
2811 err = dirmngr_status (ctrl, "PROGRESS", "tick", "? 0 0", NULL);
2814 /* Take this as in indication for a cancel request. */
2815 err = gpg_error (GPG_ERR_CANCELED);
2820 next_tick = now + 1;