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