diff --git a/CHANGES b/CHANGES index dd0ed6fa4..6205e3f96 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,13 @@ Changelog +Michal Marek (20 Mar 2008) +- Added --with-ca-path=DIRECTORY configure option to use an openSSL CApath by + default instead of a ca bundle. The configure script will also look for a + ca path if no ca bundle is found and no option given. + +- Fixed detection of previously installed curl-ca-bundle.crt + Daniel Fandrich (18 Mar 2008) - Added test 626 to reproduce an infinite loop when given an invalid SFTP quote command reported by Vincent Le Normand, and fixed it. diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 281bd59eb..6fc9c3def 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -22,6 +22,8 @@ This release includes the following changes: currently only works in C mode) o curl_easy_setopt(), curl_easy_getinfo(), curl_share_setopt() and curl_multi_setopt() uses are now checked to use exactly three arguments + o --with-ca-path=DIR configure option allows to set an openSSL CApath instead + of a default ca bundle. This release includes the following bugfixes: diff --git a/acinclude.m4 b/acinclude.m4 index 5b6a98e0a..bdfb6cea1 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -2500,41 +2500,97 @@ dnl regarding the paths this will scan: dnl /etc/ssl/certs/ca-certificates.crt Debian systems dnl /etc/pki/tls/certs/ca-bundle.crt Redhat and Mandriva dnl /usr/share/ssl/certs/ca-bundle.crt old(er) Redhat +dnl /etc/ssl/certs/ (ca path) SUSE AC_DEFUN([CURL_CHECK_CA_BUNDLE], [ - AC_MSG_CHECKING([default CA cert bundle]) + AC_MSG_CHECKING([default CA cert bundle/path]) AC_ARG_WITH(ca-bundle, AC_HELP_STRING([--with-ca-bundle=FILE], [File name to use as CA bundle]) AC_HELP_STRING([--without-ca-bundle], [Don't use a default CA bundle]), - [ ca="$withval" ], [ - dnl the path we previously would have installed the curl ca bundle - dnl to, and thus we now check for an already existing cert in that place - dnl in case we find no other - if test "x$prefix" != xNONE; then - cac="\${prefix}/share/curl/curl-ca-bundle.crt" - else - cac="$ac_default_prefix/share/curl/curl-ca-bundle.crt" + want_ca="$withval" + if test "x$want_ca" = "xyes"; then + AC_MSG_ERROR([--with-ca-bundle=FILE requires a path to the CA bundle]) fi + ], + [ want_ca="unset" ]) + AC_ARG_WITH(ca-path, +AC_HELP_STRING([--with-ca-path=DIRECTORY], [Directory to use as CA path]) +AC_HELP_STRING([--without-ca-path], [Don't use a default CA path]), + [ + want_capath="$withval" + if test "x$want_capath" = "xyes"; then + AC_MSG_ERROR([--with-ca-path=DIRECTORY requires a path to the CA path directory]) + fi + ], + [ want_capath="unset"]) - for a in /etc/ssl/certs/ca-certificates.crt \ - /etc/pki/tls/certs/ca-bundle.crt \ - /usr/share/ssl/certs/ca-bundle.crt \ - "$cac"; do - if test -f $a; then - ca="$a" - break + if test "x$want_ca" != "xno" -a "x$want_ca" != "xunset" -a \ + "x$want_capath" != "xno" -a "x$want_capath" != "xunset"; then + dnl both given + AC_MSG_ERROR([Can't specify both --with-ca-bundle and --with-ca-path.]) + elif test "x$want_ca" != "xno" -a "x$want_ca" != "xunset"; then + dnl --with-ca-bundle given + ca="$want_ca" + capath="no" + elif test "x$want_capath" != "xno" -a "x$want_capath" != "xunset"; then + dnl --with-ca-path given + if test "x$OPENSSL_ENABLED" != "x1"; then + AC_MSG_ERROR([--with-ca-path only works with openSSL]) + fi + capath="$want_capath" + ca="no" + else + dnl neither of --with-ca-* given + dnl first try autodetecting a CA bundle , then a CA path + dnl both autodetections can be skipped by --without-ca-* + ca="no" + capath="no" + if test "x$want_ca" = "xunset"; then + dnl the path we previously would have installed the curl ca bundle + dnl to, and thus we now check for an already existing cert in that place + dnl in case we find no other + if test "x$prefix" != xNONE; then + cac="${prefix}/share/curl/curl-ca-bundle.crt" + else + cac="$ac_default_prefix/share/curl/curl-ca-bundle.crt" fi - done - ] - ) + + for a in /etc/ssl/certs/ca-certificates.crt \ + /etc/pki/tls/certs/ca-bundle.crt \ + /usr/share/ssl/certs/ca-bundle.crt \ + "$cac"; do + if test -f "$a"; then + ca="$a" + break + fi + done + fi + if test "x$want_capath" = "xunset" -a "x$ca" = "xno" -a \ + "x$OPENSSL_ENABLED" = "x1"; then + for a in /etc/ssl/certs/; do + if test -d "$a" && ls "$a"/[[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]].0 >/dev/null 2>/dev/null; then + capath="$a" + break + fi + done + fi + fi + + if test "x$ca" != "xno"; then CURL_CA_BUNDLE='"'$ca'"' AC_SUBST(CURL_CA_BUNDLE) + AC_MSG_RESULT([$ca]) + elif test "x$capath" != "xno"; then + CURL_CA_PATH="\"$capath\"" + AC_SUBST(CURL_CA_PATH) + AC_MSG_RESULT([$capath (capath)]) + else + AC_MSG_RESULT([no]) fi - AC_MSG_RESULT([$ca]) ]) diff --git a/configure.ac b/configure.ac index 6c532c889..7a944431a 100644 --- a/configure.ac +++ b/configure.ac @@ -1618,6 +1618,7 @@ dnl ********************************************************************** CURL_CHECK_CA_BUNDLE AM_CONDITIONAL(CABUNDLE, test x$ca != xno) +AM_CONDITIONAL(CAPATH, test x$capath != xno) dnl ********************************************************************** dnl Check for the presence of IDN libraries and headers @@ -2488,7 +2489,8 @@ AC_MSG_NOTICE([Configured to build curl/libcurl: Built-in manual: ${curl_manual_msg} Verbose errors: ${curl_verbose_msg} SSPI support: ${curl_sspi_msg} - ca cert path: ${ca} + ca cert bundle: ${ca} + ca cert path: ${capath} LDAP support: ${curl_ldap_msg} LDAPS support: ${curl_ldaps_msg} ]) diff --git a/lib/Makefile.am b/lib/Makefile.am index f342946a6..350931df0 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -113,6 +113,11 @@ if CABUNDLE else echo '#undef CURL_CA_BUNDLE /* unknown default path */' >> $@ endif +if CAPATH + echo '#define CURL_CA_PATH @CURL_CA_PATH@' >> $@ +else + echo '#undef CURL_CA_PATH /* unknown default path */' >>$@ +endif # this hook is mainly for non-unix systems to build even if configure # isn't run diff --git a/lib/easy.c b/lib/easy.c index cfa6c41b1..93b5095a1 100644 --- a/lib/easy.c +++ b/lib/easy.c @@ -745,9 +745,11 @@ void curl_easy_reset(CURL *curl) */ data->set.ssl.verifypeer = TRUE; data->set.ssl.verifyhost = 2; -#ifdef CURL_CA_BUNDLE - /* This is our prefered CA cert bundle since install time */ + /* This is our prefered CA cert bundle/path since install time */ +#if defined(CURL_CA_BUNDLE) (void) curl_easy_setopt(curl, CURLOPT_CAINFO, (char *) CURL_CA_BUNDLE); +#elif defined(CURL_CA_PATH) + (void) curl_easy_setopt(curl, CURLOPT_CAPATH, (char *) CURL_CA_PATH); #endif data->set.ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth diff --git a/lib/url.c b/lib/url.c index 541c11e79..6b07f2e82 100644 --- a/lib/url.c +++ b/lib/url.c @@ -746,10 +746,12 @@ CURLcode Curl_open(struct SessionHandle **curl) data->set.ssl.verifypeer = TRUE; data->set.ssl.verifyhost = 2; data->set.ssl.sessionid = TRUE; /* session ID caching enabled by default */ -#ifdef CURL_CA_BUNDLE - /* This is our preferred CA cert bundle since install time */ + /* This is our preferred CA cert bundle/path since install time */ +#if defined(CURL_CA_BUNDLE) res = setstropt(&data->set.str[STRING_SSL_CAFILE], (char *) CURL_CA_BUNDLE); +#elif defined(CURL_CA_PATH) + res = setstropt(&data->set.str[STRING_SSL_CAPATH], (char *) CURL_CA_PATH); #endif }