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