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