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