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