Change capitalization of TOR to Tor.
[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
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 && enable_dns_tormode ())
717     {
718       /* Tor mode is requested but the DNS code can't enable it.  */
719       err = gpg_error (GPG_ERR_FORBIDDEN);
720       goto leave;
721     }
722
723   if (pka_mode || dane_mode)
724     {
725       char *domain;     /* Points to mbox.  */
726       char hashbuf[32]; /* For SHA-1 and SHA-256. */
727
728       /* We lowercase ascii characters but the DANE I-D does not allow
729          this.  FIXME: Check after the release of the RFC whether to
730          change this.  */
731       mbox = mailbox_from_userid (line);
732       if (!mbox || !(domain = strchr (mbox, '@')))
733         {
734           err = set_error (GPG_ERR_INV_USER_ID, "no mailbox in user id");
735           goto leave;
736         }
737       *domain++ = 0;
738
739       if (pka_mode)
740         {
741           gcry_md_hash_buffer (GCRY_MD_SHA1, hashbuf, mbox, strlen (mbox));
742           encodedhash = zb32_encode (hashbuf, 8*20);
743           if (!encodedhash)
744             {
745               err = gpg_error_from_syserror ();
746               goto leave;
747             }
748           namebuf = strconcat (encodedhash, "._pka.", domain, NULL);
749           if (!namebuf)
750             {
751               err = gpg_error_from_syserror ();
752               goto leave;
753             }
754           name = namebuf;
755           certtype = DNS_CERTTYPE_IPGP;
756         }
757       else
758         {
759           /* Note: The hash is truncated to 28 bytes and we lowercase
760              the result only for aesthetic reasons.  */
761           gcry_md_hash_buffer (GCRY_MD_SHA256, hashbuf, mbox, strlen (mbox));
762           encodedhash = bin2hex (hashbuf, 28, NULL);
763           if (!encodedhash)
764             {
765               err = gpg_error_from_syserror ();
766               goto leave;
767             }
768           ascii_strlwr (encodedhash);
769           namebuf = strconcat (encodedhash, "._openpgpkey.", domain, NULL);
770           if (!namebuf)
771             {
772               err = gpg_error_from_syserror ();
773               goto leave;
774             }
775           name = namebuf;
776           certtype = DNS_CERTTYPE_RR61;
777         }
778     }
779   else
780     name = line;
781
782   err = get_dns_cert (name, certtype, &key, &keylen, &fpr, &fprlen, &url);
783   if (err)
784     goto leave;
785
786   if (key)
787     {
788       err = data_line_write (ctx, key, keylen);
789       if (err)
790         goto leave;
791     }
792
793   if (fpr)
794     {
795       char *tmpstr;
796
797       tmpstr = bin2hex (fpr, fprlen, NULL);
798       if (!tmpstr)
799         err = gpg_error_from_syserror ();
800       else
801         {
802           err = assuan_write_status (ctx, "FPR", tmpstr);
803           xfree (tmpstr);
804         }
805       if (err)
806         goto leave;
807     }
808
809   if (url)
810     {
811       err = assuan_write_status (ctx, "URL", url);
812       if (err)
813         goto leave;
814     }
815
816
817  leave:
818   xfree (key);
819   xfree (fpr);
820   xfree (url);
821   xfree (mbox);
822   xfree (namebuf);
823   xfree (encodedhash);
824   return leave_cmd (ctx, err);
825 }
826
827
828 \f
829 static const char hlp_ldapserver[] =
830   "LDAPSERVER <data>\n"
831   "\n"
832   "Add a new LDAP server to the list of configured LDAP servers.\n"
833   "DATA is in the same format as expected in the configure file.";
834 static gpg_error_t
835 cmd_ldapserver (assuan_context_t ctx, char *line)
836 {
837 #if USE_LDAP
838   ctrl_t ctrl = assuan_get_pointer (ctx);
839   ldap_server_t server;
840   ldap_server_t *last_next_p;
841
842   while (spacep (line))
843     line++;
844   if (*line == '\0')
845     return leave_cmd (ctx, PARM_ERROR (_("ldapserver missing")));
846
847   server = ldapserver_parse_one (line, "", 0);
848   if (! server)
849     return leave_cmd (ctx, gpg_error (GPG_ERR_INV_ARG));
850
851   last_next_p = &ctrl->server_local->ldapservers;
852   while (*last_next_p)
853     last_next_p = &(*last_next_p)->next;
854   *last_next_p = server;
855   return leave_cmd (ctx, 0);
856 #else
857   (void)line;
858   return leave_cmd (ctx, gpg_error (GPG_ERR_NOT_IMPLEMENTED));
859 #endif
860 }
861
862
863 static const char hlp_isvalid[] =
864   "ISVALID [--only-ocsp] [--force-default-responder]"
865   " <certificate_id>|<certificate_fpr>\n"
866   "\n"
867   "This command checks whether the certificate identified by the\n"
868   "certificate_id is valid.  This is done by consulting CRLs or\n"
869   "whatever has been configured.  Note, that the returned error codes\n"
870   "are from gpg-error.h.  The command may callback using the inquire\n"
871   "function.  See the manual for details.\n"
872   "\n"
873   "The CERTIFICATE_ID is a hex encoded string consisting of two parts,\n"
874   "delimited by a single dot.  The first part is the SHA-1 hash of the\n"
875   "issuer name and the second part the serial number.\n"
876   "\n"
877   "Alternatively the certificate's fingerprint may be given in which\n"
878   "case an OCSP request is done before consulting the CRL.\n"
879   "\n"
880   "If the option --only-ocsp is given, no fallback to a CRL check will\n"
881   "be used.\n"
882   "\n"
883   "If the option --force-default-responder is given, only the default\n"
884   "OCSP responder will be used and any other methods of obtaining an\n"
885   "OCSP responder URL won't be used.";
886 static gpg_error_t
887 cmd_isvalid (assuan_context_t ctx, char *line)
888 {
889   ctrl_t ctrl = assuan_get_pointer (ctx);
890   char *issuerhash, *serialno;
891   gpg_error_t err;
892   int did_inquire = 0;
893   int ocsp_mode = 0;
894   int only_ocsp;
895   int force_default_responder;
896
897   only_ocsp = has_option (line, "--only-ocsp");
898   force_default_responder = has_option (line, "--force-default-responder");
899   line = skip_options (line);
900
901   issuerhash = xstrdup (line); /* We need to work on a copy of the
902                                   line because that same Assuan
903                                   context may be used for an inquiry.
904                                   That is because Assuan reuses its
905                                   line buffer.
906                                    */
907
908   serialno = strchr (issuerhash, '.');
909   if (serialno)
910     *serialno++ = 0;
911   else
912     {
913       char *endp = strchr (issuerhash, ' ');
914       if (endp)
915         *endp = 0;
916       if (strlen (issuerhash) != 40)
917         {
918           xfree (issuerhash);
919           return leave_cmd (ctx, PARM_ERROR (_("serialno missing in cert ID")));
920         }
921       ocsp_mode = 1;
922     }
923
924
925  again:
926   if (ocsp_mode)
927     {
928       /* Note, that we ignore the given issuer hash and instead rely
929          on the current certificate semantics used with this
930          command. */
931       if (!opt.allow_ocsp)
932         err = gpg_error (GPG_ERR_NOT_SUPPORTED);
933       else
934         err = ocsp_isvalid (ctrl, NULL, NULL, force_default_responder);
935       /* Fixme: If we got no ocsp response and --only-ocsp is not used
936          we should fall back to CRL mode.  Thus we need to clear
937          OCSP_MODE, get the issuerhash and the serialno from the
938          current certificate and jump to again. */
939     }
940   else if (only_ocsp)
941     err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
942   else
943     {
944       switch (crl_cache_isvalid (ctrl,
945                                  issuerhash, serialno,
946                                  ctrl->force_crl_refresh))
947         {
948         case CRL_CACHE_VALID:
949           err = 0;
950           break;
951         case CRL_CACHE_INVALID:
952           err = gpg_error (GPG_ERR_CERT_REVOKED);
953           break;
954         case CRL_CACHE_DONTKNOW:
955           if (did_inquire)
956             err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
957           else if (!(err = inquire_cert_and_load_crl (ctx)))
958             {
959               did_inquire = 1;
960               goto again;
961             }
962           break;
963         case CRL_CACHE_CANTUSE:
964           err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
965           break;
966         default:
967           log_fatal ("crl_cache_isvalid returned invalid code\n");
968         }
969     }
970
971   xfree (issuerhash);
972   return leave_cmd (ctx, err);
973 }
974
975
976 /* If the line contains a SHA-1 fingerprint as the first argument,
977    return the FPR vuffer on success.  The function checks that the
978    fingerprint consists of valid characters and prints and error
979    message if it does not and returns NULL.  Fingerprints are
980    considered optional and thus no explicit error is returned. NULL is
981    also returned if there is no fingerprint at all available.
982    FPR must be a caller provided buffer of at least 20 bytes.
983
984    Note that colons within the fingerprint are allowed to separate 2
985    hex digits; this allows for easier cutting and pasting using the
986    usual fingerprint rendering.
987 */
988 static unsigned char *
989 get_fingerprint_from_line (const char *line, unsigned char *fpr)
990 {
991   const char *s;
992   int i;
993
994   for (s=line, i=0; *s && *s != ' '; s++ )
995     {
996       if ( hexdigitp (s) && hexdigitp (s+1) )
997         {
998           if ( i >= 20 )
999             return NULL;  /* Fingerprint too long.  */
1000           fpr[i++] = xtoi_2 (s);
1001           s++;
1002         }
1003       else if ( *s != ':' )
1004         return NULL; /* Invalid.  */
1005     }
1006   if ( i != 20 )
1007     return NULL; /* Fingerprint to short.  */
1008   return fpr;
1009 }
1010
1011
1012
1013 static const char hlp_checkcrl[] =
1014   "CHECKCRL [<fingerprint>]\n"
1015   "\n"
1016   "Check whether the certificate with FINGERPRINT (SHA-1 hash of the\n"
1017   "entire X.509 certificate blob) is valid or not by consulting the\n"
1018   "CRL responsible for this certificate.  If the fingerprint has not\n"
1019   "been given or the certificate is not known, the function \n"
1020   "inquires the certificate using an\n"
1021   "\n"
1022   "  INQUIRE TARGETCERT\n"
1023   "\n"
1024   "and the caller is expected to return the certificate for the\n"
1025   "request (which should match FINGERPRINT) as a binary blob.\n"
1026   "Processing then takes place without further interaction; in\n"
1027   "particular dirmngr tries to locate other required certificate by\n"
1028   "its own mechanism which includes a local certificate store as well\n"
1029   "as a list of trusted root certificates.\n"
1030   "\n"
1031   "The return value is the usual gpg-error code or 0 for ducesss;\n"
1032   "i.e. the certificate validity has been confirmed by a valid CRL.";
1033 static gpg_error_t
1034 cmd_checkcrl (assuan_context_t ctx, char *line)
1035 {
1036   ctrl_t ctrl = assuan_get_pointer (ctx);
1037   gpg_error_t err;
1038   unsigned char fprbuffer[20], *fpr;
1039   ksba_cert_t cert;
1040
1041   fpr = get_fingerprint_from_line (line, fprbuffer);
1042   cert = fpr? get_cert_byfpr (fpr) : NULL;
1043
1044   if (!cert)
1045     {
1046       /* We do not have this certificate yet or the fingerprint has
1047          not been given.  Inquire it from the client.  */
1048       unsigned char *value = NULL;
1049       size_t valuelen;
1050
1051       err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1052                            &value, &valuelen, MAX_CERT_LENGTH);
1053       if (err)
1054         {
1055           log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1056           goto leave;
1057         }
1058
1059       if (!valuelen) /* No data returned; return a comprehensible error. */
1060         err = gpg_error (GPG_ERR_MISSING_CERT);
1061       else
1062         {
1063           err = ksba_cert_new (&cert);
1064           if (!err)
1065             err = ksba_cert_init_from_mem (cert, value, valuelen);
1066         }
1067       xfree (value);
1068       if(err)
1069         goto leave;
1070     }
1071
1072   assert (cert);
1073
1074   err = crl_cache_cert_isvalid (ctrl, cert, ctrl->force_crl_refresh);
1075   if (gpg_err_code (err) == GPG_ERR_NO_CRL_KNOWN)
1076     {
1077       err = crl_cache_reload_crl (ctrl, cert);
1078       if (!err)
1079         err = crl_cache_cert_isvalid (ctrl, cert, 0);
1080     }
1081
1082  leave:
1083   ksba_cert_release (cert);
1084   return leave_cmd (ctx, err);
1085 }
1086
1087
1088 static const char hlp_checkocsp[] =
1089   "CHECKOCSP [--force-default-responder] [<fingerprint>]\n"
1090   "\n"
1091   "Check whether the certificate with FINGERPRINT (SHA-1 hash of the\n"
1092   "entire X.509 certificate blob) is valid or not by asking an OCSP\n"
1093   "responder responsible for this certificate.  The optional\n"
1094   "fingerprint may be used for a quick check in case an OCSP check has\n"
1095   "been done for this certificate recently (we always cache OCSP\n"
1096   "responses for a couple of minutes). If the fingerprint has not been\n"
1097   "given or there is no cached result, the function inquires the\n"
1098   "certificate using an\n"
1099   "\n"
1100   "   INQUIRE TARGETCERT\n"
1101   "\n"
1102   "and the caller is expected to return the certificate for the\n"
1103   "request (which should match FINGERPRINT) as a binary blob.\n"
1104   "Processing then takes place without further interaction; in\n"
1105   "particular dirmngr tries to locate other required certificates by\n"
1106   "its own mechanism which includes a local certificate store as well\n"
1107   "as a list of trusted root certifciates.\n"
1108   "\n"
1109   "If the option --force-default-responder is given, only the default\n"
1110   "OCSP responder will be used and any other methods of obtaining an\n"
1111   "OCSP responder URL won't be used.\n"
1112   "\n"
1113   "The return value is the usual gpg-error code or 0 for ducesss;\n"
1114   "i.e. the certificate validity has been confirmed by a valid CRL.";
1115 static gpg_error_t
1116 cmd_checkocsp (assuan_context_t ctx, char *line)
1117 {
1118   ctrl_t ctrl = assuan_get_pointer (ctx);
1119   gpg_error_t err;
1120   unsigned char fprbuffer[20], *fpr;
1121   ksba_cert_t cert;
1122   int force_default_responder;
1123
1124   force_default_responder = has_option (line, "--force-default-responder");
1125   line = skip_options (line);
1126
1127   fpr = get_fingerprint_from_line (line, fprbuffer);
1128   cert = fpr? get_cert_byfpr (fpr) : NULL;
1129
1130   if (!cert)
1131     {
1132       /* We do not have this certificate yet or the fingerprint has
1133          not been given.  Inquire it from the client.  */
1134       unsigned char *value = NULL;
1135       size_t valuelen;
1136
1137       err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1138                            &value, &valuelen, MAX_CERT_LENGTH);
1139       if (err)
1140         {
1141           log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1142           goto leave;
1143         }
1144
1145       if (!valuelen) /* No data returned; return a comprehensible error. */
1146         err = gpg_error (GPG_ERR_MISSING_CERT);
1147       else
1148         {
1149           err = ksba_cert_new (&cert);
1150           if (!err)
1151             err = ksba_cert_init_from_mem (cert, value, valuelen);
1152         }
1153       xfree (value);
1154       if(err)
1155         goto leave;
1156     }
1157
1158   assert (cert);
1159
1160   if (!opt.allow_ocsp)
1161     err = gpg_error (GPG_ERR_NOT_SUPPORTED);
1162   else
1163     err = ocsp_isvalid (ctrl, cert, NULL, force_default_responder);
1164
1165  leave:
1166   ksba_cert_release (cert);
1167   return leave_cmd (ctx, err);
1168 }
1169
1170
1171
1172 static int
1173 lookup_cert_by_url (assuan_context_t ctx, const char *url)
1174 {
1175   ctrl_t ctrl = assuan_get_pointer (ctx);
1176   gpg_error_t err = 0;
1177   unsigned char *value = NULL;
1178   size_t valuelen;
1179
1180   /* Fetch single certificate given it's URL.  */
1181   err = fetch_cert_by_url (ctrl, url, &value, &valuelen);
1182   if (err)
1183     {
1184       log_error (_("fetch_cert_by_url failed: %s\n"), gpg_strerror (err));
1185       goto leave;
1186     }
1187
1188   /* Send the data, flush the buffer and then send an END. */
1189   err = assuan_send_data (ctx, value, valuelen);
1190   if (!err)
1191     err = assuan_send_data (ctx, NULL, 0);
1192   if (!err)
1193     err = assuan_write_line (ctx, "END");
1194   if (err)
1195     {
1196       log_error (_("error sending data: %s\n"), gpg_strerror (err));
1197       goto leave;
1198     }
1199
1200  leave:
1201
1202   return err;
1203 }
1204
1205
1206 /* Send the certificate, flush the buffer and then send an END. */
1207 static gpg_error_t
1208 return_one_cert (void *opaque, ksba_cert_t cert)
1209 {
1210   assuan_context_t ctx = opaque;
1211   gpg_error_t err;
1212   const unsigned char *der;
1213   size_t derlen;
1214
1215   der = ksba_cert_get_image (cert, &derlen);
1216   if (!der)
1217     err = gpg_error (GPG_ERR_INV_CERT_OBJ);
1218   else
1219     {
1220       err = assuan_send_data (ctx, der, derlen);
1221       if (!err)
1222         err = assuan_send_data (ctx, NULL, 0);
1223       if (!err)
1224         err = assuan_write_line (ctx, "END");
1225     }
1226   if (err)
1227     log_error (_("error sending data: %s\n"), gpg_strerror (err));
1228   return err;
1229 }
1230
1231
1232 /* Lookup certificates from the internal cache or using the ldap
1233    servers. */
1234 static int
1235 lookup_cert_by_pattern (assuan_context_t ctx, char *line,
1236                         int single, int cache_only)
1237 {
1238   gpg_error_t err = 0;
1239   char *p;
1240   strlist_t sl, list = NULL;
1241   int truncated = 0, truncation_forced = 0;
1242   int count = 0;
1243   int local_count = 0;
1244 #if USE_LDAP
1245   ctrl_t ctrl = assuan_get_pointer (ctx);
1246   unsigned char *value = NULL;
1247   size_t valuelen;
1248   struct ldapserver_iter ldapserver_iter;
1249   cert_fetch_context_t fetch_context;
1250 #endif /*USE_LDAP*/
1251   int any_no_data = 0;
1252
1253   /* Break the line down into an STRLIST */
1254   for (p=line; *p; line = p)
1255     {
1256       while (*p && *p != ' ')
1257         p++;
1258       if (*p)
1259         *p++ = 0;
1260
1261       if (*line)
1262         {
1263           sl = xtrymalloc (sizeof *sl + strlen (line));
1264           if (!sl)
1265             {
1266               err = gpg_error_from_errno (errno);
1267               goto leave;
1268             }
1269           memset (sl, 0, sizeof *sl);
1270           strcpy_escaped_plus (sl->d, line);
1271           sl->next = list;
1272           list = sl;
1273         }
1274     }
1275
1276   /* First look through the internal cache.  The certifcates retruned
1277      here are not counted towards the truncation limit.  */
1278   if (single && !cache_only)
1279     ; /* Do not read from the local cache in this case.  */
1280   else
1281     {
1282       for (sl=list; sl; sl = sl->next)
1283         {
1284           err = get_certs_bypattern (sl->d, return_one_cert, ctx);
1285           if (!err)
1286             local_count++;
1287           if (!err && single)
1288             goto ready;
1289
1290           if (gpg_err_code (err) == GPG_ERR_NO_DATA)
1291             {
1292               err = 0;
1293               if (cache_only)
1294                 any_no_data = 1;
1295             }
1296           else if (gpg_err_code (err) == GPG_ERR_INV_NAME && !cache_only)
1297             {
1298               /* No real fault because the internal pattern lookup
1299                  can't yet cope with all types of pattern.  */
1300               err = 0;
1301             }
1302           if (err)
1303             goto ready;
1304         }
1305     }
1306
1307   /* Loop over all configured servers unless we want only the
1308      certificates from the cache.  */
1309 #if USE_LDAP
1310   for (ldapserver_iter_begin (&ldapserver_iter, ctrl);
1311        !cache_only && !ldapserver_iter_end_p (&ldapserver_iter)
1312          && ldapserver_iter.server->host && !truncation_forced;
1313        ldapserver_iter_next (&ldapserver_iter))
1314     {
1315       ldap_server_t ldapserver = ldapserver_iter.server;
1316
1317       if (DBG_LOOKUP)
1318         log_debug ("cmd_lookup: trying %s:%d base=%s\n",
1319                    ldapserver->host, ldapserver->port,
1320                    ldapserver->base?ldapserver->base : "[default]");
1321
1322       /* Fetch certificates matching pattern */
1323       err = start_cert_fetch (ctrl, &fetch_context, list, ldapserver);
1324       if ( gpg_err_code (err) == GPG_ERR_NO_DATA )
1325         {
1326           if (DBG_LOOKUP)
1327             log_debug ("cmd_lookup: no data\n");
1328           err = 0;
1329           any_no_data = 1;
1330           continue;
1331         }
1332       if (err)
1333         {
1334           log_error (_("start_cert_fetch failed: %s\n"), gpg_strerror (err));
1335           goto leave;
1336         }
1337
1338       /* Fetch the certificates for this query. */
1339       while (!truncation_forced)
1340         {
1341           xfree (value); value = NULL;
1342           err = fetch_next_cert (fetch_context, &value, &valuelen);
1343           if (gpg_err_code (err) == GPG_ERR_NO_DATA )
1344             {
1345               err = 0;
1346               any_no_data = 1;
1347               break; /* Ready. */
1348             }
1349           if (gpg_err_code (err) == GPG_ERR_TRUNCATED)
1350             {
1351               truncated = 1;
1352               err = 0;
1353               break;  /* Ready.  */
1354             }
1355           if (gpg_err_code (err) == GPG_ERR_EOF)
1356             {
1357               err = 0;
1358               break; /* Ready. */
1359             }
1360           if (!err && !value)
1361             {
1362               err = gpg_error (GPG_ERR_BUG);
1363               goto leave;
1364             }
1365           if (err)
1366             {
1367               log_error (_("fetch_next_cert failed: %s\n"),
1368                          gpg_strerror (err));
1369               end_cert_fetch (fetch_context);
1370               goto leave;
1371             }
1372
1373           if (DBG_LOOKUP)
1374             log_debug ("cmd_lookup: returning one cert%s\n",
1375                        truncated? " (truncated)":"");
1376
1377           /* Send the data, flush the buffer and then send an END line
1378              as a certificate delimiter. */
1379           err = assuan_send_data (ctx, value, valuelen);
1380           if (!err)
1381             err = assuan_send_data (ctx, NULL, 0);
1382           if (!err)
1383             err = assuan_write_line (ctx, "END");
1384           if (err)
1385             {
1386               log_error (_("error sending data: %s\n"), gpg_strerror (err));
1387               end_cert_fetch (fetch_context);
1388               goto leave;
1389             }
1390
1391           if (++count >= opt.max_replies )
1392             {
1393               truncation_forced = 1;
1394               log_info (_("max_replies %d exceeded\n"), opt.max_replies );
1395             }
1396           if (single)
1397             break;
1398         }
1399
1400       end_cert_fetch (fetch_context);
1401     }
1402 #endif /*USE_LDAP*/
1403
1404  ready:
1405   if (truncated || truncation_forced)
1406     {
1407       char str[50];
1408
1409       sprintf (str, "%d", count);
1410       assuan_write_status (ctx, "TRUNCATED", str);
1411     }
1412
1413   if (!err && !count && !local_count && any_no_data)
1414     err = gpg_error (GPG_ERR_NO_DATA);
1415
1416  leave:
1417   free_strlist (list);
1418   return err;
1419 }
1420
1421
1422 static const char hlp_lookup[] =
1423   "LOOKUP [--url] [--single] [--cache-only] <pattern>\n"
1424   "\n"
1425   "Lookup certificates matching PATTERN. With --url the pattern is\n"
1426   "expected to be one URL.\n"
1427   "\n"
1428   "If --url is not given:  To allow for multiple patterns (which are ORed)\n"
1429   "quoting is required: Spaces are translated to \"+\" or \"%20\";\n"
1430   "obviously this requires that the usual escape quoting rules are applied.\n"
1431   "\n"
1432   "If --url is given no special escaping is required because URLs are\n"
1433   "already escaped this way.\n"
1434   "\n"
1435   "If --single is given the first and only the first match will be\n"
1436   "returned.  If --cache-only is _not_ given, no local query will be\n"
1437   "done.\n"
1438   "\n"
1439   "If --cache-only is given no external lookup is done so that only\n"
1440   "certificates from the cache may get returned.";
1441 static gpg_error_t
1442 cmd_lookup (assuan_context_t ctx, char *line)
1443 {
1444   gpg_error_t err;
1445   int lookup_url, single, cache_only;
1446
1447   lookup_url = has_leading_option (line, "--url");
1448   single = has_leading_option (line, "--single");
1449   cache_only = has_leading_option (line, "--cache-only");
1450   line = skip_options (line);
1451
1452   if (lookup_url && cache_only)
1453     err = gpg_error (GPG_ERR_NOT_FOUND);
1454   else if (lookup_url && single)
1455     err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1456   else if (lookup_url)
1457     err = lookup_cert_by_url (ctx, line);
1458   else
1459     err = lookup_cert_by_pattern (ctx, line, single, cache_only);
1460
1461   return leave_cmd (ctx, err);
1462 }
1463
1464
1465 static const char hlp_loadcrl[] =
1466   "LOADCRL [--url] <filename|url>\n"
1467   "\n"
1468   "Load the CRL in the file with name FILENAME into our cache.  Note\n"
1469   "that FILENAME should be given with an absolute path because\n"
1470   "Dirmngrs cwd is not known.  With --url the CRL is directly loaded\n"
1471   "from the given URL.\n"
1472   "\n"
1473   "This command is usually used by gpgsm using the invocation \"gpgsm\n"
1474   "--call-dirmngr loadcrl <filename>\".  A direct invocation of Dirmngr\n"
1475   "is not useful because gpgsm might need to callback gpgsm to ask for\n"
1476   "the CA's certificate.";
1477 static gpg_error_t
1478 cmd_loadcrl (assuan_context_t ctx, char *line)
1479 {
1480   ctrl_t ctrl = assuan_get_pointer (ctx);
1481   gpg_error_t err = 0;
1482   int use_url = has_leading_option (line, "--url");
1483
1484   line = skip_options (line);
1485
1486   if (use_url)
1487     {
1488       ksba_reader_t reader;
1489
1490       err = crl_fetch (ctrl, line, &reader);
1491       if (err)
1492         log_error (_("fetching CRL from '%s' failed: %s\n"),
1493                    line, gpg_strerror (err));
1494       else
1495         {
1496           err = crl_cache_insert (ctrl, line, reader);
1497           if (err)
1498             log_error (_("processing CRL from '%s' failed: %s\n"),
1499                        line, gpg_strerror (err));
1500           crl_close_reader (reader);
1501         }
1502     }
1503   else
1504     {
1505       char *buf;
1506
1507       buf = xtrymalloc (strlen (line)+1);
1508       if (!buf)
1509         err = gpg_error_from_syserror ();
1510       else
1511         {
1512           strcpy_escaped_plus (buf, line);
1513           err = crl_cache_load (ctrl, buf);
1514           xfree (buf);
1515         }
1516     }
1517
1518   return leave_cmd (ctx, err);
1519 }
1520
1521
1522 static const char hlp_listcrls[] =
1523   "LISTCRLS\n"
1524   "\n"
1525   "List the content of all CRLs in a readable format.  This command is\n"
1526   "usually used by gpgsm using the invocation \"gpgsm --call-dirmngr\n"
1527   "listcrls\".  It may also be used directly using \"dirmngr\n"
1528   "--list-crls\".";
1529 static gpg_error_t
1530 cmd_listcrls (assuan_context_t ctx, char *line)
1531 {
1532   gpg_error_t err;
1533   estream_t fp;
1534
1535   (void)line;
1536
1537   fp = es_fopencookie (ctx, "w", data_line_cookie_functions);
1538   if (!fp)
1539     err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
1540   else
1541     {
1542       err = crl_cache_list (fp);
1543       es_fclose (fp);
1544     }
1545   return leave_cmd (ctx, err);
1546 }
1547
1548
1549 static const char hlp_cachecert[] =
1550   "CACHECERT\n"
1551   "\n"
1552   "Put a certificate into the internal cache.  This command might be\n"
1553   "useful if a client knows in advance certificates required for a\n"
1554   "test and wants to make sure they get added to the internal cache.\n"
1555   "It is also helpful for debugging.  To get the actual certificate,\n"
1556   "this command immediately inquires it using\n"
1557   "\n"
1558   "  INQUIRE TARGETCERT\n"
1559   "\n"
1560   "and the caller is expected to return the certificate for the\n"
1561   "request as a binary blob.";
1562 static gpg_error_t
1563 cmd_cachecert (assuan_context_t ctx, char *line)
1564 {
1565   ctrl_t ctrl = assuan_get_pointer (ctx);
1566   gpg_error_t err;
1567   ksba_cert_t cert = NULL;
1568   unsigned char *value = NULL;
1569   size_t valuelen;
1570
1571   (void)line;
1572
1573   err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1574                        &value, &valuelen, MAX_CERT_LENGTH);
1575   if (err)
1576     {
1577       log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1578       goto leave;
1579     }
1580
1581   if (!valuelen) /* No data returned; return a comprehensible error. */
1582     err = gpg_error (GPG_ERR_MISSING_CERT);
1583   else
1584     {
1585       err = ksba_cert_new (&cert);
1586       if (!err)
1587         err = ksba_cert_init_from_mem (cert, value, valuelen);
1588     }
1589   xfree (value);
1590   if(err)
1591     goto leave;
1592
1593   err = cache_cert (cert);
1594
1595  leave:
1596   ksba_cert_release (cert);
1597   return leave_cmd (ctx, err);
1598 }
1599
1600
1601 static const char hlp_validate[] =
1602   "VALIDATE\n"
1603   "\n"
1604   "Validate a certificate using the certificate validation function\n"
1605   "used internally by dirmngr.  This command is only useful for\n"
1606   "debugging.  To get the actual certificate, this command immediately\n"
1607   "inquires it using\n"
1608   "\n"
1609   "  INQUIRE TARGETCERT\n"
1610   "\n"
1611   "and the caller is expected to return the certificate for the\n"
1612   "request as a binary blob.";
1613 static gpg_error_t
1614 cmd_validate (assuan_context_t ctx, char *line)
1615 {
1616   ctrl_t ctrl = assuan_get_pointer (ctx);
1617   gpg_error_t err;
1618   ksba_cert_t cert = NULL;
1619   unsigned char *value = NULL;
1620   size_t valuelen;
1621
1622   (void)line;
1623
1624   err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1625                        &value, &valuelen, MAX_CERT_LENGTH);
1626   if (err)
1627     {
1628       log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1629       goto leave;
1630     }
1631
1632   if (!valuelen) /* No data returned; return a comprehensible error. */
1633     err = gpg_error (GPG_ERR_MISSING_CERT);
1634   else
1635     {
1636       err = ksba_cert_new (&cert);
1637       if (!err)
1638         err = ksba_cert_init_from_mem (cert, value, valuelen);
1639     }
1640   xfree (value);
1641   if(err)
1642     goto leave;
1643
1644   /* If we have this certificate already in our cache, use the cached
1645      version for validation because this will take care of any cached
1646      results. */
1647   {
1648     unsigned char fpr[20];
1649     ksba_cert_t tmpcert;
1650
1651     cert_compute_fpr (cert, fpr);
1652     tmpcert = get_cert_byfpr (fpr);
1653     if (tmpcert)
1654       {
1655         ksba_cert_release (cert);
1656         cert = tmpcert;
1657       }
1658   }
1659
1660   err = validate_cert_chain (ctrl, cert, NULL, VALIDATE_MODE_CERT, NULL);
1661
1662  leave:
1663   ksba_cert_release (cert);
1664   return leave_cmd (ctx, err);
1665 }
1666
1667
1668 \f
1669 /* Parse an keyserver URI and store it in a new uri item which is
1670    returned at R_ITEM.  On error return an error code.  */
1671 static gpg_error_t
1672 make_keyserver_item (const char *uri, uri_item_t *r_item)
1673 {
1674   gpg_error_t err;
1675   uri_item_t item;
1676
1677   *r_item = NULL;
1678   item = xtrymalloc (sizeof *item + strlen (uri));
1679   if (!item)
1680     return gpg_error_from_syserror ();
1681
1682   item->next = NULL;
1683   item->parsed_uri = NULL;
1684   strcpy (item->uri, uri);
1685
1686 #if USE_LDAP
1687   if (ldap_uri_p (item->uri))
1688     err = ldap_parse_uri (&item->parsed_uri, uri);
1689   else
1690 #endif
1691     {
1692       err = http_parse_uri (&item->parsed_uri, uri, 1);
1693     }
1694
1695   if (err)
1696     xfree (item);
1697   else
1698     *r_item = item;
1699   return err;
1700 }
1701
1702
1703 /* If no keyserver is stored in CTRL but a global keyserver has been
1704    set, put that global keyserver into CTRL.  We need use this
1705    function to help migrate from the old gpg based keyserver
1706    configuration to the new dirmngr based configuration.  */
1707 static gpg_error_t
1708 ensure_keyserver (ctrl_t ctrl)
1709 {
1710   gpg_error_t err;
1711   uri_item_t item;
1712
1713   if (ctrl->server_local->keyservers)
1714     return 0; /* Already set for this session.  */
1715   if (!opt.keyserver)
1716     return 0; /* No global option set.  */
1717
1718   err = make_keyserver_item (opt.keyserver, &item);
1719   if (!err)
1720     ctrl->server_local->keyservers = item;
1721
1722   return err;
1723 }
1724
1725
1726 static const char hlp_keyserver[] =
1727   "KEYSERVER [<options>] [<uri>|<host>]\n"
1728   "Options are:\n"
1729   "  --help\n"
1730   "  --clear      Remove all configured keyservers\n"
1731   "  --resolve    Resolve HKP host names and rotate\n"
1732   "  --hosttable  Print table of known hosts and pools\n"
1733   "  --dead       Mark <host> as dead\n"
1734   "  --alive      Mark <host> as alive\n"
1735   "\n"
1736   "If called without arguments list all configured keyserver URLs.\n"
1737   "If called with an URI add this as keyserver.  Note that keyservers\n"
1738   "are configured on a per-session base.  A default keyserver may already be\n"
1739   "present, thus the \"--clear\" option must be used to get full control.\n"
1740   "If \"--clear\" and an URI are used together the clear command is\n"
1741   "obviously executed first.  A RESET command does not change the list\n"
1742   "of configured keyservers.";
1743 static gpg_error_t
1744 cmd_keyserver (assuan_context_t ctx, char *line)
1745 {
1746   ctrl_t ctrl = assuan_get_pointer (ctx);
1747   gpg_error_t err = 0;
1748   int clear_flag, add_flag, help_flag, host_flag, resolve_flag;
1749   int dead_flag, alive_flag;
1750   uri_item_t item = NULL; /* gcc 4.4.5 is not able to detect that it
1751                              is always initialized.  */
1752
1753   clear_flag = has_option (line, "--clear");
1754   help_flag = has_option (line, "--help");
1755   resolve_flag = has_option (line, "--resolve");
1756   host_flag = has_option (line, "--hosttable");
1757   dead_flag = has_option (line, "--dead");
1758   alive_flag = has_option (line, "--alive");
1759   line = skip_options (line);
1760   add_flag = !!*line;
1761
1762   if (help_flag)
1763     {
1764       err = ks_action_help (ctrl, line);
1765       goto leave;
1766     }
1767
1768   if (resolve_flag)
1769     {
1770       err = ensure_keyserver (ctrl);
1771       if (!err)
1772         err = ks_action_resolve (ctrl, ctrl->server_local->keyservers);
1773       if (err)
1774         goto leave;
1775     }
1776
1777   if (alive_flag && dead_flag)
1778     {
1779       err = set_error (GPG_ERR_ASS_PARAMETER, "no support for zombies");
1780       goto leave;
1781     }
1782   if (dead_flag)
1783     {
1784       err = check_owner_permission (ctx, "no permission to use --dead");
1785       if (err)
1786         goto leave;
1787     }
1788   if (alive_flag || dead_flag)
1789     {
1790       if (!*line)
1791         {
1792           err = set_error (GPG_ERR_ASS_PARAMETER, "name of host missing");
1793           goto leave;
1794         }
1795
1796       err = ks_hkp_mark_host (ctrl, line, alive_flag);
1797       if (err)
1798         goto leave;
1799     }
1800
1801   if (host_flag)
1802     {
1803       err = ks_hkp_print_hosttable (ctrl);
1804       if (err)
1805         goto leave;
1806     }
1807   if (resolve_flag || host_flag || alive_flag || dead_flag)
1808     goto leave;
1809
1810   if (add_flag)
1811     {
1812       err = make_keyserver_item (line, &item);
1813       if (err)
1814         goto leave;
1815     }
1816   if (clear_flag)
1817     release_ctrl_keyservers (ctrl);
1818   if (add_flag)
1819     {
1820       item->next = ctrl->server_local->keyservers;
1821       ctrl->server_local->keyservers = item;
1822     }
1823
1824   if (!add_flag && !clear_flag && !help_flag)
1825     {
1826       /* List configured keyservers.  However, we first add a global
1827          keyserver. */
1828       uri_item_t u;
1829
1830       err = ensure_keyserver (ctrl);
1831       if (err)
1832         {
1833           assuan_set_error (ctx, err,
1834                             "Bad keyserver configuration in dirmngr.conf");
1835           goto leave;
1836         }
1837
1838       for (u=ctrl->server_local->keyservers; u; u = u->next)
1839         dirmngr_status (ctrl, "KEYSERVER", u->uri, NULL);
1840     }
1841   err = 0;
1842
1843  leave:
1844   return leave_cmd (ctx, err);
1845 }
1846
1847
1848 \f
1849 static const char hlp_ks_search[] =
1850   "KS_SEARCH {<pattern>}\n"
1851   "\n"
1852   "Search the configured OpenPGP keyservers (see command KEYSERVER)\n"
1853   "for keys matching PATTERN";
1854 static gpg_error_t
1855 cmd_ks_search (assuan_context_t ctx, char *line)
1856 {
1857   ctrl_t ctrl = assuan_get_pointer (ctx);
1858   gpg_error_t err;
1859   strlist_t list, sl;
1860   char *p;
1861   estream_t outfp;
1862
1863   /* No options for now.  */
1864   line = skip_options (line);
1865
1866   /* Break the line down into an strlist.  Each pattern is
1867      percent-plus escaped. */
1868   list = NULL;
1869   for (p=line; *p; line = p)
1870     {
1871       while (*p && *p != ' ')
1872         p++;
1873       if (*p)
1874         *p++ = 0;
1875       if (*line)
1876         {
1877           sl = xtrymalloc (sizeof *sl + strlen (line));
1878           if (!sl)
1879             {
1880               err = gpg_error_from_syserror ();
1881               goto leave;
1882             }
1883           sl->flags = 0;
1884           strcpy_escaped_plus (sl->d, line);
1885           sl->next = list;
1886           list = sl;
1887         }
1888     }
1889
1890   err = ensure_keyserver (ctrl);
1891   if (err)
1892     goto leave;
1893
1894   /* Setup an output stream and perform the search.  */
1895   outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
1896   if (!outfp)
1897     err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
1898   else
1899     {
1900       err = ks_action_search (ctrl, ctrl->server_local->keyservers,
1901                               list, outfp);
1902       es_fclose (outfp);
1903     }
1904
1905  leave:
1906   free_strlist (list);
1907   return leave_cmd (ctx, err);
1908 }
1909
1910
1911 \f
1912 static const char hlp_ks_get[] =
1913   "KS_GET {<pattern>}\n"
1914   "\n"
1915   "Get the keys matching PATTERN from the configured OpenPGP keyservers\n"
1916   "(see command KEYSERVER).  Each pattern should be a keyid, a fingerprint,\n"
1917   "or an exact name indicated by the '=' prefix.";
1918 static gpg_error_t
1919 cmd_ks_get (assuan_context_t ctx, char *line)
1920 {
1921   ctrl_t ctrl = assuan_get_pointer (ctx);
1922   gpg_error_t err;
1923   strlist_t list, sl;
1924   char *p;
1925   estream_t outfp;
1926
1927   /* No options for now.  */
1928   line = skip_options (line);
1929
1930   /* Break the line into a strlist.  Each pattern is by
1931      definition percent-plus escaped.  However we only support keyids
1932      and fingerprints and thus the client has no need to apply the
1933      escaping.  */
1934   list = NULL;
1935   for (p=line; *p; line = p)
1936     {
1937       while (*p && *p != ' ')
1938         p++;
1939       if (*p)
1940         *p++ = 0;
1941       if (*line)
1942         {
1943           sl = xtrymalloc (sizeof *sl + strlen (line));
1944           if (!sl)
1945             {
1946               err = gpg_error_from_syserror ();
1947               goto leave;
1948             }
1949           sl->flags = 0;
1950           strcpy_escaped_plus (sl->d, line);
1951           sl->next = list;
1952           list = sl;
1953         }
1954     }
1955
1956   err = ensure_keyserver (ctrl);
1957   if (err)
1958     goto leave;
1959
1960   /* Setup an output stream and perform the get.  */
1961   outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
1962   if (!outfp)
1963     err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
1964   else
1965     {
1966       err = ks_action_get (ctrl, ctrl->server_local->keyservers, list, outfp);
1967       es_fclose (outfp);
1968     }
1969
1970  leave:
1971   free_strlist (list);
1972   return leave_cmd (ctx, err);
1973 }
1974
1975
1976 static const char hlp_ks_fetch[] =
1977   "KS_FETCH <URL>\n"
1978   "\n"
1979   "Get the key(s) from URL.";
1980 static gpg_error_t
1981 cmd_ks_fetch (assuan_context_t ctx, char *line)
1982 {
1983   ctrl_t ctrl = assuan_get_pointer (ctx);
1984   gpg_error_t err;
1985   estream_t outfp;
1986
1987   /* No options for now.  */
1988   line = skip_options (line);
1989
1990   err = ensure_keyserver (ctrl);
1991   if (err)
1992     goto leave;
1993
1994   /* Setup an output stream and perform the get.  */
1995   outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
1996   if (!outfp)
1997     err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
1998   else
1999     {
2000       err = ks_action_fetch (ctrl, line, outfp);
2001       es_fclose (outfp);
2002     }
2003
2004  leave:
2005   return leave_cmd (ctx, err);
2006 }
2007
2008
2009 \f
2010 static const char hlp_ks_put[] =
2011   "KS_PUT\n"
2012   "\n"
2013   "Send a key to the configured OpenPGP keyservers.  The actual key material\n"
2014   "is then requested by Dirmngr using\n"
2015   "\n"
2016   "  INQUIRE KEYBLOCK\n"
2017   "\n"
2018   "The client shall respond with a binary version of the keyblock (e.g.,\n"
2019   "the output of `gpg --export KEYID').  For LDAP\n"
2020   "keyservers Dirmngr may ask for meta information of the provided keyblock\n"
2021   "using:\n"
2022   "\n"
2023   "  INQUIRE KEYBLOCK_INFO\n"
2024   "\n"
2025   "The client shall respond with a colon delimited info lines (the output\n"
2026   "of 'for x in keys sigs; do gpg --list-$x --with-colons KEYID; done').\n";
2027 static gpg_error_t
2028 cmd_ks_put (assuan_context_t ctx, char *line)
2029 {
2030   ctrl_t ctrl = assuan_get_pointer (ctx);
2031   gpg_error_t err;
2032   unsigned char *value = NULL;
2033   size_t valuelen;
2034   unsigned char *info = NULL;
2035   size_t infolen;
2036
2037   /* No options for now.  */
2038   line = skip_options (line);
2039
2040   err = ensure_keyserver (ctrl);
2041   if (err)
2042     goto leave;
2043
2044   /* Ask for the key material.  */
2045   err = assuan_inquire (ctx, "KEYBLOCK",
2046                         &value, &valuelen, MAX_KEYBLOCK_LENGTH);
2047   if (err)
2048     {
2049       log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
2050       goto leave;
2051     }
2052
2053   if (!valuelen) /* No data returned; return a comprehensible error. */
2054     {
2055       err = gpg_error (GPG_ERR_MISSING_CERT);
2056       goto leave;
2057     }
2058
2059   /* Ask for the key meta data. Not actually needed for HKP servers
2060      but we do it anyway to test the client implementaion.  */
2061   err = assuan_inquire (ctx, "KEYBLOCK_INFO",
2062                         &info, &infolen, MAX_KEYBLOCK_LENGTH);
2063   if (err)
2064     {
2065       log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
2066       goto leave;
2067     }
2068
2069   /* Send the key.  */
2070   err = ks_action_put (ctrl, ctrl->server_local->keyservers,
2071                        value, valuelen, info, infolen);
2072
2073  leave:
2074   xfree (info);
2075   xfree (value);
2076   return leave_cmd (ctx, err);
2077 }
2078
2079
2080
2081 \f
2082 static const char hlp_getinfo[] =
2083   "GETINFO <what>\n"
2084   "\n"
2085   "Multi purpose command to return certain information.  \n"
2086   "Supported values of WHAT are:\n"
2087   "\n"
2088   "version     - Return the version of the program.\n"
2089   "pid         - Return the process id of the server.\n"
2090   "tor         - Return OK if running in Tor mode\n"
2091   "socket_name - Return the name of the socket.\n";
2092 static gpg_error_t
2093 cmd_getinfo (assuan_context_t ctx, char *line)
2094 {
2095   gpg_error_t err;
2096
2097   if (!strcmp (line, "version"))
2098     {
2099       const char *s = VERSION;
2100       err = assuan_send_data (ctx, s, strlen (s));
2101     }
2102   else if (!strcmp (line, "pid"))
2103     {
2104       char numbuf[50];
2105
2106       snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
2107       err = assuan_send_data (ctx, numbuf, strlen (numbuf));
2108     }
2109   else if (!strcmp (line, "socket_name"))
2110     {
2111       const char *s = dirmngr_user_socket_name ();
2112
2113       if (!s)
2114         s = dirmngr_sys_socket_name ();
2115
2116       if (s)
2117         err = assuan_send_data (ctx, s, strlen (s));
2118       else
2119         err = gpg_error (GPG_ERR_NO_DATA);
2120     }
2121   else if (!strcmp (line, "tor"))
2122     {
2123       err = opt.use_tor? 0:set_error (GPG_ERR_GENERAL, "Tor mode not enabled");
2124     }
2125   else
2126     err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
2127
2128   return leave_cmd (ctx, err);
2129 }
2130
2131
2132 \f
2133 static const char hlp_killdirmngr[] =
2134   "KILLDIRMNGR\n"
2135   "\n"
2136   "This command allows a user - given sufficient permissions -\n"
2137   "to kill this dirmngr process.\n";
2138 static gpg_error_t
2139 cmd_killdirmngr (assuan_context_t ctx, char *line)
2140 {
2141   ctrl_t ctrl = assuan_get_pointer (ctx);
2142   gpg_error_t err;
2143
2144   (void)line;
2145
2146   if (opt.system_daemon)
2147     {
2148       if (opt.system_service)
2149         err = set_error (GPG_ERR_NOT_SUPPORTED,
2150                          "can't do that whilst running as system service");
2151       else
2152         err = check_owner_permission (ctx,
2153                                       "no permission to kill this process");
2154     }
2155   else
2156     err = 0;
2157
2158   if (!err)
2159     {
2160       ctrl->server_local->stopme = 1;
2161       assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
2162       err = gpg_error (GPG_ERR_EOF);
2163     }
2164   return err;
2165 }
2166
2167
2168 static const char hlp_reloaddirmngr[] =
2169   "RELOADDIRMNGR\n"
2170   "\n"
2171   "This command is an alternative to SIGHUP\n"
2172   "to reload the configuration.";
2173 static gpg_error_t
2174 cmd_reloaddirmngr (assuan_context_t ctx, char *line)
2175 {
2176   (void)ctx;
2177   (void)line;
2178
2179  if (opt.system_daemon)
2180     {
2181 #ifndef HAVE_W32_SYSTEM
2182       {
2183         gpg_error_t err;
2184
2185         err = check_owner_permission (ctx,
2186                                       "no permission to reload this process");
2187         if (err)
2188           return err;
2189       }
2190 #endif
2191     }
2192
2193   dirmngr_sighup_action ();
2194   return 0;
2195 }
2196
2197
2198
2199 \f
2200 /* Tell the assuan library about our commands. */
2201 static int
2202 register_commands (assuan_context_t ctx)
2203 {
2204   static struct {
2205     const char *name;
2206     assuan_handler_t handler;
2207     const char * const help;
2208   } table[] = {
2209     { "DNS_CERT",   cmd_dns_cert,   hlp_dns_cert },
2210     { "LDAPSERVER", cmd_ldapserver, hlp_ldapserver },
2211     { "ISVALID",    cmd_isvalid,    hlp_isvalid },
2212     { "CHECKCRL",   cmd_checkcrl,   hlp_checkcrl },
2213     { "CHECKOCSP",  cmd_checkocsp,  hlp_checkocsp },
2214     { "LOOKUP",     cmd_lookup,     hlp_lookup },
2215     { "LOADCRL",    cmd_loadcrl,    hlp_loadcrl },
2216     { "LISTCRLS",   cmd_listcrls,   hlp_listcrls },
2217     { "CACHECERT",  cmd_cachecert,  hlp_cachecert },
2218     { "VALIDATE",   cmd_validate,   hlp_validate },
2219     { "KEYSERVER",  cmd_keyserver,  hlp_keyserver },
2220     { "KS_SEARCH",  cmd_ks_search,  hlp_ks_search },
2221     { "KS_GET",     cmd_ks_get,     hlp_ks_get },
2222     { "KS_FETCH",   cmd_ks_fetch,   hlp_ks_fetch },
2223     { "KS_PUT",     cmd_ks_put,     hlp_ks_put },
2224     { "GETINFO",    cmd_getinfo,    hlp_getinfo },
2225     { "KILLDIRMNGR",cmd_killdirmngr,hlp_killdirmngr },
2226     { "RELOADDIRMNGR",cmd_reloaddirmngr,hlp_reloaddirmngr },
2227     { NULL, NULL }
2228   };
2229   int i, j, rc;
2230
2231   for (i=j=0; table[i].name; i++)
2232     {
2233       rc = assuan_register_command (ctx, table[i].name, table[i].handler,
2234                                     table[i].help);
2235       if (rc)
2236         return rc;
2237     }
2238   return 0;
2239 }
2240
2241
2242 /* Note that we do not reset the list of configured keyservers.  */
2243 static gpg_error_t
2244 reset_notify (assuan_context_t ctx, char *line)
2245 {
2246   ctrl_t ctrl = assuan_get_pointer (ctx);
2247   (void)line;
2248
2249 #if USE_LDAP
2250   ldapserver_list_free (ctrl->server_local->ldapservers);
2251 #endif /*USE_LDAP*/
2252   ctrl->server_local->ldapservers = NULL;
2253   return 0;
2254 }
2255
2256
2257 /* Startup the server and run the main command loop.  With FD = -1,
2258    use stdin/stdout. */
2259 void
2260 start_command_handler (assuan_fd_t fd)
2261 {
2262   static const char hello[] = "Dirmngr " VERSION " at your service";
2263   static char *hello_line;
2264   int rc;
2265   assuan_context_t ctx;
2266   ctrl_t ctrl;
2267
2268   ctrl = xtrycalloc (1, sizeof *ctrl);
2269   if (ctrl)
2270     ctrl->server_local = xtrycalloc (1, sizeof *ctrl->server_local);
2271   if (!ctrl || !ctrl->server_local)
2272     {
2273       log_error (_("can't allocate control structure: %s\n"),
2274                  strerror (errno));
2275       xfree (ctrl);
2276       return;
2277     }
2278
2279   dirmngr_init_default_ctrl (ctrl);
2280
2281   rc = assuan_new (&ctx);
2282   if (rc)
2283     {
2284       log_error (_("failed to allocate assuan context: %s\n"),
2285                  gpg_strerror (rc));
2286       dirmngr_exit (2);
2287     }
2288
2289   if (fd == ASSUAN_INVALID_FD)
2290     {
2291       assuan_fd_t filedes[2];
2292
2293       filedes[0] = assuan_fdopen (0);
2294       filedes[1] = assuan_fdopen (1);
2295       rc = assuan_init_pipe_server (ctx, filedes);
2296     }
2297   else
2298     {
2299       rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED);
2300     }
2301
2302   if (rc)
2303     {
2304       assuan_release (ctx);
2305       log_error (_("failed to initialize the server: %s\n"),
2306                  gpg_strerror(rc));
2307       dirmngr_exit (2);
2308     }
2309
2310   rc = register_commands (ctx);
2311   if (rc)
2312     {
2313       log_error (_("failed to the register commands with Assuan: %s\n"),
2314                  gpg_strerror(rc));
2315       dirmngr_exit (2);
2316     }
2317
2318
2319   if (!hello_line)
2320     {
2321       size_t n;
2322       const char *cfgname;
2323
2324       cfgname = opt.config_filename? opt.config_filename : "[none]";
2325
2326       n = (30 + strlen (opt.homedir) + strlen (cfgname)
2327            + strlen (hello) + 1);
2328       hello_line = xmalloc (n+1);
2329       snprintf (hello_line, n,
2330                 "Home: %s\n"
2331                 "Config: %s\n"
2332                 "%s",
2333                 opt.homedir,
2334                 cfgname,
2335                 hello);
2336       hello_line[n] = 0;
2337     }
2338
2339   ctrl->server_local->assuan_ctx = ctx;
2340   assuan_set_pointer (ctx, ctrl);
2341
2342   assuan_set_hello_line (ctx, hello_line);
2343   assuan_register_option_handler (ctx, option_handler);
2344   assuan_register_reset_notify (ctx, reset_notify);
2345
2346   for (;;)
2347     {
2348       rc = assuan_accept (ctx);
2349       if (rc == -1)
2350         break;
2351       if (rc)
2352         {
2353           log_info (_("Assuan accept problem: %s\n"), gpg_strerror (rc));
2354           break;
2355         }
2356
2357 #ifndef HAVE_W32_SYSTEM
2358       if (opt.verbose)
2359         {
2360           assuan_peercred_t peercred;
2361
2362           if (!assuan_get_peercred (ctx, &peercred))
2363             log_info ("connection from process %ld (%ld:%ld)\n",
2364                       (long)peercred->pid, (long)peercred->uid,
2365                       (long)peercred->gid);
2366         }
2367 #endif
2368
2369       rc = assuan_process (ctx);
2370       if (rc)
2371         {
2372           log_info (_("Assuan processing failed: %s\n"), gpg_strerror (rc));
2373           continue;
2374         }
2375     }
2376
2377 #if USE_LDAP
2378   ldap_wrapper_connection_cleanup (ctrl);
2379
2380   ldapserver_list_free (ctrl->server_local->ldapservers);
2381 #endif /*USE_LDAP*/
2382   ctrl->server_local->ldapservers = NULL;
2383
2384   ctrl->server_local->assuan_ctx = NULL;
2385   assuan_release (ctx);
2386
2387   if (ctrl->server_local->stopme)
2388     dirmngr_exit (0);
2389
2390   if (ctrl->refcount)
2391     log_error ("oops: connection control structure still referenced (%d)\n",
2392                ctrl->refcount);
2393   else
2394     {
2395       release_ctrl_ocsp_certs (ctrl);
2396       xfree (ctrl->server_local);
2397       dirmngr_deinit_default_ctrl (ctrl);
2398       xfree (ctrl);
2399     }
2400 }
2401
2402
2403 /* Send a status line back to the client.  KEYWORD is the status
2404    keyword, the optional string arguments are blank separated added to
2405    the line, the last argument must be a NULL. */
2406 gpg_error_t
2407 dirmngr_status (ctrl_t ctrl, const char *keyword, ...)
2408 {
2409   gpg_error_t err = 0;
2410   va_list arg_ptr;
2411   const char *text;
2412
2413   va_start (arg_ptr, keyword);
2414
2415   if (ctrl->server_local)
2416     {
2417       assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2418       char buf[950], *p;
2419       size_t n;
2420
2421       p = buf;
2422       n = 0;
2423       while ( (text = va_arg (arg_ptr, const char *)) )
2424         {
2425           if (n)
2426             {
2427               *p++ = ' ';
2428               n++;
2429             }
2430           for ( ; *text && n < DIM (buf)-2; n++)
2431             *p++ = *text++;
2432         }
2433       *p = 0;
2434       err = assuan_write_status (ctx, keyword, buf);
2435     }
2436
2437   va_end (arg_ptr);
2438   return err;
2439 }
2440
2441
2442 /* Print a help status line.  TEXTLEN gives the length of the text
2443    from TEXT to be printed.  The function splits text at LFs.  */
2444 gpg_error_t
2445 dirmngr_status_help (ctrl_t ctrl, const char *text)
2446 {
2447   gpg_error_t err = 0;
2448
2449   if (ctrl->server_local)
2450     {
2451       assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2452       char buf[950], *p;
2453       size_t n;
2454
2455       do
2456         {
2457           p = buf;
2458           n = 0;
2459           for ( ; *text && *text != '\n' && n < DIM (buf)-2; n++)
2460             *p++ = *text++;
2461           if (*text == '\n')
2462             text++;
2463           *p = 0;
2464           err = assuan_write_status (ctx, "#", buf);
2465         }
2466       while (!err && *text);
2467     }
2468
2469   return err;
2470 }
2471
2472 /* Send a tick progress indicator back.  Fixme: This is only done for
2473    the currently active channel.  */
2474 gpg_error_t
2475 dirmngr_tick (ctrl_t ctrl)
2476 {
2477   static time_t next_tick = 0;
2478   gpg_error_t err = 0;
2479   time_t now = time (NULL);
2480
2481   if (!next_tick)
2482     {
2483       next_tick = now + 1;
2484     }
2485   else if ( now > next_tick )
2486     {
2487       if (ctrl)
2488         {
2489           err = dirmngr_status (ctrl, "PROGRESS", "tick", "? 0 0", NULL);
2490           if (err)
2491             {
2492               /* Take this as in indication for a cancel request.  */
2493               err = gpg_error (GPG_ERR_CANCELED);
2494             }
2495           now = time (NULL);
2496         }
2497
2498       next_tick = now + 1;
2499     }
2500   return err;
2501 }