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 /* fixme: We need a context for each thread or serialize the access to
49 static assuan_context_t dirmngr_ctx
= NULL
;
50 static assuan_context_t dirmngr2_ctx
= NULL
;
52 static int dirmngr_ctx_locked
;
53 static int dirmngr2_ctx_locked
;
55 static int force_pipe_server
= 0;
57 struct inq_certificate_parm_s
{
61 ksba_cert_t issuer_cert
;
64 struct isvalid_status_parm_s
{
67 unsigned char fpr
[20];
71 struct lookup_parm_s
{
74 void (*cb
)(void *, ksba_cert_t
);
80 struct run_command_parm_s
{
85 /* A simple implementation of a dynamic buffer. Use init_membuf() to
86 create a buffer, put_membuf to append bytes and get_membuf to
87 release and return the buffer. Allocation errors are detected but
88 only returned at the final get_membuf(), this helps not to clutter
89 the code with out of core checks. */
92 init_membuf (struct membuf
*mb
, int initiallen
)
95 mb
->size
= initiallen
;
97 mb
->buf
= xtrymalloc (initiallen
);
103 put_membuf (struct membuf
*mb
, const void *buf
, size_t len
)
108 if (mb
->len
+ len
>= mb
->size
)
112 mb
->size
+= len
+ 1024;
113 p
= xtryrealloc (mb
->buf
, mb
->size
);
121 memcpy (mb
->buf
+ mb
->len
, buf
, len
);
126 get_membuf (struct membuf
*mb
, size_t *len
)
140 mb
->out_of_core
= 1; /* don't allow a reuse */
145 /* This function prepares the dirmngr for a new session. The
146 audit-events option is used so that other dirmngr clients won't get
147 disturbed by such events. */
149 prepare_dirmngr (ctrl_t ctrl
, assuan_context_t ctx
, gpg_error_t err
)
151 struct keyserver_spec
*server
;
155 err
= assuan_transact (ctx
, "OPTION audit-events=1",
156 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
157 if (gpg_err_code (err
) == GPG_ERR_UNKNOWN_OPTION
)
158 err
= 0; /* Allow the use of old dirmngr versions. */
160 audit_log_ok (ctrl
->audit
, AUDIT_DIRMNGR_READY
, err
);
162 server
= opt
.keyserver
;
165 char line
[ASSUAN_LINELENGTH
];
166 char *user
= server
->user
? server
->user
: "";
167 char *pass
= server
->pass
? server
->pass
: "";
168 char *base
= server
->base
? server
->base
: "";
170 snprintf (line
, DIM (line
) - 1, "LDAPSERVER %s:%i:%s:%s:%s",
171 server
->host
, server
->port
, user
, pass
, base
);
172 line
[DIM (line
) - 1] = 0;
174 err
= assuan_transact (ctx
, line
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
175 if (gpg_err_code (err
) == GPG_ERR_ASS_UNKNOWN_CMD
)
176 err
= 0; /* Allow the use of old dirmngr versions. */
178 server
= server
->next
;
184 /* Try to connect to the agent via socket or fork it off and work by
185 pipes. Handle the server's initial greeting */
187 start_dirmngr_ext (ctrl_t ctrl
, assuan_context_t
*ctx_r
)
191 assuan_context_t ctx
;
194 if (opt
.disable_dirmngr
)
195 return gpg_error (GPG_ERR_NO_DIRMNGR
);
200 /* Note: if you change this to multiple connections, you also need
201 to take care of the implicit option sending caching. */
203 #ifdef HAVE_W32_SYSTEM
205 opt
.prefer_system_dirmngr
= 1;
207 infostr
= force_pipe_server
? NULL
: getenv ("DIRMNGR_INFO");
208 #endif /*HAVE_W32_SYSTEM*/
209 if (infostr
&& !*infostr
)
212 infostr
= xstrdup (infostr
);
214 if (opt
.prefer_system_dirmngr
&& !force_pipe_server
&& !infostr
)
216 infostr
= xstrdup (dirmngr_socket_name ());
223 int no_close_list
[3];
226 if (!opt
.dirmngr_program
|| !*opt
.dirmngr_program
)
227 opt
.dirmngr_program
= gnupg_module_name (GNUPG_MODULE_NAME_DIRMNGR
);
228 if ( !(pgmname
= strrchr (opt
.dirmngr_program
, '/')))
229 pgmname
= opt
.dirmngr_program
;
234 log_info (_("no running dirmngr - starting `%s'\n"),
235 opt
.dirmngr_program
);
239 gpg_error_t tmperr
= gpg_error (gpg_err_code_from_errno (errno
));
240 log_error ("error flushing pending output: %s\n", strerror (errno
));
245 argv
[1] = "--server";
249 if (log_get_fd () != -1)
250 no_close_list
[i
++] = log_get_fd ();
251 no_close_list
[i
++] = fileno (stderr
);
252 no_close_list
[i
] = -1;
254 /* connect to the agent and perform initial handshaking */
255 rc
= assuan_pipe_connect (&ctx
, opt
.dirmngr_program
, argv
,
265 if ( !(p
= strchr (infostr
, PATHSEP_C
)) || p
== infostr
)
267 log_error (_("malformed DIRMNGR_INFO environment variable\n"));
269 force_pipe_server
= 1;
270 return start_dirmngr_ext (ctrl
, ctx_r
);
274 while (*p
&& *p
!= PATHSEP_C
)
276 prot
= *p
? atoi (p
+1) : 0;
279 log_error (_("dirmngr protocol version %d is not supported\n"),
282 force_pipe_server
= 1;
283 return start_dirmngr_ext (ctrl
, ctx_r
);
289 rc
= assuan_socket_connect (&ctx
, infostr
, pid
);
290 #ifdef HAVE_W32_SYSTEM
292 log_debug ("connecting dirmngr at `%s' failed\n", infostr
);
296 #ifndef HAVE_W32_SYSTEM
297 if (gpg_err_code (rc
) == GPG_ERR_ASS_CONNECT_FAILED
)
299 log_info (_("can't connect to the dirmngr - trying fall back\n"));
300 force_pipe_server
= 1;
301 return start_dirmngr_ext (ctrl
, ctx_r
);
303 #endif /*!HAVE_W32_SYSTEM*/
306 prepare_dirmngr (ctrl
, ctx
, rc
);
310 log_error ("can't connect to the dirmngr: %s\n", gpg_strerror (rc
));
311 return gpg_error (GPG_ERR_NO_DIRMNGR
);
316 log_debug ("connection to dirmngr established\n");
322 start_dirmngr (ctrl_t ctrl
)
326 assert (! dirmngr_ctx_locked
);
327 dirmngr_ctx_locked
= 1;
329 err
= start_dirmngr_ext (ctrl
, &dirmngr_ctx
);
330 /* We do not check ERR but the existance of a context because the
331 error might come from a failed command send to the dirmngr.
332 Fixme: Why don't we close the drimngr context if we encountered
333 an error in prepare_dirmngr? */
335 dirmngr_ctx_locked
= 0;
341 release_dirmngr (ctrl_t ctrl
)
345 if (!dirmngr_ctx_locked
)
346 log_error ("WARNING: trying to release a non-locked dirmngr ctx\n");
347 dirmngr_ctx_locked
= 0;
352 start_dirmngr2 (ctrl_t ctrl
)
356 assert (! dirmngr2_ctx_locked
);
357 dirmngr2_ctx_locked
= 1;
359 err
= start_dirmngr_ext (ctrl
, &dirmngr2_ctx
);
361 dirmngr2_ctx_locked
= 0;
367 release_dirmngr2 (ctrl_t ctrl
)
371 if (!dirmngr2_ctx_locked
)
372 log_error ("WARNING: trying to release a non-locked dirmngr2 ctx\n");
373 dirmngr2_ctx_locked
= 0;
378 /* Handle a SENDCERT inquiry. */
380 inq_certificate (void *opaque
, const char *line
)
382 struct inq_certificate_parm_s
*parm
= opaque
;
384 const unsigned char *der
;
387 ksba_sexp_t ski
= NULL
;
389 if (!strncmp (line
, "SENDCERT", 8) && (line
[8] == ' ' || !line
[8]))
393 else if (!strncmp (line
, "SENDCERT_SKI", 12) && (line
[12]==' ' || !line
[12]))
397 /* Send a certificate where a sourceKeyIdentifier is included. */
401 ski
= make_simple_sexp_from_hexstr (line
, &n
);
406 else if (!strncmp (line
, "SENDISSUERCERT", 14)
407 && (line
[14] == ' ' || !line
[14]))
412 else if (!strncmp (line
, "ISTRUSTED", 9) && (line
[9]==' ' || !line
[9]))
414 /* The server is asking us whether the certificate is a trusted
419 struct rootca_flags_s rootca_flags
;
425 for (s
=line
,n
=0; hexdigitp (s
); s
++, n
++)
428 return gpg_error (GPG_ERR_ASS_PARAMETER
);
429 for (s
=line
, n
=0; n
< 40; s
++, n
++)
430 fpr
[n
] = (*s
>= 'a')? (*s
& 0xdf): *s
;
433 if (!gpgsm_agent_istrusted (parm
->ctrl
, NULL
, fpr
, &rootca_flags
))
434 rc
= assuan_send_data (parm
->ctx
, "1", 1);
441 log_error ("unsupported inquiry `%s'\n", line
);
442 return gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE
);
446 { /* Send the current certificate. */
447 der
= ksba_cert_get_image (issuer_mode
? parm
->issuer_cert
: parm
->cert
,
450 rc
= gpg_error (GPG_ERR_INV_CERT_OBJ
);
452 rc
= assuan_send_data (parm
->ctx
, der
, derlen
);
454 else if (issuer_mode
)
456 log_error ("sending specific issuer certificate back "
457 "is not yet implemented\n");
458 rc
= gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE
);
461 { /* Send the given certificate. */
466 err
= gpgsm_find_cert (line
, ski
, &cert
);
469 log_error ("certificate not found: %s\n", gpg_strerror (err
));
470 rc
= gpg_error (GPG_ERR_NOT_FOUND
);
474 der
= ksba_cert_get_image (cert
, &derlen
);
476 rc
= gpg_error (GPG_ERR_INV_CERT_OBJ
);
478 rc
= assuan_send_data (parm
->ctx
, der
, derlen
);
479 ksba_cert_release (cert
);
488 /* Take a 20 byte hexencoded string and put it into the the provided
489 20 byte buffer FPR in binary format. */
491 unhexify_fpr (const char *hexstr
, unsigned char *fpr
)
496 for (s
=hexstr
, n
=0; hexdigitp (s
); s
++, n
++)
499 return 0; /* no fingerprint (invalid or wrong length). */
501 for (s
=hexstr
, n
=0; *s
; s
+= 2, n
++)
507 static assuan_error_t
508 isvalid_status_cb (void *opaque
, const char *line
)
510 struct isvalid_status_parm_s
*parm
= opaque
;
512 if (!strncmp (line
, "PROGRESS", 8) && (line
[8]==' ' || !line
[8]))
516 for (line
+= 8; *line
== ' '; line
++)
518 if (gpgsm_status (parm
->ctrl
, STATUS_PROGRESS
, line
))
519 return gpg_error (GPG_ERR_ASS_CANCELED
);
522 else if (!strncmp (line
, "ONLY_VALID_IF_CERT_VALID", 24)
523 && (line
[24]==' ' || !line
[24]))
526 if (!line
[24] || !unhexify_fpr (line
+25, parm
->fpr
))
527 parm
->seen
++; /* Bumb it to indicate an error. */
535 /* Call the directory manager to check whether the certificate is valid
536 Returns 0 for valid or usually one of the errors:
538 GPG_ERR_CERTIFICATE_REVOKED
544 1 = Do an OCSP check.
545 2 = Do an OCSP check using only the default responder.
548 gpgsm_dirmngr_isvalid (ctrl_t ctrl
,
549 ksba_cert_t cert
, ksba_cert_t issuer_cert
, int use_ocsp
)
551 static int did_options
;
554 char line
[ASSUAN_LINELENGTH
];
555 struct inq_certificate_parm_s parm
;
556 struct isvalid_status_parm_s stparm
;
558 rc
= start_dirmngr (ctrl
);
564 certid
= gpgsm_get_fingerprint_hexstring (cert
, GCRY_MD_SHA1
);
568 certid
= gpgsm_get_certid (cert
);
571 log_error ("error getting the certificate ID\n");
572 release_dirmngr (ctrl
);
573 return gpg_error (GPG_ERR_GENERAL
);
579 char *fpr
= gpgsm_get_fingerprint_string (cert
, GCRY_MD_SHA1
);
580 log_info ("asking dirmngr about %s%s\n", fpr
,
581 use_ocsp
? " (using OCSP)":"");
585 parm
.ctx
= dirmngr_ctx
;
588 parm
.issuer_cert
= issuer_cert
;
592 memset (stparm
.fpr
, 0, 20);
594 /* FIXME: If --disable-crl-checks has been set, we should pass an
595 option to dirmngr, so that no fallback CRL check is done after an
596 ocsp check. It is not a problem right now as dirmngr does not
597 fallback to CRL checking. */
599 /* It is sufficient to send the options only once because we have
600 one connection per process only. */
603 if (opt
.force_crl_refresh
)
604 assuan_transact (dirmngr_ctx
, "OPTION force-crl-refresh=1",
605 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
608 snprintf (line
, DIM(line
)-1, "ISVALID%s %s",
609 use_ocsp
== 2? " --only-ocsp --force-default-responder":"",
611 line
[DIM(line
)-1] = 0;
614 rc
= assuan_transact (dirmngr_ctx
, line
, NULL
, NULL
,
615 inq_certificate
, &parm
,
616 isvalid_status_cb
, &stparm
);
618 log_info ("response of dirmngr: %s\n", rc
? gpg_strerror (rc
): "okay");
621 if (!rc
&& stparm
.seen
)
623 /* Need to also check the certificate validity. */
624 if (stparm
.seen
!= 1)
626 log_error ("communication problem with dirmngr detected\n");
627 rc
= gpg_error (GPG_ERR_INV_CRL
);
632 ksba_cert_t rspcert
= NULL
;
634 /* Fixme: First try to get the certificate from the
635 dirmngr's cache - it should be there. */
638 rc
= gpg_error (GPG_ERR_ENOMEM
);
640 rc
= keydb_search_fpr (kh
, stparm
.fpr
);
642 rc
= keydb_get_cert (kh
, &rspcert
);
645 log_error ("unable to find the certificate used "
646 "by the dirmngr: %s\n", gpg_strerror (rc
));
647 rc
= gpg_error (GPG_ERR_INV_CRL
);
653 rc
= gpgsm_cert_use_ocsp_p (rspcert
);
655 rc
= gpg_error (GPG_ERR_INV_CRL
);
658 /* Note the no_dirmngr flag: This avoids checking
659 this certificate over and over again. */
660 rc
= gpgsm_validate_chain (ctrl
, rspcert
, "", NULL
, 0, NULL
,
661 VALIDATE_FLAG_NO_DIRMNGR
, NULL
);
664 log_error ("invalid certificate used for CRL/OCSP: %s\n",
666 rc
= gpg_error (GPG_ERR_INV_CRL
);
670 ksba_cert_release (rspcert
);
673 release_dirmngr (ctrl
);
681 lookup_cb (void *opaque
, const void *buffer
, size_t length
)
683 struct lookup_parm_s
*parm
= opaque
;
694 put_membuf (&parm
->data
, buffer
, length
);
697 /* END encountered - process what we have */
698 buf
= get_membuf (&parm
->data
, &len
);
701 parm
->error
= gpg_error (GPG_ERR_ENOMEM
);
705 rc
= ksba_cert_new (&cert
);
711 rc
= ksba_cert_init_from_mem (cert
, buf
, len
);
714 log_error ("failed to parse a certificate: %s\n", gpg_strerror (rc
));
718 parm
->cb (parm
->cb_value
, cert
);
721 ksba_cert_release (cert
);
722 init_membuf (&parm
->data
, 4096);
726 /* Return a properly escaped pattern from NAMES. The only error
727 return is NULL to indicate a malloc failure. */
729 pattern_from_strlist (strlist_t names
)
736 for (n
=0, sl
=names
; sl
; sl
= sl
->next
)
738 for (s
=sl
->d
; *s
; s
++, n
++)
740 if (*s
== '%' || *s
== ' ' || *s
== '+')
746 p
= pattern
= xtrymalloc (n
+1);
750 for (sl
=names
; sl
; sl
= sl
->next
)
752 for (s
=sl
->d
; *s
; s
++)
779 *pattern
= 0; /* is empty */
781 p
[-1] = '\0'; /* remove trailing blank */
787 lookup_status_cb (void *opaque
, const char *line
)
789 struct lookup_parm_s
*parm
= opaque
;
791 if (!strncmp (line
, "PROGRESS", 8) && (line
[8]==' ' || !line
[8]))
795 for (line
+= 8; *line
== ' '; line
++)
797 if (gpgsm_status (parm
->ctrl
, STATUS_PROGRESS
, line
))
798 return gpg_error (GPG_ERR_ASS_CANCELED
);
801 else if (!strncmp (line
, "TRUNCATED", 9) && (line
[9]==' ' || !line
[9]))
805 for (line
+=9; *line
== ' '; line
++)
807 gpgsm_status (parm
->ctrl
, STATUS_TRUNCATED
, line
);
814 /* Run the Directory Manager's lookup command using the pattern
815 compiled from the strings given in NAMES. The caller must provide
816 the callback CB which will be passed cert by cert. Note that CTRL
817 is optional. With CACHE_ONLY the dirmngr will search only its own
820 gpgsm_dirmngr_lookup (ctrl_t ctrl
, strlist_t names
, int cache_only
,
821 void (*cb
)(void*, ksba_cert_t
), void *cb_value
)
825 char line
[ASSUAN_LINELENGTH
];
826 struct lookup_parm_s parm
;
828 assuan_context_t ctx
;
830 /* The lookup function can be invoked from the callback of a lookup
831 function, for example to walk the chain. */
832 if (!dirmngr_ctx_locked
)
834 rc
= start_dirmngr (ctrl
);
839 else if (!dirmngr2_ctx_locked
)
841 rc
= start_dirmngr2 (ctrl
);
848 log_fatal ("both dirmngr contexts are in use\n");
851 pattern
= pattern_from_strlist (names
);
854 if (ctx
== dirmngr_ctx
)
855 release_dirmngr (ctrl
);
857 release_dirmngr2 (ctrl
);
859 return out_of_core ();
861 snprintf (line
, DIM(line
)-1, "LOOKUP%s %s",
862 cache_only
? " --cache-only":"", pattern
);
863 line
[DIM(line
)-1] = 0;
869 parm
.cb_value
= cb_value
;
871 init_membuf (&parm
.data
, 4096);
873 rc
= assuan_transact (ctx
, line
, lookup_cb
, &parm
,
874 NULL
, NULL
, lookup_status_cb
, &parm
);
875 xfree (get_membuf (&parm
.data
, &len
));
877 if (ctx
== dirmngr_ctx
)
878 release_dirmngr (ctrl
);
880 release_dirmngr2 (ctrl
);
889 /* Run Command helpers*/
891 /* Fairly simple callback to write all output of dirmngr to stdout. */
893 run_command_cb (void *opaque
, const void *buffer
, size_t length
)
899 if ( fwrite (buffer
, length
, 1, stdout
) != 1 )
900 log_error ("error writing to stdout: %s\n", strerror (errno
));
905 /* Handle inquiries from the dirmngr COMMAND. */
907 run_command_inq_cb (void *opaque
, const char *line
)
909 struct run_command_parm_s
*parm
= opaque
;
912 if ( !strncmp (line
, "SENDCERT", 8) && (line
[8] == ' ' || !line
[8]) )
913 { /* send the given certificate */
916 const unsigned char *der
;
921 return gpg_error (GPG_ERR_ASS_PARAMETER
);
923 err
= gpgsm_find_cert (line
, NULL
, &cert
);
926 log_error ("certificate not found: %s\n", gpg_strerror (err
));
927 rc
= gpg_error (GPG_ERR_NOT_FOUND
);
931 der
= ksba_cert_get_image (cert
, &derlen
);
933 rc
= gpg_error (GPG_ERR_INV_CERT_OBJ
);
935 rc
= assuan_send_data (parm
->ctx
, der
, derlen
);
936 ksba_cert_release (cert
);
939 else if ( !strncmp (line
, "PRINTINFO", 9) && (line
[9] == ' ' || !line
[9]) )
940 { /* Simply show the message given in the argument. */
942 log_info ("dirmngr: %s\n", line
);
946 log_error ("unsupported inquiry `%s'\n", line
);
947 rc
= gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE
);
954 run_command_status_cb (void *opaque
, const char *line
)
956 ctrl_t ctrl
= opaque
;
960 log_info ("dirmngr status: %s\n", line
);
962 if (!strncmp (line
, "PROGRESS", 8) && (line
[8]==' ' || !line
[8]))
966 for (line
+= 8; *line
== ' '; line
++)
968 if (gpgsm_status (ctrl
, STATUS_PROGRESS
, line
))
969 return gpg_error (GPG_ERR_ASS_CANCELED
);
977 /* Pass COMMAND to dirmngr and print all output generated by Dirmngr
978 to stdout. A couple of inquiries are defined (see above). ARGC
979 arguments in ARGV are given to the Dirmngr. Spaces, plus and
980 percent characters within the argument strings are percent escaped
981 so that blanks can act as delimiters. */
983 gpgsm_dirmngr_run_command (ctrl_t ctrl
, const char *command
,
984 int argc
, char **argv
)
991 struct run_command_parm_s parm
;
993 rc
= start_dirmngr (ctrl
);
997 parm
.ctx
= dirmngr_ctx
;
999 len
= strlen (command
) + 1;
1000 for (i
=0; i
< argc
; i
++)
1001 len
+= 1 + 3*strlen (argv
[i
]); /* enough space for percent escaping */
1002 line
= xtrymalloc (len
);
1005 release_dirmngr (ctrl
);
1006 return out_of_core ();
1009 p
= stpcpy (line
, command
);
1010 for (i
=0; i
< argc
; i
++)
1013 for (s
=argv
[i
]; *s
; s
++)
1019 else if (!isprint (*s
) || *s
== '+')
1021 sprintf (p
, "%%%02X", *(const unsigned char *)s
);
1030 rc
= assuan_transact (dirmngr_ctx
, line
,
1031 run_command_cb
, NULL
,
1032 run_command_inq_cb
, &parm
,
1033 run_command_status_cb
, ctrl
);
1035 log_info ("response of dirmngr: %s\n", rc
? gpg_strerror (rc
): "okay");
1036 release_dirmngr (ctrl
);