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