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