diff options
author | Johannes Schindelin <johannes.schindelin@gmx.de> | 2017-07-07 11:49:08 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2017-08-28 14:56:59 +0200 |
commit | 1328f69d53f2f2e937696ea954c480412b018451 (patch) | |
tree | 289545b26293a9a261e768cc6d1192d7e7b042c1 | |
parent | b59288f88146b64ac5fda296675c523df11658b8 (diff) |
vtls: introduce curl_global_sslset()
Let's add a compile time safe API to select an SSL backend. This
function needs to be called *before* curl_global_init(), and can be
called only once.
Side note: we do not explicitly test that it is called before
curl_global_init(), but we do verify that it is not called multiple times
(even implicitly).
If SSL is used before the function was called, it will use whatever the
CURL_SSL_BACKEND environment variable says (or default to the first
available SSL backend), and if a subsequent call to
curl_global_sslset() disagrees with the previous choice, it will fail
with CURLSSLSET_TOO_LATE.
The function also accepts an "avail" parameter to point to a (read-only)
NULL-terminated list of available backends. This comes in real handy if
an application wants to let the user choose between whatever SSL backends
the currently available libcurl has to offer: simply call
curl_global_sslset(-1, NULL, &avail);
which will return CURLSSLSET_UNKNOWN_BACKEND and populate the avail
variable to point to the relevant information to present to the user.
Just like with the HTTP/2 push functions, we have to add the function
declaration of curl_global_sslset() function to the header file
*multi.h* because VMS and OS/400 require a stable order of functions
declared in include/curl/*.h (where the header files are sorted
alphabetically). This looks a bit funny, but it cannot be helped.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
-rw-r--r-- | docs/libcurl/symbols-in-versions | 3 | ||||
-rw-r--r-- | include/curl/curl.h | 5 | ||||
-rw-r--r-- | include/curl/multi.h | 44 | ||||
-rw-r--r-- | lib/vtls/vtls.c | 43 | ||||
-rw-r--r-- | tests/data/test1135 | 1 |
5 files changed, 82 insertions, 14 deletions
diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions index d3a2ff886..b9fdfe2a0 100644 --- a/docs/libcurl/symbols-in-versions +++ b/docs/libcurl/symbols-in-versions @@ -690,6 +690,9 @@ CURLSSLBACKEND_SCHANNEL 7.34.0 CURLSSLBACKEND_WOLFSSL 7.49.0 CURLSSLOPT_ALLOW_BEAST 7.25.0 CURLSSLOPT_NO_REVOKE 7.44.0 +CURLSSLSET_OK 7.56.0 +CURLSSLSET_UNKNOWN_BACKEND 7.56.0 +CURLSSLSET_TOO_LATE 7.56.0 CURLUSESSL_ALL 7.17.0 CURLUSESSL_CONTROL 7.17.0 CURLUSESSL_NONE 7.17.0 diff --git a/include/curl/curl.h b/include/curl/curl.h index 146044398..3936d1e43 100644 --- a/include/curl/curl.h +++ b/include/curl/curl.h @@ -2540,11 +2540,6 @@ CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask); #define CURLPAUSE_ALL (CURLPAUSE_RECV|CURLPAUSE_SEND) #define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT) -typedef struct { - curl_sslbackend id; - const char *name; -} curl_ssl_backend; - #ifdef __cplusplus } #endif diff --git a/include/curl/multi.h b/include/curl/multi.h index f93e511be..c7c048a05 100644 --- a/include/curl/multi.h +++ b/include/curl/multi.h @@ -432,6 +432,50 @@ typedef int (*curl_push_callback)(CURL *parent, struct curl_pushheaders *headers, void *userp); +/* + * NAME curl_global_sslset() + * + * DESCRIPTION + * + * When built with multiple SSL backends, curl_global_sslset() allows to + * choose one. This function can only be called once, and it must be called + * *before* curl_global_init(). + * + * The backend can be identified by the id (e.g. CURLSSLBACKEND_OPENSSL). The + * backend can also be specified via the name parameter (passing -1 as id). + * If both id and name are specified, the name will be ignored. If neither id + * nor name are specified, the function will fail with + * CURLSSLSET_UNKNOWN_BACKEND and set the "avail" pointer to the + * NULL-terminated list of available backends. + * + * Upon success, the function returns CURLSSLSET_OK. + * + * If the specified SSL backend is not available, the function returns + * CURLSSLSET_UNKNOWN_BACKEND and sets the "avail" pointer to a NULL-terminated + * list of available SSL backends. + * + * The SSL backend can be set only once. If it has already been set, a + * subsequent attempt to change it will result in a CURLSSLSET_TOO_LATE. + */ + +typedef struct { + curl_sslbackend id; + const char *name; +} curl_ssl_backend; + +typedef enum { + CURLSSLSET_OK = 0, + CURLSSLSET_UNKNOWN_BACKEND, + CURLSSLSET_TOO_LATE +} CURLsslset; + +CURL_EXTERN CURLsslset curl_global_sslset(curl_sslbackend id, const char *name, + const curl_ssl_backend ***avail); + +#ifdef __cplusplus +} +#endif + #ifdef __cplusplus } /* end of extern "C" */ #endif diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c index b149d40cf..5d125141f 100644 --- a/lib/vtls/vtls.c +++ b/lib/vtls/vtls.c @@ -131,13 +131,13 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config* sslc) } #ifdef USE_SSL -static int multissl_init(void); +static int multissl_init(const struct Curl_ssl *backend); #endif int Curl_ssl_backend(void) { #ifdef USE_SSL - multissl_init(); + multissl_init(NULL); return Curl_ssl->info.id; #else return (int)CURLSSLBACKEND_NONE; @@ -1056,21 +1056,21 @@ CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen, static int Curl_multissl_init(void) { - if(multissl_init()) + if(multissl_init(NULL)) return 1; return Curl_ssl->init(); } static size_t Curl_multissl_version(char *buffer, size_t size) { - if(multissl_init()) + if(multissl_init(NULL)) return 0; return Curl_ssl->version(buffer, size); } static CURLcode Curl_multissl_connect(struct connectdata *conn, int sockindex) { - if(multissl_init()) + if(multissl_init(NULL)) return CURLE_FAILED_INIT; return Curl_ssl->connect(conn, sockindex); } @@ -1078,7 +1078,7 @@ static CURLcode Curl_multissl_connect(struct connectdata *conn, int sockindex) static CURLcode Curl_multissl_connect_nonblocking(struct connectdata *conn, int sockindex, bool *done) { - if(multissl_init()) + if(multissl_init(NULL)) return CURLE_FAILED_INIT; return Curl_ssl->connect_nonblocking(conn, sockindex, done); } @@ -1086,14 +1086,14 @@ static CURLcode Curl_multissl_connect_nonblocking(struct connectdata *conn, static void *Curl_multissl_get_internals(struct ssl_connect_data *connssl, CURLINFO info) { - if(multissl_init()) + if(multissl_init(NULL)) return NULL; return Curl_ssl->get_internals(connssl, info); } static void Curl_multissl_close(struct connectdata *conn, int sockindex) { - if(multissl_init()) + if(multissl_init(NULL)) return; Curl_ssl->close(conn, sockindex); } @@ -1167,7 +1167,7 @@ static const struct Curl_ssl *available_backends[] = { NULL }; -static int multissl_init(void) +static int multissl_init(const struct Curl_ssl *backend) { const char *env; int i; @@ -1175,6 +1175,11 @@ static int multissl_init(void) if(Curl_ssl != &Curl_ssl_multi) return 1; + if(backend) { + Curl_ssl = backend; + return 0; + } + if(!available_backends[0]) return 1; @@ -1191,4 +1196,24 @@ static int multissl_init(void) return 0; } +CURLsslset curl_global_sslset(curl_sslbackend id, const char *name, + const curl_ssl_backend ***avail) +{ + int i; + + if(Curl_ssl != &Curl_ssl_multi) + return id == Curl_ssl->info.id ? CURLSSLSET_OK : CURLSSLSET_TOO_LATE; + + for(i = 0; available_backends[i]; i++) + if(available_backends[i]->info.id == id || + (name && !strcmp(available_backends[i]->info.name, name))) { + multissl_init(available_backends[i]); + return CURLSSLSET_OK; + } + + if(avail) + *avail = (const curl_ssl_backend **)&available_backends; + return CURLSSLSET_UNKNOWN_BACKEND; +} + #endif /* USE_SSL */ diff --git a/tests/data/test1135 b/tests/data/test1135 index f7c6a7ae2..fb0a4e0c1 100644 --- a/tests/data/test1135 +++ b/tests/data/test1135 @@ -89,6 +89,7 @@ CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle, CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle, CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h, CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h, +CURL_EXTERN CURLsslset curl_global_sslset(curl_sslbackend id, const char *name, </stdout> </verify> |