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