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