dirmngr: Add options --tls and --systrust 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]\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.";
1757 static gpg_error_t
1758 cmd_validate (assuan_context_t ctx, char *line)
1759 {
1760   ctrl_t ctrl = assuan_get_pointer (ctx);
1761   gpg_error_t err;
1762   ksba_cert_t cert = NULL;
1763   certlist_t certlist = NULL;
1764   unsigned char *value = NULL;
1765   size_t valuelen;
1766   int systrust_mode, tls_mode;
1767
1768   systrust_mode = has_option (line, "--systrust");
1769   tls_mode = has_option (line, "--tls");
1770   line = skip_options (line);
1771
1772   if (tls_mode)
1773     err = assuan_inquire (ctrl->server_local->assuan_ctx, "CERTLIST",
1774                           &value, &valuelen, MAX_CERTLIST_LENGTH);
1775   else
1776     err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1777                           &value, &valuelen, MAX_CERT_LENGTH);
1778   if (err)
1779     {
1780       log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1781       goto leave;
1782     }
1783
1784   if (!valuelen) /* No data returned; return a comprehensible error. */
1785     err = gpg_error (GPG_ERR_MISSING_CERT);
1786   else if (tls_mode)
1787     {
1788       estream_t fp;
1789
1790       fp = es_fopenmem_init (0, "rb", value, valuelen);
1791       if (!fp)
1792         err = gpg_error_from_syserror ();
1793       else
1794         {
1795           err = read_certlist_from_stream (&certlist, fp);
1796           es_fclose (fp);
1797           if (!err && !certlist)
1798             err = gpg_error (GPG_ERR_MISSING_CERT);
1799           if (!err)
1800             {
1801               /* Extraxt the first certificate from the list.  */
1802               cert = certlist->cert;
1803               ksba_cert_ref (cert);
1804             }
1805         }
1806     }
1807   else
1808     {
1809       err = ksba_cert_new (&cert);
1810       if (!err)
1811         err = ksba_cert_init_from_mem (cert, value, valuelen);
1812     }
1813   xfree (value);
1814   if(err)
1815     goto leave;
1816
1817   if (!tls_mode)
1818     {
1819       /* If we have this certificate already in our cache, use the
1820        * cached version for validation because this will take care of
1821        * any cached results.  We don't need to do this in tls mode
1822        * because this has already been done for certificate in a
1823        * certlist_t. */
1824       unsigned char fpr[20];
1825       ksba_cert_t tmpcert;
1826
1827       cert_compute_fpr (cert, fpr);
1828       tmpcert = get_cert_byfpr (fpr);
1829       if (tmpcert)
1830         {
1831           ksba_cert_release (cert);
1832           cert = tmpcert;
1833         }
1834     }
1835
1836   /* Quick hack to make verification work by inserting the supplied
1837    * certs into the cache.  */
1838   if (tls_mode && certlist)
1839     {
1840       certlist_t cl;
1841
1842       for (cl = certlist->next; cl; cl = cl->next)
1843         cache_cert (cl->cert);
1844     }
1845
1846
1847   err = validate_cert_chain
1848     (ctrl, cert, NULL,
1849      tls_mode && systrust_mode ? VALIDATE_MODE_TLS_SYSTRUST  :
1850      tls_mode                  ? VALIDATE_MODE_TLS           :
1851      /**/        systrust_mode ? VALIDATE_MODE_CERT_SYSTRUST :
1852      /**/                        VALIDATE_MODE_CERT,
1853      NULL);
1854
1855  leave:
1856   ksba_cert_release (cert);
1857   release_certlist (certlist);
1858   return leave_cmd (ctx, err);
1859 }
1860
1861
1862 \f
1863 /* Parse an keyserver URI and store it in a new uri item which is
1864    returned at R_ITEM.  On error return an error code.  */
1865 static gpg_error_t
1866 make_keyserver_item (const char *uri, uri_item_t *r_item)
1867 {
1868   gpg_error_t err;
1869   uri_item_t item;
1870
1871   *r_item = NULL;
1872   item = xtrymalloc (sizeof *item + strlen (uri));
1873   if (!item)
1874     return gpg_error_from_syserror ();
1875
1876   item->next = NULL;
1877   item->parsed_uri = NULL;
1878   strcpy (item->uri, uri);
1879
1880 #if USE_LDAP
1881   if (ldap_uri_p (item->uri))
1882     err = ldap_parse_uri (&item->parsed_uri, uri);
1883   else
1884 #endif
1885     {
1886       err = http_parse_uri (&item->parsed_uri, uri, 1);
1887     }
1888
1889   if (err)
1890     xfree (item);
1891   else
1892     *r_item = item;
1893   return err;
1894 }
1895
1896
1897 /* If no keyserver is stored in CTRL but a global keyserver has been
1898    set, put that global keyserver into CTRL.  We need use this
1899    function to help migrate from the old gpg based keyserver
1900    configuration to the new dirmngr based configuration.  */
1901 static gpg_error_t
1902 ensure_keyserver (ctrl_t ctrl)
1903 {
1904   gpg_error_t err;
1905   uri_item_t item;
1906   uri_item_t onion_items = NULL;
1907   uri_item_t plain_items = NULL;
1908   uri_item_t ui;
1909   strlist_t sl;
1910
1911   if (ctrl->server_local->keyservers)
1912     return 0; /* Already set for this session.  */
1913   if (!opt.keyserver)
1914     {
1915       /* No global option set.  Fall back to default:  */
1916       return make_keyserver_item (DIRMNGR_DEFAULT_KEYSERVER,
1917                                   &ctrl->server_local->keyservers);
1918     }
1919
1920   for (sl = opt.keyserver; sl; sl = sl->next)
1921     {
1922       err = make_keyserver_item (sl->d, &item);
1923       if (err)
1924         goto leave;
1925       if (item->parsed_uri->onion)
1926         {
1927           item->next = onion_items;
1928           onion_items = item;
1929         }
1930       else
1931         {
1932           item->next = plain_items;
1933           plain_items = item;
1934         }
1935     }
1936
1937   /* Decide which to use.  Note that the sesssion has no keyservers
1938      yet set. */
1939   if (onion_items && !onion_items->next && plain_items && !plain_items->next)
1940     {
1941       /* If there is just one onion and one plain keyserver given, we take
1942          only one depending on whether Tor is running or not.  */
1943       if (is_tor_running (ctrl))
1944         {
1945           ctrl->server_local->keyservers = onion_items;
1946           onion_items = NULL;
1947         }
1948       else
1949         {
1950           ctrl->server_local->keyservers = plain_items;
1951           plain_items = NULL;
1952         }
1953     }
1954   else if (!is_tor_running (ctrl))
1955     {
1956       /* Tor is not running.  It does not make sense to add Onion
1957          addresses.  */
1958       ctrl->server_local->keyservers = plain_items;
1959       plain_items = NULL;
1960     }
1961   else
1962     {
1963       /* In all other cases add all keyservers.  */
1964       ctrl->server_local->keyservers = onion_items;
1965       onion_items = NULL;
1966       for (ui = ctrl->server_local->keyservers; ui && ui->next; ui = ui->next)
1967         ;
1968       if (ui)
1969         ui->next = plain_items;
1970       else
1971         ctrl->server_local->keyservers = plain_items;
1972       plain_items = NULL;
1973     }
1974
1975  leave:
1976   release_uri_item_list (onion_items);
1977   release_uri_item_list (plain_items);
1978
1979   return err;
1980 }
1981
1982
1983 static const char hlp_keyserver[] =
1984   "KEYSERVER [<options>] [<uri>|<host>]\n"
1985   "Options are:\n"
1986   "  --help\n"
1987   "  --clear      Remove all configured keyservers\n"
1988   "  --resolve    Resolve HKP host names and rotate\n"
1989   "  --hosttable  Print table of known hosts and pools\n"
1990   "  --dead       Mark <host> as dead\n"
1991   "  --alive      Mark <host> as alive\n"
1992   "\n"
1993   "If called without arguments list all configured keyserver URLs.\n"
1994   "If called with an URI add this as keyserver.  Note that keyservers\n"
1995   "are configured on a per-session base.  A default keyserver may already be\n"
1996   "present, thus the \"--clear\" option must be used to get full control.\n"
1997   "If \"--clear\" and an URI are used together the clear command is\n"
1998   "obviously executed first.  A RESET command does not change the list\n"
1999   "of configured keyservers.";
2000 static gpg_error_t
2001 cmd_keyserver (assuan_context_t ctx, char *line)
2002 {
2003   ctrl_t ctrl = assuan_get_pointer (ctx);
2004   gpg_error_t err = 0;
2005   int clear_flag, add_flag, help_flag, host_flag, resolve_flag;
2006   int dead_flag, alive_flag;
2007   uri_item_t item = NULL; /* gcc 4.4.5 is not able to detect that it
2008                              is always initialized.  */
2009
2010   clear_flag = has_option (line, "--clear");
2011   help_flag = has_option (line, "--help");
2012   resolve_flag = has_option (line, "--resolve");
2013   host_flag = has_option (line, "--hosttable");
2014   dead_flag = has_option (line, "--dead");
2015   alive_flag = has_option (line, "--alive");
2016   line = skip_options (line);
2017   add_flag = !!*line;
2018
2019   if (help_flag)
2020     {
2021       err = ks_action_help (ctrl, line);
2022       goto leave;
2023     }
2024
2025   if (resolve_flag)
2026     {
2027       err = ensure_keyserver (ctrl);
2028       if (!err)
2029         err = ks_action_resolve (ctrl, ctrl->server_local->keyservers);
2030       if (err)
2031         goto leave;
2032     }
2033
2034   if (alive_flag && dead_flag)
2035     {
2036       err = set_error (GPG_ERR_ASS_PARAMETER, "no support for zombies");
2037       goto leave;
2038     }
2039   if (dead_flag)
2040     {
2041       err = check_owner_permission (ctx, "no permission to use --dead");
2042       if (err)
2043         goto leave;
2044     }
2045   if (alive_flag || dead_flag)
2046     {
2047       if (!*line)
2048         {
2049           err = set_error (GPG_ERR_ASS_PARAMETER, "name of host missing");
2050           goto leave;
2051         }
2052
2053       err = ks_hkp_mark_host (ctrl, line, alive_flag);
2054       if (err)
2055         goto leave;
2056     }
2057
2058   if (host_flag)
2059     {
2060       err = ks_hkp_print_hosttable (ctrl);
2061       if (err)
2062         goto leave;
2063     }
2064   if (resolve_flag || host_flag || alive_flag || dead_flag)
2065     goto leave;
2066
2067   if (add_flag)
2068     {
2069       err = make_keyserver_item (line, &item);
2070       if (err)
2071         goto leave;
2072     }
2073   if (clear_flag)
2074     release_ctrl_keyservers (ctrl);
2075   if (add_flag)
2076     {
2077       item->next = ctrl->server_local->keyservers;
2078       ctrl->server_local->keyservers = item;
2079     }
2080
2081   if (!add_flag && !clear_flag && !help_flag)
2082     {
2083       /* List configured keyservers.  However, we first add a global
2084          keyserver. */
2085       uri_item_t u;
2086
2087       err = ensure_keyserver (ctrl);
2088       if (err)
2089         {
2090           assuan_set_error (ctx, err,
2091                             "Bad keyserver configuration in dirmngr.conf");
2092           goto leave;
2093         }
2094
2095       for (u=ctrl->server_local->keyservers; u; u = u->next)
2096         dirmngr_status (ctrl, "KEYSERVER", u->uri, NULL);
2097     }
2098   err = 0;
2099
2100  leave:
2101   return leave_cmd (ctx, err);
2102 }
2103
2104
2105 \f
2106 static const char hlp_ks_search[] =
2107   "KS_SEARCH {<pattern>}\n"
2108   "\n"
2109   "Search the configured OpenPGP keyservers (see command KEYSERVER)\n"
2110   "for keys matching PATTERN";
2111 static gpg_error_t
2112 cmd_ks_search (assuan_context_t ctx, char *line)
2113 {
2114   ctrl_t ctrl = assuan_get_pointer (ctx);
2115   gpg_error_t err;
2116   strlist_t list, sl;
2117   char *p;
2118   estream_t outfp;
2119
2120   /* No options for now.  */
2121   line = skip_options (line);
2122
2123   /* Break the line down into an strlist.  Each pattern is
2124      percent-plus escaped. */
2125   list = NULL;
2126   for (p=line; *p; line = p)
2127     {
2128       while (*p && *p != ' ')
2129         p++;
2130       if (*p)
2131         *p++ = 0;
2132       if (*line)
2133         {
2134           sl = xtrymalloc (sizeof *sl + strlen (line));
2135           if (!sl)
2136             {
2137               err = gpg_error_from_syserror ();
2138               goto leave;
2139             }
2140           sl->flags = 0;
2141           strcpy_escaped_plus (sl->d, line);
2142           sl->next = list;
2143           list = sl;
2144         }
2145     }
2146
2147   err = ensure_keyserver (ctrl);
2148   if (err)
2149     goto leave;
2150
2151   /* Setup an output stream and perform the search.  */
2152   outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
2153   if (!outfp)
2154     err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2155   else
2156     {
2157       err = ks_action_search (ctrl, ctrl->server_local->keyservers,
2158                               list, outfp);
2159       es_fclose (outfp);
2160     }
2161
2162  leave:
2163   free_strlist (list);
2164   return leave_cmd (ctx, err);
2165 }
2166
2167
2168 \f
2169 static const char hlp_ks_get[] =
2170   "KS_GET {<pattern>}\n"
2171   "\n"
2172   "Get the keys matching PATTERN from the configured OpenPGP keyservers\n"
2173   "(see command KEYSERVER).  Each pattern should be a keyid, a fingerprint,\n"
2174   "or an exact name indicated by the '=' prefix.";
2175 static gpg_error_t
2176 cmd_ks_get (assuan_context_t ctx, char *line)
2177 {
2178   ctrl_t ctrl = assuan_get_pointer (ctx);
2179   gpg_error_t err;
2180   strlist_t list, sl;
2181   char *p;
2182   estream_t outfp;
2183
2184   /* No options for now.  */
2185   line = skip_options (line);
2186
2187   /* Break the line into a strlist.  Each pattern is by
2188      definition percent-plus escaped.  However we only support keyids
2189      and fingerprints and thus the client has no need to apply the
2190      escaping.  */
2191   list = NULL;
2192   for (p=line; *p; line = p)
2193     {
2194       while (*p && *p != ' ')
2195         p++;
2196       if (*p)
2197         *p++ = 0;
2198       if (*line)
2199         {
2200           sl = xtrymalloc (sizeof *sl + strlen (line));
2201           if (!sl)
2202             {
2203               err = gpg_error_from_syserror ();
2204               goto leave;
2205             }
2206           sl->flags = 0;
2207           strcpy_escaped_plus (sl->d, line);
2208           sl->next = list;
2209           list = sl;
2210         }
2211     }
2212
2213   err = ensure_keyserver (ctrl);
2214   if (err)
2215     goto leave;
2216
2217   /* Setup an output stream and perform the get.  */
2218   outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
2219   if (!outfp)
2220     err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2221   else
2222     {
2223       ctrl->server_local->inhibit_data_logging = 1;
2224       ctrl->server_local->inhibit_data_logging_now = 0;
2225       ctrl->server_local->inhibit_data_logging_count = 0;
2226       err = ks_action_get (ctrl, ctrl->server_local->keyservers, list, outfp);
2227       es_fclose (outfp);
2228       ctrl->server_local->inhibit_data_logging = 0;
2229     }
2230
2231  leave:
2232   free_strlist (list);
2233   return leave_cmd (ctx, err);
2234 }
2235
2236
2237 static const char hlp_ks_fetch[] =
2238   "KS_FETCH <URL>\n"
2239   "\n"
2240   "Get the key(s) from URL.";
2241 static gpg_error_t
2242 cmd_ks_fetch (assuan_context_t ctx, char *line)
2243 {
2244   ctrl_t ctrl = assuan_get_pointer (ctx);
2245   gpg_error_t err;
2246   estream_t outfp;
2247
2248   /* No options for now.  */
2249   line = skip_options (line);
2250
2251   err = ensure_keyserver (ctrl);  /* FIXME: Why do we needs this here?  */
2252   if (err)
2253     goto leave;
2254
2255   /* Setup an output stream and perform the get.  */
2256   outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
2257   if (!outfp)
2258     err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2259   else
2260     {
2261       ctrl->server_local->inhibit_data_logging = 1;
2262       ctrl->server_local->inhibit_data_logging_now = 0;
2263       ctrl->server_local->inhibit_data_logging_count = 0;
2264       err = ks_action_fetch (ctrl, line, outfp);
2265       es_fclose (outfp);
2266       ctrl->server_local->inhibit_data_logging = 0;
2267     }
2268
2269  leave:
2270   return leave_cmd (ctx, err);
2271 }
2272
2273
2274 \f
2275 static const char hlp_ks_put[] =
2276   "KS_PUT\n"
2277   "\n"
2278   "Send a key to the configured OpenPGP keyservers.  The actual key material\n"
2279   "is then requested by Dirmngr using\n"
2280   "\n"
2281   "  INQUIRE KEYBLOCK\n"
2282   "\n"
2283   "The client shall respond with a binary version of the keyblock (e.g.,\n"
2284   "the output of `gpg --export KEYID').  For LDAP\n"
2285   "keyservers Dirmngr may ask for meta information of the provided keyblock\n"
2286   "using:\n"
2287   "\n"
2288   "  INQUIRE KEYBLOCK_INFO\n"
2289   "\n"
2290   "The client shall respond with a colon delimited info lines (the output\n"
2291   "of 'for x in keys sigs; do gpg --list-$x --with-colons KEYID; done').\n";
2292 static gpg_error_t
2293 cmd_ks_put (assuan_context_t ctx, char *line)
2294 {
2295   ctrl_t ctrl = assuan_get_pointer (ctx);
2296   gpg_error_t err;
2297   unsigned char *value = NULL;
2298   size_t valuelen;
2299   unsigned char *info = NULL;
2300   size_t infolen;
2301
2302   /* No options for now.  */
2303   line = skip_options (line);
2304
2305   err = ensure_keyserver (ctrl);
2306   if (err)
2307     goto leave;
2308
2309   /* Ask for the key material.  */
2310   err = assuan_inquire (ctx, "KEYBLOCK",
2311                         &value, &valuelen, MAX_KEYBLOCK_LENGTH);
2312   if (err)
2313     {
2314       log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
2315       goto leave;
2316     }
2317
2318   if (!valuelen) /* No data returned; return a comprehensible error. */
2319     {
2320       err = gpg_error (GPG_ERR_MISSING_CERT);
2321       goto leave;
2322     }
2323
2324   /* Ask for the key meta data. Not actually needed for HKP servers
2325      but we do it anyway to test the client implementaion.  */
2326   err = assuan_inquire (ctx, "KEYBLOCK_INFO",
2327                         &info, &infolen, MAX_KEYBLOCK_LENGTH);
2328   if (err)
2329     {
2330       log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
2331       goto leave;
2332     }
2333
2334   /* Send the key.  */
2335   err = ks_action_put (ctrl, ctrl->server_local->keyservers,
2336                        value, valuelen, info, infolen);
2337
2338  leave:
2339   xfree (info);
2340   xfree (value);
2341   return leave_cmd (ctx, err);
2342 }
2343
2344
2345 \f
2346 static const char hlp_loadswdb[] =
2347   "LOADSWDB [--force]\n"
2348   "\n"
2349   "Load and verify the swdb.lst from the Net.";
2350 static gpg_error_t
2351 cmd_loadswdb (assuan_context_t ctx, char *line)
2352 {
2353   ctrl_t ctrl = assuan_get_pointer (ctx);
2354   gpg_error_t err;
2355
2356   err = dirmngr_load_swdb (ctrl, has_option (line, "--force"));
2357
2358   return leave_cmd (ctx, err);
2359 }
2360
2361
2362 \f
2363 static const char hlp_getinfo[] =
2364   "GETINFO <what>\n"
2365   "\n"
2366   "Multi purpose command to return certain information.  \n"
2367   "Supported values of WHAT are:\n"
2368   "\n"
2369   "version     - Return the version of the program.\n"
2370   "pid         - Return the process id of the server.\n"
2371   "tor         - Return OK if running in Tor mode\n"
2372   "dnsinfo     - Return info about the DNS resolver\n"
2373   "socket_name - Return the name of the socket.\n";
2374 static gpg_error_t
2375 cmd_getinfo (assuan_context_t ctx, char *line)
2376 {
2377   ctrl_t ctrl = assuan_get_pointer (ctx);
2378   gpg_error_t err;
2379
2380   if (!strcmp (line, "version"))
2381     {
2382       const char *s = VERSION;
2383       err = assuan_send_data (ctx, s, strlen (s));
2384     }
2385   else if (!strcmp (line, "pid"))
2386     {
2387       char numbuf[50];
2388
2389       snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
2390       err = assuan_send_data (ctx, numbuf, strlen (numbuf));
2391     }
2392   else if (!strcmp (line, "socket_name"))
2393     {
2394       const char *s = dirmngr_get_current_socket_name ();
2395       err = assuan_send_data (ctx, s, strlen (s));
2396     }
2397   else if (!strcmp (line, "tor"))
2398     {
2399       int use_tor;
2400
2401       use_tor = dirmngr_use_tor ();
2402       if (use_tor)
2403         {
2404           if (!is_tor_running (ctrl))
2405             err = assuan_write_status (ctx, "NO_TOR", "Tor not running");
2406           else
2407             err = 0;
2408           if (!err)
2409             assuan_set_okay_line (ctx, use_tor == 1 ? "- Tor mode is enabled"
2410                                   /**/              : "- Tor mode is enforced");
2411         }
2412       else
2413         err = set_error (GPG_ERR_FALSE, "Tor mode is NOT enabled");
2414     }
2415   else if (!strcmp (line, "dnsinfo"))
2416     {
2417       if (standard_resolver_p ())
2418         assuan_set_okay_line
2419           (ctx, "- Forced use of System resolver (w/o Tor support)");
2420       else
2421         {
2422 #ifdef USE_LIBDNS
2423           assuan_set_okay_line (ctx, (recursive_resolver_p ()
2424                                       ? "- Libdns recursive resolver"
2425                                       : "- Libdns stub resolver"));
2426 #else
2427           assuan_set_okay_line (ctx, "- System resolver (w/o Tor support)");
2428 #endif
2429         }
2430       err = 0;
2431     }
2432   else
2433     err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
2434
2435   return leave_cmd (ctx, err);
2436 }
2437
2438
2439 \f
2440 static const char hlp_killdirmngr[] =
2441   "KILLDIRMNGR\n"
2442   "\n"
2443   "This command allows a user - given sufficient permissions -\n"
2444   "to kill this dirmngr process.\n";
2445 static gpg_error_t
2446 cmd_killdirmngr (assuan_context_t ctx, char *line)
2447 {
2448   ctrl_t ctrl = assuan_get_pointer (ctx);
2449
2450   (void)line;
2451
2452   ctrl->server_local->stopme = 1;
2453   assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
2454   return gpg_error (GPG_ERR_EOF);
2455 }
2456
2457
2458 static const char hlp_reloaddirmngr[] =
2459   "RELOADDIRMNGR\n"
2460   "\n"
2461   "This command is an alternative to SIGHUP\n"
2462   "to reload the configuration.";
2463 static gpg_error_t
2464 cmd_reloaddirmngr (assuan_context_t ctx, char *line)
2465 {
2466   (void)ctx;
2467   (void)line;
2468
2469   dirmngr_sighup_action ();
2470   return 0;
2471 }
2472
2473
2474 \f
2475 /* Tell the assuan library about our commands. */
2476 static int
2477 register_commands (assuan_context_t ctx)
2478 {
2479   static struct {
2480     const char *name;
2481     assuan_handler_t handler;
2482     const char * const help;
2483   } table[] = {
2484     { "DNS_CERT",   cmd_dns_cert,   hlp_dns_cert },
2485     { "WKD_GET",    cmd_wkd_get,    hlp_wkd_get },
2486     { "LDAPSERVER", cmd_ldapserver, hlp_ldapserver },
2487     { "ISVALID",    cmd_isvalid,    hlp_isvalid },
2488     { "CHECKCRL",   cmd_checkcrl,   hlp_checkcrl },
2489     { "CHECKOCSP",  cmd_checkocsp,  hlp_checkocsp },
2490     { "LOOKUP",     cmd_lookup,     hlp_lookup },
2491     { "LOADCRL",    cmd_loadcrl,    hlp_loadcrl },
2492     { "LISTCRLS",   cmd_listcrls,   hlp_listcrls },
2493     { "CACHECERT",  cmd_cachecert,  hlp_cachecert },
2494     { "VALIDATE",   cmd_validate,   hlp_validate },
2495     { "KEYSERVER",  cmd_keyserver,  hlp_keyserver },
2496     { "KS_SEARCH",  cmd_ks_search,  hlp_ks_search },
2497     { "KS_GET",     cmd_ks_get,     hlp_ks_get },
2498     { "KS_FETCH",   cmd_ks_fetch,   hlp_ks_fetch },
2499     { "KS_PUT",     cmd_ks_put,     hlp_ks_put },
2500     { "GETINFO",    cmd_getinfo,    hlp_getinfo },
2501     { "LOADSWDB",   cmd_loadswdb,   hlp_loadswdb },
2502     { "KILLDIRMNGR",cmd_killdirmngr,hlp_killdirmngr },
2503     { "RELOADDIRMNGR",cmd_reloaddirmngr,hlp_reloaddirmngr },
2504     { NULL, NULL }
2505   };
2506   int i, j, rc;
2507
2508   for (i=j=0; table[i].name; i++)
2509     {
2510       rc = assuan_register_command (ctx, table[i].name, table[i].handler,
2511                                     table[i].help);
2512       if (rc)
2513         return rc;
2514     }
2515   return 0;
2516 }
2517
2518
2519 /* Note that we do not reset the list of configured keyservers.  */
2520 static gpg_error_t
2521 reset_notify (assuan_context_t ctx, char *line)
2522 {
2523   ctrl_t ctrl = assuan_get_pointer (ctx);
2524   (void)line;
2525
2526 #if USE_LDAP
2527   ldapserver_list_free (ctrl->server_local->ldapservers);
2528 #endif /*USE_LDAP*/
2529   ctrl->server_local->ldapservers = NULL;
2530   return 0;
2531 }
2532
2533
2534 /* This function is called by our assuan log handler to test whether a
2535  * log message shall really be printed.  The function must return
2536  * false to inhibit the logging of MSG.  CAT gives the requested log
2537  * category.  MSG might be NULL. */
2538 int
2539 dirmngr_assuan_log_monitor (assuan_context_t ctx, unsigned int cat,
2540                             const char *msg)
2541 {
2542   ctrl_t ctrl = assuan_get_pointer (ctx);
2543
2544   (void)cat;
2545   (void)msg;
2546
2547   if (!ctrl || !ctrl->server_local)
2548     return 1; /* Can't decide - allow logging.  */
2549
2550   if (!ctrl->server_local->inhibit_data_logging)
2551     return 1; /* Not requested - allow logging.  */
2552
2553   /* Disallow logging if *_now is true.  */
2554   return !ctrl->server_local->inhibit_data_logging_now;
2555 }
2556
2557
2558 /* Startup the server and run the main command loop.  With FD = -1,
2559    use stdin/stdout. */
2560 void
2561 start_command_handler (assuan_fd_t fd)
2562 {
2563   static const char hello[] = "Dirmngr " VERSION " at your service";
2564   static char *hello_line;
2565   int rc;
2566   assuan_context_t ctx;
2567   ctrl_t ctrl;
2568
2569   ctrl = xtrycalloc (1, sizeof *ctrl);
2570   if (ctrl)
2571     ctrl->server_local = xtrycalloc (1, sizeof *ctrl->server_local);
2572   if (!ctrl || !ctrl->server_local)
2573     {
2574       log_error (_("can't allocate control structure: %s\n"),
2575                  strerror (errno));
2576       xfree (ctrl);
2577       return;
2578     }
2579
2580   dirmngr_init_default_ctrl (ctrl);
2581
2582   rc = assuan_new (&ctx);
2583   if (rc)
2584     {
2585       log_error (_("failed to allocate assuan context: %s\n"),
2586                  gpg_strerror (rc));
2587       dirmngr_exit (2);
2588     }
2589
2590   if (fd == ASSUAN_INVALID_FD)
2591     {
2592       assuan_fd_t filedes[2];
2593
2594       filedes[0] = assuan_fdopen (0);
2595       filedes[1] = assuan_fdopen (1);
2596       rc = assuan_init_pipe_server (ctx, filedes);
2597     }
2598   else
2599     {
2600       rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED);
2601     }
2602
2603   if (rc)
2604     {
2605       assuan_release (ctx);
2606       log_error (_("failed to initialize the server: %s\n"),
2607                  gpg_strerror(rc));
2608       dirmngr_exit (2);
2609     }
2610
2611   rc = register_commands (ctx);
2612   if (rc)
2613     {
2614       log_error (_("failed to the register commands with Assuan: %s\n"),
2615                  gpg_strerror(rc));
2616       dirmngr_exit (2);
2617     }
2618
2619
2620   if (!hello_line)
2621     {
2622       hello_line = xtryasprintf
2623         ("Home: %s\n"
2624          "Config: %s\n"
2625          "%s",
2626          gnupg_homedir (),
2627          opt.config_filename? opt.config_filename : "[none]",
2628          hello);
2629     }
2630
2631   ctrl->server_local->assuan_ctx = ctx;
2632   assuan_set_pointer (ctx, ctrl);
2633
2634   assuan_set_hello_line (ctx, hello_line);
2635   assuan_register_option_handler (ctx, option_handler);
2636   assuan_register_reset_notify (ctx, reset_notify);
2637
2638   for (;;)
2639     {
2640       rc = assuan_accept (ctx);
2641       if (rc == -1)
2642         break;
2643       if (rc)
2644         {
2645           log_info (_("Assuan accept problem: %s\n"), gpg_strerror (rc));
2646           break;
2647         }
2648
2649 #ifndef HAVE_W32_SYSTEM
2650       if (opt.verbose)
2651         {
2652           assuan_peercred_t peercred;
2653
2654           if (!assuan_get_peercred (ctx, &peercred))
2655             log_info ("connection from process %ld (%ld:%ld)\n",
2656                       (long)peercred->pid, (long)peercred->uid,
2657                       (long)peercred->gid);
2658         }
2659 #endif
2660
2661       rc = assuan_process (ctx);
2662       if (rc)
2663         {
2664           log_info (_("Assuan processing failed: %s\n"), gpg_strerror (rc));
2665           continue;
2666         }
2667     }
2668
2669
2670 #if USE_LDAP
2671   ldap_wrapper_connection_cleanup (ctrl);
2672
2673   ldapserver_list_free (ctrl->server_local->ldapservers);
2674 #endif /*USE_LDAP*/
2675   ctrl->server_local->ldapservers = NULL;
2676
2677   release_ctrl_keyservers (ctrl);
2678
2679   ctrl->server_local->assuan_ctx = NULL;
2680   assuan_release (ctx);
2681
2682   if (ctrl->server_local->stopme)
2683     dirmngr_exit (0);
2684
2685   if (ctrl->refcount)
2686     log_error ("oops: connection control structure still referenced (%d)\n",
2687                ctrl->refcount);
2688   else
2689     {
2690       release_ctrl_ocsp_certs (ctrl);
2691       xfree (ctrl->server_local);
2692       dirmngr_deinit_default_ctrl (ctrl);
2693       xfree (ctrl);
2694     }
2695 }
2696
2697
2698 /* Send a status line back to the client.  KEYWORD is the status
2699    keyword, the optional string arguments are blank separated added to
2700    the line, the last argument must be a NULL. */
2701 gpg_error_t
2702 dirmngr_status (ctrl_t ctrl, const char *keyword, ...)
2703 {
2704   gpg_error_t err = 0;
2705   va_list arg_ptr;
2706   const char *text;
2707
2708   va_start (arg_ptr, keyword);
2709
2710   if (ctrl->server_local)
2711     {
2712       assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2713       char buf[950], *p;
2714       size_t n;
2715
2716       p = buf;
2717       n = 0;
2718       while ( (text = va_arg (arg_ptr, const char *)) )
2719         {
2720           if (n)
2721             {
2722               *p++ = ' ';
2723               n++;
2724             }
2725           for ( ; *text && n < DIM (buf)-2; n++)
2726             *p++ = *text++;
2727         }
2728       *p = 0;
2729       err = assuan_write_status (ctx, keyword, buf);
2730     }
2731
2732   va_end (arg_ptr);
2733   return err;
2734 }
2735
2736
2737 /* Print a help status line.  TEXTLEN gives the length of the text
2738    from TEXT to be printed.  The function splits text at LFs.  */
2739 gpg_error_t
2740 dirmngr_status_help (ctrl_t ctrl, const char *text)
2741 {
2742   gpg_error_t err = 0;
2743
2744   if (ctrl->server_local)
2745     {
2746       assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2747       char buf[950], *p;
2748       size_t n;
2749
2750       do
2751         {
2752           p = buf;
2753           n = 0;
2754           for ( ; *text && *text != '\n' && n < DIM (buf)-2; n++)
2755             *p++ = *text++;
2756           if (*text == '\n')
2757             text++;
2758           *p = 0;
2759           err = assuan_write_status (ctx, "#", buf);
2760         }
2761       while (!err && *text);
2762     }
2763
2764   return err;
2765 }
2766
2767 /* Send a tick progress indicator back.  Fixme: This is only done for
2768    the currently active channel.  */
2769 gpg_error_t
2770 dirmngr_tick (ctrl_t ctrl)
2771 {
2772   static time_t next_tick = 0;
2773   gpg_error_t err = 0;
2774   time_t now = time (NULL);
2775
2776   if (!next_tick)
2777     {
2778       next_tick = now + 1;
2779     }
2780   else if ( now > next_tick )
2781     {
2782       if (ctrl)
2783         {
2784           err = dirmngr_status (ctrl, "PROGRESS", "tick", "? 0 0", NULL);
2785           if (err)
2786             {
2787               /* Take this as in indication for a cancel request.  */
2788               err = gpg_error (GPG_ERR_CANCELED);
2789             }
2790           now = time (NULL);
2791         }
2792
2793       next_tick = now + 1;
2794     }
2795   return err;
2796 }