Imported Upstream version 2.1.19
[platform/upstream/gpg2.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 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                              (VALIDATE_FLAG_TRUST_CONFIG
1856                               | (tls_mode ? VALIDATE_FLAG_TLS : 0)
1857                               | (systrust_mode ? VALIDATE_FLAG_TRUST_SYSTEM : 0)
1858                               | (no_crl ? VALIDATE_FLAG_NOCRLCHECK : 0)),
1859                              NULL);
1860
1861  leave:
1862   ksba_cert_release (cert);
1863   release_certlist (certlist);
1864   return leave_cmd (ctx, err);
1865 }
1866
1867
1868 \f
1869 /* Parse an keyserver URI and store it in a new uri item which is
1870    returned at R_ITEM.  On error return an error code.  */
1871 static gpg_error_t
1872 make_keyserver_item (const char *uri, uri_item_t *r_item)
1873 {
1874   gpg_error_t err;
1875   uri_item_t item;
1876
1877   *r_item = NULL;
1878   item = xtrymalloc (sizeof *item + strlen (uri));
1879   if (!item)
1880     return gpg_error_from_syserror ();
1881
1882   item->next = NULL;
1883   item->parsed_uri = NULL;
1884   strcpy (item->uri, uri);
1885
1886 #if USE_LDAP
1887   if (ldap_uri_p (item->uri))
1888     err = ldap_parse_uri (&item->parsed_uri, uri);
1889   else
1890 #endif
1891     {
1892       err = http_parse_uri (&item->parsed_uri, uri, 1);
1893     }
1894
1895   if (err)
1896     xfree (item);
1897   else
1898     *r_item = item;
1899   return err;
1900 }
1901
1902
1903 /* If no keyserver is stored in CTRL but a global keyserver has been
1904    set, put that global keyserver into CTRL.  We need use this
1905    function to help migrate from the old gpg based keyserver
1906    configuration to the new dirmngr based configuration.  */
1907 static gpg_error_t
1908 ensure_keyserver (ctrl_t ctrl)
1909 {
1910   gpg_error_t err;
1911   uri_item_t item;
1912   uri_item_t onion_items = NULL;
1913   uri_item_t plain_items = NULL;
1914   uri_item_t ui;
1915   strlist_t sl;
1916
1917   if (ctrl->server_local->keyservers)
1918     return 0; /* Already set for this session.  */
1919   if (!opt.keyserver)
1920     {
1921       /* No global option set.  Fall back to default:  */
1922       return make_keyserver_item (DIRMNGR_DEFAULT_KEYSERVER,
1923                                   &ctrl->server_local->keyservers);
1924     }
1925
1926   for (sl = opt.keyserver; sl; sl = sl->next)
1927     {
1928       err = make_keyserver_item (sl->d, &item);
1929       if (err)
1930         goto leave;
1931       if (item->parsed_uri->onion)
1932         {
1933           item->next = onion_items;
1934           onion_items = item;
1935         }
1936       else
1937         {
1938           item->next = plain_items;
1939           plain_items = item;
1940         }
1941     }
1942
1943   /* Decide which to use.  Note that the sesssion has no keyservers
1944      yet set. */
1945   if (onion_items && !onion_items->next && plain_items && !plain_items->next)
1946     {
1947       /* If there is just one onion and one plain keyserver given, we take
1948          only one depending on whether Tor is running or not.  */
1949       if (is_tor_running (ctrl))
1950         {
1951           ctrl->server_local->keyservers = onion_items;
1952           onion_items = NULL;
1953         }
1954       else
1955         {
1956           ctrl->server_local->keyservers = plain_items;
1957           plain_items = NULL;
1958         }
1959     }
1960   else if (!is_tor_running (ctrl))
1961     {
1962       /* Tor is not running.  It does not make sense to add Onion
1963          addresses.  */
1964       ctrl->server_local->keyservers = plain_items;
1965       plain_items = NULL;
1966     }
1967   else
1968     {
1969       /* In all other cases add all keyservers.  */
1970       ctrl->server_local->keyservers = onion_items;
1971       onion_items = NULL;
1972       for (ui = ctrl->server_local->keyservers; ui && ui->next; ui = ui->next)
1973         ;
1974       if (ui)
1975         ui->next = plain_items;
1976       else
1977         ctrl->server_local->keyservers = plain_items;
1978       plain_items = NULL;
1979     }
1980
1981  leave:
1982   release_uri_item_list (onion_items);
1983   release_uri_item_list (plain_items);
1984
1985   return err;
1986 }
1987
1988
1989 static const char hlp_keyserver[] =
1990   "KEYSERVER [<options>] [<uri>|<host>]\n"
1991   "Options are:\n"
1992   "  --help\n"
1993   "  --clear      Remove all configured keyservers\n"
1994   "  --resolve    Resolve HKP host names and rotate\n"
1995   "  --hosttable  Print table of known hosts and pools\n"
1996   "  --dead       Mark <host> as dead\n"
1997   "  --alive      Mark <host> as alive\n"
1998   "\n"
1999   "If called without arguments list all configured keyserver URLs.\n"
2000   "If called with an URI add this as keyserver.  Note that keyservers\n"
2001   "are configured on a per-session base.  A default keyserver may already be\n"
2002   "present, thus the \"--clear\" option must be used to get full control.\n"
2003   "If \"--clear\" and an URI are used together the clear command is\n"
2004   "obviously executed first.  A RESET command does not change the list\n"
2005   "of configured keyservers.";
2006 static gpg_error_t
2007 cmd_keyserver (assuan_context_t ctx, char *line)
2008 {
2009   ctrl_t ctrl = assuan_get_pointer (ctx);
2010   gpg_error_t err = 0;
2011   int clear_flag, add_flag, help_flag, host_flag, resolve_flag;
2012   int dead_flag, alive_flag;
2013   uri_item_t item = NULL; /* gcc 4.4.5 is not able to detect that it
2014                              is always initialized.  */
2015
2016   clear_flag = has_option (line, "--clear");
2017   help_flag = has_option (line, "--help");
2018   resolve_flag = has_option (line, "--resolve");
2019   host_flag = has_option (line, "--hosttable");
2020   dead_flag = has_option (line, "--dead");
2021   alive_flag = has_option (line, "--alive");
2022   line = skip_options (line);
2023   add_flag = !!*line;
2024
2025   if (help_flag)
2026     {
2027       err = ks_action_help (ctrl, line);
2028       goto leave;
2029     }
2030
2031   if (resolve_flag)
2032     {
2033       err = ensure_keyserver (ctrl);
2034       if (!err)
2035         err = ks_action_resolve (ctrl, ctrl->server_local->keyservers);
2036       if (err)
2037         goto leave;
2038     }
2039
2040   if (alive_flag && dead_flag)
2041     {
2042       err = set_error (GPG_ERR_ASS_PARAMETER, "no support for zombies");
2043       goto leave;
2044     }
2045   if (dead_flag)
2046     {
2047       err = check_owner_permission (ctx, "no permission to use --dead");
2048       if (err)
2049         goto leave;
2050     }
2051   if (alive_flag || dead_flag)
2052     {
2053       if (!*line)
2054         {
2055           err = set_error (GPG_ERR_ASS_PARAMETER, "name of host missing");
2056           goto leave;
2057         }
2058
2059       err = ks_hkp_mark_host (ctrl, line, alive_flag);
2060       if (err)
2061         goto leave;
2062     }
2063
2064   if (host_flag)
2065     {
2066       err = ks_hkp_print_hosttable (ctrl);
2067       if (err)
2068         goto leave;
2069     }
2070   if (resolve_flag || host_flag || alive_flag || dead_flag)
2071     goto leave;
2072
2073   if (add_flag)
2074     {
2075       err = make_keyserver_item (line, &item);
2076       if (err)
2077         goto leave;
2078     }
2079   if (clear_flag)
2080     release_ctrl_keyservers (ctrl);
2081   if (add_flag)
2082     {
2083       item->next = ctrl->server_local->keyservers;
2084       ctrl->server_local->keyservers = item;
2085     }
2086
2087   if (!add_flag && !clear_flag && !help_flag)
2088     {
2089       /* List configured keyservers.  However, we first add a global
2090          keyserver. */
2091       uri_item_t u;
2092
2093       err = ensure_keyserver (ctrl);
2094       if (err)
2095         {
2096           assuan_set_error (ctx, err,
2097                             "Bad keyserver configuration in dirmngr.conf");
2098           goto leave;
2099         }
2100
2101       for (u=ctrl->server_local->keyservers; u; u = u->next)
2102         dirmngr_status (ctrl, "KEYSERVER", u->uri, NULL);
2103     }
2104   err = 0;
2105
2106  leave:
2107   return leave_cmd (ctx, err);
2108 }
2109
2110
2111 \f
2112 static const char hlp_ks_search[] =
2113   "KS_SEARCH {<pattern>}\n"
2114   "\n"
2115   "Search the configured OpenPGP keyservers (see command KEYSERVER)\n"
2116   "for keys matching PATTERN";
2117 static gpg_error_t
2118 cmd_ks_search (assuan_context_t ctx, char *line)
2119 {
2120   ctrl_t ctrl = assuan_get_pointer (ctx);
2121   gpg_error_t err;
2122   strlist_t list, sl;
2123   char *p;
2124   estream_t outfp;
2125
2126   /* No options for now.  */
2127   line = skip_options (line);
2128
2129   /* Break the line down into an strlist.  Each pattern is
2130      percent-plus escaped. */
2131   list = NULL;
2132   for (p=line; *p; line = p)
2133     {
2134       while (*p && *p != ' ')
2135         p++;
2136       if (*p)
2137         *p++ = 0;
2138       if (*line)
2139         {
2140           sl = xtrymalloc (sizeof *sl + strlen (line));
2141           if (!sl)
2142             {
2143               err = gpg_error_from_syserror ();
2144               goto leave;
2145             }
2146           sl->flags = 0;
2147           strcpy_escaped_plus (sl->d, line);
2148           sl->next = list;
2149           list = sl;
2150         }
2151     }
2152
2153   err = ensure_keyserver (ctrl);
2154   if (err)
2155     goto leave;
2156
2157   /* Setup an output stream and perform the search.  */
2158   outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
2159   if (!outfp)
2160     err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2161   else
2162     {
2163       err = ks_action_search (ctrl, ctrl->server_local->keyservers,
2164                               list, outfp);
2165       es_fclose (outfp);
2166     }
2167
2168  leave:
2169   free_strlist (list);
2170   return leave_cmd (ctx, err);
2171 }
2172
2173
2174 \f
2175 static const char hlp_ks_get[] =
2176   "KS_GET {<pattern>}\n"
2177   "\n"
2178   "Get the keys matching PATTERN from the configured OpenPGP keyservers\n"
2179   "(see command KEYSERVER).  Each pattern should be a keyid, a fingerprint,\n"
2180   "or an exact name indicated by the '=' prefix.";
2181 static gpg_error_t
2182 cmd_ks_get (assuan_context_t ctx, char *line)
2183 {
2184   ctrl_t ctrl = assuan_get_pointer (ctx);
2185   gpg_error_t err;
2186   strlist_t list, sl;
2187   char *p;
2188   estream_t outfp;
2189
2190   /* No options for now.  */
2191   line = skip_options (line);
2192
2193   /* Break the line into a strlist.  Each pattern is by
2194      definition percent-plus escaped.  However we only support keyids
2195      and fingerprints and thus the client has no need to apply the
2196      escaping.  */
2197   list = NULL;
2198   for (p=line; *p; line = p)
2199     {
2200       while (*p && *p != ' ')
2201         p++;
2202       if (*p)
2203         *p++ = 0;
2204       if (*line)
2205         {
2206           sl = xtrymalloc (sizeof *sl + strlen (line));
2207           if (!sl)
2208             {
2209               err = gpg_error_from_syserror ();
2210               goto leave;
2211             }
2212           sl->flags = 0;
2213           strcpy_escaped_plus (sl->d, line);
2214           sl->next = list;
2215           list = sl;
2216         }
2217     }
2218
2219   err = ensure_keyserver (ctrl);
2220   if (err)
2221     goto leave;
2222
2223   /* Setup an output stream and perform the get.  */
2224   outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
2225   if (!outfp)
2226     err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2227   else
2228     {
2229       ctrl->server_local->inhibit_data_logging = 1;
2230       ctrl->server_local->inhibit_data_logging_now = 0;
2231       ctrl->server_local->inhibit_data_logging_count = 0;
2232       err = ks_action_get (ctrl, ctrl->server_local->keyservers, list, outfp);
2233       es_fclose (outfp);
2234       ctrl->server_local->inhibit_data_logging = 0;
2235     }
2236
2237  leave:
2238   free_strlist (list);
2239   return leave_cmd (ctx, err);
2240 }
2241
2242
2243 static const char hlp_ks_fetch[] =
2244   "KS_FETCH <URL>\n"
2245   "\n"
2246   "Get the key(s) from URL.";
2247 static gpg_error_t
2248 cmd_ks_fetch (assuan_context_t ctx, char *line)
2249 {
2250   ctrl_t ctrl = assuan_get_pointer (ctx);
2251   gpg_error_t err;
2252   estream_t outfp;
2253
2254   /* No options for now.  */
2255   line = skip_options (line);
2256
2257   err = ensure_keyserver (ctrl);  /* FIXME: Why do we needs this here?  */
2258   if (err)
2259     goto leave;
2260
2261   /* Setup an output stream and perform the get.  */
2262   outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
2263   if (!outfp)
2264     err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2265   else
2266     {
2267       ctrl->server_local->inhibit_data_logging = 1;
2268       ctrl->server_local->inhibit_data_logging_now = 0;
2269       ctrl->server_local->inhibit_data_logging_count = 0;
2270       err = ks_action_fetch (ctrl, line, outfp);
2271       es_fclose (outfp);
2272       ctrl->server_local->inhibit_data_logging = 0;
2273     }
2274
2275  leave:
2276   return leave_cmd (ctx, err);
2277 }
2278
2279
2280 \f
2281 static const char hlp_ks_put[] =
2282   "KS_PUT\n"
2283   "\n"
2284   "Send a key to the configured OpenPGP keyservers.  The actual key material\n"
2285   "is then requested by Dirmngr using\n"
2286   "\n"
2287   "  INQUIRE KEYBLOCK\n"
2288   "\n"
2289   "The client shall respond with a binary version of the keyblock (e.g.,\n"
2290   "the output of `gpg --export KEYID').  For LDAP\n"
2291   "keyservers Dirmngr may ask for meta information of the provided keyblock\n"
2292   "using:\n"
2293   "\n"
2294   "  INQUIRE KEYBLOCK_INFO\n"
2295   "\n"
2296   "The client shall respond with a colon delimited info lines (the output\n"
2297   "of 'for x in keys sigs; do gpg --list-$x --with-colons KEYID; done').\n";
2298 static gpg_error_t
2299 cmd_ks_put (assuan_context_t ctx, char *line)
2300 {
2301   ctrl_t ctrl = assuan_get_pointer (ctx);
2302   gpg_error_t err;
2303   unsigned char *value = NULL;
2304   size_t valuelen;
2305   unsigned char *info = NULL;
2306   size_t infolen;
2307
2308   /* No options for now.  */
2309   line = skip_options (line);
2310
2311   err = ensure_keyserver (ctrl);
2312   if (err)
2313     goto leave;
2314
2315   /* Ask for the key material.  */
2316   err = assuan_inquire (ctx, "KEYBLOCK",
2317                         &value, &valuelen, MAX_KEYBLOCK_LENGTH);
2318   if (err)
2319     {
2320       log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
2321       goto leave;
2322     }
2323
2324   if (!valuelen) /* No data returned; return a comprehensible error. */
2325     {
2326       err = gpg_error (GPG_ERR_MISSING_CERT);
2327       goto leave;
2328     }
2329
2330   /* Ask for the key meta data. Not actually needed for HKP servers
2331      but we do it anyway to test the client implementaion.  */
2332   err = assuan_inquire (ctx, "KEYBLOCK_INFO",
2333                         &info, &infolen, MAX_KEYBLOCK_LENGTH);
2334   if (err)
2335     {
2336       log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
2337       goto leave;
2338     }
2339
2340   /* Send the key.  */
2341   err = ks_action_put (ctrl, ctrl->server_local->keyservers,
2342                        value, valuelen, info, infolen);
2343
2344  leave:
2345   xfree (info);
2346   xfree (value);
2347   return leave_cmd (ctx, err);
2348 }
2349
2350
2351 \f
2352 static const char hlp_loadswdb[] =
2353   "LOADSWDB [--force]\n"
2354   "\n"
2355   "Load and verify the swdb.lst from the Net.";
2356 static gpg_error_t
2357 cmd_loadswdb (assuan_context_t ctx, char *line)
2358 {
2359   ctrl_t ctrl = assuan_get_pointer (ctx);
2360   gpg_error_t err;
2361
2362   err = dirmngr_load_swdb (ctrl, has_option (line, "--force"));
2363
2364   return leave_cmd (ctx, err);
2365 }
2366
2367
2368 \f
2369 static const char hlp_getinfo[] =
2370   "GETINFO <what>\n"
2371   "\n"
2372   "Multi purpose command to return certain information.  \n"
2373   "Supported values of WHAT are:\n"
2374   "\n"
2375   "version     - Return the version of the program.\n"
2376   "pid         - Return the process id of the server.\n"
2377   "tor         - Return OK if running in Tor mode\n"
2378   "dnsinfo     - Return info about the DNS resolver\n"
2379   "socket_name - Return the name of the socket.\n";
2380 static gpg_error_t
2381 cmd_getinfo (assuan_context_t ctx, char *line)
2382 {
2383   ctrl_t ctrl = assuan_get_pointer (ctx);
2384   gpg_error_t err;
2385
2386   if (!strcmp (line, "version"))
2387     {
2388       const char *s = VERSION;
2389       err = assuan_send_data (ctx, s, strlen (s));
2390     }
2391   else if (!strcmp (line, "pid"))
2392     {
2393       char numbuf[50];
2394
2395       snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
2396       err = assuan_send_data (ctx, numbuf, strlen (numbuf));
2397     }
2398   else if (!strcmp (line, "socket_name"))
2399     {
2400       const char *s = dirmngr_get_current_socket_name ();
2401       err = assuan_send_data (ctx, s, strlen (s));
2402     }
2403   else if (!strcmp (line, "tor"))
2404     {
2405       int use_tor;
2406
2407       use_tor = dirmngr_use_tor ();
2408       if (use_tor)
2409         {
2410           if (!is_tor_running (ctrl))
2411             err = assuan_write_status (ctx, "NO_TOR", "Tor not running");
2412           else
2413             err = 0;
2414           if (!err)
2415             assuan_set_okay_line (ctx, use_tor == 1 ? "- Tor mode is enabled"
2416                                   /**/              : "- Tor mode is enforced");
2417         }
2418       else
2419         err = set_error (GPG_ERR_FALSE, "Tor mode is NOT enabled");
2420     }
2421   else if (!strcmp (line, "dnsinfo"))
2422     {
2423       if (standard_resolver_p ())
2424         assuan_set_okay_line
2425           (ctx, "- Forced use of System resolver (w/o Tor support)");
2426       else
2427         {
2428 #ifdef USE_LIBDNS
2429           assuan_set_okay_line (ctx, (recursive_resolver_p ()
2430                                       ? "- Libdns recursive resolver"
2431                                       : "- Libdns stub resolver"));
2432 #else
2433           assuan_set_okay_line (ctx, "- System resolver (w/o Tor support)");
2434 #endif
2435         }
2436       err = 0;
2437     }
2438   else
2439     err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
2440
2441   return leave_cmd (ctx, err);
2442 }
2443
2444
2445 \f
2446 static const char hlp_killdirmngr[] =
2447   "KILLDIRMNGR\n"
2448   "\n"
2449   "This command allows a user - given sufficient permissions -\n"
2450   "to kill this dirmngr process.\n";
2451 static gpg_error_t
2452 cmd_killdirmngr (assuan_context_t ctx, char *line)
2453 {
2454   ctrl_t ctrl = assuan_get_pointer (ctx);
2455
2456   (void)line;
2457
2458   ctrl->server_local->stopme = 1;
2459   assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
2460   return gpg_error (GPG_ERR_EOF);
2461 }
2462
2463
2464 static const char hlp_reloaddirmngr[] =
2465   "RELOADDIRMNGR\n"
2466   "\n"
2467   "This command is an alternative to SIGHUP\n"
2468   "to reload the configuration.";
2469 static gpg_error_t
2470 cmd_reloaddirmngr (assuan_context_t ctx, char *line)
2471 {
2472   (void)ctx;
2473   (void)line;
2474
2475   dirmngr_sighup_action ();
2476   return 0;
2477 }
2478
2479
2480 \f
2481 /* Tell the assuan library about our commands. */
2482 static int
2483 register_commands (assuan_context_t ctx)
2484 {
2485   static struct {
2486     const char *name;
2487     assuan_handler_t handler;
2488     const char * const help;
2489   } table[] = {
2490     { "DNS_CERT",   cmd_dns_cert,   hlp_dns_cert },
2491     { "WKD_GET",    cmd_wkd_get,    hlp_wkd_get },
2492     { "LDAPSERVER", cmd_ldapserver, hlp_ldapserver },
2493     { "ISVALID",    cmd_isvalid,    hlp_isvalid },
2494     { "CHECKCRL",   cmd_checkcrl,   hlp_checkcrl },
2495     { "CHECKOCSP",  cmd_checkocsp,  hlp_checkocsp },
2496     { "LOOKUP",     cmd_lookup,     hlp_lookup },
2497     { "LOADCRL",    cmd_loadcrl,    hlp_loadcrl },
2498     { "LISTCRLS",   cmd_listcrls,   hlp_listcrls },
2499     { "CACHECERT",  cmd_cachecert,  hlp_cachecert },
2500     { "VALIDATE",   cmd_validate,   hlp_validate },
2501     { "KEYSERVER",  cmd_keyserver,  hlp_keyserver },
2502     { "KS_SEARCH",  cmd_ks_search,  hlp_ks_search },
2503     { "KS_GET",     cmd_ks_get,     hlp_ks_get },
2504     { "KS_FETCH",   cmd_ks_fetch,   hlp_ks_fetch },
2505     { "KS_PUT",     cmd_ks_put,     hlp_ks_put },
2506     { "GETINFO",    cmd_getinfo,    hlp_getinfo },
2507     { "LOADSWDB",   cmd_loadswdb,   hlp_loadswdb },
2508     { "KILLDIRMNGR",cmd_killdirmngr,hlp_killdirmngr },
2509     { "RELOADDIRMNGR",cmd_reloaddirmngr,hlp_reloaddirmngr },
2510     { NULL, NULL }
2511   };
2512   int i, j, rc;
2513
2514   for (i=j=0; table[i].name; i++)
2515     {
2516       rc = assuan_register_command (ctx, table[i].name, table[i].handler,
2517                                     table[i].help);
2518       if (rc)
2519         return rc;
2520     }
2521   return 0;
2522 }
2523
2524
2525 /* Note that we do not reset the list of configured keyservers.  */
2526 static gpg_error_t
2527 reset_notify (assuan_context_t ctx, char *line)
2528 {
2529   ctrl_t ctrl = assuan_get_pointer (ctx);
2530   (void)line;
2531
2532 #if USE_LDAP
2533   ldapserver_list_free (ctrl->server_local->ldapservers);
2534 #endif /*USE_LDAP*/
2535   ctrl->server_local->ldapservers = NULL;
2536   return 0;
2537 }
2538
2539
2540 /* This function is called by our assuan log handler to test whether a
2541  * log message shall really be printed.  The function must return
2542  * false to inhibit the logging of MSG.  CAT gives the requested log
2543  * category.  MSG might be NULL. */
2544 int
2545 dirmngr_assuan_log_monitor (assuan_context_t ctx, unsigned int cat,
2546                             const char *msg)
2547 {
2548   ctrl_t ctrl = assuan_get_pointer (ctx);
2549
2550   (void)cat;
2551   (void)msg;
2552
2553   if (!ctrl || !ctrl->server_local)
2554     return 1; /* Can't decide - allow logging.  */
2555
2556   if (!ctrl->server_local->inhibit_data_logging)
2557     return 1; /* Not requested - allow logging.  */
2558
2559   /* Disallow logging if *_now is true.  */
2560   return !ctrl->server_local->inhibit_data_logging_now;
2561 }
2562
2563
2564 /* Startup the server and run the main command loop.  With FD = -1,
2565    use stdin/stdout. */
2566 void
2567 start_command_handler (assuan_fd_t fd)
2568 {
2569   static const char hello[] = "Dirmngr " VERSION " at your service";
2570   static char *hello_line;
2571   int rc;
2572   assuan_context_t ctx;
2573   ctrl_t ctrl;
2574
2575   ctrl = xtrycalloc (1, sizeof *ctrl);
2576   if (ctrl)
2577     ctrl->server_local = xtrycalloc (1, sizeof *ctrl->server_local);
2578   if (!ctrl || !ctrl->server_local)
2579     {
2580       log_error (_("can't allocate control structure: %s\n"),
2581                  strerror (errno));
2582       xfree (ctrl);
2583       return;
2584     }
2585
2586   dirmngr_init_default_ctrl (ctrl);
2587
2588   rc = assuan_new (&ctx);
2589   if (rc)
2590     {
2591       log_error (_("failed to allocate assuan context: %s\n"),
2592                  gpg_strerror (rc));
2593       dirmngr_exit (2);
2594     }
2595
2596   if (fd == ASSUAN_INVALID_FD)
2597     {
2598       assuan_fd_t filedes[2];
2599
2600       filedes[0] = assuan_fdopen (0);
2601       filedes[1] = assuan_fdopen (1);
2602       rc = assuan_init_pipe_server (ctx, filedes);
2603     }
2604   else
2605     {
2606       rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED);
2607     }
2608
2609   if (rc)
2610     {
2611       assuan_release (ctx);
2612       log_error (_("failed to initialize the server: %s\n"),
2613                  gpg_strerror(rc));
2614       dirmngr_exit (2);
2615     }
2616
2617   rc = register_commands (ctx);
2618   if (rc)
2619     {
2620       log_error (_("failed to the register commands with Assuan: %s\n"),
2621                  gpg_strerror(rc));
2622       dirmngr_exit (2);
2623     }
2624
2625
2626   if (!hello_line)
2627     {
2628       hello_line = xtryasprintf
2629         ("Home: %s\n"
2630          "Config: %s\n"
2631          "%s",
2632          gnupg_homedir (),
2633          opt.config_filename? opt.config_filename : "[none]",
2634          hello);
2635     }
2636
2637   ctrl->server_local->assuan_ctx = ctx;
2638   assuan_set_pointer (ctx, ctrl);
2639
2640   assuan_set_hello_line (ctx, hello_line);
2641   assuan_register_option_handler (ctx, option_handler);
2642   assuan_register_reset_notify (ctx, reset_notify);
2643
2644   for (;;)
2645     {
2646       rc = assuan_accept (ctx);
2647       if (rc == -1)
2648         break;
2649       if (rc)
2650         {
2651           log_info (_("Assuan accept problem: %s\n"), gpg_strerror (rc));
2652           break;
2653         }
2654
2655 #ifndef HAVE_W32_SYSTEM
2656       if (opt.verbose)
2657         {
2658           assuan_peercred_t peercred;
2659
2660           if (!assuan_get_peercred (ctx, &peercred))
2661             log_info ("connection from process %ld (%ld:%ld)\n",
2662                       (long)peercred->pid, (long)peercred->uid,
2663                       (long)peercred->gid);
2664         }
2665 #endif
2666
2667       rc = assuan_process (ctx);
2668       if (rc)
2669         {
2670           log_info (_("Assuan processing failed: %s\n"), gpg_strerror (rc));
2671           continue;
2672         }
2673     }
2674
2675
2676 #if USE_LDAP
2677   ldap_wrapper_connection_cleanup (ctrl);
2678
2679   ldapserver_list_free (ctrl->server_local->ldapservers);
2680 #endif /*USE_LDAP*/
2681   ctrl->server_local->ldapservers = NULL;
2682
2683   release_ctrl_keyservers (ctrl);
2684
2685   ctrl->server_local->assuan_ctx = NULL;
2686   assuan_release (ctx);
2687
2688   if (ctrl->server_local->stopme)
2689     dirmngr_exit (0);
2690
2691   if (ctrl->refcount)
2692     log_error ("oops: connection control structure still referenced (%d)\n",
2693                ctrl->refcount);
2694   else
2695     {
2696       release_ctrl_ocsp_certs (ctrl);
2697       xfree (ctrl->server_local);
2698       dirmngr_deinit_default_ctrl (ctrl);
2699       xfree (ctrl);
2700     }
2701 }
2702
2703
2704 /* Send a status line back to the client.  KEYWORD is the status
2705    keyword, the optional string arguments are blank separated added to
2706    the line, the last argument must be a NULL. */
2707 gpg_error_t
2708 dirmngr_status (ctrl_t ctrl, const char *keyword, ...)
2709 {
2710   gpg_error_t err = 0;
2711   va_list arg_ptr;
2712   const char *text;
2713
2714   va_start (arg_ptr, keyword);
2715
2716   if (ctrl->server_local)
2717     {
2718       assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2719       char buf[950], *p;
2720       size_t n;
2721
2722       p = buf;
2723       n = 0;
2724       while ( (text = va_arg (arg_ptr, const char *)) )
2725         {
2726           if (n)
2727             {
2728               *p++ = ' ';
2729               n++;
2730             }
2731           for ( ; *text && n < DIM (buf)-2; n++)
2732             *p++ = *text++;
2733         }
2734       *p = 0;
2735       err = assuan_write_status (ctx, keyword, buf);
2736     }
2737
2738   va_end (arg_ptr);
2739   return err;
2740 }
2741
2742
2743 /* Print a help status line.  TEXTLEN gives the length of the text
2744    from TEXT to be printed.  The function splits text at LFs.  */
2745 gpg_error_t
2746 dirmngr_status_help (ctrl_t ctrl, const char *text)
2747 {
2748   gpg_error_t err = 0;
2749
2750   if (ctrl->server_local)
2751     {
2752       assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2753       char buf[950], *p;
2754       size_t n;
2755
2756       do
2757         {
2758           p = buf;
2759           n = 0;
2760           for ( ; *text && *text != '\n' && n < DIM (buf)-2; n++)
2761             *p++ = *text++;
2762           if (*text == '\n')
2763             text++;
2764           *p = 0;
2765           err = assuan_write_status (ctx, "#", buf);
2766         }
2767       while (!err && *text);
2768     }
2769
2770   return err;
2771 }
2772
2773 /* Send a tick progress indicator back.  Fixme: This is only done for
2774    the currently active channel.  */
2775 gpg_error_t
2776 dirmngr_tick (ctrl_t ctrl)
2777 {
2778   static time_t next_tick = 0;
2779   gpg_error_t err = 0;
2780   time_t now = time (NULL);
2781
2782   if (!next_tick)
2783     {
2784       next_tick = now + 1;
2785     }
2786   else if ( now > next_tick )
2787     {
2788       if (ctrl)
2789         {
2790           err = dirmngr_status (ctrl, "PROGRESS", "tick", "? 0 0", NULL);
2791           if (err)
2792             {
2793               /* Take this as in indication for a cancel request.  */
2794               err = gpg_error (GPG_ERR_CANCELED);
2795             }
2796           now = time (NULL);
2797         }
2798
2799       next_tick = now + 1;
2800     }
2801   return err;
2802 }