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