gpg: No need to create a trustdb when encrypting with --always-trust.
[gnupg.git] / sm / call-dirmngr.c
1 /* call-dirmngr.c - communication with the dromngr
2  * Copyright (C) 2002, 2003, 2005, 2007, 2008 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <unistd.h>
26 #include <time.h>
27 #include <assert.h>
28 #include <ctype.h>
29
30 #include "gpgsm.h"
31 #include <gcrypt.h>
32 #include <assuan.h>
33
34 #include "i18n.h"
35 #include "keydb.h"
36
37
38 struct membuf {
39   size_t len;
40   size_t size;
41   char *buf;
42   int out_of_core;
43 };
44
45
46
47 /* fixme: We need a context for each thread or serialize the access to
48    the dirmngr.  */
49 static assuan_context_t dirmngr_ctx = NULL;
50 static assuan_context_t dirmngr2_ctx = NULL;
51
52 static int dirmngr_ctx_locked;
53 static int dirmngr2_ctx_locked;
54
55 static int force_pipe_server = 0;
56
57 struct inq_certificate_parm_s {
58   ctrl_t ctrl;
59   assuan_context_t ctx;
60   ksba_cert_t cert;
61   ksba_cert_t issuer_cert;
62 };
63
64 struct isvalid_status_parm_s {
65   ctrl_t ctrl;
66   int seen;
67   unsigned char fpr[20];
68 };
69
70
71 struct lookup_parm_s {
72   ctrl_t ctrl;
73   assuan_context_t ctx;
74   void (*cb)(void *, ksba_cert_t);
75   void *cb_value;
76   struct membuf data;
77   int error;
78 };
79
80 struct run_command_parm_s {
81   assuan_context_t ctx;
82 };
83
84
85
86 static gpg_error_t get_cached_cert (assuan_context_t ctx,
87                                     const unsigned char *fpr,
88                                     ksba_cert_t *r_cert);
89
90
91 \f
92 /* A simple implementation of a dynamic buffer.  Use init_membuf() to
93    create a buffer, put_membuf to append bytes and get_membuf to
94    release and return the buffer.  Allocation errors are detected but
95    only returned at the final get_membuf(), this helps not to clutter
96    the code with out of core checks.  */
97
98 static void
99 init_membuf (struct membuf *mb, int initiallen)
100 {
101   mb->len = 0;
102   mb->size = initiallen;
103   mb->out_of_core = 0;
104   mb->buf = xtrymalloc (initiallen);
105   if (!mb->buf)
106       mb->out_of_core = 1;
107 }
108
109 static void
110 put_membuf (struct membuf *mb, const void *buf, size_t len)
111 {
112   if (mb->out_of_core)
113     return;
114
115   if (mb->len + len >= mb->size)
116     {
117       char *p;
118
119       mb->size += len + 1024;
120       p = xtryrealloc (mb->buf, mb->size);
121       if (!p)
122         {
123           mb->out_of_core = 1;
124           return;
125         }
126       mb->buf = p;
127     }
128   memcpy (mb->buf + mb->len, buf, len);
129   mb->len += len;
130 }
131
132 static void *
133 get_membuf (struct membuf *mb, size_t *len)
134 {
135   char *p;
136
137   if (mb->out_of_core)
138     {
139       xfree (mb->buf);
140       mb->buf = NULL;
141       return NULL;
142     }
143
144   p = mb->buf;
145   *len = mb->len;
146   mb->buf = NULL;
147   mb->out_of_core = 1; /* don't allow a reuse */
148   return p;
149 }
150
151
152 /* This function prepares the dirmngr for a new session.  The
153    audit-events option is used so that other dirmngr clients won't get
154    disturbed by such events.  */
155 static void
156 prepare_dirmngr (ctrl_t ctrl, assuan_context_t ctx, gpg_error_t err)
157 {
158   struct keyserver_spec *server;
159
160   if (!err)
161     {
162       err = assuan_transact (ctx, "OPTION audit-events=1",
163                              NULL, NULL, NULL, NULL, NULL, NULL);
164       if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION)
165         err = 0;  /* Allow the use of old dirmngr versions.  */
166     }
167   audit_log_ok (ctrl->audit, AUDIT_DIRMNGR_READY, err);
168
169   if (!ctx || err)
170     return;
171
172   server = opt.keyserver;
173   while (server)
174     {
175       char line[ASSUAN_LINELENGTH];
176       char *user = server->user ? server->user : "";
177       char *pass = server->pass ? server->pass : "";
178       char *base = server->base ? server->base : "";
179
180       snprintf (line, DIM (line) - 1, "LDAPSERVER %s:%i:%s:%s:%s",
181                 server->host, server->port, user, pass, base);
182       line[DIM (line) - 1] = 0;
183
184       err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
185       if (gpg_err_code (err) == GPG_ERR_ASS_UNKNOWN_CMD)
186         err = 0;  /* Allow the use of old dirmngr versions.  */
187
188       server = server->next;
189     }
190 }
191
192
193 \f
194 /* Try to connect to the agent via socket or fork it off and work by
195    pipes.  Handle the server's initial greeting */
196 static int
197 start_dirmngr_ext (ctrl_t ctrl, assuan_context_t *ctx_r)
198 {
199   int rc;
200   char *infostr, *p;
201   assuan_context_t ctx = NULL;
202   int try_default = 0;
203
204   if (opt.disable_dirmngr)
205     return gpg_error (GPG_ERR_NO_DIRMNGR);
206
207   if (*ctx_r)
208     return 0;
209
210   /* Note: if you change this to multiple connections, you also need
211      to take care of the implicit option sending caching. */
212
213 #ifdef HAVE_W32_SYSTEM
214   infostr = NULL;
215   opt.prefer_system_dirmngr = 1;
216 #else
217   infostr = force_pipe_server? NULL : getenv ("DIRMNGR_INFO");
218 #endif /*HAVE_W32_SYSTEM*/
219   if (infostr && !*infostr)
220     infostr = NULL;
221   else if (infostr)
222     infostr = xstrdup (infostr);
223
224   if (opt.prefer_system_dirmngr && !force_pipe_server && !infostr)
225     {
226       infostr = xstrdup (dirmngr_socket_name ());
227       try_default = 1;
228     }
229
230   rc = assuan_new (&ctx);
231   if (rc)
232     {
233       log_error ("can't allocate assuan context: %s\n", gpg_strerror (rc));
234       return rc;
235     }
236
237   if (!infostr)
238     {
239       const char *pgmname;
240       const char *argv[3];
241       int no_close_list[3];
242       int i;
243
244       if (!opt.dirmngr_program || !*opt.dirmngr_program)
245         opt.dirmngr_program = gnupg_module_name (GNUPG_MODULE_NAME_DIRMNGR);
246       if ( !(pgmname = strrchr (opt.dirmngr_program, '/')))
247         pgmname = opt.dirmngr_program;
248       else
249         pgmname++;
250
251       if (opt.verbose)
252         log_info (_("no running dirmngr - starting `%s'\n"),
253                   opt.dirmngr_program);
254
255       if (fflush (NULL))
256         {
257           gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
258           log_error ("error flushing pending output: %s\n", strerror (errno));
259           return tmperr;
260         }
261
262       argv[0] = pgmname;
263       argv[1] = "--server";
264       argv[2] = NULL;
265
266       i=0;
267       if (log_get_fd () != -1)
268         no_close_list[i++] = assuan_fd_from_posix_fd (log_get_fd ());
269       no_close_list[i++] = assuan_fd_from_posix_fd (fileno (stderr));
270       no_close_list[i] = -1;
271
272       /* connect to the agent and perform initial handshaking */
273       rc = assuan_pipe_connect (ctx, opt.dirmngr_program, argv,
274                                 no_close_list, NULL, NULL, 0);
275     }
276   else
277     {
278       int prot;
279       int pid;
280
281       if (!try_default)
282         {
283           if ( !(p = strchr (infostr, PATHSEP_C)) || p == infostr)
284             {
285               log_error (_("malformed DIRMNGR_INFO environment variable\n"));
286               xfree (infostr);
287               force_pipe_server = 1;
288               return start_dirmngr_ext (ctrl, ctx_r);
289             }
290           *p++ = 0;
291           pid = atoi (p);
292           while (*p && *p != PATHSEP_C)
293             p++;
294           prot = *p? atoi (p+1) : 0;
295           if (prot != 1)
296             {
297               log_error (_("dirmngr protocol version %d is not supported\n"),
298                          prot);
299               xfree (infostr);
300               force_pipe_server = 1;
301               return start_dirmngr_ext (ctrl, ctx_r);
302             }
303         }
304       else
305         pid = -1;
306
307       rc = assuan_socket_connect (ctx, infostr, pid, 0);
308 #ifdef HAVE_W32_SYSTEM
309       if (rc)
310         log_debug ("connecting dirmngr at `%s' failed\n", infostr);
311 #endif
312
313       xfree (infostr);
314 #ifndef HAVE_W32_SYSTEM
315       if (gpg_err_code (rc) == GPG_ERR_ASS_CONNECT_FAILED)
316         {
317           log_info (_("can't connect to the dirmngr - trying fall back\n"));
318           force_pipe_server = 1;
319           return start_dirmngr_ext (ctrl, ctx_r);
320         }
321 #endif /*!HAVE_W32_SYSTEM*/
322     }
323
324   prepare_dirmngr (ctrl, ctx, rc);
325
326   if (rc)
327     {
328       assuan_release (ctx);
329       log_error ("can't connect to the dirmngr: %s\n", gpg_strerror (rc));
330       return gpg_error (GPG_ERR_NO_DIRMNGR);
331     }
332   *ctx_r = ctx;
333
334   if (DBG_ASSUAN)
335     log_debug ("connection to dirmngr established\n");
336   return 0;
337 }
338
339
340 static int
341 start_dirmngr (ctrl_t ctrl)
342 {
343   gpg_error_t err;
344
345   assert (! dirmngr_ctx_locked);
346   dirmngr_ctx_locked = 1;
347
348   err = start_dirmngr_ext (ctrl, &dirmngr_ctx);
349   /* We do not check ERR but the existance of a context because the
350      error might come from a failed command send to the dirmngr.
351      Fixme: Why don't we close the drimngr context if we encountered
352      an error in prepare_dirmngr?  */
353   if (!dirmngr_ctx)
354     dirmngr_ctx_locked = 0;
355   return err;
356 }
357
358
359 static void
360 release_dirmngr (ctrl_t ctrl)
361 {
362   (void)ctrl;
363
364   if (!dirmngr_ctx_locked)
365     log_error ("WARNING: trying to release a non-locked dirmngr ctx\n");
366   dirmngr_ctx_locked = 0;
367 }
368
369
370 static int
371 start_dirmngr2 (ctrl_t ctrl)
372 {
373   gpg_error_t err;
374
375   assert (! dirmngr2_ctx_locked);
376   dirmngr2_ctx_locked = 1;
377
378   err = start_dirmngr_ext (ctrl, &dirmngr2_ctx);
379   if (!dirmngr2_ctx)
380     dirmngr2_ctx_locked = 0;
381   return err;
382 }
383
384
385 static void
386 release_dirmngr2 (ctrl_t ctrl)
387 {
388   (void)ctrl;
389
390   if (!dirmngr2_ctx_locked)
391     log_error ("WARNING: trying to release a non-locked dirmngr2 ctx\n");
392   dirmngr2_ctx_locked = 0;
393 }
394
395
396 \f
397 /* Handle a SENDCERT inquiry. */
398 static gpg_error_t
399 inq_certificate (void *opaque, const char *line)
400 {
401   struct inq_certificate_parm_s *parm = opaque;
402   int rc;
403   const unsigned char *der;
404   size_t derlen;
405   int issuer_mode = 0;
406   ksba_sexp_t ski = NULL;
407
408   if (!strncmp (line, "SENDCERT", 8) && (line[8] == ' ' || !line[8]))
409     {
410       line += 8;
411     }
412   else if (!strncmp (line, "SENDCERT_SKI", 12) && (line[12]==' ' || !line[12]))
413     {
414       size_t n;
415
416       /* Send a certificate where a sourceKeyIdentifier is included. */
417       line += 12;
418       while (*line == ' ')
419         line++;
420       ski = make_simple_sexp_from_hexstr (line, &n);
421       line += n;
422       while (*line == ' ')
423         line++;
424     }
425   else if (!strncmp (line, "SENDISSUERCERT", 14)
426            && (line[14] == ' ' || !line[14]))
427     {
428       line += 14;
429       issuer_mode = 1;
430     }
431   else if (!strncmp (line, "ISTRUSTED", 9) && (line[9]==' ' || !line[9]))
432     {
433       /* The server is asking us whether the certificate is a trusted
434          root certificate.  */
435       const char *s;
436       size_t n;
437       char fpr[41];
438       struct rootca_flags_s rootca_flags;
439
440       line += 9;
441       while (*line == ' ')
442         line++;
443
444       for (s=line,n=0; hexdigitp (s); s++, n++)
445         ;
446       if (*s || n != 40)
447         return gpg_error (GPG_ERR_ASS_PARAMETER);
448       for (s=line, n=0; n < 40; s++, n++)
449         fpr[n] = (*s >= 'a')? (*s & 0xdf): *s;
450       fpr[n] = 0;
451
452       if (!gpgsm_agent_istrusted (parm->ctrl, NULL, fpr, &rootca_flags))
453         rc = assuan_send_data (parm->ctx, "1", 1);
454       else
455         rc = 0;
456       return rc;
457     }
458   else
459     {
460       log_error ("unsupported inquiry `%s'\n", line);
461       return gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
462     }
463
464   if (!*line)
465     { /* Send the current certificate. */
466       der = ksba_cert_get_image (issuer_mode? parm->issuer_cert : parm->cert,
467                                  &derlen);
468       if (!der)
469         rc = gpg_error (GPG_ERR_INV_CERT_OBJ);
470       else
471         rc = assuan_send_data (parm->ctx, der, derlen);
472     }
473   else if (issuer_mode)
474     {
475       log_error ("sending specific issuer certificate back "
476                  "is not yet implemented\n");
477       rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
478     }
479   else
480     { /* Send the given certificate. */
481       int err;
482       ksba_cert_t cert;
483
484
485       err = gpgsm_find_cert (line, ski, &cert);
486       if (err)
487         {
488           log_error ("certificate not found: %s\n", gpg_strerror (err));
489           rc = gpg_error (GPG_ERR_NOT_FOUND);
490         }
491       else
492         {
493           der = ksba_cert_get_image (cert, &derlen);
494           if (!der)
495             rc = gpg_error (GPG_ERR_INV_CERT_OBJ);
496           else
497             rc = assuan_send_data (parm->ctx, der, derlen);
498           ksba_cert_release (cert);
499         }
500     }
501
502   xfree (ski);
503   return rc;
504 }
505
506
507 /* Take a 20 byte hexencoded string and put it into the the provided
508    20 byte buffer FPR in binary format. */
509 static int
510 unhexify_fpr (const char *hexstr, unsigned char *fpr)
511 {
512   const char *s;
513   int n;
514
515   for (s=hexstr, n=0; hexdigitp (s); s++, n++)
516     ;
517   if (*s || (n != 40))
518     return 0; /* no fingerprint (invalid or wrong length). */
519   n /= 2;
520   for (s=hexstr, n=0; *s; s += 2, n++)
521     fpr[n] = xtoi_2 (s);
522   return 1; /* okay */
523 }
524
525
526 static gpg_error_t
527 isvalid_status_cb (void *opaque, const char *line)
528 {
529   struct isvalid_status_parm_s *parm = opaque;
530
531   if (!strncmp (line, "PROGRESS", 8) && (line[8]==' ' || !line[8]))
532     {
533       if (parm->ctrl)
534         {
535           for (line += 8; *line == ' '; line++)
536             ;
537           if (gpgsm_status (parm->ctrl, STATUS_PROGRESS, line))
538             return gpg_error (GPG_ERR_ASS_CANCELED);
539         }
540     }
541   else if (!strncmp (line, "ONLY_VALID_IF_CERT_VALID", 24)
542       && (line[24]==' ' || !line[24]))
543     {
544       parm->seen++;
545       if (!line[24] || !unhexify_fpr (line+25, parm->fpr))
546         parm->seen++; /* Bumb it to indicate an error. */
547     }
548   return 0;
549 }
550
551
552
553 \f
554 /* Call the directory manager to check whether the certificate is valid
555    Returns 0 for valid or usually one of the errors:
556
557   GPG_ERR_CERTIFICATE_REVOKED
558   GPG_ERR_NO_CRL_KNOWN
559   GPG_ERR_CRL_TOO_OLD
560
561   Values for USE_OCSP:
562      0 = Do CRL check.
563      1 = Do an OCSP check.
564      2 = Do an OCSP check using only the default responder.
565  */
566 int
567 gpgsm_dirmngr_isvalid (ctrl_t ctrl,
568                        ksba_cert_t cert, ksba_cert_t issuer_cert, int use_ocsp)
569 {
570   static int did_options;
571   int rc;
572   char *certid;
573   char line[ASSUAN_LINELENGTH];
574   struct inq_certificate_parm_s parm;
575   struct isvalid_status_parm_s stparm;
576
577   rc = start_dirmngr (ctrl);
578   if (rc)
579     return rc;
580
581   if (use_ocsp)
582     {
583       certid = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
584     }
585   else
586     {
587       certid = gpgsm_get_certid (cert);
588       if (!certid)
589         {
590           log_error ("error getting the certificate ID\n");
591           release_dirmngr (ctrl);
592           return gpg_error (GPG_ERR_GENERAL);
593         }
594     }
595
596   if (opt.verbose > 1)
597     {
598       char *fpr = gpgsm_get_fingerprint_string (cert, GCRY_MD_SHA1);
599       log_info ("asking dirmngr about %s%s\n", fpr,
600                 use_ocsp? " (using OCSP)":"");
601       xfree (fpr);
602     }
603
604   parm.ctx = dirmngr_ctx;
605   parm.ctrl = ctrl;
606   parm.cert = cert;
607   parm.issuer_cert = issuer_cert;
608
609   stparm.ctrl = ctrl;
610   stparm.seen = 0;
611   memset (stparm.fpr, 0, 20);
612
613   /* FIXME: If --disable-crl-checks has been set, we should pass an
614      option to dirmngr, so that no fallback CRL check is done after an
615      ocsp check.  It is not a problem right now as dirmngr does not
616      fallback to CRL checking.  */
617
618   /* It is sufficient to send the options only once because we have
619      one connection per process only. */
620   if (!did_options)
621     {
622       if (opt.force_crl_refresh)
623         assuan_transact (dirmngr_ctx, "OPTION force-crl-refresh=1",
624                          NULL, NULL, NULL, NULL, NULL, NULL);
625       did_options = 1;
626     }
627   snprintf (line, DIM(line)-1, "ISVALID%s %s",
628             use_ocsp == 2? " --only-ocsp --force-default-responder":"",
629             certid);
630   line[DIM(line)-1] = 0;
631   xfree (certid);
632
633   rc = assuan_transact (dirmngr_ctx, line, NULL, NULL,
634                         inq_certificate, &parm,
635                         isvalid_status_cb, &stparm);
636   if (opt.verbose > 1)
637     log_info ("response of dirmngr: %s\n", rc? gpg_strerror (rc): "okay");
638   rc = rc;
639
640   if (!rc && stparm.seen)
641     {
642       /* Need to also check the certificate validity. */
643       if (stparm.seen != 1)
644         {
645           log_error ("communication problem with dirmngr detected\n");
646           rc = gpg_error (GPG_ERR_INV_CRL);
647         }
648       else
649         {
650           ksba_cert_t rspcert = NULL;
651
652           if (get_cached_cert (dirmngr_ctx, stparm.fpr, &rspcert))
653             {
654               /* Ooops: Something went wrong getting the certificate
655                  from the dirmngr.  Try our own cert store now.  */
656               KEYDB_HANDLE kh;
657
658               kh = keydb_new (0);
659               if (!kh)
660                 rc = gpg_error (GPG_ERR_ENOMEM);
661               if (!rc)
662                 rc = keydb_search_fpr (kh, stparm.fpr);
663               if (!rc)
664                 rc = keydb_get_cert (kh, &rspcert);
665               if (rc)
666                 {
667                   log_error ("unable to find the certificate used "
668                              "by the dirmngr: %s\n", gpg_strerror (rc));
669                   rc = gpg_error (GPG_ERR_INV_CRL);
670                 }
671               keydb_release (kh);
672             }
673
674           if (!rc)
675             {
676               rc = gpgsm_cert_use_ocsp_p (rspcert);
677               if (rc)
678                 rc = gpg_error (GPG_ERR_INV_CRL);
679               else
680                 {
681                   /* Note the no_dirmngr flag: This avoids checking
682                      this certificate over and over again. */
683                   rc = gpgsm_validate_chain (ctrl, rspcert, "", NULL, 0, NULL,
684                                              VALIDATE_FLAG_NO_DIRMNGR, NULL);
685                   if (rc)
686                     {
687                       log_error ("invalid certificate used for CRL/OCSP: %s\n",
688                                  gpg_strerror (rc));
689                       rc = gpg_error (GPG_ERR_INV_CRL);
690                     }
691                 }
692             }
693           ksba_cert_release (rspcert);
694         }
695     }
696   release_dirmngr (ctrl);
697   return rc;
698 }
699
700
701 \f
702 /* Lookup helpers*/
703 static gpg_error_t
704 lookup_cb (void *opaque, const void *buffer, size_t length)
705 {
706   struct lookup_parm_s *parm = opaque;
707   size_t len;
708   char *buf;
709   ksba_cert_t cert;
710   int rc;
711
712   if (parm->error)
713     return 0;
714
715   if (buffer)
716     {
717       put_membuf (&parm->data, buffer, length);
718       return 0;
719     }
720   /* END encountered - process what we have */
721   buf = get_membuf (&parm->data, &len);
722   if (!buf)
723     {
724       parm->error = gpg_error (GPG_ERR_ENOMEM);
725       return 0;
726     }
727
728   rc = ksba_cert_new (&cert);
729   if (rc)
730     {
731       parm->error = rc;
732       return 0;
733     }
734   rc = ksba_cert_init_from_mem (cert, buf, len);
735   if (rc)
736     {
737       log_error ("failed to parse a certificate: %s\n", gpg_strerror (rc));
738     }
739   else
740     {
741       parm->cb (parm->cb_value, cert);
742     }
743
744   ksba_cert_release (cert);
745   init_membuf (&parm->data, 4096);
746   return 0;
747 }
748
749 /* Return a properly escaped pattern from NAMES.  The only error
750    return is NULL to indicate a malloc failure. */
751 static char *
752 pattern_from_strlist (strlist_t names)
753 {
754   strlist_t sl;
755   int n;
756   const char *s;
757   char *pattern, *p;
758
759   for (n=0, sl=names; sl; sl = sl->next)
760     {
761       for (s=sl->d; *s; s++, n++)
762         {
763           if (*s == '%' || *s == ' ' || *s == '+')
764             n += 2;
765         }
766       n++;
767     }
768
769   p = pattern = xtrymalloc (n+1);
770   if (!pattern)
771     return NULL;
772
773   for (sl=names; sl; sl = sl->next)
774     {
775       for (s=sl->d; *s; s++)
776         {
777           switch (*s)
778             {
779             case '%':
780               *p++ = '%';
781               *p++ = '2';
782               *p++ = '5';
783               break;
784             case ' ':
785               *p++ = '%';
786               *p++ = '2';
787               *p++ = '0';
788               break;
789             case '+':
790               *p++ = '%';
791               *p++ = '2';
792               *p++ = 'B';
793               break;
794             default:
795               *p++ = *s;
796               break;
797             }
798         }
799       *p++ = ' ';
800     }
801   if (p == pattern)
802     *pattern = 0; /* is empty */
803   else
804     p[-1] = '\0'; /* remove trailing blank */
805
806   return pattern;
807 }
808
809 static gpg_error_t
810 lookup_status_cb (void *opaque, const char *line)
811 {
812   struct lookup_parm_s *parm = opaque;
813
814   if (!strncmp (line, "PROGRESS", 8) && (line[8]==' ' || !line[8]))
815     {
816       if (parm->ctrl)
817         {
818           for (line += 8; *line == ' '; line++)
819             ;
820           if (gpgsm_status (parm->ctrl, STATUS_PROGRESS, line))
821             return gpg_error (GPG_ERR_ASS_CANCELED);
822         }
823     }
824   else if (!strncmp (line, "TRUNCATED", 9) && (line[9]==' ' || !line[9]))
825     {
826       if (parm->ctrl)
827         {
828           for (line +=9; *line == ' '; line++)
829             ;
830           gpgsm_status (parm->ctrl, STATUS_TRUNCATED, line);
831         }
832     }
833   return 0;
834 }
835
836
837 /* Run the Directory Manager's lookup command using the pattern
838    compiled from the strings given in NAMES.  The caller must provide
839    the callback CB which will be passed cert by cert.  Note that CTRL
840    is optional.  With CACHE_ONLY the dirmngr will search only its own
841    key cache. */
842 int
843 gpgsm_dirmngr_lookup (ctrl_t ctrl, strlist_t names, int cache_only,
844                       void (*cb)(void*, ksba_cert_t), void *cb_value)
845 {
846   int rc;
847   char *pattern;
848   char line[ASSUAN_LINELENGTH];
849   struct lookup_parm_s parm;
850   size_t len;
851   assuan_context_t ctx;
852
853   /* The lookup function can be invoked from the callback of a lookup
854      function, for example to walk the chain.  */
855   if (!dirmngr_ctx_locked)
856     {
857       rc = start_dirmngr (ctrl);
858       if (rc)
859         return rc;
860       ctx = dirmngr_ctx;
861     }
862   else if (!dirmngr2_ctx_locked)
863     {
864       rc = start_dirmngr2 (ctrl);
865       if (rc)
866         return rc;
867       ctx = dirmngr2_ctx;
868     }
869   else
870     {
871       log_fatal ("both dirmngr contexts are in use\n");
872     }
873
874   pattern = pattern_from_strlist (names);
875   if (!pattern)
876     {
877       if (ctx == dirmngr_ctx)
878         release_dirmngr (ctrl);
879       else
880         release_dirmngr2 (ctrl);
881
882       return out_of_core ();
883     }
884   snprintf (line, DIM(line)-1, "LOOKUP%s %s",
885             cache_only? " --cache-only":"", pattern);
886   line[DIM(line)-1] = 0;
887   xfree (pattern);
888
889   parm.ctrl = ctrl;
890   parm.ctx = ctx;
891   parm.cb = cb;
892   parm.cb_value = cb_value;
893   parm.error = 0;
894   init_membuf (&parm.data, 4096);
895
896   rc = assuan_transact (ctx, line, lookup_cb, &parm,
897                         NULL, NULL, lookup_status_cb, &parm);
898   xfree (get_membuf (&parm.data, &len));
899
900   if (ctx == dirmngr_ctx)
901     release_dirmngr (ctrl);
902   else
903     release_dirmngr2 (ctrl);
904
905   if (rc)
906       return rc;
907   return parm.error;
908 }
909
910
911 \f
912 static gpg_error_t
913 get_cached_cert_data_cb (void *opaque, const void *buffer, size_t length)
914 {
915   struct membuf *mb = opaque;
916
917   if (buffer)
918     put_membuf (mb, buffer, length);
919   return 0;
920 }
921
922 /* Return a certificate from the Directory Manager's cache.  This
923    function only returns one certificate which must be specified using
924    the fingerprint FPR and will be stored at R_CERT.  On error NULL is
925    stored at R_CERT and an error code returned.  Note that the caller
926    must provide the locked dirmngr context CTX. */
927 static gpg_error_t
928 get_cached_cert (assuan_context_t ctx,
929                  const unsigned char *fpr, ksba_cert_t *r_cert)
930 {
931   gpg_error_t err;
932   char line[ASSUAN_LINELENGTH];
933   char hexfpr[2*20+1];
934   struct membuf mb;
935   char *buf;
936   size_t buflen;
937   ksba_cert_t cert;
938
939   *r_cert = NULL;
940
941   bin2hex (fpr, 20, hexfpr);
942   snprintf (line, DIM(line)-1, "LOOKUP --single --cache-only 0x%s", hexfpr);
943
944   init_membuf (&mb, 4096);
945   err = assuan_transact (ctx, line, get_cached_cert_data_cb, &mb,
946                          NULL, NULL, NULL, NULL);
947   buf = get_membuf (&mb, &buflen);
948   if (err)
949     {
950       xfree (buf);
951       return err;
952     }
953   if (!buf)
954     return gpg_error (GPG_ERR_ENOMEM);
955
956   err = ksba_cert_new (&cert);
957   if (err)
958     {
959       xfree (buf);
960       return err;
961     }
962   err = ksba_cert_init_from_mem (cert, buf, buflen);
963   xfree (buf);
964   if (err)
965     {
966       log_error ("failed to parse a certificate: %s\n", gpg_strerror (err));
967       ksba_cert_release (cert);
968       return err;
969     }
970
971   *r_cert = cert;
972   return 0;
973 }
974
975
976 \f
977 /* Run Command helpers*/
978
979 /* Fairly simple callback to write all output of dirmngr to stdout. */
980 static gpg_error_t
981 run_command_cb (void *opaque, const void *buffer, size_t length)
982 {
983   (void)opaque;
984
985   if (buffer)
986     {
987       if ( fwrite (buffer, length, 1, stdout) != 1 )
988         log_error ("error writing to stdout: %s\n", strerror (errno));
989     }
990   return 0;
991 }
992
993 /* Handle inquiries from the dirmngr COMMAND. */
994 static gpg_error_t
995 run_command_inq_cb (void *opaque, const char *line)
996 {
997   struct run_command_parm_s *parm = opaque;
998   int rc = 0;
999
1000   if ( !strncmp (line, "SENDCERT", 8) && (line[8] == ' ' || !line[8]) )
1001     { /* send the given certificate */
1002       int err;
1003       ksba_cert_t cert;
1004       const unsigned char *der;
1005       size_t derlen;
1006
1007       line += 8;
1008       if (!*line)
1009         return gpg_error (GPG_ERR_ASS_PARAMETER);
1010
1011       err = gpgsm_find_cert (line, NULL, &cert);
1012       if (err)
1013         {
1014           log_error ("certificate not found: %s\n", gpg_strerror (err));
1015           rc = gpg_error (GPG_ERR_NOT_FOUND);
1016         }
1017       else
1018         {
1019           der = ksba_cert_get_image (cert, &derlen);
1020           if (!der)
1021             rc = gpg_error (GPG_ERR_INV_CERT_OBJ);
1022           else
1023             rc = assuan_send_data (parm->ctx, der, derlen);
1024           ksba_cert_release (cert);
1025         }
1026     }
1027   else if ( !strncmp (line, "PRINTINFO", 9) && (line[9] == ' ' || !line[9]) )
1028     { /* Simply show the message given in the argument. */
1029       line += 9;
1030       log_info ("dirmngr: %s\n", line);
1031     }
1032   else
1033     {
1034       log_error ("unsupported inquiry `%s'\n", line);
1035       rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
1036     }
1037
1038   return rc;
1039 }
1040
1041 static gpg_error_t
1042 run_command_status_cb (void *opaque, const char *line)
1043 {
1044   ctrl_t ctrl = opaque;
1045
1046   if (opt.verbose)
1047     {
1048       log_info ("dirmngr status: %s\n", line);
1049     }
1050   if (!strncmp (line, "PROGRESS", 8) && (line[8]==' ' || !line[8]))
1051     {
1052       if (ctrl)
1053         {
1054           for (line += 8; *line == ' '; line++)
1055             ;
1056           if (gpgsm_status (ctrl, STATUS_PROGRESS, line))
1057             return gpg_error (GPG_ERR_ASS_CANCELED);
1058         }
1059     }
1060   return 0;
1061 }
1062
1063
1064
1065 /* Pass COMMAND to dirmngr and print all output generated by Dirmngr
1066    to stdout.  A couple of inquiries are defined (see above).  ARGC
1067    arguments in ARGV are given to the Dirmngr.  Spaces, plus and
1068    percent characters within the argument strings are percent escaped
1069    so that blanks can act as delimiters. */
1070 int
1071 gpgsm_dirmngr_run_command (ctrl_t ctrl, const char *command,
1072                            int argc, char **argv)
1073 {
1074   int rc;
1075   int i;
1076   const char *s;
1077   char *line, *p;
1078   size_t len;
1079   struct run_command_parm_s parm;
1080
1081   rc = start_dirmngr (ctrl);
1082   if (rc)
1083     return rc;
1084
1085   parm.ctx = dirmngr_ctx;
1086
1087   len = strlen (command) + 1;
1088   for (i=0; i < argc; i++)
1089     len += 1 + 3*strlen (argv[i]); /* enough space for percent escaping */
1090   line = xtrymalloc (len);
1091   if (!line)
1092     {
1093       release_dirmngr (ctrl);
1094       return out_of_core ();
1095     }
1096
1097   p = stpcpy (line, command);
1098   for (i=0; i < argc; i++)
1099     {
1100       *p++ = ' ';
1101       for (s=argv[i]; *s; s++)
1102         {
1103           if (!isascii (*s))
1104             *p++ = *s;
1105           else if (*s == ' ')
1106             *p++ = '+';
1107           else if (!isprint (*s) || *s == '+')
1108             {
1109               sprintf (p, "%%%02X", *(const unsigned char *)s);
1110               p += 3;
1111             }
1112           else
1113             *p++ = *s;
1114         }
1115     }
1116   *p = 0;
1117
1118   rc = assuan_transact (dirmngr_ctx, line,
1119                         run_command_cb, NULL,
1120                         run_command_inq_cb, &parm,
1121                         run_command_status_cb, ctrl);
1122   xfree (line);
1123   log_info ("response of dirmngr: %s\n", rc? gpg_strerror (rc): "okay");
1124   release_dirmngr (ctrl);
1125   return rc;
1126 }