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