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