9a024419575966f6f1bf96fdd98cb7aac2317351
[gnupg.git] / dirmngr / server.c
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 g10 Code GmbH
4  * Copyright (C) 2014 Werner Koch
5  *
6  * This file is part of GnuPG.
7  *
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.
12  *
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.
17  *
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/>.
20  */
21
22 #include <config.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <stddef.h>
26 #include <string.h>
27 #include <assert.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <unistd.h>
31 #include <errno.h>
32
33 #define JNLIB_NEED_LOG_LOGV
34 #include "dirmngr.h"
35 #include <assuan.h>
36
37 #include "crlcache.h"
38 #include "crlfetch.h"
39 #include "ldapserver.h"
40 #include "ocsp.h"
41 #include "certcache.h"
42 #include "validate.h"
43 #include "misc.h"
44 #include "ldap-wrapper.h"
45 #include "ks-action.h"
46 #include "ks-engine.h"  /* (ks_hkp_print_hosttable) */
47
48 /* To avoid DoS attacks we limit the size of a certificate to
49    something reasonable. */
50 #define MAX_CERT_LENGTH (8*1024)
51
52 /* The same goes for OpenPGP keyblocks, but here we need to allow for
53    much longer blocks; a 200k keyblock is not too unusual for keys
54    with a lot of signatures (e.g. 0x5b0358a2).  */
55 #define MAX_KEYBLOCK_LENGTH (512*1024)
56
57
58 #define PARM_ERROR(t) assuan_set_error (ctx, \
59                                         gpg_error (GPG_ERR_ASS_PARAMETER), (t))
60 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
61
62
63
64 /* Control structure per connection. */
65 struct server_local_s
66 {
67   /* Data used to associate an Assuan context with local server data */
68   assuan_context_t assuan_ctx;
69
70   /* Per-session LDAP servers.  */
71   ldap_server_t ldapservers;
72
73   /* If this flag is set to true this dirmngr process will be
74      terminated after the end of this session.  */
75   int stopme;
76 };
77
78
79 /* Cookie definition for assuan data line output.  */
80 static ssize_t data_line_cookie_write (void *cookie,
81                                        const void *buffer, size_t size);
82 static int data_line_cookie_close (void *cookie);
83 static es_cookie_io_functions_t data_line_cookie_functions =
84   {
85     NULL,
86     data_line_cookie_write,
87     NULL,
88     data_line_cookie_close
89   };
90
91
92
93
94 \f
95 /* Accessor for the local ldapservers variable. */
96 ldap_server_t
97 get_ldapservers_from_ctrl (ctrl_t ctrl)
98 {
99   if (ctrl && ctrl->server_local)
100     return ctrl->server_local->ldapservers;
101   else
102     return NULL;
103 }
104
105
106 /* Release all configured keyserver info from CTRL.  */
107 void
108 release_ctrl_keyservers (ctrl_t ctrl)
109 {
110   while (ctrl->keyservers)
111     {
112       uri_item_t tmp = ctrl->keyservers->next;
113       http_release_parsed_uri (ctrl->keyservers->parsed_uri);
114       xfree (ctrl->keyservers);
115       ctrl->keyservers = tmp;
116     }
117 }
118
119
120
121 /* Helper to print a message while leaving a command.  */
122 static gpg_error_t
123 leave_cmd (assuan_context_t ctx, gpg_error_t err)
124
125 {
126   if (err)
127     {
128       const char *name = assuan_get_command_name (ctx);
129       if (!name)
130         name = "?";
131       if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT)
132         log_error ("command '%s' failed: %s\n", name,
133                    gpg_strerror (err));
134       else
135         log_error ("command '%s' failed: %s <%s>\n", name,
136                    gpg_strerror (err), gpg_strsource (err));
137     }
138   return err;
139 }
140
141 /* A write handler used by es_fopencookie to write assuan data
142    lines.  */
143 static ssize_t
144 data_line_cookie_write (void *cookie, const void *buffer, size_t size)
145 {
146   assuan_context_t ctx = cookie;
147
148   if (assuan_send_data (ctx, buffer, size))
149     {
150       gpg_err_set_errno (EIO);
151       return -1;
152     }
153
154   return size;
155 }
156
157 static int
158 data_line_cookie_close (void *cookie)
159 {
160   assuan_context_t ctx = cookie;
161
162   if (assuan_send_data (ctx, NULL, 0))
163     {
164       gpg_err_set_errno (EIO);
165       return -1;
166     }
167
168   return 0;
169 }
170
171
172 /* Copy the % and + escaped string S into the buffer D and replace the
173    escape sequences.  Note, that it is sufficient to allocate the
174    target string D as long as the source string S, i.e.: strlen(s)+1.
175    Note further that if S contains an escaped binary Nul the resulting
176    string D will contain the 0 as well as all other characters but it
177    will be impossible to know whether this is the original EOS or a
178    copied Nul. */
179 static void
180 strcpy_escaped_plus (char *d, const unsigned char *s)
181 {
182   while (*s)
183     {
184       if (*s == '%' && s[1] && s[2])
185         {
186           s++;
187           *d++ = xtoi_2 ( s);
188           s += 2;
189         }
190       else if (*s == '+')
191         *d++ = ' ', s++;
192       else
193         *d++ = *s++;
194     }
195   *d = 0;
196 }
197
198
199 /* Check whether the option NAME appears in LINE */
200 static int
201 has_option (const char *line, const char *name)
202 {
203   const char *s;
204   int n = strlen (name);
205
206   s = strstr (line, name);
207   return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
208 }
209
210 /* Same as has_option but only considers options at the begin of the
211    line.  This is useful for commands which allow arbitrary strings on
212    the line.  */
213 static int
214 has_leading_option (const char *line, const char *name)
215 {
216   const char *s;
217   int n;
218
219   if (name[0] != '-' || name[1] != '-' || !name[2] || spacep (name+2))
220     return 0;
221   n = strlen (name);
222   while ( *line == '-' && line[1] == '-' )
223     {
224       s = line;
225       while (*line && !spacep (line))
226         line++;
227       if (n == (line - s) && !strncmp (s, name, n))
228         return 1;
229       while (spacep (line))
230         line++;
231     }
232   return 0;
233 }
234
235
236 /* Same as has_option but does only test for the name of the option
237    and ignores an argument, i.e. with NAME being "--hash" it would
238    return a pointer for "--hash" as well as for "--hash=foo".  If
239    thhere is no such option NULL is returned.  The pointer returned
240    points right behind the option name, this may be an equal sign, Nul
241    or a space.  */
242 /* static const char * */
243 /* has_option_name (const char *line, const char *name) */
244 /* { */
245 /*   const char *s; */
246 /*   int n = strlen (name); */
247
248 /*   s = strstr (line, name); */
249 /*   return (s && (s == line || spacep (s-1)) */
250 /*           && (!s[n] || spacep (s+n) || s[n] == '=')) ? (s+n) : NULL; */
251 /* } */
252
253
254 /* Skip over options.  It is assumed that leading spaces have been
255    removed (this is the case for lines passed to a handler from
256    assuan).  Blanks after the options are also removed. */
257 static char *
258 skip_options (char *line)
259 {
260   while ( *line == '-' && line[1] == '-' )
261     {
262       while (*line && !spacep (line))
263         line++;
264       while (spacep (line))
265         line++;
266     }
267   return line;
268 }
269
270
271 /* Common code for get_cert_local and get_issuer_cert_local. */
272 static ksba_cert_t
273 do_get_cert_local (ctrl_t ctrl, const char *name, const char *command)
274 {
275   unsigned char *value;
276   size_t valuelen;
277   int rc;
278   char *buf;
279   ksba_cert_t cert;
280
281   if (name)
282     {
283       buf = xmalloc ( strlen (command) + 1 + strlen(name) + 1);
284       strcpy (stpcpy (stpcpy (buf, command), " "), name);
285     }
286   else
287     buf = xstrdup (command);
288
289   rc = assuan_inquire (ctrl->server_local->assuan_ctx, buf,
290                        &value, &valuelen, MAX_CERT_LENGTH);
291   xfree (buf);
292   if (rc)
293     {
294       log_error (_("assuan_inquire(%s) failed: %s\n"),
295                  command, gpg_strerror (rc));
296       return NULL;
297     }
298
299   if (!valuelen)
300     {
301       xfree (value);
302       return NULL;
303     }
304
305   rc = ksba_cert_new (&cert);
306   if (!rc)
307     {
308       rc = ksba_cert_init_from_mem (cert, value, valuelen);
309       if (rc)
310         {
311           ksba_cert_release (cert);
312           cert = NULL;
313         }
314     }
315   xfree (value);
316   return cert;
317 }
318
319
320
321 /* Ask back to return a certificate for name, given as a regular
322    gpgsm certificate indentificates (e.g. fingerprint or one of the
323    other methods).  Alternatively, NULL may be used for NAME to
324    return the current target certificate. Either return the certificate
325    in a KSBA object or NULL if it is not available.
326 */
327 ksba_cert_t
328 get_cert_local (ctrl_t ctrl, const char *name)
329 {
330   if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
331     {
332       if (opt.debug)
333         log_debug ("get_cert_local called w/o context\n");
334       return NULL;
335     }
336   return do_get_cert_local (ctrl, name, "SENDCERT");
337
338 }
339
340 /* Ask back to return the issuing certificate for name, given as a
341    regular gpgsm certificate indentificates (e.g. fingerprint or one
342    of the other methods).  Alternatively, NULL may be used for NAME to
343    return thecurrent target certificate. Either return the certificate
344    in a KSBA object or NULL if it is not available.
345
346 */
347 ksba_cert_t
348 get_issuing_cert_local (ctrl_t ctrl, const char *name)
349 {
350   if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
351     {
352       if (opt.debug)
353         log_debug ("get_issuing_cert_local called w/o context\n");
354       return NULL;
355     }
356   return do_get_cert_local (ctrl, name, "SENDISSUERCERT");
357 }
358
359 /* Ask back to return a certificate with subject NAME and a
360    subjectKeyIdentifier of KEYID. */
361 ksba_cert_t
362 get_cert_local_ski (ctrl_t ctrl, const char *name, ksba_sexp_t keyid)
363 {
364   unsigned char *value;
365   size_t valuelen;
366   int rc;
367   char *buf;
368   ksba_cert_t cert;
369   char *hexkeyid;
370
371   if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
372     {
373       if (opt.debug)
374         log_debug ("get_cert_local_ski called w/o context\n");
375       return NULL;
376     }
377   if (!name || !keyid)
378     {
379       log_debug ("get_cert_local_ski called with insufficient arguments\n");
380       return NULL;
381     }
382
383   hexkeyid = serial_hex (keyid);
384   if (!hexkeyid)
385     {
386       log_debug ("serial_hex() failed\n");
387       return NULL;
388     }
389
390   buf = xtrymalloc (15 + strlen (hexkeyid) + 2 + strlen(name) + 1);
391   if (!buf)
392     {
393
394       log_error ("can't allocate enough memory: %s\n", strerror (errno));
395       xfree (hexkeyid);
396       return NULL;
397     }
398   strcpy (stpcpy (stpcpy (stpcpy (buf, "SENDCERT_SKI "), hexkeyid)," /"),name);
399   xfree (hexkeyid);
400
401   rc = assuan_inquire (ctrl->server_local->assuan_ctx, buf,
402                        &value, &valuelen, MAX_CERT_LENGTH);
403   xfree (buf);
404   if (rc)
405     {
406       log_error (_("assuan_inquire(%s) failed: %s\n"), "SENDCERT_SKI",
407                  gpg_strerror (rc));
408       return NULL;
409     }
410
411   if (!valuelen)
412     {
413       xfree (value);
414       return NULL;
415     }
416
417   rc = ksba_cert_new (&cert);
418   if (!rc)
419     {
420       rc = ksba_cert_init_from_mem (cert, value, valuelen);
421       if (rc)
422         {
423           ksba_cert_release (cert);
424           cert = NULL;
425         }
426     }
427   xfree (value);
428   return cert;
429 }
430
431
432 /* Ask the client via an inquiry to check the istrusted status of the
433    certificate specified by the hexified fingerprint HEXFPR.  Returns
434    0 if the certificate is trusted by the client or an error code.  */
435 gpg_error_t
436 get_istrusted_from_client (ctrl_t ctrl, const char *hexfpr)
437 {
438   unsigned char *value;
439   size_t valuelen;
440   int rc;
441   char request[100];
442
443   if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx
444       || !hexfpr)
445     return gpg_error (GPG_ERR_INV_ARG);
446
447   snprintf (request, sizeof request, "ISTRUSTED %s", hexfpr);
448   rc = assuan_inquire (ctrl->server_local->assuan_ctx, request,
449                        &value, &valuelen, 100);
450   if (rc)
451     {
452       log_error (_("assuan_inquire(%s) failed: %s\n"),
453                  request, gpg_strerror (rc));
454       return rc;
455     }
456   /* The expected data is: "1" or "1 cruft" (not a C-string).  */
457   if (valuelen && *value == '1' && (valuelen == 1 || spacep (value+1)))
458     rc = 0;
459   else
460     rc = gpg_error (GPG_ERR_NOT_TRUSTED);
461   xfree (value);
462   return rc;
463 }
464
465
466
467
468 /* Ask the client to return the certificate associated with the
469    current command. This is sometimes needed because the client usually
470    sends us just the cert ID, assuming that the request can be
471    satisfied from the cache, where the cert ID is used as key. */
472 static int
473 inquire_cert_and_load_crl (assuan_context_t ctx)
474 {
475   ctrl_t ctrl = assuan_get_pointer (ctx);
476   gpg_error_t err;
477   unsigned char *value = NULL;
478   size_t valuelen;
479   ksba_cert_t cert = NULL;
480
481   err = assuan_inquire( ctx, "SENDCERT", &value, &valuelen, 0);
482   if (err)
483     return err;
484
485 /*   { */
486 /*     FILE *fp = fopen ("foo.der", "r"); */
487 /*     value = xmalloc (2000); */
488 /*     valuelen = fread (value, 1, 2000, fp); */
489 /*     fclose (fp); */
490 /*   } */
491
492   if (!valuelen) /* No data returned; return a comprehensible error. */
493     return gpg_error (GPG_ERR_MISSING_CERT);
494
495   err = ksba_cert_new (&cert);
496   if (err)
497     goto leave;
498   err = ksba_cert_init_from_mem (cert, value, valuelen);
499   if(err)
500     goto leave;
501   xfree (value); value = NULL;
502
503   err = crl_cache_reload_crl (ctrl, cert);
504
505  leave:
506   ksba_cert_release (cert);
507   xfree (value);
508   return err;
509 }
510
511
512 /* Handle OPTION commands. */
513 static gpg_error_t
514 option_handler (assuan_context_t ctx, const char *key, const char *value)
515 {
516   ctrl_t ctrl = assuan_get_pointer (ctx);
517
518   if (!strcmp (key, "force-crl-refresh"))
519     {
520       int i = *value? atoi (value) : 0;
521       ctrl->force_crl_refresh = i;
522     }
523   else if (!strcmp (key, "audit-events"))
524     {
525       int i = *value? atoi (value) : 0;
526       ctrl->audit_events = i;
527     }
528   else
529     return gpg_error (GPG_ERR_UNKNOWN_OPTION);
530
531   return 0;
532 }
533
534 static const char hlp_ldapserver[] =
535   "LDAPSERVER <data>\n"
536   "\n"
537   "Add a new LDAP server to the list of configured LDAP servers.\n"
538   "DATA is in the same format as expected in the configure file.";
539 static gpg_error_t
540 cmd_ldapserver (assuan_context_t ctx, char *line)
541 {
542   ctrl_t ctrl = assuan_get_pointer (ctx);
543   ldap_server_t server;
544   ldap_server_t *last_next_p;
545
546   while (spacep (line))
547     line++;
548   if (*line == '\0')
549     return leave_cmd (ctx, PARM_ERROR (_("ldapserver missing")));
550
551   server = ldapserver_parse_one (line, "", 0);
552   if (! server)
553     return leave_cmd (ctx, gpg_error (GPG_ERR_INV_ARG));
554
555   last_next_p = &ctrl->server_local->ldapservers;
556   while (*last_next_p)
557     last_next_p = &(*last_next_p)->next;
558   *last_next_p = server;
559   return leave_cmd (ctx, 0);
560 }
561
562
563 static const char hlp_isvalid[] =
564   "ISVALID [--only-ocsp] [--force-default-responder]"
565   " <certificate_id>|<certificate_fpr>\n"
566   "\n"
567   "This command checks whether the certificate identified by the\n"
568   "certificate_id is valid.  This is done by consulting CRLs or\n"
569   "whatever has been configured.  Note, that the returned error codes\n"
570   "are from gpg-error.h.  The command may callback using the inquire\n"
571   "function.  See the manual for details.\n"
572   "\n"
573   "The CERTIFICATE_ID is a hex encoded string consisting of two parts,\n"
574   "delimited by a single dot.  The first part is the SHA-1 hash of the\n"
575   "issuer name and the second part the serial number.\n"
576   "\n"
577   "Alternatively the certificate's fingerprint may be given in which\n"
578   "case an OCSP request is done before consulting the CRL.\n"
579   "\n"
580   "If the option --only-ocsp is given, no fallback to a CRL check will\n"
581   "be used.\n"
582   "\n"
583   "If the option --force-default-responder is given, only the default\n"
584   "OCSP responder will be used and any other methods of obtaining an\n"
585   "OCSP responder URL won't be used.";
586 static gpg_error_t
587 cmd_isvalid (assuan_context_t ctx, char *line)
588 {
589   ctrl_t ctrl = assuan_get_pointer (ctx);
590   char *issuerhash, *serialno;
591   gpg_error_t err;
592   int did_inquire = 0;
593   int ocsp_mode = 0;
594   int only_ocsp;
595   int force_default_responder;
596
597   only_ocsp = has_option (line, "--only-ocsp");
598   force_default_responder = has_option (line, "--force-default-responder");
599   line = skip_options (line);
600
601   issuerhash = xstrdup (line); /* We need to work on a copy of the
602                                   line because that same Assuan
603                                   context may be used for an inquiry.
604                                   That is because Assuan reuses its
605                                   line buffer.
606                                    */
607
608   serialno = strchr (issuerhash, '.');
609   if (serialno)
610     *serialno++ = 0;
611   else
612     {
613       char *endp = strchr (issuerhash, ' ');
614       if (endp)
615         *endp = 0;
616       if (strlen (issuerhash) != 40)
617         {
618           xfree (issuerhash);
619           return leave_cmd (ctx, PARM_ERROR (_("serialno missing in cert ID")));
620         }
621       ocsp_mode = 1;
622     }
623
624
625  again:
626   if (ocsp_mode)
627     {
628       /* Note, that we ignore the given issuer hash and instead rely
629          on the current certificate semantics used with this
630          command. */
631       if (!opt.allow_ocsp)
632         err = gpg_error (GPG_ERR_NOT_SUPPORTED);
633       else
634         err = ocsp_isvalid (ctrl, NULL, NULL, force_default_responder);
635       /* Fixme: If we got no ocsp response and --only-ocsp is not used
636          we should fall back to CRL mode.  Thus we need to clear
637          OCSP_MODE, get the issuerhash and the serialno from the
638          current certificate and jump to again. */
639     }
640   else if (only_ocsp)
641     err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
642   else
643     {
644       switch (crl_cache_isvalid (ctrl,
645                                  issuerhash, serialno,
646                                  ctrl->force_crl_refresh))
647         {
648         case CRL_CACHE_VALID:
649           err = 0;
650           break;
651         case CRL_CACHE_INVALID:
652           err = gpg_error (GPG_ERR_CERT_REVOKED);
653           break;
654         case CRL_CACHE_DONTKNOW:
655           if (did_inquire)
656             err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
657           else if (!(err = inquire_cert_and_load_crl (ctx)))
658             {
659               did_inquire = 1;
660               goto again;
661             }
662           break;
663         case CRL_CACHE_CANTUSE:
664           err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
665           break;
666         default:
667           log_fatal ("crl_cache_isvalid returned invalid code\n");
668         }
669     }
670
671   xfree (issuerhash);
672   return leave_cmd (ctx, err);
673 }
674
675
676 /* If the line contains a SHA-1 fingerprint as the first argument,
677    return the FPR vuffer on success.  The function checks that the
678    fingerprint consists of valid characters and prints and error
679    message if it does not and returns NULL.  Fingerprints are
680    considered optional and thus no explicit error is returned. NULL is
681    also returned if there is no fingerprint at all available.
682    FPR must be a caller provided buffer of at least 20 bytes.
683
684    Note that colons within the fingerprint are allowed to separate 2
685    hex digits; this allows for easier cutting and pasting using the
686    usual fingerprint rendering.
687 */
688 static unsigned char *
689 get_fingerprint_from_line (const char *line, unsigned char *fpr)
690 {
691   const char *s;
692   int i;
693
694   for (s=line, i=0; *s && *s != ' '; s++ )
695     {
696       if ( hexdigitp (s) && hexdigitp (s+1) )
697         {
698           if ( i >= 20 )
699             return NULL;  /* Fingerprint too long.  */
700           fpr[i++] = xtoi_2 (s);
701           s++;
702         }
703       else if ( *s != ':' )
704         return NULL; /* Invalid.  */
705     }
706   if ( i != 20 )
707     return NULL; /* Fingerprint to short.  */
708   return fpr;
709 }
710
711
712
713 static const char hlp_checkcrl[] =
714   "CHECKCRL [<fingerprint>]\n"
715   "\n"
716   "Check whether the certificate with FINGERPRINT (SHA-1 hash of the\n"
717   "entire X.509 certificate blob) is valid or not by consulting the\n"
718   "CRL responsible for this certificate.  If the fingerprint has not\n"
719   "been given or the certificate is not known, the function \n"
720   "inquires the certificate using an\n"
721   "\n"
722   "  INQUIRE TARGETCERT\n"
723   "\n"
724   "and the caller is expected to return the certificate for the\n"
725   "request (which should match FINGERPRINT) as a binary blob.\n"
726   "Processing then takes place without further interaction; in\n"
727   "particular dirmngr tries to locate other required certificate by\n"
728   "its own mechanism which includes a local certificate store as well\n"
729   "as a list of trusted root certificates.\n"
730   "\n"
731   "The return value is the usual gpg-error code or 0 for ducesss;\n"
732   "i.e. the certificate validity has been confirmed by a valid CRL.";
733 static gpg_error_t
734 cmd_checkcrl (assuan_context_t ctx, char *line)
735 {
736   ctrl_t ctrl = assuan_get_pointer (ctx);
737   gpg_error_t err;
738   unsigned char fprbuffer[20], *fpr;
739   ksba_cert_t cert;
740
741   fpr = get_fingerprint_from_line (line, fprbuffer);
742   cert = fpr? get_cert_byfpr (fpr) : NULL;
743
744   if (!cert)
745     {
746       /* We do not have this certificate yet or the fingerprint has
747          not been given.  Inquire it from the client.  */
748       unsigned char *value = NULL;
749       size_t valuelen;
750
751       err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
752                            &value, &valuelen, MAX_CERT_LENGTH);
753       if (err)
754         {
755           log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
756           goto leave;
757         }
758
759       if (!valuelen) /* No data returned; return a comprehensible error. */
760         err = gpg_error (GPG_ERR_MISSING_CERT);
761       else
762         {
763           err = ksba_cert_new (&cert);
764           if (!err)
765             err = ksba_cert_init_from_mem (cert, value, valuelen);
766         }
767       xfree (value);
768       if(err)
769         goto leave;
770     }
771
772   assert (cert);
773
774   err = crl_cache_cert_isvalid (ctrl, cert, ctrl->force_crl_refresh);
775   if (gpg_err_code (err) == GPG_ERR_NO_CRL_KNOWN)
776     {
777       err = crl_cache_reload_crl (ctrl, cert);
778       if (!err)
779         err = crl_cache_cert_isvalid (ctrl, cert, 0);
780     }
781
782  leave:
783   ksba_cert_release (cert);
784   return leave_cmd (ctx, err);
785 }
786
787
788 static const char hlp_checkocsp[] =
789   "CHECKOCSP [--force-default-responder] [<fingerprint>]\n"
790   "\n"
791   "Check whether the certificate with FINGERPRINT (SHA-1 hash of the\n"
792   "entire X.509 certificate blob) is valid or not by asking an OCSP\n"
793   "responder responsible for this certificate.  The optional\n"
794   "fingerprint may be used for a quick check in case an OCSP check has\n"
795   "been done for this certificate recently (we always cache OCSP\n"
796   "responses for a couple of minutes). If the fingerprint has not been\n"
797   "given or there is no cached result, the function inquires the\n"
798   "certificate using an\n"
799   "\n"
800   "   INQUIRE TARGETCERT\n"
801   "\n"
802   "and the caller is expected to return the certificate for the\n"
803   "request (which should match FINGERPRINT) as a binary blob.\n"
804   "Processing then takes place without further interaction; in\n"
805   "particular dirmngr tries to locate other required certificates by\n"
806   "its own mechanism which includes a local certificate store as well\n"
807   "as a list of trusted root certifciates.\n"
808   "\n"
809   "If the option --force-default-responder is given, only the default\n"
810   "OCSP responder will be used and any other methods of obtaining an\n"
811   "OCSP responder URL won't be used.\n"
812   "\n"
813   "The return value is the usual gpg-error code or 0 for ducesss;\n"
814   "i.e. the certificate validity has been confirmed by a valid CRL.";
815 static gpg_error_t
816 cmd_checkocsp (assuan_context_t ctx, char *line)
817 {
818   ctrl_t ctrl = assuan_get_pointer (ctx);
819   gpg_error_t err;
820   unsigned char fprbuffer[20], *fpr;
821   ksba_cert_t cert;
822   int force_default_responder;
823
824   force_default_responder = has_option (line, "--force-default-responder");
825   line = skip_options (line);
826
827   fpr = get_fingerprint_from_line (line, fprbuffer);
828   cert = fpr? get_cert_byfpr (fpr) : NULL;
829
830   if (!cert)
831     {
832       /* We do not have this certificate yet or the fingerprint has
833          not been given.  Inquire it from the client.  */
834       unsigned char *value = NULL;
835       size_t valuelen;
836
837       err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
838                            &value, &valuelen, MAX_CERT_LENGTH);
839       if (err)
840         {
841           log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
842           goto leave;
843         }
844
845       if (!valuelen) /* No data returned; return a comprehensible error. */
846         err = gpg_error (GPG_ERR_MISSING_CERT);
847       else
848         {
849           err = ksba_cert_new (&cert);
850           if (!err)
851             err = ksba_cert_init_from_mem (cert, value, valuelen);
852         }
853       xfree (value);
854       if(err)
855         goto leave;
856     }
857
858   assert (cert);
859
860   if (!opt.allow_ocsp)
861     err = gpg_error (GPG_ERR_NOT_SUPPORTED);
862   else
863     err = ocsp_isvalid (ctrl, cert, NULL, force_default_responder);
864
865  leave:
866   ksba_cert_release (cert);
867   return leave_cmd (ctx, err);
868 }
869
870
871
872 static int
873 lookup_cert_by_url (assuan_context_t ctx, const char *url)
874 {
875   ctrl_t ctrl = assuan_get_pointer (ctx);
876   gpg_error_t err = 0;
877   unsigned char *value = NULL;
878   size_t valuelen;
879
880   /* Fetch single certificate given it's URL.  */
881   err = fetch_cert_by_url (ctrl, url, &value, &valuelen);
882   if (err)
883     {
884       log_error (_("fetch_cert_by_url failed: %s\n"), gpg_strerror (err));
885       goto leave;
886     }
887
888   /* Send the data, flush the buffer and then send an END. */
889   err = assuan_send_data (ctx, value, valuelen);
890   if (!err)
891     err = assuan_send_data (ctx, NULL, 0);
892   if (!err)
893     err = assuan_write_line (ctx, "END");
894   if (err)
895     {
896       log_error (_("error sending data: %s\n"), gpg_strerror (err));
897       goto leave;
898     }
899
900  leave:
901
902   return err;
903 }
904
905
906 /* Send the certificate, flush the buffer and then send an END. */
907 static gpg_error_t
908 return_one_cert (void *opaque, ksba_cert_t cert)
909 {
910   assuan_context_t ctx = opaque;
911   gpg_error_t err;
912   const unsigned char *der;
913   size_t derlen;
914
915   der = ksba_cert_get_image (cert, &derlen);
916   if (!der)
917     err = gpg_error (GPG_ERR_INV_CERT_OBJ);
918   else
919     {
920       err = assuan_send_data (ctx, der, derlen);
921       if (!err)
922         err = assuan_send_data (ctx, NULL, 0);
923       if (!err)
924         err = assuan_write_line (ctx, "END");
925     }
926   if (err)
927     log_error (_("error sending data: %s\n"), gpg_strerror (err));
928   return err;
929 }
930
931
932 /* Lookup certificates from the internal cache or using the ldap
933    servers. */
934 static int
935 lookup_cert_by_pattern (assuan_context_t ctx, char *line,
936                         int single, int cache_only)
937 {
938   ctrl_t ctrl = assuan_get_pointer (ctx);
939   gpg_error_t err = 0;
940   char *p;
941   strlist_t sl, list = NULL;
942   int truncated = 0, truncation_forced = 0;
943   int count = 0;
944   int local_count = 0;
945   unsigned char *value = NULL;
946   size_t valuelen;
947   struct ldapserver_iter ldapserver_iter;
948   cert_fetch_context_t fetch_context;
949   int any_no_data = 0;
950
951   /* Break the line down into an STRLIST */
952   for (p=line; *p; line = p)
953     {
954       while (*p && *p != ' ')
955         p++;
956       if (*p)
957         *p++ = 0;
958
959       if (*line)
960         {
961           sl = xtrymalloc (sizeof *sl + strlen (line));
962           if (!sl)
963             {
964               err = gpg_error_from_errno (errno);
965               goto leave;
966             }
967           memset (sl, 0, sizeof *sl);
968           strcpy_escaped_plus (sl->d, line);
969           sl->next = list;
970           list = sl;
971         }
972     }
973
974   /* First look through the internal cache.  The certifcates retruned
975      here are not counted towards the truncation limit.  */
976   if (single && !cache_only)
977     ; /* Do not read from the local cache in this case.  */
978   else
979     {
980       for (sl=list; sl; sl = sl->next)
981         {
982           err = get_certs_bypattern (sl->d, return_one_cert, ctx);
983           if (!err)
984             local_count++;
985           if (!err && single)
986             goto ready;
987
988           if (gpg_err_code (err) == GPG_ERR_NO_DATA)
989             {
990               err = 0;
991               if (cache_only)
992                 any_no_data = 1;
993             }
994           else if (gpg_err_code (err) == GPG_ERR_INV_NAME && !cache_only)
995             {
996               /* No real fault because the internal pattern lookup
997                  can't yet cope with all types of pattern.  */
998               err = 0;
999             }
1000           if (err)
1001             goto ready;
1002         }
1003     }
1004
1005   /* Loop over all configured servers unless we want only the
1006      certificates from the cache.  */
1007   for (ldapserver_iter_begin (&ldapserver_iter, ctrl);
1008        !cache_only && !ldapserver_iter_end_p (&ldapserver_iter)
1009          && ldapserver_iter.server->host && !truncation_forced;
1010        ldapserver_iter_next (&ldapserver_iter))
1011     {
1012       ldap_server_t ldapserver = ldapserver_iter.server;
1013
1014       if (DBG_LOOKUP)
1015         log_debug ("cmd_lookup: trying %s:%d base=%s\n",
1016                    ldapserver->host, ldapserver->port,
1017                    ldapserver->base?ldapserver->base : "[default]");
1018
1019       /* Fetch certificates matching pattern */
1020       err = start_cert_fetch (ctrl, &fetch_context, list, ldapserver);
1021       if ( gpg_err_code (err) == GPG_ERR_NO_DATA )
1022         {
1023           if (DBG_LOOKUP)
1024             log_debug ("cmd_lookup: no data\n");
1025           err = 0;
1026           any_no_data = 1;
1027           continue;
1028         }
1029       if (err)
1030         {
1031           log_error (_("start_cert_fetch failed: %s\n"), gpg_strerror (err));
1032           goto leave;
1033         }
1034
1035       /* Fetch the certificates for this query. */
1036       while (!truncation_forced)
1037         {
1038           xfree (value); value = NULL;
1039           err = fetch_next_cert (fetch_context, &value, &valuelen);
1040           if (gpg_err_code (err) == GPG_ERR_NO_DATA )
1041             {
1042               err = 0;
1043               any_no_data = 1;
1044               break; /* Ready. */
1045             }
1046           if (gpg_err_code (err) == GPG_ERR_TRUNCATED)
1047             {
1048               truncated = 1;
1049               err = 0;
1050               break;  /* Ready.  */
1051             }
1052           if (gpg_err_code (err) == GPG_ERR_EOF)
1053             {
1054               err = 0;
1055               break; /* Ready. */
1056             }
1057           if (!err && !value)
1058             {
1059               err = gpg_error (GPG_ERR_BUG);
1060               goto leave;
1061             }
1062           if (err)
1063             {
1064               log_error (_("fetch_next_cert failed: %s\n"),
1065                          gpg_strerror (err));
1066               end_cert_fetch (fetch_context);
1067               goto leave;
1068             }
1069
1070           if (DBG_LOOKUP)
1071             log_debug ("cmd_lookup: returning one cert%s\n",
1072                        truncated? " (truncated)":"");
1073
1074           /* Send the data, flush the buffer and then send an END line
1075              as a certificate delimiter. */
1076           err = assuan_send_data (ctx, value, valuelen);
1077           if (!err)
1078             err = assuan_send_data (ctx, NULL, 0);
1079           if (!err)
1080             err = assuan_write_line (ctx, "END");
1081           if (err)
1082             {
1083               log_error (_("error sending data: %s\n"), gpg_strerror (err));
1084               end_cert_fetch (fetch_context);
1085               goto leave;
1086             }
1087
1088           if (++count >= opt.max_replies )
1089             {
1090               truncation_forced = 1;
1091               log_info (_("max_replies %d exceeded\n"), opt.max_replies );
1092             }
1093           if (single)
1094             break;
1095         }
1096
1097       end_cert_fetch (fetch_context);
1098     }
1099
1100  ready:
1101   if (truncated || truncation_forced)
1102     {
1103       char str[50];
1104
1105       sprintf (str, "%d", count);
1106       assuan_write_status (ctx, "TRUNCATED", str);
1107     }
1108
1109   if (!err && !count && !local_count && any_no_data)
1110     err = gpg_error (GPG_ERR_NO_DATA);
1111
1112  leave:
1113   free_strlist (list);
1114   return err;
1115 }
1116
1117
1118 static const char hlp_lookup[] =
1119   "LOOKUP [--url] [--single] [--cache-only] <pattern>\n"
1120   "\n"
1121   "Lookup certificates matching PATTERN. With --url the pattern is\n"
1122   "expected to be one URL.\n"
1123   "\n"
1124   "If --url is not given:  To allow for multiple patterns (which are ORed)\n"
1125   "quoting is required: Spaces are translated to \"+\" or \"%20\";\n"
1126   "obviously this requires that the usual escape quoting rules are applied.\n"
1127   "\n"
1128   "If --url is given no special escaping is required because URLs are\n"
1129   "already escaped this way.\n"
1130   "\n"
1131   "If --single is given the first and only the first match will be\n"
1132   "returned.  If --cache-only is _not_ given, no local query will be\n"
1133   "done.\n"
1134   "\n"
1135   "If --cache-only is given no external lookup is done so that only\n"
1136   "certificates from the cache may get returned.";
1137 static gpg_error_t
1138 cmd_lookup (assuan_context_t ctx, char *line)
1139 {
1140   gpg_error_t err;
1141   int lookup_url, single, cache_only;
1142
1143   lookup_url = has_leading_option (line, "--url");
1144   single = has_leading_option (line, "--single");
1145   cache_only = has_leading_option (line, "--cache-only");
1146   line = skip_options (line);
1147
1148   if (lookup_url && cache_only)
1149     err = gpg_error (GPG_ERR_NOT_FOUND);
1150   else if (lookup_url && single)
1151     err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1152   else if (lookup_url)
1153     err = lookup_cert_by_url (ctx, line);
1154   else
1155     err = lookup_cert_by_pattern (ctx, line, single, cache_only);
1156
1157   return leave_cmd (ctx, err);
1158 }
1159
1160
1161 static const char hlp_loadcrl[] =
1162   "LOADCRL [--url] <filename|url>\n"
1163   "\n"
1164   "Load the CRL in the file with name FILENAME into our cache.  Note\n"
1165   "that FILENAME should be given with an absolute path because\n"
1166   "Dirmngrs cwd is not known.  With --url the CRL is directly loaded\n"
1167   "from the given URL.\n"
1168   "\n"
1169   "This command is usually used by gpgsm using the invocation \"gpgsm\n"
1170   "--call-dirmngr loadcrl <filename>\".  A direct invocation of Dirmngr\n"
1171   "is not useful because gpgsm might need to callback gpgsm to ask for\n"
1172   "the CA's certificate.";
1173 static gpg_error_t
1174 cmd_loadcrl (assuan_context_t ctx, char *line)
1175 {
1176   ctrl_t ctrl = assuan_get_pointer (ctx);
1177   gpg_error_t err = 0;
1178   int use_url = has_leading_option (line, "--url");
1179
1180   line = skip_options (line);
1181
1182   if (use_url)
1183     {
1184       ksba_reader_t reader;
1185
1186       err = crl_fetch (ctrl, line, &reader);
1187       if (err)
1188         log_error (_("fetching CRL from '%s' failed: %s\n"),
1189                    line, gpg_strerror (err));
1190       else
1191         {
1192           err = crl_cache_insert (ctrl, line, reader);
1193           if (err)
1194             log_error (_("processing CRL from '%s' failed: %s\n"),
1195                        line, gpg_strerror (err));
1196           crl_close_reader (reader);
1197         }
1198     }
1199   else
1200     {
1201       char *buf;
1202
1203       buf = xtrymalloc (strlen (line)+1);
1204       if (!buf)
1205         err = gpg_error_from_syserror ();
1206       else
1207         {
1208           strcpy_escaped_plus (buf, line);
1209           err = crl_cache_load (ctrl, buf);
1210           xfree (buf);
1211         }
1212     }
1213
1214   return leave_cmd (ctx, err);
1215 }
1216
1217
1218 static const char hlp_listcrls[] =
1219   "LISTCRLS\n"
1220   "\n"
1221   "List the content of all CRLs in a readable format.  This command is\n"
1222   "usually used by gpgsm using the invocation \"gpgsm --call-dirmngr\n"
1223   "listcrls\".  It may also be used directly using \"dirmngr\n"
1224   "--list-crls\".";
1225 static gpg_error_t
1226 cmd_listcrls (assuan_context_t ctx, char *line)
1227 {
1228   gpg_error_t err;
1229   estream_t fp;
1230
1231   (void)line;
1232
1233   fp = es_fopencookie (ctx, "w", data_line_cookie_functions);
1234   if (!fp)
1235     err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
1236   else
1237     {
1238       err = crl_cache_list (fp);
1239       es_fclose (fp);
1240     }
1241   return leave_cmd (ctx, err);
1242 }
1243
1244
1245 static const char hlp_cachecert[] =
1246   "CACHECERT\n"
1247   "\n"
1248   "Put a certificate into the internal cache.  This command might be\n"
1249   "useful if a client knows in advance certificates required for a\n"
1250   "test and wants to make sure they get added to the internal cache.\n"
1251   "It is also helpful for debugging.  To get the actual certificate,\n"
1252   "this command immediately inquires it using\n"
1253   "\n"
1254   "  INQUIRE TARGETCERT\n"
1255   "\n"
1256   "and the caller is expected to return the certificate for the\n"
1257   "request as a binary blob.";
1258 static gpg_error_t
1259 cmd_cachecert (assuan_context_t ctx, char *line)
1260 {
1261   ctrl_t ctrl = assuan_get_pointer (ctx);
1262   gpg_error_t err;
1263   ksba_cert_t cert = NULL;
1264   unsigned char *value = NULL;
1265   size_t valuelen;
1266
1267   (void)line;
1268
1269   err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1270                        &value, &valuelen, MAX_CERT_LENGTH);
1271   if (err)
1272     {
1273       log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1274       goto leave;
1275     }
1276
1277   if (!valuelen) /* No data returned; return a comprehensible error. */
1278     err = gpg_error (GPG_ERR_MISSING_CERT);
1279   else
1280     {
1281       err = ksba_cert_new (&cert);
1282       if (!err)
1283         err = ksba_cert_init_from_mem (cert, value, valuelen);
1284     }
1285   xfree (value);
1286   if(err)
1287     goto leave;
1288
1289   err = cache_cert (cert);
1290
1291  leave:
1292   ksba_cert_release (cert);
1293   return leave_cmd (ctx, err);
1294 }
1295
1296
1297 static const char hlp_validate[] =
1298   "VALIDATE\n"
1299   "\n"
1300   "Validate a certificate using the certificate validation function\n"
1301   "used internally by dirmngr.  This command is only useful for\n"
1302   "debugging.  To get the actual certificate, this command immediately\n"
1303   "inquires it using\n"
1304   "\n"
1305   "  INQUIRE TARGETCERT\n"
1306   "\n"
1307   "and the caller is expected to return the certificate for the\n"
1308   "request as a binary blob.";
1309 static gpg_error_t
1310 cmd_validate (assuan_context_t ctx, char *line)
1311 {
1312   ctrl_t ctrl = assuan_get_pointer (ctx);
1313   gpg_error_t err;
1314   ksba_cert_t cert = NULL;
1315   unsigned char *value = NULL;
1316   size_t valuelen;
1317
1318   (void)line;
1319
1320   err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1321                        &value, &valuelen, MAX_CERT_LENGTH);
1322   if (err)
1323     {
1324       log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1325       goto leave;
1326     }
1327
1328   if (!valuelen) /* No data returned; return a comprehensible error. */
1329     err = gpg_error (GPG_ERR_MISSING_CERT);
1330   else
1331     {
1332       err = ksba_cert_new (&cert);
1333       if (!err)
1334         err = ksba_cert_init_from_mem (cert, value, valuelen);
1335     }
1336   xfree (value);
1337   if(err)
1338     goto leave;
1339
1340   /* If we have this certificate already in our cache, use the cached
1341      version for validation because this will take care of any cached
1342      results. */
1343   {
1344     unsigned char fpr[20];
1345     ksba_cert_t tmpcert;
1346
1347     cert_compute_fpr (cert, fpr);
1348     tmpcert = get_cert_byfpr (fpr);
1349     if (tmpcert)
1350       {
1351         ksba_cert_release (cert);
1352         cert = tmpcert;
1353       }
1354   }
1355
1356   err = validate_cert_chain (ctrl, cert, NULL, VALIDATE_MODE_CERT, NULL);
1357
1358  leave:
1359   ksba_cert_release (cert);
1360   return leave_cmd (ctx, err);
1361 }
1362
1363 \f
1364 static const char hlp_keyserver[] =
1365   "KEYSERVER [--clear|--help] [<uri>]\n"
1366   "\n"
1367   "If called without arguments list all configured keyserver URLs.\n"
1368   "If called with option \"--clear\" remove all configured keyservers\n"
1369   "If called with an URI add this as keyserver.  Note that keyservers\n"
1370   "are configured on a per-session base.  A default keyserver may already be\n"
1371   "present, thus the \"--clear\" option must be used to get full control.\n"
1372   "If \"--clear\" and an URI are used together the clear command is\n"
1373   "obviously executed first.  A RESET command does not change the list\n"
1374   "of configured keyservers.";
1375 static gpg_error_t
1376 cmd_keyserver (assuan_context_t ctx, char *line)
1377 {
1378   ctrl_t ctrl = assuan_get_pointer (ctx);
1379   gpg_error_t err = 0;
1380   int clear_flag, add_flag, help_flag, host_flag, resolve_flag;
1381   uri_item_t item = NULL; /* gcc 4.4.5 is not able to detect that it
1382                              is always initialized.  */
1383
1384   clear_flag = has_option (line, "--clear");
1385   help_flag = has_option (line, "--help");
1386   resolve_flag = has_option (line, "--resolve");
1387   host_flag = has_option (line, "--hosttable");
1388   line = skip_options (line);
1389   add_flag = !!*line;
1390
1391   if (help_flag)
1392     {
1393       err = ks_action_help (ctrl, line);
1394       goto leave;
1395     }
1396
1397   if (resolve_flag)
1398     {
1399       err = ks_action_resolve (ctrl);
1400       if (err)
1401         goto leave;
1402     }
1403
1404   if (host_flag)
1405     {
1406       err = ks_hkp_print_hosttable (ctrl);
1407       if (err)
1408         goto leave;
1409     }
1410   if (resolve_flag || host_flag)
1411     goto leave;
1412
1413   if (add_flag)
1414     {
1415       item = xtrymalloc (sizeof *item + strlen (line));
1416       if (!item)
1417         {
1418           err = gpg_error_from_syserror ();
1419           goto leave;
1420         }
1421       item->next = NULL;
1422       item->parsed_uri = NULL;
1423       strcpy (item->uri, line);
1424
1425       err = http_parse_uri (&item->parsed_uri, line, 1);
1426       if (err)
1427         {
1428           xfree (item);
1429           goto leave;
1430         }
1431     }
1432   if (clear_flag)
1433     release_ctrl_keyservers (ctrl);
1434   if (add_flag)
1435     {
1436       item->next = ctrl->keyservers;
1437       ctrl->keyservers = item;
1438     }
1439
1440   if (!add_flag && !clear_flag && !help_flag) /* List configured keyservers.  */
1441     {
1442       uri_item_t u;
1443
1444       for (u=ctrl->keyservers; u; u = u->next)
1445         dirmngr_status (ctrl, "KEYSERVER", u->uri, NULL);
1446     }
1447   err = 0;
1448
1449  leave:
1450   return leave_cmd (ctx, err);
1451 }
1452
1453
1454 \f
1455 static const char hlp_ks_search[] =
1456   "KS_SEARCH {<pattern>}\n"
1457   "\n"
1458   "Search the configured OpenPGP keyservers (see command KEYSERVER)\n"
1459   "for keys matching PATTERN";
1460 static gpg_error_t
1461 cmd_ks_search (assuan_context_t ctx, char *line)
1462 {
1463   ctrl_t ctrl = assuan_get_pointer (ctx);
1464   gpg_error_t err;
1465   strlist_t list, sl;
1466   char *p;
1467   estream_t outfp;
1468
1469   /* No options for now.  */
1470   line = skip_options (line);
1471
1472   /* Break the line down into an strlist.  Each pattern is
1473      percent-plus escaped. */
1474   list = NULL;
1475   for (p=line; *p; line = p)
1476     {
1477       while (*p && *p != ' ')
1478         p++;
1479       if (*p)
1480         *p++ = 0;
1481       if (*line)
1482         {
1483           sl = xtrymalloc (sizeof *sl + strlen (line));
1484           if (!sl)
1485             {
1486               err = gpg_error_from_syserror ();
1487               free_strlist (list);
1488               goto leave;
1489             }
1490           sl->flags = 0;
1491           strcpy_escaped_plus (sl->d, line);
1492           sl->next = list;
1493           list = sl;
1494         }
1495     }
1496
1497   /* Setup an output stream and perform the search.  */
1498   outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
1499   if (!outfp)
1500     err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
1501   else
1502     {
1503       err = ks_action_search (ctrl, list, outfp);
1504       es_fclose (outfp);
1505     }
1506
1507  leave:
1508   return leave_cmd (ctx, err);
1509 }
1510
1511
1512 \f
1513 static const char hlp_ks_get[] =
1514   "KS_GET {<pattern>}\n"
1515   "\n"
1516   "Get the keys matching PATTERN from the configured OpenPGP keyservers\n"
1517   "(see command KEYSERVER).  Each pattern should be a keyid or a fingerprint";
1518 static gpg_error_t
1519 cmd_ks_get (assuan_context_t ctx, char *line)
1520 {
1521   ctrl_t ctrl = assuan_get_pointer (ctx);
1522   gpg_error_t err;
1523   strlist_t list, sl;
1524   char *p;
1525   estream_t outfp;
1526
1527   /* No options for now.  */
1528   line = skip_options (line);
1529
1530   /* Break the line down into an strlist.  Each pattern is by
1531      definition percent-plus escaped.  However we only support keyids
1532      and fingerprints and thus the client has no need to apply the
1533      escaping.  */
1534   list = NULL;
1535   for (p=line; *p; line = p)
1536     {
1537       while (*p && *p != ' ')
1538         p++;
1539       if (*p)
1540         *p++ = 0;
1541       if (*line)
1542         {
1543           sl = xtrymalloc (sizeof *sl + strlen (line));
1544           if (!sl)
1545             {
1546               err = gpg_error_from_syserror ();
1547               free_strlist (list);
1548               goto leave;
1549             }
1550           sl->flags = 0;
1551           strcpy_escaped_plus (sl->d, line);
1552           sl->next = list;
1553           list = sl;
1554         }
1555     }
1556
1557   /* Setup an output stream and perform the get.  */
1558   outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
1559   if (!outfp)
1560     err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
1561   else
1562     {
1563       err = ks_action_get (ctrl, list, outfp);
1564       es_fclose (outfp);
1565     }
1566
1567  leave:
1568   return leave_cmd (ctx, err);
1569 }
1570
1571
1572 static const char hlp_ks_fetch[] =
1573   "KS_FETCH <URL>\n"
1574   "\n"
1575   "Get the key(s) from URL.";
1576 static gpg_error_t
1577 cmd_ks_fetch (assuan_context_t ctx, char *line)
1578 {
1579   ctrl_t ctrl = assuan_get_pointer (ctx);
1580   gpg_error_t err;
1581   estream_t outfp;
1582
1583   /* No options for now.  */
1584   line = skip_options (line);
1585
1586   /* Setup an output stream and perform the get.  */
1587   outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
1588   if (!outfp)
1589     err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
1590   else
1591     {
1592       err = ks_action_fetch (ctrl, line, outfp);
1593       es_fclose (outfp);
1594     }
1595
1596   return leave_cmd (ctx, err);
1597 }
1598
1599
1600 \f
1601 static const char hlp_ks_put[] =
1602   "KS_PUT\n"
1603   "\n"
1604   "Send a key to the configured OpenPGP keyservers.  The actual key material\n"
1605   "is then requested by Dirmngr using\n"
1606   "\n"
1607   "  INQUIRE KEYBLOCK\n"
1608   "\n"
1609   "The client shall respond with a binary version of the keyblock.  For LDAP\n"
1610   "keyservers Dirmngr may ask for meta information of the provided keyblock\n"
1611   "using:\n"
1612   "\n"
1613   "  INQUIRE KEYBLOCK_INFO\n"
1614   "\n"
1615   "The client shall respond with a colon delimited info lines";
1616 static gpg_error_t
1617 cmd_ks_put (assuan_context_t ctx, char *line)
1618 {
1619   ctrl_t ctrl = assuan_get_pointer (ctx);
1620   gpg_error_t err;
1621   unsigned char *value = NULL;
1622   size_t valuelen;
1623   unsigned char *info = NULL;
1624   size_t infolen;
1625
1626   /* No options for now.  */
1627   line = skip_options (line);
1628
1629   /* Ask for the key material.  */
1630   err = assuan_inquire (ctx, "KEYBLOCK",
1631                         &value, &valuelen, MAX_KEYBLOCK_LENGTH);
1632   if (err)
1633     {
1634       log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1635       goto leave;
1636     }
1637
1638   if (!valuelen) /* No data returned; return a comprehensible error. */
1639     {
1640       err = gpg_error (GPG_ERR_MISSING_CERT);
1641       goto leave;
1642     }
1643
1644   /* Ask for the key meta data. Not actually needed for HKP servers
1645      but we do it anyway test the client implementaion.  */
1646   err = assuan_inquire (ctx, "KEYBLOCK_INFO",
1647                         &info, &infolen, MAX_KEYBLOCK_LENGTH);
1648   if (err)
1649     {
1650       log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1651       goto leave;
1652     }
1653
1654   /* Send the key.  */
1655   err = ks_action_put (ctrl, value, valuelen);
1656
1657  leave:
1658   xfree (info);
1659   xfree (value);
1660   return leave_cmd (ctx, err);
1661 }
1662
1663
1664
1665 \f
1666 static const char hlp_getinfo[] =
1667   "GETINFO <what>\n"
1668   "\n"
1669   "Multi purpose command to return certain information.  \n"
1670   "Supported values of WHAT are:\n"
1671   "\n"
1672   "version     - Return the version of the program.\n"
1673   "pid         - Return the process id of the server.\n"
1674   "\n"
1675   "socket_name - Return the name of the socket.\n";
1676 static gpg_error_t
1677 cmd_getinfo (assuan_context_t ctx, char *line)
1678 {
1679   gpg_error_t err;
1680
1681   if (!strcmp (line, "version"))
1682     {
1683       const char *s = VERSION;
1684       err = assuan_send_data (ctx, s, strlen (s));
1685     }
1686   else if (!strcmp (line, "pid"))
1687     {
1688       char numbuf[50];
1689
1690       snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
1691       err = assuan_send_data (ctx, numbuf, strlen (numbuf));
1692     }
1693   else if (!strcmp (line, "socket_name"))
1694     {
1695       const char *s = dirmngr_socket_name ();
1696
1697       if (s)
1698         err = assuan_send_data (ctx, s, strlen (s));
1699       else
1700         err = gpg_error (GPG_ERR_NO_DATA);
1701     }
1702   else
1703     err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
1704
1705   return leave_cmd (ctx, err);
1706 }
1707
1708
1709 \f
1710 static const char hlp_killdirmngr[] =
1711   "KILLDIRMNGR\n"
1712   "\n"
1713   "This command allows a user - given sufficient permissions -\n"
1714   "to kill this dirmngr process.\n";
1715 static gpg_error_t
1716 cmd_killdirmngr (assuan_context_t ctx, char *line)
1717 {
1718   ctrl_t ctrl = assuan_get_pointer (ctx);
1719
1720   (void)line;
1721
1722   if (opt.system_daemon)
1723     {
1724       if (opt.system_service)
1725         return set_error (GPG_ERR_NOT_SUPPORTED,
1726                           "can't do that whilst running as system service");
1727 #ifndef HAVE_W32_SYSTEM
1728       {
1729         gpg_err_code_t ec;
1730         assuan_peercred_t cred;
1731
1732         ec = gpg_err_code (assuan_get_peercred (ctx, &cred));
1733         if (!ec && cred->uid)
1734           ec = GPG_ERR_EPERM; /* Only root may terminate.  */
1735         if (ec)
1736           return set_error (ec, "no permission to kill this process");
1737       }
1738 #endif
1739     }
1740
1741   ctrl->server_local->stopme = 1;
1742   return gpg_error (GPG_ERR_EOF);
1743 }
1744
1745
1746 static const char hlp_reloaddirmngr[] =
1747   "RELOADDIRMNGR\n"
1748   "\n"
1749   "This command is an alternative to SIGHUP\n"
1750   "to reload the configuration.";
1751 static gpg_error_t
1752 cmd_reloaddirmngr (assuan_context_t ctx, char *line)
1753 {
1754   (void)ctx;
1755   (void)line;
1756
1757  if (opt.system_daemon)
1758     {
1759 #ifndef HAVE_W32_SYSTEM
1760       {
1761         gpg_err_code_t ec;
1762         assuan_peercred_t cred;
1763
1764         ec = gpg_err_code (assuan_get_peercred (ctx, &cred));
1765         if (!ec && cred->uid)
1766           ec = GPG_ERR_EPERM; /* Only root may terminate.  */
1767         if (ec)
1768           return set_error (ec, "no permission to reload this process");
1769       }
1770 #endif
1771     }
1772
1773   dirmngr_sighup_action ();
1774   return 0;
1775 }
1776
1777
1778
1779 \f
1780 /* Tell the assuan library about our commands. */
1781 static int
1782 register_commands (assuan_context_t ctx)
1783 {
1784   static struct {
1785     const char *name;
1786     assuan_handler_t handler;
1787     const char * const help;
1788   } table[] = {
1789     { "LDAPSERVER", cmd_ldapserver, hlp_ldapserver },
1790     { "ISVALID",    cmd_isvalid,    hlp_isvalid },
1791     { "CHECKCRL",   cmd_checkcrl,   hlp_checkcrl },
1792     { "CHECKOCSP",  cmd_checkocsp,  hlp_checkocsp },
1793     { "LOOKUP",     cmd_lookup,     hlp_lookup },
1794     { "LOADCRL",    cmd_loadcrl,    hlp_loadcrl },
1795     { "LISTCRLS",   cmd_listcrls,   hlp_listcrls },
1796     { "CACHECERT",  cmd_cachecert,  hlp_cachecert },
1797     { "VALIDATE",   cmd_validate,   hlp_validate },
1798     { "KEYSERVER",  cmd_keyserver,  hlp_keyserver },
1799     { "KS_SEARCH",  cmd_ks_search,  hlp_ks_search },
1800     { "KS_GET",     cmd_ks_get,     hlp_ks_get },
1801     { "KS_FETCH",   cmd_ks_fetch,   hlp_ks_fetch },
1802     { "KS_PUT",     cmd_ks_put,     hlp_ks_put },
1803     { "GETINFO",    cmd_getinfo,    hlp_getinfo },
1804     { "KILLDIRMNGR",cmd_killdirmngr,hlp_killdirmngr },
1805     { "RELOADDIRMNGR",cmd_reloaddirmngr,hlp_reloaddirmngr },
1806     { NULL, NULL }
1807   };
1808   int i, j, rc;
1809
1810   for (i=j=0; table[i].name; i++)
1811     {
1812       rc = assuan_register_command (ctx, table[i].name, table[i].handler,
1813                                     table[i].help);
1814       if (rc)
1815         return rc;
1816     }
1817   return 0;
1818 }
1819
1820
1821 /* Note that we do not reset the list of configured keyservers.  */
1822 static gpg_error_t
1823 reset_notify (assuan_context_t ctx, char *line)
1824 {
1825   ctrl_t ctrl = assuan_get_pointer (ctx);
1826   (void)line;
1827
1828   ldapserver_list_free (ctrl->server_local->ldapservers);
1829   ctrl->server_local->ldapservers = NULL;
1830   return 0;
1831 }
1832
1833
1834 /* Startup the server and run the main command loop.  With FD = -1
1835    used stdin/stdout. */
1836 void
1837 start_command_handler (assuan_fd_t fd)
1838 {
1839   static const char hello[] = "Dirmngr " VERSION " at your service";
1840   static char *hello_line;
1841   int rc;
1842   assuan_context_t ctx;
1843   ctrl_t ctrl;
1844
1845   ctrl = xtrycalloc (1, sizeof *ctrl);
1846   if (ctrl)
1847     ctrl->server_local = xtrycalloc (1, sizeof *ctrl->server_local);
1848   if (!ctrl || !ctrl->server_local)
1849     {
1850       log_error (_("can't allocate control structure: %s\n"),
1851                  strerror (errno));
1852       xfree (ctrl);
1853       return;
1854     }
1855
1856   dirmngr_init_default_ctrl (ctrl);
1857
1858   rc = assuan_new (&ctx);
1859   if (rc)
1860     {
1861       log_error (_("failed to allocate assuan context: %s\n"),
1862                  gpg_strerror (rc));
1863       dirmngr_exit (2);
1864     }
1865
1866   if (fd == ASSUAN_INVALID_FD)
1867     {
1868       assuan_fd_t filedes[2];
1869
1870       filedes[0] = assuan_fdopen (0);
1871       filedes[1] = assuan_fdopen (1);
1872       rc = assuan_init_pipe_server (ctx, filedes);
1873     }
1874   else
1875     {
1876       rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED);
1877     }
1878
1879   if (rc)
1880     {
1881       assuan_release (ctx);
1882       log_error (_("failed to initialize the server: %s\n"),
1883                  gpg_strerror(rc));
1884       dirmngr_exit (2);
1885     }
1886
1887   rc = register_commands (ctx);
1888   if (rc)
1889     {
1890       log_error (_("failed to the register commands with Assuan: %s\n"),
1891                  gpg_strerror(rc));
1892       dirmngr_exit (2);
1893     }
1894
1895
1896   if (!hello_line)
1897     {
1898       size_t n;
1899       const char *cfgname;
1900
1901       cfgname = opt.config_filename? opt.config_filename : "[none]";
1902
1903       n = (30 + strlen (opt.homedir) + strlen (cfgname)
1904            + strlen (hello) + 1);
1905       hello_line = xmalloc (n+1);
1906       snprintf (hello_line, n,
1907                 "Home: %s\n"
1908                 "Config: %s\n"
1909                 "%s",
1910                 opt.homedir,
1911                 cfgname,
1912                 hello);
1913       hello_line[n] = 0;
1914     }
1915
1916   ctrl->server_local->assuan_ctx = ctx;
1917   assuan_set_pointer (ctx, ctrl);
1918
1919   assuan_set_hello_line (ctx, hello_line);
1920   assuan_register_option_handler (ctx, option_handler);
1921   assuan_register_reset_notify (ctx, reset_notify);
1922
1923   for (;;)
1924     {
1925       rc = assuan_accept (ctx);
1926       if (rc == -1)
1927         break;
1928       if (rc)
1929         {
1930           log_info (_("Assuan accept problem: %s\n"), gpg_strerror (rc));
1931           break;
1932         }
1933
1934 #ifndef HAVE_W32_SYSTEM
1935       if (opt.verbose)
1936         {
1937           assuan_peercred_t peercred;
1938
1939           if (!assuan_get_peercred (ctx, &peercred))
1940             log_info ("connection from process %ld (%ld:%ld)\n",
1941                       (long)peercred->pid, (long)peercred->uid,
1942                       (long)peercred->gid);
1943         }
1944 #endif
1945
1946       rc = assuan_process (ctx);
1947       if (rc)
1948         {
1949           log_info (_("Assuan processing failed: %s\n"), gpg_strerror (rc));
1950           continue;
1951         }
1952     }
1953
1954   ldap_wrapper_connection_cleanup (ctrl);
1955
1956   ldapserver_list_free (ctrl->server_local->ldapservers);
1957   ctrl->server_local->ldapservers = NULL;
1958
1959   ctrl->server_local->assuan_ctx = NULL;
1960   assuan_release (ctx);
1961
1962   if (ctrl->server_local->stopme)
1963     dirmngr_exit (0);
1964
1965   if (ctrl->refcount)
1966     log_error ("oops: connection control structure still referenced (%d)\n",
1967                ctrl->refcount);
1968   else
1969     {
1970       release_ctrl_ocsp_certs (ctrl);
1971       xfree (ctrl->server_local);
1972       xfree (ctrl);
1973     }
1974 }
1975
1976
1977 /* Send a status line back to the client.  KEYWORD is the status
1978    keyword, the optional string arguments are blank separated added to
1979    the line, the last argument must be a NULL. */
1980 gpg_error_t
1981 dirmngr_status (ctrl_t ctrl, const char *keyword, ...)
1982 {
1983   gpg_error_t err = 0;
1984   va_list arg_ptr;
1985   const char *text;
1986
1987   va_start (arg_ptr, keyword);
1988
1989   if (ctrl->server_local)
1990     {
1991       assuan_context_t ctx = ctrl->server_local->assuan_ctx;
1992       char buf[950], *p;
1993       size_t n;
1994
1995       p = buf;
1996       n = 0;
1997       while ( (text = va_arg (arg_ptr, const char *)) )
1998         {
1999           if (n)
2000             {
2001               *p++ = ' ';
2002               n++;
2003             }
2004           for ( ; *text && n < DIM (buf)-2; n++)
2005             *p++ = *text++;
2006         }
2007       *p = 0;
2008       err = assuan_write_status (ctx, keyword, buf);
2009     }
2010
2011   va_end (arg_ptr);
2012   return err;
2013 }
2014
2015
2016 /* Print a help status line.  TEXTLEN gives the length of the text
2017    from TEXT to be printed.  The function splits text at LFs.  */
2018 gpg_error_t
2019 dirmngr_status_help (ctrl_t ctrl, const char *text)
2020 {
2021   gpg_error_t err = 0;
2022
2023   if (ctrl->server_local)
2024     {
2025       assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2026       char buf[950], *p;
2027       size_t n;
2028
2029       do
2030         {
2031           p = buf;
2032           n = 0;
2033           for ( ; *text && *text != '\n' && n < DIM (buf)-2; n++)
2034             *p++ = *text++;
2035           if (*text == '\n')
2036             text++;
2037           *p = 0;
2038           err = assuan_write_status (ctx, "#", buf);
2039         }
2040       while (!err && *text);
2041     }
2042
2043   return err;
2044 }
2045
2046 /* Send a tick progress indicator back.  Fixme: This is only does for
2047    the currently active channel.  */
2048 gpg_error_t
2049 dirmngr_tick (ctrl_t ctrl)
2050 {
2051   static time_t next_tick = 0;
2052   gpg_error_t err = 0;
2053   time_t now = time (NULL);
2054
2055   if (!next_tick)
2056     {
2057       next_tick = now + 1;
2058     }
2059   else if ( now > next_tick )
2060     {
2061       if (ctrl)
2062         {
2063           err = dirmngr_status (ctrl, "PROGRESS", "tick", "? 0 0", NULL);
2064           if (err)
2065             {
2066               /* Take this as in indication for a cancel request.  */
2067               err = gpg_error (GPG_ERR_CANCELED);
2068             }
2069           now = time (NULL);
2070         }
2071
2072       next_tick = now + 1;
2073     }
2074   return err;
2075 }