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