diff --git a/deps/deps-linux.cmake b/deps/deps-linux.cmake index 9050a0701..3727eba7b 100644 --- a/deps/deps-linux.cmake +++ b/deps/deps-linux.cmake @@ -55,7 +55,12 @@ ExternalProject_Add(dep_libcurl --enable-versioned-symbols --enable-threaded-resolver --with-random=/dev/urandom - --with-ca-bundle=/etc/ssl/certs/ca-certificates.crt + + # CA root certificate paths will be set for openssl at runtime. + --without-ca-bundle + --without-ca-path + --with-ca-fallback # to look for the ssl backend's ca store + --disable-ldap --disable-ldaps --disable-manual diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 5e0c34da0..0bc26405b 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -197,6 +197,10 @@ if(APPLE) target_link_libraries(libslic3r_gui ${DISKARBITRATION_LIBRARY}) endif() +if (SLIC3R_STATIC) + target_compile_definitions(libslic3r_gui PRIVATE OPENSSL_CERT_OVERRIDE) +endif () + if (SLIC3R_PCH AND NOT SLIC3R_SYNTAXONLY) add_precompiled_header(libslic3r_gui pchheader.hpp FORCEINCLUDE) endif () diff --git a/src/slic3r/Utils/Http.cpp b/src/slic3r/Utils/Http.cpp index 69301547c..30e25abe2 100644 --- a/src/slic3r/Utils/Http.cpp +++ b/src/slic3r/Utils/Http.cpp @@ -7,10 +7,17 @@ #include #include #include +#include +#include #include +#include #include +#ifdef OPENSSL_CERT_OVERRIDE +#include +#endif + #include "libslic3r/libslic3r.h" #include "libslic3r/Utils.hpp" @@ -22,14 +29,56 @@ namespace Slic3r { // Private -class CurlGlobalInit +struct CurlGlobalInit { - static const CurlGlobalInit instance; + static std::unique_ptr instance; - CurlGlobalInit() { ::curl_global_init(CURL_GLOBAL_DEFAULT); } + CurlGlobalInit() + { +#ifdef OPENSSL_CERT_OVERRIDE // defined if SLIC3R_STATIC=ON + + // Look for a set of distro specific directories. Don't change the + // order: https://bugzilla.redhat.com/show_bug.cgi?id=1053882 + static const char * CA_BUNDLES[] = { + "/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL 6 + "/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc. + "/usr/share/ssl/certs/ca-bundle.crt", + "/usr/local/share/certs/ca-root-nss.crt", // FreeBSD + "/etc/ssl/cert.pem", + "/etc/ssl/ca-bundle.pem" // OpenSUSE Tumbleweed + }; + + namespace fs = boost::filesystem; + // Env var name for the OpenSSL CA bundle (SSL_CERT_FILE nomally) + const char *const SSL_CA_FILE = X509_get_default_cert_file_env(); + const char * ssl_cafile = ::getenv(SSL_CA_FILE); + + if (!ssl_cafile) + ssl_cafile = X509_get_default_cert_file(); + + int replace = true; + + if (!ssl_cafile || !fs::exists(fs::path(ssl_cafile))) + for (const char * bundle : CA_BUNDLES) { + if (fs::exists(fs::path(bundle))) { + ::setenv(SSL_CA_FILE, bundle, replace); + break; + } + } + + BOOST_LOG_TRIVIAL(info) + << "Detected OpenSSL root CA store: " << ::getenv(SSL_CA_FILE); + +#endif + + ::curl_global_init(CURL_GLOBAL_DEFAULT); + } + ~CurlGlobalInit() { ::curl_global_cleanup(); } }; +std::unique_ptr CurlGlobalInit::instance; + struct Http::priv { enum { @@ -83,6 +132,9 @@ Http::priv::priv(const std::string &url) , limit(0) , cancel(false) { + if (!CurlGlobalInit::instance) + CurlGlobalInit::instance = std::make_unique(); + if (curl == nullptr) { throw std::runtime_error(std::string("Could not construct Curl object")); }