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