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