dirmngr: Make sure Tor mode is also set for DNS on SIGHUP.
[gnupg.git] / dirmngr / server.c
1 /* server.c - LDAP and Keyserver access server
2  * Copyright (C) 2002 Klarälvdalens Datakonsult AB
3  * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2011, 2015 g10 Code GmbH
4  * Copyright (C) 2014, 2015, 2016 Werner Koch
5  *
6  * This file is part of GnuPG.
7  *
8  * GnuPG is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * GnuPG is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, see <https://www.gnu.org/licenses/>.
20  */
21
22 #include <config.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <stddef.h>
26 #include <string.h>
27 #include <assert.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <unistd.h>
31 #include <errno.h>
32
33 #include "dirmngr.h"
34 #include <assuan.h>
35
36 #include "crlcache.h"
37 #include "crlfetch.h"
38 #if USE_LDAP
39 # include "ldapserver.h"
40 #endif
41 #include "ocsp.h"
42 #include "certcache.h"
43 #include "validate.h"
44 #include "misc.h"
45 #if USE_LDAP
46 # include "ldap-wrapper.h"
47 #endif
48 #include "ks-action.h"
49 #include "ks-engine.h"  /* (ks_hkp_print_hosttable) */
50 #if USE_LDAP
51 # include "ldap-parse-uri.h"
52 #endif
53 #include "dns-stuff.h"
54 #include "mbox-util.h"
55 #include "zb32.h"
56 #include "server-help.h"
57
58 /* To avoid DoS attacks we limit the size of a certificate to
59    something reasonable.  The DoS was actually only an issue back when
60    Dirmngr was a system service and not a user service. */
61 #define MAX_CERT_LENGTH (16*1024)
62
63 /* The 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 connection.  */
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 (pka_mode || dane_mode)
713     {
714       char *domain;     /* Points to mbox.  */
715       char hashbuf[32]; /* For SHA-1 and SHA-256. */
716
717       /* We lowercase ascii characters but the DANE I-D does not allow
718          this.  FIXME: Check after the release of the RFC whether to
719          change this.  */
720       mbox = mailbox_from_userid (line);
721       if (!mbox || !(domain = strchr (mbox, '@')))
722         {
723           err = set_error (GPG_ERR_INV_USER_ID, "no mailbox in user id");
724           goto leave;
725         }
726       *domain++ = 0;
727
728       if (pka_mode)
729         {
730           gcry_md_hash_buffer (GCRY_MD_SHA1, hashbuf, mbox, strlen (mbox));
731           encodedhash = zb32_encode (hashbuf, 8*20);
732           if (!encodedhash)
733             {
734               err = gpg_error_from_syserror ();
735               goto leave;
736             }
737           namebuf = strconcat (encodedhash, "._pka.", domain, NULL);
738           if (!namebuf)
739             {
740               err = gpg_error_from_syserror ();
741               goto leave;
742             }
743           name = namebuf;
744           certtype = DNS_CERTTYPE_IPGP;
745         }
746       else
747         {
748           /* Note: The hash is truncated to 28 bytes and we lowercase
749              the result only for aesthetic reasons.  */
750           gcry_md_hash_buffer (GCRY_MD_SHA256, hashbuf, mbox, strlen (mbox));
751           encodedhash = bin2hex (hashbuf, 28, NULL);
752           if (!encodedhash)
753             {
754               err = gpg_error_from_syserror ();
755               goto leave;
756             }
757           ascii_strlwr (encodedhash);
758           namebuf = strconcat (encodedhash, "._openpgpkey.", domain, NULL);
759           if (!namebuf)
760             {
761               err = gpg_error_from_syserror ();
762               goto leave;
763             }
764           name = namebuf;
765           certtype = DNS_CERTTYPE_RR61;
766         }
767     }
768   else
769     name = line;
770
771   err = get_dns_cert (name, certtype, &key, &keylen, &fpr, &fprlen, &url);
772   if (err)
773     goto leave;
774
775   if (key)
776     {
777       err = data_line_write (ctx, key, keylen);
778       if (err)
779         goto leave;
780     }
781
782   if (fpr)
783     {
784       char *tmpstr;
785
786       tmpstr = bin2hex (fpr, fprlen, NULL);
787       if (!tmpstr)
788         err = gpg_error_from_syserror ();
789       else
790         {
791           err = assuan_write_status (ctx, "FPR", tmpstr);
792           xfree (tmpstr);
793         }
794       if (err)
795         goto leave;
796     }
797
798   if (url)
799     {
800       err = assuan_write_status (ctx, "URL", url);
801       if (err)
802         goto leave;
803     }
804
805
806  leave:
807   xfree (key);
808   xfree (fpr);
809   xfree (url);
810   xfree (mbox);
811   xfree (namebuf);
812   xfree (encodedhash);
813   return leave_cmd (ctx, err);
814 }
815
816
817 \f
818 static const char hlp_wkd_get[] =
819   "WKD_GET [--submission-address|--policy-flags] <user_id>\n"
820   "\n"
821   "Return the key or other info for <user_id>\n"
822   "from the Web Key Directory.";
823 static gpg_error_t
824 cmd_wkd_get (assuan_context_t ctx, char *line)
825 {
826   ctrl_t ctrl = assuan_get_pointer (ctx);
827   gpg_error_t err = 0;
828   char *mbox = NULL;
829   char *domain;     /* Points to mbox.  */
830   char sha1buf[20];
831   char *uri = NULL;
832   char *encodedhash = NULL;
833   int opt_submission_addr;
834   int opt_policy_flags;
835   int no_log = 0;
836
837   opt_submission_addr = has_option (line, "--submission-address");
838   opt_policy_flags = has_option (line, "--policy-flags");
839   line = skip_options (line);
840
841   mbox = mailbox_from_userid (line);
842   if (!mbox || !(domain = strchr (mbox, '@')))
843     {
844       err = set_error (GPG_ERR_INV_USER_ID, "no mailbox in user id");
845       goto leave;
846     }
847   *domain++ = 0;
848
849   gcry_md_hash_buffer (GCRY_MD_SHA1, sha1buf, mbox, strlen (mbox));
850   encodedhash = zb32_encode (sha1buf, 8*20);
851   if (!encodedhash)
852     {
853       err = gpg_error_from_syserror ();
854       goto leave;
855     }
856
857   if (opt_submission_addr)
858     {
859       uri = strconcat ("https://",
860                        domain,
861                        "/.well-known/openpgpkey/submission-address",
862                        NULL);
863     }
864   else if (opt_policy_flags)
865     {
866       uri = strconcat ("https://",
867                        domain,
868                        "/.well-known/openpgpkey/policy",
869                        NULL);
870     }
871   else
872     {
873       uri = strconcat ("https://",
874                        domain,
875                        "/.well-known/openpgpkey/hu/",
876                        encodedhash,
877                        NULL);
878       no_log = 1;
879     }
880   if (!uri)
881     {
882       err = gpg_error_from_syserror ();
883       goto leave;
884     }
885
886   /* Setup an output stream and perform the get.  */
887   {
888     estream_t outfp;
889
890     outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
891     if (!outfp)
892       err = set_error (GPG_ERR_ASS_GENERAL,
893                        "error setting up a data stream");
894     else
895       {
896         if (no_log)
897           ctrl->server_local->inhibit_data_logging = 1;
898         ctrl->server_local->inhibit_data_logging_now = 0;
899         ctrl->server_local->inhibit_data_logging_count = 0;
900         err = ks_action_fetch (ctrl, uri, outfp);
901         es_fclose (outfp);
902         ctrl->server_local->inhibit_data_logging = 0;
903       }
904   }
905
906  leave:
907   xfree (uri);
908   xfree (encodedhash);
909   xfree (mbox);
910   return leave_cmd (ctx, err);
911 }
912
913
914 \f
915 static const char hlp_ldapserver[] =
916   "LDAPSERVER <data>\n"
917   "\n"
918   "Add a new LDAP server to the list of configured LDAP servers.\n"
919   "DATA is in the same format as expected in the configure file.";
920 static gpg_error_t
921 cmd_ldapserver (assuan_context_t ctx, char *line)
922 {
923 #if USE_LDAP
924   ctrl_t ctrl = assuan_get_pointer (ctx);
925   ldap_server_t server;
926   ldap_server_t *last_next_p;
927
928   while (spacep (line))
929     line++;
930   if (*line == '\0')
931     return leave_cmd (ctx, PARM_ERROR (_("ldapserver missing")));
932
933   server = ldapserver_parse_one (line, "", 0);
934   if (! server)
935     return leave_cmd (ctx, gpg_error (GPG_ERR_INV_ARG));
936
937   last_next_p = &ctrl->server_local->ldapservers;
938   while (*last_next_p)
939     last_next_p = &(*last_next_p)->next;
940   *last_next_p = server;
941   return leave_cmd (ctx, 0);
942 #else
943   (void)line;
944   return leave_cmd (ctx, gpg_error (GPG_ERR_NOT_IMPLEMENTED));
945 #endif
946 }
947
948
949 static const char hlp_isvalid[] =
950   "ISVALID [--only-ocsp] [--force-default-responder]"
951   " <certificate_id>|<certificate_fpr>\n"
952   "\n"
953   "This command checks whether the certificate identified by the\n"
954   "certificate_id is valid.  This is done by consulting CRLs or\n"
955   "whatever has been configured.  Note, that the returned error codes\n"
956   "are from gpg-error.h.  The command may callback using the inquire\n"
957   "function.  See the manual for details.\n"
958   "\n"
959   "The CERTIFICATE_ID is a hex encoded string consisting of two parts,\n"
960   "delimited by a single dot.  The first part is the SHA-1 hash of the\n"
961   "issuer name and the second part the serial number.\n"
962   "\n"
963   "Alternatively the certificate's fingerprint may be given in which\n"
964   "case an OCSP request is done before consulting the CRL.\n"
965   "\n"
966   "If the option --only-ocsp is given, no fallback to a CRL check will\n"
967   "be used.\n"
968   "\n"
969   "If the option --force-default-responder is given, only the default\n"
970   "OCSP responder will be used and any other methods of obtaining an\n"
971   "OCSP responder URL won't be used.";
972 static gpg_error_t
973 cmd_isvalid (assuan_context_t ctx, char *line)
974 {
975   ctrl_t ctrl = assuan_get_pointer (ctx);
976   char *issuerhash, *serialno;
977   gpg_error_t err;
978   int did_inquire = 0;
979   int ocsp_mode = 0;
980   int only_ocsp;
981   int force_default_responder;
982
983   only_ocsp = has_option (line, "--only-ocsp");
984   force_default_responder = has_option (line, "--force-default-responder");
985   line = skip_options (line);
986
987   issuerhash = xstrdup (line); /* We need to work on a copy of the
988                                   line because that same Assuan
989                                   context may be used for an inquiry.
990                                   That is because Assuan reuses its
991                                   line buffer.
992                                    */
993
994   serialno = strchr (issuerhash, '.');
995   if (serialno)
996     *serialno++ = 0;
997   else
998     {
999       char *endp = strchr (issuerhash, ' ');
1000       if (endp)
1001         *endp = 0;
1002       if (strlen (issuerhash) != 40)
1003         {
1004           xfree (issuerhash);
1005           return leave_cmd (ctx, PARM_ERROR (_("serialno missing in cert ID")));
1006         }
1007       ocsp_mode = 1;
1008     }
1009
1010
1011  again:
1012   if (ocsp_mode)
1013     {
1014       /* Note, that we ignore the given issuer hash and instead rely
1015          on the current certificate semantics used with this
1016          command. */
1017       if (!opt.allow_ocsp)
1018         err = gpg_error (GPG_ERR_NOT_SUPPORTED);
1019       else
1020         err = ocsp_isvalid (ctrl, NULL, NULL, force_default_responder);
1021       /* Fixme: If we got no ocsp response and --only-ocsp is not used
1022          we should fall back to CRL mode.  Thus we need to clear
1023          OCSP_MODE, get the issuerhash and the serialno from the
1024          current certificate and jump to again. */
1025     }
1026   else if (only_ocsp)
1027     err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
1028   else
1029     {
1030       switch (crl_cache_isvalid (ctrl,
1031                                  issuerhash, serialno,
1032                                  ctrl->force_crl_refresh))
1033         {
1034         case CRL_CACHE_VALID:
1035           err = 0;
1036           break;
1037         case CRL_CACHE_INVALID:
1038           err = gpg_error (GPG_ERR_CERT_REVOKED);
1039           break;
1040         case CRL_CACHE_DONTKNOW:
1041           if (did_inquire)
1042             err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
1043           else if (!(err = inquire_cert_and_load_crl (ctx)))
1044             {
1045               did_inquire = 1;
1046               goto again;
1047             }
1048           break;
1049         case CRL_CACHE_CANTUSE:
1050           err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
1051           break;
1052         default:
1053           log_fatal ("crl_cache_isvalid returned invalid code\n");
1054         }
1055     }
1056
1057   xfree (issuerhash);
1058   return leave_cmd (ctx, err);
1059 }
1060
1061
1062 /* If the line contains a SHA-1 fingerprint as the first argument,
1063    return the FPR vuffer on success.  The function checks that the
1064    fingerprint consists of valid characters and prints and error
1065    message if it does not and returns NULL.  Fingerprints are
1066    considered optional and thus no explicit error is returned. NULL is
1067    also returned if there is no fingerprint at all available.
1068    FPR must be a caller provided buffer of at least 20 bytes.
1069
1070    Note that colons within the fingerprint are allowed to separate 2
1071    hex digits; this allows for easier cutting and pasting using the
1072    usual fingerprint rendering.
1073 */
1074 static unsigned char *
1075 get_fingerprint_from_line (const char *line, unsigned char *fpr)
1076 {
1077   const char *s;
1078   int i;
1079
1080   for (s=line, i=0; *s && *s != ' '; s++ )
1081     {
1082       if ( hexdigitp (s) && hexdigitp (s+1) )
1083         {
1084           if ( i >= 20 )
1085             return NULL;  /* Fingerprint too long.  */
1086           fpr[i++] = xtoi_2 (s);
1087           s++;
1088         }
1089       else if ( *s != ':' )
1090         return NULL; /* Invalid.  */
1091     }
1092   if ( i != 20 )
1093     return NULL; /* Fingerprint to short.  */
1094   return fpr;
1095 }
1096
1097
1098
1099 static const char hlp_checkcrl[] =
1100   "CHECKCRL [<fingerprint>]\n"
1101   "\n"
1102   "Check whether the certificate with FINGERPRINT (SHA-1 hash of the\n"
1103   "entire X.509 certificate blob) is valid or not by consulting the\n"
1104   "CRL responsible for this certificate.  If the fingerprint has not\n"
1105   "been given or the certificate is not known, the function \n"
1106   "inquires the certificate using an\n"
1107   "\n"
1108   "  INQUIRE TARGETCERT\n"
1109   "\n"
1110   "and the caller is expected to return the certificate for the\n"
1111   "request (which should match FINGERPRINT) as a binary blob.\n"
1112   "Processing then takes place without further interaction; in\n"
1113   "particular dirmngr tries to locate other required certificate by\n"
1114   "its own mechanism which includes a local certificate store as well\n"
1115   "as a list of trusted root certificates.\n"
1116   "\n"
1117   "The return value is the usual gpg-error code or 0 for ducesss;\n"
1118   "i.e. the certificate validity has been confirmed by a valid CRL.";
1119 static gpg_error_t
1120 cmd_checkcrl (assuan_context_t ctx, char *line)
1121 {
1122   ctrl_t ctrl = assuan_get_pointer (ctx);
1123   gpg_error_t err;
1124   unsigned char fprbuffer[20], *fpr;
1125   ksba_cert_t cert;
1126
1127   fpr = get_fingerprint_from_line (line, fprbuffer);
1128   cert = fpr? get_cert_byfpr (fpr) : NULL;
1129
1130   if (!cert)
1131     {
1132       /* We do not have this certificate yet or the fingerprint has
1133          not been given.  Inquire it from the client.  */
1134       unsigned char *value = NULL;
1135       size_t valuelen;
1136
1137       err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1138                            &value, &valuelen, MAX_CERT_LENGTH);
1139       if (err)
1140         {
1141           log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1142           goto leave;
1143         }
1144
1145       if (!valuelen) /* No data returned; return a comprehensible error. */
1146         err = gpg_error (GPG_ERR_MISSING_CERT);
1147       else
1148         {
1149           err = ksba_cert_new (&cert);
1150           if (!err)
1151             err = ksba_cert_init_from_mem (cert, value, valuelen);
1152         }
1153       xfree (value);
1154       if(err)
1155         goto leave;
1156     }
1157
1158   assert (cert);
1159
1160   err = crl_cache_cert_isvalid (ctrl, cert, ctrl->force_crl_refresh);
1161   if (gpg_err_code (err) == GPG_ERR_NO_CRL_KNOWN)
1162     {
1163       err = crl_cache_reload_crl (ctrl, cert);
1164       if (!err)
1165         err = crl_cache_cert_isvalid (ctrl, cert, 0);
1166     }
1167
1168  leave:
1169   ksba_cert_release (cert);
1170   return leave_cmd (ctx, err);
1171 }
1172
1173
1174 static const char hlp_checkocsp[] =
1175   "CHECKOCSP [--force-default-responder] [<fingerprint>]\n"
1176   "\n"
1177   "Check whether the certificate with FINGERPRINT (SHA-1 hash of the\n"
1178   "entire X.509 certificate blob) is valid or not by asking an OCSP\n"
1179   "responder responsible for this certificate.  The optional\n"
1180   "fingerprint may be used for a quick check in case an OCSP check has\n"
1181   "been done for this certificate recently (we always cache OCSP\n"
1182   "responses for a couple of minutes). If the fingerprint has not been\n"
1183   "given or there is no cached result, the function inquires the\n"
1184   "certificate using an\n"
1185   "\n"
1186   "   INQUIRE TARGETCERT\n"
1187   "\n"
1188   "and the caller is expected to return the certificate for the\n"
1189   "request (which should match FINGERPRINT) as a binary blob.\n"
1190   "Processing then takes place without further interaction; in\n"
1191   "particular dirmngr tries to locate other required certificates by\n"
1192   "its own mechanism which includes a local certificate store as well\n"
1193   "as a list of trusted root certificates.\n"
1194   "\n"
1195   "If the option --force-default-responder is given, only the default\n"
1196   "OCSP responder will be used and any other methods of obtaining an\n"
1197   "OCSP responder URL won't be used.\n"
1198   "\n"
1199   "The return value is the usual gpg-error code or 0 for ducesss;\n"
1200   "i.e. the certificate validity has been confirmed by a valid CRL.";
1201 static gpg_error_t
1202 cmd_checkocsp (assuan_context_t ctx, char *line)
1203 {
1204   ctrl_t ctrl = assuan_get_pointer (ctx);
1205   gpg_error_t err;
1206   unsigned char fprbuffer[20], *fpr;
1207   ksba_cert_t cert;
1208   int force_default_responder;
1209
1210   force_default_responder = has_option (line, "--force-default-responder");
1211   line = skip_options (line);
1212
1213   fpr = get_fingerprint_from_line (line, fprbuffer);
1214   cert = fpr? get_cert_byfpr (fpr) : NULL;
1215
1216   if (!cert)
1217     {
1218       /* We do not have this certificate yet or the fingerprint has
1219          not been given.  Inquire it from the client.  */
1220       unsigned char *value = NULL;
1221       size_t valuelen;
1222
1223       err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1224                            &value, &valuelen, MAX_CERT_LENGTH);
1225       if (err)
1226         {
1227           log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1228           goto leave;
1229         }
1230
1231       if (!valuelen) /* No data returned; return a comprehensible error. */
1232         err = gpg_error (GPG_ERR_MISSING_CERT);
1233       else
1234         {
1235           err = ksba_cert_new (&cert);
1236           if (!err)
1237             err = ksba_cert_init_from_mem (cert, value, valuelen);
1238         }
1239       xfree (value);
1240       if(err)
1241         goto leave;
1242     }
1243
1244   assert (cert);
1245
1246   if (!opt.allow_ocsp)
1247     err = gpg_error (GPG_ERR_NOT_SUPPORTED);
1248   else
1249     err = ocsp_isvalid (ctrl, cert, NULL, force_default_responder);
1250
1251  leave:
1252   ksba_cert_release (cert);
1253   return leave_cmd (ctx, err);
1254 }
1255
1256
1257
1258 static int
1259 lookup_cert_by_url (assuan_context_t ctx, const char *url)
1260 {
1261   ctrl_t ctrl = assuan_get_pointer (ctx);
1262   gpg_error_t err = 0;
1263   unsigned char *value = NULL;
1264   size_t valuelen;
1265
1266   /* Fetch single certificate given it's URL.  */
1267   err = fetch_cert_by_url (ctrl, url, &value, &valuelen);
1268   if (err)
1269     {
1270       log_error (_("fetch_cert_by_url failed: %s\n"), gpg_strerror (err));
1271       goto leave;
1272     }
1273
1274   /* Send the data, flush the buffer and then send an END. */
1275   err = assuan_send_data (ctx, value, valuelen);
1276   if (!err)
1277     err = assuan_send_data (ctx, NULL, 0);
1278   if (!err)
1279     err = assuan_write_line (ctx, "END");
1280   if (err)
1281     {
1282       log_error (_("error sending data: %s\n"), gpg_strerror (err));
1283       goto leave;
1284     }
1285
1286  leave:
1287
1288   return err;
1289 }
1290
1291
1292 /* Send the certificate, flush the buffer and then send an END. */
1293 static gpg_error_t
1294 return_one_cert (void *opaque, ksba_cert_t cert)
1295 {
1296   assuan_context_t ctx = opaque;
1297   gpg_error_t err;
1298   const unsigned char *der;
1299   size_t derlen;
1300
1301   der = ksba_cert_get_image (cert, &derlen);
1302   if (!der)
1303     err = gpg_error (GPG_ERR_INV_CERT_OBJ);
1304   else
1305     {
1306       err = assuan_send_data (ctx, der, derlen);
1307       if (!err)
1308         err = assuan_send_data (ctx, NULL, 0);
1309       if (!err)
1310         err = assuan_write_line (ctx, "END");
1311     }
1312   if (err)
1313     log_error (_("error sending data: %s\n"), gpg_strerror (err));
1314   return err;
1315 }
1316
1317
1318 /* Lookup certificates from the internal cache or using the ldap
1319    servers. */
1320 static int
1321 lookup_cert_by_pattern (assuan_context_t ctx, char *line,
1322                         int single, int cache_only)
1323 {
1324   gpg_error_t err = 0;
1325   char *p;
1326   strlist_t sl, list = NULL;
1327   int truncated = 0, truncation_forced = 0;
1328   int count = 0;
1329   int local_count = 0;
1330 #if USE_LDAP
1331   ctrl_t ctrl = assuan_get_pointer (ctx);
1332   unsigned char *value = NULL;
1333   size_t valuelen;
1334   struct ldapserver_iter ldapserver_iter;
1335   cert_fetch_context_t fetch_context;
1336 #endif /*USE_LDAP*/
1337   int any_no_data = 0;
1338
1339   /* Break the line down into an STRLIST */
1340   for (p=line; *p; line = p)
1341     {
1342       while (*p && *p != ' ')
1343         p++;
1344       if (*p)
1345         *p++ = 0;
1346
1347       if (*line)
1348         {
1349           sl = xtrymalloc (sizeof *sl + strlen (line));
1350           if (!sl)
1351             {
1352               err = gpg_error_from_errno (errno);
1353               goto leave;
1354             }
1355           memset (sl, 0, sizeof *sl);
1356           strcpy_escaped_plus (sl->d, line);
1357           sl->next = list;
1358           list = sl;
1359         }
1360     }
1361
1362   /* First look through the internal cache.  The certifcates returned
1363      here are not counted towards the truncation limit.  */
1364   if (single && !cache_only)
1365     ; /* Do not read from the local cache in this case.  */
1366   else
1367     {
1368       for (sl=list; sl; sl = sl->next)
1369         {
1370           err = get_certs_bypattern (sl->d, return_one_cert, ctx);
1371           if (!err)
1372             local_count++;
1373           if (!err && single)
1374             goto ready;
1375
1376           if (gpg_err_code (err) == GPG_ERR_NO_DATA)
1377             {
1378               err = 0;
1379               if (cache_only)
1380                 any_no_data = 1;
1381             }
1382           else if (gpg_err_code (err) == GPG_ERR_INV_NAME && !cache_only)
1383             {
1384               /* No real fault because the internal pattern lookup
1385                  can't yet cope with all types of pattern.  */
1386               err = 0;
1387             }
1388           if (err)
1389             goto ready;
1390         }
1391     }
1392
1393   /* Loop over all configured servers unless we want only the
1394      certificates from the cache.  */
1395 #if USE_LDAP
1396   for (ldapserver_iter_begin (&ldapserver_iter, ctrl);
1397        !cache_only && !ldapserver_iter_end_p (&ldapserver_iter)
1398          && ldapserver_iter.server->host && !truncation_forced;
1399        ldapserver_iter_next (&ldapserver_iter))
1400     {
1401       ldap_server_t ldapserver = ldapserver_iter.server;
1402
1403       if (DBG_LOOKUP)
1404         log_debug ("cmd_lookup: trying %s:%d base=%s\n",
1405                    ldapserver->host, ldapserver->port,
1406                    ldapserver->base?ldapserver->base : "[default]");
1407
1408       /* Fetch certificates matching pattern */
1409       err = start_cert_fetch (ctrl, &fetch_context, list, ldapserver);
1410       if ( gpg_err_code (err) == GPG_ERR_NO_DATA )
1411         {
1412           if (DBG_LOOKUP)
1413             log_debug ("cmd_lookup: no data\n");
1414           err = 0;
1415           any_no_data = 1;
1416           continue;
1417         }
1418       if (err)
1419         {
1420           log_error (_("start_cert_fetch failed: %s\n"), gpg_strerror (err));
1421           goto leave;
1422         }
1423
1424       /* Fetch the certificates for this query. */
1425       while (!truncation_forced)
1426         {
1427           xfree (value); value = NULL;
1428           err = fetch_next_cert (fetch_context, &value, &valuelen);
1429           if (gpg_err_code (err) == GPG_ERR_NO_DATA )
1430             {
1431               err = 0;
1432               any_no_data = 1;
1433               break; /* Ready. */
1434             }
1435           if (gpg_err_code (err) == GPG_ERR_TRUNCATED)
1436             {
1437               truncated = 1;
1438               err = 0;
1439               break;  /* Ready.  */
1440             }
1441           if (gpg_err_code (err) == GPG_ERR_EOF)
1442             {
1443               err = 0;
1444               break; /* Ready. */
1445             }
1446           if (!err && !value)
1447             {
1448               err = gpg_error (GPG_ERR_BUG);
1449               goto leave;
1450             }
1451           if (err)
1452             {
1453               log_error (_("fetch_next_cert failed: %s\n"),
1454                          gpg_strerror (err));
1455               end_cert_fetch (fetch_context);
1456               goto leave;
1457             }
1458
1459           if (DBG_LOOKUP)
1460             log_debug ("cmd_lookup: returning one cert%s\n",
1461                        truncated? " (truncated)":"");
1462
1463           /* Send the data, flush the buffer and then send an END line
1464              as a certificate delimiter. */
1465           err = assuan_send_data (ctx, value, valuelen);
1466           if (!err)
1467             err = assuan_send_data (ctx, NULL, 0);
1468           if (!err)
1469             err = assuan_write_line (ctx, "END");
1470           if (err)
1471             {
1472               log_error (_("error sending data: %s\n"), gpg_strerror (err));
1473               end_cert_fetch (fetch_context);
1474               goto leave;
1475             }
1476
1477           if (++count >= opt.max_replies )
1478             {
1479               truncation_forced = 1;
1480               log_info (_("max_replies %d exceeded\n"), opt.max_replies );
1481             }
1482           if (single)
1483             break;
1484         }
1485
1486       end_cert_fetch (fetch_context);
1487     }
1488 #endif /*USE_LDAP*/
1489
1490  ready:
1491   if (truncated || truncation_forced)
1492     {
1493       char str[50];
1494
1495       sprintf (str, "%d", count);
1496       assuan_write_status (ctx, "TRUNCATED", str);
1497     }
1498
1499   if (!err && !count && !local_count && any_no_data)
1500     err = gpg_error (GPG_ERR_NO_DATA);
1501
1502  leave:
1503   free_strlist (list);
1504   return err;
1505 }
1506
1507
1508 static const char hlp_lookup[] =
1509   "LOOKUP [--url] [--single] [--cache-only] <pattern>\n"
1510   "\n"
1511   "Lookup certificates matching PATTERN. With --url the pattern is\n"
1512   "expected to be one URL.\n"
1513   "\n"
1514   "If --url is not given:  To allow for multiple patterns (which are ORed)\n"
1515   "quoting is required: Spaces are translated to \"+\" or \"%20\";\n"
1516   "obviously this requires that the usual escape quoting rules are applied.\n"
1517   "\n"
1518   "If --url is given no special escaping is required because URLs are\n"
1519   "already escaped this way.\n"
1520   "\n"
1521   "If --single is given the first and only the first match will be\n"
1522   "returned.  If --cache-only is _not_ given, no local query will be\n"
1523   "done.\n"
1524   "\n"
1525   "If --cache-only is given no external lookup is done so that only\n"
1526   "certificates from the cache may get returned.";
1527 static gpg_error_t
1528 cmd_lookup (assuan_context_t ctx, char *line)
1529 {
1530   gpg_error_t err;
1531   int lookup_url, single, cache_only;
1532
1533   lookup_url = has_leading_option (line, "--url");
1534   single = has_leading_option (line, "--single");
1535   cache_only = has_leading_option (line, "--cache-only");
1536   line = skip_options (line);
1537
1538   if (lookup_url && cache_only)
1539     err = gpg_error (GPG_ERR_NOT_FOUND);
1540   else if (lookup_url && single)
1541     err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1542   else if (lookup_url)
1543     err = lookup_cert_by_url (ctx, line);
1544   else
1545     err = lookup_cert_by_pattern (ctx, line, single, cache_only);
1546
1547   return leave_cmd (ctx, err);
1548 }
1549
1550
1551 static const char hlp_loadcrl[] =
1552   "LOADCRL [--url] <filename|url>\n"
1553   "\n"
1554   "Load the CRL in the file with name FILENAME into our cache.  Note\n"
1555   "that FILENAME should be given with an absolute path because\n"
1556   "Dirmngrs cwd is not known.  With --url the CRL is directly loaded\n"
1557   "from the given URL.\n"
1558   "\n"
1559   "This command is usually used by gpgsm using the invocation \"gpgsm\n"
1560   "--call-dirmngr loadcrl <filename>\".  A direct invocation of Dirmngr\n"
1561   "is not useful because gpgsm might need to callback gpgsm to ask for\n"
1562   "the CA's certificate.";
1563 static gpg_error_t
1564 cmd_loadcrl (assuan_context_t ctx, char *line)
1565 {
1566   ctrl_t ctrl = assuan_get_pointer (ctx);
1567   gpg_error_t err = 0;
1568   int use_url = has_leading_option (line, "--url");
1569
1570   line = skip_options (line);
1571
1572   if (use_url)
1573     {
1574       ksba_reader_t reader;
1575
1576       err = crl_fetch (ctrl, line, &reader);
1577       if (err)
1578         log_error (_("fetching CRL from '%s' failed: %s\n"),
1579                    line, gpg_strerror (err));
1580       else
1581         {
1582           err = crl_cache_insert (ctrl, line, reader);
1583           if (err)
1584             log_error (_("processing CRL from '%s' failed: %s\n"),
1585                        line, gpg_strerror (err));
1586           crl_close_reader (reader);
1587         }
1588     }
1589   else
1590     {
1591       char *buf;
1592
1593       buf = xtrymalloc (strlen (line)+1);
1594       if (!buf)
1595         err = gpg_error_from_syserror ();
1596       else
1597         {
1598           strcpy_escaped_plus (buf, line);
1599           err = crl_cache_load (ctrl, buf);
1600           xfree (buf);
1601         }
1602     }
1603
1604   return leave_cmd (ctx, err);
1605 }
1606
1607
1608 static const char hlp_listcrls[] =
1609   "LISTCRLS\n"
1610   "\n"
1611   "List the content of all CRLs in a readable format.  This command is\n"
1612   "usually used by gpgsm using the invocation \"gpgsm --call-dirmngr\n"
1613   "listcrls\".  It may also be used directly using \"dirmngr\n"
1614   "--list-crls\".";
1615 static gpg_error_t
1616 cmd_listcrls (assuan_context_t ctx, char *line)
1617 {
1618   gpg_error_t err;
1619   estream_t fp;
1620
1621   (void)line;
1622
1623   fp = es_fopencookie (ctx, "w", data_line_cookie_functions);
1624   if (!fp)
1625     err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
1626   else
1627     {
1628       err = crl_cache_list (fp);
1629       es_fclose (fp);
1630     }
1631   return leave_cmd (ctx, err);
1632 }
1633
1634
1635 static const char hlp_cachecert[] =
1636   "CACHECERT\n"
1637   "\n"
1638   "Put a certificate into the internal cache.  This command might be\n"
1639   "useful if a client knows in advance certificates required for a\n"
1640   "test and wants to make sure they get added to the internal cache.\n"
1641   "It is also helpful for debugging.  To get the actual certificate,\n"
1642   "this command immediately inquires it using\n"
1643   "\n"
1644   "  INQUIRE TARGETCERT\n"
1645   "\n"
1646   "and the caller is expected to return the certificate for the\n"
1647   "request as a binary blob.";
1648 static gpg_error_t
1649 cmd_cachecert (assuan_context_t ctx, char *line)
1650 {
1651   ctrl_t ctrl = assuan_get_pointer (ctx);
1652   gpg_error_t err;
1653   ksba_cert_t cert = NULL;
1654   unsigned char *value = NULL;
1655   size_t valuelen;
1656
1657   (void)line;
1658
1659   err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1660                        &value, &valuelen, MAX_CERT_LENGTH);
1661   if (err)
1662     {
1663       log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1664       goto leave;
1665     }
1666
1667   if (!valuelen) /* No data returned; return a comprehensible error. */
1668     err = gpg_error (GPG_ERR_MISSING_CERT);
1669   else
1670     {
1671       err = ksba_cert_new (&cert);
1672       if (!err)
1673         err = ksba_cert_init_from_mem (cert, value, valuelen);
1674     }
1675   xfree (value);
1676   if(err)
1677     goto leave;
1678
1679   err = cache_cert (cert);
1680
1681  leave:
1682   ksba_cert_release (cert);
1683   return leave_cmd (ctx, err);
1684 }
1685
1686
1687 static const char hlp_validate[] =
1688   "VALIDATE\n"
1689   "\n"
1690   "Validate a certificate using the certificate validation function\n"
1691   "used internally by dirmngr.  This command is only useful for\n"
1692   "debugging.  To get the actual certificate, this command immediately\n"
1693   "inquires it using\n"
1694   "\n"
1695   "  INQUIRE TARGETCERT\n"
1696   "\n"
1697   "and the caller is expected to return the certificate for the\n"
1698   "request as a binary blob.";
1699 static gpg_error_t
1700 cmd_validate (assuan_context_t ctx, char *line)
1701 {
1702   ctrl_t ctrl = assuan_get_pointer (ctx);
1703   gpg_error_t err;
1704   ksba_cert_t cert = NULL;
1705   unsigned char *value = NULL;
1706   size_t valuelen;
1707
1708   (void)line;
1709
1710   err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1711                        &value, &valuelen, MAX_CERT_LENGTH);
1712   if (err)
1713     {
1714       log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1715       goto leave;
1716     }
1717
1718   if (!valuelen) /* No data returned; return a comprehensible error. */
1719     err = gpg_error (GPG_ERR_MISSING_CERT);
1720   else
1721     {
1722       err = ksba_cert_new (&cert);
1723       if (!err)
1724         err = ksba_cert_init_from_mem (cert, value, valuelen);
1725     }
1726   xfree (value);
1727   if(err)
1728     goto leave;
1729
1730   /* If we have this certificate already in our cache, use the cached
1731      version for validation because this will take care of any cached
1732      results. */
1733   {
1734     unsigned char fpr[20];
1735     ksba_cert_t tmpcert;
1736
1737     cert_compute_fpr (cert, fpr);
1738     tmpcert = get_cert_byfpr (fpr);
1739     if (tmpcert)
1740       {
1741         ksba_cert_release (cert);
1742         cert = tmpcert;
1743       }
1744   }
1745
1746   err = validate_cert_chain (ctrl, cert, NULL, VALIDATE_MODE_CERT, NULL);
1747
1748  leave:
1749   ksba_cert_release (cert);
1750   return leave_cmd (ctx, err);
1751 }
1752
1753
1754 \f
1755 /* Parse an keyserver URI and store it in a new uri item which is
1756    returned at R_ITEM.  On error return an error code.  */
1757 static gpg_error_t
1758 make_keyserver_item (const char *uri, uri_item_t *r_item)
1759 {
1760   gpg_error_t err;
1761   uri_item_t item;
1762
1763   *r_item = NULL;
1764   item = xtrymalloc (sizeof *item + strlen (uri));
1765   if (!item)
1766     return gpg_error_from_syserror ();
1767
1768   item->next = NULL;
1769   item->parsed_uri = NULL;
1770   strcpy (item->uri, uri);
1771
1772 #if USE_LDAP
1773   if (ldap_uri_p (item->uri))
1774     err = ldap_parse_uri (&item->parsed_uri, uri);
1775   else
1776 #endif
1777     {
1778       err = http_parse_uri (&item->parsed_uri, uri, 1);
1779     }
1780
1781   if (err)
1782     xfree (item);
1783   else
1784     *r_item = item;
1785   return err;
1786 }
1787
1788
1789 /* If no keyserver is stored in CTRL but a global keyserver has been
1790    set, put that global keyserver into CTRL.  We need use this
1791    function to help migrate from the old gpg based keyserver
1792    configuration to the new dirmngr based configuration.  */
1793 static gpg_error_t
1794 ensure_keyserver (ctrl_t ctrl)
1795 {
1796   gpg_error_t err;
1797   uri_item_t item;
1798   uri_item_t onion_items = NULL;
1799   uri_item_t plain_items = NULL;
1800   uri_item_t ui;
1801   strlist_t sl;
1802
1803   if (ctrl->server_local->keyservers)
1804     return 0; /* Already set for this session.  */
1805   if (!opt.keyserver)
1806     {
1807       /* No global option set.  Fall back to default:  */
1808       return make_keyserver_item (DIRMNGR_DEFAULT_KEYSERVER,
1809                                   &ctrl->server_local->keyservers);
1810     }
1811
1812   for (sl = opt.keyserver; sl; sl = sl->next)
1813     {
1814       err = make_keyserver_item (sl->d, &item);
1815       if (err)
1816         goto leave;
1817       if (item->parsed_uri->onion)
1818         {
1819           item->next = onion_items;
1820           onion_items = item;
1821         }
1822       else
1823         {
1824           item->next = plain_items;
1825           plain_items = item;
1826         }
1827     }
1828
1829   /* Decide which to use.  Note that the sesssion has no keyservers
1830      yet set. */
1831   if (onion_items && !onion_items->next && plain_items && !plain_items->next)
1832     {
1833       /* If there is just one onion and one plain keyserver given, we take
1834          only one depending on whether Tor is running or not.  */
1835       if (is_tor_running (ctrl))
1836         {
1837           ctrl->server_local->keyservers = onion_items;
1838           onion_items = NULL;
1839         }
1840       else
1841         {
1842           ctrl->server_local->keyservers = plain_items;
1843           plain_items = NULL;
1844         }
1845     }
1846   else if (!is_tor_running (ctrl))
1847     {
1848       /* Tor is not running.  It does not make sense to add Onion
1849          addresses.  */
1850       ctrl->server_local->keyservers = plain_items;
1851       plain_items = NULL;
1852     }
1853   else
1854     {
1855       /* In all other cases add all keyservers.  */
1856       ctrl->server_local->keyservers = onion_items;
1857       onion_items = NULL;
1858       for (ui = ctrl->server_local->keyservers; ui && ui->next; ui = ui->next)
1859         ;
1860       if (ui)
1861         ui->next = plain_items;
1862       else
1863         ctrl->server_local->keyservers = plain_items;
1864       plain_items = NULL;
1865     }
1866
1867  leave:
1868   release_uri_item_list (onion_items);
1869   release_uri_item_list (plain_items);
1870
1871   return err;
1872 }
1873
1874
1875 static const char hlp_keyserver[] =
1876   "KEYSERVER [<options>] [<uri>|<host>]\n"
1877   "Options are:\n"
1878   "  --help\n"
1879   "  --clear      Remove all configured keyservers\n"
1880   "  --resolve    Resolve HKP host names and rotate\n"
1881   "  --hosttable  Print table of known hosts and pools\n"
1882   "  --dead       Mark <host> as dead\n"
1883   "  --alive      Mark <host> as alive\n"
1884   "\n"
1885   "If called without arguments list all configured keyserver URLs.\n"
1886   "If called with an URI add this as keyserver.  Note that keyservers\n"
1887   "are configured on a per-session base.  A default keyserver may already be\n"
1888   "present, thus the \"--clear\" option must be used to get full control.\n"
1889   "If \"--clear\" and an URI are used together the clear command is\n"
1890   "obviously executed first.  A RESET command does not change the list\n"
1891   "of configured keyservers.";
1892 static gpg_error_t
1893 cmd_keyserver (assuan_context_t ctx, char *line)
1894 {
1895   ctrl_t ctrl = assuan_get_pointer (ctx);
1896   gpg_error_t err = 0;
1897   int clear_flag, add_flag, help_flag, host_flag, resolve_flag;
1898   int dead_flag, alive_flag;
1899   uri_item_t item = NULL; /* gcc 4.4.5 is not able to detect that it
1900                              is always initialized.  */
1901
1902   clear_flag = has_option (line, "--clear");
1903   help_flag = has_option (line, "--help");
1904   resolve_flag = has_option (line, "--resolve");
1905   host_flag = has_option (line, "--hosttable");
1906   dead_flag = has_option (line, "--dead");
1907   alive_flag = has_option (line, "--alive");
1908   line = skip_options (line);
1909   add_flag = !!*line;
1910
1911   if (help_flag)
1912     {
1913       err = ks_action_help (ctrl, line);
1914       goto leave;
1915     }
1916
1917   if (resolve_flag)
1918     {
1919       err = ensure_keyserver (ctrl);
1920       if (!err)
1921         err = ks_action_resolve (ctrl, ctrl->server_local->keyservers);
1922       if (err)
1923         goto leave;
1924     }
1925
1926   if (alive_flag && dead_flag)
1927     {
1928       err = set_error (GPG_ERR_ASS_PARAMETER, "no support for zombies");
1929       goto leave;
1930     }
1931   if (dead_flag)
1932     {
1933       err = check_owner_permission (ctx, "no permission to use --dead");
1934       if (err)
1935         goto leave;
1936     }
1937   if (alive_flag || dead_flag)
1938     {
1939       if (!*line)
1940         {
1941           err = set_error (GPG_ERR_ASS_PARAMETER, "name of host missing");
1942           goto leave;
1943         }
1944
1945       err = ks_hkp_mark_host (ctrl, line, alive_flag);
1946       if (err)
1947         goto leave;
1948     }
1949
1950   if (host_flag)
1951     {
1952       err = ks_hkp_print_hosttable (ctrl);
1953       if (err)
1954         goto leave;
1955     }
1956   if (resolve_flag || host_flag || alive_flag || dead_flag)
1957     goto leave;
1958
1959   if (add_flag)
1960     {
1961       err = make_keyserver_item (line, &item);
1962       if (err)
1963         goto leave;
1964     }
1965   if (clear_flag)
1966     release_ctrl_keyservers (ctrl);
1967   if (add_flag)
1968     {
1969       item->next = ctrl->server_local->keyservers;
1970       ctrl->server_local->keyservers = item;
1971     }
1972
1973   if (!add_flag && !clear_flag && !help_flag)
1974     {
1975       /* List configured keyservers.  However, we first add a global
1976          keyserver. */
1977       uri_item_t u;
1978
1979       err = ensure_keyserver (ctrl);
1980       if (err)
1981         {
1982           assuan_set_error (ctx, err,
1983                             "Bad keyserver configuration in dirmngr.conf");
1984           goto leave;
1985         }
1986
1987       for (u=ctrl->server_local->keyservers; u; u = u->next)
1988         dirmngr_status (ctrl, "KEYSERVER", u->uri, NULL);
1989     }
1990   err = 0;
1991
1992  leave:
1993   return leave_cmd (ctx, err);
1994 }
1995
1996
1997 \f
1998 static const char hlp_ks_search[] =
1999   "KS_SEARCH {<pattern>}\n"
2000   "\n"
2001   "Search the configured OpenPGP keyservers (see command KEYSERVER)\n"
2002   "for keys matching PATTERN";
2003 static gpg_error_t
2004 cmd_ks_search (assuan_context_t ctx, char *line)
2005 {
2006   ctrl_t ctrl = assuan_get_pointer (ctx);
2007   gpg_error_t err;
2008   strlist_t list, sl;
2009   char *p;
2010   estream_t outfp;
2011
2012   /* No options for now.  */
2013   line = skip_options (line);
2014
2015   /* Break the line down into an strlist.  Each pattern is
2016      percent-plus escaped. */
2017   list = NULL;
2018   for (p=line; *p; line = p)
2019     {
2020       while (*p && *p != ' ')
2021         p++;
2022       if (*p)
2023         *p++ = 0;
2024       if (*line)
2025         {
2026           sl = xtrymalloc (sizeof *sl + strlen (line));
2027           if (!sl)
2028             {
2029               err = gpg_error_from_syserror ();
2030               goto leave;
2031             }
2032           sl->flags = 0;
2033           strcpy_escaped_plus (sl->d, line);
2034           sl->next = list;
2035           list = sl;
2036         }
2037     }
2038
2039   err = ensure_keyserver (ctrl);
2040   if (err)
2041     goto leave;
2042
2043   /* Setup an output stream and perform the search.  */
2044   outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
2045   if (!outfp)
2046     err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2047   else
2048     {
2049       err = ks_action_search (ctrl, ctrl->server_local->keyservers,
2050                               list, outfp);
2051       es_fclose (outfp);
2052     }
2053
2054  leave:
2055   free_strlist (list);
2056   return leave_cmd (ctx, err);
2057 }
2058
2059
2060 \f
2061 static const char hlp_ks_get[] =
2062   "KS_GET {<pattern>}\n"
2063   "\n"
2064   "Get the keys matching PATTERN from the configured OpenPGP keyservers\n"
2065   "(see command KEYSERVER).  Each pattern should be a keyid, a fingerprint,\n"
2066   "or an exact name indicated by the '=' prefix.";
2067 static gpg_error_t
2068 cmd_ks_get (assuan_context_t ctx, char *line)
2069 {
2070   ctrl_t ctrl = assuan_get_pointer (ctx);
2071   gpg_error_t err;
2072   strlist_t list, sl;
2073   char *p;
2074   estream_t outfp;
2075
2076   /* No options for now.  */
2077   line = skip_options (line);
2078
2079   /* Break the line into a strlist.  Each pattern is by
2080      definition percent-plus escaped.  However we only support keyids
2081      and fingerprints and thus the client has no need to apply the
2082      escaping.  */
2083   list = NULL;
2084   for (p=line; *p; line = p)
2085     {
2086       while (*p && *p != ' ')
2087         p++;
2088       if (*p)
2089         *p++ = 0;
2090       if (*line)
2091         {
2092           sl = xtrymalloc (sizeof *sl + strlen (line));
2093           if (!sl)
2094             {
2095               err = gpg_error_from_syserror ();
2096               goto leave;
2097             }
2098           sl->flags = 0;
2099           strcpy_escaped_plus (sl->d, line);
2100           sl->next = list;
2101           list = sl;
2102         }
2103     }
2104
2105   err = ensure_keyserver (ctrl);
2106   if (err)
2107     goto leave;
2108
2109   /* Setup an output stream and perform the get.  */
2110   outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
2111   if (!outfp)
2112     err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2113   else
2114     {
2115       ctrl->server_local->inhibit_data_logging = 1;
2116       ctrl->server_local->inhibit_data_logging_now = 0;
2117       ctrl->server_local->inhibit_data_logging_count = 0;
2118       err = ks_action_get (ctrl, ctrl->server_local->keyservers, list, outfp);
2119       es_fclose (outfp);
2120       ctrl->server_local->inhibit_data_logging = 0;
2121     }
2122
2123  leave:
2124   free_strlist (list);
2125   return leave_cmd (ctx, err);
2126 }
2127
2128
2129 static const char hlp_ks_fetch[] =
2130   "KS_FETCH <URL>\n"
2131   "\n"
2132   "Get the key(s) from URL.";
2133 static gpg_error_t
2134 cmd_ks_fetch (assuan_context_t ctx, char *line)
2135 {
2136   ctrl_t ctrl = assuan_get_pointer (ctx);
2137   gpg_error_t err;
2138   estream_t outfp;
2139
2140   /* No options for now.  */
2141   line = skip_options (line);
2142
2143   err = ensure_keyserver (ctrl);  /* FIXME: Why do we needs this here?  */
2144   if (err)
2145     goto leave;
2146
2147   /* Setup an output stream and perform the get.  */
2148   outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
2149   if (!outfp)
2150     err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2151   else
2152     {
2153       ctrl->server_local->inhibit_data_logging = 1;
2154       ctrl->server_local->inhibit_data_logging_now = 0;
2155       ctrl->server_local->inhibit_data_logging_count = 0;
2156       err = ks_action_fetch (ctrl, line, outfp);
2157       es_fclose (outfp);
2158       ctrl->server_local->inhibit_data_logging = 0;
2159     }
2160
2161  leave:
2162   return leave_cmd (ctx, err);
2163 }
2164
2165
2166 \f
2167 static const char hlp_ks_put[] =
2168   "KS_PUT\n"
2169   "\n"
2170   "Send a key to the configured OpenPGP keyservers.  The actual key material\n"
2171   "is then requested by Dirmngr using\n"
2172   "\n"
2173   "  INQUIRE KEYBLOCK\n"
2174   "\n"
2175   "The client shall respond with a binary version of the keyblock (e.g.,\n"
2176   "the output of `gpg --export KEYID').  For LDAP\n"
2177   "keyservers Dirmngr may ask for meta information of the provided keyblock\n"
2178   "using:\n"
2179   "\n"
2180   "  INQUIRE KEYBLOCK_INFO\n"
2181   "\n"
2182   "The client shall respond with a colon delimited info lines (the output\n"
2183   "of 'for x in keys sigs; do gpg --list-$x --with-colons KEYID; done').\n";
2184 static gpg_error_t
2185 cmd_ks_put (assuan_context_t ctx, char *line)
2186 {
2187   ctrl_t ctrl = assuan_get_pointer (ctx);
2188   gpg_error_t err;
2189   unsigned char *value = NULL;
2190   size_t valuelen;
2191   unsigned char *info = NULL;
2192   size_t infolen;
2193
2194   /* No options for now.  */
2195   line = skip_options (line);
2196
2197   err = ensure_keyserver (ctrl);
2198   if (err)
2199     goto leave;
2200
2201   /* Ask for the key material.  */
2202   err = assuan_inquire (ctx, "KEYBLOCK",
2203                         &value, &valuelen, MAX_KEYBLOCK_LENGTH);
2204   if (err)
2205     {
2206       log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
2207       goto leave;
2208     }
2209
2210   if (!valuelen) /* No data returned; return a comprehensible error. */
2211     {
2212       err = gpg_error (GPG_ERR_MISSING_CERT);
2213       goto leave;
2214     }
2215
2216   /* Ask for the key meta data. Not actually needed for HKP servers
2217      but we do it anyway to test the client implementaion.  */
2218   err = assuan_inquire (ctx, "KEYBLOCK_INFO",
2219                         &info, &infolen, MAX_KEYBLOCK_LENGTH);
2220   if (err)
2221     {
2222       log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
2223       goto leave;
2224     }
2225
2226   /* Send the key.  */
2227   err = ks_action_put (ctrl, ctrl->server_local->keyservers,
2228                        value, valuelen, info, infolen);
2229
2230  leave:
2231   xfree (info);
2232   xfree (value);
2233   return leave_cmd (ctx, err);
2234 }
2235
2236
2237 \f
2238 static const char hlp_loadswdb[] =
2239   "LOADSWDB [--force]\n"
2240   "\n"
2241   "Load and verify the swdb.lst from the Net.";
2242 static gpg_error_t
2243 cmd_loadswdb (assuan_context_t ctx, char *line)
2244 {
2245   ctrl_t ctrl = assuan_get_pointer (ctx);
2246   gpg_error_t err;
2247
2248   err = dirmngr_load_swdb (ctrl, has_option (line, "--force"));
2249
2250   return leave_cmd (ctx, err);
2251 }
2252
2253
2254 \f
2255 static const char hlp_getinfo[] =
2256   "GETINFO <what>\n"
2257   "\n"
2258   "Multi purpose command to return certain information.  \n"
2259   "Supported values of WHAT are:\n"
2260   "\n"
2261   "version     - Return the version of the program.\n"
2262   "pid         - Return the process id of the server.\n"
2263   "tor         - Return OK if running in Tor mode\n"
2264   "dnsinfo     - Return info about the DNS resolver\n"
2265   "socket_name - Return the name of the socket.\n";
2266 static gpg_error_t
2267 cmd_getinfo (assuan_context_t ctx, char *line)
2268 {
2269   ctrl_t ctrl = assuan_get_pointer (ctx);
2270   gpg_error_t err;
2271
2272   if (!strcmp (line, "version"))
2273     {
2274       const char *s = VERSION;
2275       err = assuan_send_data (ctx, s, strlen (s));
2276     }
2277   else if (!strcmp (line, "pid"))
2278     {
2279       char numbuf[50];
2280
2281       snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
2282       err = assuan_send_data (ctx, numbuf, strlen (numbuf));
2283     }
2284   else if (!strcmp (line, "socket_name"))
2285     {
2286       const char *s = dirmngr_get_current_socket_name ();
2287       err = assuan_send_data (ctx, s, strlen (s));
2288     }
2289   else if (!strcmp (line, "tor"))
2290     {
2291       if (opt.use_tor)
2292         {
2293           if (!is_tor_running (ctrl))
2294             err = assuan_write_status (ctx, "NO_TOR", "Tor not running");
2295           else
2296             err = 0;
2297           if (!err)
2298             assuan_set_okay_line (ctx, "- Tor mode is enabled");
2299         }
2300       else
2301         err = set_error (GPG_ERR_FALSE, "Tor mode is NOT enabled");
2302     }
2303   else if (!strcmp (line, "dnsinfo"))
2304     {
2305       if (standard_resolver_p ())
2306         assuan_set_okay_line
2307           (ctx, "- Forced use of System resolver (w/o Tor support)");
2308       else
2309         {
2310 #ifdef USE_LIBDNS
2311           assuan_set_okay_line (ctx, (recursive_resolver_p ()
2312                                       ? "- Libdns recursive resolver"
2313                                       : "- Libdns stub resolver"));
2314 #else
2315           assuan_set_okay_line (ctx, "- System resolver (w/o Tor support)");
2316 #endif
2317         }
2318       err = 0;
2319     }
2320   else
2321     err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
2322
2323   return leave_cmd (ctx, err);
2324 }
2325
2326
2327 \f
2328 static const char hlp_killdirmngr[] =
2329   "KILLDIRMNGR\n"
2330   "\n"
2331   "This command allows a user - given sufficient permissions -\n"
2332   "to kill this dirmngr process.\n";
2333 static gpg_error_t
2334 cmd_killdirmngr (assuan_context_t ctx, char *line)
2335 {
2336   ctrl_t ctrl = assuan_get_pointer (ctx);
2337
2338   (void)line;
2339
2340   ctrl->server_local->stopme = 1;
2341   assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
2342   return gpg_error (GPG_ERR_EOF);
2343 }
2344
2345
2346 static const char hlp_reloaddirmngr[] =
2347   "RELOADDIRMNGR\n"
2348   "\n"
2349   "This command is an alternative to SIGHUP\n"
2350   "to reload the configuration.";
2351 static gpg_error_t
2352 cmd_reloaddirmngr (assuan_context_t ctx, char *line)
2353 {
2354   (void)ctx;
2355   (void)line;
2356
2357   dirmngr_sighup_action ();
2358   return 0;
2359 }
2360
2361
2362 \f
2363 /* Tell the assuan library about our commands. */
2364 static int
2365 register_commands (assuan_context_t ctx)
2366 {
2367   static struct {
2368     const char *name;
2369     assuan_handler_t handler;
2370     const char * const help;
2371   } table[] = {
2372     { "DNS_CERT",   cmd_dns_cert,   hlp_dns_cert },
2373     { "WKD_GET",    cmd_wkd_get,    hlp_wkd_get },
2374     { "LDAPSERVER", cmd_ldapserver, hlp_ldapserver },
2375     { "ISVALID",    cmd_isvalid,    hlp_isvalid },
2376     { "CHECKCRL",   cmd_checkcrl,   hlp_checkcrl },
2377     { "CHECKOCSP",  cmd_checkocsp,  hlp_checkocsp },
2378     { "LOOKUP",     cmd_lookup,     hlp_lookup },
2379     { "LOADCRL",    cmd_loadcrl,    hlp_loadcrl },
2380     { "LISTCRLS",   cmd_listcrls,   hlp_listcrls },
2381     { "CACHECERT",  cmd_cachecert,  hlp_cachecert },
2382     { "VALIDATE",   cmd_validate,   hlp_validate },
2383     { "KEYSERVER",  cmd_keyserver,  hlp_keyserver },
2384     { "KS_SEARCH",  cmd_ks_search,  hlp_ks_search },
2385     { "KS_GET",     cmd_ks_get,     hlp_ks_get },
2386     { "KS_FETCH",   cmd_ks_fetch,   hlp_ks_fetch },
2387     { "KS_PUT",     cmd_ks_put,     hlp_ks_put },
2388     { "GETINFO",    cmd_getinfo,    hlp_getinfo },
2389     { "LOADSWDB",   cmd_loadswdb,   hlp_loadswdb },
2390     { "KILLDIRMNGR",cmd_killdirmngr,hlp_killdirmngr },
2391     { "RELOADDIRMNGR",cmd_reloaddirmngr,hlp_reloaddirmngr },
2392     { NULL, NULL }
2393   };
2394   int i, j, rc;
2395
2396   for (i=j=0; table[i].name; i++)
2397     {
2398       rc = assuan_register_command (ctx, table[i].name, table[i].handler,
2399                                     table[i].help);
2400       if (rc)
2401         return rc;
2402     }
2403   return 0;
2404 }
2405
2406
2407 /* Note that we do not reset the list of configured keyservers.  */
2408 static gpg_error_t
2409 reset_notify (assuan_context_t ctx, char *line)
2410 {
2411   ctrl_t ctrl = assuan_get_pointer (ctx);
2412   (void)line;
2413
2414 #if USE_LDAP
2415   ldapserver_list_free (ctrl->server_local->ldapservers);
2416 #endif /*USE_LDAP*/
2417   ctrl->server_local->ldapservers = NULL;
2418   return 0;
2419 }
2420
2421
2422 /* This function is called by our assuan log handler to test whether a
2423  * log message shall really be printed.  The function must return
2424  * false to inhibit the logging of MSG.  CAT gives the requested log
2425  * category.  MSG might be NULL. */
2426 int
2427 dirmngr_assuan_log_monitor (assuan_context_t ctx, unsigned int cat,
2428                             const char *msg)
2429 {
2430   ctrl_t ctrl = assuan_get_pointer (ctx);
2431
2432   (void)cat;
2433   (void)msg;
2434
2435   if (!ctrl || !ctrl->server_local)
2436     return 1; /* Can't decide - allow logging.  */
2437
2438   if (!ctrl->server_local->inhibit_data_logging)
2439     return 1; /* Not requested - allow logging.  */
2440
2441   /* Disallow logging if *_now is true.  */
2442   return !ctrl->server_local->inhibit_data_logging_now;
2443 }
2444
2445
2446 /* Startup the server and run the main command loop.  With FD = -1,
2447    use stdin/stdout. */
2448 void
2449 start_command_handler (assuan_fd_t fd)
2450 {
2451   static const char hello[] = "Dirmngr " VERSION " at your service";
2452   static char *hello_line;
2453   int rc;
2454   assuan_context_t ctx;
2455   ctrl_t ctrl;
2456
2457   ctrl = xtrycalloc (1, sizeof *ctrl);
2458   if (ctrl)
2459     ctrl->server_local = xtrycalloc (1, sizeof *ctrl->server_local);
2460   if (!ctrl || !ctrl->server_local)
2461     {
2462       log_error (_("can't allocate control structure: %s\n"),
2463                  strerror (errno));
2464       xfree (ctrl);
2465       return;
2466     }
2467
2468   dirmngr_init_default_ctrl (ctrl);
2469
2470   rc = assuan_new (&ctx);
2471   if (rc)
2472     {
2473       log_error (_("failed to allocate assuan context: %s\n"),
2474                  gpg_strerror (rc));
2475       dirmngr_exit (2);
2476     }
2477
2478   if (fd == ASSUAN_INVALID_FD)
2479     {
2480       assuan_fd_t filedes[2];
2481
2482       filedes[0] = assuan_fdopen (0);
2483       filedes[1] = assuan_fdopen (1);
2484       rc = assuan_init_pipe_server (ctx, filedes);
2485     }
2486   else
2487     {
2488       rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED);
2489     }
2490
2491   if (rc)
2492     {
2493       assuan_release (ctx);
2494       log_error (_("failed to initialize the server: %s\n"),
2495                  gpg_strerror(rc));
2496       dirmngr_exit (2);
2497     }
2498
2499   rc = register_commands (ctx);
2500   if (rc)
2501     {
2502       log_error (_("failed to the register commands with Assuan: %s\n"),
2503                  gpg_strerror(rc));
2504       dirmngr_exit (2);
2505     }
2506
2507
2508   if (!hello_line)
2509     {
2510       hello_line = xtryasprintf
2511         ("Home: %s\n"
2512          "Config: %s\n"
2513          "%s",
2514          gnupg_homedir (),
2515          opt.config_filename? opt.config_filename : "[none]",
2516          hello);
2517     }
2518
2519   ctrl->server_local->assuan_ctx = ctx;
2520   assuan_set_pointer (ctx, ctrl);
2521
2522   assuan_set_hello_line (ctx, hello_line);
2523   assuan_register_option_handler (ctx, option_handler);
2524   assuan_register_reset_notify (ctx, reset_notify);
2525
2526   for (;;)
2527     {
2528       rc = assuan_accept (ctx);
2529       if (rc == -1)
2530         break;
2531       if (rc)
2532         {
2533           log_info (_("Assuan accept problem: %s\n"), gpg_strerror (rc));
2534           break;
2535         }
2536
2537 #ifndef HAVE_W32_SYSTEM
2538       if (opt.verbose)
2539         {
2540           assuan_peercred_t peercred;
2541
2542           if (!assuan_get_peercred (ctx, &peercred))
2543             log_info ("connection from process %ld (%ld:%ld)\n",
2544                       (long)peercred->pid, (long)peercred->uid,
2545                       (long)peercred->gid);
2546         }
2547 #endif
2548
2549       rc = assuan_process (ctx);
2550       if (rc)
2551         {
2552           log_info (_("Assuan processing failed: %s\n"), gpg_strerror (rc));
2553           continue;
2554         }
2555     }
2556
2557
2558 #if USE_LDAP
2559   ldap_wrapper_connection_cleanup (ctrl);
2560
2561   ldapserver_list_free (ctrl->server_local->ldapservers);
2562 #endif /*USE_LDAP*/
2563   ctrl->server_local->ldapservers = NULL;
2564
2565   release_ctrl_keyservers (ctrl);
2566
2567   ctrl->server_local->assuan_ctx = NULL;
2568   assuan_release (ctx);
2569
2570   if (ctrl->server_local->stopme)
2571     dirmngr_exit (0);
2572
2573   if (ctrl->refcount)
2574     log_error ("oops: connection control structure still referenced (%d)\n",
2575                ctrl->refcount);
2576   else
2577     {
2578       release_ctrl_ocsp_certs (ctrl);
2579       xfree (ctrl->server_local);
2580       dirmngr_deinit_default_ctrl (ctrl);
2581       xfree (ctrl);
2582     }
2583 }
2584
2585
2586 /* Send a status line back to the client.  KEYWORD is the status
2587    keyword, the optional string arguments are blank separated added to
2588    the line, the last argument must be a NULL. */
2589 gpg_error_t
2590 dirmngr_status (ctrl_t ctrl, const char *keyword, ...)
2591 {
2592   gpg_error_t err = 0;
2593   va_list arg_ptr;
2594   const char *text;
2595
2596   va_start (arg_ptr, keyword);
2597
2598   if (ctrl->server_local)
2599     {
2600       assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2601       char buf[950], *p;
2602       size_t n;
2603
2604       p = buf;
2605       n = 0;
2606       while ( (text = va_arg (arg_ptr, const char *)) )
2607         {
2608           if (n)
2609             {
2610               *p++ = ' ';
2611               n++;
2612             }
2613           for ( ; *text && n < DIM (buf)-2; n++)
2614             *p++ = *text++;
2615         }
2616       *p = 0;
2617       err = assuan_write_status (ctx, keyword, buf);
2618     }
2619
2620   va_end (arg_ptr);
2621   return err;
2622 }
2623
2624
2625 /* Print a help status line.  TEXTLEN gives the length of the text
2626    from TEXT to be printed.  The function splits text at LFs.  */
2627 gpg_error_t
2628 dirmngr_status_help (ctrl_t ctrl, const char *text)
2629 {
2630   gpg_error_t err = 0;
2631
2632   if (ctrl->server_local)
2633     {
2634       assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2635       char buf[950], *p;
2636       size_t n;
2637
2638       do
2639         {
2640           p = buf;
2641           n = 0;
2642           for ( ; *text && *text != '\n' && n < DIM (buf)-2; n++)
2643             *p++ = *text++;
2644           if (*text == '\n')
2645             text++;
2646           *p = 0;
2647           err = assuan_write_status (ctx, "#", buf);
2648         }
2649       while (!err && *text);
2650     }
2651
2652   return err;
2653 }
2654
2655 /* Send a tick progress indicator back.  Fixme: This is only done for
2656    the currently active channel.  */
2657 gpg_error_t
2658 dirmngr_tick (ctrl_t ctrl)
2659 {
2660   static time_t next_tick = 0;
2661   gpg_error_t err = 0;
2662   time_t now = time (NULL);
2663
2664   if (!next_tick)
2665     {
2666       next_tick = now + 1;
2667     }
2668   else if ( now > next_tick )
2669     {
2670       if (ctrl)
2671         {
2672           err = dirmngr_status (ctrl, "PROGRESS", "tick", "? 0 0", NULL);
2673           if (err)
2674             {
2675               /* Take this as in indication for a cancel request.  */
2676               err = gpg_error (GPG_ERR_CANCELED);
2677             }
2678           now = time (NULL);
2679         }
2680
2681       next_tick = now + 1;
2682     }
2683   return err;
2684 }