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