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