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 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"
54 #include "mbox-util.h"
56 /* To avoid DoS attacks we limit the size of a certificate to
57 something reasonable. */
58 #define MAX_CERT_LENGTH (8*1024)
60 /* The same goes for OpenPGP keyblocks, but here we need to allow for
61 much longer blocks; a 200k keyblock is not too unusual for keys
62 with a lot of signatures (e.g. 0x5b0358a2). */
63 #define MAX_KEYBLOCK_LENGTH (512*1024)
66 #define PARM_ERROR(t) assuan_set_error (ctx, \
67 gpg_error (GPG_ERR_ASS_PARAMETER), (t))
68 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
72 /* Control structure per connection. */
75 /* Data used to associate an Assuan context with local server data */
76 assuan_context_t assuan_ctx;
78 /* Per-session LDAP servers. */
79 ldap_server_t ldapservers;
81 /* Per-session list of keyservers. */
82 uri_item_t keyservers;
84 /* If this flag is set to true this dirmngr process will be
85 terminated after the end of this session. */
90 /* Cookie definition for assuan data line output. */
91 static ssize_t data_line_cookie_write (void *cookie,
92 const void *buffer, size_t size);
93 static int data_line_cookie_close (void *cookie);
94 static es_cookie_io_functions_t data_line_cookie_functions =
97 data_line_cookie_write,
99 data_line_cookie_close
106 /* Accessor for the local ldapservers variable. */
108 get_ldapservers_from_ctrl (ctrl_t ctrl)
110 if (ctrl && ctrl->server_local)
111 return ctrl->server_local->ldapservers;
117 /* Release all configured keyserver info from CTRL. */
119 release_ctrl_keyservers (ctrl_t ctrl)
121 if (! ctrl->server_local)
124 while (ctrl->server_local->keyservers)
126 uri_item_t tmp = ctrl->server_local->keyservers->next;
127 http_release_parsed_uri (ctrl->server_local->keyservers->parsed_uri);
128 xfree (ctrl->server_local->keyservers);
129 ctrl->server_local->keyservers = tmp;
135 /* Helper to print a message while leaving a command. */
137 leave_cmd (assuan_context_t ctx, gpg_error_t err)
141 const char *name = assuan_get_command_name (ctx);
144 if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT)
145 log_error ("command '%s' failed: %s\n", name,
148 log_error ("command '%s' failed: %s <%s>\n", name,
149 gpg_strerror (err), gpg_strsource (err));
155 /* This is a wrapper around assuan_send_data which makes debugging the
156 output in verbose mode easier. */
158 data_line_write (assuan_context_t ctx, const void *buffer_arg, size_t size)
160 const char *buffer = buffer_arg;
163 if (opt.verbose && buffer && size)
165 /* Ease reading of output by sending a physical line at each LF. */
172 p = memchr (buffer, '\n', nbytes);
173 n = p ? (p - buffer) + 1 : nbytes;
174 err = assuan_send_data (ctx, buffer, n);
177 gpg_err_set_errno (EIO);
182 if (nbytes && (err=assuan_send_data (ctx, NULL, 0))) /* Flush line. */
184 gpg_err_set_errno (EIO);
192 err = assuan_send_data (ctx, buffer, size);
195 gpg_err_set_errno (EIO); /* For use by data_line_cookie_write. */
204 /* A write handler used by es_fopencookie to write assuan data
207 data_line_cookie_write (void *cookie, const void *buffer, size_t size)
209 assuan_context_t ctx = cookie;
211 if (data_line_write (ctx, buffer, size))
213 return (ssize_t)size;
218 data_line_cookie_close (void *cookie)
220 assuan_context_t ctx = cookie;
222 if (assuan_send_data (ctx, NULL, 0))
224 gpg_err_set_errno (EIO);
232 /* Copy the % and + escaped string S into the buffer D and replace the
233 escape sequences. Note, that it is sufficient to allocate the
234 target string D as long as the source string S, i.e.: strlen(s)+1.
235 Note further that if S contains an escaped binary Nul the resulting
236 string D will contain the 0 as well as all other characters but it
237 will be impossible to know whether this is the original EOS or a
240 strcpy_escaped_plus (char *d, const unsigned char *s)
244 if (*s == '%' && s[1] && s[2])
259 /* Check whether the option NAME appears in LINE */
261 has_option (const char *line, const char *name)
264 int n = strlen (name);
266 s = strstr (line, name);
267 return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
270 /* Same as has_option but only considers options at the begin of the
271 line. This is useful for commands which allow arbitrary strings on
274 has_leading_option (const char *line, const char *name)
279 if (name[0] != '-' || name[1] != '-' || !name[2] || spacep (name+2))
282 while ( *line == '-' && line[1] == '-' )
285 while (*line && !spacep (line))
287 if (n == (line - s) && !strncmp (s, name, n))
289 while (spacep (line))
296 /* Same as has_option but does only test for the name of the option
297 and ignores an argument, i.e. with NAME being "--hash" it would
298 return a pointer for "--hash" as well as for "--hash=foo". If
299 thhere is no such option NULL is returned. The pointer returned
300 points right behind the option name, this may be an equal sign, Nul
302 /* static const char * */
303 /* has_option_name (const char *line, const char *name) */
306 /* int n = strlen (name); */
308 /* s = strstr (line, name); */
309 /* return (s && (s == line || spacep (s-1)) */
310 /* && (!s[n] || spacep (s+n) || s[n] == '=')) ? (s+n) : NULL; */
314 /* Skip over options. It is assumed that leading spaces have been
315 removed (this is the case for lines passed to a handler from
316 assuan). Blanks after the options are also removed. */
318 skip_options (char *line)
320 while ( *line == '-' && line[1] == '-' )
322 while (*line && !spacep (line))
324 while (spacep (line))
331 /* Return an error if the assuan context does not belong to the owner
332 of the process or to root. On error FAILTEXT is set as Assuan
335 check_owner_permission (assuan_context_t ctx, const char *failtext)
337 #ifdef HAVE_W32_SYSTEM
338 /* Under Windows the dirmngr is always run under the control of the
344 assuan_peercred_t cred;
346 ec = gpg_err_code (assuan_get_peercred (ctx, &cred));
347 if (!ec && cred->uid && cred->uid != getuid ())
350 return set_error (ec, failtext);
357 /* Common code for get_cert_local and get_issuer_cert_local. */
359 do_get_cert_local (ctrl_t ctrl, const char *name, const char *command)
361 unsigned char *value;
369 buf = xmalloc ( strlen (command) + 1 + strlen(name) + 1);
370 strcpy (stpcpy (stpcpy (buf, command), " "), name);
373 buf = xstrdup (command);
375 rc = assuan_inquire (ctrl->server_local->assuan_ctx, buf,
376 &value, &valuelen, MAX_CERT_LENGTH);
380 log_error (_("assuan_inquire(%s) failed: %s\n"),
381 command, gpg_strerror (rc));
391 rc = ksba_cert_new (&cert);
394 rc = ksba_cert_init_from_mem (cert, value, valuelen);
397 ksba_cert_release (cert);
407 /* Ask back to return a certificate for name, given as a regular
408 gpgsm certificate indentificates (e.g. fingerprint or one of the
409 other methods). Alternatively, NULL may be used for NAME to
410 return the current target certificate. Either return the certificate
411 in a KSBA object or NULL if it is not available.
414 get_cert_local (ctrl_t ctrl, const char *name)
416 if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
419 log_debug ("get_cert_local called w/o context\n");
422 return do_get_cert_local (ctrl, name, "SENDCERT");
426 /* Ask back to return the issuing certificate for name, given as a
427 regular gpgsm certificate indentificates (e.g. fingerprint or one
428 of the other methods). Alternatively, NULL may be used for NAME to
429 return thecurrent target certificate. Either return the certificate
430 in a KSBA object or NULL if it is not available.
434 get_issuing_cert_local (ctrl_t ctrl, const char *name)
436 if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
439 log_debug ("get_issuing_cert_local called w/o context\n");
442 return do_get_cert_local (ctrl, name, "SENDISSUERCERT");
445 /* Ask back to return a certificate with subject NAME and a
446 subjectKeyIdentifier of KEYID. */
448 get_cert_local_ski (ctrl_t ctrl, const char *name, ksba_sexp_t keyid)
450 unsigned char *value;
457 if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
460 log_debug ("get_cert_local_ski called w/o context\n");
465 log_debug ("get_cert_local_ski called with insufficient arguments\n");
469 hexkeyid = serial_hex (keyid);
472 log_debug ("serial_hex() failed\n");
476 buf = xtrymalloc (15 + strlen (hexkeyid) + 2 + strlen(name) + 1);
480 log_error ("can't allocate enough memory: %s\n", strerror (errno));
484 strcpy (stpcpy (stpcpy (stpcpy (buf, "SENDCERT_SKI "), hexkeyid)," /"),name);
487 rc = assuan_inquire (ctrl->server_local->assuan_ctx, buf,
488 &value, &valuelen, MAX_CERT_LENGTH);
492 log_error (_("assuan_inquire(%s) failed: %s\n"), "SENDCERT_SKI",
503 rc = ksba_cert_new (&cert);
506 rc = ksba_cert_init_from_mem (cert, value, valuelen);
509 ksba_cert_release (cert);
518 /* Ask the client via an inquiry to check the istrusted status of the
519 certificate specified by the hexified fingerprint HEXFPR. Returns
520 0 if the certificate is trusted by the client or an error code. */
522 get_istrusted_from_client (ctrl_t ctrl, const char *hexfpr)
524 unsigned char *value;
529 if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx
531 return gpg_error (GPG_ERR_INV_ARG);
533 snprintf (request, sizeof request, "ISTRUSTED %s", hexfpr);
534 rc = assuan_inquire (ctrl->server_local->assuan_ctx, request,
535 &value, &valuelen, 100);
538 log_error (_("assuan_inquire(%s) failed: %s\n"),
539 request, gpg_strerror (rc));
542 /* The expected data is: "1" or "1 cruft" (not a C-string). */
543 if (valuelen && *value == '1' && (valuelen == 1 || spacep (value+1)))
546 rc = gpg_error (GPG_ERR_NOT_TRUSTED);
554 /* Ask the client to return the certificate associated with the
555 current command. This is sometimes needed because the client usually
556 sends us just the cert ID, assuming that the request can be
557 satisfied from the cache, where the cert ID is used as key. */
559 inquire_cert_and_load_crl (assuan_context_t ctx)
561 ctrl_t ctrl = assuan_get_pointer (ctx);
563 unsigned char *value = NULL;
565 ksba_cert_t cert = NULL;
567 err = assuan_inquire( ctx, "SENDCERT", &value, &valuelen, 0);
572 /* FILE *fp = fopen ("foo.der", "r"); */
573 /* value = xmalloc (2000); */
574 /* valuelen = fread (value, 1, 2000, fp); */
578 if (!valuelen) /* No data returned; return a comprehensible error. */
579 return gpg_error (GPG_ERR_MISSING_CERT);
581 err = ksba_cert_new (&cert);
584 err = ksba_cert_init_from_mem (cert, value, valuelen);
587 xfree (value); value = NULL;
589 err = crl_cache_reload_crl (ctrl, cert);
592 ksba_cert_release (cert);
598 /* Handle OPTION commands. */
600 option_handler (assuan_context_t ctx, const char *key, const char *value)
602 ctrl_t ctrl = assuan_get_pointer (ctx);
605 if (!strcmp (key, "force-crl-refresh"))
607 int i = *value? atoi (value) : 0;
608 ctrl->force_crl_refresh = i;
610 else if (!strcmp (key, "audit-events"))
612 int i = *value? atoi (value) : 0;
613 ctrl->audit_events = i;
615 else if (!strcmp (key, "http-proxy"))
617 xfree (ctrl->http_proxy);
618 if (!*value || !strcmp (value, "none"))
619 ctrl->http_proxy = NULL;
620 else if (!(ctrl->http_proxy = xtrystrdup (value)))
621 err = gpg_error_from_syserror ();
624 err = gpg_error (GPG_ERR_UNKNOWN_OPTION);
631 static const char hlp_dns_cert[] =
632 "DNS_CERT <subtype> <name>\n"
633 "DNS_CERT --pka <user_id>\n"
635 "Return the CERT record for <name>. <subtype> is one of\n"
636 " * Return the first record of any supported subtype\n"
637 " PGP Return the first record of subtype PGP (3)\n"
638 " IPGP Return the first record of subtype IPGP (6)\n"
639 "If the content of a certifciate is available (PGP) it is returned\n"
640 "by data lines. Fingerprints and URLs are returned via status lines.\n"
641 "In --pka mode the fingerprint and if available an URL is returned.";
643 cmd_dns_cert (assuan_context_t ctx, char *line)
645 /* ctrl_t ctrl = assuan_get_pointer (ctx); */
649 char *namebuf = NULL;
650 char *encodedhash = NULL;
656 unsigned char *fpr = NULL;
660 pka_mode = has_option (line, "--pka");
661 line = skip_options (line);
663 ; /* No need to parse here - we do this later. */
666 p = strchr (line, ' ');
669 err = PARM_ERROR ("missing arguments");
673 if (!strcmp (line, "*"))
674 certtype = DNS_CERTTYPE_ANY;
675 else if (!strcmp (line, "IPGP"))
676 certtype = DNS_CERTTYPE_IPGP;
677 else if (!strcmp (line, "PGP"))
678 certtype = DNS_CERTTYPE_PGP;
681 err = PARM_ERROR ("unknown subtype");
689 err = PARM_ERROR ("name missing");
696 char *domain; /* Points to mbox. */
699 mbox = mailbox_from_userid (line);
700 if (!mbox || !(domain = strchr (mbox, '@')))
702 err = set_error (GPG_ERR_INV_USER_ID, "no mailbox in user id");
707 gcry_md_hash_buffer (GCRY_MD_SHA1, hashbuf, mbox, strlen (mbox));
708 encodedhash = zb32_encode (hashbuf, 8*20);
711 err = gpg_error_from_syserror ();
714 namebuf = strconcat (encodedhash, "._pka.", domain, NULL);
717 err = gpg_error_from_syserror ();
721 certtype = DNS_CERTTYPE_IPGP;
726 err = get_dns_cert (name, certtype, &key, &keylen, &fpr, &fprlen, &url);
732 err = data_line_write (ctx, key, keylen);
741 tmpstr = bin2hex (fpr, fprlen, NULL);
743 err = gpg_error_from_syserror ();
746 err = assuan_write_status (ctx, "FPR", tmpstr);
755 err = assuan_write_status (ctx, "URL", url);
768 return leave_cmd (ctx, err);
773 static const char hlp_ldapserver[] =
774 "LDAPSERVER <data>\n"
776 "Add a new LDAP server to the list of configured LDAP servers.\n"
777 "DATA is in the same format as expected in the configure file.";
779 cmd_ldapserver (assuan_context_t ctx, char *line)
782 ctrl_t ctrl = assuan_get_pointer (ctx);
783 ldap_server_t server;
784 ldap_server_t *last_next_p;
786 while (spacep (line))
789 return leave_cmd (ctx, PARM_ERROR (_("ldapserver missing")));
791 server = ldapserver_parse_one (line, "", 0);
793 return leave_cmd (ctx, gpg_error (GPG_ERR_INV_ARG));
795 last_next_p = &ctrl->server_local->ldapservers;
797 last_next_p = &(*last_next_p)->next;
798 *last_next_p = server;
799 return leave_cmd (ctx, 0);
802 return leave_cmd (ctx, gpg_error (GPG_ERR_NOT_IMPLEMENTED));
807 static const char hlp_isvalid[] =
808 "ISVALID [--only-ocsp] [--force-default-responder]"
809 " <certificate_id>|<certificate_fpr>\n"
811 "This command checks whether the certificate identified by the\n"
812 "certificate_id is valid. This is done by consulting CRLs or\n"
813 "whatever has been configured. Note, that the returned error codes\n"
814 "are from gpg-error.h. The command may callback using the inquire\n"
815 "function. See the manual for details.\n"
817 "The CERTIFICATE_ID is a hex encoded string consisting of two parts,\n"
818 "delimited by a single dot. The first part is the SHA-1 hash of the\n"
819 "issuer name and the second part the serial number.\n"
821 "Alternatively the certificate's fingerprint may be given in which\n"
822 "case an OCSP request is done before consulting the CRL.\n"
824 "If the option --only-ocsp is given, no fallback to a CRL check will\n"
827 "If the option --force-default-responder is given, only the default\n"
828 "OCSP responder will be used and any other methods of obtaining an\n"
829 "OCSP responder URL won't be used.";
831 cmd_isvalid (assuan_context_t ctx, char *line)
833 ctrl_t ctrl = assuan_get_pointer (ctx);
834 char *issuerhash, *serialno;
839 int force_default_responder;
841 only_ocsp = has_option (line, "--only-ocsp");
842 force_default_responder = has_option (line, "--force-default-responder");
843 line = skip_options (line);
845 issuerhash = xstrdup (line); /* We need to work on a copy of the
846 line because that same Assuan
847 context may be used for an inquiry.
848 That is because Assuan reuses its
852 serialno = strchr (issuerhash, '.');
857 char *endp = strchr (issuerhash, ' ');
860 if (strlen (issuerhash) != 40)
863 return leave_cmd (ctx, PARM_ERROR (_("serialno missing in cert ID")));
872 /* Note, that we ignore the given issuer hash and instead rely
873 on the current certificate semantics used with this
876 err = gpg_error (GPG_ERR_NOT_SUPPORTED);
878 err = ocsp_isvalid (ctrl, NULL, NULL, force_default_responder);
879 /* Fixme: If we got no ocsp response and --only-ocsp is not used
880 we should fall back to CRL mode. Thus we need to clear
881 OCSP_MODE, get the issuerhash and the serialno from the
882 current certificate and jump to again. */
885 err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
888 switch (crl_cache_isvalid (ctrl,
889 issuerhash, serialno,
890 ctrl->force_crl_refresh))
892 case CRL_CACHE_VALID:
895 case CRL_CACHE_INVALID:
896 err = gpg_error (GPG_ERR_CERT_REVOKED);
898 case CRL_CACHE_DONTKNOW:
900 err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
901 else if (!(err = inquire_cert_and_load_crl (ctx)))
907 case CRL_CACHE_CANTUSE:
908 err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
911 log_fatal ("crl_cache_isvalid returned invalid code\n");
916 return leave_cmd (ctx, err);
920 /* If the line contains a SHA-1 fingerprint as the first argument,
921 return the FPR vuffer on success. The function checks that the
922 fingerprint consists of valid characters and prints and error
923 message if it does not and returns NULL. Fingerprints are
924 considered optional and thus no explicit error is returned. NULL is
925 also returned if there is no fingerprint at all available.
926 FPR must be a caller provided buffer of at least 20 bytes.
928 Note that colons within the fingerprint are allowed to separate 2
929 hex digits; this allows for easier cutting and pasting using the
930 usual fingerprint rendering.
932 static unsigned char *
933 get_fingerprint_from_line (const char *line, unsigned char *fpr)
938 for (s=line, i=0; *s && *s != ' '; s++ )
940 if ( hexdigitp (s) && hexdigitp (s+1) )
943 return NULL; /* Fingerprint too long. */
944 fpr[i++] = xtoi_2 (s);
947 else if ( *s != ':' )
948 return NULL; /* Invalid. */
951 return NULL; /* Fingerprint to short. */
957 static const char hlp_checkcrl[] =
958 "CHECKCRL [<fingerprint>]\n"
960 "Check whether the certificate with FINGERPRINT (SHA-1 hash of the\n"
961 "entire X.509 certificate blob) is valid or not by consulting the\n"
962 "CRL responsible for this certificate. If the fingerprint has not\n"
963 "been given or the certificate is not known, the function \n"
964 "inquires the certificate using an\n"
966 " INQUIRE TARGETCERT\n"
968 "and the caller is expected to return the certificate for the\n"
969 "request (which should match FINGERPRINT) as a binary blob.\n"
970 "Processing then takes place without further interaction; in\n"
971 "particular dirmngr tries to locate other required certificate by\n"
972 "its own mechanism which includes a local certificate store as well\n"
973 "as a list of trusted root certificates.\n"
975 "The return value is the usual gpg-error code or 0 for ducesss;\n"
976 "i.e. the certificate validity has been confirmed by a valid CRL.";
978 cmd_checkcrl (assuan_context_t ctx, char *line)
980 ctrl_t ctrl = assuan_get_pointer (ctx);
982 unsigned char fprbuffer[20], *fpr;
985 fpr = get_fingerprint_from_line (line, fprbuffer);
986 cert = fpr? get_cert_byfpr (fpr) : NULL;
990 /* We do not have this certificate yet or the fingerprint has
991 not been given. Inquire it from the client. */
992 unsigned char *value = NULL;
995 err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
996 &value, &valuelen, MAX_CERT_LENGTH);
999 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1003 if (!valuelen) /* No data returned; return a comprehensible error. */
1004 err = gpg_error (GPG_ERR_MISSING_CERT);
1007 err = ksba_cert_new (&cert);
1009 err = ksba_cert_init_from_mem (cert, value, valuelen);
1018 err = crl_cache_cert_isvalid (ctrl, cert, ctrl->force_crl_refresh);
1019 if (gpg_err_code (err) == GPG_ERR_NO_CRL_KNOWN)
1021 err = crl_cache_reload_crl (ctrl, cert);
1023 err = crl_cache_cert_isvalid (ctrl, cert, 0);
1027 ksba_cert_release (cert);
1028 return leave_cmd (ctx, err);
1032 static const char hlp_checkocsp[] =
1033 "CHECKOCSP [--force-default-responder] [<fingerprint>]\n"
1035 "Check whether the certificate with FINGERPRINT (SHA-1 hash of the\n"
1036 "entire X.509 certificate blob) is valid or not by asking an OCSP\n"
1037 "responder responsible for this certificate. The optional\n"
1038 "fingerprint may be used for a quick check in case an OCSP check has\n"
1039 "been done for this certificate recently (we always cache OCSP\n"
1040 "responses for a couple of minutes). If the fingerprint has not been\n"
1041 "given or there is no cached result, the function inquires the\n"
1042 "certificate using an\n"
1044 " INQUIRE TARGETCERT\n"
1046 "and the caller is expected to return the certificate for the\n"
1047 "request (which should match FINGERPRINT) as a binary blob.\n"
1048 "Processing then takes place without further interaction; in\n"
1049 "particular dirmngr tries to locate other required certificates by\n"
1050 "its own mechanism which includes a local certificate store as well\n"
1051 "as a list of trusted root certifciates.\n"
1053 "If the option --force-default-responder is given, only the default\n"
1054 "OCSP responder will be used and any other methods of obtaining an\n"
1055 "OCSP responder URL won't be used.\n"
1057 "The return value is the usual gpg-error code or 0 for ducesss;\n"
1058 "i.e. the certificate validity has been confirmed by a valid CRL.";
1060 cmd_checkocsp (assuan_context_t ctx, char *line)
1062 ctrl_t ctrl = assuan_get_pointer (ctx);
1064 unsigned char fprbuffer[20], *fpr;
1066 int force_default_responder;
1068 force_default_responder = has_option (line, "--force-default-responder");
1069 line = skip_options (line);
1071 fpr = get_fingerprint_from_line (line, fprbuffer);
1072 cert = fpr? get_cert_byfpr (fpr) : NULL;
1076 /* We do not have this certificate yet or the fingerprint has
1077 not been given. Inquire it from the client. */
1078 unsigned char *value = NULL;
1081 err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1082 &value, &valuelen, MAX_CERT_LENGTH);
1085 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1089 if (!valuelen) /* No data returned; return a comprehensible error. */
1090 err = gpg_error (GPG_ERR_MISSING_CERT);
1093 err = ksba_cert_new (&cert);
1095 err = ksba_cert_init_from_mem (cert, value, valuelen);
1104 if (!opt.allow_ocsp)
1105 err = gpg_error (GPG_ERR_NOT_SUPPORTED);
1107 err = ocsp_isvalid (ctrl, cert, NULL, force_default_responder);
1110 ksba_cert_release (cert);
1111 return leave_cmd (ctx, err);
1117 lookup_cert_by_url (assuan_context_t ctx, const char *url)
1119 ctrl_t ctrl = assuan_get_pointer (ctx);
1120 gpg_error_t err = 0;
1121 unsigned char *value = NULL;
1124 /* Fetch single certificate given it's URL. */
1125 err = fetch_cert_by_url (ctrl, url, &value, &valuelen);
1128 log_error (_("fetch_cert_by_url failed: %s\n"), gpg_strerror (err));
1132 /* Send the data, flush the buffer and then send an END. */
1133 err = assuan_send_data (ctx, value, valuelen);
1135 err = assuan_send_data (ctx, NULL, 0);
1137 err = assuan_write_line (ctx, "END");
1140 log_error (_("error sending data: %s\n"), gpg_strerror (err));
1150 /* Send the certificate, flush the buffer and then send an END. */
1152 return_one_cert (void *opaque, ksba_cert_t cert)
1154 assuan_context_t ctx = opaque;
1156 const unsigned char *der;
1159 der = ksba_cert_get_image (cert, &derlen);
1161 err = gpg_error (GPG_ERR_INV_CERT_OBJ);
1164 err = assuan_send_data (ctx, der, derlen);
1166 err = assuan_send_data (ctx, NULL, 0);
1168 err = assuan_write_line (ctx, "END");
1171 log_error (_("error sending data: %s\n"), gpg_strerror (err));
1176 /* Lookup certificates from the internal cache or using the ldap
1179 lookup_cert_by_pattern (assuan_context_t ctx, char *line,
1180 int single, int cache_only)
1182 gpg_error_t err = 0;
1184 strlist_t sl, list = NULL;
1185 int truncated = 0, truncation_forced = 0;
1187 int local_count = 0;
1189 ctrl_t ctrl = assuan_get_pointer (ctx);
1190 unsigned char *value = NULL;
1192 struct ldapserver_iter ldapserver_iter;
1193 cert_fetch_context_t fetch_context;
1195 int any_no_data = 0;
1197 /* Break the line down into an STRLIST */
1198 for (p=line; *p; line = p)
1200 while (*p && *p != ' ')
1207 sl = xtrymalloc (sizeof *sl + strlen (line));
1210 err = gpg_error_from_errno (errno);
1213 memset (sl, 0, sizeof *sl);
1214 strcpy_escaped_plus (sl->d, line);
1220 /* First look through the internal cache. The certifcates retruned
1221 here are not counted towards the truncation limit. */
1222 if (single && !cache_only)
1223 ; /* Do not read from the local cache in this case. */
1226 for (sl=list; sl; sl = sl->next)
1228 err = get_certs_bypattern (sl->d, return_one_cert, ctx);
1234 if (gpg_err_code (err) == GPG_ERR_NO_DATA)
1240 else if (gpg_err_code (err) == GPG_ERR_INV_NAME && !cache_only)
1242 /* No real fault because the internal pattern lookup
1243 can't yet cope with all types of pattern. */
1251 /* Loop over all configured servers unless we want only the
1252 certificates from the cache. */
1254 for (ldapserver_iter_begin (&ldapserver_iter, ctrl);
1255 !cache_only && !ldapserver_iter_end_p (&ldapserver_iter)
1256 && ldapserver_iter.server->host && !truncation_forced;
1257 ldapserver_iter_next (&ldapserver_iter))
1259 ldap_server_t ldapserver = ldapserver_iter.server;
1262 log_debug ("cmd_lookup: trying %s:%d base=%s\n",
1263 ldapserver->host, ldapserver->port,
1264 ldapserver->base?ldapserver->base : "[default]");
1266 /* Fetch certificates matching pattern */
1267 err = start_cert_fetch (ctrl, &fetch_context, list, ldapserver);
1268 if ( gpg_err_code (err) == GPG_ERR_NO_DATA )
1271 log_debug ("cmd_lookup: no data\n");
1278 log_error (_("start_cert_fetch failed: %s\n"), gpg_strerror (err));
1282 /* Fetch the certificates for this query. */
1283 while (!truncation_forced)
1285 xfree (value); value = NULL;
1286 err = fetch_next_cert (fetch_context, &value, &valuelen);
1287 if (gpg_err_code (err) == GPG_ERR_NO_DATA )
1293 if (gpg_err_code (err) == GPG_ERR_TRUNCATED)
1299 if (gpg_err_code (err) == GPG_ERR_EOF)
1306 err = gpg_error (GPG_ERR_BUG);
1311 log_error (_("fetch_next_cert failed: %s\n"),
1312 gpg_strerror (err));
1313 end_cert_fetch (fetch_context);
1318 log_debug ("cmd_lookup: returning one cert%s\n",
1319 truncated? " (truncated)":"");
1321 /* Send the data, flush the buffer and then send an END line
1322 as a certificate delimiter. */
1323 err = assuan_send_data (ctx, value, valuelen);
1325 err = assuan_send_data (ctx, NULL, 0);
1327 err = assuan_write_line (ctx, "END");
1330 log_error (_("error sending data: %s\n"), gpg_strerror (err));
1331 end_cert_fetch (fetch_context);
1335 if (++count >= opt.max_replies )
1337 truncation_forced = 1;
1338 log_info (_("max_replies %d exceeded\n"), opt.max_replies );
1344 end_cert_fetch (fetch_context);
1349 if (truncated || truncation_forced)
1353 sprintf (str, "%d", count);
1354 assuan_write_status (ctx, "TRUNCATED", str);
1357 if (!err && !count && !local_count && any_no_data)
1358 err = gpg_error (GPG_ERR_NO_DATA);
1361 free_strlist (list);
1366 static const char hlp_lookup[] =
1367 "LOOKUP [--url] [--single] [--cache-only] <pattern>\n"
1369 "Lookup certificates matching PATTERN. With --url the pattern is\n"
1370 "expected to be one URL.\n"
1372 "If --url is not given: To allow for multiple patterns (which are ORed)\n"
1373 "quoting is required: Spaces are translated to \"+\" or \"%20\";\n"
1374 "obviously this requires that the usual escape quoting rules are applied.\n"
1376 "If --url is given no special escaping is required because URLs are\n"
1377 "already escaped this way.\n"
1379 "If --single is given the first and only the first match will be\n"
1380 "returned. If --cache-only is _not_ given, no local query will be\n"
1383 "If --cache-only is given no external lookup is done so that only\n"
1384 "certificates from the cache may get returned.";
1386 cmd_lookup (assuan_context_t ctx, char *line)
1389 int lookup_url, single, cache_only;
1391 lookup_url = has_leading_option (line, "--url");
1392 single = has_leading_option (line, "--single");
1393 cache_only = has_leading_option (line, "--cache-only");
1394 line = skip_options (line);
1396 if (lookup_url && cache_only)
1397 err = gpg_error (GPG_ERR_NOT_FOUND);
1398 else if (lookup_url && single)
1399 err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1400 else if (lookup_url)
1401 err = lookup_cert_by_url (ctx, line);
1403 err = lookup_cert_by_pattern (ctx, line, single, cache_only);
1405 return leave_cmd (ctx, err);
1409 static const char hlp_loadcrl[] =
1410 "LOADCRL [--url] <filename|url>\n"
1412 "Load the CRL in the file with name FILENAME into our cache. Note\n"
1413 "that FILENAME should be given with an absolute path because\n"
1414 "Dirmngrs cwd is not known. With --url the CRL is directly loaded\n"
1415 "from the given URL.\n"
1417 "This command is usually used by gpgsm using the invocation \"gpgsm\n"
1418 "--call-dirmngr loadcrl <filename>\". A direct invocation of Dirmngr\n"
1419 "is not useful because gpgsm might need to callback gpgsm to ask for\n"
1420 "the CA's certificate.";
1422 cmd_loadcrl (assuan_context_t ctx, char *line)
1424 ctrl_t ctrl = assuan_get_pointer (ctx);
1425 gpg_error_t err = 0;
1426 int use_url = has_leading_option (line, "--url");
1428 line = skip_options (line);
1432 ksba_reader_t reader;
1434 err = crl_fetch (ctrl, line, &reader);
1436 log_error (_("fetching CRL from '%s' failed: %s\n"),
1437 line, gpg_strerror (err));
1440 err = crl_cache_insert (ctrl, line, reader);
1442 log_error (_("processing CRL from '%s' failed: %s\n"),
1443 line, gpg_strerror (err));
1444 crl_close_reader (reader);
1451 buf = xtrymalloc (strlen (line)+1);
1453 err = gpg_error_from_syserror ();
1456 strcpy_escaped_plus (buf, line);
1457 err = crl_cache_load (ctrl, buf);
1462 return leave_cmd (ctx, err);
1466 static const char hlp_listcrls[] =
1469 "List the content of all CRLs in a readable format. This command is\n"
1470 "usually used by gpgsm using the invocation \"gpgsm --call-dirmngr\n"
1471 "listcrls\". It may also be used directly using \"dirmngr\n"
1474 cmd_listcrls (assuan_context_t ctx, char *line)
1481 fp = es_fopencookie (ctx, "w", data_line_cookie_functions);
1483 err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
1486 err = crl_cache_list (fp);
1489 return leave_cmd (ctx, err);
1493 static const char hlp_cachecert[] =
1496 "Put a certificate into the internal cache. This command might be\n"
1497 "useful if a client knows in advance certificates required for a\n"
1498 "test and wants to make sure they get added to the internal cache.\n"
1499 "It is also helpful for debugging. To get the actual certificate,\n"
1500 "this command immediately inquires it using\n"
1502 " INQUIRE TARGETCERT\n"
1504 "and the caller is expected to return the certificate for the\n"
1505 "request as a binary blob.";
1507 cmd_cachecert (assuan_context_t ctx, char *line)
1509 ctrl_t ctrl = assuan_get_pointer (ctx);
1511 ksba_cert_t cert = NULL;
1512 unsigned char *value = NULL;
1517 err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1518 &value, &valuelen, MAX_CERT_LENGTH);
1521 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1525 if (!valuelen) /* No data returned; return a comprehensible error. */
1526 err = gpg_error (GPG_ERR_MISSING_CERT);
1529 err = ksba_cert_new (&cert);
1531 err = ksba_cert_init_from_mem (cert, value, valuelen);
1537 err = cache_cert (cert);
1540 ksba_cert_release (cert);
1541 return leave_cmd (ctx, err);
1545 static const char hlp_validate[] =
1548 "Validate a certificate using the certificate validation function\n"
1549 "used internally by dirmngr. This command is only useful for\n"
1550 "debugging. To get the actual certificate, this command immediately\n"
1551 "inquires it using\n"
1553 " INQUIRE TARGETCERT\n"
1555 "and the caller is expected to return the certificate for the\n"
1556 "request as a binary blob.";
1558 cmd_validate (assuan_context_t ctx, char *line)
1560 ctrl_t ctrl = assuan_get_pointer (ctx);
1562 ksba_cert_t cert = NULL;
1563 unsigned char *value = NULL;
1568 err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1569 &value, &valuelen, MAX_CERT_LENGTH);
1572 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1576 if (!valuelen) /* No data returned; return a comprehensible error. */
1577 err = gpg_error (GPG_ERR_MISSING_CERT);
1580 err = ksba_cert_new (&cert);
1582 err = ksba_cert_init_from_mem (cert, value, valuelen);
1588 /* If we have this certificate already in our cache, use the cached
1589 version for validation because this will take care of any cached
1592 unsigned char fpr[20];
1593 ksba_cert_t tmpcert;
1595 cert_compute_fpr (cert, fpr);
1596 tmpcert = get_cert_byfpr (fpr);
1599 ksba_cert_release (cert);
1604 err = validate_cert_chain (ctrl, cert, NULL, VALIDATE_MODE_CERT, NULL);
1607 ksba_cert_release (cert);
1608 return leave_cmd (ctx, err);
1612 static const char hlp_keyserver[] =
1613 "KEYSERVER [<options>] [<uri>|<host>]\n"
1616 " --clear Remove all configured keyservers\n"
1617 " --resolve Resolve HKP host names and rotate\n"
1618 " --hosttable Print table of known hosts and pools\n"
1619 " --dead Mark <host> as dead\n"
1620 " --alive Mark <host> as alive\n"
1622 "If called without arguments list all configured keyserver URLs.\n"
1623 "If called with an URI add this as keyserver. Note that keyservers\n"
1624 "are configured on a per-session base. A default keyserver may already be\n"
1625 "present, thus the \"--clear\" option must be used to get full control.\n"
1626 "If \"--clear\" and an URI are used together the clear command is\n"
1627 "obviously executed first. A RESET command does not change the list\n"
1628 "of configured keyservers.";
1630 cmd_keyserver (assuan_context_t ctx, char *line)
1632 ctrl_t ctrl = assuan_get_pointer (ctx);
1633 gpg_error_t err = 0;
1634 int clear_flag, add_flag, help_flag, host_flag, resolve_flag;
1635 int dead_flag, alive_flag;
1636 uri_item_t item = NULL; /* gcc 4.4.5 is not able to detect that it
1637 is always initialized. */
1639 clear_flag = has_option (line, "--clear");
1640 help_flag = has_option (line, "--help");
1641 resolve_flag = has_option (line, "--resolve");
1642 host_flag = has_option (line, "--hosttable");
1643 dead_flag = has_option (line, "--dead");
1644 alive_flag = has_option (line, "--alive");
1645 line = skip_options (line);
1650 err = ks_action_help (ctrl, line);
1656 err = ks_action_resolve (ctrl, ctrl->server_local->keyservers);
1661 if (alive_flag && dead_flag)
1663 err = set_error (GPG_ERR_ASS_PARAMETER, "no support for zombies");
1668 err = check_owner_permission (ctx, "no permission to use --dead");
1672 if (alive_flag || dead_flag)
1676 err = set_error (GPG_ERR_ASS_PARAMETER, "name of host missing");
1680 err = ks_hkp_mark_host (ctrl, line, alive_flag);
1687 err = ks_hkp_print_hosttable (ctrl);
1691 if (resolve_flag || host_flag || alive_flag || dead_flag)
1696 item = xtrymalloc (sizeof *item + strlen (line));
1699 err = gpg_error_from_syserror ();
1703 item->parsed_uri = NULL;
1704 strcpy (item->uri, line);
1707 if (ldap_uri_p (item->uri))
1708 err = ldap_parse_uri (&item->parsed_uri, line);
1712 err = http_parse_uri (&item->parsed_uri, line, 1);
1721 release_ctrl_keyservers (ctrl);
1724 item->next = ctrl->server_local->keyservers;
1725 ctrl->server_local->keyservers = item;
1728 if (!add_flag && !clear_flag && !help_flag) /* List configured keyservers. */
1732 for (u=ctrl->server_local->keyservers; u; u = u->next)
1733 dirmngr_status (ctrl, "KEYSERVER", u->uri, NULL);
1738 return leave_cmd (ctx, err);
1743 static const char hlp_ks_search[] =
1744 "KS_SEARCH {<pattern>}\n"
1746 "Search the configured OpenPGP keyservers (see command KEYSERVER)\n"
1747 "for keys matching PATTERN";
1749 cmd_ks_search (assuan_context_t ctx, char *line)
1751 ctrl_t ctrl = assuan_get_pointer (ctx);
1757 /* No options for now. */
1758 line = skip_options (line);
1760 /* Break the line down into an strlist. Each pattern is
1761 percent-plus escaped. */
1763 for (p=line; *p; line = p)
1765 while (*p && *p != ' ')
1771 sl = xtrymalloc (sizeof *sl + strlen (line));
1774 err = gpg_error_from_syserror ();
1778 strcpy_escaped_plus (sl->d, line);
1784 /* Setup an output stream and perform the search. */
1785 outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
1787 err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
1790 err = ks_action_search (ctrl, ctrl->server_local->keyservers,
1796 free_strlist (list);
1797 return leave_cmd (ctx, err);
1802 static const char hlp_ks_get[] =
1803 "KS_GET {<pattern>}\n"
1805 "Get the keys matching PATTERN from the configured OpenPGP keyservers\n"
1806 "(see command KEYSERVER). Each pattern should be a keyid, a fingerprint,\n"
1807 "or an exact name indicated by the '=' prefix.";
1809 cmd_ks_get (assuan_context_t ctx, char *line)
1811 ctrl_t ctrl = assuan_get_pointer (ctx);
1817 /* No options for now. */
1818 line = skip_options (line);
1820 /* Break the line into a strlist. Each pattern is by
1821 definition percent-plus escaped. However we only support keyids
1822 and fingerprints and thus the client has no need to apply the
1825 for (p=line; *p; line = p)
1827 while (*p && *p != ' ')
1833 sl = xtrymalloc (sizeof *sl + strlen (line));
1836 err = gpg_error_from_syserror ();
1840 strcpy_escaped_plus (sl->d, line);
1846 /* Setup an output stream and perform the get. */
1847 outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
1849 err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
1852 err = ks_action_get (ctrl, ctrl->server_local->keyservers, list, outfp);
1857 free_strlist (list);
1858 return leave_cmd (ctx, err);
1862 static const char hlp_ks_fetch[] =
1865 "Get the key(s) from URL.";
1867 cmd_ks_fetch (assuan_context_t ctx, char *line)
1869 ctrl_t ctrl = assuan_get_pointer (ctx);
1873 /* No options for now. */
1874 line = skip_options (line);
1876 /* Setup an output stream and perform the get. */
1877 outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
1879 err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
1882 err = ks_action_fetch (ctrl, line, outfp);
1886 return leave_cmd (ctx, err);
1891 static const char hlp_ks_put[] =
1894 "Send a key to the configured OpenPGP keyservers. The actual key material\n"
1895 "is then requested by Dirmngr using\n"
1897 " INQUIRE KEYBLOCK\n"
1899 "The client shall respond with a binary version of the keyblock (e.g.,\n"
1900 "the output of `gpg --export KEYID'). For LDAP\n"
1901 "keyservers Dirmngr may ask for meta information of the provided keyblock\n"
1904 " INQUIRE KEYBLOCK_INFO\n"
1906 "The client shall respond with a colon delimited info lines (the output\n"
1907 "of 'for x in keys sigs; do gpg --list-$x --with-colons KEYID; done').\n";
1909 cmd_ks_put (assuan_context_t ctx, char *line)
1911 ctrl_t ctrl = assuan_get_pointer (ctx);
1913 unsigned char *value = NULL;
1915 unsigned char *info = NULL;
1918 /* No options for now. */
1919 line = skip_options (line);
1921 /* Ask for the key material. */
1922 err = assuan_inquire (ctx, "KEYBLOCK",
1923 &value, &valuelen, MAX_KEYBLOCK_LENGTH);
1926 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1930 if (!valuelen) /* No data returned; return a comprehensible error. */
1932 err = gpg_error (GPG_ERR_MISSING_CERT);
1936 /* Ask for the key meta data. Not actually needed for HKP servers
1937 but we do it anyway to test the client implementaion. */
1938 err = assuan_inquire (ctx, "KEYBLOCK_INFO",
1939 &info, &infolen, MAX_KEYBLOCK_LENGTH);
1942 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1947 err = ks_action_put (ctrl, ctrl->server_local->keyservers,
1948 value, valuelen, info, infolen);
1953 return leave_cmd (ctx, err);
1959 static const char hlp_getinfo[] =
1962 "Multi purpose command to return certain information. \n"
1963 "Supported values of WHAT are:\n"
1965 "version - Return the version of the program.\n"
1966 "pid - Return the process id of the server.\n"
1968 "socket_name - Return the name of the socket.\n";
1970 cmd_getinfo (assuan_context_t ctx, char *line)
1974 if (!strcmp (line, "version"))
1976 const char *s = VERSION;
1977 err = assuan_send_data (ctx, s, strlen (s));
1979 else if (!strcmp (line, "pid"))
1983 snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
1984 err = assuan_send_data (ctx, numbuf, strlen (numbuf));
1986 else if (!strcmp (line, "socket_name"))
1988 const char *s = dirmngr_user_socket_name ();
1991 s = dirmngr_sys_socket_name ();
1994 err = assuan_send_data (ctx, s, strlen (s));
1996 err = gpg_error (GPG_ERR_NO_DATA);
1999 err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
2001 return leave_cmd (ctx, err);
2006 static const char hlp_killdirmngr[] =
2009 "This command allows a user - given sufficient permissions -\n"
2010 "to kill this dirmngr process.\n";
2012 cmd_killdirmngr (assuan_context_t ctx, char *line)
2014 ctrl_t ctrl = assuan_get_pointer (ctx);
2019 if (opt.system_daemon)
2021 if (opt.system_service)
2022 err = set_error (GPG_ERR_NOT_SUPPORTED,
2023 "can't do that whilst running as system service");
2025 err = check_owner_permission (ctx,
2026 "no permission to kill this process");
2033 ctrl->server_local->stopme = 1;
2034 err = gpg_error (GPG_ERR_EOF);
2040 static const char hlp_reloaddirmngr[] =
2043 "This command is an alternative to SIGHUP\n"
2044 "to reload the configuration.";
2046 cmd_reloaddirmngr (assuan_context_t ctx, char *line)
2051 if (opt.system_daemon)
2053 #ifndef HAVE_W32_SYSTEM
2056 assuan_peercred_t cred;
2058 ec = gpg_err_code (assuan_get_peercred (ctx, &cred));
2059 if (!ec && cred->uid)
2060 ec = GPG_ERR_EPERM; /* Only root may terminate. */
2062 return set_error (ec, "no permission to reload this process");
2067 dirmngr_sighup_action ();
2074 /* Tell the assuan library about our commands. */
2076 register_commands (assuan_context_t ctx)
2080 assuan_handler_t handler;
2081 const char * const help;
2083 { "DNS_CERT", cmd_dns_cert, hlp_dns_cert },
2084 { "LDAPSERVER", cmd_ldapserver, hlp_ldapserver },
2085 { "ISVALID", cmd_isvalid, hlp_isvalid },
2086 { "CHECKCRL", cmd_checkcrl, hlp_checkcrl },
2087 { "CHECKOCSP", cmd_checkocsp, hlp_checkocsp },
2088 { "LOOKUP", cmd_lookup, hlp_lookup },
2089 { "LOADCRL", cmd_loadcrl, hlp_loadcrl },
2090 { "LISTCRLS", cmd_listcrls, hlp_listcrls },
2091 { "CACHECERT", cmd_cachecert, hlp_cachecert },
2092 { "VALIDATE", cmd_validate, hlp_validate },
2093 { "KEYSERVER", cmd_keyserver, hlp_keyserver },
2094 { "KS_SEARCH", cmd_ks_search, hlp_ks_search },
2095 { "KS_GET", cmd_ks_get, hlp_ks_get },
2096 { "KS_FETCH", cmd_ks_fetch, hlp_ks_fetch },
2097 { "KS_PUT", cmd_ks_put, hlp_ks_put },
2098 { "GETINFO", cmd_getinfo, hlp_getinfo },
2099 { "KILLDIRMNGR",cmd_killdirmngr,hlp_killdirmngr },
2100 { "RELOADDIRMNGR",cmd_reloaddirmngr,hlp_reloaddirmngr },
2105 for (i=j=0; table[i].name; i++)
2107 rc = assuan_register_command (ctx, table[i].name, table[i].handler,
2116 /* Note that we do not reset the list of configured keyservers. */
2118 reset_notify (assuan_context_t ctx, char *line)
2120 ctrl_t ctrl = assuan_get_pointer (ctx);
2124 ldapserver_list_free (ctrl->server_local->ldapservers);
2126 ctrl->server_local->ldapservers = NULL;
2131 /* Startup the server and run the main command loop. With FD = -1,
2132 use stdin/stdout. */
2134 start_command_handler (assuan_fd_t fd)
2136 static const char hello[] = "Dirmngr " VERSION " at your service";
2137 static char *hello_line;
2139 assuan_context_t ctx;
2142 ctrl = xtrycalloc (1, sizeof *ctrl);
2144 ctrl->server_local = xtrycalloc (1, sizeof *ctrl->server_local);
2145 if (!ctrl || !ctrl->server_local)
2147 log_error (_("can't allocate control structure: %s\n"),
2153 dirmngr_init_default_ctrl (ctrl);
2155 rc = assuan_new (&ctx);
2158 log_error (_("failed to allocate assuan context: %s\n"),
2163 if (fd == ASSUAN_INVALID_FD)
2165 assuan_fd_t filedes[2];
2167 filedes[0] = assuan_fdopen (0);
2168 filedes[1] = assuan_fdopen (1);
2169 rc = assuan_init_pipe_server (ctx, filedes);
2173 rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED);
2178 assuan_release (ctx);
2179 log_error (_("failed to initialize the server: %s\n"),
2184 rc = register_commands (ctx);
2187 log_error (_("failed to the register commands with Assuan: %s\n"),
2196 const char *cfgname;
2198 cfgname = opt.config_filename? opt.config_filename : "[none]";
2200 n = (30 + strlen (opt.homedir) + strlen (cfgname)
2201 + strlen (hello) + 1);
2202 hello_line = xmalloc (n+1);
2203 snprintf (hello_line, n,
2213 ctrl->server_local->assuan_ctx = ctx;
2214 assuan_set_pointer (ctx, ctrl);
2216 assuan_set_hello_line (ctx, hello_line);
2217 assuan_register_option_handler (ctx, option_handler);
2218 assuan_register_reset_notify (ctx, reset_notify);
2222 rc = assuan_accept (ctx);
2227 log_info (_("Assuan accept problem: %s\n"), gpg_strerror (rc));
2231 #ifndef HAVE_W32_SYSTEM
2234 assuan_peercred_t peercred;
2236 if (!assuan_get_peercred (ctx, &peercred))
2237 log_info ("connection from process %ld (%ld:%ld)\n",
2238 (long)peercred->pid, (long)peercred->uid,
2239 (long)peercred->gid);
2243 rc = assuan_process (ctx);
2246 log_info (_("Assuan processing failed: %s\n"), gpg_strerror (rc));
2252 ldap_wrapper_connection_cleanup (ctrl);
2254 ldapserver_list_free (ctrl->server_local->ldapservers);
2256 ctrl->server_local->ldapservers = NULL;
2258 ctrl->server_local->assuan_ctx = NULL;
2259 assuan_release (ctx);
2261 if (ctrl->server_local->stopme)
2265 log_error ("oops: connection control structure still referenced (%d)\n",
2269 release_ctrl_ocsp_certs (ctrl);
2270 xfree (ctrl->server_local);
2271 dirmngr_deinit_default_ctrl (ctrl);
2277 /* Send a status line back to the client. KEYWORD is the status
2278 keyword, the optional string arguments are blank separated added to
2279 the line, the last argument must be a NULL. */
2281 dirmngr_status (ctrl_t ctrl, const char *keyword, ...)
2283 gpg_error_t err = 0;
2287 va_start (arg_ptr, keyword);
2289 if (ctrl->server_local)
2291 assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2297 while ( (text = va_arg (arg_ptr, const char *)) )
2304 for ( ; *text && n < DIM (buf)-2; n++)
2308 err = assuan_write_status (ctx, keyword, buf);
2316 /* Print a help status line. TEXTLEN gives the length of the text
2317 from TEXT to be printed. The function splits text at LFs. */
2319 dirmngr_status_help (ctrl_t ctrl, const char *text)
2321 gpg_error_t err = 0;
2323 if (ctrl->server_local)
2325 assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2333 for ( ; *text && *text != '\n' && n < DIM (buf)-2; n++)
2338 err = assuan_write_status (ctx, "#", buf);
2340 while (!err && *text);
2346 /* Send a tick progress indicator back. Fixme: This is only done for
2347 the currently active channel. */
2349 dirmngr_tick (ctrl_t ctrl)
2351 static time_t next_tick = 0;
2352 gpg_error_t err = 0;
2353 time_t now = time (NULL);
2357 next_tick = now + 1;
2359 else if ( now > next_tick )
2363 err = dirmngr_status (ctrl, "PROGRESS", "tick", "? 0 0", NULL);
2366 /* Take this as in indication for a cancel request. */
2367 err = gpg_error (GPG_ERR_CANCELED);
2372 next_tick = now + 1;