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