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>
33 #define JNLIB_NEED_LOG_LOGV
40 # include "ldapserver.h"
43 #include "certcache.h"
47 # include "ldap-wrapper.h"
49 #include "ks-action.h"
50 #include "ks-engine.h" /* (ks_hkp_print_hosttable) */
51 #include "ldap-parse-uri.h"
53 /* To avoid DoS attacks we limit the size of a certificate to
54 something reasonable. */
55 #define MAX_CERT_LENGTH (8*1024)
57 /* The same goes for OpenPGP keyblocks, but here we need to allow for
58 much longer blocks; a 200k keyblock is not too unusual for keys
59 with a lot of signatures (e.g. 0x5b0358a2). */
60 #define MAX_KEYBLOCK_LENGTH (512*1024)
63 #define PARM_ERROR(t) assuan_set_error (ctx, \
64 gpg_error (GPG_ERR_ASS_PARAMETER), (t))
65 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
69 /* Control structure per connection. */
72 /* Data used to associate an Assuan context with local server data */
73 assuan_context_t assuan_ctx;
75 /* Per-session LDAP servers. */
76 ldap_server_t ldapservers;
78 /* Per-session list of keyservers. */
79 uri_item_t keyservers;
81 /* If this flag is set to true this dirmngr process will be
82 terminated after the end of this session. */
87 /* Cookie definition for assuan data line output. */
88 static ssize_t data_line_cookie_write (void *cookie,
89 const void *buffer, size_t size);
90 static int data_line_cookie_close (void *cookie);
91 static es_cookie_io_functions_t data_line_cookie_functions =
94 data_line_cookie_write,
96 data_line_cookie_close
103 /* Accessor for the local ldapservers variable. */
105 get_ldapservers_from_ctrl (ctrl_t ctrl)
107 if (ctrl && ctrl->server_local)
108 return ctrl->server_local->ldapservers;
114 /* Release all configured keyserver info from CTRL. */
116 release_ctrl_keyservers (ctrl_t ctrl)
118 if (! ctrl->server_local)
121 while (ctrl->server_local->keyservers)
123 uri_item_t tmp = ctrl->server_local->keyservers->next;
124 http_release_parsed_uri (ctrl->server_local->keyservers->parsed_uri);
125 xfree (ctrl->server_local->keyservers);
126 ctrl->server_local->keyservers = tmp;
132 /* Helper to print a message while leaving a command. */
134 leave_cmd (assuan_context_t ctx, gpg_error_t err)
138 const char *name = assuan_get_command_name (ctx);
141 if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT)
142 log_error ("command '%s' failed: %s\n", name,
145 log_error ("command '%s' failed: %s <%s>\n", name,
146 gpg_strerror (err), gpg_strsource (err));
151 /* A write handler used by es_fopencookie to write assuan data
154 data_line_cookie_write (void *cookie, const void *buffer_arg, size_t size)
156 assuan_context_t ctx = cookie;
157 const char *buffer = buffer_arg;
159 if (opt.verbose && buffer && size)
161 /* Ease reading of output by sending a physical line at each LF. */
168 p = memchr (buffer, '\n', nbytes);
169 n = p ? (p - buffer) + 1 : nbytes;
170 if (assuan_send_data (ctx, buffer, n))
172 gpg_err_set_errno (EIO);
177 if (nbytes && assuan_send_data (ctx, NULL, 0)) /* Flush line. */
179 gpg_err_set_errno (EIO);
187 if (assuan_send_data (ctx, buffer, size))
189 gpg_err_set_errno (EIO);
198 data_line_cookie_close (void *cookie)
200 assuan_context_t ctx = cookie;
202 if (assuan_send_data (ctx, NULL, 0))
204 gpg_err_set_errno (EIO);
212 /* Copy the % and + escaped string S into the buffer D and replace the
213 escape sequences. Note, that it is sufficient to allocate the
214 target string D as long as the source string S, i.e.: strlen(s)+1.
215 Note further that if S contains an escaped binary Nul the resulting
216 string D will contain the 0 as well as all other characters but it
217 will be impossible to know whether this is the original EOS or a
220 strcpy_escaped_plus (char *d, const unsigned char *s)
224 if (*s == '%' && s[1] && s[2])
239 /* Check whether the option NAME appears in LINE */
241 has_option (const char *line, const char *name)
244 int n = strlen (name);
246 s = strstr (line, name);
247 return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
250 /* Same as has_option but only considers options at the begin of the
251 line. This is useful for commands which allow arbitrary strings on
254 has_leading_option (const char *line, const char *name)
259 if (name[0] != '-' || name[1] != '-' || !name[2] || spacep (name+2))
262 while ( *line == '-' && line[1] == '-' )
265 while (*line && !spacep (line))
267 if (n == (line - s) && !strncmp (s, name, n))
269 while (spacep (line))
276 /* Same as has_option but does only test for the name of the option
277 and ignores an argument, i.e. with NAME being "--hash" it would
278 return a pointer for "--hash" as well as for "--hash=foo". If
279 thhere is no such option NULL is returned. The pointer returned
280 points right behind the option name, this may be an equal sign, Nul
282 /* static const char * */
283 /* has_option_name (const char *line, const char *name) */
286 /* int n = strlen (name); */
288 /* s = strstr (line, name); */
289 /* return (s && (s == line || spacep (s-1)) */
290 /* && (!s[n] || spacep (s+n) || s[n] == '=')) ? (s+n) : NULL; */
294 /* Skip over options. It is assumed that leading spaces have been
295 removed (this is the case for lines passed to a handler from
296 assuan). Blanks after the options are also removed. */
298 skip_options (char *line)
300 while ( *line == '-' && line[1] == '-' )
302 while (*line && !spacep (line))
304 while (spacep (line))
311 /* Return an error if the assuan context does not belong to the owner
312 of the process or to root. On error FAILTEXT is set as Assuan
315 check_owner_permission (assuan_context_t ctx, const char *failtext)
317 #ifdef HAVE_W32_SYSTEM
318 /* Under Windows the dirmngr is always run under the control of the
324 assuan_peercred_t cred;
326 ec = gpg_err_code (assuan_get_peercred (ctx, &cred));
327 if (!ec && cred->uid && cred->uid != getuid ())
330 return set_error (ec, failtext);
337 /* Common code for get_cert_local and get_issuer_cert_local. */
339 do_get_cert_local (ctrl_t ctrl, const char *name, const char *command)
341 unsigned char *value;
349 buf = xmalloc ( strlen (command) + 1 + strlen(name) + 1);
350 strcpy (stpcpy (stpcpy (buf, command), " "), name);
353 buf = xstrdup (command);
355 rc = assuan_inquire (ctrl->server_local->assuan_ctx, buf,
356 &value, &valuelen, MAX_CERT_LENGTH);
360 log_error (_("assuan_inquire(%s) failed: %s\n"),
361 command, gpg_strerror (rc));
371 rc = ksba_cert_new (&cert);
374 rc = ksba_cert_init_from_mem (cert, value, valuelen);
377 ksba_cert_release (cert);
387 /* Ask back to return a certificate for name, given as a regular
388 gpgsm certificate indentificates (e.g. fingerprint or one of the
389 other methods). Alternatively, NULL may be used for NAME to
390 return the current target certificate. Either return the certificate
391 in a KSBA object or NULL if it is not available.
394 get_cert_local (ctrl_t ctrl, const char *name)
396 if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
399 log_debug ("get_cert_local called w/o context\n");
402 return do_get_cert_local (ctrl, name, "SENDCERT");
406 /* Ask back to return the issuing certificate for name, given as a
407 regular gpgsm certificate indentificates (e.g. fingerprint or one
408 of the other methods). Alternatively, NULL may be used for NAME to
409 return thecurrent target certificate. Either return the certificate
410 in a KSBA object or NULL if it is not available.
414 get_issuing_cert_local (ctrl_t ctrl, const char *name)
416 if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
419 log_debug ("get_issuing_cert_local called w/o context\n");
422 return do_get_cert_local (ctrl, name, "SENDISSUERCERT");
425 /* Ask back to return a certificate with subject NAME and a
426 subjectKeyIdentifier of KEYID. */
428 get_cert_local_ski (ctrl_t ctrl, const char *name, ksba_sexp_t keyid)
430 unsigned char *value;
437 if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
440 log_debug ("get_cert_local_ski called w/o context\n");
445 log_debug ("get_cert_local_ski called with insufficient arguments\n");
449 hexkeyid = serial_hex (keyid);
452 log_debug ("serial_hex() failed\n");
456 buf = xtrymalloc (15 + strlen (hexkeyid) + 2 + strlen(name) + 1);
460 log_error ("can't allocate enough memory: %s\n", strerror (errno));
464 strcpy (stpcpy (stpcpy (stpcpy (buf, "SENDCERT_SKI "), hexkeyid)," /"),name);
467 rc = assuan_inquire (ctrl->server_local->assuan_ctx, buf,
468 &value, &valuelen, MAX_CERT_LENGTH);
472 log_error (_("assuan_inquire(%s) failed: %s\n"), "SENDCERT_SKI",
483 rc = ksba_cert_new (&cert);
486 rc = ksba_cert_init_from_mem (cert, value, valuelen);
489 ksba_cert_release (cert);
498 /* Ask the client via an inquiry to check the istrusted status of the
499 certificate specified by the hexified fingerprint HEXFPR. Returns
500 0 if the certificate is trusted by the client or an error code. */
502 get_istrusted_from_client (ctrl_t ctrl, const char *hexfpr)
504 unsigned char *value;
509 if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx
511 return gpg_error (GPG_ERR_INV_ARG);
513 snprintf (request, sizeof request, "ISTRUSTED %s", hexfpr);
514 rc = assuan_inquire (ctrl->server_local->assuan_ctx, request,
515 &value, &valuelen, 100);
518 log_error (_("assuan_inquire(%s) failed: %s\n"),
519 request, gpg_strerror (rc));
522 /* The expected data is: "1" or "1 cruft" (not a C-string). */
523 if (valuelen && *value == '1' && (valuelen == 1 || spacep (value+1)))
526 rc = gpg_error (GPG_ERR_NOT_TRUSTED);
534 /* Ask the client to return the certificate associated with the
535 current command. This is sometimes needed because the client usually
536 sends us just the cert ID, assuming that the request can be
537 satisfied from the cache, where the cert ID is used as key. */
539 inquire_cert_and_load_crl (assuan_context_t ctx)
541 ctrl_t ctrl = assuan_get_pointer (ctx);
543 unsigned char *value = NULL;
545 ksba_cert_t cert = NULL;
547 err = assuan_inquire( ctx, "SENDCERT", &value, &valuelen, 0);
552 /* FILE *fp = fopen ("foo.der", "r"); */
553 /* value = xmalloc (2000); */
554 /* valuelen = fread (value, 1, 2000, fp); */
558 if (!valuelen) /* No data returned; return a comprehensible error. */
559 return gpg_error (GPG_ERR_MISSING_CERT);
561 err = ksba_cert_new (&cert);
564 err = ksba_cert_init_from_mem (cert, value, valuelen);
567 xfree (value); value = NULL;
569 err = crl_cache_reload_crl (ctrl, cert);
572 ksba_cert_release (cert);
578 /* Handle OPTION commands. */
580 option_handler (assuan_context_t ctx, const char *key, const char *value)
582 ctrl_t ctrl = assuan_get_pointer (ctx);
584 if (!strcmp (key, "force-crl-refresh"))
586 int i = *value? atoi (value) : 0;
587 ctrl->force_crl_refresh = i;
589 else if (!strcmp (key, "audit-events"))
591 int i = *value? atoi (value) : 0;
592 ctrl->audit_events = i;
595 return gpg_error (GPG_ERR_UNKNOWN_OPTION);
600 static const char hlp_ldapserver[] =
601 "LDAPSERVER <data>\n"
603 "Add a new LDAP server to the list of configured LDAP servers.\n"
604 "DATA is in the same format as expected in the configure file.";
606 cmd_ldapserver (assuan_context_t ctx, char *line)
609 ctrl_t ctrl = assuan_get_pointer (ctx);
610 ldap_server_t server;
611 ldap_server_t *last_next_p;
613 while (spacep (line))
616 return leave_cmd (ctx, PARM_ERROR (_("ldapserver missing")));
618 server = ldapserver_parse_one (line, "", 0);
620 return leave_cmd (ctx, gpg_error (GPG_ERR_INV_ARG));
622 last_next_p = &ctrl->server_local->ldapservers;
624 last_next_p = &(*last_next_p)->next;
625 *last_next_p = server;
626 return leave_cmd (ctx, 0);
629 return leave_cmd (ctx, gpg_error (GPG_ERR_NOT_IMPLEMENTED));
634 static const char hlp_isvalid[] =
635 "ISVALID [--only-ocsp] [--force-default-responder]"
636 " <certificate_id>|<certificate_fpr>\n"
638 "This command checks whether the certificate identified by the\n"
639 "certificate_id is valid. This is done by consulting CRLs or\n"
640 "whatever has been configured. Note, that the returned error codes\n"
641 "are from gpg-error.h. The command may callback using the inquire\n"
642 "function. See the manual for details.\n"
644 "The CERTIFICATE_ID is a hex encoded string consisting of two parts,\n"
645 "delimited by a single dot. The first part is the SHA-1 hash of the\n"
646 "issuer name and the second part the serial number.\n"
648 "Alternatively the certificate's fingerprint may be given in which\n"
649 "case an OCSP request is done before consulting the CRL.\n"
651 "If the option --only-ocsp is given, no fallback to a CRL check will\n"
654 "If the option --force-default-responder is given, only the default\n"
655 "OCSP responder will be used and any other methods of obtaining an\n"
656 "OCSP responder URL won't be used.";
658 cmd_isvalid (assuan_context_t ctx, char *line)
660 ctrl_t ctrl = assuan_get_pointer (ctx);
661 char *issuerhash, *serialno;
666 int force_default_responder;
668 only_ocsp = has_option (line, "--only-ocsp");
669 force_default_responder = has_option (line, "--force-default-responder");
670 line = skip_options (line);
672 issuerhash = xstrdup (line); /* We need to work on a copy of the
673 line because that same Assuan
674 context may be used for an inquiry.
675 That is because Assuan reuses its
679 serialno = strchr (issuerhash, '.');
684 char *endp = strchr (issuerhash, ' ');
687 if (strlen (issuerhash) != 40)
690 return leave_cmd (ctx, PARM_ERROR (_("serialno missing in cert ID")));
699 /* Note, that we ignore the given issuer hash and instead rely
700 on the current certificate semantics used with this
703 err = gpg_error (GPG_ERR_NOT_SUPPORTED);
705 err = ocsp_isvalid (ctrl, NULL, NULL, force_default_responder);
706 /* Fixme: If we got no ocsp response and --only-ocsp is not used
707 we should fall back to CRL mode. Thus we need to clear
708 OCSP_MODE, get the issuerhash and the serialno from the
709 current certificate and jump to again. */
712 err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
715 switch (crl_cache_isvalid (ctrl,
716 issuerhash, serialno,
717 ctrl->force_crl_refresh))
719 case CRL_CACHE_VALID:
722 case CRL_CACHE_INVALID:
723 err = gpg_error (GPG_ERR_CERT_REVOKED);
725 case CRL_CACHE_DONTKNOW:
727 err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
728 else if (!(err = inquire_cert_and_load_crl (ctx)))
734 case CRL_CACHE_CANTUSE:
735 err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
738 log_fatal ("crl_cache_isvalid returned invalid code\n");
743 return leave_cmd (ctx, err);
747 /* If the line contains a SHA-1 fingerprint as the first argument,
748 return the FPR vuffer on success. The function checks that the
749 fingerprint consists of valid characters and prints and error
750 message if it does not and returns NULL. Fingerprints are
751 considered optional and thus no explicit error is returned. NULL is
752 also returned if there is no fingerprint at all available.
753 FPR must be a caller provided buffer of at least 20 bytes.
755 Note that colons within the fingerprint are allowed to separate 2
756 hex digits; this allows for easier cutting and pasting using the
757 usual fingerprint rendering.
759 static unsigned char *
760 get_fingerprint_from_line (const char *line, unsigned char *fpr)
765 for (s=line, i=0; *s && *s != ' '; s++ )
767 if ( hexdigitp (s) && hexdigitp (s+1) )
770 return NULL; /* Fingerprint too long. */
771 fpr[i++] = xtoi_2 (s);
774 else if ( *s != ':' )
775 return NULL; /* Invalid. */
778 return NULL; /* Fingerprint to short. */
784 static const char hlp_checkcrl[] =
785 "CHECKCRL [<fingerprint>]\n"
787 "Check whether the certificate with FINGERPRINT (SHA-1 hash of the\n"
788 "entire X.509 certificate blob) is valid or not by consulting the\n"
789 "CRL responsible for this certificate. If the fingerprint has not\n"
790 "been given or the certificate is not known, the function \n"
791 "inquires the certificate using an\n"
793 " INQUIRE TARGETCERT\n"
795 "and the caller is expected to return the certificate for the\n"
796 "request (which should match FINGERPRINT) as a binary blob.\n"
797 "Processing then takes place without further interaction; in\n"
798 "particular dirmngr tries to locate other required certificate by\n"
799 "its own mechanism which includes a local certificate store as well\n"
800 "as a list of trusted root certificates.\n"
802 "The return value is the usual gpg-error code or 0 for ducesss;\n"
803 "i.e. the certificate validity has been confirmed by a valid CRL.";
805 cmd_checkcrl (assuan_context_t ctx, char *line)
807 ctrl_t ctrl = assuan_get_pointer (ctx);
809 unsigned char fprbuffer[20], *fpr;
812 fpr = get_fingerprint_from_line (line, fprbuffer);
813 cert = fpr? get_cert_byfpr (fpr) : NULL;
817 /* We do not have this certificate yet or the fingerprint has
818 not been given. Inquire it from the client. */
819 unsigned char *value = NULL;
822 err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
823 &value, &valuelen, MAX_CERT_LENGTH);
826 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
830 if (!valuelen) /* No data returned; return a comprehensible error. */
831 err = gpg_error (GPG_ERR_MISSING_CERT);
834 err = ksba_cert_new (&cert);
836 err = ksba_cert_init_from_mem (cert, value, valuelen);
845 err = crl_cache_cert_isvalid (ctrl, cert, ctrl->force_crl_refresh);
846 if (gpg_err_code (err) == GPG_ERR_NO_CRL_KNOWN)
848 err = crl_cache_reload_crl (ctrl, cert);
850 err = crl_cache_cert_isvalid (ctrl, cert, 0);
854 ksba_cert_release (cert);
855 return leave_cmd (ctx, err);
859 static const char hlp_checkocsp[] =
860 "CHECKOCSP [--force-default-responder] [<fingerprint>]\n"
862 "Check whether the certificate with FINGERPRINT (SHA-1 hash of the\n"
863 "entire X.509 certificate blob) is valid or not by asking an OCSP\n"
864 "responder responsible for this certificate. The optional\n"
865 "fingerprint may be used for a quick check in case an OCSP check has\n"
866 "been done for this certificate recently (we always cache OCSP\n"
867 "responses for a couple of minutes). If the fingerprint has not been\n"
868 "given or there is no cached result, the function inquires the\n"
869 "certificate using an\n"
871 " INQUIRE TARGETCERT\n"
873 "and the caller is expected to return the certificate for the\n"
874 "request (which should match FINGERPRINT) as a binary blob.\n"
875 "Processing then takes place without further interaction; in\n"
876 "particular dirmngr tries to locate other required certificates by\n"
877 "its own mechanism which includes a local certificate store as well\n"
878 "as a list of trusted root certifciates.\n"
880 "If the option --force-default-responder is given, only the default\n"
881 "OCSP responder will be used and any other methods of obtaining an\n"
882 "OCSP responder URL won't be used.\n"
884 "The return value is the usual gpg-error code or 0 for ducesss;\n"
885 "i.e. the certificate validity has been confirmed by a valid CRL.";
887 cmd_checkocsp (assuan_context_t ctx, char *line)
889 ctrl_t ctrl = assuan_get_pointer (ctx);
891 unsigned char fprbuffer[20], *fpr;
893 int force_default_responder;
895 force_default_responder = has_option (line, "--force-default-responder");
896 line = skip_options (line);
898 fpr = get_fingerprint_from_line (line, fprbuffer);
899 cert = fpr? get_cert_byfpr (fpr) : NULL;
903 /* We do not have this certificate yet or the fingerprint has
904 not been given. Inquire it from the client. */
905 unsigned char *value = NULL;
908 err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
909 &value, &valuelen, MAX_CERT_LENGTH);
912 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
916 if (!valuelen) /* No data returned; return a comprehensible error. */
917 err = gpg_error (GPG_ERR_MISSING_CERT);
920 err = ksba_cert_new (&cert);
922 err = ksba_cert_init_from_mem (cert, value, valuelen);
932 err = gpg_error (GPG_ERR_NOT_SUPPORTED);
934 err = ocsp_isvalid (ctrl, cert, NULL, force_default_responder);
937 ksba_cert_release (cert);
938 return leave_cmd (ctx, err);
944 lookup_cert_by_url (assuan_context_t ctx, const char *url)
946 ctrl_t ctrl = assuan_get_pointer (ctx);
948 unsigned char *value = NULL;
951 /* Fetch single certificate given it's URL. */
952 err = fetch_cert_by_url (ctrl, url, &value, &valuelen);
955 log_error (_("fetch_cert_by_url failed: %s\n"), gpg_strerror (err));
959 /* Send the data, flush the buffer and then send an END. */
960 err = assuan_send_data (ctx, value, valuelen);
962 err = assuan_send_data (ctx, NULL, 0);
964 err = assuan_write_line (ctx, "END");
967 log_error (_("error sending data: %s\n"), gpg_strerror (err));
977 /* Send the certificate, flush the buffer and then send an END. */
979 return_one_cert (void *opaque, ksba_cert_t cert)
981 assuan_context_t ctx = opaque;
983 const unsigned char *der;
986 der = ksba_cert_get_image (cert, &derlen);
988 err = gpg_error (GPG_ERR_INV_CERT_OBJ);
991 err = assuan_send_data (ctx, der, derlen);
993 err = assuan_send_data (ctx, NULL, 0);
995 err = assuan_write_line (ctx, "END");
998 log_error (_("error sending data: %s\n"), gpg_strerror (err));
1003 /* Lookup certificates from the internal cache or using the ldap
1006 lookup_cert_by_pattern (assuan_context_t ctx, char *line,
1007 int single, int cache_only)
1009 gpg_error_t err = 0;
1011 strlist_t sl, list = NULL;
1012 int truncated = 0, truncation_forced = 0;
1014 int local_count = 0;
1016 ctrl_t ctrl = assuan_get_pointer (ctx);
1017 unsigned char *value = NULL;
1019 struct ldapserver_iter ldapserver_iter;
1020 cert_fetch_context_t fetch_context;
1022 int any_no_data = 0;
1024 /* Break the line down into an STRLIST */
1025 for (p=line; *p; line = p)
1027 while (*p && *p != ' ')
1034 sl = xtrymalloc (sizeof *sl + strlen (line));
1037 err = gpg_error_from_errno (errno);
1040 memset (sl, 0, sizeof *sl);
1041 strcpy_escaped_plus (sl->d, line);
1047 /* First look through the internal cache. The certifcates retruned
1048 here are not counted towards the truncation limit. */
1049 if (single && !cache_only)
1050 ; /* Do not read from the local cache in this case. */
1053 for (sl=list; sl; sl = sl->next)
1055 err = get_certs_bypattern (sl->d, return_one_cert, ctx);
1061 if (gpg_err_code (err) == GPG_ERR_NO_DATA)
1067 else if (gpg_err_code (err) == GPG_ERR_INV_NAME && !cache_only)
1069 /* No real fault because the internal pattern lookup
1070 can't yet cope with all types of pattern. */
1078 /* Loop over all configured servers unless we want only the
1079 certificates from the cache. */
1081 for (ldapserver_iter_begin (&ldapserver_iter, ctrl);
1082 !cache_only && !ldapserver_iter_end_p (&ldapserver_iter)
1083 && ldapserver_iter.server->host && !truncation_forced;
1084 ldapserver_iter_next (&ldapserver_iter))
1086 ldap_server_t ldapserver = ldapserver_iter.server;
1089 log_debug ("cmd_lookup: trying %s:%d base=%s\n",
1090 ldapserver->host, ldapserver->port,
1091 ldapserver->base?ldapserver->base : "[default]");
1093 /* Fetch certificates matching pattern */
1094 err = start_cert_fetch (ctrl, &fetch_context, list, ldapserver);
1095 if ( gpg_err_code (err) == GPG_ERR_NO_DATA )
1098 log_debug ("cmd_lookup: no data\n");
1105 log_error (_("start_cert_fetch failed: %s\n"), gpg_strerror (err));
1109 /* Fetch the certificates for this query. */
1110 while (!truncation_forced)
1112 xfree (value); value = NULL;
1113 err = fetch_next_cert (fetch_context, &value, &valuelen);
1114 if (gpg_err_code (err) == GPG_ERR_NO_DATA )
1120 if (gpg_err_code (err) == GPG_ERR_TRUNCATED)
1126 if (gpg_err_code (err) == GPG_ERR_EOF)
1133 err = gpg_error (GPG_ERR_BUG);
1138 log_error (_("fetch_next_cert failed: %s\n"),
1139 gpg_strerror (err));
1140 end_cert_fetch (fetch_context);
1145 log_debug ("cmd_lookup: returning one cert%s\n",
1146 truncated? " (truncated)":"");
1148 /* Send the data, flush the buffer and then send an END line
1149 as a certificate delimiter. */
1150 err = assuan_send_data (ctx, value, valuelen);
1152 err = assuan_send_data (ctx, NULL, 0);
1154 err = assuan_write_line (ctx, "END");
1157 log_error (_("error sending data: %s\n"), gpg_strerror (err));
1158 end_cert_fetch (fetch_context);
1162 if (++count >= opt.max_replies )
1164 truncation_forced = 1;
1165 log_info (_("max_replies %d exceeded\n"), opt.max_replies );
1171 end_cert_fetch (fetch_context);
1176 if (truncated || truncation_forced)
1180 sprintf (str, "%d", count);
1181 assuan_write_status (ctx, "TRUNCATED", str);
1184 if (!err && !count && !local_count && any_no_data)
1185 err = gpg_error (GPG_ERR_NO_DATA);
1188 free_strlist (list);
1193 static const char hlp_lookup[] =
1194 "LOOKUP [--url] [--single] [--cache-only] <pattern>\n"
1196 "Lookup certificates matching PATTERN. With --url the pattern is\n"
1197 "expected to be one URL.\n"
1199 "If --url is not given: To allow for multiple patterns (which are ORed)\n"
1200 "quoting is required: Spaces are translated to \"+\" or \"%20\";\n"
1201 "obviously this requires that the usual escape quoting rules are applied.\n"
1203 "If --url is given no special escaping is required because URLs are\n"
1204 "already escaped this way.\n"
1206 "If --single is given the first and only the first match will be\n"
1207 "returned. If --cache-only is _not_ given, no local query will be\n"
1210 "If --cache-only is given no external lookup is done so that only\n"
1211 "certificates from the cache may get returned.";
1213 cmd_lookup (assuan_context_t ctx, char *line)
1216 int lookup_url, single, cache_only;
1218 lookup_url = has_leading_option (line, "--url");
1219 single = has_leading_option (line, "--single");
1220 cache_only = has_leading_option (line, "--cache-only");
1221 line = skip_options (line);
1223 if (lookup_url && cache_only)
1224 err = gpg_error (GPG_ERR_NOT_FOUND);
1225 else if (lookup_url && single)
1226 err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1227 else if (lookup_url)
1228 err = lookup_cert_by_url (ctx, line);
1230 err = lookup_cert_by_pattern (ctx, line, single, cache_only);
1232 return leave_cmd (ctx, err);
1236 static const char hlp_loadcrl[] =
1237 "LOADCRL [--url] <filename|url>\n"
1239 "Load the CRL in the file with name FILENAME into our cache. Note\n"
1240 "that FILENAME should be given with an absolute path because\n"
1241 "Dirmngrs cwd is not known. With --url the CRL is directly loaded\n"
1242 "from the given URL.\n"
1244 "This command is usually used by gpgsm using the invocation \"gpgsm\n"
1245 "--call-dirmngr loadcrl <filename>\". A direct invocation of Dirmngr\n"
1246 "is not useful because gpgsm might need to callback gpgsm to ask for\n"
1247 "the CA's certificate.";
1249 cmd_loadcrl (assuan_context_t ctx, char *line)
1251 ctrl_t ctrl = assuan_get_pointer (ctx);
1252 gpg_error_t err = 0;
1253 int use_url = has_leading_option (line, "--url");
1255 line = skip_options (line);
1259 ksba_reader_t reader;
1261 err = crl_fetch (ctrl, line, &reader);
1263 log_error (_("fetching CRL from '%s' failed: %s\n"),
1264 line, gpg_strerror (err));
1267 err = crl_cache_insert (ctrl, line, reader);
1269 log_error (_("processing CRL from '%s' failed: %s\n"),
1270 line, gpg_strerror (err));
1271 crl_close_reader (reader);
1278 buf = xtrymalloc (strlen (line)+1);
1280 err = gpg_error_from_syserror ();
1283 strcpy_escaped_plus (buf, line);
1284 err = crl_cache_load (ctrl, buf);
1289 return leave_cmd (ctx, err);
1293 static const char hlp_listcrls[] =
1296 "List the content of all CRLs in a readable format. This command is\n"
1297 "usually used by gpgsm using the invocation \"gpgsm --call-dirmngr\n"
1298 "listcrls\". It may also be used directly using \"dirmngr\n"
1301 cmd_listcrls (assuan_context_t ctx, char *line)
1308 fp = es_fopencookie (ctx, "w", data_line_cookie_functions);
1310 err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
1313 err = crl_cache_list (fp);
1316 return leave_cmd (ctx, err);
1320 static const char hlp_cachecert[] =
1323 "Put a certificate into the internal cache. This command might be\n"
1324 "useful if a client knows in advance certificates required for a\n"
1325 "test and wants to make sure they get added to the internal cache.\n"
1326 "It is also helpful for debugging. To get the actual certificate,\n"
1327 "this command immediately inquires it using\n"
1329 " INQUIRE TARGETCERT\n"
1331 "and the caller is expected to return the certificate for the\n"
1332 "request as a binary blob.";
1334 cmd_cachecert (assuan_context_t ctx, char *line)
1336 ctrl_t ctrl = assuan_get_pointer (ctx);
1338 ksba_cert_t cert = NULL;
1339 unsigned char *value = NULL;
1344 err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1345 &value, &valuelen, MAX_CERT_LENGTH);
1348 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1352 if (!valuelen) /* No data returned; return a comprehensible error. */
1353 err = gpg_error (GPG_ERR_MISSING_CERT);
1356 err = ksba_cert_new (&cert);
1358 err = ksba_cert_init_from_mem (cert, value, valuelen);
1364 err = cache_cert (cert);
1367 ksba_cert_release (cert);
1368 return leave_cmd (ctx, err);
1372 static const char hlp_validate[] =
1375 "Validate a certificate using the certificate validation function\n"
1376 "used internally by dirmngr. This command is only useful for\n"
1377 "debugging. To get the actual certificate, this command immediately\n"
1378 "inquires it using\n"
1380 " INQUIRE TARGETCERT\n"
1382 "and the caller is expected to return the certificate for the\n"
1383 "request as a binary blob.";
1385 cmd_validate (assuan_context_t ctx, char *line)
1387 ctrl_t ctrl = assuan_get_pointer (ctx);
1389 ksba_cert_t cert = NULL;
1390 unsigned char *value = NULL;
1395 err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1396 &value, &valuelen, MAX_CERT_LENGTH);
1399 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1403 if (!valuelen) /* No data returned; return a comprehensible error. */
1404 err = gpg_error (GPG_ERR_MISSING_CERT);
1407 err = ksba_cert_new (&cert);
1409 err = ksba_cert_init_from_mem (cert, value, valuelen);
1415 /* If we have this certificate already in our cache, use the cached
1416 version for validation because this will take care of any cached
1419 unsigned char fpr[20];
1420 ksba_cert_t tmpcert;
1422 cert_compute_fpr (cert, fpr);
1423 tmpcert = get_cert_byfpr (fpr);
1426 ksba_cert_release (cert);
1431 err = validate_cert_chain (ctrl, cert, NULL, VALIDATE_MODE_CERT, NULL);
1434 ksba_cert_release (cert);
1435 return leave_cmd (ctx, err);
1439 static const char hlp_keyserver[] =
1440 "KEYSERVER [<options>] [<uri>|<host>]\n"
1443 " --clear Remove all configured keyservers\n"
1444 " --resolve Resolve HKP host names and rotate\n"
1445 " --hosttable Print table of known hosts and pools\n"
1446 " --dead Mark <host> as dead\n"
1447 " --alive Mark <host> as alive\n"
1449 "If called without arguments list all configured keyserver URLs.\n"
1450 "If called with an URI add this as keyserver. Note that keyservers\n"
1451 "are configured on a per-session base. A default keyserver may already be\n"
1452 "present, thus the \"--clear\" option must be used to get full control.\n"
1453 "If \"--clear\" and an URI are used together the clear command is\n"
1454 "obviously executed first. A RESET command does not change the list\n"
1455 "of configured keyservers.";
1457 cmd_keyserver (assuan_context_t ctx, char *line)
1459 ctrl_t ctrl = assuan_get_pointer (ctx);
1460 gpg_error_t err = 0;
1461 int clear_flag, add_flag, help_flag, host_flag, resolve_flag;
1462 int dead_flag, alive_flag;
1463 uri_item_t item = NULL; /* gcc 4.4.5 is not able to detect that it
1464 is always initialized. */
1466 clear_flag = has_option (line, "--clear");
1467 help_flag = has_option (line, "--help");
1468 resolve_flag = has_option (line, "--resolve");
1469 host_flag = has_option (line, "--hosttable");
1470 dead_flag = has_option (line, "--dead");
1471 alive_flag = has_option (line, "--alive");
1472 line = skip_options (line);
1477 err = ks_action_help (ctrl, line);
1483 err = ks_action_resolve (ctrl, ctrl->server_local->keyservers);
1488 if (alive_flag && dead_flag)
1490 err = set_error (GPG_ERR_ASS_PARAMETER, "no support for zombies");
1495 err = check_owner_permission (ctx, "no permission to use --dead");
1499 if (alive_flag || dead_flag)
1503 err = set_error (GPG_ERR_ASS_PARAMETER, "name of host missing");
1507 err = ks_hkp_mark_host (ctrl, line, alive_flag);
1514 err = ks_hkp_print_hosttable (ctrl);
1518 if (resolve_flag || host_flag || alive_flag || dead_flag)
1523 item = xtrymalloc (sizeof *item + strlen (line));
1526 err = gpg_error_from_syserror ();
1530 item->parsed_uri = NULL;
1531 strcpy (item->uri, line);
1533 if (ldap_uri_p (item->uri))
1534 err = ldap_parse_uri (&item->parsed_uri, line);
1536 err = http_parse_uri (&item->parsed_uri, line, 1);
1544 release_ctrl_keyservers (ctrl);
1547 item->next = ctrl->server_local->keyservers;
1548 ctrl->server_local->keyservers = item;
1551 if (!add_flag && !clear_flag && !help_flag) /* List configured keyservers. */
1555 for (u=ctrl->server_local->keyservers; u; u = u->next)
1556 dirmngr_status (ctrl, "KEYSERVER", u->uri, NULL);
1561 return leave_cmd (ctx, err);
1566 static const char hlp_ks_search[] =
1567 "KS_SEARCH {<pattern>}\n"
1569 "Search the configured OpenPGP keyservers (see command KEYSERVER)\n"
1570 "for keys matching PATTERN";
1572 cmd_ks_search (assuan_context_t ctx, char *line)
1574 ctrl_t ctrl = assuan_get_pointer (ctx);
1580 /* No options for now. */
1581 line = skip_options (line);
1583 /* Break the line down into an strlist. Each pattern is
1584 percent-plus escaped. */
1586 for (p=line; *p; line = p)
1588 while (*p && *p != ' ')
1594 sl = xtrymalloc (sizeof *sl + strlen (line));
1597 err = gpg_error_from_syserror ();
1601 strcpy_escaped_plus (sl->d, line);
1607 /* Setup an output stream and perform the search. */
1608 outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
1610 err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
1613 err = ks_action_search (ctrl, ctrl->server_local->keyservers,
1619 free_strlist (list);
1620 return leave_cmd (ctx, err);
1625 static const char hlp_ks_get[] =
1626 "KS_GET {<pattern>}\n"
1628 "Get the keys matching PATTERN from the configured OpenPGP keyservers\n"
1629 "(see command KEYSERVER). Each pattern should be a keyid, a fingerprint,\n"
1630 "or an exact name indicastes by the '=' prefix.";
1632 cmd_ks_get (assuan_context_t ctx, char *line)
1634 ctrl_t ctrl = assuan_get_pointer (ctx);
1640 /* No options for now. */
1641 line = skip_options (line);
1643 /* Break the line into a strlist. Each pattern is by
1644 definition percent-plus escaped. However we only support keyids
1645 and fingerprints and thus the client has no need to apply the
1648 for (p=line; *p; line = p)
1650 while (*p && *p != ' ')
1656 sl = xtrymalloc (sizeof *sl + strlen (line));
1659 err = gpg_error_from_syserror ();
1663 strcpy_escaped_plus (sl->d, line);
1669 /* Setup an output stream and perform the get. */
1670 outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
1672 err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
1675 err = ks_action_get (ctrl, ctrl->server_local->keyservers, list, outfp);
1680 free_strlist (list);
1681 return leave_cmd (ctx, err);
1685 static const char hlp_ks_fetch[] =
1688 "Get the key(s) from URL.";
1690 cmd_ks_fetch (assuan_context_t ctx, char *line)
1692 ctrl_t ctrl = assuan_get_pointer (ctx);
1696 /* No options for now. */
1697 line = skip_options (line);
1699 /* Setup an output stream and perform the get. */
1700 outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
1702 err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
1705 err = ks_action_fetch (ctrl, line, outfp);
1709 return leave_cmd (ctx, err);
1714 static const char hlp_ks_put[] =
1717 "Send a key to the configured OpenPGP keyservers. The actual key material\n"
1718 "is then requested by Dirmngr using\n"
1720 " INQUIRE KEYBLOCK\n"
1722 "The client shall respond with a binary version of the keyblock (e.g.,\n"
1723 "the output of `gpg --export KEYID'). For LDAP\n"
1724 "keyservers Dirmngr may ask for meta information of the provided keyblock\n"
1727 " INQUIRE KEYBLOCK_INFO\n"
1729 "The client shall respond with a colon delimited info lines (the output\n"
1730 "of 'for x in keys sigs; do gpg --list-$x --with-colons KEYID; done').\n";
1732 cmd_ks_put (assuan_context_t ctx, char *line)
1734 ctrl_t ctrl = assuan_get_pointer (ctx);
1736 unsigned char *value = NULL;
1738 unsigned char *info = NULL;
1741 /* No options for now. */
1742 line = skip_options (line);
1744 /* Ask for the key material. */
1745 err = assuan_inquire (ctx, "KEYBLOCK",
1746 &value, &valuelen, MAX_KEYBLOCK_LENGTH);
1749 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1753 if (!valuelen) /* No data returned; return a comprehensible error. */
1755 err = gpg_error (GPG_ERR_MISSING_CERT);
1759 /* Ask for the key meta data. Not actually needed for HKP servers
1760 but we do it anyway to test the client implementaion. */
1761 err = assuan_inquire (ctx, "KEYBLOCK_INFO",
1762 &info, &infolen, MAX_KEYBLOCK_LENGTH);
1765 log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1770 err = ks_action_put (ctrl, ctrl->server_local->keyservers,
1771 value, valuelen, info, infolen);
1776 return leave_cmd (ctx, err);
1782 static const char hlp_getinfo[] =
1785 "Multi purpose command to return certain information. \n"
1786 "Supported values of WHAT are:\n"
1788 "version - Return the version of the program.\n"
1789 "pid - Return the process id of the server.\n"
1791 "socket_name - Return the name of the socket.\n";
1793 cmd_getinfo (assuan_context_t ctx, char *line)
1797 if (!strcmp (line, "version"))
1799 const char *s = VERSION;
1800 err = assuan_send_data (ctx, s, strlen (s));
1802 else if (!strcmp (line, "pid"))
1806 snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
1807 err = assuan_send_data (ctx, numbuf, strlen (numbuf));
1809 else if (!strcmp (line, "socket_name"))
1811 const char *s = dirmngr_user_socket_name ();
1814 s = dirmngr_sys_socket_name ();
1817 err = assuan_send_data (ctx, s, strlen (s));
1819 err = gpg_error (GPG_ERR_NO_DATA);
1822 err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
1824 return leave_cmd (ctx, err);
1829 static const char hlp_killdirmngr[] =
1832 "This command allows a user - given sufficient permissions -\n"
1833 "to kill this dirmngr process.\n";
1835 cmd_killdirmngr (assuan_context_t ctx, char *line)
1837 ctrl_t ctrl = assuan_get_pointer (ctx);
1842 if (opt.system_daemon)
1844 if (opt.system_service)
1845 err = set_error (GPG_ERR_NOT_SUPPORTED,
1846 "can't do that whilst running as system service");
1848 err = check_owner_permission (ctx,
1849 "no permission to kill this process");
1856 ctrl->server_local->stopme = 1;
1857 err = gpg_error (GPG_ERR_EOF);
1863 static const char hlp_reloaddirmngr[] =
1866 "This command is an alternative to SIGHUP\n"
1867 "to reload the configuration.";
1869 cmd_reloaddirmngr (assuan_context_t ctx, char *line)
1874 if (opt.system_daemon)
1876 #ifndef HAVE_W32_SYSTEM
1879 assuan_peercred_t cred;
1881 ec = gpg_err_code (assuan_get_peercred (ctx, &cred));
1882 if (!ec && cred->uid)
1883 ec = GPG_ERR_EPERM; /* Only root may terminate. */
1885 return set_error (ec, "no permission to reload this process");
1890 dirmngr_sighup_action ();
1897 /* Tell the assuan library about our commands. */
1899 register_commands (assuan_context_t ctx)
1903 assuan_handler_t handler;
1904 const char * const help;
1906 { "LDAPSERVER", cmd_ldapserver, hlp_ldapserver },
1907 { "ISVALID", cmd_isvalid, hlp_isvalid },
1908 { "CHECKCRL", cmd_checkcrl, hlp_checkcrl },
1909 { "CHECKOCSP", cmd_checkocsp, hlp_checkocsp },
1910 { "LOOKUP", cmd_lookup, hlp_lookup },
1911 { "LOADCRL", cmd_loadcrl, hlp_loadcrl },
1912 { "LISTCRLS", cmd_listcrls, hlp_listcrls },
1913 { "CACHECERT", cmd_cachecert, hlp_cachecert },
1914 { "VALIDATE", cmd_validate, hlp_validate },
1915 { "KEYSERVER", cmd_keyserver, hlp_keyserver },
1916 { "KS_SEARCH", cmd_ks_search, hlp_ks_search },
1917 { "KS_GET", cmd_ks_get, hlp_ks_get },
1918 { "KS_FETCH", cmd_ks_fetch, hlp_ks_fetch },
1919 { "KS_PUT", cmd_ks_put, hlp_ks_put },
1920 { "GETINFO", cmd_getinfo, hlp_getinfo },
1921 { "KILLDIRMNGR",cmd_killdirmngr,hlp_killdirmngr },
1922 { "RELOADDIRMNGR",cmd_reloaddirmngr,hlp_reloaddirmngr },
1927 for (i=j=0; table[i].name; i++)
1929 rc = assuan_register_command (ctx, table[i].name, table[i].handler,
1938 /* Note that we do not reset the list of configured keyservers. */
1940 reset_notify (assuan_context_t ctx, char *line)
1942 ctrl_t ctrl = assuan_get_pointer (ctx);
1946 ldapserver_list_free (ctrl->server_local->ldapservers);
1948 ctrl->server_local->ldapservers = NULL;
1953 /* Startup the server and run the main command loop. With FD = -1,
1954 use stdin/stdout. */
1956 start_command_handler (assuan_fd_t fd)
1958 static const char hello[] = "Dirmngr " VERSION " at your service";
1959 static char *hello_line;
1961 assuan_context_t ctx;
1964 ctrl = xtrycalloc (1, sizeof *ctrl);
1966 ctrl->server_local = xtrycalloc (1, sizeof *ctrl->server_local);
1967 if (!ctrl || !ctrl->server_local)
1969 log_error (_("can't allocate control structure: %s\n"),
1975 dirmngr_init_default_ctrl (ctrl);
1977 rc = assuan_new (&ctx);
1980 log_error (_("failed to allocate assuan context: %s\n"),
1985 if (fd == ASSUAN_INVALID_FD)
1987 assuan_fd_t filedes[2];
1989 filedes[0] = assuan_fdopen (0);
1990 filedes[1] = assuan_fdopen (1);
1991 rc = assuan_init_pipe_server (ctx, filedes);
1995 rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED);
2000 assuan_release (ctx);
2001 log_error (_("failed to initialize the server: %s\n"),
2006 rc = register_commands (ctx);
2009 log_error (_("failed to the register commands with Assuan: %s\n"),
2018 const char *cfgname;
2020 cfgname = opt.config_filename? opt.config_filename : "[none]";
2022 n = (30 + strlen (opt.homedir) + strlen (cfgname)
2023 + strlen (hello) + 1);
2024 hello_line = xmalloc (n+1);
2025 snprintf (hello_line, n,
2035 ctrl->server_local->assuan_ctx = ctx;
2036 assuan_set_pointer (ctx, ctrl);
2038 assuan_set_hello_line (ctx, hello_line);
2039 assuan_register_option_handler (ctx, option_handler);
2040 assuan_register_reset_notify (ctx, reset_notify);
2044 rc = assuan_accept (ctx);
2049 log_info (_("Assuan accept problem: %s\n"), gpg_strerror (rc));
2053 #ifndef HAVE_W32_SYSTEM
2056 assuan_peercred_t peercred;
2058 if (!assuan_get_peercred (ctx, &peercred))
2059 log_info ("connection from process %ld (%ld:%ld)\n",
2060 (long)peercred->pid, (long)peercred->uid,
2061 (long)peercred->gid);
2065 rc = assuan_process (ctx);
2068 log_info (_("Assuan processing failed: %s\n"), gpg_strerror (rc));
2074 ldap_wrapper_connection_cleanup (ctrl);
2076 ldapserver_list_free (ctrl->server_local->ldapservers);
2078 ctrl->server_local->ldapservers = NULL;
2080 ctrl->server_local->assuan_ctx = NULL;
2081 assuan_release (ctx);
2083 if (ctrl->server_local->stopme)
2087 log_error ("oops: connection control structure still referenced (%d)\n",
2091 release_ctrl_ocsp_certs (ctrl);
2092 xfree (ctrl->server_local);
2098 /* Send a status line back to the client. KEYWORD is the status
2099 keyword, the optional string arguments are blank separated added to
2100 the line, the last argument must be a NULL. */
2102 dirmngr_status (ctrl_t ctrl, const char *keyword, ...)
2104 gpg_error_t err = 0;
2108 va_start (arg_ptr, keyword);
2110 if (ctrl->server_local)
2112 assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2118 while ( (text = va_arg (arg_ptr, const char *)) )
2125 for ( ; *text && n < DIM (buf)-2; n++)
2129 err = assuan_write_status (ctx, keyword, buf);
2137 /* Print a help status line. TEXTLEN gives the length of the text
2138 from TEXT to be printed. The function splits text at LFs. */
2140 dirmngr_status_help (ctrl_t ctrl, const char *text)
2142 gpg_error_t err = 0;
2144 if (ctrl->server_local)
2146 assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2154 for ( ; *text && *text != '\n' && n < DIM (buf)-2; n++)
2159 err = assuan_write_status (ctx, "#", buf);
2161 while (!err && *text);
2167 /* Send a tick progress indicator back. Fixme: This is only done for
2168 the currently active channel. */
2170 dirmngr_tick (ctrl_t ctrl)
2172 static time_t next_tick = 0;
2173 gpg_error_t err = 0;
2174 time_t now = time (NULL);
2178 next_tick = now + 1;
2180 else if ( now > next_tick )
2184 err = dirmngr_status (ctrl, "PROGRESS", "tick", "? 0 0", NULL);
2187 /* Take this as in indication for a cancel request. */
2188 err = gpg_error (GPG_ERR_CANCELED);
2193 next_tick = now + 1;