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