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