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