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