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