1 /* call-dirmngr.c - communication with the dromngr
2 * Copyright (C) 2002, 2003, 2005, 2007, 2008 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
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.
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.
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/>.
47 static assuan_context_t dirmngr_ctx = NULL;
48 static int force_pipe_server = 0;
50 struct inq_certificate_parm_s {
53 ksba_cert_t issuer_cert;
56 struct isvalid_status_parm_s {
59 unsigned char fpr[20];
63 struct lookup_parm_s {
66 void (*cb)(void *, ksba_cert_t);
72 struct run_command_parm_s {
77 /* A simple implementation of a dynamic buffer. Use init_membuf() to
78 create a buffer, put_membuf to append bytes and get_membuf to
79 release and return the buffer. Allocation errors are detected but
80 only returned at the final get_membuf(), this helps not to clutter
81 the code with out of core checks. */
84 init_membuf (struct membuf *mb, int initiallen)
87 mb->size = initiallen;
89 mb->buf = xtrymalloc (initiallen);
95 put_membuf (struct membuf *mb, const void *buf, size_t len)
100 if (mb->len + len >= mb->size)
104 mb->size += len + 1024;
105 p = xtryrealloc (mb->buf, mb->size);
113 memcpy (mb->buf + mb->len, buf, len);
118 get_membuf (struct membuf *mb, size_t *len)
132 mb->out_of_core = 1; /* don't allow a reuse */
137 /* This fucntion prepares the dirmngr for a new session. The
138 audit-events option is used so that other dirmngr clients won't get
139 disturbed by such events. */
141 prepare_dirmngr (ctrl_t ctrl, assuan_context_t ctx, gpg_error_t err)
143 if (!ctrl->dirmngr_seen)
145 ctrl->dirmngr_seen = 1;
148 err = assuan_transact (ctx, "OPTION audit-events=1",
149 NULL, NULL, NULL, NULL, NULL, NULL);
150 if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION)
151 err = 0; /* Allow the use of old dirmngr versions. */
153 audit_log_ok (ctrl->audit, AUDIT_DIRMNGR_READY, err);
159 /* Try to connect to the agent via socket or fork it off and work by
160 pipes. Handle the server's initial greeting */
162 start_dirmngr (ctrl_t ctrl)
166 assuan_context_t ctx;
169 if (opt.disable_dirmngr)
170 return gpg_error (GPG_ERR_NO_DIRMNGR);
174 prepare_dirmngr (ctrl, dirmngr_ctx, 0);
175 return 0; /* fixme: We need a context for each thread or serialize
176 the access to the dirmngr */
178 /* Note: if you change this to multiple connections, you also need
179 to take care of the implicit option sending caching. */
181 #ifdef HAVE_W32_SYSTEM
183 opt.prefer_system_dirmngr = 1;
185 infostr = force_pipe_server? NULL : getenv ("DIRMNGR_INFO");
186 #endif /*HAVE_W32_SYSTEM*/
187 if (infostr && !*infostr)
190 infostr = xstrdup (infostr);
192 if (opt.prefer_system_dirmngr && !force_pipe_server && !infostr)
194 infostr = xstrdup (dirmngr_socket_name ());
201 int no_close_list[3];
204 if (!opt.dirmngr_program || !*opt.dirmngr_program)
205 opt.dirmngr_program = gnupg_module_name (GNUPG_MODULE_NAME_DIRMNGR);
206 if ( !(pgmname = strrchr (opt.dirmngr_program, '/')))
207 pgmname = opt.dirmngr_program;
212 log_info (_("no running dirmngr - starting `%s'\n"),
213 opt.dirmngr_program);
217 gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
218 log_error ("error flushing pending output: %s\n", strerror (errno));
223 argv[1] = "--server";
227 if (log_get_fd () != -1)
228 no_close_list[i++] = log_get_fd ();
229 no_close_list[i++] = fileno (stderr);
230 no_close_list[i] = -1;
232 /* connect to the agent and perform initial handshaking */
233 rc = assuan_pipe_connect (&ctx, opt.dirmngr_program, argv,
243 if ( !(p = strchr (infostr, PATHSEP_C)) || p == infostr)
245 log_error (_("malformed DIRMNGR_INFO environment variable\n"));
247 force_pipe_server = 1;
248 return start_dirmngr (ctrl);
252 while (*p && *p != PATHSEP_C)
254 prot = *p? atoi (p+1) : 0;
257 log_error (_("dirmngr protocol version %d is not supported\n"),
260 force_pipe_server = 1;
261 return start_dirmngr (ctrl);
267 rc = assuan_socket_connect (&ctx, infostr, pid);
268 #ifdef HAVE_W32_SYSTEM
270 log_debug ("connecting dirmngr at `%s' failed\n", infostr);
274 #ifndef HAVE_W32_SYSTEM
275 if (gpg_err_code (rc) == GPG_ERR_ASS_CONNECT_FAILED)
277 log_info (_("can't connect to the dirmngr - trying fall back\n"));
278 force_pipe_server = 1;
279 return start_dirmngr (ctrl);
281 #endif /*!HAVE_W32_SYSTEM*/
284 prepare_dirmngr (ctrl, ctx, rc);
288 log_error ("can't connect to the dirmngr: %s\n", gpg_strerror (rc));
289 return gpg_error (GPG_ERR_NO_DIRMNGR);
294 log_debug ("connection to dirmngr established\n");
300 /* Handle a SENDCERT inquiry. */
302 inq_certificate (void *opaque, const char *line)
304 struct inq_certificate_parm_s *parm = opaque;
306 const unsigned char *der;
309 ksba_sexp_t ski = NULL;
311 if (!strncmp (line, "SENDCERT", 8) && (line[8] == ' ' || !line[8]))
315 else if (!strncmp (line, "SENDCERT_SKI", 12) && (line[12]==' ' || !line[12]))
319 /* Send a certificate where a sourceKeyIdentifier is included. */
323 ski = make_simple_sexp_from_hexstr (line, &n);
328 else if (!strncmp (line, "SENDISSUERCERT", 14)
329 && (line[14] == ' ' || !line[14]))
336 log_error ("unsupported inquiry `%s'\n", line);
337 return gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
341 { /* Send the current certificate. */
342 der = ksba_cert_get_image (issuer_mode? parm->issuer_cert : parm->cert,
345 rc = gpg_error (GPG_ERR_INV_CERT_OBJ);
347 rc = assuan_send_data (parm->ctx, der, derlen);
349 else if (issuer_mode)
351 log_error ("sending specific issuer certificate back "
352 "is not yet implemented\n");
353 rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
356 { /* Send the given certificate. */
361 err = gpgsm_find_cert (line, ski, &cert);
364 log_error ("certificate not found: %s\n", gpg_strerror (err));
365 rc = gpg_error (GPG_ERR_NOT_FOUND);
369 der = ksba_cert_get_image (cert, &derlen);
371 rc = gpg_error (GPG_ERR_INV_CERT_OBJ);
373 rc = assuan_send_data (parm->ctx, der, derlen);
374 ksba_cert_release (cert);
383 /* Take a 20 byte hexencoded string and put it into the the provided
384 20 byte buffer FPR in binary format. */
386 unhexify_fpr (const char *hexstr, unsigned char *fpr)
391 for (s=hexstr, n=0; hexdigitp (s); s++, n++)
394 return 0; /* no fingerprint (invalid or wrong length). */
396 for (s=hexstr, n=0; *s; s += 2, n++)
402 static assuan_error_t
403 isvalid_status_cb (void *opaque, const char *line)
405 struct isvalid_status_parm_s *parm = opaque;
407 if (!strncmp (line, "PROGRESS", 8) && (line[8]==' ' || !line[8]))
411 for (line += 8; *line == ' '; line++)
413 if (gpgsm_status (parm->ctrl, STATUS_PROGRESS, line))
414 return gpg_error (GPG_ERR_ASS_CANCELED);
417 else if (!strncmp (line, "ONLY_VALID_IF_CERT_VALID", 24)
418 && (line[24]==' ' || !line[24]))
421 if (!line[24] || !unhexify_fpr (line+25, parm->fpr))
422 parm->seen++; /* Bumb it to indicate an error. */
430 /* Call the directory manager to check whether the certificate is valid
431 Returns 0 for valid or usually one of the errors:
433 GPG_ERR_CERTIFICATE_REVOKED
439 1 = Do an OCSP check.
440 2 = Do an OCSP check using only the default responder.
443 gpgsm_dirmngr_isvalid (ctrl_t ctrl,
444 ksba_cert_t cert, ksba_cert_t issuer_cert, int use_ocsp)
446 static int did_options;
449 char line[ASSUAN_LINELENGTH];
450 struct inq_certificate_parm_s parm;
451 struct isvalid_status_parm_s stparm;
453 rc = start_dirmngr (ctrl);
459 certid = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
463 certid = gpgsm_get_certid (cert);
466 log_error ("error getting the certificate ID\n");
467 return gpg_error (GPG_ERR_GENERAL);
473 char *fpr = gpgsm_get_fingerprint_string (cert, GCRY_MD_SHA1);
474 log_info ("asking dirmngr about %s%s\n", fpr,
475 use_ocsp? " (using OCSP)":"");
479 parm.ctx = dirmngr_ctx;
481 parm.issuer_cert = issuer_cert;
485 memset (stparm.fpr, 0, 20);
487 /* FIXME: If --disable-crl-checks has been set, we should pass an
488 option to dirmngr, so that no fallback CRL check is done after an
489 ocsp check. It is not a problem right now as dirmngr does not
490 fallback to CRL checking. */
492 /* It is sufficient to send the options only once because we have
493 one connection per process only. */
496 if (opt.force_crl_refresh)
497 assuan_transact (dirmngr_ctx, "OPTION force-crl-refresh=1",
498 NULL, NULL, NULL, NULL, NULL, NULL);
501 snprintf (line, DIM(line)-1, "ISVALID%s %s",
502 use_ocsp == 2? " --only-ocsp --force-default-responder":"",
504 line[DIM(line)-1] = 0;
507 rc = assuan_transact (dirmngr_ctx, line, NULL, NULL,
508 inq_certificate, &parm,
509 isvalid_status_cb, &stparm);
511 log_info ("response of dirmngr: %s\n", rc? gpg_strerror (rc): "okay");
514 if (!rc && stparm.seen)
516 /* Need to also check the certificate validity. */
517 if (stparm.seen != 1)
519 log_error ("communication problem with dirmngr detected\n");
520 rc = gpg_error (GPG_ERR_INV_CRL);
525 ksba_cert_t rspcert = NULL;
527 /* Fixme: First try to get the certificate from the
528 dirmngr's cache - it should be there. */
531 rc = gpg_error (GPG_ERR_ENOMEM);
533 rc = keydb_search_fpr (kh, stparm.fpr);
535 rc = keydb_get_cert (kh, &rspcert);
538 log_error ("unable to find the certificate used "
539 "by the dirmngr: %s\n", gpg_strerror (rc));
540 rc = gpg_error (GPG_ERR_INV_CRL);
546 rc = gpgsm_cert_use_ocsp_p (rspcert);
548 rc = gpg_error (GPG_ERR_INV_CRL);
551 /* Note the no_dirmngr flag: This avoids checking
552 this certificate over and over again. */
553 rc = gpgsm_validate_chain (ctrl, rspcert, "", NULL, 0, NULL,
554 VALIDATE_FLAG_NO_DIRMNGR, NULL);
557 log_error ("invalid certificate used for CRL/OCSP: %s\n",
559 rc = gpg_error (GPG_ERR_INV_CRL);
563 ksba_cert_release (rspcert);
573 lookup_cb (void *opaque, const void *buffer, size_t length)
575 struct lookup_parm_s *parm = opaque;
586 put_membuf (&parm->data, buffer, length);
589 /* END encountered - process what we have */
590 buf = get_membuf (&parm->data, &len);
593 parm->error = gpg_error (GPG_ERR_ENOMEM);
597 rc = ksba_cert_new (&cert);
603 rc = ksba_cert_init_from_mem (cert, buf, len);
606 log_error ("failed to parse a certificate: %s\n", gpg_strerror (rc));
610 parm->cb (parm->cb_value, cert);
613 ksba_cert_release (cert);
614 init_membuf (&parm->data, 4096);
618 /* Return a properly escaped pattern from NAMES. The only error
619 return is NULL to indicate a malloc failure. */
621 pattern_from_strlist (strlist_t names)
628 for (n=0, sl=names; sl; sl = sl->next)
630 for (s=sl->d; *s; s++, n++)
632 if (*s == '%' || *s == ' ' || *s == '+')
638 p = pattern = xtrymalloc (n+1);
642 for (n=0, sl=names; sl; sl = sl->next)
644 for (s=sl->d; *s; s++)
671 *pattern = 0; /* is empty */
673 p[-1] = '\0'; /* remove trailing blank */
679 lookup_status_cb (void *opaque, const char *line)
681 struct lookup_parm_s *parm = opaque;
683 if (!strncmp (line, "PROGRESS", 8) && (line[8]==' ' || !line[8]))
687 for (line += 8; *line == ' '; line++)
689 if (gpgsm_status (parm->ctrl, STATUS_PROGRESS, line))
690 return gpg_error (GPG_ERR_ASS_CANCELED);
693 else if (!strncmp (line, "TRUNCATED", 9) && (line[9]==' ' || !line[9]))
697 for (line +=9; *line == ' '; line++)
699 gpgsm_status (parm->ctrl, STATUS_TRUNCATED, line);
706 /* Run the Directory Manager's lookup command using the pattern
707 compiled from the strings given in NAMES. The caller must provide
708 the callback CB which will be passed cert by cert. Note that CTRL
709 is optional. With CACHE_ONLY the dirmngr will search only its own
712 gpgsm_dirmngr_lookup (ctrl_t ctrl, strlist_t names, int cache_only,
713 void (*cb)(void*, ksba_cert_t), void *cb_value)
717 char line[ASSUAN_LINELENGTH];
718 struct lookup_parm_s parm;
721 rc = start_dirmngr (ctrl);
725 pattern = pattern_from_strlist (names);
727 return out_of_core ();
728 snprintf (line, DIM(line)-1, "LOOKUP%s %s",
729 cache_only? " --cache-only":"", pattern);
730 line[DIM(line)-1] = 0;
734 parm.ctx = dirmngr_ctx;
736 parm.cb_value = cb_value;
738 init_membuf (&parm.data, 4096);
740 rc = assuan_transact (dirmngr_ctx, line, lookup_cb, &parm,
741 NULL, NULL, lookup_status_cb, &parm);
742 xfree (get_membuf (&parm.data, &len));
750 /* Run Command helpers*/
752 /* Fairly simple callback to write all output of dirmngr to stdout. */
754 run_command_cb (void *opaque, const void *buffer, size_t length)
758 if ( fwrite (buffer, length, 1, stdout) != 1 )
759 log_error ("error writing to stdout: %s\n", strerror (errno));
764 /* Handle inquiries from the dirmngr COMMAND. */
766 run_command_inq_cb (void *opaque, const char *line)
768 struct run_command_parm_s *parm = opaque;
771 if ( !strncmp (line, "SENDCERT", 8) && (line[8] == ' ' || !line[8]) )
772 { /* send the given certificate */
775 const unsigned char *der;
780 return gpg_error (GPG_ERR_ASS_PARAMETER);
782 err = gpgsm_find_cert (line, NULL, &cert);
785 log_error ("certificate not found: %s\n", gpg_strerror (err));
786 rc = gpg_error (GPG_ERR_NOT_FOUND);
790 der = ksba_cert_get_image (cert, &derlen);
792 rc = gpg_error (GPG_ERR_INV_CERT_OBJ);
794 rc = assuan_send_data (parm->ctx, der, derlen);
795 ksba_cert_release (cert);
798 else if ( !strncmp (line, "PRINTINFO", 9) && (line[9] == ' ' || !line[9]) )
799 { /* Simply show the message given in the argument. */
801 log_info ("dirmngr: %s\n", line);
805 log_error ("unsupported inquiry `%s'\n", line);
806 rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
813 run_command_status_cb (void *opaque, const char *line)
815 ctrl_t ctrl = opaque;
819 log_info ("dirmngr status: %s\n", line);
821 if (!strncmp (line, "PROGRESS", 8) && (line[8]==' ' || !line[8]))
825 for (line += 8; *line == ' '; line++)
827 if (gpgsm_status (ctrl, STATUS_PROGRESS, line))
828 return gpg_error (GPG_ERR_ASS_CANCELED);
836 /* Pass COMMAND to dirmngr and print all output generated by Dirmngr
837 to stdout. A couple of inquiries are defined (see above). ARGC
838 arguments in ARGV are given to the Dirmngr. Spaces, plus and
839 percent characters within the argument strings are percent escaped
840 so that blanks can act as delimiters. */
842 gpgsm_dirmngr_run_command (ctrl_t ctrl, const char *command,
843 int argc, char **argv)
850 struct run_command_parm_s parm;
852 rc = start_dirmngr (ctrl);
856 parm.ctx = dirmngr_ctx;
858 len = strlen (command) + 1;
859 for (i=0; i < argc; i++)
860 len += 1 + 3*strlen (argv[i]); /* enough space for percent escaping */
861 line = xtrymalloc (len);
863 return out_of_core ();
865 p = stpcpy (line, command);
866 for (i=0; i < argc; i++)
869 for (s=argv[i]; *s; s++)
875 else if (!isprint (*s) || *s == '+')
877 sprintf (p, "%%%02X", *(const unsigned char *)s);
886 rc = assuan_transact (dirmngr_ctx, line,
887 run_command_cb, NULL,
888 run_command_inq_cb, &parm,
889 run_command_status_cb, ctrl);
891 log_info ("response of dirmngr: %s\n", rc? gpg_strerror (rc): "okay");