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>
This commit is contained in:
Johannes Schindelin 2017-07-07 11:49:08 +02:00 committed by Daniel Stenberg
parent b59288f881
commit 1328f69d53
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
5 changed files with 82 additions and 14 deletions

View file

@ -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 */