Imported Upstream version 2.1.10
[platform/upstream/gpg2.git] / dirmngr / server.c
1 /* server.c - LDAP and Keyserver access server
2  * Copyright (C) 2002 Klarälvdalens Datakonsult AB
3  * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2011, 2015 g10 Code GmbH
4  * Copyright (C) 2014 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   "dnsinfo     - Return info about the DNS resolver\n"
2194   "socket_name - Return the name of the socket.\n";
2195 static gpg_error_t
2196 cmd_getinfo (assuan_context_t ctx, char *line)
2197 {
2198   ctrl_t ctrl = assuan_get_pointer (ctx);
2199   gpg_error_t err;
2200
2201   if (!strcmp (line, "version"))
2202     {
2203       const char *s = VERSION;
2204       err = assuan_send_data (ctx, s, strlen (s));
2205     }
2206   else if (!strcmp (line, "pid"))
2207     {
2208       char numbuf[50];
2209
2210       snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
2211       err = assuan_send_data (ctx, numbuf, strlen (numbuf));
2212     }
2213   else if (!strcmp (line, "socket_name"))
2214     {
2215       const char *s = dirmngr_user_socket_name ();
2216
2217       if (!s)
2218         s = dirmngr_sys_socket_name ();
2219
2220       if (s)
2221         err = assuan_send_data (ctx, s, strlen (s));
2222       else
2223         err = gpg_error (GPG_ERR_NO_DATA);
2224     }
2225   else if (!strcmp (line, "tor"))
2226     {
2227       if (opt.use_tor)
2228         {
2229           if (!is_tor_running (ctrl))
2230             err = assuan_write_status (ctx, "NO_TOR", "Tor not running");
2231           else
2232             err = 0;
2233           if (!err)
2234             assuan_set_okay_line (ctx, "- Tor mode is enabled");
2235         }
2236       else
2237         err = set_error (GPG_ERR_FALSE, "Tor mode is NOT enabled");
2238     }
2239   else if (!strcmp (line, "dnsinfo"))
2240     {
2241 #if USE_ADNS && HAVE_ADNS_IF_TORMODE
2242       assuan_set_okay_line (ctx, "- ADNS with Tor support");
2243 #elif USE_ADNS
2244       assuan_set_okay_line (ctx, "- ADNS w/o Tor support");
2245 #else
2246       assuan_set_okay_line (ctx, "- System resolver w/o Tor support");
2247 #endif
2248       err = 0;
2249     }
2250   else
2251     err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
2252
2253   return leave_cmd (ctx, err);
2254 }
2255
2256
2257 \f
2258 static const char hlp_killdirmngr[] =
2259   "KILLDIRMNGR\n"
2260   "\n"
2261   "This command allows a user - given sufficient permissions -\n"
2262   "to kill this dirmngr process.\n";
2263 static gpg_error_t
2264 cmd_killdirmngr (assuan_context_t ctx, char *line)
2265 {
2266   ctrl_t ctrl = assuan_get_pointer (ctx);
2267   gpg_error_t err;
2268
2269   (void)line;
2270
2271   if (opt.system_daemon)
2272     {
2273       if (opt.system_service)
2274         err = set_error (GPG_ERR_NOT_SUPPORTED,
2275                          "can't do that whilst running as system service");
2276       else
2277         err = check_owner_permission (ctx,
2278                                       "no permission to kill this process");
2279     }
2280   else
2281     err = 0;
2282
2283   if (!err)
2284     {
2285       ctrl->server_local->stopme = 1;
2286       assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
2287       err = gpg_error (GPG_ERR_EOF);
2288     }
2289   return err;
2290 }
2291
2292
2293 static const char hlp_reloaddirmngr[] =
2294   "RELOADDIRMNGR\n"
2295   "\n"
2296   "This command is an alternative to SIGHUP\n"
2297   "to reload the configuration.";
2298 static gpg_error_t
2299 cmd_reloaddirmngr (assuan_context_t ctx, char *line)
2300 {
2301   (void)ctx;
2302   (void)line;
2303
2304  if (opt.system_daemon)
2305     {
2306 #ifndef HAVE_W32_SYSTEM
2307       {
2308         gpg_error_t err;
2309
2310         err = check_owner_permission (ctx,
2311                                       "no permission to reload this process");
2312         if (err)
2313           return err;
2314       }
2315 #endif
2316     }
2317
2318   dirmngr_sighup_action ();
2319   return 0;
2320 }
2321
2322
2323
2324 \f
2325 /* Tell the assuan library about our commands. */
2326 static int
2327 register_commands (assuan_context_t ctx)
2328 {
2329   static struct {
2330     const char *name;
2331     assuan_handler_t handler;
2332     const char * const help;
2333   } table[] = {
2334     { "DNS_CERT",   cmd_dns_cert,   hlp_dns_cert },
2335     { "LDAPSERVER", cmd_ldapserver, hlp_ldapserver },
2336     { "ISVALID",    cmd_isvalid,    hlp_isvalid },
2337     { "CHECKCRL",   cmd_checkcrl,   hlp_checkcrl },
2338     { "CHECKOCSP",  cmd_checkocsp,  hlp_checkocsp },
2339     { "LOOKUP",     cmd_lookup,     hlp_lookup },
2340     { "LOADCRL",    cmd_loadcrl,    hlp_loadcrl },
2341     { "LISTCRLS",   cmd_listcrls,   hlp_listcrls },
2342     { "CACHECERT",  cmd_cachecert,  hlp_cachecert },
2343     { "VALIDATE",   cmd_validate,   hlp_validate },
2344     { "KEYSERVER",  cmd_keyserver,  hlp_keyserver },
2345     { "KS_SEARCH",  cmd_ks_search,  hlp_ks_search },
2346     { "KS_GET",     cmd_ks_get,     hlp_ks_get },
2347     { "KS_FETCH",   cmd_ks_fetch,   hlp_ks_fetch },
2348     { "KS_PUT",     cmd_ks_put,     hlp_ks_put },
2349     { "GETINFO",    cmd_getinfo,    hlp_getinfo },
2350     { "KILLDIRMNGR",cmd_killdirmngr,hlp_killdirmngr },
2351     { "RELOADDIRMNGR",cmd_reloaddirmngr,hlp_reloaddirmngr },
2352     { NULL, NULL }
2353   };
2354   int i, j, rc;
2355
2356   for (i=j=0; table[i].name; i++)
2357     {
2358       rc = assuan_register_command (ctx, table[i].name, table[i].handler,
2359                                     table[i].help);
2360       if (rc)
2361         return rc;
2362     }
2363   return 0;
2364 }
2365
2366
2367 /* Note that we do not reset the list of configured keyservers.  */
2368 static gpg_error_t
2369 reset_notify (assuan_context_t ctx, char *line)
2370 {
2371   ctrl_t ctrl = assuan_get_pointer (ctx);
2372   (void)line;
2373
2374 #if USE_LDAP
2375   ldapserver_list_free (ctrl->server_local->ldapservers);
2376 #endif /*USE_LDAP*/
2377   ctrl->server_local->ldapservers = NULL;
2378   return 0;
2379 }
2380
2381
2382 /* Startup the server and run the main command loop.  With FD = -1,
2383    use stdin/stdout. */
2384 void
2385 start_command_handler (assuan_fd_t fd)
2386 {
2387   static const char hello[] = "Dirmngr " VERSION " at your service";
2388   static char *hello_line;
2389   int rc;
2390   assuan_context_t ctx;
2391   ctrl_t ctrl;
2392
2393   ctrl = xtrycalloc (1, sizeof *ctrl);
2394   if (ctrl)
2395     ctrl->server_local = xtrycalloc (1, sizeof *ctrl->server_local);
2396   if (!ctrl || !ctrl->server_local)
2397     {
2398       log_error (_("can't allocate control structure: %s\n"),
2399                  strerror (errno));
2400       xfree (ctrl);
2401       return;
2402     }
2403
2404   dirmngr_init_default_ctrl (ctrl);
2405
2406   rc = assuan_new (&ctx);
2407   if (rc)
2408     {
2409       log_error (_("failed to allocate assuan context: %s\n"),
2410                  gpg_strerror (rc));
2411       dirmngr_exit (2);
2412     }
2413
2414   if (fd == ASSUAN_INVALID_FD)
2415     {
2416       assuan_fd_t filedes[2];
2417
2418       filedes[0] = assuan_fdopen (0);
2419       filedes[1] = assuan_fdopen (1);
2420       rc = assuan_init_pipe_server (ctx, filedes);
2421     }
2422   else
2423     {
2424       rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED);
2425     }
2426
2427   if (rc)
2428     {
2429       assuan_release (ctx);
2430       log_error (_("failed to initialize the server: %s\n"),
2431                  gpg_strerror(rc));
2432       dirmngr_exit (2);
2433     }
2434
2435   rc = register_commands (ctx);
2436   if (rc)
2437     {
2438       log_error (_("failed to the register commands with Assuan: %s\n"),
2439                  gpg_strerror(rc));
2440       dirmngr_exit (2);
2441     }
2442
2443
2444   if (!hello_line)
2445     {
2446       size_t n;
2447       const char *cfgname;
2448
2449       cfgname = opt.config_filename? opt.config_filename : "[none]";
2450
2451       n = (30 + strlen (opt.homedir) + strlen (cfgname)
2452            + strlen (hello) + 1);
2453       hello_line = xmalloc (n+1);
2454       snprintf (hello_line, n,
2455                 "Home: %s\n"
2456                 "Config: %s\n"
2457                 "%s",
2458                 opt.homedir,
2459                 cfgname,
2460                 hello);
2461       hello_line[n] = 0;
2462     }
2463
2464   ctrl->server_local->assuan_ctx = ctx;
2465   assuan_set_pointer (ctx, ctrl);
2466
2467   assuan_set_hello_line (ctx, hello_line);
2468   assuan_register_option_handler (ctx, option_handler);
2469   assuan_register_reset_notify (ctx, reset_notify);
2470
2471   for (;;)
2472     {
2473       rc = assuan_accept (ctx);
2474       if (rc == -1)
2475         break;
2476       if (rc)
2477         {
2478           log_info (_("Assuan accept problem: %s\n"), gpg_strerror (rc));
2479           break;
2480         }
2481
2482 #ifndef HAVE_W32_SYSTEM
2483       if (opt.verbose)
2484         {
2485           assuan_peercred_t peercred;
2486
2487           if (!assuan_get_peercred (ctx, &peercred))
2488             log_info ("connection from process %ld (%ld:%ld)\n",
2489                       (long)peercred->pid, (long)peercred->uid,
2490                       (long)peercred->gid);
2491         }
2492 #endif
2493
2494       rc = assuan_process (ctx);
2495       if (rc)
2496         {
2497           log_info (_("Assuan processing failed: %s\n"), gpg_strerror (rc));
2498           continue;
2499         }
2500     }
2501
2502
2503 #if USE_LDAP
2504   ldap_wrapper_connection_cleanup (ctrl);
2505
2506   ldapserver_list_free (ctrl->server_local->ldapservers);
2507 #endif /*USE_LDAP*/
2508   ctrl->server_local->ldapservers = NULL;
2509
2510   release_ctrl_keyservers (ctrl);
2511
2512   ctrl->server_local->assuan_ctx = NULL;
2513   assuan_release (ctx);
2514
2515   if (ctrl->server_local->stopme)
2516     dirmngr_exit (0);
2517
2518   if (ctrl->refcount)
2519     log_error ("oops: connection control structure still referenced (%d)\n",
2520                ctrl->refcount);
2521   else
2522     {
2523       release_ctrl_ocsp_certs (ctrl);
2524       xfree (ctrl->server_local);
2525       dirmngr_deinit_default_ctrl (ctrl);
2526       xfree (ctrl);
2527     }
2528 }
2529
2530
2531 /* Send a status line back to the client.  KEYWORD is the status
2532    keyword, the optional string arguments are blank separated added to
2533    the line, the last argument must be a NULL. */
2534 gpg_error_t
2535 dirmngr_status (ctrl_t ctrl, const char *keyword, ...)
2536 {
2537   gpg_error_t err = 0;
2538   va_list arg_ptr;
2539   const char *text;
2540
2541   va_start (arg_ptr, keyword);
2542
2543   if (ctrl->server_local)
2544     {
2545       assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2546       char buf[950], *p;
2547       size_t n;
2548
2549       p = buf;
2550       n = 0;
2551       while ( (text = va_arg (arg_ptr, const char *)) )
2552         {
2553           if (n)
2554             {
2555               *p++ = ' ';
2556               n++;
2557             }
2558           for ( ; *text && n < DIM (buf)-2; n++)
2559             *p++ = *text++;
2560         }
2561       *p = 0;
2562       err = assuan_write_status (ctx, keyword, buf);
2563     }
2564
2565   va_end (arg_ptr);
2566   return err;
2567 }
2568
2569
2570 /* Print a help status line.  TEXTLEN gives the length of the text
2571    from TEXT to be printed.  The function splits text at LFs.  */
2572 gpg_error_t
2573 dirmngr_status_help (ctrl_t ctrl, const char *text)
2574 {
2575   gpg_error_t err = 0;
2576
2577   if (ctrl->server_local)
2578     {
2579       assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2580       char buf[950], *p;
2581       size_t n;
2582
2583       do
2584         {
2585           p = buf;
2586           n = 0;
2587           for ( ; *text && *text != '\n' && n < DIM (buf)-2; n++)
2588             *p++ = *text++;
2589           if (*text == '\n')
2590             text++;
2591           *p = 0;
2592           err = assuan_write_status (ctx, "#", buf);
2593         }
2594       while (!err && *text);
2595     }
2596
2597   return err;
2598 }
2599
2600 /* Send a tick progress indicator back.  Fixme: This is only done for
2601    the currently active channel.  */
2602 gpg_error_t
2603 dirmngr_tick (ctrl_t ctrl)
2604 {
2605   static time_t next_tick = 0;
2606   gpg_error_t err = 0;
2607   time_t now = time (NULL);
2608
2609   if (!next_tick)
2610     {
2611       next_tick = now + 1;
2612     }
2613   else if ( now > next_tick )
2614     {
2615       if (ctrl)
2616         {
2617           err = dirmngr_status (ctrl, "PROGRESS", "tick", "? 0 0", NULL);
2618           if (err)
2619             {
2620               /* Take this as in indication for a cancel request.  */
2621               err = gpg_error (GPG_ERR_CANCELED);
2622             }
2623           now = time (NULL);
2624         }
2625
2626       next_tick = now + 1;
2627     }
2628   return err;
2629 }