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