2
0
mirror of https://github.com/curl/curl.git synced 2025-04-24 16:40:32 +08:00

curl: make --libcurl output better CURLOPT_*SSLVERSION

The option is really two enums ORed together, so it needs special
attention to make the code output nice.

Added test 1481 to verify. Both the server and the proxy versions.

Reported-by: Boris Verkhovskiy
Fixes 
Closes 
This commit is contained in:
Daniel Stenberg 2024-03-14 13:58:45 +01:00
parent 09f367977a
commit 40948189ff
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
5 changed files with 187 additions and 5 deletions

@ -1763,11 +1763,11 @@ static CURLcode single_transfer(struct GlobalConfig *global,
if(config->falsestart)
my_setopt(curl, CURLOPT_SSL_FALSESTART, 1L);
my_setopt_enum(curl, CURLOPT_SSLVERSION,
config->ssl_version | config->ssl_version_max);
my_setopt_SSLVERSION(curl, CURLOPT_SSLVERSION,
config->ssl_version | config->ssl_version_max);
if(config->proxy)
my_setopt_enum(curl, CURLOPT_PROXY_SSLVERSION,
config->proxy_ssl_version);
my_setopt_SSLVERSION(curl, CURLOPT_PROXY_SSLVERSION,
config->proxy_ssl_version);
{
long mask =

@ -107,6 +107,16 @@ const struct NameValue setopt_nv_CURL_SSLVERSION[] = {
NVEND,
};
const struct NameValue setopt_nv_CURL_SSLVERSION_MAX[] = {
NV(CURL_SSLVERSION_MAX_NONE),
NV(CURL_SSLVERSION_MAX_DEFAULT),
NV(CURL_SSLVERSION_MAX_TLSv1_0),
NV(CURL_SSLVERSION_MAX_TLSv1_1),
NV(CURL_SSLVERSION_MAX_TLSv1_2),
NV(CURL_SSLVERSION_MAX_TLSv1_3),
NVEND,
};
const struct NameValue setopt_nv_CURL_TIMECOND[] = {
NV(CURL_TIMECOND_IFMODSINCE),
NV(CURL_TIMECOND_IFUNMODSINCE),
@ -296,6 +306,50 @@ nomem:
return ret;
}
/* setopt wrapper for CURLOPT_SSLVERSION */
CURLcode tool_setopt_SSLVERSION(CURL *curl, struct GlobalConfig *config,
const char *name, CURLoption tag,
long lval)
{
CURLcode ret = CURLE_OK;
bool skip = FALSE;
ret = curl_easy_setopt(curl, tag, lval);
if(!lval)
skip = TRUE;
if(config->libcurl && !skip && !ret) {
/* we only use this for real if --libcurl was used */
const struct NameValue *nv = NULL;
const struct NameValue *nv2 = NULL;
for(nv = setopt_nv_CURL_SSLVERSION; nv->name; nv++) {
if(nv->value == (lval & 0xffff))
break; /* found it */
}
for(nv2 = setopt_nv_CURL_SSLVERSION_MAX; nv2->name; nv2++) {
if(nv2->value == (lval & ~0xffff))
break; /* found it */
}
if(!nv->name) {
/* If no definition was found, output an explicit value.
* This could happen if new values are defined and used
* but the NameValue list is not updated. */
CODE2("curl_easy_setopt(hnd, %s, %ldL);", name, lval);
}
else {
CODE3("curl_easy_setopt(hnd, %s, (long)(%s | %s));",
name, nv->name, nv2->name);
}
}
#ifdef DEBUGBUILD
if(ret)
warnf(config, "option %s returned error (%d)", name, (int)ret);
#endif
nomem:
return ret;
}
/* setopt wrapper for bitmasks */
CURLcode tool_setopt_bitmask(CURL *curl, struct GlobalConfig *config,
const char *name, CURLoption tag,

@ -52,6 +52,7 @@ extern const struct NameValue setopt_nv_CURLPROXY[];
extern const struct NameValue setopt_nv_CURL_SOCKS_PROXY[];
extern const struct NameValue setopt_nv_CURL_HTTP_VERSION[];
extern const struct NameValue setopt_nv_CURL_SSLVERSION[];
extern const struct NameValue setopt_nv_CURL_SSLVERSION_MAX[];
extern const struct NameValue setopt_nv_CURL_TIMECOND[];
extern const struct NameValue setopt_nv_CURLFTPSSL_CCC[];
extern const struct NameValue setopt_nv_CURLUSESSL[];
@ -81,6 +82,9 @@ extern const struct NameValueUnsigned setopt_nv_CURLHSTS[];
CURLcode tool_setopt_enum(CURL *curl, struct GlobalConfig *config,
const char *name, CURLoption tag,
const struct NameValue *nv, long lval);
CURLcode tool_setopt_SSLVERSION(CURL *curl, struct GlobalConfig *config,
const char *name, CURLoption tag,
long lval);
CURLcode tool_setopt_flags(CURL *curl, struct GlobalConfig *config,
const char *name, CURLoption tag,
const struct NameValue *nv, long lval);
@ -106,6 +110,9 @@ CURLcode tool_setopt(CURL *curl, bool str, struct GlobalConfig *global,
#define my_setopt_enum(x,y,z) \
SETOPT_CHECK(tool_setopt_enum(x, global, #y, y, setopt_nv_ ## y, z), y)
#define my_setopt_SSLVERSION(x,y,z) \
SETOPT_CHECK(tool_setopt_SSLVERSION(x, global, #y, y, z), y)
#define my_setopt_bitmask(x,y,z) \
SETOPT_CHECK(tool_setopt_bitmask(x, global, #y, y, setopt_nv_ ## y, z), y)
@ -132,6 +139,9 @@ CURLcode tool_setopt(CURL *curl, bool str, struct GlobalConfig *global,
#define my_setopt_enum(x,y,z) \
SETOPT_CHECK(curl_easy_setopt(x, y, z), y)
#define my_setopt_SSLVERSION(x,y,z) \
SETOPT_CHECK(curl_easy_setopt(x, y, z), y)
#define my_setopt_bitmask(x,y,z) \
SETOPT_CHECK(curl_easy_setopt(x, y, z), y)

@ -188,7 +188,7 @@ test1447 test1448 test1449 test1450 test1451 test1452 test1453 test1454 \
test1455 test1456 test1457 test1458 test1459 test1460 test1461 test1462 \
test1463 test1464 test1465 test1466 test1467 test1468 test1469 test1470 \
test1471 test1472 test1473 test1474 test1475 test1476 test1477 test1478 \
test1479 test1480 \
test1479 test1480 test1481 \
\
test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \
test1508 test1509 test1510 test1511 test1512 test1513 test1514 test1515 \

118
tests/data/test1481 Normal file

@ -0,0 +1,118 @@
<testcase>
<info>
<keywords>
HTTP
HTTP GET
--libcurl
</keywords>
</info>
# Server-side
<reply>
<data>
HTTP/1.1 200 OK
Date: Thu, 29 Jul 2008 14:49:00 GMT
Server: test-server/fake
Content-Length: 0
Connection: close
</data>
</reply>
# Client-side
<client>
<server>
http
</server>
<features>
proxy
ssl
</features>
<name>
--libcurl with TLS version options
</name>
<setenv>
SSL_CERT_FILE=
</setenv>
<command>
http://moo/ --libcurl %LOGDIR/test%TESTNUMBER.c --tls-max 1.3 --proxy-tlsv1 -x http://%HOSTIP:%HTTPPORT
</command>
</client>
# Verify data after the test has been "shot"
<verify>
<protocol>
GET http://moo/ HTTP/1.1
Host: moo
User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
</protocol>
<stripfile>
s/(USERAGENT, \")[^\"]+/${1}stripped/
# CURLOPT_SSL_VERIFYPEER, SSH_KNOWNHOSTS and HTTP_VERSION vary with
# CURLOPT_INTERLEAVEDATA requires RTSP protocol
# configurations - just ignore them
$_ = '' if /CURLOPT_SSL_VERIFYPEER/
$_ = '' if /CURLOPT_SSH_KNOWNHOSTS/
$_ = '' if /CURLOPT_HTTP_VERSION/
$_ = '' if /CURLOPT_HTTP09_ALLOWED/
$_ = '' if /CURLOPT_INTERLEAVEDATA/
</stripfile>
<file name="%LOGDIR/test%TESTNUMBER.c" mode="text">
/********* Sample code generated by the curl command line tool **********
* All curl_easy_setopt() options are documented at:
* https://curl.se/libcurl/c/curl_easy_setopt.html
************************************************************************/
#include <curl/curl.h>
int main(int argc, char *argv[])
{
CURLcode ret;
CURL *hnd;
hnd = curl_easy_init();
curl_easy_setopt(hnd, CURLOPT_BUFFERSIZE, 102400L);
curl_easy_setopt(hnd, CURLOPT_URL, "http://moo/");
curl_easy_setopt(hnd, CURLOPT_PROXY, "http://%HOSTIP:%HTTPPORT");
curl_easy_setopt(hnd, CURLOPT_USERAGENT, "stripped");
curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
curl_easy_setopt(hnd, CURLOPT_SSLVERSION, (long)(CURL_SSLVERSION_DEFAULT | CURL_SSLVERSION_MAX_TLSv1_3));
curl_easy_setopt(hnd, CURLOPT_PROXY_SSLVERSION, (long)(CURL_SSLVERSION_TLSv1 | CURL_SSLVERSION_MAX_NONE));
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
%if ftp
curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L);
%endif
curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
/* Here is a list of options the curl code used that cannot get generated
as source easily. You may choose to either not use them or implement
them yourself.
CURLOPT_WRITEDATA was set to an object pointer
CURLOPT_WRITEFUNCTION was set to a function pointer
CURLOPT_READDATA was set to an object pointer
CURLOPT_READFUNCTION was set to a function pointer
CURLOPT_SEEKDATA was set to an object pointer
CURLOPT_SEEKFUNCTION was set to a function pointer
CURLOPT_ERRORBUFFER was set to an object pointer
CURLOPT_STDERR was set to an object pointer
CURLOPT_DEBUGFUNCTION was set to a function pointer
CURLOPT_DEBUGDATA was set to an object pointer
CURLOPT_HEADERFUNCTION was set to a function pointer
CURLOPT_HEADERDATA was set to an object pointer
*/
ret = curl_easy_perform(hnd);
curl_easy_cleanup(hnd);
hnd = NULL;
return (int)ret;
}
/**** End of sample code ****/
</file>
</verify>
</testcase>