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