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
6 * This file is part of GnuPG.
8 * GnuPG is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * GnuPG is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see <http://www.gnu.org/licenses/>.
28 #include <sys/types.h>
39 # include "ldapserver.h"
42 #include "certcache.h"
46 # include "ldap-wrapper.h"
48 #include "ks-action.h"
49 #include "ks-engine.h" /* (ks_hkp_print_hosttable) */
51 # include "ldap-parse-uri.h"
53 #include "dns-stuff.h"
54 #include "mbox-util.h"
56 #include "server-help.h"
58 /* To avoid DoS attacks we limit the size of a certificate to
59 something reasonable. The DoS was actually only an issue back when
60 Dirmngr was a system service and not a user service. */
61 #define MAX_CERT_LENGTH (16*1024)
63 /* The same goes for OpenPGP keyblocks, but here we need to allow for
64 much longer blocks; a 200k keyblock is not too unusual for keys
65 with a lot of signatures (e.g. 0x5b0358a2). 9C31503C6D866396 even
66 has 770 KiB as of 2015-08-23. To avoid adding a runtime option we
67 now use 20MiB which should really be enough. Well, a key with
68 several pictures could be larger (the parser as a 18MiB limit for
69 attribute packets) but it won't be nice to the keyservers to send
70 them such large blobs. */
71 #define MAX_KEYBLOCK_LENGTH (20*1024*1024)
74 #define PARM_ERROR(t) assuan_set_error (ctx, \
75 gpg_error (GPG_ERR_ASS_PARAMETER), (t))
76 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
80 /* Control structure per connection. */
83 /* Data used to associate an Assuan context with local server data */
84 assuan_context_t assuan_ctx;
86 /* Per-session LDAP servers. */
87 ldap_server_t ldapservers;
89 /* Per-session list of keyservers. */
90 uri_item_t keyservers;
92 /* If this flag is set to true this dirmngr process will be
93 terminated after the end of this session. */
96 /* State variable private to is_tor_running. */
101 /* Cookie definition for assuan data line output. */
102 static gpgrt_ssize_t data_line_cookie_write (void *cookie,
103 const void *buffer, size_t size);
104 static int data_line_cookie_close (void *cookie);
105 static es_cookie_io_functions_t data_line_cookie_functions =
108 data_line_cookie_write,
110 data_line_cookie_close
117 /* Accessor for the local ldapservers variable. */
119 get_ldapservers_from_ctrl (ctrl_t ctrl)
121 if (ctrl && ctrl->server_local)
122 return ctrl->server_local->ldapservers;
127 /* Release an uri_item_t list. */
129 release_uri_item_list (uri_item_t list)
133 uri_item_t tmp = list->next;
134 http_release_parsed_uri (list->parsed_uri);
140 /* Release all configured keyserver info from CTRL. */
142 release_ctrl_keyservers (ctrl_t ctrl)
144 if (! ctrl->server_local)
147 release_uri_item_list (ctrl->server_local->keyservers);
148 ctrl->server_local->keyservers = NULL;
153 /* Helper to print a message while leaving a command. */
155 leave_cmd (assuan_context_t ctx, gpg_error_t err)
159 const char *name = assuan_get_command_name (ctx);
162 if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT)
163 log_error ("command '%s' failed: %s\n", name,
166 log_error ("command '%s' failed: %s <%s>\n", name,
167 gpg_strerror (err), gpg_strsource (err));
173 /* This is a wrapper around assuan_send_data which makes debugging the
174 output in verbose mode easier. */
176 data_line_write (assuan_context_t ctx, const void *buffer_arg, size_t size)
178 const char *buffer = buffer_arg;
181 if (opt.verbose && buffer && size)
183 /* Ease reading of output by sending a physical line at each LF. */
190 p = memchr (buffer, '\n', nbytes);
191 n = p ? (p - buffer) + 1 : nbytes;
192 err = assuan_send_data (ctx, buffer, n);
195 gpg_err_set_errno (EIO);
200 if (nbytes && (err=assuan_send_data (ctx, NULL, 0))) /* Flush line. */
202 gpg_err_set_errno (EIO);
210 err = assuan_send_data (ctx, buffer, size);
213 gpg_err_set_errno (EIO); /* For use by data_line_cookie_write. */
222 /* A write handler used by es_fopencookie to write assuan data
225 data_line_cookie_write (void *cookie, const void *buffer, size_t size)
227 assuan_context_t ctx = cookie;
229 if (data_line_write (ctx, buffer, size))
231 return (gpgrt_ssize_t)size;
236 data_line_cookie_close (void *cookie)
238 assuan_context_t ctx = cookie;
240 if (assuan_send_data (ctx, NULL, 0))
242 gpg_err_set_errno (EIO);
250 /* Copy the % and + escaped string S into the buffer D and replace the
251 escape sequences. Note, that it is sufficient to allocate the
252 target string D as long as the source string S, i.e.: strlen(s)+1.
253 Note further that if S contains an escaped binary Nul the resulting
254 string D will contain the 0 as well as all other characters but it
255 will be impossible to know whether this is the original EOS or a
258 strcpy_escaped_plus (char *d, const unsigned char *s)
262 if (*s == '%' && s[1] && s[2])
277 /* This fucntion returns true if a Tor server is running. The sattus
278 is cached for the current conenction. */
280 is_tor_running (ctrl_t ctrl)
282 #if ASSUAN_VERSION_NUMBER >= 0x020402
283 /* Check whether we can connect to the proxy. We use a
284 special feature introduced with libassuan 2.4.2. */
286 if (!ctrl || !ctrl->server_local)
287 return 0; /* Ooops. */
289 if (!ctrl->server_local->tor_state)
293 sock = assuan_sock_connect_byname (NULL, 0, 0, NULL, ASSUAN_SOCK_TOR);
294 if (sock == ASSUAN_INVALID_FD)
295 ctrl->server_local->tor_state = -1; /* Not running. */
298 assuan_sock_close (sock);
299 ctrl->server_local->tor_state = 1; /* Running. */
302 return (ctrl->server_local->tor_state > 0);
303 #else /* Libassuan < 2.4.2 */
304 return 0; /* We don't know. */
309 /* Return an error if the assuan context does not belong to the owner
310 of the process or to root. On error FAILTEXT is set as Assuan
313 check_owner_permission (assuan_context_t ctx, const char *failtext)
315 #ifdef HAVE_W32_SYSTEM
316 /* Under Windows the dirmngr is always run under the control of the
322 assuan_peercred_t cred;
324 ec = gpg_err_code (assuan_get_peercred (ctx, &cred));
325 if (!ec && cred->uid && cred->uid != getuid ())
328 return set_error (ec, failtext);
335 /* Common code for get_cert_local and get_issuer_cert_local. */
337 do_get_cert_local (ctrl_t ctrl, const char *name, const char *command)
339 unsigned char *value;
347 buf = xmalloc ( strlen (command) + 1 + strlen(name) + 1);
348 strcpy (stpcpy (stpcpy (buf, command), " "), name);
351 buf = xstrdup (command);
353 rc = assuan_inquire (ctrl->server_local->assuan_ctx, buf,
354 &value, &valuelen, MAX_CERT_LENGTH);
358 log_error (_("assuan_inquire(%s) failed: %s\n"),
359 command, gpg_strerror (rc));
369 rc = ksba_cert_new (&cert);
372 rc = ksba_cert_init_from_mem (cert, value, valuelen);
375 ksba_cert_release (cert);
385 /* Ask back to return a certificate for name, given as a regular
386 gpgsm certificate indentificates (e.g. fingerprint or one of the
387 other methods). Alternatively, NULL may be used for NAME to
388 return the current target certificate. Either return the certificate
389 in a KSBA object or NULL if it is not available.
392 get_cert_local (ctrl_t ctrl, const char *name)
394 if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
397 log_debug ("get_cert_local called w/o context\n");
400 return do_get_cert_local (ctrl, name, "SENDCERT");
404 /* Ask back to return the issuing certificate for name, given as a
405 regular gpgsm certificate indentificates (e.g. fingerprint or one
406 of the other methods). Alternatively, NULL may be used for NAME to
407 return thecurrent target certificate. Either return the certificate
408 in a KSBA object or NULL if it is not available.
412 get_issuing_cert_local (ctrl_t ctrl, const char *name)
414 if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
417 log_debug ("get_issuing_cert_local called w/o context\n");
420 return do_get_cert_local (ctrl, name, "SENDISSUERCERT");
423 /* Ask back to return a certificate with subject NAME and a
424 subjectKeyIdentifier of KEYID. */
426 get_cert_local_ski (ctrl_t ctrl, const char *name, ksba_sexp_t keyid)
428 unsigned char *value;
435 if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
438 log_debug ("get_cert_local_ski called w/o context\n");
443 log_debug ("get_cert_local_ski called with insufficient arguments\n");
447 hexkeyid = serial_hex (keyid);
450 log_debug ("serial_hex() failed\n");
454 buf = xtrymalloc (15 + strlen (hexkeyid) + 2 + strlen(name) + 1);
458 log_error ("can't allocate enough memory: %s\n", strerror (errno));
462 strcpy (stpcpy (stpcpy (stpcpy (buf, "SENDCERT_SKI "), hexkeyid)," /"),name);
465 rc = assuan_inquire (ctrl->server_local->assuan_ctx, buf,
466 &value, &valuelen, MAX_CERT_LENGTH);
470 log_error (_("assuan_inquire(%s) failed: %s\n"), "SENDCERT_SKI",
481 rc = ksba_cert_new (&cert);
484 rc = ksba_cert_init_from_mem (cert, value, valuelen);
487 ksba_cert_release (cert);
496 /* Ask the client via an inquiry to check the istrusted status of the
497 certificate specified by the hexified fingerprint HEXFPR. Returns
498 0 if the certificate is trusted by the client or an error code. */
500 get_istrusted_from_client (ctrl_t ctrl, const char *hexfpr)
502 unsigned char *value;
507 if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx
509 return gpg_error (GPG_ERR_INV_ARG);
511 snprintf (request, sizeof request, "ISTRUSTED %s", hexfpr);
512 rc = assuan_inquire (ctrl->server_local->assuan_ctx, request,
513 &value, &valuelen, 100);
516 log_error (_("assuan_inquire(%s) failed: %s\n"),
517 request, gpg_strerror (rc));
520 /* The expected data is: "1" or "1 cruft" (not a C-string). */
521 if (valuelen && *value == '1' && (valuelen == 1 || spacep (value+1)))
524 rc = gpg_error (GPG_ERR_NOT_TRUSTED);
532 /* Ask the client to return the certificate associated with the
533 current command. This is sometimes needed because the client usually
534 sends us just the cert ID, assuming that the request can be
535 satisfied from the cache, where the cert ID is used as key. */
537 inquire_cert_and_load_crl (assuan_context_t ctx)
539 ctrl_t ctrl = assuan_get_pointer (ctx);
541 unsigned char *value = NULL;
543 ksba_cert_t cert = NULL;
545 err = assuan_inquire( ctx, "SENDCERT", &value, &valuelen, 0);
550 /* FILE *fp = fopen ("foo.der", "r"); */
551 /* value = xmalloc (2000); */
552 /* valuelen = fread (value, 1, 2000, fp); */
556 if (!valuelen) /* No data returned; return a comprehensible error. */
557 return gpg_error (GPG_ERR_MISSING_CERT);
559 err = ksba_cert_new (&cert);
562 err = ksba_cert_init_from_mem (cert, value, valuelen);
565 xfree (value); value = NULL;
567 err = crl_cache_reload_crl (ctrl, cert);
570 ksba_cert_release (cert);
576 /* Handle OPTION commands. */
578 option_handler (assuan_context_t ctx, const char *key, const char *value)
580 ctrl_t ctrl = assuan_get_pointer (ctx);
583 if (!strcmp (key, "force-crl-refresh"))
585 int i = *value? atoi (value) : 0;
586 ctrl->force_crl_refresh = i;
588 else if (!strcmp (key, "audit-events"))
590 int i = *value? atoi (value) : 0;
591 ctrl->audit_events = i;
593 else if (!strcmp (key, "http-proxy"))
595 xfree (ctrl->http_proxy);
596 if (!*value || !strcmp (value, "none"))
597 ctrl->http_proxy = NULL;
598 else if (!(ctrl->http_proxy = xtrystrdup (value)))
599 err = gpg_error_from_syserror ();
601 else if (!strcmp (key, "honor-keyserver-url-used"))
603 /* Return an error if we are running in Tor mode. */
605 err = gpg_error (GPG_ERR_FORBIDDEN);
608 err = gpg_error (GPG_ERR_UNKNOWN_OPTION);
615 static const char hlp_dns_cert[] =
616 "DNS_CERT <subtype> <name>\n"
617 "DNS_CERT --pka <user_id>\n"
618 "DNS_CERT --dane <user_id>\n"
620 "Return the CERT record for <name>. <subtype> is one of\n"
621 " * Return the first record of any supported subtype\n"
622 " PGP Return the first record of subtype PGP (3)\n"
623 " IPGP Return the first record of subtype IPGP (6)\n"
624 "If the content of a certificate is available (PGP) it is returned\n"
625 "by data lines. Fingerprints and URLs are returned via status lines.\n"
626 "In --pka mode the fingerprint and if available an URL is returned.\n"
627 "In --dane mode the key is returned from RR type 61";
629 cmd_dns_cert (assuan_context_t ctx, char *line)
631 /* ctrl_t ctrl = assuan_get_pointer (ctx); */
633 int pka_mode, dane_mode;
635 char *namebuf = NULL;
636 char *encodedhash = NULL;
642 unsigned char *fpr = NULL;
646 pka_mode = has_option (line, "--pka");
647 dane_mode = has_option (line, "--dane");
648 line = skip_options (line);
650 if (pka_mode && dane_mode)
652 err = PARM_ERROR ("either --pka or --dane may be given");
656 if (pka_mode || dane_mode)
657 ; /* No need to parse here - we do this later. */
660 p = strchr (line, ' ');
663 err = PARM_ERROR ("missing arguments");
667 if (!strcmp (line, "*"))
668 certtype = DNS_CERTTYPE_ANY;
669 else if (!strcmp (line, "IPGP"))
670 certtype = DNS_CERTTYPE_IPGP;
671 else if (!strcmp (line, "PGP"))
672 certtype = DNS_CERTTYPE_PGP;
675 err = PARM_ERROR ("unknown subtype");
683 err = PARM_ERROR ("name missing");
688 if (opt.use_tor && (err = enable_dns_tormode (0)))
690 /* Tor mode is requested but the DNS code can't enable it. */
691 assuan_set_error (ctx, err, "error enabling Tor mode");
695 if (pka_mode || dane_mode)
697 char *domain; /* Points to mbox. */
698 char hashbuf[32]; /* For SHA-1 and SHA-256. */
700 /* We lowercase ascii characters but the DANE I-D does not allow
701 this. FIXME: Check after the release of the RFC whether to
703 mbox = mailbox_from_userid (line);
704 if (!mbox || !(domain = strchr (mbox, '@')))
706 err = set_error (GPG_ERR_INV_USER_ID, "no mailbox in user id");
713 gcry_md_hash_buffer (GCRY_MD_SHA1, hashbuf, mbox, strlen (mbox));
714 encodedhash = zb32_encode (hashbuf, 8*20);
717 err = gpg_error_from_syserror ();
720 namebuf = strconcat (encodedhash, "._pka.", domain, NULL);
723 err = gpg_error_from_syserror ();
727 certtype = DNS_CERTTYPE_IPGP;
731 /* Note: The hash is truncated to 28 bytes and we lowercase
732 the result only for aesthetic reasons. */
733 gcry_md_hash_buffer (GCRY_MD_SHA256, hashbuf, mbox, strlen (mbox));
734 encodedhash = bin2hex (hashbuf, 28, NULL);
737 err = gpg_error_from_syserror ();
740 ascii_strlwr (encodedhash);
741 namebuf = strconcat (encodedhash, "._openpgpkey.", domain, NULL);
744 err = gpg_error_from_syserror ();
748 certtype = DNS_CERTTYPE_RR61;
754 err = get_dns_cert (name, certtype, &key, &keylen, &fpr, &fprlen, &url);
760 err = data_line_write (ctx, key, keylen);
769 tmpstr = bin2hex (fpr, fprlen, NULL);
771 err = gpg_error_from_syserror ();
774 err = assuan_write_status (ctx, "FPR", tmpstr);
783 err = assuan_write_status (ctx, "URL", url);
796 return leave_cmd (ctx, err);
801 static const char hlp_wkd_get[] =
802 "WKD_GET <user_id>\n"
804 "Return the key for <user_id> from a Web Key Directory.\n";
806 cmd_wkd_get (assuan_context_t ctx, char *line)
808 ctrl_t ctrl = assuan_get_pointer (ctx);
811 char *domain; /* Points to mbox. */
814 char *encodedhash = NULL;
816 line = skip_options (line);
818 mbox = mailbox_from_userid (line);
819 if (!mbox || !(domain = strchr (mbox, '@')))
821 err = set_error (GPG_ERR_INV_USER_ID, "no mailbox in user id");
826 gcry_md_hash_buffer (GCRY_MD_SHA1, sha1buf, mbox, strlen (mbox));
827 encodedhash = zb32_encode (sha1buf, 8*20);
830 err = gpg_error_from_syserror ();
834 uri = strconcat ("https://",
836 "/.well-known/openpgpkey/hu/",
843 err = gpg_error_from_syserror ();
847 /* Setup an output stream and perform the get. */
851 outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
853 err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
856 err = ks_action_fetch (ctrl, uri, outfp);
865 return leave_cmd (ctx, err);
870 static const char hlp_ldapserver[] =
871 "LDAPSERVER <data>\n"
873 "Add a new LDAP server to the list of configured LDAP servers.\n"
874 "DATA is in the same format as expected in the configure file.";
876 cmd_ldapserver (assuan_context_t ctx, char *line)
879 ctrl_t ctrl = assuan_get_pointer (ctx);
880 ldap_server_t server;
881 ldap_server_t *last_next_p;
883 while (spacep (line))
886 return leave_cmd (ctx, PARM_ERROR (_("ldapserver missing")));
888 server = ldapserver_parse_one (line, "", 0);
890 return leave_cmd (ctx, gpg_error (GPG_ERR_INV_ARG));
892 last_next_p = &ctrl->server_local->ldapservers;
894 last_next_p = &(*last_next_p)->next;
895 *last_next_p = server;
896 return leave_cmd (ctx, 0);
899 return leave_cmd (ctx, gpg_error (GPG_ERR_NOT_IMPLEMENTED));
904 static const char hlp_isvalid[] =
905 "ISVALID [--only-ocsp] [--force-default-responder]"
906 " <certificate_id>|<certificate_fpr>\n"
908 "This command checks whether the certificate identified by the\n"
909 "certificate_id is valid. This is done by consulting CRLs or\n"
910 "whatever has been configured. Note, that the returned error codes\n"
911 "are from gpg-error.h. The command may callback using the inquire\n"
912 "function. See the manual for details.\n"
914 "The CERTIFICATE_ID is a hex encoded string consisting of two parts,\n"
915 "delimited by a single dot. The first part is the SHA-1 hash of the\n"
916 "issuer name and the second part the serial number.\n"
918 "Alternatively the certificate's fingerprint may be given in which\n"
919 "case an OCSP request is done before consulting the CRL.\n"
921 "If the option --only-ocsp is given, no fallback to a CRL check will\n"
924 "If the option --force-default-responder is given, only the default\n"
925 "OCSP responder will be used and any other methods of obtaining an\n"
926 "OCSP responder URL won't be used.";
928 cmd_isvalid (assuan_context_t ctx, char *line)
930 ctrl_t ctrl = assuan_get_pointer (ctx);
931 char *issuerhash, *serialno;
936 int force_default_responder;
938 only_ocsp = has_option (line, "--only-ocsp");
939 force_default_responder = has_option (line, "--force-default-responder");
940 line = skip_options (line);
942 issuerhash = xstrdup (line); /* We need to work on a copy of the
943 line because that same Assuan
944 context may be used for an inquiry.
945 That is because Assuan reuses its
949 serialno = strchr (issuerhash, '.');
954 char *endp = strchr (issuerhash, ' ');
957 if (strlen (issuerhash) != 40)
960 return leave_cmd (ctx, PARM_ERROR (_("serialno missing in cert ID")));
969 /* Note, that we ignore the given issuer hash and instead rely
970 on the current certificate semantics used with this
973 err = gpg_error (GPG_ERR_NOT_SUPPORTED);
975 err = ocsp_isvalid (ctrl, NULL, NULL, force_default_responder);
976 /* Fixme: If we got no ocsp response and --only-ocsp is not used
977 we should fall back to CRL mode. Thus we need to clear
978 OCSP_MODE, get the issuerhash and the serialno from the
979 current certificate and jump to again. */
982 err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
985 switch (crl_cache_isvalid (ctrl,
986 issuerhash, serialno,
987 ctrl->force_crl_refresh))
989 case CRL_CACHE_VALID:
992 case CRL_CACHE_INVALID:
993 err = gpg_error (GPG_ERR_CERT_REVOKED);
995 case CRL_CACHE_DONTKNOW:
997 err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
998 else if (!(err = inquire_cert_and_load_crl (ctx)))
1004 case CRL_CACHE_CANTUSE:
1005 err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
1008 log_fatal ("crl_cache_isvalid returned invalid code\n");
1013 return leave_cmd (ctx, err);
1017 /* If the line contains a SHA-1 fingerprint as the first argument,
1018 return the FPR vuffer on success. The function checks that the
1019 fingerprint consists of valid characters and prints and error
1020 message if it does not and returns NULL. Fingerprints are
1021 considered optional and thus no explicit error is returned. NULL is
1022 also returned if there is no fingerprint at all available.
1023 FPR must be a caller provided buffer of at least 20 bytes.
1025 Note that colons within the fingerprint are allowed to separate 2
1026 hex digits; this allows for easier cutting and pasting using the
1027 usual fingerprint rendering.
1029 static unsigned char *
1030 get_fingerprint_from_line (const char *line, unsigned char *fpr)
1035 for (s=line, i=0; *s && *s != ' '; s++ )
1037 if ( hexdigitp (s) && hexdigitp (s+1) )
1040 return NULL; /* Fingerprint too long. */
1041 fpr[i++] = xtoi_2 (s);
1044 else if ( *s != ':' )
1045 return NULL; /* Invalid. */
1048 return NULL; /* Fingerprint to short. */
1054 static const char hlp_checkcrl[] =
1055 "CHECKCRL [<fingerprint>]\n"
1057 "Check whether the certificate with FINGERPRINT (SHA-1 hash of the\n"
1058 "entire X.509 certificate blob) is valid or not by consulting the\n"
1059 "CRL responsible for this certificate. If the fingerprint has not\n"
1060 "been given or the certificate is not known, the function \n"
1061 "inquires the certificate using an\n"
1063 " INQUIRE TARGETCERT\n"
1065 "and the caller is expected to return the certificate for the\n"
1066 "request (which should match FINGERPRINT) as a binary blob.\n"
1067 "Processing then takes place without further interaction; in\n"
1068 "particular dirmngr tries to locate other required certificate by\n"
1069 "its own mechanism which includes a local certificate store as well\n"
1070 "as a list of trusted root certificates.\n"
1072 "The return value is the usual gpg-error code or 0 for ducesss;\n"
1073 "i.e. the certificate validity has been confirmed by a valid CRL.";
1075 cmd_checkcrl (assuan_context_t ctx, char *line)
1077 ctrl_t ctrl = assuan_get_pointer (ctx);
1079 unsigned char fprbuffer[20], *fpr;
1082 fpr = get_fingerprint_from_line (line, fprbuffer);
1083 cert = fpr? get_cert_byfpr (fpr) : NULL;
1087 /* We do not have this certificate yet or the fingerprint has
1088 not been given. Inquire it from the client. */
1089 unsigned char *value = NULL;
1092 err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1093 &value, &valuelen, MAX_CERT_LENGTH);
1096 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1100 if (!valuelen) /* No data returned; return a comprehensible error. */
1101 err = gpg_error (GPG_ERR_MISSING_CERT);
1104 err = ksba_cert_new (&cert);
1106 err = ksba_cert_init_from_mem (cert, value, valuelen);
1115 err = crl_cache_cert_isvalid (ctrl, cert, ctrl->force_crl_refresh);
1116 if (gpg_err_code (err) == GPG_ERR_NO_CRL_KNOWN)
1118 err = crl_cache_reload_crl (ctrl, cert);
1120 err = crl_cache_cert_isvalid (ctrl, cert, 0);
1124 ksba_cert_release (cert);
1125 return leave_cmd (ctx, err);
1129 static const char hlp_checkocsp[] =
1130 "CHECKOCSP [--force-default-responder] [<fingerprint>]\n"
1132 "Check whether the certificate with FINGERPRINT (SHA-1 hash of the\n"
1133 "entire X.509 certificate blob) is valid or not by asking an OCSP\n"
1134 "responder responsible for this certificate. The optional\n"
1135 "fingerprint may be used for a quick check in case an OCSP check has\n"
1136 "been done for this certificate recently (we always cache OCSP\n"
1137 "responses for a couple of minutes). If the fingerprint has not been\n"
1138 "given or there is no cached result, the function inquires the\n"
1139 "certificate using an\n"
1141 " INQUIRE TARGETCERT\n"
1143 "and the caller is expected to return the certificate for the\n"
1144 "request (which should match FINGERPRINT) as a binary blob.\n"
1145 "Processing then takes place without further interaction; in\n"
1146 "particular dirmngr tries to locate other required certificates by\n"
1147 "its own mechanism which includes a local certificate store as well\n"
1148 "as a list of trusted root certificates.\n"
1150 "If the option --force-default-responder is given, only the default\n"
1151 "OCSP responder will be used and any other methods of obtaining an\n"
1152 "OCSP responder URL won't be used.\n"
1154 "The return value is the usual gpg-error code or 0 for ducesss;\n"
1155 "i.e. the certificate validity has been confirmed by a valid CRL.";
1157 cmd_checkocsp (assuan_context_t ctx, char *line)
1159 ctrl_t ctrl = assuan_get_pointer (ctx);
1161 unsigned char fprbuffer[20], *fpr;
1163 int force_default_responder;
1165 force_default_responder = has_option (line, "--force-default-responder");
1166 line = skip_options (line);
1168 fpr = get_fingerprint_from_line (line, fprbuffer);
1169 cert = fpr? get_cert_byfpr (fpr) : NULL;
1173 /* We do not have this certificate yet or the fingerprint has
1174 not been given. Inquire it from the client. */
1175 unsigned char *value = NULL;
1178 err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1179 &value, &valuelen, MAX_CERT_LENGTH);
1182 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1186 if (!valuelen) /* No data returned; return a comprehensible error. */
1187 err = gpg_error (GPG_ERR_MISSING_CERT);
1190 err = ksba_cert_new (&cert);
1192 err = ksba_cert_init_from_mem (cert, value, valuelen);
1201 if (!opt.allow_ocsp)
1202 err = gpg_error (GPG_ERR_NOT_SUPPORTED);
1204 err = ocsp_isvalid (ctrl, cert, NULL, force_default_responder);
1207 ksba_cert_release (cert);
1208 return leave_cmd (ctx, err);
1214 lookup_cert_by_url (assuan_context_t ctx, const char *url)
1216 ctrl_t ctrl = assuan_get_pointer (ctx);
1217 gpg_error_t err = 0;
1218 unsigned char *value = NULL;
1221 /* Fetch single certificate given it's URL. */
1222 err = fetch_cert_by_url (ctrl, url, &value, &valuelen);
1225 log_error (_("fetch_cert_by_url failed: %s\n"), gpg_strerror (err));
1229 /* Send the data, flush the buffer and then send an END. */
1230 err = assuan_send_data (ctx, value, valuelen);
1232 err = assuan_send_data (ctx, NULL, 0);
1234 err = assuan_write_line (ctx, "END");
1237 log_error (_("error sending data: %s\n"), gpg_strerror (err));
1247 /* Send the certificate, flush the buffer and then send an END. */
1249 return_one_cert (void *opaque, ksba_cert_t cert)
1251 assuan_context_t ctx = opaque;
1253 const unsigned char *der;
1256 der = ksba_cert_get_image (cert, &derlen);
1258 err = gpg_error (GPG_ERR_INV_CERT_OBJ);
1261 err = assuan_send_data (ctx, der, derlen);
1263 err = assuan_send_data (ctx, NULL, 0);
1265 err = assuan_write_line (ctx, "END");
1268 log_error (_("error sending data: %s\n"), gpg_strerror (err));
1273 /* Lookup certificates from the internal cache or using the ldap
1276 lookup_cert_by_pattern (assuan_context_t ctx, char *line,
1277 int single, int cache_only)
1279 gpg_error_t err = 0;
1281 strlist_t sl, list = NULL;
1282 int truncated = 0, truncation_forced = 0;
1284 int local_count = 0;
1286 ctrl_t ctrl = assuan_get_pointer (ctx);
1287 unsigned char *value = NULL;
1289 struct ldapserver_iter ldapserver_iter;
1290 cert_fetch_context_t fetch_context;
1292 int any_no_data = 0;
1294 /* Break the line down into an STRLIST */
1295 for (p=line; *p; line = p)
1297 while (*p && *p != ' ')
1304 sl = xtrymalloc (sizeof *sl + strlen (line));
1307 err = gpg_error_from_errno (errno);
1310 memset (sl, 0, sizeof *sl);
1311 strcpy_escaped_plus (sl->d, line);
1317 /* First look through the internal cache. The certifcates retruned
1318 here are not counted towards the truncation limit. */
1319 if (single && !cache_only)
1320 ; /* Do not read from the local cache in this case. */
1323 for (sl=list; sl; sl = sl->next)
1325 err = get_certs_bypattern (sl->d, return_one_cert, ctx);
1331 if (gpg_err_code (err) == GPG_ERR_NO_DATA)
1337 else if (gpg_err_code (err) == GPG_ERR_INV_NAME && !cache_only)
1339 /* No real fault because the internal pattern lookup
1340 can't yet cope with all types of pattern. */
1348 /* Loop over all configured servers unless we want only the
1349 certificates from the cache. */
1351 for (ldapserver_iter_begin (&ldapserver_iter, ctrl);
1352 !cache_only && !ldapserver_iter_end_p (&ldapserver_iter)
1353 && ldapserver_iter.server->host && !truncation_forced;
1354 ldapserver_iter_next (&ldapserver_iter))
1356 ldap_server_t ldapserver = ldapserver_iter.server;
1359 log_debug ("cmd_lookup: trying %s:%d base=%s\n",
1360 ldapserver->host, ldapserver->port,
1361 ldapserver->base?ldapserver->base : "[default]");
1363 /* Fetch certificates matching pattern */
1364 err = start_cert_fetch (ctrl, &fetch_context, list, ldapserver);
1365 if ( gpg_err_code (err) == GPG_ERR_NO_DATA )
1368 log_debug ("cmd_lookup: no data\n");
1375 log_error (_("start_cert_fetch failed: %s\n"), gpg_strerror (err));
1379 /* Fetch the certificates for this query. */
1380 while (!truncation_forced)
1382 xfree (value); value = NULL;
1383 err = fetch_next_cert (fetch_context, &value, &valuelen);
1384 if (gpg_err_code (err) == GPG_ERR_NO_DATA )
1390 if (gpg_err_code (err) == GPG_ERR_TRUNCATED)
1396 if (gpg_err_code (err) == GPG_ERR_EOF)
1403 err = gpg_error (GPG_ERR_BUG);
1408 log_error (_("fetch_next_cert failed: %s\n"),
1409 gpg_strerror (err));
1410 end_cert_fetch (fetch_context);
1415 log_debug ("cmd_lookup: returning one cert%s\n",
1416 truncated? " (truncated)":"");
1418 /* Send the data, flush the buffer and then send an END line
1419 as a certificate delimiter. */
1420 err = assuan_send_data (ctx, value, valuelen);
1422 err = assuan_send_data (ctx, NULL, 0);
1424 err = assuan_write_line (ctx, "END");
1427 log_error (_("error sending data: %s\n"), gpg_strerror (err));
1428 end_cert_fetch (fetch_context);
1432 if (++count >= opt.max_replies )
1434 truncation_forced = 1;
1435 log_info (_("max_replies %d exceeded\n"), opt.max_replies );
1441 end_cert_fetch (fetch_context);
1446 if (truncated || truncation_forced)
1450 sprintf (str, "%d", count);
1451 assuan_write_status (ctx, "TRUNCATED", str);
1454 if (!err && !count && !local_count && any_no_data)
1455 err = gpg_error (GPG_ERR_NO_DATA);
1458 free_strlist (list);
1463 static const char hlp_lookup[] =
1464 "LOOKUP [--url] [--single] [--cache-only] <pattern>\n"
1466 "Lookup certificates matching PATTERN. With --url the pattern is\n"
1467 "expected to be one URL.\n"
1469 "If --url is not given: To allow for multiple patterns (which are ORed)\n"
1470 "quoting is required: Spaces are translated to \"+\" or \"%20\";\n"
1471 "obviously this requires that the usual escape quoting rules are applied.\n"
1473 "If --url is given no special escaping is required because URLs are\n"
1474 "already escaped this way.\n"
1476 "If --single is given the first and only the first match will be\n"
1477 "returned. If --cache-only is _not_ given, no local query will be\n"
1480 "If --cache-only is given no external lookup is done so that only\n"
1481 "certificates from the cache may get returned.";
1483 cmd_lookup (assuan_context_t ctx, char *line)
1486 int lookup_url, single, cache_only;
1488 lookup_url = has_leading_option (line, "--url");
1489 single = has_leading_option (line, "--single");
1490 cache_only = has_leading_option (line, "--cache-only");
1491 line = skip_options (line);
1493 if (lookup_url && cache_only)
1494 err = gpg_error (GPG_ERR_NOT_FOUND);
1495 else if (lookup_url && single)
1496 err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1497 else if (lookup_url)
1498 err = lookup_cert_by_url (ctx, line);
1500 err = lookup_cert_by_pattern (ctx, line, single, cache_only);
1502 return leave_cmd (ctx, err);
1506 static const char hlp_loadcrl[] =
1507 "LOADCRL [--url] <filename|url>\n"
1509 "Load the CRL in the file with name FILENAME into our cache. Note\n"
1510 "that FILENAME should be given with an absolute path because\n"
1511 "Dirmngrs cwd is not known. With --url the CRL is directly loaded\n"
1512 "from the given URL.\n"
1514 "This command is usually used by gpgsm using the invocation \"gpgsm\n"
1515 "--call-dirmngr loadcrl <filename>\". A direct invocation of Dirmngr\n"
1516 "is not useful because gpgsm might need to callback gpgsm to ask for\n"
1517 "the CA's certificate.";
1519 cmd_loadcrl (assuan_context_t ctx, char *line)
1521 ctrl_t ctrl = assuan_get_pointer (ctx);
1522 gpg_error_t err = 0;
1523 int use_url = has_leading_option (line, "--url");
1525 line = skip_options (line);
1529 ksba_reader_t reader;
1531 err = crl_fetch (ctrl, line, &reader);
1533 log_error (_("fetching CRL from '%s' failed: %s\n"),
1534 line, gpg_strerror (err));
1537 err = crl_cache_insert (ctrl, line, reader);
1539 log_error (_("processing CRL from '%s' failed: %s\n"),
1540 line, gpg_strerror (err));
1541 crl_close_reader (reader);
1548 buf = xtrymalloc (strlen (line)+1);
1550 err = gpg_error_from_syserror ();
1553 strcpy_escaped_plus (buf, line);
1554 err = crl_cache_load (ctrl, buf);
1559 return leave_cmd (ctx, err);
1563 static const char hlp_listcrls[] =
1566 "List the content of all CRLs in a readable format. This command is\n"
1567 "usually used by gpgsm using the invocation \"gpgsm --call-dirmngr\n"
1568 "listcrls\". It may also be used directly using \"dirmngr\n"
1571 cmd_listcrls (assuan_context_t ctx, char *line)
1578 fp = es_fopencookie (ctx, "w", data_line_cookie_functions);
1580 err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
1583 err = crl_cache_list (fp);
1586 return leave_cmd (ctx, err);
1590 static const char hlp_cachecert[] =
1593 "Put a certificate into the internal cache. This command might be\n"
1594 "useful if a client knows in advance certificates required for a\n"
1595 "test and wants to make sure they get added to the internal cache.\n"
1596 "It is also helpful for debugging. To get the actual certificate,\n"
1597 "this command immediately inquires it using\n"
1599 " INQUIRE TARGETCERT\n"
1601 "and the caller is expected to return the certificate for the\n"
1602 "request as a binary blob.";
1604 cmd_cachecert (assuan_context_t ctx, char *line)
1606 ctrl_t ctrl = assuan_get_pointer (ctx);
1608 ksba_cert_t cert = NULL;
1609 unsigned char *value = NULL;
1614 err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1615 &value, &valuelen, MAX_CERT_LENGTH);
1618 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1622 if (!valuelen) /* No data returned; return a comprehensible error. */
1623 err = gpg_error (GPG_ERR_MISSING_CERT);
1626 err = ksba_cert_new (&cert);
1628 err = ksba_cert_init_from_mem (cert, value, valuelen);
1634 err = cache_cert (cert);
1637 ksba_cert_release (cert);
1638 return leave_cmd (ctx, err);
1642 static const char hlp_validate[] =
1645 "Validate a certificate using the certificate validation function\n"
1646 "used internally by dirmngr. This command is only useful for\n"
1647 "debugging. To get the actual certificate, this command immediately\n"
1648 "inquires it using\n"
1650 " INQUIRE TARGETCERT\n"
1652 "and the caller is expected to return the certificate for the\n"
1653 "request as a binary blob.";
1655 cmd_validate (assuan_context_t ctx, char *line)
1657 ctrl_t ctrl = assuan_get_pointer (ctx);
1659 ksba_cert_t cert = NULL;
1660 unsigned char *value = NULL;
1665 err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1666 &value, &valuelen, MAX_CERT_LENGTH);
1669 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1673 if (!valuelen) /* No data returned; return a comprehensible error. */
1674 err = gpg_error (GPG_ERR_MISSING_CERT);
1677 err = ksba_cert_new (&cert);
1679 err = ksba_cert_init_from_mem (cert, value, valuelen);
1685 /* If we have this certificate already in our cache, use the cached
1686 version for validation because this will take care of any cached
1689 unsigned char fpr[20];
1690 ksba_cert_t tmpcert;
1692 cert_compute_fpr (cert, fpr);
1693 tmpcert = get_cert_byfpr (fpr);
1696 ksba_cert_release (cert);
1701 err = validate_cert_chain (ctrl, cert, NULL, VALIDATE_MODE_CERT, NULL);
1704 ksba_cert_release (cert);
1705 return leave_cmd (ctx, err);
1710 /* Parse an keyserver URI and store it in a new uri item which is
1711 returned at R_ITEM. On error return an error code. */
1713 make_keyserver_item (const char *uri, uri_item_t *r_item)
1719 item = xtrymalloc (sizeof *item + strlen (uri));
1721 return gpg_error_from_syserror ();
1724 item->parsed_uri = NULL;
1725 strcpy (item->uri, uri);
1728 if (ldap_uri_p (item->uri))
1729 err = ldap_parse_uri (&item->parsed_uri, uri);
1733 err = http_parse_uri (&item->parsed_uri, uri, 1);
1744 /* If no keyserver is stored in CTRL but a global keyserver has been
1745 set, put that global keyserver into CTRL. We need use this
1746 function to help migrate from the old gpg based keyserver
1747 configuration to the new dirmngr based configuration. */
1749 ensure_keyserver (ctrl_t ctrl)
1753 uri_item_t onion_items = NULL;
1754 uri_item_t plain_items = NULL;
1758 if (ctrl->server_local->keyservers)
1759 return 0; /* Already set for this session. */
1761 return 0; /* No global option set. */
1763 for (sl = opt.keyserver; sl; sl = sl->next)
1765 err = make_keyserver_item (sl->d, &item);
1768 if (item->parsed_uri->onion)
1770 item->next = onion_items;
1775 item->next = plain_items;
1780 /* Decide which to use. Note that the sesssion has no keyservers
1782 if (onion_items && !onion_items->next && plain_items && !plain_items->next)
1784 /* If there is just one onion and one plain keyserver given, we take
1785 only one depending on whether Tor is running or not. */
1786 if (is_tor_running (ctrl))
1788 ctrl->server_local->keyservers = onion_items;
1793 ctrl->server_local->keyservers = plain_items;
1797 else if (!is_tor_running (ctrl))
1799 /* Tor is not running. It does not make sense to add Onion
1801 ctrl->server_local->keyservers = plain_items;
1806 /* In all other cases add all keyservers. */
1807 ctrl->server_local->keyservers = onion_items;
1809 for (ui = ctrl->server_local->keyservers; ui && ui->next; ui = ui->next)
1812 ui->next = plain_items;
1814 ctrl->server_local->keyservers = plain_items;
1819 release_uri_item_list (onion_items);
1820 release_uri_item_list (plain_items);
1826 static const char hlp_keyserver[] =
1827 "KEYSERVER [<options>] [<uri>|<host>]\n"
1830 " --clear Remove all configured keyservers\n"
1831 " --resolve Resolve HKP host names and rotate\n"
1832 " --hosttable Print table of known hosts and pools\n"
1833 " --dead Mark <host> as dead\n"
1834 " --alive Mark <host> as alive\n"
1836 "If called without arguments list all configured keyserver URLs.\n"
1837 "If called with an URI add this as keyserver. Note that keyservers\n"
1838 "are configured on a per-session base. A default keyserver may already be\n"
1839 "present, thus the \"--clear\" option must be used to get full control.\n"
1840 "If \"--clear\" and an URI are used together the clear command is\n"
1841 "obviously executed first. A RESET command does not change the list\n"
1842 "of configured keyservers.";
1844 cmd_keyserver (assuan_context_t ctx, char *line)
1846 ctrl_t ctrl = assuan_get_pointer (ctx);
1847 gpg_error_t err = 0;
1848 int clear_flag, add_flag, help_flag, host_flag, resolve_flag;
1849 int dead_flag, alive_flag;
1850 uri_item_t item = NULL; /* gcc 4.4.5 is not able to detect that it
1851 is always initialized. */
1853 clear_flag = has_option (line, "--clear");
1854 help_flag = has_option (line, "--help");
1855 resolve_flag = has_option (line, "--resolve");
1856 host_flag = has_option (line, "--hosttable");
1857 dead_flag = has_option (line, "--dead");
1858 alive_flag = has_option (line, "--alive");
1859 line = skip_options (line);
1864 err = ks_action_help (ctrl, line);
1870 err = ensure_keyserver (ctrl);
1872 err = ks_action_resolve (ctrl, ctrl->server_local->keyservers);
1877 if (alive_flag && dead_flag)
1879 err = set_error (GPG_ERR_ASS_PARAMETER, "no support for zombies");
1884 err = check_owner_permission (ctx, "no permission to use --dead");
1888 if (alive_flag || dead_flag)
1892 err = set_error (GPG_ERR_ASS_PARAMETER, "name of host missing");
1896 err = ks_hkp_mark_host (ctrl, line, alive_flag);
1903 err = ks_hkp_print_hosttable (ctrl);
1907 if (resolve_flag || host_flag || alive_flag || dead_flag)
1912 err = make_keyserver_item (line, &item);
1917 release_ctrl_keyservers (ctrl);
1920 item->next = ctrl->server_local->keyservers;
1921 ctrl->server_local->keyservers = item;
1924 if (!add_flag && !clear_flag && !help_flag)
1926 /* List configured keyservers. However, we first add a global
1930 err = ensure_keyserver (ctrl);
1933 assuan_set_error (ctx, err,
1934 "Bad keyserver configuration in dirmngr.conf");
1938 for (u=ctrl->server_local->keyservers; u; u = u->next)
1939 dirmngr_status (ctrl, "KEYSERVER", u->uri, NULL);
1944 return leave_cmd (ctx, err);
1949 static const char hlp_ks_search[] =
1950 "KS_SEARCH {<pattern>}\n"
1952 "Search the configured OpenPGP keyservers (see command KEYSERVER)\n"
1953 "for keys matching PATTERN";
1955 cmd_ks_search (assuan_context_t ctx, char *line)
1957 ctrl_t ctrl = assuan_get_pointer (ctx);
1963 /* No options for now. */
1964 line = skip_options (line);
1966 /* Break the line down into an strlist. Each pattern is
1967 percent-plus escaped. */
1969 for (p=line; *p; line = p)
1971 while (*p && *p != ' ')
1977 sl = xtrymalloc (sizeof *sl + strlen (line));
1980 err = gpg_error_from_syserror ();
1984 strcpy_escaped_plus (sl->d, line);
1990 err = ensure_keyserver (ctrl);
1994 /* Setup an output stream and perform the search. */
1995 outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
1997 err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2000 err = ks_action_search (ctrl, ctrl->server_local->keyservers,
2006 free_strlist (list);
2007 return leave_cmd (ctx, err);
2012 static const char hlp_ks_get[] =
2013 "KS_GET {<pattern>}\n"
2015 "Get the keys matching PATTERN from the configured OpenPGP keyservers\n"
2016 "(see command KEYSERVER). Each pattern should be a keyid, a fingerprint,\n"
2017 "or an exact name indicated by the '=' prefix.";
2019 cmd_ks_get (assuan_context_t ctx, char *line)
2021 ctrl_t ctrl = assuan_get_pointer (ctx);
2027 /* No options for now. */
2028 line = skip_options (line);
2030 /* Break the line into a strlist. Each pattern is by
2031 definition percent-plus escaped. However we only support keyids
2032 and fingerprints and thus the client has no need to apply the
2035 for (p=line; *p; line = p)
2037 while (*p && *p != ' ')
2043 sl = xtrymalloc (sizeof *sl + strlen (line));
2046 err = gpg_error_from_syserror ();
2050 strcpy_escaped_plus (sl->d, line);
2056 err = ensure_keyserver (ctrl);
2060 /* Setup an output stream and perform the get. */
2061 outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
2063 err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2066 err = ks_action_get (ctrl, ctrl->server_local->keyservers, list, outfp);
2071 free_strlist (list);
2072 return leave_cmd (ctx, err);
2076 static const char hlp_ks_fetch[] =
2079 "Get the key(s) from URL.";
2081 cmd_ks_fetch (assuan_context_t ctx, char *line)
2083 ctrl_t ctrl = assuan_get_pointer (ctx);
2087 /* No options for now. */
2088 line = skip_options (line);
2090 err = ensure_keyserver (ctrl); /* FIXME: Why do we needs this here? */
2094 /* Setup an output stream and perform the get. */
2095 outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
2097 err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2100 err = ks_action_fetch (ctrl, line, outfp);
2105 return leave_cmd (ctx, err);
2110 static const char hlp_ks_put[] =
2113 "Send a key to the configured OpenPGP keyservers. The actual key material\n"
2114 "is then requested by Dirmngr using\n"
2116 " INQUIRE KEYBLOCK\n"
2118 "The client shall respond with a binary version of the keyblock (e.g.,\n"
2119 "the output of `gpg --export KEYID'). For LDAP\n"
2120 "keyservers Dirmngr may ask for meta information of the provided keyblock\n"
2123 " INQUIRE KEYBLOCK_INFO\n"
2125 "The client shall respond with a colon delimited info lines (the output\n"
2126 "of 'for x in keys sigs; do gpg --list-$x --with-colons KEYID; done').\n";
2128 cmd_ks_put (assuan_context_t ctx, char *line)
2130 ctrl_t ctrl = assuan_get_pointer (ctx);
2132 unsigned char *value = NULL;
2134 unsigned char *info = NULL;
2137 /* No options for now. */
2138 line = skip_options (line);
2140 err = ensure_keyserver (ctrl);
2144 /* Ask for the key material. */
2145 err = assuan_inquire (ctx, "KEYBLOCK",
2146 &value, &valuelen, MAX_KEYBLOCK_LENGTH);
2149 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
2153 if (!valuelen) /* No data returned; return a comprehensible error. */
2155 err = gpg_error (GPG_ERR_MISSING_CERT);
2159 /* Ask for the key meta data. Not actually needed for HKP servers
2160 but we do it anyway to test the client implementaion. */
2161 err = assuan_inquire (ctx, "KEYBLOCK_INFO",
2162 &info, &infolen, MAX_KEYBLOCK_LENGTH);
2165 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
2170 err = ks_action_put (ctrl, ctrl->server_local->keyservers,
2171 value, valuelen, info, infolen);
2176 return leave_cmd (ctx, err);
2182 static const char hlp_getinfo[] =
2185 "Multi purpose command to return certain information. \n"
2186 "Supported values of WHAT are:\n"
2188 "version - Return the version of the program.\n"
2189 "pid - Return the process id of the server.\n"
2190 "tor - Return OK if running in Tor mode\n"
2191 "dnsinfo - Return info about the DNS resolver\n"
2192 "socket_name - Return the name of the socket.\n";
2194 cmd_getinfo (assuan_context_t ctx, char *line)
2196 ctrl_t ctrl = assuan_get_pointer (ctx);
2199 if (!strcmp (line, "version"))
2201 const char *s = VERSION;
2202 err = assuan_send_data (ctx, s, strlen (s));
2204 else if (!strcmp (line, "pid"))
2208 snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
2209 err = assuan_send_data (ctx, numbuf, strlen (numbuf));
2211 else if (!strcmp (line, "socket_name"))
2213 const char *s = dirmngr_user_socket_name ();
2216 s = dirmngr_sys_socket_name ();
2219 err = assuan_send_data (ctx, s, strlen (s));
2221 err = gpg_error (GPG_ERR_NO_DATA);
2223 else if (!strcmp (line, "tor"))
2227 if (!is_tor_running (ctrl))
2228 err = assuan_write_status (ctx, "NO_TOR", "Tor not running");
2232 assuan_set_okay_line (ctx, "- Tor mode is enabled");
2235 err = set_error (GPG_ERR_FALSE, "Tor mode is NOT enabled");
2237 else if (!strcmp (line, "dnsinfo"))
2239 #if USE_ADNS && HAVE_ADNS_IF_TORMODE
2240 assuan_set_okay_line (ctx, "- ADNS with Tor support");
2242 assuan_set_okay_line (ctx, "- ADNS w/o Tor support");
2244 assuan_set_okay_line (ctx, "- System resolver w/o Tor support");
2249 err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
2251 return leave_cmd (ctx, err);
2256 static const char hlp_killdirmngr[] =
2259 "This command allows a user - given sufficient permissions -\n"
2260 "to kill this dirmngr process.\n";
2262 cmd_killdirmngr (assuan_context_t ctx, char *line)
2264 ctrl_t ctrl = assuan_get_pointer (ctx);
2269 if (opt.system_daemon)
2271 if (opt.system_service)
2272 err = set_error (GPG_ERR_NOT_SUPPORTED,
2273 "can't do that whilst running as system service");
2275 err = check_owner_permission (ctx,
2276 "no permission to kill this process");
2283 ctrl->server_local->stopme = 1;
2284 assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
2285 err = gpg_error (GPG_ERR_EOF);
2291 static const char hlp_reloaddirmngr[] =
2294 "This command is an alternative to SIGHUP\n"
2295 "to reload the configuration.";
2297 cmd_reloaddirmngr (assuan_context_t ctx, char *line)
2302 if (opt.system_daemon)
2304 #ifndef HAVE_W32_SYSTEM
2308 err = check_owner_permission (ctx,
2309 "no permission to reload this process");
2316 dirmngr_sighup_action ();
2323 /* Tell the assuan library about our commands. */
2325 register_commands (assuan_context_t ctx)
2329 assuan_handler_t handler;
2330 const char * const help;
2332 { "DNS_CERT", cmd_dns_cert, hlp_dns_cert },
2333 { "WKD_GET", cmd_wkd_get, hlp_wkd_get },
2334 { "LDAPSERVER", cmd_ldapserver, hlp_ldapserver },
2335 { "ISVALID", cmd_isvalid, hlp_isvalid },
2336 { "CHECKCRL", cmd_checkcrl, hlp_checkcrl },
2337 { "CHECKOCSP", cmd_checkocsp, hlp_checkocsp },
2338 { "LOOKUP", cmd_lookup, hlp_lookup },
2339 { "LOADCRL", cmd_loadcrl, hlp_loadcrl },
2340 { "LISTCRLS", cmd_listcrls, hlp_listcrls },
2341 { "CACHECERT", cmd_cachecert, hlp_cachecert },
2342 { "VALIDATE", cmd_validate, hlp_validate },
2343 { "KEYSERVER", cmd_keyserver, hlp_keyserver },
2344 { "KS_SEARCH", cmd_ks_search, hlp_ks_search },
2345 { "KS_GET", cmd_ks_get, hlp_ks_get },
2346 { "KS_FETCH", cmd_ks_fetch, hlp_ks_fetch },
2347 { "KS_PUT", cmd_ks_put, hlp_ks_put },
2348 { "GETINFO", cmd_getinfo, hlp_getinfo },
2349 { "KILLDIRMNGR",cmd_killdirmngr,hlp_killdirmngr },
2350 { "RELOADDIRMNGR",cmd_reloaddirmngr,hlp_reloaddirmngr },
2355 for (i=j=0; table[i].name; i++)
2357 rc = assuan_register_command (ctx, table[i].name, table[i].handler,
2366 /* Note that we do not reset the list of configured keyservers. */
2368 reset_notify (assuan_context_t ctx, char *line)
2370 ctrl_t ctrl = assuan_get_pointer (ctx);
2374 ldapserver_list_free (ctrl->server_local->ldapservers);
2376 ctrl->server_local->ldapservers = NULL;
2381 /* Startup the server and run the main command loop. With FD = -1,
2382 use stdin/stdout. */
2384 start_command_handler (assuan_fd_t fd)
2386 static const char hello[] = "Dirmngr " VERSION " at your service";
2387 static char *hello_line;
2389 assuan_context_t ctx;
2392 ctrl = xtrycalloc (1, sizeof *ctrl);
2394 ctrl->server_local = xtrycalloc (1, sizeof *ctrl->server_local);
2395 if (!ctrl || !ctrl->server_local)
2397 log_error (_("can't allocate control structure: %s\n"),
2403 dirmngr_init_default_ctrl (ctrl);
2405 rc = assuan_new (&ctx);
2408 log_error (_("failed to allocate assuan context: %s\n"),
2413 if (fd == ASSUAN_INVALID_FD)
2415 assuan_fd_t filedes[2];
2417 filedes[0] = assuan_fdopen (0);
2418 filedes[1] = assuan_fdopen (1);
2419 rc = assuan_init_pipe_server (ctx, filedes);
2423 rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED);
2428 assuan_release (ctx);
2429 log_error (_("failed to initialize the server: %s\n"),
2434 rc = register_commands (ctx);
2437 log_error (_("failed to the register commands with Assuan: %s\n"),
2446 const char *cfgname;
2448 cfgname = opt.config_filename? opt.config_filename : "[none]";
2450 n = (30 + strlen (opt.homedir) + strlen (cfgname)
2451 + strlen (hello) + 1);
2452 hello_line = xmalloc (n+1);
2453 snprintf (hello_line, n,
2463 ctrl->server_local->assuan_ctx = ctx;
2464 assuan_set_pointer (ctx, ctrl);
2466 assuan_set_hello_line (ctx, hello_line);
2467 assuan_register_option_handler (ctx, option_handler);
2468 assuan_register_reset_notify (ctx, reset_notify);
2472 rc = assuan_accept (ctx);
2477 log_info (_("Assuan accept problem: %s\n"), gpg_strerror (rc));
2481 #ifndef HAVE_W32_SYSTEM
2484 assuan_peercred_t peercred;
2486 if (!assuan_get_peercred (ctx, &peercred))
2487 log_info ("connection from process %ld (%ld:%ld)\n",
2488 (long)peercred->pid, (long)peercred->uid,
2489 (long)peercred->gid);
2493 rc = assuan_process (ctx);
2496 log_info (_("Assuan processing failed: %s\n"), gpg_strerror (rc));
2503 ldap_wrapper_connection_cleanup (ctrl);
2505 ldapserver_list_free (ctrl->server_local->ldapservers);
2507 ctrl->server_local->ldapservers = NULL;
2509 release_ctrl_keyservers (ctrl);
2511 ctrl->server_local->assuan_ctx = NULL;
2512 assuan_release (ctx);
2514 if (ctrl->server_local->stopme)
2518 log_error ("oops: connection control structure still referenced (%d)\n",
2522 release_ctrl_ocsp_certs (ctrl);
2523 xfree (ctrl->server_local);
2524 dirmngr_deinit_default_ctrl (ctrl);
2530 /* Send a status line back to the client. KEYWORD is the status
2531 keyword, the optional string arguments are blank separated added to
2532 the line, the last argument must be a NULL. */
2534 dirmngr_status (ctrl_t ctrl, const char *keyword, ...)
2536 gpg_error_t err = 0;
2540 va_start (arg_ptr, keyword);
2542 if (ctrl->server_local)
2544 assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2550 while ( (text = va_arg (arg_ptr, const char *)) )
2557 for ( ; *text && n < DIM (buf)-2; n++)
2561 err = assuan_write_status (ctx, keyword, buf);
2569 /* Print a help status line. TEXTLEN gives the length of the text
2570 from TEXT to be printed. The function splits text at LFs. */
2572 dirmngr_status_help (ctrl_t ctrl, const char *text)
2574 gpg_error_t err = 0;
2576 if (ctrl->server_local)
2578 assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2586 for ( ; *text && *text != '\n' && n < DIM (buf)-2; n++)
2591 err = assuan_write_status (ctx, "#", buf);
2593 while (!err && *text);
2599 /* Send a tick progress indicator back. Fixme: This is only done for
2600 the currently active channel. */
2602 dirmngr_tick (ctrl_t ctrl)
2604 static time_t next_tick = 0;
2605 gpg_error_t err = 0;
2606 time_t now = time (NULL);
2610 next_tick = now + 1;
2612 else if ( now > next_tick )
2616 err = dirmngr_status (ctrl, "PROGRESS", "tick", "? 0 0", NULL);
2619 /* Take this as in indication for a cancel request. */
2620 err = gpg_error (GPG_ERR_CANCELED);
2625 next_tick = now + 1;