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