dirmngr: improve VERSIONCHECK
[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, 2015 g10 Code GmbH
4  * Copyright (C) 2014, 2015, 2016 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 #include "dirmngr.h"
34 #include <assuan.h>
35
36 #include "crlcache.h"
37 #include "crlfetch.h"
38 #if USE_LDAP
39 # include "ldapserver.h"
40 #endif
41 #include "ocsp.h"
42 #include "certcache.h"
43 #include "validate.h"
44 #include "misc.h"
45 #if USE_LDAP
46 # include "ldap-wrapper.h"
47 #endif
48 #include "ks-action.h"
49 #include "ks-engine.h"  /* (ks_hkp_print_hosttable) */
50 #if USE_LDAP
51 # include "ldap-parse-uri.h"
52 #endif
53 #include "dns-stuff.h"
54 #include "mbox-util.h"
55 #include "zb32.h"
56 #include "server-help.h"
57 #include "../common/exectool.h"
58
59 /* To avoid DoS attacks we limit the size of a certificate to
60    something reasonable.  The DoS was actually only an issue back when
61    Dirmngr was a system service and not a user service. */
62 #define MAX_CERT_LENGTH (16*1024)
63
64 /* The same goes for OpenPGP keyblocks, but here we need to allow for
65    much longer blocks; a 200k keyblock is not too unusual for keys
66    with a lot of signatures (e.g. 0x5b0358a2).  9C31503C6D866396 even
67    has 770 KiB as of 2015-08-23.  To avoid adding a runtime option we
68    now use 20MiB which should really be enough.  Well, a key with
69    several pictures could be larger (the parser as a 18MiB limit for
70    attribute packets) but it won't be nice to the keyservers to send
71    them such large blobs.  */
72 #define MAX_KEYBLOCK_LENGTH (20*1024*1024)
73
74
75 #define PARM_ERROR(t) assuan_set_error (ctx, \
76                                         gpg_error (GPG_ERR_ASS_PARAMETER), (t))
77 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
78
79
80
81 /* Control structure per connection. */
82 struct server_local_s
83 {
84   /* Data used to associate an Assuan context with local server data */
85   assuan_context_t assuan_ctx;
86
87   /* Per-session LDAP servers.  */
88   ldap_server_t ldapservers;
89
90   /* Per-session list of keyservers.  */
91   uri_item_t keyservers;
92
93   /* If this flag is set to true this dirmngr process will be
94      terminated after the end of this session.  */
95   int stopme;
96
97   /* State variable private to is_tor_running.  */
98   int tor_state;
99
100   /* If the first both flags are set the assuan logging of data lines
101    * is suppressed.  The count variable is used to show the number of
102    * non-logged bytes.  */
103   size_t inhibit_data_logging_count;
104   unsigned int inhibit_data_logging : 1;
105   unsigned int inhibit_data_logging_now : 1;
106 };
107
108
109 /* Cookie definition for assuan data line output.  */
110 static gpgrt_ssize_t data_line_cookie_write (void *cookie,
111                                              const void *buffer, size_t size);
112 static int data_line_cookie_close (void *cookie);
113 static es_cookie_io_functions_t data_line_cookie_functions =
114   {
115     NULL,
116     data_line_cookie_write,
117     NULL,
118     data_line_cookie_close
119   };
120
121
122
123
124 \f
125 /* Accessor for the local ldapservers variable. */
126 ldap_server_t
127 get_ldapservers_from_ctrl (ctrl_t ctrl)
128 {
129   if (ctrl && ctrl->server_local)
130     return ctrl->server_local->ldapservers;
131   else
132     return NULL;
133 }
134
135 /* Release an uri_item_t list.  */
136 static void
137 release_uri_item_list (uri_item_t list)
138 {
139   while (list)
140     {
141       uri_item_t tmp = list->next;
142       http_release_parsed_uri (list->parsed_uri);
143       xfree (list);
144       list = tmp;
145     }
146 }
147
148 /* Release all configured keyserver info from CTRL.  */
149 void
150 release_ctrl_keyservers (ctrl_t ctrl)
151 {
152   if (! ctrl->server_local)
153     return;
154
155   release_uri_item_list (ctrl->server_local->keyservers);
156   ctrl->server_local->keyservers = NULL;
157 }
158
159
160
161 /* Helper to print a message while leaving a command.  */
162 static gpg_error_t
163 leave_cmd (assuan_context_t ctx, gpg_error_t err)
164 {
165   if (err)
166     {
167       const char *name = assuan_get_command_name (ctx);
168       if (!name)
169         name = "?";
170       if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT)
171         log_error ("command '%s' failed: %s\n", name,
172                    gpg_strerror (err));
173       else
174         log_error ("command '%s' failed: %s <%s>\n", name,
175                    gpg_strerror (err), gpg_strsource (err));
176     }
177   return err;
178 }
179
180
181 /* This is a wrapper around assuan_send_data which makes debugging the
182    output in verbose mode easier.  */
183 static gpg_error_t
184 data_line_write (assuan_context_t ctx, const void *buffer_arg, size_t size)
185 {
186   ctrl_t ctrl = assuan_get_pointer (ctx);
187   const char *buffer = buffer_arg;
188   gpg_error_t err;
189
190   /* If we do not want logging, enable it it here.  */
191   if (ctrl && ctrl->server_local && ctrl->server_local->inhibit_data_logging)
192     ctrl->server_local->inhibit_data_logging_now = 1;
193
194   if (opt.verbose && buffer && size)
195     {
196       /* Ease reading of output by sending a physical line at each LF.  */
197       const char *p;
198       size_t n, nbytes;
199
200       nbytes = size;
201       do
202         {
203           p = memchr (buffer, '\n', nbytes);
204           n = p ? (p - buffer) + 1 : nbytes;
205           err = assuan_send_data (ctx, buffer, n);
206           if (err)
207             {
208               gpg_err_set_errno (EIO);
209               goto leave;
210             }
211           buffer += n;
212           nbytes -= n;
213           if (nbytes && (err=assuan_send_data (ctx, NULL, 0))) /* Flush line. */
214             {
215               gpg_err_set_errno (EIO);
216               goto leave;
217             }
218         }
219       while (nbytes);
220     }
221   else
222     {
223       err = assuan_send_data (ctx, buffer, size);
224       if (err)
225         {
226           gpg_err_set_errno (EIO);  /* For use by data_line_cookie_write.  */
227           goto leave;
228         }
229     }
230
231  leave:
232   if (ctrl && ctrl->server_local && ctrl->server_local->inhibit_data_logging)
233     {
234       ctrl->server_local->inhibit_data_logging_now = 0;
235       ctrl->server_local->inhibit_data_logging_count += size;
236     }
237
238   return err;
239 }
240
241
242 /* A write handler used by es_fopencookie to write assuan data
243    lines.  */
244 static gpgrt_ssize_t
245 data_line_cookie_write (void *cookie, const void *buffer, size_t size)
246 {
247   assuan_context_t ctx = cookie;
248
249   if (data_line_write (ctx, buffer, size))
250     return -1;
251   return (gpgrt_ssize_t)size;
252 }
253
254
255 static int
256 data_line_cookie_close (void *cookie)
257 {
258   assuan_context_t ctx = cookie;
259
260   if (DBG_IPC)
261     {
262       ctrl_t ctrl = assuan_get_pointer (ctx);
263
264       if (ctrl && ctrl->server_local
265           && ctrl->server_local->inhibit_data_logging
266           && ctrl->server_local->inhibit_data_logging_count)
267         log_debug ("(%zu bytes sent via D lines not shown)\n",
268                    ctrl->server_local->inhibit_data_logging_count);
269     }
270   if (assuan_send_data (ctx, NULL, 0))
271     {
272       gpg_err_set_errno (EIO);
273       return -1;
274     }
275
276   return 0;
277 }
278
279
280 /* Copy the % and + escaped string S into the buffer D and replace the
281    escape sequences.  Note, that it is sufficient to allocate the
282    target string D as long as the source string S, i.e.: strlen(s)+1.
283    Note further that if S contains an escaped binary Nul the resulting
284    string D will contain the 0 as well as all other characters but it
285    will be impossible to know whether this is the original EOS or a
286    copied Nul. */
287 static void
288 strcpy_escaped_plus (char *d, const unsigned char *s)
289 {
290   while (*s)
291     {
292       if (*s == '%' && s[1] && s[2])
293         {
294           s++;
295           *d++ = xtoi_2 ( s);
296           s += 2;
297         }
298       else if (*s == '+')
299         *d++ = ' ', s++;
300       else
301         *d++ = *s++;
302     }
303   *d = 0;
304 }
305
306
307 /* This function returns true if a Tor server is running.  The sattus
308    is cached for the current connection.  */
309 static int
310 is_tor_running (ctrl_t ctrl)
311 {
312   /* Check whether we can connect to the proxy.  */
313
314   if (!ctrl || !ctrl->server_local)
315     return 0; /* Ooops.  */
316
317   if (!ctrl->server_local->tor_state)
318     {
319       assuan_fd_t sock;
320
321       sock = assuan_sock_connect_byname (NULL, 0, 0, NULL, ASSUAN_SOCK_TOR);
322       if (sock == ASSUAN_INVALID_FD)
323         ctrl->server_local->tor_state = -1; /* Not running.  */
324       else
325         {
326           assuan_sock_close (sock);
327           ctrl->server_local->tor_state = 1; /* Running.  */
328         }
329     }
330   return (ctrl->server_local->tor_state > 0);
331 }
332
333
334 /* Return an error if the assuan context does not belong to the owner
335    of the process or to root.  On error FAILTEXT is set as Assuan
336    error string.  */
337 static gpg_error_t
338 check_owner_permission (assuan_context_t ctx, const char *failtext)
339 {
340 #ifdef HAVE_W32_SYSTEM
341   /* Under Windows the dirmngr is always run under the control of the
342      user.  */
343   (void)ctx;
344   (void)failtext;
345 #else
346   gpg_err_code_t ec;
347   assuan_peercred_t cred;
348
349   ec = gpg_err_code (assuan_get_peercred (ctx, &cred));
350   if (!ec && cred->uid && cred->uid != getuid ())
351     ec = GPG_ERR_EPERM;
352   if (ec)
353     return set_error (ec, failtext);
354 #endif
355   return 0;
356 }
357
358
359
360 /* Common code for get_cert_local and get_issuer_cert_local. */
361 static ksba_cert_t
362 do_get_cert_local (ctrl_t ctrl, const char *name, const char *command)
363 {
364   unsigned char *value;
365   size_t valuelen;
366   int rc;
367   char *buf;
368   ksba_cert_t cert;
369
370   if (name)
371     {
372       buf = xmalloc ( strlen (command) + 1 + strlen(name) + 1);
373       strcpy (stpcpy (stpcpy (buf, command), " "), name);
374     }
375   else
376     buf = xstrdup (command);
377
378   rc = assuan_inquire (ctrl->server_local->assuan_ctx, buf,
379                        &value, &valuelen, MAX_CERT_LENGTH);
380   xfree (buf);
381   if (rc)
382     {
383       log_error (_("assuan_inquire(%s) failed: %s\n"),
384                  command, gpg_strerror (rc));
385       return NULL;
386     }
387
388   if (!valuelen)
389     {
390       xfree (value);
391       return NULL;
392     }
393
394   rc = ksba_cert_new (&cert);
395   if (!rc)
396     {
397       rc = ksba_cert_init_from_mem (cert, value, valuelen);
398       if (rc)
399         {
400           ksba_cert_release (cert);
401           cert = NULL;
402         }
403     }
404   xfree (value);
405   return cert;
406 }
407
408
409
410 /* Ask back to return a certificate for name, given as a regular
411    gpgsm certificate indentificates (e.g. fingerprint or one of the
412    other methods).  Alternatively, NULL may be used for NAME to
413    return the current target certificate. Either return the certificate
414    in a KSBA object or NULL if it is not available.
415 */
416 ksba_cert_t
417 get_cert_local (ctrl_t ctrl, const char *name)
418 {
419   if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
420     {
421       if (opt.debug)
422         log_debug ("get_cert_local called w/o context\n");
423       return NULL;
424     }
425   return do_get_cert_local (ctrl, name, "SENDCERT");
426
427 }
428
429 /* Ask back to return the issuing certificate for name, given as a
430    regular gpgsm certificate indentificates (e.g. fingerprint or one
431    of the other methods).  Alternatively, NULL may be used for NAME to
432    return thecurrent target certificate. Either return the certificate
433    in a KSBA object or NULL if it is not available.
434
435 */
436 ksba_cert_t
437 get_issuing_cert_local (ctrl_t ctrl, const char *name)
438 {
439   if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
440     {
441       if (opt.debug)
442         log_debug ("get_issuing_cert_local called w/o context\n");
443       return NULL;
444     }
445   return do_get_cert_local (ctrl, name, "SENDISSUERCERT");
446 }
447
448 /* Ask back to return a certificate with subject NAME and a
449    subjectKeyIdentifier of KEYID. */
450 ksba_cert_t
451 get_cert_local_ski (ctrl_t ctrl, const char *name, ksba_sexp_t keyid)
452 {
453   unsigned char *value;
454   size_t valuelen;
455   int rc;
456   char *buf;
457   ksba_cert_t cert;
458   char *hexkeyid;
459
460   if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
461     {
462       if (opt.debug)
463         log_debug ("get_cert_local_ski called w/o context\n");
464       return NULL;
465     }
466   if (!name || !keyid)
467     {
468       log_debug ("get_cert_local_ski called with insufficient arguments\n");
469       return NULL;
470     }
471
472   hexkeyid = serial_hex (keyid);
473   if (!hexkeyid)
474     {
475       log_debug ("serial_hex() failed\n");
476       return NULL;
477     }
478
479   buf = xtrymalloc (15 + strlen (hexkeyid) + 2 + strlen(name) + 1);
480   if (!buf)
481     {
482
483       log_error ("can't allocate enough memory: %s\n", strerror (errno));
484       xfree (hexkeyid);
485       return NULL;
486     }
487   strcpy (stpcpy (stpcpy (stpcpy (buf, "SENDCERT_SKI "), hexkeyid)," /"),name);
488   xfree (hexkeyid);
489
490   rc = assuan_inquire (ctrl->server_local->assuan_ctx, buf,
491                        &value, &valuelen, MAX_CERT_LENGTH);
492   xfree (buf);
493   if (rc)
494     {
495       log_error (_("assuan_inquire(%s) failed: %s\n"), "SENDCERT_SKI",
496                  gpg_strerror (rc));
497       return NULL;
498     }
499
500   if (!valuelen)
501     {
502       xfree (value);
503       return NULL;
504     }
505
506   rc = ksba_cert_new (&cert);
507   if (!rc)
508     {
509       rc = ksba_cert_init_from_mem (cert, value, valuelen);
510       if (rc)
511         {
512           ksba_cert_release (cert);
513           cert = NULL;
514         }
515     }
516   xfree (value);
517   return cert;
518 }
519
520
521 /* Ask the client via an inquiry to check the istrusted status of the
522    certificate specified by the hexified fingerprint HEXFPR.  Returns
523    0 if the certificate is trusted by the client or an error code.  */
524 gpg_error_t
525 get_istrusted_from_client (ctrl_t ctrl, const char *hexfpr)
526 {
527   unsigned char *value;
528   size_t valuelen;
529   int rc;
530   char request[100];
531
532   if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx
533       || !hexfpr)
534     return gpg_error (GPG_ERR_INV_ARG);
535
536   snprintf (request, sizeof request, "ISTRUSTED %s", hexfpr);
537   rc = assuan_inquire (ctrl->server_local->assuan_ctx, request,
538                        &value, &valuelen, 100);
539   if (rc)
540     {
541       log_error (_("assuan_inquire(%s) failed: %s\n"),
542                  request, gpg_strerror (rc));
543       return rc;
544     }
545   /* The expected data is: "1" or "1 cruft" (not a C-string).  */
546   if (valuelen && *value == '1' && (valuelen == 1 || spacep (value+1)))
547     rc = 0;
548   else
549     rc = gpg_error (GPG_ERR_NOT_TRUSTED);
550   xfree (value);
551   return rc;
552 }
553
554
555
556
557 /* Ask the client to return the certificate associated with the
558    current command. This is sometimes needed because the client usually
559    sends us just the cert ID, assuming that the request can be
560    satisfied from the cache, where the cert ID is used as key. */
561 static int
562 inquire_cert_and_load_crl (assuan_context_t ctx)
563 {
564   ctrl_t ctrl = assuan_get_pointer (ctx);
565   gpg_error_t err;
566   unsigned char *value = NULL;
567   size_t valuelen;
568   ksba_cert_t cert = NULL;
569
570   err = assuan_inquire( ctx, "SENDCERT", &value, &valuelen, 0);
571   if (err)
572     return err;
573
574 /*   { */
575 /*     FILE *fp = fopen ("foo.der", "r"); */
576 /*     value = xmalloc (2000); */
577 /*     valuelen = fread (value, 1, 2000, fp); */
578 /*     fclose (fp); */
579 /*   } */
580
581   if (!valuelen) /* No data returned; return a comprehensible error. */
582     return gpg_error (GPG_ERR_MISSING_CERT);
583
584   err = ksba_cert_new (&cert);
585   if (err)
586     goto leave;
587   err = ksba_cert_init_from_mem (cert, value, valuelen);
588   if(err)
589     goto leave;
590   xfree (value); value = NULL;
591
592   err = crl_cache_reload_crl (ctrl, cert);
593
594  leave:
595   ksba_cert_release (cert);
596   xfree (value);
597   return err;
598 }
599
600
601 /* Handle OPTION commands. */
602 static gpg_error_t
603 option_handler (assuan_context_t ctx, const char *key, const char *value)
604 {
605   ctrl_t ctrl = assuan_get_pointer (ctx);
606   gpg_error_t err = 0;
607
608   if (!strcmp (key, "force-crl-refresh"))
609     {
610       int i = *value? atoi (value) : 0;
611       ctrl->force_crl_refresh = i;
612     }
613   else if (!strcmp (key, "audit-events"))
614     {
615       int i = *value? atoi (value) : 0;
616       ctrl->audit_events = i;
617     }
618   else if (!strcmp (key, "http-proxy"))
619     {
620       xfree (ctrl->http_proxy);
621       if (!*value || !strcmp (value, "none"))
622         ctrl->http_proxy = NULL;
623       else if (!(ctrl->http_proxy = xtrystrdup (value)))
624         err = gpg_error_from_syserror ();
625     }
626   else if (!strcmp (key, "honor-keyserver-url-used"))
627     {
628       /* Return an error if we are running in Tor mode.  */
629       if (opt.use_tor)
630         err = gpg_error (GPG_ERR_FORBIDDEN);
631     }
632   else
633     err = gpg_error (GPG_ERR_UNKNOWN_OPTION);
634
635   return err;
636 }
637
638
639 \f
640 static const char hlp_dns_cert[] =
641   "DNS_CERT <subtype> <name>\n"
642   "DNS_CERT --pka <user_id>\n"
643   "DNS_CERT --dane <user_id>\n"
644   "\n"
645   "Return the CERT record for <name>.  <subtype> is one of\n"
646   "  *     Return the first record of any supported subtype\n"
647   "  PGP   Return the first record of subtype PGP (3)\n"
648   "  IPGP  Return the first record of subtype IPGP (6)\n"
649   "If the content of a certificate is available (PGP) it is returned\n"
650   "by data lines.  Fingerprints and URLs are returned via status lines.\n"
651   "In --pka mode the fingerprint and if available an URL is returned.\n"
652   "In --dane mode the key is returned from RR type 61";
653 static gpg_error_t
654 cmd_dns_cert (assuan_context_t ctx, char *line)
655 {
656   /* ctrl_t ctrl = assuan_get_pointer (ctx); */
657   gpg_error_t err = 0;
658   int pka_mode, dane_mode;
659   char *mbox = NULL;
660   char *namebuf = NULL;
661   char *encodedhash = NULL;
662   const char *name;
663   int certtype;
664   char *p;
665   void *key = NULL;
666   size_t keylen;
667   unsigned char *fpr = NULL;
668   size_t fprlen;
669   char *url = NULL;
670
671   pka_mode = has_option (line, "--pka");
672   dane_mode = has_option (line, "--dane");
673   line = skip_options (line);
674
675   if (pka_mode && dane_mode)
676     {
677       err = PARM_ERROR ("either --pka or --dane may be given");
678       goto leave;
679     }
680
681   if (pka_mode || dane_mode)
682     ; /* No need to parse here - we do this later.  */
683   else
684     {
685       p = strchr (line, ' ');
686       if (!p)
687         {
688           err = PARM_ERROR ("missing arguments");
689           goto leave;
690         }
691       *p++ = 0;
692       if (!strcmp (line, "*"))
693         certtype = DNS_CERTTYPE_ANY;
694       else if (!strcmp (line, "IPGP"))
695         certtype = DNS_CERTTYPE_IPGP;
696       else if (!strcmp (line, "PGP"))
697         certtype = DNS_CERTTYPE_PGP;
698       else
699         {
700           err = PARM_ERROR ("unknown subtype");
701           goto leave;
702         }
703       while (spacep (p))
704         p++;
705       line = p;
706       if (!*line)
707         {
708           err = PARM_ERROR ("name missing");
709           goto leave;
710         }
711     }
712
713   if (opt.use_tor && (err = enable_dns_tormode (0)))
714     {
715       /* Tor mode is requested but the DNS code can't enable it.  */
716       assuan_set_error (ctx, err, "error enabling Tor mode");
717       goto leave;
718     }
719
720   if (pka_mode || dane_mode)
721     {
722       char *domain;     /* Points to mbox.  */
723       char hashbuf[32]; /* For SHA-1 and SHA-256. */
724
725       /* We lowercase ascii characters but the DANE I-D does not allow
726          this.  FIXME: Check after the release of the RFC whether to
727          change this.  */
728       mbox = mailbox_from_userid (line);
729       if (!mbox || !(domain = strchr (mbox, '@')))
730         {
731           err = set_error (GPG_ERR_INV_USER_ID, "no mailbox in user id");
732           goto leave;
733         }
734       *domain++ = 0;
735
736       if (pka_mode)
737         {
738           gcry_md_hash_buffer (GCRY_MD_SHA1, hashbuf, mbox, strlen (mbox));
739           encodedhash = zb32_encode (hashbuf, 8*20);
740           if (!encodedhash)
741             {
742               err = gpg_error_from_syserror ();
743               goto leave;
744             }
745           namebuf = strconcat (encodedhash, "._pka.", domain, NULL);
746           if (!namebuf)
747             {
748               err = gpg_error_from_syserror ();
749               goto leave;
750             }
751           name = namebuf;
752           certtype = DNS_CERTTYPE_IPGP;
753         }
754       else
755         {
756           /* Note: The hash is truncated to 28 bytes and we lowercase
757              the result only for aesthetic reasons.  */
758           gcry_md_hash_buffer (GCRY_MD_SHA256, hashbuf, mbox, strlen (mbox));
759           encodedhash = bin2hex (hashbuf, 28, NULL);
760           if (!encodedhash)
761             {
762               err = gpg_error_from_syserror ();
763               goto leave;
764             }
765           ascii_strlwr (encodedhash);
766           namebuf = strconcat (encodedhash, "._openpgpkey.", domain, NULL);
767           if (!namebuf)
768             {
769               err = gpg_error_from_syserror ();
770               goto leave;
771             }
772           name = namebuf;
773           certtype = DNS_CERTTYPE_RR61;
774         }
775     }
776   else
777     name = line;
778
779   err = get_dns_cert (name, certtype, &key, &keylen, &fpr, &fprlen, &url);
780   if (err)
781     goto leave;
782
783   if (key)
784     {
785       err = data_line_write (ctx, key, keylen);
786       if (err)
787         goto leave;
788     }
789
790   if (fpr)
791     {
792       char *tmpstr;
793
794       tmpstr = bin2hex (fpr, fprlen, NULL);
795       if (!tmpstr)
796         err = gpg_error_from_syserror ();
797       else
798         {
799           err = assuan_write_status (ctx, "FPR", tmpstr);
800           xfree (tmpstr);
801         }
802       if (err)
803         goto leave;
804     }
805
806   if (url)
807     {
808       err = assuan_write_status (ctx, "URL", url);
809       if (err)
810         goto leave;
811     }
812
813
814  leave:
815   xfree (key);
816   xfree (fpr);
817   xfree (url);
818   xfree (mbox);
819   xfree (namebuf);
820   xfree (encodedhash);
821   return leave_cmd (ctx, err);
822 }
823
824
825 \f
826 static const char hlp_wkd_get[] =
827   "WKD_GET [--submission-address|--policy-flags] <user_id>\n"
828   "\n"
829   "Return the key or other info for <user_id>\n"
830   "from the Web Key Directory.";
831 static gpg_error_t
832 cmd_wkd_get (assuan_context_t ctx, char *line)
833 {
834   ctrl_t ctrl = assuan_get_pointer (ctx);
835   gpg_error_t err = 0;
836   char *mbox = NULL;
837   char *domain;     /* Points to mbox.  */
838   char sha1buf[20];
839   char *uri = NULL;
840   char *encodedhash = NULL;
841   int opt_submission_addr;
842   int opt_policy_flags;
843   int no_log = 0;
844
845   opt_submission_addr = has_option (line, "--submission-address");
846   opt_policy_flags = has_option (line, "--policy-flags");
847   line = skip_options (line);
848
849   mbox = mailbox_from_userid (line);
850   if (!mbox || !(domain = strchr (mbox, '@')))
851     {
852       err = set_error (GPG_ERR_INV_USER_ID, "no mailbox in user id");
853       goto leave;
854     }
855   *domain++ = 0;
856
857   gcry_md_hash_buffer (GCRY_MD_SHA1, sha1buf, mbox, strlen (mbox));
858   encodedhash = zb32_encode (sha1buf, 8*20);
859   if (!encodedhash)
860     {
861       err = gpg_error_from_syserror ();
862       goto leave;
863     }
864
865   if (opt_submission_addr)
866     {
867       uri = strconcat ("https://",
868                        domain,
869                        "/.well-known/openpgpkey/submission-address",
870                        NULL);
871     }
872   else if (opt_policy_flags)
873     {
874       uri = strconcat ("https://",
875                        domain,
876                        "/.well-known/openpgpkey/policy",
877                        NULL);
878     }
879   else
880     {
881       uri = strconcat ("https://",
882                        domain,
883                        "/.well-known/openpgpkey/hu/",
884                        encodedhash,
885                        NULL);
886       no_log = 1;
887     }
888   if (!uri)
889     {
890       err = gpg_error_from_syserror ();
891       goto leave;
892     }
893
894   /* Setup an output stream and perform the get.  */
895   {
896     estream_t outfp;
897
898     outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
899     if (!outfp)
900       err = set_error (GPG_ERR_ASS_GENERAL,
901                        "error setting up a data stream");
902     else
903       {
904         if (no_log)
905           ctrl->server_local->inhibit_data_logging = 1;
906         ctrl->server_local->inhibit_data_logging_now = 0;
907         ctrl->server_local->inhibit_data_logging_count = 0;
908         err = ks_action_fetch (ctrl, uri, outfp);
909         es_fclose (outfp);
910         ctrl->server_local->inhibit_data_logging = 0;
911       }
912   }
913
914  leave:
915   xfree (uri);
916   xfree (encodedhash);
917   xfree (mbox);
918   return leave_cmd (ctx, err);
919 }
920
921
922 \f
923 static const char hlp_ldapserver[] =
924   "LDAPSERVER <data>\n"
925   "\n"
926   "Add a new LDAP server to the list of configured LDAP servers.\n"
927   "DATA is in the same format as expected in the configure file.";
928 static gpg_error_t
929 cmd_ldapserver (assuan_context_t ctx, char *line)
930 {
931 #if USE_LDAP
932   ctrl_t ctrl = assuan_get_pointer (ctx);
933   ldap_server_t server;
934   ldap_server_t *last_next_p;
935
936   while (spacep (line))
937     line++;
938   if (*line == '\0')
939     return leave_cmd (ctx, PARM_ERROR (_("ldapserver missing")));
940
941   server = ldapserver_parse_one (line, "", 0);
942   if (! server)
943     return leave_cmd (ctx, gpg_error (GPG_ERR_INV_ARG));
944
945   last_next_p = &ctrl->server_local->ldapservers;
946   while (*last_next_p)
947     last_next_p = &(*last_next_p)->next;
948   *last_next_p = server;
949   return leave_cmd (ctx, 0);
950 #else
951   (void)line;
952   return leave_cmd (ctx, gpg_error (GPG_ERR_NOT_IMPLEMENTED));
953 #endif
954 }
955
956
957 static const char hlp_isvalid[] =
958   "ISVALID [--only-ocsp] [--force-default-responder]"
959   " <certificate_id>|<certificate_fpr>\n"
960   "\n"
961   "This command checks whether the certificate identified by the\n"
962   "certificate_id is valid.  This is done by consulting CRLs or\n"
963   "whatever has been configured.  Note, that the returned error codes\n"
964   "are from gpg-error.h.  The command may callback using the inquire\n"
965   "function.  See the manual for details.\n"
966   "\n"
967   "The CERTIFICATE_ID is a hex encoded string consisting of two parts,\n"
968   "delimited by a single dot.  The first part is the SHA-1 hash of the\n"
969   "issuer name and the second part the serial number.\n"
970   "\n"
971   "Alternatively the certificate's fingerprint may be given in which\n"
972   "case an OCSP request is done before consulting the CRL.\n"
973   "\n"
974   "If the option --only-ocsp is given, no fallback to a CRL check will\n"
975   "be used.\n"
976   "\n"
977   "If the option --force-default-responder is given, only the default\n"
978   "OCSP responder will be used and any other methods of obtaining an\n"
979   "OCSP responder URL won't be used.";
980 static gpg_error_t
981 cmd_isvalid (assuan_context_t ctx, char *line)
982 {
983   ctrl_t ctrl = assuan_get_pointer (ctx);
984   char *issuerhash, *serialno;
985   gpg_error_t err;
986   int did_inquire = 0;
987   int ocsp_mode = 0;
988   int only_ocsp;
989   int force_default_responder;
990
991   only_ocsp = has_option (line, "--only-ocsp");
992   force_default_responder = has_option (line, "--force-default-responder");
993   line = skip_options (line);
994
995   issuerhash = xstrdup (line); /* We need to work on a copy of the
996                                   line because that same Assuan
997                                   context may be used for an inquiry.
998                                   That is because Assuan reuses its
999                                   line buffer.
1000                                    */
1001
1002   serialno = strchr (issuerhash, '.');
1003   if (serialno)
1004     *serialno++ = 0;
1005   else
1006     {
1007       char *endp = strchr (issuerhash, ' ');
1008       if (endp)
1009         *endp = 0;
1010       if (strlen (issuerhash) != 40)
1011         {
1012           xfree (issuerhash);
1013           return leave_cmd (ctx, PARM_ERROR (_("serialno missing in cert ID")));
1014         }
1015       ocsp_mode = 1;
1016     }
1017
1018
1019  again:
1020   if (ocsp_mode)
1021     {
1022       /* Note, that we ignore the given issuer hash and instead rely
1023          on the current certificate semantics used with this
1024          command. */
1025       if (!opt.allow_ocsp)
1026         err = gpg_error (GPG_ERR_NOT_SUPPORTED);
1027       else
1028         err = ocsp_isvalid (ctrl, NULL, NULL, force_default_responder);
1029       /* Fixme: If we got no ocsp response and --only-ocsp is not used
1030          we should fall back to CRL mode.  Thus we need to clear
1031          OCSP_MODE, get the issuerhash and the serialno from the
1032          current certificate and jump to again. */
1033     }
1034   else if (only_ocsp)
1035     err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
1036   else
1037     {
1038       switch (crl_cache_isvalid (ctrl,
1039                                  issuerhash, serialno,
1040                                  ctrl->force_crl_refresh))
1041         {
1042         case CRL_CACHE_VALID:
1043           err = 0;
1044           break;
1045         case CRL_CACHE_INVALID:
1046           err = gpg_error (GPG_ERR_CERT_REVOKED);
1047           break;
1048         case CRL_CACHE_DONTKNOW:
1049           if (did_inquire)
1050             err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
1051           else if (!(err = inquire_cert_and_load_crl (ctx)))
1052             {
1053               did_inquire = 1;
1054               goto again;
1055             }
1056           break;
1057         case CRL_CACHE_CANTUSE:
1058           err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
1059           break;
1060         default:
1061           log_fatal ("crl_cache_isvalid returned invalid code\n");
1062         }
1063     }
1064
1065   xfree (issuerhash);
1066   return leave_cmd (ctx, err);
1067 }
1068
1069
1070 /* If the line contains a SHA-1 fingerprint as the first argument,
1071    return the FPR vuffer on success.  The function checks that the
1072    fingerprint consists of valid characters and prints and error
1073    message if it does not and returns NULL.  Fingerprints are
1074    considered optional and thus no explicit error is returned. NULL is
1075    also returned if there is no fingerprint at all available.
1076    FPR must be a caller provided buffer of at least 20 bytes.
1077
1078    Note that colons within the fingerprint are allowed to separate 2
1079    hex digits; this allows for easier cutting and pasting using the
1080    usual fingerprint rendering.
1081 */
1082 static unsigned char *
1083 get_fingerprint_from_line (const char *line, unsigned char *fpr)
1084 {
1085   const char *s;
1086   int i;
1087
1088   for (s=line, i=0; *s && *s != ' '; s++ )
1089     {
1090       if ( hexdigitp (s) && hexdigitp (s+1) )
1091         {
1092           if ( i >= 20 )
1093             return NULL;  /* Fingerprint too long.  */
1094           fpr[i++] = xtoi_2 (s);
1095           s++;
1096         }
1097       else if ( *s != ':' )
1098         return NULL; /* Invalid.  */
1099     }
1100   if ( i != 20 )
1101     return NULL; /* Fingerprint to short.  */
1102   return fpr;
1103 }
1104
1105
1106
1107 static const char hlp_checkcrl[] =
1108   "CHECKCRL [<fingerprint>]\n"
1109   "\n"
1110   "Check whether the certificate with FINGERPRINT (SHA-1 hash of the\n"
1111   "entire X.509 certificate blob) is valid or not by consulting the\n"
1112   "CRL responsible for this certificate.  If the fingerprint has not\n"
1113   "been given or the certificate is not known, the function \n"
1114   "inquires the certificate using an\n"
1115   "\n"
1116   "  INQUIRE TARGETCERT\n"
1117   "\n"
1118   "and the caller is expected to return the certificate for the\n"
1119   "request (which should match FINGERPRINT) as a binary blob.\n"
1120   "Processing then takes place without further interaction; in\n"
1121   "particular dirmngr tries to locate other required certificate by\n"
1122   "its own mechanism which includes a local certificate store as well\n"
1123   "as a list of trusted root certificates.\n"
1124   "\n"
1125   "The return value is the usual gpg-error code or 0 for ducesss;\n"
1126   "i.e. the certificate validity has been confirmed by a valid CRL.";
1127 static gpg_error_t
1128 cmd_checkcrl (assuan_context_t ctx, char *line)
1129 {
1130   ctrl_t ctrl = assuan_get_pointer (ctx);
1131   gpg_error_t err;
1132   unsigned char fprbuffer[20], *fpr;
1133   ksba_cert_t cert;
1134
1135   fpr = get_fingerprint_from_line (line, fprbuffer);
1136   cert = fpr? get_cert_byfpr (fpr) : NULL;
1137
1138   if (!cert)
1139     {
1140       /* We do not have this certificate yet or the fingerprint has
1141          not been given.  Inquire it from the client.  */
1142       unsigned char *value = NULL;
1143       size_t valuelen;
1144
1145       err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1146                            &value, &valuelen, MAX_CERT_LENGTH);
1147       if (err)
1148         {
1149           log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1150           goto leave;
1151         }
1152
1153       if (!valuelen) /* No data returned; return a comprehensible error. */
1154         err = gpg_error (GPG_ERR_MISSING_CERT);
1155       else
1156         {
1157           err = ksba_cert_new (&cert);
1158           if (!err)
1159             err = ksba_cert_init_from_mem (cert, value, valuelen);
1160         }
1161       xfree (value);
1162       if(err)
1163         goto leave;
1164     }
1165
1166   assert (cert);
1167
1168   err = crl_cache_cert_isvalid (ctrl, cert, ctrl->force_crl_refresh);
1169   if (gpg_err_code (err) == GPG_ERR_NO_CRL_KNOWN)
1170     {
1171       err = crl_cache_reload_crl (ctrl, cert);
1172       if (!err)
1173         err = crl_cache_cert_isvalid (ctrl, cert, 0);
1174     }
1175
1176  leave:
1177   ksba_cert_release (cert);
1178   return leave_cmd (ctx, err);
1179 }
1180
1181
1182 static const char hlp_checkocsp[] =
1183   "CHECKOCSP [--force-default-responder] [<fingerprint>]\n"
1184   "\n"
1185   "Check whether the certificate with FINGERPRINT (SHA-1 hash of the\n"
1186   "entire X.509 certificate blob) is valid or not by asking an OCSP\n"
1187   "responder responsible for this certificate.  The optional\n"
1188   "fingerprint may be used for a quick check in case an OCSP check has\n"
1189   "been done for this certificate recently (we always cache OCSP\n"
1190   "responses for a couple of minutes). If the fingerprint has not been\n"
1191   "given or there is no cached result, the function inquires the\n"
1192   "certificate using an\n"
1193   "\n"
1194   "   INQUIRE TARGETCERT\n"
1195   "\n"
1196   "and the caller is expected to return the certificate for the\n"
1197   "request (which should match FINGERPRINT) as a binary blob.\n"
1198   "Processing then takes place without further interaction; in\n"
1199   "particular dirmngr tries to locate other required certificates by\n"
1200   "its own mechanism which includes a local certificate store as well\n"
1201   "as a list of trusted root certificates.\n"
1202   "\n"
1203   "If the option --force-default-responder is given, only the default\n"
1204   "OCSP responder will be used and any other methods of obtaining an\n"
1205   "OCSP responder URL won't be used.\n"
1206   "\n"
1207   "The return value is the usual gpg-error code or 0 for ducesss;\n"
1208   "i.e. the certificate validity has been confirmed by a valid CRL.";
1209 static gpg_error_t
1210 cmd_checkocsp (assuan_context_t ctx, char *line)
1211 {
1212   ctrl_t ctrl = assuan_get_pointer (ctx);
1213   gpg_error_t err;
1214   unsigned char fprbuffer[20], *fpr;
1215   ksba_cert_t cert;
1216   int force_default_responder;
1217
1218   force_default_responder = has_option (line, "--force-default-responder");
1219   line = skip_options (line);
1220
1221   fpr = get_fingerprint_from_line (line, fprbuffer);
1222   cert = fpr? get_cert_byfpr (fpr) : NULL;
1223
1224   if (!cert)
1225     {
1226       /* We do not have this certificate yet or the fingerprint has
1227          not been given.  Inquire it from the client.  */
1228       unsigned char *value = NULL;
1229       size_t valuelen;
1230
1231       err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1232                            &value, &valuelen, MAX_CERT_LENGTH);
1233       if (err)
1234         {
1235           log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1236           goto leave;
1237         }
1238
1239       if (!valuelen) /* No data returned; return a comprehensible error. */
1240         err = gpg_error (GPG_ERR_MISSING_CERT);
1241       else
1242         {
1243           err = ksba_cert_new (&cert);
1244           if (!err)
1245             err = ksba_cert_init_from_mem (cert, value, valuelen);
1246         }
1247       xfree (value);
1248       if(err)
1249         goto leave;
1250     }
1251
1252   assert (cert);
1253
1254   if (!opt.allow_ocsp)
1255     err = gpg_error (GPG_ERR_NOT_SUPPORTED);
1256   else
1257     err = ocsp_isvalid (ctrl, cert, NULL, force_default_responder);
1258
1259  leave:
1260   ksba_cert_release (cert);
1261   return leave_cmd (ctx, err);
1262 }
1263
1264
1265
1266 static int
1267 lookup_cert_by_url (assuan_context_t ctx, const char *url)
1268 {
1269   ctrl_t ctrl = assuan_get_pointer (ctx);
1270   gpg_error_t err = 0;
1271   unsigned char *value = NULL;
1272   size_t valuelen;
1273
1274   /* Fetch single certificate given it's URL.  */
1275   err = fetch_cert_by_url (ctrl, url, &value, &valuelen);
1276   if (err)
1277     {
1278       log_error (_("fetch_cert_by_url failed: %s\n"), gpg_strerror (err));
1279       goto leave;
1280     }
1281
1282   /* Send the data, flush the buffer and then send an END. */
1283   err = assuan_send_data (ctx, value, valuelen);
1284   if (!err)
1285     err = assuan_send_data (ctx, NULL, 0);
1286   if (!err)
1287     err = assuan_write_line (ctx, "END");
1288   if (err)
1289     {
1290       log_error (_("error sending data: %s\n"), gpg_strerror (err));
1291       goto leave;
1292     }
1293
1294  leave:
1295
1296   return err;
1297 }
1298
1299
1300 /* Send the certificate, flush the buffer and then send an END. */
1301 static gpg_error_t
1302 return_one_cert (void *opaque, ksba_cert_t cert)
1303 {
1304   assuan_context_t ctx = opaque;
1305   gpg_error_t err;
1306   const unsigned char *der;
1307   size_t derlen;
1308
1309   der = ksba_cert_get_image (cert, &derlen);
1310   if (!der)
1311     err = gpg_error (GPG_ERR_INV_CERT_OBJ);
1312   else
1313     {
1314       err = assuan_send_data (ctx, der, derlen);
1315       if (!err)
1316         err = assuan_send_data (ctx, NULL, 0);
1317       if (!err)
1318         err = assuan_write_line (ctx, "END");
1319     }
1320   if (err)
1321     log_error (_("error sending data: %s\n"), gpg_strerror (err));
1322   return err;
1323 }
1324
1325
1326 /* Lookup certificates from the internal cache or using the ldap
1327    servers. */
1328 static int
1329 lookup_cert_by_pattern (assuan_context_t ctx, char *line,
1330                         int single, int cache_only)
1331 {
1332   gpg_error_t err = 0;
1333   char *p;
1334   strlist_t sl, list = NULL;
1335   int truncated = 0, truncation_forced = 0;
1336   int count = 0;
1337   int local_count = 0;
1338 #if USE_LDAP
1339   ctrl_t ctrl = assuan_get_pointer (ctx);
1340   unsigned char *value = NULL;
1341   size_t valuelen;
1342   struct ldapserver_iter ldapserver_iter;
1343   cert_fetch_context_t fetch_context;
1344 #endif /*USE_LDAP*/
1345   int any_no_data = 0;
1346
1347   /* Break the line down into an STRLIST */
1348   for (p=line; *p; line = p)
1349     {
1350       while (*p && *p != ' ')
1351         p++;
1352       if (*p)
1353         *p++ = 0;
1354
1355       if (*line)
1356         {
1357           sl = xtrymalloc (sizeof *sl + strlen (line));
1358           if (!sl)
1359             {
1360               err = gpg_error_from_errno (errno);
1361               goto leave;
1362             }
1363           memset (sl, 0, sizeof *sl);
1364           strcpy_escaped_plus (sl->d, line);
1365           sl->next = list;
1366           list = sl;
1367         }
1368     }
1369
1370   /* First look through the internal cache.  The certifcates retruned
1371      here are not counted towards the truncation limit.  */
1372   if (single && !cache_only)
1373     ; /* Do not read from the local cache in this case.  */
1374   else
1375     {
1376       for (sl=list; sl; sl = sl->next)
1377         {
1378           err = get_certs_bypattern (sl->d, return_one_cert, ctx);
1379           if (!err)
1380             local_count++;
1381           if (!err && single)
1382             goto ready;
1383
1384           if (gpg_err_code (err) == GPG_ERR_NO_DATA)
1385             {
1386               err = 0;
1387               if (cache_only)
1388                 any_no_data = 1;
1389             }
1390           else if (gpg_err_code (err) == GPG_ERR_INV_NAME && !cache_only)
1391             {
1392               /* No real fault because the internal pattern lookup
1393                  can't yet cope with all types of pattern.  */
1394               err = 0;
1395             }
1396           if (err)
1397             goto ready;
1398         }
1399     }
1400
1401   /* Loop over all configured servers unless we want only the
1402      certificates from the cache.  */
1403 #if USE_LDAP
1404   for (ldapserver_iter_begin (&ldapserver_iter, ctrl);
1405        !cache_only && !ldapserver_iter_end_p (&ldapserver_iter)
1406          && ldapserver_iter.server->host && !truncation_forced;
1407        ldapserver_iter_next (&ldapserver_iter))
1408     {
1409       ldap_server_t ldapserver = ldapserver_iter.server;
1410
1411       if (DBG_LOOKUP)
1412         log_debug ("cmd_lookup: trying %s:%d base=%s\n",
1413                    ldapserver->host, ldapserver->port,
1414                    ldapserver->base?ldapserver->base : "[default]");
1415
1416       /* Fetch certificates matching pattern */
1417       err = start_cert_fetch (ctrl, &fetch_context, list, ldapserver);
1418       if ( gpg_err_code (err) == GPG_ERR_NO_DATA )
1419         {
1420           if (DBG_LOOKUP)
1421             log_debug ("cmd_lookup: no data\n");
1422           err = 0;
1423           any_no_data = 1;
1424           continue;
1425         }
1426       if (err)
1427         {
1428           log_error (_("start_cert_fetch failed: %s\n"), gpg_strerror (err));
1429           goto leave;
1430         }
1431
1432       /* Fetch the certificates for this query. */
1433       while (!truncation_forced)
1434         {
1435           xfree (value); value = NULL;
1436           err = fetch_next_cert (fetch_context, &value, &valuelen);
1437           if (gpg_err_code (err) == GPG_ERR_NO_DATA )
1438             {
1439               err = 0;
1440               any_no_data = 1;
1441               break; /* Ready. */
1442             }
1443           if (gpg_err_code (err) == GPG_ERR_TRUNCATED)
1444             {
1445               truncated = 1;
1446               err = 0;
1447               break;  /* Ready.  */
1448             }
1449           if (gpg_err_code (err) == GPG_ERR_EOF)
1450             {
1451               err = 0;
1452               break; /* Ready. */
1453             }
1454           if (!err && !value)
1455             {
1456               err = gpg_error (GPG_ERR_BUG);
1457               goto leave;
1458             }
1459           if (err)
1460             {
1461               log_error (_("fetch_next_cert failed: %s\n"),
1462                          gpg_strerror (err));
1463               end_cert_fetch (fetch_context);
1464               goto leave;
1465             }
1466
1467           if (DBG_LOOKUP)
1468             log_debug ("cmd_lookup: returning one cert%s\n",
1469                        truncated? " (truncated)":"");
1470
1471           /* Send the data, flush the buffer and then send an END line
1472              as a certificate delimiter. */
1473           err = assuan_send_data (ctx, value, valuelen);
1474           if (!err)
1475             err = assuan_send_data (ctx, NULL, 0);
1476           if (!err)
1477             err = assuan_write_line (ctx, "END");
1478           if (err)
1479             {
1480               log_error (_("error sending data: %s\n"), gpg_strerror (err));
1481               end_cert_fetch (fetch_context);
1482               goto leave;
1483             }
1484
1485           if (++count >= opt.max_replies )
1486             {
1487               truncation_forced = 1;
1488               log_info (_("max_replies %d exceeded\n"), opt.max_replies );
1489             }
1490           if (single)
1491             break;
1492         }
1493
1494       end_cert_fetch (fetch_context);
1495     }
1496 #endif /*USE_LDAP*/
1497
1498  ready:
1499   if (truncated || truncation_forced)
1500     {
1501       char str[50];
1502
1503       sprintf (str, "%d", count);
1504       assuan_write_status (ctx, "TRUNCATED", str);
1505     }
1506
1507   if (!err && !count && !local_count && any_no_data)
1508     err = gpg_error (GPG_ERR_NO_DATA);
1509
1510  leave:
1511   free_strlist (list);
1512   return err;
1513 }
1514
1515
1516 static const char hlp_lookup[] =
1517   "LOOKUP [--url] [--single] [--cache-only] <pattern>\n"
1518   "\n"
1519   "Lookup certificates matching PATTERN. With --url the pattern is\n"
1520   "expected to be one URL.\n"
1521   "\n"
1522   "If --url is not given:  To allow for multiple patterns (which are ORed)\n"
1523   "quoting is required: Spaces are translated to \"+\" or \"%20\";\n"
1524   "obviously this requires that the usual escape quoting rules are applied.\n"
1525   "\n"
1526   "If --url is given no special escaping is required because URLs are\n"
1527   "already escaped this way.\n"
1528   "\n"
1529   "If --single is given the first and only the first match will be\n"
1530   "returned.  If --cache-only is _not_ given, no local query will be\n"
1531   "done.\n"
1532   "\n"
1533   "If --cache-only is given no external lookup is done so that only\n"
1534   "certificates from the cache may get returned.";
1535 static gpg_error_t
1536 cmd_lookup (assuan_context_t ctx, char *line)
1537 {
1538   gpg_error_t err;
1539   int lookup_url, single, cache_only;
1540
1541   lookup_url = has_leading_option (line, "--url");
1542   single = has_leading_option (line, "--single");
1543   cache_only = has_leading_option (line, "--cache-only");
1544   line = skip_options (line);
1545
1546   if (lookup_url && cache_only)
1547     err = gpg_error (GPG_ERR_NOT_FOUND);
1548   else if (lookup_url && single)
1549     err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1550   else if (lookup_url)
1551     err = lookup_cert_by_url (ctx, line);
1552   else
1553     err = lookup_cert_by_pattern (ctx, line, single, cache_only);
1554
1555   return leave_cmd (ctx, err);
1556 }
1557
1558
1559 static const char hlp_loadcrl[] =
1560   "LOADCRL [--url] <filename|url>\n"
1561   "\n"
1562   "Load the CRL in the file with name FILENAME into our cache.  Note\n"
1563   "that FILENAME should be given with an absolute path because\n"
1564   "Dirmngrs cwd is not known.  With --url the CRL is directly loaded\n"
1565   "from the given URL.\n"
1566   "\n"
1567   "This command is usually used by gpgsm using the invocation \"gpgsm\n"
1568   "--call-dirmngr loadcrl <filename>\".  A direct invocation of Dirmngr\n"
1569   "is not useful because gpgsm might need to callback gpgsm to ask for\n"
1570   "the CA's certificate.";
1571 static gpg_error_t
1572 cmd_loadcrl (assuan_context_t ctx, char *line)
1573 {
1574   ctrl_t ctrl = assuan_get_pointer (ctx);
1575   gpg_error_t err = 0;
1576   int use_url = has_leading_option (line, "--url");
1577
1578   line = skip_options (line);
1579
1580   if (use_url)
1581     {
1582       ksba_reader_t reader;
1583
1584       err = crl_fetch (ctrl, line, &reader);
1585       if (err)
1586         log_error (_("fetching CRL from '%s' failed: %s\n"),
1587                    line, gpg_strerror (err));
1588       else
1589         {
1590           err = crl_cache_insert (ctrl, line, reader);
1591           if (err)
1592             log_error (_("processing CRL from '%s' failed: %s\n"),
1593                        line, gpg_strerror (err));
1594           crl_close_reader (reader);
1595         }
1596     }
1597   else
1598     {
1599       char *buf;
1600
1601       buf = xtrymalloc (strlen (line)+1);
1602       if (!buf)
1603         err = gpg_error_from_syserror ();
1604       else
1605         {
1606           strcpy_escaped_plus (buf, line);
1607           err = crl_cache_load (ctrl, buf);
1608           xfree (buf);
1609         }
1610     }
1611
1612   return leave_cmd (ctx, err);
1613 }
1614
1615
1616 static const char hlp_listcrls[] =
1617   "LISTCRLS\n"
1618   "\n"
1619   "List the content of all CRLs in a readable format.  This command is\n"
1620   "usually used by gpgsm using the invocation \"gpgsm --call-dirmngr\n"
1621   "listcrls\".  It may also be used directly using \"dirmngr\n"
1622   "--list-crls\".";
1623 static gpg_error_t
1624 cmd_listcrls (assuan_context_t ctx, char *line)
1625 {
1626   gpg_error_t err;
1627   estream_t fp;
1628
1629   (void)line;
1630
1631   fp = es_fopencookie (ctx, "w", data_line_cookie_functions);
1632   if (!fp)
1633     err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
1634   else
1635     {
1636       err = crl_cache_list (fp);
1637       es_fclose (fp);
1638     }
1639   return leave_cmd (ctx, err);
1640 }
1641
1642
1643 static const char hlp_cachecert[] =
1644   "CACHECERT\n"
1645   "\n"
1646   "Put a certificate into the internal cache.  This command might be\n"
1647   "useful if a client knows in advance certificates required for a\n"
1648   "test and wants to make sure they get added to the internal cache.\n"
1649   "It is also helpful for debugging.  To get the actual certificate,\n"
1650   "this command immediately inquires it using\n"
1651   "\n"
1652   "  INQUIRE TARGETCERT\n"
1653   "\n"
1654   "and the caller is expected to return the certificate for the\n"
1655   "request as a binary blob.";
1656 static gpg_error_t
1657 cmd_cachecert (assuan_context_t ctx, char *line)
1658 {
1659   ctrl_t ctrl = assuan_get_pointer (ctx);
1660   gpg_error_t err;
1661   ksba_cert_t cert = NULL;
1662   unsigned char *value = NULL;
1663   size_t valuelen;
1664
1665   (void)line;
1666
1667   err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1668                        &value, &valuelen, MAX_CERT_LENGTH);
1669   if (err)
1670     {
1671       log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1672       goto leave;
1673     }
1674
1675   if (!valuelen) /* No data returned; return a comprehensible error. */
1676     err = gpg_error (GPG_ERR_MISSING_CERT);
1677   else
1678     {
1679       err = ksba_cert_new (&cert);
1680       if (!err)
1681         err = ksba_cert_init_from_mem (cert, value, valuelen);
1682     }
1683   xfree (value);
1684   if(err)
1685     goto leave;
1686
1687   err = cache_cert (cert);
1688
1689  leave:
1690   ksba_cert_release (cert);
1691   return leave_cmd (ctx, err);
1692 }
1693
1694
1695 static const char hlp_validate[] =
1696   "VALIDATE\n"
1697   "\n"
1698   "Validate a certificate using the certificate validation function\n"
1699   "used internally by dirmngr.  This command is only useful for\n"
1700   "debugging.  To get the actual certificate, this command immediately\n"
1701   "inquires it using\n"
1702   "\n"
1703   "  INQUIRE TARGETCERT\n"
1704   "\n"
1705   "and the caller is expected to return the certificate for the\n"
1706   "request as a binary blob.";
1707 static gpg_error_t
1708 cmd_validate (assuan_context_t ctx, char *line)
1709 {
1710   ctrl_t ctrl = assuan_get_pointer (ctx);
1711   gpg_error_t err;
1712   ksba_cert_t cert = NULL;
1713   unsigned char *value = NULL;
1714   size_t valuelen;
1715
1716   (void)line;
1717
1718   err = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT",
1719                        &value, &valuelen, MAX_CERT_LENGTH);
1720   if (err)
1721     {
1722       log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
1723       goto leave;
1724     }
1725
1726   if (!valuelen) /* No data returned; return a comprehensible error. */
1727     err = gpg_error (GPG_ERR_MISSING_CERT);
1728   else
1729     {
1730       err = ksba_cert_new (&cert);
1731       if (!err)
1732         err = ksba_cert_init_from_mem (cert, value, valuelen);
1733     }
1734   xfree (value);
1735   if(err)
1736     goto leave;
1737
1738   /* If we have this certificate already in our cache, use the cached
1739      version for validation because this will take care of any cached
1740      results. */
1741   {
1742     unsigned char fpr[20];
1743     ksba_cert_t tmpcert;
1744
1745     cert_compute_fpr (cert, fpr);
1746     tmpcert = get_cert_byfpr (fpr);
1747     if (tmpcert)
1748       {
1749         ksba_cert_release (cert);
1750         cert = tmpcert;
1751       }
1752   }
1753
1754   err = validate_cert_chain (ctrl, cert, NULL, VALIDATE_MODE_CERT, NULL);
1755
1756  leave:
1757   ksba_cert_release (cert);
1758   return leave_cmd (ctx, err);
1759 }
1760
1761
1762 \f
1763 /* Parse an keyserver URI and store it in a new uri item which is
1764    returned at R_ITEM.  On error return an error code.  */
1765 static gpg_error_t
1766 make_keyserver_item (const char *uri, uri_item_t *r_item)
1767 {
1768   gpg_error_t err;
1769   uri_item_t item;
1770
1771   *r_item = NULL;
1772   item = xtrymalloc (sizeof *item + strlen (uri));
1773   if (!item)
1774     return gpg_error_from_syserror ();
1775
1776   item->next = NULL;
1777   item->parsed_uri = NULL;
1778   strcpy (item->uri, uri);
1779
1780 #if USE_LDAP
1781   if (ldap_uri_p (item->uri))
1782     err = ldap_parse_uri (&item->parsed_uri, uri);
1783   else
1784 #endif
1785     {
1786       err = http_parse_uri (&item->parsed_uri, uri, 1);
1787     }
1788
1789   if (err)
1790     xfree (item);
1791   else
1792     *r_item = item;
1793   return err;
1794 }
1795
1796
1797 /* If no keyserver is stored in CTRL but a global keyserver has been
1798    set, put that global keyserver into CTRL.  We need use this
1799    function to help migrate from the old gpg based keyserver
1800    configuration to the new dirmngr based configuration.  */
1801 static gpg_error_t
1802 ensure_keyserver (ctrl_t ctrl)
1803 {
1804   gpg_error_t err;
1805   uri_item_t item;
1806   uri_item_t onion_items = NULL;
1807   uri_item_t plain_items = NULL;
1808   uri_item_t ui;
1809   strlist_t sl;
1810
1811   if (ctrl->server_local->keyservers)
1812     return 0; /* Already set for this session.  */
1813   if (!opt.keyserver)
1814     return 0; /* No global option set.  */
1815
1816   for (sl = opt.keyserver; sl; sl = sl->next)
1817     {
1818       err = make_keyserver_item (sl->d, &item);
1819       if (err)
1820         goto leave;
1821       if (item->parsed_uri->onion)
1822         {
1823           item->next = onion_items;
1824           onion_items = item;
1825         }
1826       else
1827         {
1828           item->next = plain_items;
1829           plain_items = item;
1830         }
1831     }
1832
1833   /* Decide which to use.  Note that the sesssion has no keyservers
1834      yet set. */
1835   if (onion_items && !onion_items->next && plain_items && !plain_items->next)
1836     {
1837       /* If there is just one onion and one plain keyserver given, we take
1838          only one depending on whether Tor is running or not.  */
1839       if (is_tor_running (ctrl))
1840         {
1841           ctrl->server_local->keyservers = onion_items;
1842           onion_items = NULL;
1843         }
1844       else
1845         {
1846           ctrl->server_local->keyservers = plain_items;
1847           plain_items = NULL;
1848         }
1849     }
1850   else if (!is_tor_running (ctrl))
1851     {
1852       /* Tor is not running.  It does not make sense to add Onion
1853          addresses.  */
1854       ctrl->server_local->keyservers = plain_items;
1855       plain_items = NULL;
1856     }
1857   else
1858     {
1859       /* In all other cases add all keyservers.  */
1860       ctrl->server_local->keyservers = onion_items;
1861       onion_items = NULL;
1862       for (ui = ctrl->server_local->keyservers; ui && ui->next; ui = ui->next)
1863         ;
1864       if (ui)
1865         ui->next = plain_items;
1866       else
1867         ctrl->server_local->keyservers = plain_items;
1868       plain_items = NULL;
1869     }
1870
1871  leave:
1872   release_uri_item_list (onion_items);
1873   release_uri_item_list (plain_items);
1874
1875   return err;
1876 }
1877
1878
1879 static const char hlp_keyserver[] =
1880   "KEYSERVER [<options>] [<uri>|<host>]\n"
1881   "Options are:\n"
1882   "  --help\n"
1883   "  --clear      Remove all configured keyservers\n"
1884   "  --resolve    Resolve HKP host names and rotate\n"
1885   "  --hosttable  Print table of known hosts and pools\n"
1886   "  --dead       Mark <host> as dead\n"
1887   "  --alive      Mark <host> as alive\n"
1888   "\n"
1889   "If called without arguments list all configured keyserver URLs.\n"
1890   "If called with an URI add this as keyserver.  Note that keyservers\n"
1891   "are configured on a per-session base.  A default keyserver may already be\n"
1892   "present, thus the \"--clear\" option must be used to get full control.\n"
1893   "If \"--clear\" and an URI are used together the clear command is\n"
1894   "obviously executed first.  A RESET command does not change the list\n"
1895   "of configured keyservers.";
1896 static gpg_error_t
1897 cmd_keyserver (assuan_context_t ctx, char *line)
1898 {
1899   ctrl_t ctrl = assuan_get_pointer (ctx);
1900   gpg_error_t err = 0;
1901   int clear_flag, add_flag, help_flag, host_flag, resolve_flag;
1902   int dead_flag, alive_flag;
1903   uri_item_t item = NULL; /* gcc 4.4.5 is not able to detect that it
1904                              is always initialized.  */
1905
1906   clear_flag = has_option (line, "--clear");
1907   help_flag = has_option (line, "--help");
1908   resolve_flag = has_option (line, "--resolve");
1909   host_flag = has_option (line, "--hosttable");
1910   dead_flag = has_option (line, "--dead");
1911   alive_flag = has_option (line, "--alive");
1912   line = skip_options (line);
1913   add_flag = !!*line;
1914
1915   if (help_flag)
1916     {
1917       err = ks_action_help (ctrl, line);
1918       goto leave;
1919     }
1920
1921   if (resolve_flag)
1922     {
1923       err = ensure_keyserver (ctrl);
1924       if (!err)
1925         err = ks_action_resolve (ctrl, ctrl->server_local->keyservers);
1926       if (err)
1927         goto leave;
1928     }
1929
1930   if (alive_flag && dead_flag)
1931     {
1932       err = set_error (GPG_ERR_ASS_PARAMETER, "no support for zombies");
1933       goto leave;
1934     }
1935   if (dead_flag)
1936     {
1937       err = check_owner_permission (ctx, "no permission to use --dead");
1938       if (err)
1939         goto leave;
1940     }
1941   if (alive_flag || dead_flag)
1942     {
1943       if (!*line)
1944         {
1945           err = set_error (GPG_ERR_ASS_PARAMETER, "name of host missing");
1946           goto leave;
1947         }
1948
1949       err = ks_hkp_mark_host (ctrl, line, alive_flag);
1950       if (err)
1951         goto leave;
1952     }
1953
1954   if (host_flag)
1955     {
1956       err = ks_hkp_print_hosttable (ctrl);
1957       if (err)
1958         goto leave;
1959     }
1960   if (resolve_flag || host_flag || alive_flag || dead_flag)
1961     goto leave;
1962
1963   if (add_flag)
1964     {
1965       err = make_keyserver_item (line, &item);
1966       if (err)
1967         goto leave;
1968     }
1969   if (clear_flag)
1970     release_ctrl_keyservers (ctrl);
1971   if (add_flag)
1972     {
1973       item->next = ctrl->server_local->keyservers;
1974       ctrl->server_local->keyservers = item;
1975     }
1976
1977   if (!add_flag && !clear_flag && !help_flag)
1978     {
1979       /* List configured keyservers.  However, we first add a global
1980          keyserver. */
1981       uri_item_t u;
1982
1983       err = ensure_keyserver (ctrl);
1984       if (err)
1985         {
1986           assuan_set_error (ctx, err,
1987                             "Bad keyserver configuration in dirmngr.conf");
1988           goto leave;
1989         }
1990
1991       for (u=ctrl->server_local->keyservers; u; u = u->next)
1992         dirmngr_status (ctrl, "KEYSERVER", u->uri, NULL);
1993     }
1994   err = 0;
1995
1996  leave:
1997   return leave_cmd (ctx, err);
1998 }
1999
2000
2001 \f
2002 static const char hlp_ks_search[] =
2003   "KS_SEARCH {<pattern>}\n"
2004   "\n"
2005   "Search the configured OpenPGP keyservers (see command KEYSERVER)\n"
2006   "for keys matching PATTERN";
2007 static gpg_error_t
2008 cmd_ks_search (assuan_context_t ctx, char *line)
2009 {
2010   ctrl_t ctrl = assuan_get_pointer (ctx);
2011   gpg_error_t err;
2012   strlist_t list, sl;
2013   char *p;
2014   estream_t outfp;
2015
2016   /* No options for now.  */
2017   line = skip_options (line);
2018
2019   /* Break the line down into an strlist.  Each pattern is
2020      percent-plus escaped. */
2021   list = NULL;
2022   for (p=line; *p; line = p)
2023     {
2024       while (*p && *p != ' ')
2025         p++;
2026       if (*p)
2027         *p++ = 0;
2028       if (*line)
2029         {
2030           sl = xtrymalloc (sizeof *sl + strlen (line));
2031           if (!sl)
2032             {
2033               err = gpg_error_from_syserror ();
2034               goto leave;
2035             }
2036           sl->flags = 0;
2037           strcpy_escaped_plus (sl->d, line);
2038           sl->next = list;
2039           list = sl;
2040         }
2041     }
2042
2043   err = ensure_keyserver (ctrl);
2044   if (err)
2045     goto leave;
2046
2047   /* Setup an output stream and perform the search.  */
2048   outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
2049   if (!outfp)
2050     err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2051   else
2052     {
2053       err = ks_action_search (ctrl, ctrl->server_local->keyservers,
2054                               list, outfp);
2055       es_fclose (outfp);
2056     }
2057
2058  leave:
2059   free_strlist (list);
2060   return leave_cmd (ctx, err);
2061 }
2062
2063
2064 \f
2065 static const char hlp_ks_get[] =
2066   "KS_GET {<pattern>}\n"
2067   "\n"
2068   "Get the keys matching PATTERN from the configured OpenPGP keyservers\n"
2069   "(see command KEYSERVER).  Each pattern should be a keyid, a fingerprint,\n"
2070   "or an exact name indicated by the '=' prefix.";
2071 static gpg_error_t
2072 cmd_ks_get (assuan_context_t ctx, char *line)
2073 {
2074   ctrl_t ctrl = assuan_get_pointer (ctx);
2075   gpg_error_t err;
2076   strlist_t list, sl;
2077   char *p;
2078   estream_t outfp;
2079
2080   /* No options for now.  */
2081   line = skip_options (line);
2082
2083   /* Break the line into a strlist.  Each pattern is by
2084      definition percent-plus escaped.  However we only support keyids
2085      and fingerprints and thus the client has no need to apply the
2086      escaping.  */
2087   list = NULL;
2088   for (p=line; *p; line = p)
2089     {
2090       while (*p && *p != ' ')
2091         p++;
2092       if (*p)
2093         *p++ = 0;
2094       if (*line)
2095         {
2096           sl = xtrymalloc (sizeof *sl + strlen (line));
2097           if (!sl)
2098             {
2099               err = gpg_error_from_syserror ();
2100               goto leave;
2101             }
2102           sl->flags = 0;
2103           strcpy_escaped_plus (sl->d, line);
2104           sl->next = list;
2105           list = sl;
2106         }
2107     }
2108
2109   err = ensure_keyserver (ctrl);
2110   if (err)
2111     goto leave;
2112
2113   /* Setup an output stream and perform the get.  */
2114   outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
2115   if (!outfp)
2116     err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2117   else
2118     {
2119       ctrl->server_local->inhibit_data_logging = 1;
2120       ctrl->server_local->inhibit_data_logging_now = 0;
2121       ctrl->server_local->inhibit_data_logging_count = 0;
2122       err = ks_action_get (ctrl, ctrl->server_local->keyservers, list, outfp);
2123       es_fclose (outfp);
2124       ctrl->server_local->inhibit_data_logging = 0;
2125     }
2126
2127  leave:
2128   free_strlist (list);
2129   return leave_cmd (ctx, err);
2130 }
2131
2132
2133 static const char hlp_ks_fetch[] =
2134   "KS_FETCH <URL>\n"
2135   "\n"
2136   "Get the key(s) from URL.";
2137 static gpg_error_t
2138 cmd_ks_fetch (assuan_context_t ctx, char *line)
2139 {
2140   ctrl_t ctrl = assuan_get_pointer (ctx);
2141   gpg_error_t err;
2142   estream_t outfp;
2143
2144   /* No options for now.  */
2145   line = skip_options (line);
2146
2147   err = ensure_keyserver (ctrl);  /* FIXME: Why do we needs this here?  */
2148   if (err)
2149     goto leave;
2150
2151   /* Setup an output stream and perform the get.  */
2152   outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
2153   if (!outfp)
2154     err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
2155   else
2156     {
2157       ctrl->server_local->inhibit_data_logging = 1;
2158       ctrl->server_local->inhibit_data_logging_now = 0;
2159       ctrl->server_local->inhibit_data_logging_count = 0;
2160       err = ks_action_fetch (ctrl, line, outfp);
2161       es_fclose (outfp);
2162       ctrl->server_local->inhibit_data_logging = 0;
2163     }
2164
2165  leave:
2166   return leave_cmd (ctx, err);
2167 }
2168
2169
2170 \f
2171 static const char hlp_ks_put[] =
2172   "KS_PUT\n"
2173   "\n"
2174   "Send a key to the configured OpenPGP keyservers.  The actual key material\n"
2175   "is then requested by Dirmngr using\n"
2176   "\n"
2177   "  INQUIRE KEYBLOCK\n"
2178   "\n"
2179   "The client shall respond with a binary version of the keyblock (e.g.,\n"
2180   "the output of `gpg --export KEYID').  For LDAP\n"
2181   "keyservers Dirmngr may ask for meta information of the provided keyblock\n"
2182   "using:\n"
2183   "\n"
2184   "  INQUIRE KEYBLOCK_INFO\n"
2185   "\n"
2186   "The client shall respond with a colon delimited info lines (the output\n"
2187   "of 'for x in keys sigs; do gpg --list-$x --with-colons KEYID; done').\n";
2188 static gpg_error_t
2189 cmd_ks_put (assuan_context_t ctx, char *line)
2190 {
2191   ctrl_t ctrl = assuan_get_pointer (ctx);
2192   gpg_error_t err;
2193   unsigned char *value = NULL;
2194   size_t valuelen;
2195   unsigned char *info = NULL;
2196   size_t infolen;
2197
2198   /* No options for now.  */
2199   line = skip_options (line);
2200
2201   err = ensure_keyserver (ctrl);
2202   if (err)
2203     goto leave;
2204
2205   /* Ask for the key material.  */
2206   err = assuan_inquire (ctx, "KEYBLOCK",
2207                         &value, &valuelen, MAX_KEYBLOCK_LENGTH);
2208   if (err)
2209     {
2210       log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
2211       goto leave;
2212     }
2213
2214   if (!valuelen) /* No data returned; return a comprehensible error. */
2215     {
2216       err = gpg_error (GPG_ERR_MISSING_CERT);
2217       goto leave;
2218     }
2219
2220   /* Ask for the key meta data. Not actually needed for HKP servers
2221      but we do it anyway to test the client implementaion.  */
2222   err = assuan_inquire (ctx, "KEYBLOCK_INFO",
2223                         &info, &infolen, MAX_KEYBLOCK_LENGTH);
2224   if (err)
2225     {
2226       log_error (_("assuan_inquire failed: %s\n"), gpg_strerror (err));
2227       goto leave;
2228     }
2229
2230   /* Send the key.  */
2231   err = ks_action_put (ctrl, ctrl->server_local->keyservers,
2232                        value, valuelen, info, infolen);
2233
2234  leave:
2235   xfree (info);
2236   xfree (value);
2237   return leave_cmd (ctx, err);
2238 }
2239
2240
2241
2242 \f
2243 static const char hlp_getinfo[] =
2244   "GETINFO <what>\n"
2245   "\n"
2246   "Multi purpose command to return certain information.  \n"
2247   "Supported values of WHAT are:\n"
2248   "\n"
2249   "version     - Return the version of the program.\n"
2250   "pid         - Return the process id of the server.\n"
2251   "tor         - Return OK if running in Tor mode\n"
2252   "dnsinfo     - Return info about the DNS resolver\n"
2253   "socket_name - Return the name of the socket.\n";
2254 static gpg_error_t
2255 cmd_getinfo (assuan_context_t ctx, char *line)
2256 {
2257   ctrl_t ctrl = assuan_get_pointer (ctx);
2258   gpg_error_t err;
2259
2260   if (!strcmp (line, "version"))
2261     {
2262       const char *s = VERSION;
2263       err = assuan_send_data (ctx, s, strlen (s));
2264     }
2265   else if (!strcmp (line, "pid"))
2266     {
2267       char numbuf[50];
2268
2269       snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
2270       err = assuan_send_data (ctx, numbuf, strlen (numbuf));
2271     }
2272   else if (!strcmp (line, "socket_name"))
2273     {
2274       const char *s = dirmngr_socket_name ();
2275       err = assuan_send_data (ctx, s, strlen (s));
2276     }
2277   else if (!strcmp (line, "tor"))
2278     {
2279       if (opt.use_tor)
2280         {
2281           if (!is_tor_running (ctrl))
2282             err = assuan_write_status (ctx, "NO_TOR", "Tor not running");
2283           else
2284             err = 0;
2285           if (!err)
2286             assuan_set_okay_line (ctx, "- Tor mode is enabled");
2287         }
2288       else
2289         err = set_error (GPG_ERR_FALSE, "Tor mode is NOT enabled");
2290     }
2291   else if (!strcmp (line, "dnsinfo"))
2292     {
2293 #if USE_ADNS && HAVE_ADNS_IF_TORMODE
2294       assuan_set_okay_line (ctx, "- ADNS with Tor support");
2295 #elif USE_ADNS
2296       assuan_set_okay_line (ctx, "- ADNS w/o Tor support");
2297 #else
2298       assuan_set_okay_line (ctx, "- System resolver w/o Tor support");
2299 #endif
2300       err = 0;
2301     }
2302   else
2303     err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
2304
2305   return leave_cmd (ctx, err);
2306 }
2307
2308
2309 \f
2310 static const char hlp_killdirmngr[] =
2311   "KILLDIRMNGR\n"
2312   "\n"
2313   "This command allows a user - given sufficient permissions -\n"
2314   "to kill this dirmngr process.\n";
2315 static gpg_error_t
2316 cmd_killdirmngr (assuan_context_t ctx, char *line)
2317 {
2318   ctrl_t ctrl = assuan_get_pointer (ctx);
2319
2320   (void)line;
2321
2322   ctrl->server_local->stopme = 1;
2323   assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
2324   return gpg_error (GPG_ERR_EOF);
2325 }
2326
2327
2328 static const char hlp_reloaddirmngr[] =
2329   "RELOADDIRMNGR\n"
2330   "\n"
2331   "This command is an alternative to SIGHUP\n"
2332   "to reload the configuration.";
2333 static gpg_error_t
2334 cmd_reloaddirmngr (assuan_context_t ctx, char *line)
2335 {
2336   (void)ctx;
2337   (void)line;
2338
2339   dirmngr_sighup_action ();
2340   return 0;
2341 }
2342
2343
2344 \f
2345 static const char*
2346 parse_version_number (const char *s, int *number)
2347 {
2348   int val = 0;
2349
2350   if (*s == '0' && digitp (&s[1]))
2351     return NULL;  /* Leading zeros are not allowed.  */
2352   for (; digitp (s); s++)
2353     {
2354       val *= 10;
2355       val += *s - '0';
2356     }
2357   *number = val;
2358   return val < 0 ? NULL : s;
2359 }
2360
2361
2362 static const char *
2363 parse_version_string (const char *s, int *major, int *minor)
2364 {
2365   s = parse_version_number (s, major);
2366   if (!s || *s != '.')
2367     return NULL;
2368   s++;
2369   s = parse_version_number (s, minor);
2370   if (!s)
2371     return NULL;
2372   return s;  /* Patchlevel.  */
2373 }
2374
2375 /* Class Confucius.
2376
2377    "Don't worry that other people don't know you;
2378    worry that you don't know other people."            Analects--1.16.  */
2379
2380 /* Create temporary directory with mode 0700.  Returns a dynamically
2381    allocated string with the filename of the directory.  */
2382 static char *
2383 confucius_mktmpdir (void)
2384 {
2385   char *name, *p;
2386
2387   p = getenv ("TMPDIR");
2388   if (!p || !*p)
2389     p = "/tmp";
2390   if (p[strlen (p) - 1] == '/')
2391     name = xstrconcat (p, "gpg-XXXXXX", NULL);
2392   else
2393     name = xstrconcat (p, "/", "gpg-XXXXXX", NULL);
2394   if (!name || !gnupg_mkdtemp (name))
2395     {
2396       log_error (_("can't create temporary directory '%s': %s\n"),
2397                  name?name:"", strerror (errno));
2398       return NULL;
2399     }
2400
2401   return name;
2402 }
2403
2404 /* Sets result to -1 if version a is less than b, 0 if the versions are equal
2405  * and 1 otherwise. Patch levels are compared as strings.  */
2406 static gpg_error_t
2407 cmp_version (const char *a, const char *b, int *result)
2408 {
2409   int a_major, b_major;
2410   int a_minor, b_minor;
2411   const char *a_patch, *b_patch;
2412
2413   if (!a || !b || !result)
2414     return GPG_ERR_EINVAL;
2415
2416   a_patch = parse_version_string (a, &a_major, &a_minor);
2417   b_patch = parse_version_string (b, &b_major, &b_minor);
2418
2419   if (!a_patch || !b_patch)
2420     return GPG_ERR_EINVAL;
2421
2422   if (a_major == b_major)
2423     {
2424       if (a_minor == b_minor)
2425         *result = strcmp (a_patch, b_patch);
2426       else
2427         *result = a_minor - b_minor;
2428     }
2429   else
2430     *result = a_major - b_major;
2431
2432   return 0;
2433 }
2434
2435 static gpg_error_t
2436 fetch_into_tmpdir (ctrl_t ctrl, const char* url, estream_t* strm_out,
2437                    char** path)
2438 {
2439   gpg_error_t err;
2440   char* filename = NULL;
2441   char* dirname = NULL;
2442   estream_t file;
2443   estream_t strm;
2444   size_t len = 0;
2445   char buf[1024];
2446
2447   if (!strm_out || !path || !url)
2448     {
2449       err = (GPG_ERR_INV_ARG);
2450       goto leave;
2451     }
2452
2453   dirname = confucius_mktmpdir ();
2454   if (!dirname)
2455     {
2456       err = gpg_error_from_syserror ();
2457       goto leave;
2458     }
2459
2460   filename = strconcat (dirname, DIRSEP_S, "file", NULL);
2461   if (!filename)
2462     {
2463       err = gpg_error_from_syserror ();
2464       goto leave;
2465     }
2466
2467   file = es_fopen (filename, "w+");
2468
2469   if ((err = ks_http_fetch (ctrl, url, &strm)))
2470     goto leave;
2471
2472   while (!es_read (strm, buf, sizeof buf, &len))
2473     {
2474       if (!len)
2475         break;
2476       if ((err = es_write (file, buf, len, NULL)))
2477         {
2478           log_error ("error writing message to pipe: %s\n", gpg_strerror (err));
2479           es_free (strm);
2480           goto leave;
2481         }
2482     }
2483
2484   es_rewind (file);
2485   es_fclose (strm);
2486   *strm_out = file;
2487   err = 0;
2488
2489   if (path)
2490     {
2491     *path = dirname;
2492     dirname = NULL;
2493     }
2494
2495 leave:
2496   xfree (dirname);
2497   xfree (filename);
2498   return err;
2499 }
2500
2501 static const char hlp_versioncheck[] =
2502   "VERSIONCHECK <name> <version>"
2503   "\n"
2504   "Checks the internet to find whenever a new program version is available."
2505   "\n"
2506   "<name> program name i.e. \"gnupg\""
2507   "<version> current version of the program i.e. \"2.0.2\"";
2508 static gpg_error_t
2509 cmd_versioncheck (assuan_context_t ctx, char *line)
2510 {
2511   gpg_error_t err;
2512
2513   char* name;
2514   char* version;
2515   size_t name_len;
2516   char *cmd_fields[2];
2517
2518   ctrl_t ctrl;
2519   estream_t swdb;
2520   estream_t swdb_sig;
2521   char* swdb_dir = NULL;
2522   char* swdb_sig_dir = NULL;
2523   char* buf = NULL;
2524   size_t len = 0;
2525   const char *argv[8];
2526   char keyring_path[128];
2527   char swdb_path[128];
2528   char swdb_sig_path[128];
2529
2530   swdb_path[0] = 0;
2531   swdb_sig_path[0] = 0;
2532   ctrl = assuan_get_pointer (ctx);
2533
2534   if (split_fields (line, &cmd_fields, 2) != 2)
2535     {
2536       err = set_error (GPG_ERR_ASS_PARAMETER,
2537                        "No program name and/or version given");
2538       goto out;
2539     }
2540
2541   name = cmd_fields[0];
2542   name_len = strlen (name);
2543   version = cmd_fields[1];
2544
2545   if ((err = fetch_into_tmpdir (ctrl, "https://versions.gnupg.org/swdb.lst",
2546                                 &swdb, &swdb_dir)))
2547     goto out;
2548
2549   snprintf (swdb_path, sizeof swdb_path, "%s%s%s", swdb_dir, DIRSEP_S, "file");
2550
2551   if ((err = fetch_into_tmpdir (ctrl, "https://versions.gnupg.org/swdb.lst.sig",
2552                                 &swdb_sig, &swdb_sig_dir)))
2553     goto out;
2554
2555   snprintf (keyring_path, sizeof keyring_path, "%s%s%s", gnupg_datadir (),
2556            DIRSEP_S, "distsigkey.gpg");
2557   snprintf (swdb_sig_path, sizeof swdb_sig_path, "%s%s%s", swdb_sig_dir,
2558            DIRSEP_S, "file");
2559
2560   argv[0] = "--batch";
2561   argv[1] = "--no-default-keyring";
2562   argv[2] = "--keyring";
2563   argv[3] = keyring_path;
2564   argv[4] = "--verify";
2565   argv[5] = swdb_sig_path;
2566   argv[6] = "-";
2567   argv[7] = NULL;
2568
2569   if ((err = gnupg_exec_tool_stream (gnupg_module_name (GNUPG_MODULE_NAME_GPG),
2570                                      argv, swdb, NULL, NULL, NULL, NULL)))
2571     goto out;
2572
2573   es_fseek (swdb, 0, SEEK_SET);
2574
2575   while (es_getline (&buf, &len, swdb) > 0)
2576     {
2577       if (len > name_len + 5 &&
2578           strncmp (buf, name, name_len) == 0 &&
2579           strncmp (buf + name_len, "_ver ", 5) == 0)
2580         {
2581           const char* this_ver_start = buf + name_len + 5;
2582           char* this_ver_end = strchr (this_ver_start, '\n');
2583           int cmp;
2584
2585           if (this_ver_end)
2586             *this_ver_end = 0;
2587
2588           err = assuan_write_status (ctx, "LINE", buf);
2589
2590           err = cmp_version (this_ver_start, version, &cmp);
2591           if (err > 0)
2592             goto out;
2593
2594           if (cmp < 0)
2595             err = assuan_send_data (ctx, "ROLLBACK", strlen ("ROLLBACK"));
2596           else if (cmp == 0)
2597             err = assuan_send_data (ctx, "CURRENT", strlen ("CURRENT"));
2598           else
2599             err = assuan_send_data (ctx, "UPDATE", strlen ("UPDATE"));
2600
2601           goto out;
2602         }
2603     }
2604
2605   err = assuan_send_data (ctx, "NOT_FOUND", strlen ("NOT_FOUND"));
2606
2607   out:
2608   es_fclose (swdb);
2609   es_fclose (swdb_sig);
2610   xfree (buf);
2611
2612   if (strlen (swdb_path) > 0)
2613     unlink (swdb_path);
2614   if (swdb_dir)
2615     rmdir (swdb_dir);
2616   xfree (swdb_dir);
2617
2618   if (strlen (swdb_sig_path) > 0)
2619     unlink (swdb_sig_path);
2620   if (swdb_sig_dir)
2621     rmdir (swdb_sig_dir);
2622   xfree (swdb_sig_dir);
2623
2624   return leave_cmd (ctx, err);
2625 }
2626
2627
2628 \f
2629 /* Tell the assuan library about our commands. */
2630 static int
2631 register_commands (assuan_context_t ctx)
2632 {
2633   static struct {
2634     const char *name;
2635     assuan_handler_t handler;
2636     const char * const help;
2637   } table[] = {
2638     { "DNS_CERT",   cmd_dns_cert,   hlp_dns_cert },
2639     { "WKD_GET",    cmd_wkd_get,    hlp_wkd_get },
2640     { "LDAPSERVER", cmd_ldapserver, hlp_ldapserver },
2641     { "ISVALID",    cmd_isvalid,    hlp_isvalid },
2642     { "CHECKCRL",   cmd_checkcrl,   hlp_checkcrl },
2643     { "CHECKOCSP",  cmd_checkocsp,  hlp_checkocsp },
2644     { "LOOKUP",     cmd_lookup,     hlp_lookup },
2645     { "LOADCRL",    cmd_loadcrl,    hlp_loadcrl },
2646     { "LISTCRLS",   cmd_listcrls,   hlp_listcrls },
2647     { "CACHECERT",  cmd_cachecert,  hlp_cachecert },
2648     { "VALIDATE",   cmd_validate,   hlp_validate },
2649     { "KEYSERVER",  cmd_keyserver,  hlp_keyserver },
2650     { "KS_SEARCH",  cmd_ks_search,  hlp_ks_search },
2651     { "KS_GET",     cmd_ks_get,     hlp_ks_get },
2652     { "KS_FETCH",   cmd_ks_fetch,   hlp_ks_fetch },
2653     { "KS_PUT",     cmd_ks_put,     hlp_ks_put },
2654     { "GETINFO",    cmd_getinfo,    hlp_getinfo },
2655     { "KILLDIRMNGR",cmd_killdirmngr,hlp_killdirmngr },
2656     { "RELOADDIRMNGR",cmd_reloaddirmngr,hlp_reloaddirmngr },
2657     { "VERSIONCHECK",cmd_versioncheck,hlp_versioncheck },
2658     { NULL, NULL }
2659   };
2660   int i, j, rc;
2661
2662   for (i=j=0; table[i].name; i++)
2663     {
2664       rc = assuan_register_command (ctx, table[i].name, table[i].handler,
2665                                     table[i].help);
2666       if (rc)
2667         return rc;
2668     }
2669   return 0;
2670 }
2671
2672
2673 /* Note that we do not reset the list of configured keyservers.  */
2674 static gpg_error_t
2675 reset_notify (assuan_context_t ctx, char *line)
2676 {
2677   ctrl_t ctrl = assuan_get_pointer (ctx);
2678   (void)line;
2679
2680 #if USE_LDAP
2681   ldapserver_list_free (ctrl->server_local->ldapservers);
2682 #endif /*USE_LDAP*/
2683   ctrl->server_local->ldapservers = NULL;
2684   return 0;
2685 }
2686
2687
2688 /* This function is called by our assuan log handler to test whether a
2689  * log message shall really be printed.  The function must return
2690  * false to inhibit the logging of MSG.  CAT gives the requested log
2691  * category.  MSG might be NULL. */
2692 int
2693 dirmngr_assuan_log_monitor (assuan_context_t ctx, unsigned int cat,
2694                             const char *msg)
2695 {
2696   ctrl_t ctrl = assuan_get_pointer (ctx);
2697
2698   (void)cat;
2699   (void)msg;
2700
2701   if (!ctrl || !ctrl->server_local)
2702     return 1; /* Can't decide - allow logging.  */
2703
2704   if (!ctrl->server_local->inhibit_data_logging)
2705     return 1; /* Not requested - allow logging.  */
2706
2707   /* Disallow logging if *_now is true.  */
2708   return !ctrl->server_local->inhibit_data_logging_now;
2709 }
2710
2711
2712 /* Startup the server and run the main command loop.  With FD = -1,
2713    use stdin/stdout. */
2714 void
2715 start_command_handler (assuan_fd_t fd)
2716 {
2717   static const char hello[] = "Dirmngr " VERSION " at your service";
2718   static char *hello_line;
2719   int rc;
2720   assuan_context_t ctx;
2721   ctrl_t ctrl;
2722
2723   ctrl = xtrycalloc (1, sizeof *ctrl);
2724   if (ctrl)
2725     ctrl->server_local = xtrycalloc (1, sizeof *ctrl->server_local);
2726   if (!ctrl || !ctrl->server_local)
2727     {
2728       log_error (_("can't allocate control structure: %s\n"),
2729                  strerror (errno));
2730       xfree (ctrl);
2731       return;
2732     }
2733
2734   dirmngr_init_default_ctrl (ctrl);
2735
2736   rc = assuan_new (&ctx);
2737   if (rc)
2738     {
2739       log_error (_("failed to allocate assuan context: %s\n"),
2740                  gpg_strerror (rc));
2741       dirmngr_exit (2);
2742     }
2743
2744   if (fd == ASSUAN_INVALID_FD)
2745     {
2746       assuan_fd_t filedes[2];
2747
2748       filedes[0] = assuan_fdopen (0);
2749       filedes[1] = assuan_fdopen (1);
2750       rc = assuan_init_pipe_server (ctx, filedes);
2751     }
2752   else
2753     {
2754       rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED);
2755     }
2756
2757   if (rc)
2758     {
2759       assuan_release (ctx);
2760       log_error (_("failed to initialize the server: %s\n"),
2761                  gpg_strerror(rc));
2762       dirmngr_exit (2);
2763     }
2764
2765   rc = register_commands (ctx);
2766   if (rc)
2767     {
2768       log_error (_("failed to the register commands with Assuan: %s\n"),
2769                  gpg_strerror(rc));
2770       dirmngr_exit (2);
2771     }
2772
2773
2774   if (!hello_line)
2775     {
2776       hello_line = xtryasprintf
2777         ("Home: %s\n"
2778          "Config: %s\n"
2779          "%s",
2780          gnupg_homedir (),
2781          opt.config_filename? opt.config_filename : "[none]",
2782          hello);
2783     }
2784
2785   ctrl->server_local->assuan_ctx = ctx;
2786   assuan_set_pointer (ctx, ctrl);
2787
2788   assuan_set_hello_line (ctx, hello_line);
2789   assuan_register_option_handler (ctx, option_handler);
2790   assuan_register_reset_notify (ctx, reset_notify);
2791
2792   for (;;)
2793     {
2794       rc = assuan_accept (ctx);
2795       if (rc == -1)
2796         break;
2797       if (rc)
2798         {
2799           log_info (_("Assuan accept problem: %s\n"), gpg_strerror (rc));
2800           break;
2801         }
2802
2803 #ifndef HAVE_W32_SYSTEM
2804       if (opt.verbose)
2805         {
2806           assuan_peercred_t peercred;
2807
2808           if (!assuan_get_peercred (ctx, &peercred))
2809             log_info ("connection from process %ld (%ld:%ld)\n",
2810                       (long)peercred->pid, (long)peercred->uid,
2811                       (long)peercred->gid);
2812         }
2813 #endif
2814
2815       rc = assuan_process (ctx);
2816       if (rc)
2817         {
2818           log_info (_("Assuan processing failed: %s\n"), gpg_strerror (rc));
2819           continue;
2820         }
2821     }
2822
2823
2824 #if USE_LDAP
2825   ldap_wrapper_connection_cleanup (ctrl);
2826
2827   ldapserver_list_free (ctrl->server_local->ldapservers);
2828 #endif /*USE_LDAP*/
2829   ctrl->server_local->ldapservers = NULL;
2830
2831   release_ctrl_keyservers (ctrl);
2832
2833   ctrl->server_local->assuan_ctx = NULL;
2834   assuan_release (ctx);
2835
2836   if (ctrl->server_local->stopme)
2837     dirmngr_exit (0);
2838
2839   if (ctrl->refcount)
2840     log_error ("oops: connection control structure still referenced (%d)\n",
2841                ctrl->refcount);
2842   else
2843     {
2844       release_ctrl_ocsp_certs (ctrl);
2845       xfree (ctrl->server_local);
2846       dirmngr_deinit_default_ctrl (ctrl);
2847       xfree (ctrl);
2848     }
2849 }
2850
2851
2852 /* Send a status line back to the client.  KEYWORD is the status
2853    keyword, the optional string arguments are blank separated added to
2854    the line, the last argument must be a NULL. */
2855 gpg_error_t
2856 dirmngr_status (ctrl_t ctrl, const char *keyword, ...)
2857 {
2858   gpg_error_t err = 0;
2859   va_list arg_ptr;
2860   const char *text;
2861
2862   va_start (arg_ptr, keyword);
2863
2864   if (ctrl->server_local)
2865     {
2866       assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2867       char buf[950], *p;
2868       size_t n;
2869
2870       p = buf;
2871       n = 0;
2872       while ( (text = va_arg (arg_ptr, const char *)) )
2873         {
2874           if (n)
2875             {
2876               *p++ = ' ';
2877               n++;
2878             }
2879           for ( ; *text && n < DIM (buf)-2; n++)
2880             *p++ = *text++;
2881         }
2882       *p = 0;
2883       err = assuan_write_status (ctx, keyword, buf);
2884     }
2885
2886   va_end (arg_ptr);
2887   return err;
2888 }
2889
2890
2891 /* Print a help status line.  TEXTLEN gives the length of the text
2892    from TEXT to be printed.  The function splits text at LFs.  */
2893 gpg_error_t
2894 dirmngr_status_help (ctrl_t ctrl, const char *text)
2895 {
2896   gpg_error_t err = 0;
2897
2898   if (ctrl->server_local)
2899     {
2900       assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2901       char buf[950], *p;
2902       size_t n;
2903
2904       do
2905         {
2906           p = buf;
2907           n = 0;
2908           for ( ; *text && *text != '\n' && n < DIM (buf)-2; n++)
2909             *p++ = *text++;
2910           if (*text == '\n')
2911             text++;
2912           *p = 0;
2913           err = assuan_write_status (ctx, "#", buf);
2914         }
2915       while (!err && *text);
2916     }
2917
2918   return err;
2919 }
2920
2921 /* Send a tick progress indicator back.  Fixme: This is only done for
2922    the currently active channel.  */
2923 gpg_error_t
2924 dirmngr_tick (ctrl_t ctrl)
2925 {
2926   static time_t next_tick = 0;
2927   gpg_error_t err = 0;
2928   time_t now = time (NULL);
2929
2930   if (!next_tick)
2931     {
2932       next_tick = now + 1;
2933     }
2934   else if ( now > next_tick )
2935     {
2936       if (ctrl)
2937         {
2938           err = dirmngr_status (ctrl, "PROGRESS", "tick", "? 0 0", NULL);
2939           if (err)
2940             {
2941               /* Take this as in indication for a cancel request.  */
2942               err = gpg_error (GPG_ERR_CANCELED);
2943             }
2944           now = time (NULL);
2945         }
2946
2947       next_tick = now + 1;
2948     }
2949   return err;
2950 }