dirmngr: Add option --no-crl to the VALIDATE cmd.
[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, 2015 g10 Code GmbH
4  * Copyright (C) 2014, 2015, 2016 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 <https://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 #include "dirmngr.h"
34 #include <assuan.h>
35
36 #include "crlcache.h"
37 #include "crlfetch.h"
38 #if USE_LDAP
39 # include "ldapserver.h"
40 #endif
41 #include "ocsp.h"
42 #include "certcache.h"
43 #include "validate.h"
44 #include "misc.h"
45 #if USE_LDAP
46 # include "ldap-wrapper.h"
47 #endif
48 #include "ks-action.h"
49 #include "ks-engine.h"  /* (ks_hkp_print_hosttable) */
50 #if USE_LDAP
51 # include "ldap-parse-uri.h"
52 #endif
53 #include "dns-stuff.h"
54 #include "mbox-util.h"
55 #include "zb32.h"
56 #include "server-help.h"
57
58 /* To avoid DoS attacks we limit the size of a certificate to
59    something reasonable.  The DoS was actually only an issue back when
60    Dirmngr was a system service and not a user service. */
61 #define MAX_CERT_LENGTH (16*1024)
62
63 /* The limit for the CERTLIST inquiry.  We allow for up to 20
64  * certificates but also take PEM encoding into account.  */
65 #define MAX_CERTLIST_LENGTH ((MAX_CERT_LENGTH * 20 * 4)/3)
66
67 /* The same goes for OpenPGP keyblocks, but here we need to allow for
68    much longer blocks; a 200k keyblock is not too unusual for keys
69    with a lot of signatures (e.g. 0x5b0358a2).  9C31503C6D866396 even
70    has 770 KiB as of 2015-08-23.  To avoid adding a runtime option we
71    now use 20MiB which should really be enough.  Well, a key with
72    several pictures could be larger (the parser as a 18MiB limit for
73    attribute packets) but it won't be nice to the keyservers to send
74    them such large blobs.  */
75 #define MAX_KEYBLOCK_LENGTH (20*1024*1024)
76
77
78 #define PARM_ERROR(t) assuan_set_error (ctx, \
79                                         gpg_error (GPG_ERR_ASS_PARAMETER), (t))
80 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
81
82
83
84 /* Control structure per connection. */
85 struct server_local_s
86 {
87   /* Data used to associate an Assuan context with local server data */
88   assuan_context_t assuan_ctx;
89
90   /* Per-session LDAP servers.  */
91   ldap_server_t ldapservers;
92
93   /* Per-session list of keyservers.  */
94   uri_item_t keyservers;
95
96   /* If this flag is set to true this dirmngr process will be
97      terminated after the end of this session.  */
98   int stopme;
99
100   /* State variable private to is_tor_running.  */
101   int tor_state;
102
103   /* If the first both flags are set the assuan logging of data lines
104    * is suppressed.  The count variable is used to show the number of
105    * non-logged bytes.  */
106   size_t inhibit_data_logging_count;
107   unsigned int inhibit_data_logging : 1;
108   unsigned int inhibit_data_logging_now : 1;
109 };
110
111
112 /* Cookie definition for assuan data line output.  */
113 static gpgrt_ssize_t data_line_cookie_write (void *cookie,
114                                              const void *buffer, size_t size);
115 static int data_line_cookie_close (void *cookie);
116 static es_cookie_io_functions_t data_line_cookie_functions =
117   {
118     NULL,
119     data_line_cookie_write,
120     NULL,
121     data_line_cookie_close
122   };
123
124
125
126
127 \f
128 /* Accessor for the local ldapservers variable. */
129 ldap_server_t
130 get_ldapservers_from_ctrl (ctrl_t ctrl)
131 {
132   if (ctrl && ctrl->server_local)
133     return ctrl->server_local->ldapservers;
134   else
135     return NULL;
136 }
137
138 /* Release an uri_item_t list.  */
139 static void
140 release_uri_item_list (uri_item_t list)
141 {
142   while (list)
143     {
144       uri_item_t tmp = list->next;
145       http_release_parsed_uri (list->parsed_uri);
146       xfree (list);
147       list = tmp;
148     }
149 }
150
151 /* Release all configured keyserver info from CTRL.  */
152 void
153 release_ctrl_keyservers (ctrl_t ctrl)
154 {
155   if (! ctrl->server_local)
156     return;
157
158   release_uri_item_list (ctrl->server_local->keyservers);
159   ctrl->server_local->keyservers = NULL;
160 }
161
162
163
164 /* Helper to print a message while leaving a command.  */
165 static gpg_error_t
166 leave_cmd (assuan_context_t ctx, gpg_error_t err)
167 {
168   if (err)
169     {
170       const char *name = assuan_get_command_name (ctx);
171       if (!name)
172         name = "?";
173       if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT)
174         log_error ("command '%s' failed: %s\n", name,
175                    gpg_strerror (err));
176       else
177         log_error ("command '%s' failed: %s <%s>\n", name,
178                    gpg_strerror (err), gpg_strsource (err));
179     }
180   return err;
181 }
182
183
184 /* This is a wrapper around assuan_send_data which makes debugging the
185    output in verbose mode easier.  */
186 static gpg_error_t
187 data_line_write (assuan_context_t ctx, const void *buffer_arg, size_t size)
188 {
189   ctrl_t ctrl = assuan_get_pointer (ctx);
190   const char *buffer = buffer_arg;
191   gpg_error_t err;
192
193   /* If we do not want logging, enable it it here.  */
194   if (ctrl && ctrl->server_local && ctrl->server_local->inhibit_data_logging)
195     ctrl->server_local->inhibit_data_logging_now = 1;
196
197   if (opt.verbose && buffer && size)
198     {
199       /* Ease reading of output by sending a physical line at each LF.  */
200       const char *p;
201       size_t n, nbytes;
202
203       nbytes = size;
204       do
205         {
206           p = memchr (buffer, '\n', nbytes);
207           n = p ? (p - buffer) + 1 : nbytes;
208           err = assuan_send_data (ctx, buffer, n);
209           if (err)
210             {
211               gpg_err_set_errno (EIO);
212               goto leave;
213             }
214           buffer += n;
215           nbytes -= n;
216           if (nbytes && (err=assuan_send_data (ctx, NULL, 0))) /* Flush line. */
217             {
218               gpg_err_set_errno (EIO);
219               goto leave;
220             }
221         }
222       while (nbytes);
223     }
224   else
225     {
226       err = assuan_send_data (ctx, buffer, size);
227       if (err)
228         {
229           gpg_err_set_errno (EIO);  /* For use by data_line_cookie_write.  */
230           goto leave;
231         }
232     }
233
234  leave:
235   if (ctrl && ctrl->server_local && ctrl->server_local->inhibit_data_logging)
236     {
237       ctrl->server_local->inhibit_data_logging_now = 0;
238       ctrl->server_local->inhibit_data_logging_count += size;
239     }
240
241   return err;
242 }
243
244
245 /* A write handler used by es_fopencookie to write assuan data
246    lines.  */
247 static gpgrt_ssize_t
248 data_line_cookie_write (void *cookie, const void *buffer, size_t size)
249 {
250   assuan_context_t ctx = cookie;
251
252   if (data_line_write (ctx, buffer, size))
253     return -1;
254   return (gpgrt_ssize_t)size;
255 }
256
257
258 static int
259 data_line_cookie_close (void *cookie)
260 {
261   assuan_context_t ctx = cookie;
262
263   if (DBG_IPC)
264     {
265       ctrl_t ctrl = assuan_get_pointer (ctx);
266
267       if (ctrl && ctrl->server_local
268           && ctrl->server_local->inhibit_data_logging
269           && ctrl->server_local->inhibit_data_logging_count)
270         log_debug ("(%zu bytes sent via D lines not shown)\n",
271                    ctrl->server_local->inhibit_data_logging_count);
272     }
273   if (assuan_send_data (ctx, NULL, 0))
274     {
275       gpg_err_set_errno (EIO);
276       return -1;
277     }
278
279   return 0;
280 }
281
282
283 /* Copy the % and + escaped string S into the buffer D and replace the
284    escape sequences.  Note, that it is sufficient to allocate the
285    target string D as long as the source string S, i.e.: strlen(s)+1.
286    Note further that if S contains an escaped binary Nul the resulting
287    string D will contain the 0 as well as all other characters but it
288    will be impossible to know whether this is the original EOS or a
289    copied Nul. */
290 static void
291 strcpy_escaped_plus (char *d, const unsigned char *s)
292 {
293   while (*s)
294     {
295       if (*s == '%' && s[1] && s[2])
296         {
297           s++;
298           *d++ = xtoi_2 ( s);
299           s += 2;
300         }
301       else if (*s == '+')
302         *d++ = ' ', s++;
303       else
304         *d++ = *s++;
305     }
306   *d = 0;
307 }
308
309
310 /* This function returns true if a Tor server is running.  The sattus
311    is cached for the current connection.  */
312 static int
313 is_tor_running (ctrl_t ctrl)
314 {
315   /* Check whether we can connect to the proxy.  */
316
317   if (!ctrl || !ctrl->server_local)
318     return 0; /* Ooops.  */
319
320   if (!ctrl->server_local->tor_state)
321     {
322       assuan_fd_t sock;
323
324       sock = assuan_sock_connect_byname (NULL, 0, 0, NULL, ASSUAN_SOCK_TOR);
325       if (sock == ASSUAN_INVALID_FD)
326         ctrl->server_local->tor_state = -1; /* Not running.  */
327       else
328         {
329           assuan_sock_close (sock);
330           ctrl->server_local->tor_state = 1; /* Running.  */
331         }
332     }
333   return (ctrl->server_local->tor_state > 0);
334 }
335
336
337 /* Return an error if the assuan context does not belong to the owner
338    of the process or to root.  On error FAILTEXT is set as Assuan
339    error string.  */
340 static gpg_error_t
341 check_owner_permission (assuan_context_t ctx, const char *failtext)
342 {
343 #ifdef HAVE_W32_SYSTEM
344   /* Under Windows the dirmngr is always run under the control of the
345      user.  */
346   (void)ctx;
347   (void)failtext;
348 #else
349   gpg_err_code_t ec;
350   assuan_peercred_t cred;
351
352   ec = gpg_err_code (assuan_get_peercred (ctx, &cred));
353   if (!ec && cred->uid && cred->uid != getuid ())
354     ec = GPG_ERR_EPERM;
355   if (ec)
356     return set_error (ec, failtext);
357 #endif
358   return 0;
359 }
360
361
362
363 /* Common code for get_cert_local and get_issuer_cert_local. */
364 static ksba_cert_t
365 do_get_cert_local (ctrl_t ctrl, const char *name, const char *command)
366 {
367   unsigned char *value;
368   size_t valuelen;
369   int rc;
370   char *buf;
371   ksba_cert_t cert;
372
373   if (name)
374     buf = xstrconcat (command, " ", name, NULL);
375   else
376     buf = xstrdup (command);
377
378   rc = assuan_inquire (ctrl->server_local->assuan_ctx, buf,
379                        &value, &valuelen, MAX_CERT_LENGTH);
380   xfree (buf);
381   if (rc)
382     {
383       log_error (_("assuan_inquire(%s) failed: %s\n"),
384                  command, gpg_strerror (rc));
385       return NULL;
386     }
387
388   if (!valuelen)
389     {
390       xfree (value);
391       return NULL;
392     }
393
394   rc = ksba_cert_new (&cert);
395   if (!rc)
396     {
397       rc = ksba_cert_init_from_mem (cert, value, valuelen);
398       if (rc)
399         {
400           ksba_cert_release (cert);
401           cert = NULL;
402         }
403     }
404   xfree (value);
405   return cert;
406 }
407
408
409
410 /* Ask back to return a certificate for NAME, given as a regular gpgsm
411  * certificate identifier (e.g. fingerprint or one of the other
412  * methods).  Alternatively, NULL may be used for NAME to return the
413  * current target certificate.  Either return the certificate in a
414  * KSBA object or NULL if it is not available.  */
415 ksba_cert_t
416 get_cert_local (ctrl_t ctrl, const char *name)
417 {
418   if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
419     {
420       if (opt.debug)
421         log_debug ("get_cert_local called w/o context\n");
422       return NULL;
423     }
424   return do_get_cert_local (ctrl, name, "SENDCERT");
425
426 }
427
428
429 /* Ask back to return the issuing certificate for NAME, given as a
430  * regular gpgsm certificate identifier (e.g. fingerprint or one
431  * of the other methods).  Alternatively, NULL may be used for NAME to
432  * return the current target certificate. Either return the certificate
433  * in a KSBA object or NULL if it is not available.  */
434 ksba_cert_t
435 get_issuing_cert_local (ctrl_t ctrl, const char *name)
436 {
437   if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
438     {
439       if (opt.debug)
440         log_debug ("get_issuing_cert_local called w/o context\n");
441       return NULL;
442     }
443   return do_get_cert_local (ctrl, name, "SENDISSUERCERT");
444 }
445
446
447 /* Ask back to return a certificate with subject NAME and a
448  * subjectKeyIdentifier of KEYID. */
449 ksba_cert_t
450 get_cert_local_ski (ctrl_t ctrl, const char *name, ksba_sexp_t keyid)
451 {
452   unsigned char *value;
453   size_t valuelen;
454   int rc;
455   char *buf;
456   ksba_cert_t cert;
457   char *hexkeyid;
458
459   if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
460     {
461       if (opt.debug)
462         log_debug ("get_cert_local_ski called w/o context\n");
463       return NULL;
464     }
465   if (!name || !keyid)
466     {
467       log_debug ("get_cert_local_ski called with insufficient arguments\n");
468       return NULL;
469     }
470
471   hexkeyid = serial_hex (keyid);
472   if (!hexkeyid)
473     {
474       log_debug ("serial_hex() failed\n");
475       return NULL;
476     }
477
478   buf = strconcat ("SENDCERT_SKI ", hexkeyid, " /", name, NULL);
479   if (!buf)
480     {
481       log_error ("can't allocate enough memory: %s\n", strerror (errno));
482       xfree (hexkeyid);
483       return NULL;
484     }
485   xfree (hexkeyid);
486
487   rc = assuan_inquire (ctrl->server_local->assuan_ctx, buf,
488                        &value, &valuelen, MAX_CERT_LENGTH);
489   xfree (buf);
490   if (rc)
491     {
492       log_error (_("assuan_inquire(%s) failed: %s\n"), "SENDCERT_SKI",
493                  gpg_strerror (rc));
494       return NULL;
495     }
496
497   if (!valuelen)
498     {
499       xfree (value);
500       return NULL;
501     }
502
503   rc = ksba_cert_new (&cert);
504   if (!rc)
505     {
506       rc = ksba_cert_init_from_mem (cert, value, valuelen);
507       if (rc)
508         {
509           ksba_cert_release (cert);
510           cert = NULL;
511         }
512     }
513   xfree (value);
514   return cert;
515 }
516
517
518 /* Ask the client via an inquiry to check the istrusted status of the
519    certificate specified by the hexified fingerprint HEXFPR.  Returns
520    0 if the certificate is trusted by the client or an error code.  */
521 gpg_error_t
522 get_istrusted_from_client (ctrl_t ctrl, const char *hexfpr)
523 {
524   unsigned char *value;
525   size_t valuelen;
526   int rc;
527   char request[100];
528
529   if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx
530       || !hexfpr)
531     return gpg_error (GPG_ERR_INV_ARG);
532
533   snprintf (request, sizeof request, "ISTRUSTED %s", hexfpr);
534   rc = assuan_inquire (ctrl->server_local->assuan_ctx, request,
535                        &value, &valuelen, 100);
536   if (rc)
537     {
538       log_error (_("assuan_inquire(%s) failed: %s\n"),
539                  request, gpg_strerror (rc));
540       return rc;
541     }
542   /* The expected data is: "1" or "1 cruft" (not a C-string).  */
543   if (valuelen && *value == '1' && (valuelen == 1 || spacep (value+1)))
544     rc = 0;
545   else
546     rc = gpg_error (GPG_ERR_NOT_TRUSTED);
547   xfree (value);
548   return rc;
549 }
550
551
552
553
554 /* Ask the client to return the certificate associated with the
555    current command. This is sometimes needed because the client usually
556    sends us just the cert ID, assuming that the request can be
557    satisfied from the cache, where the cert ID is used as key. */
558 static int
559 inquire_cert_and_load_crl (assuan_context_t ctx)
560 {
561   ctrl_t ctrl = assuan_get_pointer (ctx);
562   gpg_error_t err;
563   unsigned char *value = NULL;
564   size_t valuelen;
565   ksba_cert_t cert = NULL;
566
567   err = assuan_inquire( ctx, "SENDCERT", &value, &valuelen, 0);
568   if (err)
569     return err;
570
571 /*   { */
572 /*     FILE *fp = fopen ("foo.der", "r"); */
573 /*     value = xmalloc (2000); */
574 /*     valuelen = fread (value, 1, 2000, fp); */
575 /*     fclose (fp); */
576 /*   } */
577
578   if (!valuelen) /* No data returned; return a comprehensible error. */
579     return gpg_error (GPG_ERR_MISSING_CERT);
580
581   err = ksba_cert_new (&cert);
582   if (err)
583     goto leave;
584   err = ksba_cert_init_from_mem (cert, value, valuelen);
585   if(err)
586     goto leave;
587   xfree (value); value = NULL;
588
589   err = crl_cache_reload_crl (ctrl, cert);
590
591  leave:
592   ksba_cert_release (cert);
593   xfree (value);
594   return err;
595 }
596
597
598 /* Handle OPTION commands. */
599 static gpg_error_t
600 option_handler (assuan_context_t ctx, const char *key, const char *value)
601 {
602   ctrl_t ctrl = assuan_get_pointer (ctx);
603   gpg_error_t err = 0;
604
605   if (!strcmp (key, "force-crl-refresh"))
606     {
607       int i = *value? atoi (value) : 0;
608       ctrl->force_crl_refresh = i;
609     }
610   else if (!strcmp (key, "audit-events"))
611     {
612       int i = *value? atoi (value) : 0;
613       ctrl->audit_events = i;
614     }
615   else if (!strcmp (key, "http-proxy"))
616     {
617       xfree (ctrl->http_proxy);
618       if (!*value || !strcmp (value, "none"))
619         ctrl->http_proxy = NULL;
620       else if (!(ctrl->http_proxy = xtrystrdup (value)))
621         err = gpg_error_from_syserror ();
622     }
623   else if (!strcmp (key, "honor-keyserver-url-used"))
624     {
625       /* Return an error if we are running in Tor mode.  */
626       if (dirmngr_use_tor ())
627         err = gpg_error (GPG_ERR_FORBIDDEN);
628     }
629   else
630     err = gpg_error (GPG_ERR_UNKNOWN_OPTION);
631
632   return err;
633 }
634
635
636 \f
637 static const char hlp_dns_cert[] =
638   "DNS_CERT <subtype> <name>\n"
639   "DNS_CERT --pka <user_id>\n"
640   "DNS_CERT --dane <user_id>\n"
641   "\n"
642   "Return the CERT record for <name>.  <subtype> is one of\n"
643   "  *     Return the first record of any supported subtype\n"
644   "  PGP   Return the first record of subtype PGP (3)\n"
645   "  IPGP  Return the first record of subtype IPGP (6)\n"
646   "If the content of a certificate is available (PGP) it is returned\n"
647   "by data lines.  Fingerprints and URLs are returned via status lines.\n"
648   "In --pka mode the fingerprint and if available an URL is returned.\n"
649   "In --dane mode the key is returned from RR type 61";
650 static gpg_error_t
651 cmd_dns_cert (assuan_context_t ctx, char *line)
652 {
653   /* ctrl_t ctrl = assuan_get_pointer (ctx); */
654   gpg_error_t err = 0;
655   int pka_mode, dane_mode;
656   char *mbox = NULL;
657   char *namebuf = NULL;
658   char *encodedhash = NULL;
659   const char *name;
660   int certtype;
661   char *p;
662   void *key = NULL;
663   size_t keylen;
664   unsigned char *fpr = NULL;
665   size_t fprlen;
666   char *url = NULL;
667
668   pka_mode = has_option (line, "--pka");
669   dane_mode = has_option (line, "--dane");
670   line = skip_options (line);
671
672   if (pka_mode && dane_mode)
673     {
674       err = PARM_ERROR ("either --pka or --dane may be given");
675       goto leave;
676     }
677
678   if (pka_mode || dane_mode)
679     ; /* No need to parse here - we do this later.  */
680   else
681     {
682       p = strchr (line, ' ');
683       if (!p)
684         {
685           err = PARM_ERROR ("missing arguments");
686           goto leave;
687         }
688       *p++ = 0;
689       if (!strcmp (line, "*"))
690         certtype = DNS_CERTTYPE_ANY;
691       else if (!strcmp (line, "IPGP"))
692         certtype = DNS_CERTTYPE_IPGP;
693       else if (!strcmp (line, "PGP"))
694         certtype = DNS_CERTTYPE_PGP;
695       else
696         {
697           err = PARM_ERROR ("unknown subtype");
698           goto leave;
699         }
700       while (spacep (p))
701         p++;
702       line = p;
703       if (!*line)
704         {
705           err = PARM_ERROR ("name missing");
706           goto leave;
707         }
708     }
709
710   if (pka_mode || dane_mode)
711     {
712       char *domain;     /* Points to mbox.  */
713       char hashbuf[32]; /* For SHA-1 and SHA-256. */
714
715       /* We lowercase ascii characters but the DANE I-D does not allow
716          this.  FIXME: Check after the release of the RFC whether to
717          change this.  */
718       mbox = mailbox_from_userid (line);
719       if (!mbox || !(domain = strchr (mbox, '@')))
720         {
721           err = set_error (GPG_ERR_INV_USER_ID, "no mailbox in user id");
722           goto leave;
723         }
724       *domain++ = 0;
725
726       if (pka_mode)
727         {
728           gcry_md_hash_buffer (GCRY_MD_SHA1, hashbuf, mbox, strlen (mbox));
729           encodedhash = zb32_encode (hashbuf, 8*20);
730           if (!encodedhash)
731             {
732               err = gpg_error_from_syserror ();
733               goto leave;
734             }
735           namebuf = strconcat (encodedhash, "._pka.", domain, NULL);
736           if (!namebuf)
737             {
738               err = gpg_error_from_syserror ();
739               goto leave;
740             }
741           name = namebuf;
742           certtype = DNS_CERTTYPE_IPGP;
743         }
744       else
745         {
746           /* Note: The hash is truncated to 28 bytes and we lowercase
747              the result only for aesthetic reasons.  */
748           gcry_md_hash_buffer (GCRY_MD_SHA256, hashbuf, mbox, strlen (mbox));
749           encodedhash = bin2hex (hashbuf, 28, NULL);
750           if (!encodedhash)
751             {
752               err = gpg_error_from_syserror ();
753               goto leave;
754             }
755           ascii_strlwr (encodedhash);
756           namebuf = strconcat (encodedhash, "._openpgpkey.", domain, NULL);
757           if (!namebuf)
758             {
759               err = gpg_error_from_syserror ();
760               goto leave;
761             }
762           name = namebuf;
763           certtype = DNS_CERTTYPE_RR61;
764         }
765     }
766   else
767     name = line;
768
769   err = get_dns_cert (name, certtype, &key, &keylen, &fpr, &fprlen, &url);
770   if (err)
771     goto leave;
772
773   if (key)
774     {
775       err = data_line_write (ctx, key, keylen);
776       if (err)
777         goto leave;
778     }
779
780   if (fpr)
781     {
782       char *tmpstr;
783
784       tmpstr = bin2hex (fpr, fprlen, NULL);
785       if (!tmpstr)
786         err = gpg_error_from_syserror ();
787       else
788         {
789           err = assuan_write_status (ctx, "FPR", tmpstr);
790           xfree (tmpstr);
791         }
792       if (err)
793         goto leave;
794     }
795
796   if (url)
797     {
798       err = assuan_write_status (ctx, "URL", url);
799       if (err)
800         goto leave;
801     }
802
803
804  leave:
805   xfree (key);
806   xfree (fpr);
807   xfree (url);
808   xfree (mbox);
809   xfree (namebuf);
810   xfree (encodedhash);
811   return leave_cmd (ctx, err);
812 }
813
814
815 \f
816 static const char hlp_wkd_get[] =
817   "WKD_GET [--submission-address|--policy-flags] <user_id>\n"
818   "\n"
819   "Return the key or other info for <user_id>\n"
820   "from the Web Key Directory.";
821 static gpg_error_t
822 cmd_wkd_get (assuan_context_t ctx, char *line)
823 {
824   ctrl_t ctrl = assuan_get_pointer (ctx);
825   gpg_error_t err = 0;
826   char *mbox = NULL;
827   char *domainbuf = NULL;
828   char *domain;     /* Points to mbox or domainbuf.  */
829   char sha1buf[20];
830   char *uri = NULL;
831   char *encodedhash = NULL;
832   int opt_submission_addr;
833   int opt_policy_flags;
834   int no_log = 0;
835   char portstr[20] = { 0 };
836
837   opt_submission_addr = has_option (line, "--submission-address");
838   opt_policy_flags = has_option (line, "--policy-flags");
839   line = skip_options (line);
840
841   mbox = mailbox_from_userid (line);
842   if (!mbox || !(domain = strchr (mbox, '@')))
843     {
844       err = set_error (GPG_ERR_INV_USER_ID, "no mailbox in user id");
845       goto leave;
846     }
847   *domain++ = 0;
848
849   /* Check for SRV records.  */
850   if (1)
851     {
852       struct srventry *srvs;
853       unsigned int srvscount;
854       size_t domainlen, targetlen;
855       int i;
856
857       err = get_dns_srv (domain, "openpgpkey", NULL, &srvs, &srvscount);
858       if (err)
859         goto leave;
860
861       /* Find the first target which also ends in DOMAIN or is equal
862        * to DOMAIN.  */
863       domainlen = strlen (domain);
864       for (i = 0; i < srvscount; i++)
865         {
866           log_debug ("srv: trying '%s:%hu'\n", srvs[i].target, srvs[i].port);
867           targetlen = strlen (srvs[i].target);
868           if ((targetlen > domainlen + 1
869                && srvs[i].target[targetlen - domainlen - 1] == '.'
870                && !ascii_strcasecmp (srvs[i].target + targetlen - domainlen,
871                                      domain))
872               || (targetlen == domainlen
873                   && !ascii_strcasecmp (srvs[i].target, domain)))
874             {
875               /* found.  */
876               domainbuf = xtrystrdup (srvs[i].target);
877               if (!domainbuf)
878                 {
879                   err = gpg_error_from_syserror ();
880                   xfree (srvs);
881                   goto leave;
882                 }
883               domain = domainbuf;
884               if (srvs[i].port)
885                 snprintf (portstr, sizeof portstr, ":%hu", srvs[i].port);
886               break;
887             }
888         }
889       xfree (srvs);
890       log_debug ("srv: got '%s%s'\n", domain, portstr);
891     }
892
893   gcry_md_hash_buffer (GCRY_MD_SHA1, sha1buf, mbox, strlen (mbox));
894   encodedhash = zb32_encode (sha1buf, 8*20);
895   if (!encodedhash)
896     {
897       err = gpg_error_from_syserror ();
898       goto leave;
899     }
900
901   if (opt_submission_addr)
902     {
903       uri = strconcat ("https://",
904                        domain,
905                        portstr,
906                        "/.well-known/openpgpkey/submission-address",
907                        NULL);
908     }
909   else if (opt_policy_flags)
910     {
911       uri = strconcat ("https://",
912                        domain,
913                        portstr,
914                        "/.well-known/openpgpkey/policy",
915                        NULL);
916     }
917   else
918     {
919       uri = strconcat ("https://",
920                        domain,
921                        portstr,
922                        "/.well-known/openpgpkey/hu/",
923                        encodedhash,
924                        NULL);
925       no_log = 1;
926     }
927   if (!uri)
928     {
929       err = gpg_error_from_syserror ();
930       goto leave;
931     }
932
933   /* Setup an output stream and perform the get.  */
934   {
935     estream_t outfp;
936
937     outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
938     if (!outfp)
939       err = set_error (GPG_ERR_ASS_GENERAL,
940                        "error setting up a data stream");
941     else
942       {
943         if (no_log)
944           ctrl->server_local->inhibit_data_logging = 1;
945         ctrl->server_local->inhibit_data_logging_now = 0;
946         ctrl->server_local->inhibit_data_logging_count = 0;
947         err = ks_action_fetch (ctrl, uri, outfp);
948         es_fclose (outfp);
949         ctrl->server_local->inhibit_data_logging = 0;
950       }
951   }
952
953  leave:
954   xfree (uri);
955   xfree (encodedhash);
956   xfree (mbox);
957   xfree (domainbuf);
958   return leave_cmd (ctx, err);
959 }
960
961
962 \f
963 static const char hlp_ldapserver[] =
964   "LDAPSERVER <data>\n"
965   "\n"
966   "Add a new LDAP server to the list of configured LDAP servers.\n"
967   "DATA is in the same format as expected in the configure file.";
968 static gpg_error_t
969 cmd_ldapserver (assuan_context_t ctx, char *line)
970 {
971 #if USE_LDAP
972   ctrl_t ctrl = assuan_get_pointer (ctx);
973   ldap_server_t server;
974   ldap_server_t *last_next_p;
975
976   while (spacep (line))
977     line++;
978   if (*line == '\0')
979     return leave_cmd (ctx, PARM_ERROR (_("ldapserver missing")));
980
981   server = ldapserver_parse_one (line, "", 0);
982   if (! server)
983     return leave_cmd (ctx, gpg_error (GPG_ERR_INV_ARG));
984
985   last_next_p = &ctrl->server_local->ldapservers;
986   while (*last_next_p)
987     last_next_p = &(*last_next_p)->next;
988   *last_next_p = server;
989   return leave_cmd (ctx, 0);
990 #else
991   (void)line;
992   return leave_cmd (ctx, gpg_error (GPG_ERR_NOT_IMPLEMENTED));
993 #endif
994 }
995
996
997 static const char hlp_isvalid[] =
998   "ISVALID [--only-ocsp] [--force-default-responder]"
999   " <certificate_id>|<certificate_fpr>\n"
1000   "\n"
1001   "This command checks whether the certificate identified by the\n"
1002   "certificate_id is valid.  This is done by consulting CRLs or\n"
1003   "whatever has been configured.  Note, that the returned error codes\n"
1004   "are from gpg-error.h.  The command may callback using the inquire\n"
1005   "function.  See the manual for details.\n"
1006   "\n"
1007   "The CERTIFICATE_ID is a hex encoded string consisting of two parts,\n"
1008   "delimited by a single dot.  The first part is the SHA-1 hash of the\n"
1009   "issuer name and the second part the serial number.\n"
1010   "\n"
1011   "Alternatively the certificate's fingerprint may be given in which\n"
1012   "case an OCSP request is done before consulting the CRL.\n"
1013   "\n"
1014   "If the option --only-ocsp is given, no fallback to a CRL check will\n"
1015   "be used.\n"
1016   "\n"
1017   "If the option --force-default-responder is given, only the default\n"
1018   "OCSP responder will be used and any other methods of obtaining an\n"
1019   "OCSP responder URL won't be used.";
1020 static gpg_error_t
1021 cmd_isvalid (assuan_context_t ctx, char *line)
1022 {
1023   ctrl_t ctrl = assuan_get_pointer (ctx);
1024   char *issuerhash, *serialno;
1025   gpg_error_t err;
1026   int did_inquire = 0;
1027   int ocsp_mode = 0;
1028   int only_ocsp;
1029   int force_default_responder;
1030
1031   only_ocsp = has_option (line, "--only-ocsp");
1032   force_default_responder = has_option (line, "--force-default-responder");
1033   line = skip_options (line);
1034
1035   issuerhash = xstrdup (line); /* We need to work on a copy of the
1036                                   line because that same Assuan
1037                                   context may be used for an inquiry.
1038                                   That is because Assuan reuses its
1039                                   line buffer.
1040                                    */
1041
1042   serialno = strchr (issuerhash, '.');
1043   if (serialno)
1044     *serialno++ = 0;
1045   else
1046     {
1047       char *endp = strchr (issuerhash, ' ');
1048       if (endp)
1049         *endp = 0;
1050       if (strlen (issuerhash) != 40)
1051         {
1052           xfree (issuerhash);
1053           return leave_cmd (ctx, PARM_ERROR (_("serialno missing in cert ID")));
1054         }
1055       ocsp_mode = 1;
1056     }
1057
1058
1059  again:
1060   if (ocsp_mode)
1061     {
1062       /* Note, that we ignore the given issuer hash and instead rely
1063          on the current certificate semantics used with this
1064          command. */
1065       if (!opt.allow_ocsp)
1066         err = gpg_error (GPG_ERR_NOT_SUPPORTED);
1067       else
1068         err = ocsp_isvalid (ctrl, NULL, NULL, force_default_responder);
1069       /* Fixme: If we got no ocsp response and --only-ocsp is not used
1070          we should fall back to CRL mode.  Thus we need to clear
1071          OCSP_MODE, get the issuerhash and the serialno from the
1072          current certificate and jump to again. */
1073     }
1074   else if (only_ocsp)
1075     err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
1076   else
1077     {
1078       switch (crl_cache_isvalid (ctrl,
1079                                  issuerhash, serialno,
1080                                  ctrl->force_crl_refresh))
1081         {
1082         case CRL_CACHE_VALID:
1083           err = 0;
1084           break;
1085         case CRL_CACHE_INVALID:
1086           err = gpg_error (GPG_ERR_CERT_REVOKED);
1087           break;
1088         case CRL_CACHE_DONTKNOW:
1089           if (did_inquire)
1090             err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
1091           else if (!(err = inquire_cert_and_load_crl (ctx)))
1092             {
1093               did_inquire = 1;
1094               goto again;
1095             }
1096           break;
1097         case CRL_CACHE_CANTUSE:
1098           err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
1099           break;
1100         default:
1101           log_fatal ("crl_cache_isvalid returned invalid code\n");
1102         }
1103     }
1104
1105   xfree (issuerhash);
1106   return leave_cmd (ctx, err);
1107 }
1108
1109
1110 /* If the line contains a SHA-1 fingerprint as the first argument,
1111    return the FPR vuffer on success.  The function checks that the
1112    fingerprint consists of valid characters and prints and error
1113    message if it does not and returns NULL.  Fingerprints are
1114    considered optional and thus no explicit error is returned. NULL is
1115    also returned if there is no fingerprint at all available.
1116    FPR must be a caller provided buffer of at least 20 bytes.
1117
1118    Note that colons within the fingerprint are allowed to separate 2
1119    hex digits; this allows for easier cutting and pasting using the
1120    usual fingerprint rendering.
1121 */
1122 static unsigned char *
1123 get_fingerprint_from_line (const char *line, unsigned char *fpr)
1124 {
1125   const char *s;
1126   int i;
1127
1128   for (s=line, i=0; *s && *s != ' '; s++ )
1129     {
1130       if ( hexdigitp (s) && hexdigitp (s+1) )
1131         {
1132           if ( i >= 20 )
1133             return NULL;  /* Fingerprint too long.  */
1134           fpr[i++] = xtoi_2 (s);
1135           s++;
1136         }
1137       else if ( *s != ':' )
1138         return NULL; /* Invalid.  */
1139     }
1140   if ( i != 20 )
1141     return NULL; /* Fingerprint to short.  */
1142   return fpr;
1143 }
1144
1145
1146
1147 static const char hlp_checkcrl[] =
1148   "CHECKCRL [<fingerprint>]\n"
1149   "\n"
1150   "Check whether the certificate with FINGERPRINT (SHA-1 hash of the\n"
1151   "entire X.509 certificate blob) is valid or not by consulting the\n"
1152   "CRL responsible for this certificate.  If the fingerprint has not\n"
1153   "been given or the certificate is not known, the function \n"
1154   "inquires the certificate using an\n"
1155   "\n"
1156   "  INQUIRE TARGETCERT\n"
1157   "\n"
1158   "and the caller is expected to return the certificate for the\n"
1159   "request (which should match FINGERPRINT) as a binary blob.\n"
1160   "Processing then takes place without further interaction; in\n"
1161   "particular dirmngr tries to locate other required certificate by\n"
1162   "its own mechanism which includes a local certificate store as well\n"
1163   "as a list of trusted root certificates.\n"
1164   "\n"
1165   "The return value is the usual gpg-error code or 0 for ducesss;\n"
1166   "i.e. the certificate validity has been confirmed by a valid CRL.";
1167 static gpg_error_t
1168 cmd_checkcrl (assuan_context_t ctx, char *line)
1169 {
1170   ctrl_t ctrl = assuan_get_pointer (ctx);
1171   gpg_error_t err;
1172   unsigned char fprbuffer[20], *fpr;
1173   ksba_cert_t cert;
1174
1175   fpr = get_fingerprint_from_line (line, fprbuffer);
1176   cert = fpr? get_cert_byfpr (fpr) : NULL;
1177
1178   if (!cert)
1179     {
1180       /* We do not have this certificate yet or the fingerprint has
1181          not been given.  Inquire it from the client.  */
1182       unsigned char *value = NULL;
1183       size_t valuelen;
1184
1185       err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1186                            &value, &valuelen, MAX_CERT_LENGTH);
1187       if (err)
1188         {
1189           log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1190           goto leave;
1191         }
1192
1193       if (!valuelen) /* No data returned; return a comprehensible error. */
1194         err = gpg_error (GPG_ERR_MISSING_CERT);
1195       else
1196         {
1197           err = ksba_cert_new (&cert);
1198           if (!err)
1199             err = ksba_cert_init_from_mem (cert, value, valuelen);
1200         }
1201       xfree (value);
1202       if(err)
1203         goto leave;
1204     }
1205
1206   assert (cert);
1207
1208   err = crl_cache_cert_isvalid (ctrl, cert, ctrl->force_crl_refresh);
1209   if (gpg_err_code (err) == GPG_ERR_NO_CRL_KNOWN)
1210     {
1211       err = crl_cache_reload_crl (ctrl, cert);
1212       if (!err)
1213         err = crl_cache_cert_isvalid (ctrl, cert, 0);
1214     }
1215
1216  leave:
1217   ksba_cert_release (cert);
1218   return leave_cmd (ctx, err);
1219 }
1220
1221
1222 static const char hlp_checkocsp[] =
1223   "CHECKOCSP [--force-default-responder] [<fingerprint>]\n"
1224   "\n"
1225   "Check whether the certificate with FINGERPRINT (SHA-1 hash of the\n"
1226   "entire X.509 certificate blob) is valid or not by asking an OCSP\n"
1227   "responder responsible for this certificate.  The optional\n"
1228   "fingerprint may be used for a quick check in case an OCSP check has\n"
1229   "been done for this certificate recently (we always cache OCSP\n"
1230   "responses for a couple of minutes). If the fingerprint has not been\n"
1231   "given or there is no cached result, the function inquires the\n"
1232   "certificate using an\n"
1233   "\n"
1234   "   INQUIRE TARGETCERT\n"
1235   "\n"
1236   "and the caller is expected to return the certificate for the\n"
1237   "request (which should match FINGERPRINT) as a binary blob.\n"
1238   "Processing then takes place without further interaction; in\n"
1239   "particular dirmngr tries to locate other required certificates by\n"
1240   "its own mechanism which includes a local certificate store as well\n"
1241   "as a list of trusted root certificates.\n"
1242   "\n"
1243   "If the option --force-default-responder is given, only the default\n"
1244   "OCSP responder will be used and any other methods of obtaining an\n"
1245   "OCSP responder URL won't be used.\n"
1246   "\n"
1247   "The return value is the usual gpg-error code or 0 for ducesss;\n"
1248   "i.e. the certificate validity has been confirmed by a valid CRL.";
1249 static gpg_error_t
1250 cmd_checkocsp (assuan_context_t ctx, char *line)
1251 {
1252   ctrl_t ctrl = assuan_get_pointer (ctx);
1253   gpg_error_t err;
1254   unsigned char fprbuffer[20], *fpr;
1255   ksba_cert_t cert;
1256   int force_default_responder;
1257
1258   force_default_responder = has_option (line, "--force-default-responder");
1259   line = skip_options (line);
1260
1261   fpr = get_fingerprint_from_line (line, fprbuffer);
1262   cert = fpr? get_cert_byfpr (fpr) : NULL;
1263
1264   if (!cert)
1265     {
1266       /* We do not have this certificate yet or the fingerprint has
1267          not been given.  Inquire it from the client.  */
1268       unsigned char *value = NULL;
1269       size_t valuelen;
1270
1271       err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1272                            &value, &valuelen, MAX_CERT_LENGTH);
1273       if (err)
1274         {
1275           log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1276           goto leave;
1277         }
1278
1279       if (!valuelen) /* No data returned; return a comprehensible error. */
1280         err = gpg_error (GPG_ERR_MISSING_CERT);
1281       else
1282         {
1283           err = ksba_cert_new (&cert);
1284           if (!err)
1285             err = ksba_cert_init_from_mem (cert, value, valuelen);
1286         }
1287       xfree (value);
1288       if(err)
1289         goto leave;
1290     }
1291
1292   assert (cert);
1293
1294   if (!opt.allow_ocsp)
1295     err = gpg_error (GPG_ERR_NOT_SUPPORTED);
1296   else
1297     err = ocsp_isvalid (ctrl, cert, NULL, force_default_responder);
1298
1299  leave:
1300   ksba_cert_release (cert);
1301   return leave_cmd (ctx, err);
1302 }
1303
1304
1305
1306 static int
1307 lookup_cert_by_url (assuan_context_t ctx, const char *url)
1308 {
1309   ctrl_t ctrl = assuan_get_pointer (ctx);
1310   gpg_error_t err = 0;
1311   unsigned char *value = NULL;
1312   size_t valuelen;
1313
1314   /* Fetch single certificate given it's URL.  */
1315   err = fetch_cert_by_url (ctrl, url, &value, &valuelen);
1316   if (err)
1317     {
1318       log_error (_("fetch_cert_by_url failed: %s\n"), gpg_strerror (err));
1319       goto leave;
1320     }
1321
1322   /* Send the data, flush the buffer and then send an END. */
1323   err = assuan_send_data (ctx, value, valuelen);
1324   if (!err)
1325     err = assuan_send_data (ctx, NULL, 0);
1326   if (!err)
1327     err = assuan_write_line (ctx, "END");
1328   if (err)
1329     {
1330       log_error (_("error sending data: %s\n"), gpg_strerror (err));
1331       goto leave;
1332     }
1333
1334  leave:
1335
1336   return err;
1337 }
1338
1339
1340 /* Send the certificate, flush the buffer and then send an END. */
1341 static gpg_error_t
1342 return_one_cert (void *opaque, ksba_cert_t cert)
1343 {
1344   assuan_context_t ctx = opaque;
1345   gpg_error_t err;
1346   const unsigned char *der;
1347   size_t derlen;
1348
1349   der = ksba_cert_get_image (cert, &derlen);
1350   if (!der)
1351     err = gpg_error (GPG_ERR_INV_CERT_OBJ);
1352   else
1353     {
1354       err = assuan_send_data (ctx, der, derlen);
1355       if (!err)
1356         err = assuan_send_data (ctx, NULL, 0);
1357       if (!err)
1358         err = assuan_write_line (ctx, "END");
1359     }
1360   if (err)
1361     log_error (_("error sending data: %s\n"), gpg_strerror (err));
1362   return err;
1363 }
1364
1365
1366 /* Lookup certificates from the internal cache or using the ldap
1367    servers. */
1368 static int
1369 lookup_cert_by_pattern (assuan_context_t ctx, char *line,
1370                         int single, int cache_only)
1371 {
1372   gpg_error_t err = 0;
1373   char *p;
1374   strlist_t sl, list = NULL;
1375   int truncated = 0, truncation_forced = 0;
1376   int count = 0;
1377   int local_count = 0;
1378 #if USE_LDAP
1379   ctrl_t ctrl = assuan_get_pointer (ctx);
1380   unsigned char *value = NULL;
1381   size_t valuelen;
1382   struct ldapserver_iter ldapserver_iter;
1383   cert_fetch_context_t fetch_context;
1384 #endif /*USE_LDAP*/
1385   int any_no_data = 0;
1386
1387   /* Break the line down into an STRLIST */
1388   for (p=line; *p; line = p)
1389     {
1390       while (*p && *p != ' ')
1391         p++;
1392       if (*p)
1393         *p++ = 0;
1394
1395       if (*line)
1396         {
1397           sl = xtrymalloc (sizeof *sl + strlen (line));
1398           if (!sl)
1399             {
1400               err = gpg_error_from_errno (errno);
1401               goto leave;
1402             }
1403           memset (sl, 0, sizeof *sl);
1404           strcpy_escaped_plus (sl->d, line);
1405           sl->next = list;
1406           list = sl;
1407         }
1408     }
1409
1410   /* First look through the internal cache.  The certifcates returned
1411      here are not counted towards the truncation limit.  */
1412   if (single && !cache_only)
1413     ; /* Do not read from the local cache in this case.  */
1414   else
1415     {
1416       for (sl=list; sl; sl = sl->next)
1417         {
1418           err = get_certs_bypattern (sl->d, return_one_cert, ctx);
1419           if (!err)
1420             local_count++;
1421           if (!err && single)
1422             goto ready;
1423
1424           if (gpg_err_code (err) == GPG_ERR_NO_DATA)
1425             {
1426               err = 0;
1427               if (cache_only)
1428                 any_no_data = 1;
1429             }
1430           else if (gpg_err_code (err) == GPG_ERR_INV_NAME && !cache_only)
1431             {
1432               /* No real fault because the internal pattern lookup
1433                  can't yet cope with all types of pattern.  */
1434               err = 0;
1435             }
1436           if (err)
1437             goto ready;
1438         }
1439     }
1440
1441   /* Loop over all configured servers unless we want only the
1442      certificates from the cache.  */
1443 #if USE_LDAP
1444   for (ldapserver_iter_begin (&ldapserver_iter, ctrl);
1445        !cache_only && !ldapserver_iter_end_p (&ldapserver_iter)
1446          && ldapserver_iter.server->host && !truncation_forced;
1447        ldapserver_iter_next (&ldapserver_iter))
1448     {
1449       ldap_server_t ldapserver = ldapserver_iter.server;
1450
1451       if (DBG_LOOKUP)
1452         log_debug ("cmd_lookup: trying %s:%d base=%s\n",
1453                    ldapserver->host, ldapserver->port,
1454                    ldapserver->base?ldapserver->base : "[default]");
1455
1456       /* Fetch certificates matching pattern */
1457       err = start_cert_fetch (ctrl, &fetch_context, list, ldapserver);
1458       if ( gpg_err_code (err) == GPG_ERR_NO_DATA )
1459         {
1460           if (DBG_LOOKUP)
1461             log_debug ("cmd_lookup: no data\n");
1462           err = 0;
1463           any_no_data = 1;
1464           continue;
1465         }
1466       if (err)
1467         {
1468           log_error (_("start_cert_fetch failed: %s\n"), gpg_strerror (err));
1469           goto leave;
1470         }
1471
1472       /* Fetch the certificates for this query. */
1473       while (!truncation_forced)
1474         {
1475           xfree (value); value = NULL;
1476           err = fetch_next_cert (fetch_context, &value, &valuelen);
1477           if (gpg_err_code (err) == GPG_ERR_NO_DATA )
1478             {
1479               err = 0;
1480               any_no_data = 1;
1481               break; /* Ready. */
1482             }
1483           if (gpg_err_code (err) == GPG_ERR_TRUNCATED)
1484             {
1485               truncated = 1;
1486               err = 0;
1487               break;  /* Ready.  */
1488             }
1489           if (gpg_err_code (err) == GPG_ERR_EOF)
1490             {
1491               err = 0;
1492               break; /* Ready. */
1493             }
1494           if (!err && !value)
1495             {
1496               err = gpg_error (GPG_ERR_BUG);
1497               goto leave;
1498             }
1499           if (err)
1500             {
1501               log_error (_("fetch_next_cert failed: %s\n"),
1502                          gpg_strerror (err));
1503               end_cert_fetch (fetch_context);
1504               goto leave;
1505             }
1506
1507           if (DBG_LOOKUP)
1508             log_debug ("cmd_lookup: returning one cert%s\n",
1509                        truncated? " (truncated)":"");
1510
1511           /* Send the data, flush the buffer and then send an END line
1512              as a certificate delimiter. */
1513           err = assuan_send_data (ctx, value, valuelen);
1514           if (!err)
1515             err = assuan_send_data (ctx, NULL, 0);
1516           if (!err)
1517             err = assuan_write_line (ctx, "END");
1518           if (err)
1519             {
1520               log_error (_("error sending data: %s\n"), gpg_strerror (err));
1521               end_cert_fetch (fetch_context);
1522               goto leave;
1523             }
1524
1525           if (++count >= opt.max_replies )
1526             {
1527               truncation_forced = 1;
1528               log_info (_("max_replies %d exceeded\n"), opt.max_replies );
1529             }
1530           if (single)
1531             break;
1532         }
1533
1534       end_cert_fetch (fetch_context);
1535     }
1536 #endif /*USE_LDAP*/
1537
1538  ready:
1539   if (truncated || truncation_forced)
1540     {
1541       char str[50];
1542
1543       sprintf (str, "%d", count);
1544       assuan_write_status (ctx, "TRUNCATED", str);
1545     }
1546
1547   if (!err && !count && !local_count && any_no_data)
1548     err = gpg_error (GPG_ERR_NO_DATA);
1549
1550  leave:
1551   free_strlist (list);
1552   return err;
1553 }
1554
1555
1556 static const char hlp_lookup[] =
1557   "LOOKUP [--url] [--single] [--cache-only] <pattern>\n"
1558   "\n"
1559   "Lookup certificates matching PATTERN. With --url the pattern is\n"
1560   "expected to be one URL.\n"
1561   "\n"
1562   "If --url is not given:  To allow for multiple patterns (which are ORed)\n"
1563   "quoting is required: Spaces are translated to \"+\" or \"%20\";\n"
1564   "obviously this requires that the usual escape quoting rules are applied.\n"
1565   "\n"
1566   "If --url is given no special escaping is required because URLs are\n"
1567   "already escaped this way.\n"
1568   "\n"
1569   "If --single is given the first and only the first match will be\n"
1570   "returned.  If --cache-only is _not_ given, no local query will be\n"
1571   "done.\n"
1572   "\n"
1573   "If --cache-only is given no external lookup is done so that only\n"
1574   "certificates from the cache may get returned.";
1575 static gpg_error_t
1576 cmd_lookup (assuan_context_t ctx, char *line)
1577 {
1578   gpg_error_t err;
1579   int lookup_url, single, cache_only;
1580
1581   lookup_url = has_leading_option (line, "--url");
1582   single = has_leading_option (line, "--single");
1583   cache_only = has_leading_option (line, "--cache-only");
1584   line = skip_options (line);
1585
1586   if (lookup_url && cache_only)
1587     err = gpg_error (GPG_ERR_NOT_FOUND);
1588   else if (lookup_url && single)
1589     err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1590   else if (lookup_url)
1591     err = lookup_cert_by_url (ctx, line);
1592   else
1593     err = lookup_cert_by_pattern (ctx, line, single, cache_only);
1594
1595   return leave_cmd (ctx, err);
1596 }
1597
1598
1599 static const char hlp_loadcrl[] =
1600   "LOADCRL [--url] <filename|url>\n"
1601   "\n"
1602   "Load the CRL in the file with name FILENAME into our cache.  Note\n"
1603   "that FILENAME should be given with an absolute path because\n"
1604   "Dirmngrs cwd is not known.  With --url the CRL is directly loaded\n"
1605   "from the given URL.\n"
1606   "\n"
1607   "This command is usually used by gpgsm using the invocation \"gpgsm\n"
1608   "--call-dirmngr loadcrl <filename>\".  A direct invocation of Dirmngr\n"
1609   "is not useful because gpgsm might need to callback gpgsm to ask for\n"
1610   "the CA's certificate.";
1611 static gpg_error_t
1612 cmd_loadcrl (assuan_context_t ctx, char *line)
1613 {
1614   ctrl_t ctrl = assuan_get_pointer (ctx);
1615   gpg_error_t err = 0;
1616   int use_url = has_leading_option (line, "--url");
1617
1618   line = skip_options (line);
1619
1620   if (use_url)
1621     {
1622       ksba_reader_t reader;
1623
1624       err = crl_fetch (ctrl, line, &reader);
1625       if (err)
1626         log_error (_("fetching CRL from '%s' failed: %s\n"),
1627                    line, gpg_strerror (err));
1628       else
1629         {
1630           err = crl_cache_insert (ctrl, line, reader);
1631           if (err)
1632             log_error (_("processing CRL from '%s' failed: %s\n"),
1633                        line, gpg_strerror (err));
1634           crl_close_reader (reader);
1635         }
1636     }
1637   else
1638     {
1639       char *buf;
1640
1641       buf = xtrymalloc (strlen (line)+1);
1642       if (!buf)
1643         err = gpg_error_from_syserror ();
1644       else
1645         {
1646           strcpy_escaped_plus (buf, line);
1647           err = crl_cache_load (ctrl, buf);
1648           xfree (buf);
1649         }
1650     }
1651
1652   return leave_cmd (ctx, err);
1653 }
1654
1655
1656 static const char hlp_listcrls[] =
1657   "LISTCRLS\n"
1658   "\n"
1659   "List the content of all CRLs in a readable format.  This command is\n"
1660   "usually used by gpgsm using the invocation \"gpgsm --call-dirmngr\n"
1661   "listcrls\".  It may also be used directly using \"dirmngr\n"
1662   "--list-crls\".";
1663 static gpg_error_t
1664 cmd_listcrls (assuan_context_t ctx, char *line)
1665 {
1666   gpg_error_t err;
1667   estream_t fp;
1668
1669   (void)line;
1670
1671   fp = es_fopencookie (ctx, "w", data_line_cookie_functions);
1672   if (!fp)
1673     err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
1674   else
1675     {
1676       err = crl_cache_list (fp);
1677       es_fclose (fp);
1678     }
1679   return leave_cmd (ctx, err);
1680 }
1681
1682
1683 static const char hlp_cachecert[] =
1684   "CACHECERT\n"
1685   "\n"
1686   "Put a certificate into the internal cache.  This command might be\n"
1687   "useful if a client knows in advance certificates required for a\n"
1688   "test and wants to make sure they get added to the internal cache.\n"
1689   "It is also helpful for debugging.  To get the actual certificate,\n"
1690   "this command immediately inquires it using\n"
1691   "\n"
1692   "  INQUIRE TARGETCERT\n"
1693   "\n"
1694   "and the caller is expected to return the certificate for the\n"
1695   "request as a binary blob.";
1696 static gpg_error_t
1697 cmd_cachecert (assuan_context_t ctx, char *line)
1698 {
1699   ctrl_t ctrl = assuan_get_pointer (ctx);
1700   gpg_error_t err;
1701   ksba_cert_t cert = NULL;
1702   unsigned char *value = NULL;
1703   size_t valuelen;
1704
1705   (void)line;
1706
1707   err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1708                        &value, &valuelen, MAX_CERT_LENGTH);
1709   if (err)
1710     {
1711       log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1712       goto leave;
1713     }
1714
1715   if (!valuelen) /* No data returned; return a comprehensible error. */
1716     err = gpg_error (GPG_ERR_MISSING_CERT);
1717   else
1718     {
1719       err = ksba_cert_new (&cert);
1720       if (!err)
1721         err = ksba_cert_init_from_mem (cert, value, valuelen);
1722     }
1723   xfree (value);
1724   if(err)
1725     goto leave;
1726
1727   err = cache_cert (cert);
1728
1729  leave:
1730   ksba_cert_release (cert);
1731   return leave_cmd (ctx, err);
1732 }
1733
1734
1735 static const char hlp_validate[] =
1736   "VALIDATE [--systrust] [--tls] [--no-crl]\n"
1737   "\n"
1738   "Validate a certificate using the certificate validation function\n"
1739   "used internally by dirmngr.  This command is only useful for\n"
1740   "debugging.  To get the actual certificate, this command immediately\n"
1741   "inquires it using\n"
1742   "\n"
1743   "  INQUIRE TARGETCERT\n"
1744   "\n"
1745   "and the caller is expected to return the certificate for the\n"
1746   "request as a binary blob.  The option --tls modifies this by asking\n"
1747   "for list of certificates with\n"
1748   "\n"
1749   "  INQUIRE CERTLIST\n"
1750   "\n"
1751   "Here the first certificate is the target certificate, the remaining\n"
1752   "certificates are suggested intermediary certificates.  All certifciates\n"
1753   "need to be PEM encoded.\n"
1754   "\n"
1755   "The option --systrust changes the behaviour to include the system\n"
1756   "provided root certificates as trust anchors.  The option --no-crl\n"
1757   "skips CRL checks";
1758 static gpg_error_t
1759 cmd_validate (assuan_context_t ctx, char *line)
1760 {
1761   ctrl_t ctrl = assuan_get_pointer (ctx);
1762   gpg_error_t err;
1763   ksba_cert_t cert = NULL;
1764   certlist_t certlist = NULL;
1765   unsigned char *value = NULL;
1766   size_t valuelen;
1767   int systrust_mode, tls_mode, no_crl;
1768
1769   systrust_mode = has_option (line, "--systrust");
1770   tls_mode = has_option (line, "--tls");
1771   no_crl = has_option (line, "--no-crl");
1772   line = skip_options (line);
1773
1774   if (tls_mode)
1775     err = assuan_inquire (ctrl->server_local->assuan_ctx, "CERTLIST",
1776                           &value, &valuelen, MAX_CERTLIST_LENGTH);
1777   else
1778     err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1779                           &value, &valuelen, MAX_CERT_LENGTH);
1780   if (err)
1781     {
1782       log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1783       goto leave;
1784     }
1785
1786   if (!valuelen) /* No data returned; return a comprehensible error. */
1787     err = gpg_error (GPG_ERR_MISSING_CERT);
1788   else if (tls_mode)
1789     {
1790       estream_t fp;
1791
1792       fp = es_fopenmem_init (0, "rb", value, valuelen);
1793       if (!fp)
1794         err = gpg_error_from_syserror ();
1795       else
1796         {
1797           err = read_certlist_from_stream (&certlist, fp);
1798           es_fclose (fp);
1799           if (!err && !certlist)
1800             err = gpg_error (GPG_ERR_MISSING_CERT);
1801           if (!err)
1802             {
1803               /* Extraxt the first certificate from the list.  */
1804               cert = certlist->cert;
1805               ksba_cert_ref (cert);
1806             }
1807         }
1808     }
1809   else
1810     {
1811       err = ksba_cert_new (&cert);
1812       if (!err)
1813         err = ksba_cert_init_from_mem (cert, value, valuelen);
1814     }
1815   xfree (value);
1816   if(err)
1817     goto leave;
1818
1819   if (!tls_mode)
1820     {
1821       /* If we have this certificate already in our cache, use the
1822        * cached version for validation because this will take care of
1823        * any cached results.  We don't need to do this in tls mode
1824        * because this has already been done for certificate in a
1825        * certlist_t. */
1826       unsigned char fpr[20];
1827       ksba_cert_t tmpcert;
1828
1829       cert_compute_fpr (cert, fpr);
1830       tmpcert = get_cert_byfpr (fpr);
1831       if (tmpcert)
1832         {
1833           ksba_cert_release (cert);
1834           cert = tmpcert;
1835         }
1836     }
1837
1838   /* Quick hack to make verification work by inserting the supplied
1839    * certs into the cache.  */
1840   if (tls_mode && certlist)
1841     {
1842       certlist_t cl;
1843
1844       for (cl = certlist->next; cl; cl = cl->next)
1845         cache_cert (cl->cert);
1846     }
1847
1848   err = validate_cert_chain (ctrl, cert, NULL,
1849                              ((tls_mode ? VALIDATE_FLAG_TLS : 0)
1850                               | (systrust_mode ? VALIDATE_FLAG_SYSTRUST : 0)
1851                               | (no_crl ? VALIDATE_FLAG_NOCRLCHECK : 0)),
1852                              NULL);
1853
1854  leave:
1855   ksba_cert_release (cert);
1856   release_certlist (certlist);
1857   return leave_cmd (ctx, err);
1858 }
1859
1860
1861 \f
1862 /* Parse an keyserver URI and store it in a new uri item which is
1863    returned at R_ITEM.  On error return an error code.  */
1864 static gpg_error_t
1865 make_keyserver_item (const char *uri, uri_item_t *r_item)
1866 {
1867   gpg_error_t err;
1868   uri_item_t item;
1869
1870   *r_item = NULL;
1871   item = xtrymalloc (sizeof *item + strlen (uri));
1872   if (!item)
1873     return gpg_error_from_syserror ();
1874
1875   item->next = NULL;
1876   item->parsed_uri = NULL;
1877   strcpy (item->uri, uri);
1878
1879 #if USE_LDAP
1880   if (ldap_uri_p (item->uri))
1881     err = ldap_parse_uri (&item->parsed_uri, uri);
1882   else
1883 #endif
1884     {
1885       err = http_parse_uri (&item->parsed_uri, uri, 1);
1886     }
1887
1888   if (err)
1889     xfree (item);
1890   else
1891     *r_item = item;
1892   return err;
1893 }
1894
1895
1896 /* If no keyserver is stored in CTRL but a global keyserver has been
1897    set, put that global keyserver into CTRL.  We need use this
1898    function to help migrate from the old gpg based keyserver
1899    configuration to the new dirmngr based configuration.  */
1900 static gpg_error_t
1901 ensure_keyserver (ctrl_t ctrl)
1902 {
1903   gpg_error_t err;
1904   uri_item_t item;
1905   uri_item_t onion_items = NULL;
1906   uri_item_t plain_items = NULL;
1907   uri_item_t ui;
1908   strlist_t sl;
1909
1910   if (ctrl->server_local->keyservers)
1911     return 0; /* Already set for this session.  */
1912   if (!opt.keyserver)
1913     {
1914       /* No global option set.  Fall back to default:  */
1915       return make_keyserver_item (DIRMNGR_DEFAULT_KEYSERVER,
1916                                   &ctrl->server_local->keyservers);
1917     }
1918
1919   for (sl = opt.keyserver; sl; sl = sl->next)
1920     {
1921       err = make_keyserver_item (sl->d, &item);
1922       if (err)
1923         goto leave;
1924       if (item->parsed_uri->onion)
1925         {
1926           item->next = onion_items;
1927           onion_items = item;
1928         }
1929       else
1930         {
1931           item->next = plain_items;
1932           plain_items = item;
1933         }
1934     }
1935
1936   /* Decide which to use.  Note that the sesssion has no keyservers
1937      yet set. */
1938   if (onion_items && !onion_items->next && plain_items && !plain_items->next)
1939     {
1940       /* If there is just one onion and one plain keyserver given, we take
1941          only one depending on whether Tor is running or not.  */
1942       if (is_tor_running (ctrl))
1943         {
1944           ctrl->server_local->keyservers = onion_items;
1945           onion_items = NULL;
1946         }
1947       else
1948         {
1949           ctrl->server_local->keyservers = plain_items;
1950           plain_items = NULL;
1951         }
1952     }
1953   else if (!is_tor_running (ctrl))
1954     {
1955       /* Tor is not running.  It does not make sense to add Onion
1956          addresses.  */
1957       ctrl->server_local->keyservers = plain_items;
1958       plain_items = NULL;
1959     }
1960   else
1961     {
1962       /* In all other cases add all keyservers.  */
1963       ctrl->server_local->keyservers = onion_items;
1964       onion_items = NULL;
1965       for (ui = ctrl->server_local->keyservers; ui && ui->next; ui = ui->next)
1966         ;
1967       if (ui)
1968         ui->next = plain_items;
1969       else
1970         ctrl->server_local->keyservers = plain_items;
1971       plain_items = NULL;
1972     }
1973
1974  leave:
1975   release_uri_item_list (onion_items);
1976   release_uri_item_list (plain_items);
1977
1978   return err;
1979 }
1980
1981
1982 static const char hlp_keyserver[] =
1983   "KEYSERVER [<options>] [<uri>|<host>]\n"
1984   "Options are:\n"
1985   "  --help\n"
1986   "  --clear      Remove all configured keyservers\n"
1987   "  --resolve    Resolve HKP host names and rotate\n"
1988   "  --hosttable  Print table of known hosts and pools\n"
1989   "  --dead       Mark <host> as dead\n"
1990   "  --alive      Mark <host> as alive\n"
1991   "\n"
1992   "If called without arguments list all configured keyserver URLs.\n"
1993   "If called with an URI add this as keyserver.  Note that keyservers\n"
1994   "are configured on a per-session base.  A default keyserver may already be\n"
1995   "present, thus the \"--clear\" option must be used to get full control.\n"
1996   "If \"--clear\" and an URI are used together the clear command is\n"
1997   "obviously executed first.  A RESET command does not change the list\n"
1998   "of configured keyservers.";
1999 static gpg_error_t
2000 cmd_keyserver (assuan_context_t ctx, char *line)
2001 {
2002   ctrl_t ctrl = assuan_get_pointer (ctx);
2003   gpg_error_t err = 0;
2004   int clear_flag, add_flag, help_flag, host_flag, resolve_flag;
2005   int dead_flag, alive_flag;
2006   uri_item_t item = NULL; /* gcc 4.4.5 is not able to detect that it
2007                              is always initialized.  */
2008
2009   clear_flag = has_option (line, "--clear");
2010   help_flag = has_option (line, "--help");
2011   resolve_flag = has_option (line, "--resolve");
2012   host_flag = has_option (line, "--hosttable");
2013   dead_flag = has_option (line, "--dead");
2014   alive_flag = has_option (line, "--alive");
2015   line = skip_options (line);
2016   add_flag = !!*line;
2017
2018   if (help_flag)
2019     {
2020       err = ks_action_help (ctrl, line);
2021       goto leave;
2022     }
2023
2024   if (resolve_flag)
2025     {
2026       err = ensure_keyserver (ctrl);
2027       if (!err)
2028         err = ks_action_resolve (ctrl, ctrl->server_local->keyservers);
2029       if (err)
2030         goto leave;
2031     }
2032
2033   if (alive_flag && dead_flag)
2034     {
2035       err = set_error (GPG_ERR_ASS_PARAMETER, "no support for zombies");
2036       goto leave;
2037     }
2038   if (dead_flag)
2039     {
2040       err = check_owner_permission (ctx, "no permission to use --dead");
2041       if (err)
2042         goto leave;
2043     }
2044   if (alive_flag || dead_flag)
2045     {
2046       if (!*line)
2047         {
2048           err = set_error (GPG_ERR_ASS_PARAMETER, "name of host missing");
2049           goto leave;
2050         }
2051
2052       err = ks_hkp_mark_host (ctrl, line, alive_flag);
2053       if (err)
2054         goto leave;
2055     }
2056
2057   if (host_flag)
2058     {
2059       err = ks_hkp_print_hosttable (ctrl);
2060       if (err)
2061         goto leave;
2062     }
2063   if (resolve_flag || host_flag || alive_flag || dead_flag)
2064     goto leave;
2065
2066   if (add_flag)
2067     {
2068       err = make_keyserver_item (line, &item);
2069       if (err)
2070         goto leave;
2071     }
2072   if (clear_flag)
2073     release_ctrl_keyservers (ctrl);
2074   if (add_flag)
2075     {
2076       item->next = ctrl->server_local->keyservers;
2077       ctrl->server_local->keyservers = item;
2078     }
2079
2080   if (!add_flag && !clear_flag && !help_flag)
2081     {
2082       /* List configured keyservers.  However, we first add a global
2083          keyserver. */
2084       uri_item_t u;
2085
2086       err = ensure_keyserver (ctrl);
2087       if (err)
2088         {
2089           assuan_set_error (ctx, err,
2090                             "Bad keyserver configuration in dirmngr.conf");
2091           goto leave;
2092         }
2093
2094       for (u=ctrl->server_local->keyservers; u; u = u->next)
2095         dirmngr_status (ctrl, "KEYSERVER", u->uri, NULL);
2096     }
2097   err = 0;
2098
2099  leave:
2100   return leave_cmd (ctx, err);
2101 }
2102
2103
2104 \f
2105 static const char hlp_ks_search[] =
2106   "KS_SEARCH {<pattern>}\n"
2107   "\n"
2108   "Search the configured OpenPGP keyservers (see command KEYSERVER)\n"
2109   "for keys matching PATTERN";
2110 static gpg_error_t
2111 cmd_ks_search (assuan_context_t ctx, char *line)
2112 {
2113   ctrl_t ctrl = assuan_get_pointer (ctx);
2114   gpg_error_t err;
2115   strlist_t list, sl;
2116   char *p;
2117   estream_t outfp;
2118
2119   /* No options for now.  */
2120   line = skip_options (line);
2121
2122   /* Break the line down into an strlist.  Each pattern is
2123      percent-plus escaped. */
2124   list = NULL;
2125   for (p=line; *p; line = p)
2126     {
2127       while (*p && *p != ' ')
2128         p++;
2129       if (*p)
2130         *p++ = 0;
2131       if (*line)
2132         {
2133           sl = xtrymalloc (sizeof *sl + strlen (line));
2134           if (!sl)
2135             {
2136               err = gpg_error_from_syserror ();
2137               goto leave;
2138             }
2139           sl->flags = 0;
2140           strcpy_escaped_plus (sl->d, line);
2141           sl->next = list;
2142           list = sl;
2143         }
2144     }
2145
2146   err = ensure_keyserver (ctrl);
2147   if (err)
2148     goto leave;
2149
2150   /* Setup an output stream and perform the search.  */
2151   outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
2152   if (!outfp)
2153     err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2154   else
2155     {
2156       err = ks_action_search (ctrl, ctrl->server_local->keyservers,
2157                               list, outfp);
2158       es_fclose (outfp);
2159     }
2160
2161  leave:
2162   free_strlist (list);
2163   return leave_cmd (ctx, err);
2164 }
2165
2166
2167 \f
2168 static const char hlp_ks_get[] =
2169   "KS_GET {<pattern>}\n"
2170   "\n"
2171   "Get the keys matching PATTERN from the configured OpenPGP keyservers\n"
2172   "(see command KEYSERVER).  Each pattern should be a keyid, a fingerprint,\n"
2173   "or an exact name indicated by the '=' prefix.";
2174 static gpg_error_t
2175 cmd_ks_get (assuan_context_t ctx, char *line)
2176 {
2177   ctrl_t ctrl = assuan_get_pointer (ctx);
2178   gpg_error_t err;
2179   strlist_t list, sl;
2180   char *p;
2181   estream_t outfp;
2182
2183   /* No options for now.  */
2184   line = skip_options (line);
2185
2186   /* Break the line into a strlist.  Each pattern is by
2187      definition percent-plus escaped.  However we only support keyids
2188      and fingerprints and thus the client has no need to apply the
2189      escaping.  */
2190   list = NULL;
2191   for (p=line; *p; line = p)
2192     {
2193       while (*p && *p != ' ')
2194         p++;
2195       if (*p)
2196         *p++ = 0;
2197       if (*line)
2198         {
2199           sl = xtrymalloc (sizeof *sl + strlen (line));
2200           if (!sl)
2201             {
2202               err = gpg_error_from_syserror ();
2203               goto leave;
2204             }
2205           sl->flags = 0;
2206           strcpy_escaped_plus (sl->d, line);
2207           sl->next = list;
2208           list = sl;
2209         }
2210     }
2211
2212   err = ensure_keyserver (ctrl);
2213   if (err)
2214     goto leave;
2215
2216   /* Setup an output stream and perform the get.  */
2217   outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
2218   if (!outfp)
2219     err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2220   else
2221     {
2222       ctrl->server_local->inhibit_data_logging = 1;
2223       ctrl->server_local->inhibit_data_logging_now = 0;
2224       ctrl->server_local->inhibit_data_logging_count = 0;
2225       err = ks_action_get (ctrl, ctrl->server_local->keyservers, list, outfp);
2226       es_fclose (outfp);
2227       ctrl->server_local->inhibit_data_logging = 0;
2228     }
2229
2230  leave:
2231   free_strlist (list);
2232   return leave_cmd (ctx, err);
2233 }
2234
2235
2236 static const char hlp_ks_fetch[] =
2237   "KS_FETCH <URL>\n"
2238   "\n"
2239   "Get the key(s) from URL.";
2240 static gpg_error_t
2241 cmd_ks_fetch (assuan_context_t ctx, char *line)
2242 {
2243   ctrl_t ctrl = assuan_get_pointer (ctx);
2244   gpg_error_t err;
2245   estream_t outfp;
2246
2247   /* No options for now.  */
2248   line = skip_options (line);
2249
2250   err = ensure_keyserver (ctrl);  /* FIXME: Why do we needs this here?  */
2251   if (err)
2252     goto leave;
2253
2254   /* Setup an output stream and perform the get.  */
2255   outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
2256   if (!outfp)
2257     err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2258   else
2259     {
2260       ctrl->server_local->inhibit_data_logging = 1;
2261       ctrl->server_local->inhibit_data_logging_now = 0;
2262       ctrl->server_local->inhibit_data_logging_count = 0;
2263       err = ks_action_fetch (ctrl, line, outfp);
2264       es_fclose (outfp);
2265       ctrl->server_local->inhibit_data_logging = 0;
2266     }
2267
2268  leave:
2269   return leave_cmd (ctx, err);
2270 }
2271
2272
2273 \f
2274 static const char hlp_ks_put[] =
2275   "KS_PUT\n"
2276   "\n"
2277   "Send a key to the configured OpenPGP keyservers.  The actual key material\n"
2278   "is then requested by Dirmngr using\n"
2279   "\n"
2280   "  INQUIRE KEYBLOCK\n"
2281   "\n"
2282   "The client shall respond with a binary version of the keyblock (e.g.,\n"
2283   "the output of `gpg --export KEYID').  For LDAP\n"
2284   "keyservers Dirmngr may ask for meta information of the provided keyblock\n"
2285   "using:\n"
2286   "\n"
2287   "  INQUIRE KEYBLOCK_INFO\n"
2288   "\n"
2289   "The client shall respond with a colon delimited info lines (the output\n"
2290   "of 'for x in keys sigs; do gpg --list-$x --with-colons KEYID; done').\n";
2291 static gpg_error_t
2292 cmd_ks_put (assuan_context_t ctx, char *line)
2293 {
2294   ctrl_t ctrl = assuan_get_pointer (ctx);
2295   gpg_error_t err;
2296   unsigned char *value = NULL;
2297   size_t valuelen;
2298   unsigned char *info = NULL;
2299   size_t infolen;
2300
2301   /* No options for now.  */
2302   line = skip_options (line);
2303
2304   err = ensure_keyserver (ctrl);
2305   if (err)
2306     goto leave;
2307
2308   /* Ask for the key material.  */
2309   err = assuan_inquire (ctx, "KEYBLOCK",
2310                         &value, &valuelen, MAX_KEYBLOCK_LENGTH);
2311   if (err)
2312     {
2313       log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
2314       goto leave;
2315     }
2316
2317   if (!valuelen) /* No data returned; return a comprehensible error. */
2318     {
2319       err = gpg_error (GPG_ERR_MISSING_CERT);
2320       goto leave;
2321     }
2322
2323   /* Ask for the key meta data. Not actually needed for HKP servers
2324      but we do it anyway to test the client implementaion.  */
2325   err = assuan_inquire (ctx, "KEYBLOCK_INFO",
2326                         &info, &infolen, MAX_KEYBLOCK_LENGTH);
2327   if (err)
2328     {
2329       log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
2330       goto leave;
2331     }
2332
2333   /* Send the key.  */
2334   err = ks_action_put (ctrl, ctrl->server_local->keyservers,
2335                        value, valuelen, info, infolen);
2336
2337  leave:
2338   xfree (info);
2339   xfree (value);
2340   return leave_cmd (ctx, err);
2341 }
2342
2343
2344 \f
2345 static const char hlp_loadswdb[] =
2346   "LOADSWDB [--force]\n"
2347   "\n"
2348   "Load and verify the swdb.lst from the Net.";
2349 static gpg_error_t
2350 cmd_loadswdb (assuan_context_t ctx, char *line)
2351 {
2352   ctrl_t ctrl = assuan_get_pointer (ctx);
2353   gpg_error_t err;
2354
2355   err = dirmngr_load_swdb (ctrl, has_option (line, "--force"));
2356
2357   return leave_cmd (ctx, err);
2358 }
2359
2360
2361 \f
2362 static const char hlp_getinfo[] =
2363   "GETINFO <what>\n"
2364   "\n"
2365   "Multi purpose command to return certain information.  \n"
2366   "Supported values of WHAT are:\n"
2367   "\n"
2368   "version     - Return the version of the program.\n"
2369   "pid         - Return the process id of the server.\n"
2370   "tor         - Return OK if running in Tor mode\n"
2371   "dnsinfo     - Return info about the DNS resolver\n"
2372   "socket_name - Return the name of the socket.\n";
2373 static gpg_error_t
2374 cmd_getinfo (assuan_context_t ctx, char *line)
2375 {
2376   ctrl_t ctrl = assuan_get_pointer (ctx);
2377   gpg_error_t err;
2378
2379   if (!strcmp (line, "version"))
2380     {
2381       const char *s = VERSION;
2382       err = assuan_send_data (ctx, s, strlen (s));
2383     }
2384   else if (!strcmp (line, "pid"))
2385     {
2386       char numbuf[50];
2387
2388       snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
2389       err = assuan_send_data (ctx, numbuf, strlen (numbuf));
2390     }
2391   else if (!strcmp (line, "socket_name"))
2392     {
2393       const char *s = dirmngr_get_current_socket_name ();
2394       err = assuan_send_data (ctx, s, strlen (s));
2395     }
2396   else if (!strcmp (line, "tor"))
2397     {
2398       int use_tor;
2399
2400       use_tor = dirmngr_use_tor ();
2401       if (use_tor)
2402         {
2403           if (!is_tor_running (ctrl))
2404             err = assuan_write_status (ctx, "NO_TOR", "Tor not running");
2405           else
2406             err = 0;
2407           if (!err)
2408             assuan_set_okay_line (ctx, use_tor == 1 ? "- Tor mode is enabled"
2409                                   /**/              : "- Tor mode is enforced");
2410         }
2411       else
2412         err = set_error (GPG_ERR_FALSE, "Tor mode is NOT enabled");
2413     }
2414   else if (!strcmp (line, "dnsinfo"))
2415     {
2416       if (standard_resolver_p ())
2417         assuan_set_okay_line
2418           (ctx, "- Forced use of System resolver (w/o Tor support)");
2419       else
2420         {
2421 #ifdef USE_LIBDNS
2422           assuan_set_okay_line (ctx, (recursive_resolver_p ()
2423                                       ? "- Libdns recursive resolver"
2424                                       : "- Libdns stub resolver"));
2425 #else
2426           assuan_set_okay_line (ctx, "- System resolver (w/o Tor support)");
2427 #endif
2428         }
2429       err = 0;
2430     }
2431   else
2432     err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
2433
2434   return leave_cmd (ctx, err);
2435 }
2436
2437
2438 \f
2439 static const char hlp_killdirmngr[] =
2440   "KILLDIRMNGR\n"
2441   "\n"
2442   "This command allows a user - given sufficient permissions -\n"
2443   "to kill this dirmngr process.\n";
2444 static gpg_error_t
2445 cmd_killdirmngr (assuan_context_t ctx, char *line)
2446 {
2447   ctrl_t ctrl = assuan_get_pointer (ctx);
2448
2449   (void)line;
2450
2451   ctrl->server_local->stopme = 1;
2452   assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
2453   return gpg_error (GPG_ERR_EOF);
2454 }
2455
2456
2457 static const char hlp_reloaddirmngr[] =
2458   "RELOADDIRMNGR\n"
2459   "\n"
2460   "This command is an alternative to SIGHUP\n"
2461   "to reload the configuration.";
2462 static gpg_error_t
2463 cmd_reloaddirmngr (assuan_context_t ctx, char *line)
2464 {
2465   (void)ctx;
2466   (void)line;
2467
2468   dirmngr_sighup_action ();
2469   return 0;
2470 }
2471
2472
2473 \f
2474 /* Tell the assuan library about our commands. */
2475 static int
2476 register_commands (assuan_context_t ctx)
2477 {
2478   static struct {
2479     const char *name;
2480     assuan_handler_t handler;
2481     const char * const help;
2482   } table[] = {
2483     { "DNS_CERT",   cmd_dns_cert,   hlp_dns_cert },
2484     { "WKD_GET",    cmd_wkd_get,    hlp_wkd_get },
2485     { "LDAPSERVER", cmd_ldapserver, hlp_ldapserver },
2486     { "ISVALID",    cmd_isvalid,    hlp_isvalid },
2487     { "CHECKCRL",   cmd_checkcrl,   hlp_checkcrl },
2488     { "CHECKOCSP",  cmd_checkocsp,  hlp_checkocsp },
2489     { "LOOKUP",     cmd_lookup,     hlp_lookup },
2490     { "LOADCRL",    cmd_loadcrl,    hlp_loadcrl },
2491     { "LISTCRLS",   cmd_listcrls,   hlp_listcrls },
2492     { "CACHECERT",  cmd_cachecert,  hlp_cachecert },
2493     { "VALIDATE",   cmd_validate,   hlp_validate },
2494     { "KEYSERVER",  cmd_keyserver,  hlp_keyserver },
2495     { "KS_SEARCH",  cmd_ks_search,  hlp_ks_search },
2496     { "KS_GET",     cmd_ks_get,     hlp_ks_get },
2497     { "KS_FETCH",   cmd_ks_fetch,   hlp_ks_fetch },
2498     { "KS_PUT",     cmd_ks_put,     hlp_ks_put },
2499     { "GETINFO",    cmd_getinfo,    hlp_getinfo },
2500     { "LOADSWDB",   cmd_loadswdb,   hlp_loadswdb },
2501     { "KILLDIRMNGR",cmd_killdirmngr,hlp_killdirmngr },
2502     { "RELOADDIRMNGR",cmd_reloaddirmngr,hlp_reloaddirmngr },
2503     { NULL, NULL }
2504   };
2505   int i, j, rc;
2506
2507   for (i=j=0; table[i].name; i++)
2508     {
2509       rc = assuan_register_command (ctx, table[i].name, table[i].handler,
2510                                     table[i].help);
2511       if (rc)
2512         return rc;
2513     }
2514   return 0;
2515 }
2516
2517
2518 /* Note that we do not reset the list of configured keyservers.  */
2519 static gpg_error_t
2520 reset_notify (assuan_context_t ctx, char *line)
2521 {
2522   ctrl_t ctrl = assuan_get_pointer (ctx);
2523   (void)line;
2524
2525 #if USE_LDAP
2526   ldapserver_list_free (ctrl->server_local->ldapservers);
2527 #endif /*USE_LDAP*/
2528   ctrl->server_local->ldapservers = NULL;
2529   return 0;
2530 }
2531
2532
2533 /* This function is called by our assuan log handler to test whether a
2534  * log message shall really be printed.  The function must return
2535  * false to inhibit the logging of MSG.  CAT gives the requested log
2536  * category.  MSG might be NULL. */
2537 int
2538 dirmngr_assuan_log_monitor (assuan_context_t ctx, unsigned int cat,
2539                             const char *msg)
2540 {
2541   ctrl_t ctrl = assuan_get_pointer (ctx);
2542
2543   (void)cat;
2544   (void)msg;
2545
2546   if (!ctrl || !ctrl->server_local)
2547     return 1; /* Can't decide - allow logging.  */
2548
2549   if (!ctrl->server_local->inhibit_data_logging)
2550     return 1; /* Not requested - allow logging.  */
2551
2552   /* Disallow logging if *_now is true.  */
2553   return !ctrl->server_local->inhibit_data_logging_now;
2554 }
2555
2556
2557 /* Startup the server and run the main command loop.  With FD = -1,
2558    use stdin/stdout. */
2559 void
2560 start_command_handler (assuan_fd_t fd)
2561 {
2562   static const char hello[] = "Dirmngr " VERSION " at your service";
2563   static char *hello_line;
2564   int rc;
2565   assuan_context_t ctx;
2566   ctrl_t ctrl;
2567
2568   ctrl = xtrycalloc (1, sizeof *ctrl);
2569   if (ctrl)
2570     ctrl->server_local = xtrycalloc (1, sizeof *ctrl->server_local);
2571   if (!ctrl || !ctrl->server_local)
2572     {
2573       log_error (_("can't allocate control structure: %s\n"),
2574                  strerror (errno));
2575       xfree (ctrl);
2576       return;
2577     }
2578
2579   dirmngr_init_default_ctrl (ctrl);
2580
2581   rc = assuan_new (&ctx);
2582   if (rc)
2583     {
2584       log_error (_("failed to allocate assuan context: %s\n"),
2585                  gpg_strerror (rc));
2586       dirmngr_exit (2);
2587     }
2588
2589   if (fd == ASSUAN_INVALID_FD)
2590     {
2591       assuan_fd_t filedes[2];
2592
2593       filedes[0] = assuan_fdopen (0);
2594       filedes[1] = assuan_fdopen (1);
2595       rc = assuan_init_pipe_server (ctx, filedes);
2596     }
2597   else
2598     {
2599       rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED);
2600     }
2601
2602   if (rc)
2603     {
2604       assuan_release (ctx);
2605       log_error (_("failed to initialize the server: %s\n"),
2606                  gpg_strerror(rc));
2607       dirmngr_exit (2);
2608     }
2609
2610   rc = register_commands (ctx);
2611   if (rc)
2612     {
2613       log_error (_("failed to the register commands with Assuan: %s\n"),
2614                  gpg_strerror(rc));
2615       dirmngr_exit (2);
2616     }
2617
2618
2619   if (!hello_line)
2620     {
2621       hello_line = xtryasprintf
2622         ("Home: %s\n"
2623          "Config: %s\n"
2624          "%s",
2625          gnupg_homedir (),
2626          opt.config_filename? opt.config_filename : "[none]",
2627          hello);
2628     }
2629
2630   ctrl->server_local->assuan_ctx = ctx;
2631   assuan_set_pointer (ctx, ctrl);
2632
2633   assuan_set_hello_line (ctx, hello_line);
2634   assuan_register_option_handler (ctx, option_handler);
2635   assuan_register_reset_notify (ctx, reset_notify);
2636
2637   for (;;)
2638     {
2639       rc = assuan_accept (ctx);
2640       if (rc == -1)
2641         break;
2642       if (rc)
2643         {
2644           log_info (_("Assuan accept problem: %s\n"), gpg_strerror (rc));
2645           break;
2646         }
2647
2648 #ifndef HAVE_W32_SYSTEM
2649       if (opt.verbose)
2650         {
2651           assuan_peercred_t peercred;
2652
2653           if (!assuan_get_peercred (ctx, &peercred))
2654             log_info ("connection from process %ld (%ld:%ld)\n",
2655                       (long)peercred->pid, (long)peercred->uid,
2656                       (long)peercred->gid);
2657         }
2658 #endif
2659
2660       rc = assuan_process (ctx);
2661       if (rc)
2662         {
2663           log_info (_("Assuan processing failed: %s\n"), gpg_strerror (rc));
2664           continue;
2665         }
2666     }
2667
2668
2669 #if USE_LDAP
2670   ldap_wrapper_connection_cleanup (ctrl);
2671
2672   ldapserver_list_free (ctrl->server_local->ldapservers);
2673 #endif /*USE_LDAP*/
2674   ctrl->server_local->ldapservers = NULL;
2675
2676   release_ctrl_keyservers (ctrl);
2677
2678   ctrl->server_local->assuan_ctx = NULL;
2679   assuan_release (ctx);
2680
2681   if (ctrl->server_local->stopme)
2682     dirmngr_exit (0);
2683
2684   if (ctrl->refcount)
2685     log_error ("oops: connection control structure still referenced (%d)\n",
2686                ctrl->refcount);
2687   else
2688     {
2689       release_ctrl_ocsp_certs (ctrl);
2690       xfree (ctrl->server_local);
2691       dirmngr_deinit_default_ctrl (ctrl);
2692       xfree (ctrl);
2693     }
2694 }
2695
2696
2697 /* Send a status line back to the client.  KEYWORD is the status
2698    keyword, the optional string arguments are blank separated added to
2699    the line, the last argument must be a NULL. */
2700 gpg_error_t
2701 dirmngr_status (ctrl_t ctrl, const char *keyword, ...)
2702 {
2703   gpg_error_t err = 0;
2704   va_list arg_ptr;
2705   const char *text;
2706
2707   va_start (arg_ptr, keyword);
2708
2709   if (ctrl->server_local)
2710     {
2711       assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2712       char buf[950], *p;
2713       size_t n;
2714
2715       p = buf;
2716       n = 0;
2717       while ( (text = va_arg (arg_ptr, const char *)) )
2718         {
2719           if (n)
2720             {
2721               *p++ = ' ';
2722               n++;
2723             }
2724           for ( ; *text && n < DIM (buf)-2; n++)
2725             *p++ = *text++;
2726         }
2727       *p = 0;
2728       err = assuan_write_status (ctx, keyword, buf);
2729     }
2730
2731   va_end (arg_ptr);
2732   return err;
2733 }
2734
2735
2736 /* Print a help status line.  TEXTLEN gives the length of the text
2737    from TEXT to be printed.  The function splits text at LFs.  */
2738 gpg_error_t
2739 dirmngr_status_help (ctrl_t ctrl, const char *text)
2740 {
2741   gpg_error_t err = 0;
2742
2743   if (ctrl->server_local)
2744     {
2745       assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2746       char buf[950], *p;
2747       size_t n;
2748
2749       do
2750         {
2751           p = buf;
2752           n = 0;
2753           for ( ; *text && *text != '\n' && n < DIM (buf)-2; n++)
2754             *p++ = *text++;
2755           if (*text == '\n')
2756             text++;
2757           *p = 0;
2758           err = assuan_write_status (ctx, "#", buf);
2759         }
2760       while (!err && *text);
2761     }
2762
2763   return err;
2764 }
2765
2766 /* Send a tick progress indicator back.  Fixme: This is only done for
2767    the currently active channel.  */
2768 gpg_error_t
2769 dirmngr_tick (ctrl_t ctrl)
2770 {
2771   static time_t next_tick = 0;
2772   gpg_error_t err = 0;
2773   time_t now = time (NULL);
2774
2775   if (!next_tick)
2776     {
2777       next_tick = now + 1;
2778     }
2779   else if ( now > next_tick )
2780     {
2781       if (ctrl)
2782         {
2783           err = dirmngr_status (ctrl, "PROGRESS", "tick", "? 0 0", NULL);
2784           if (err)
2785             {
2786               /* Take this as in indication for a cancel request.  */
2787               err = gpg_error (GPG_ERR_CANCELED);
2788             }
2789           now = time (NULL);
2790         }
2791
2792       next_tick = now + 1;
2793     }
2794   return err;
2795 }