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