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