From 290d762ea13a1d95affa0888c5450b33b00241e8 Mon Sep 17 00:00:00 2001 From: Bo Anderson Date: Tue, 21 Jul 2020 18:28:31 +0100 Subject: [PATCH] Handle MultiSSL Upstream-Status: Accepted [https://github.com/pycurl/pycurl/pull/639] Signed-off-by: Stefan Strogin --- src/module.c | 41 ++++++++++++++++++++++++++++++++++++++++- src/pycurl.h | 11 +++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/module.c b/src/module.c index 23387ec..dbc5b0c 100644 --- a/src/module.c +++ b/src/module.c @@ -322,12 +322,21 @@ initpycurl(void) { PyObject *m, *d; const curl_version_info_data *vi; - const char *libcurl_version, *runtime_ssl_lib; + const char *libcurl_version; size_t libcurl_version_len, pycurl_version_len; PyObject *xio_module = NULL; PyObject *collections_module = NULL; PyObject *named_tuple = NULL; PyObject *arglist = NULL; +#ifdef HAVE_CURL_GLOBAL_SSLSET + const curl_ssl_backend **ssllist = NULL; + CURLsslset sslset; + int i, runtime_supported_backend_found = 0; + char backends[200]; + size_t backends_len = 0; +#else + const char *runtime_ssl_lib; +#endif assert(Curl_Type.tp_weaklistoffset > 0); assert(CurlMulti_Type.tp_weaklistoffset > 0); @@ -346,6 +355,35 @@ initpycurl(void) } /* Our compiled crypto locks should correspond to runtime ssl library. */ +#ifdef HAVE_CURL_GLOBAL_SSLSET + sslset = curl_global_sslset(-1, COMPILE_SSL_LIB, &ssllist); + if (sslset != CURLSSLSET_OK) { + if (sslset == CURLSSLSET_NO_BACKENDS) { + strcpy(backends, "none"); + } else { + for (i = 0; ssllist[i] != NULL; i++) { + switch (ssllist[i]->id) { + case CURLSSLBACKEND_OPENSSL: + case CURLSSLBACKEND_GNUTLS: + case CURLSSLBACKEND_NSS: + case CURLSSLBACKEND_WOLFSSL: + case CURLSSLBACKEND_MBEDTLS: + runtime_supported_backend_found = 1; + break; + default: + break; + } + if (backends_len < sizeof(backends)) { + backends_len += snprintf(backends + backends_len, sizeof(backends) - backends_len, "%s%s", (i > 0) ? ", " : "", ssllist[i]->name); + } + } + } + if (runtime_supported_backend_found == COMPILE_SUPPORTED_SSL_BACKEND_FOUND) { + PyErr_Format(PyExc_ImportError, "pycurl: libcurl link-time ssl backends (%s) do not include compile-time ssl backend (%s)", backends, COMPILE_SSL_LIB); + goto error; + } + } +#else if (vi->ssl_version == NULL) { runtime_ssl_lib = "none/other"; } else if (!strncmp(vi->ssl_version, "OpenSSL/", 8) || !strncmp(vi->ssl_version, "LibreSSL/", 9) || @@ -366,6 +404,7 @@ initpycurl(void) PyErr_Format(PyExc_ImportError, "pycurl: libcurl link-time ssl backend (%s) is different from compile-time ssl backend (%s)", runtime_ssl_lib, COMPILE_SSL_LIB); goto error; } +#endif /* Initialize the type of the new type objects here; doing it here * is required for portability to Windows without requiring C++. */ diff --git a/src/pycurl.h b/src/pycurl.h index 02db495..a83c85b 100644 --- a/src/pycurl.h +++ b/src/pycurl.h @@ -154,6 +154,10 @@ pycurl_inet_ntop (int family, void *addr, char *string, size_t string_size); #define HAVE_CURLINFO_HTTP_VERSION #endif +#if LIBCURL_VERSION_NUM >= 0x073800 /* check for 7.56.0 or greater */ +#define HAVE_CURL_GLOBAL_SSLSET +#endif + #undef UNUSED #define UNUSED(var) ((void)&var) @@ -165,6 +169,7 @@ pycurl_inet_ntop (int family, void *addr, char *string, size_t string_size); # include # include # define COMPILE_SSL_LIB "openssl" +# define COMPILE_SUPPORTED_SSL_BACKEND_FOUND 1 # elif defined(HAVE_CURL_WOLFSSL) # include # if defined(OPENSSL_EXTRA) @@ -187,6 +192,7 @@ pycurl_inet_ntop (int family, void *addr, char *string, size_t string_size); # endif # endif # define COMPILE_SSL_LIB "wolfssl" +# define COMPILE_SUPPORTED_SSL_BACKEND_FOUND 1 # elif defined(HAVE_CURL_GNUTLS) # include # if GNUTLS_VERSION_NUMBER <= 0x020b00 @@ -195,13 +201,16 @@ pycurl_inet_ntop (int family, void *addr, char *string, size_t string_size); # include # endif # define COMPILE_SSL_LIB "gnutls" +# define COMPILE_SUPPORTED_SSL_BACKEND_FOUND 1 # elif defined(HAVE_CURL_NSS) # define COMPILE_SSL_LIB "nss" +# define COMPILE_SUPPORTED_SSL_BACKEND_FOUND 1 # elif defined(HAVE_CURL_MBEDTLS) # include # define PYCURL_NEED_SSL_TSL # define PYCURL_NEED_MBEDTLS_TSL # define COMPILE_SSL_LIB "mbedtls" +# define COMPILE_SUPPORTED_SSL_BACKEND_FOUND 1 # else # ifdef _MSC_VER /* sigh */ @@ -218,9 +227,11 @@ pycurl_inet_ntop (int family, void *addr, char *string, size_t string_size); /* since we have no crypto callbacks for other ssl backends, * no reason to require users match those */ # define COMPILE_SSL_LIB "none/other" +# define COMPILE_SUPPORTED_SSL_BACKEND_FOUND 0 # endif /* HAVE_CURL_OPENSSL || HAVE_CURL_WOLFSSL || HAVE_CURL_GNUTLS || HAVE_CURL_NSS || HAVE_CURL_MBEDTLS */ #else # define COMPILE_SSL_LIB "none/other" +# define COMPILE_SUPPORTED_SSL_BACKEND_FOUND 0 #endif /* HAVE_CURL_SSL */ #if defined(PYCURL_NEED_SSL_TSL) -- 2.28.0