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