diff --git a/src/tool_operate.c b/src/tool_operate.c index 5a5fc8745e..7e2c1eefe0 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -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 = diff --git a/src/tool_setopt.c b/src/tool_setopt.c index b41b6d1d26..656adbda8a 100644 --- a/src/tool_setopt.c +++ b/src/tool_setopt.c @@ -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, diff --git a/src/tool_setopt.h b/src/tool_setopt.h index cd59a74cd8..6588da9ced 100644 --- a/src/tool_setopt.h +++ b/src/tool_setopt.h @@ -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) diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc index 06bc5c54f9..50b404b468 100644 --- a/tests/data/Makefile.inc +++ b/tests/data/Makefile.inc @@ -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 \ diff --git a/tests/data/test1481 b/tests/data/test1481 new file mode 100644 index 0000000000..ca638f5130 --- /dev/null +++ b/tests/data/test1481 @@ -0,0 +1,118 @@ + + + +HTTP +HTTP GET +--libcurl + + + +# Server-side + + +HTTP/1.1 200 OK +Date: Thu, 29 Jul 2008 14:49:00 GMT +Server: test-server/fake +Content-Length: 0 +Connection: close + + + + +# Client-side + + +http + + +proxy +ssl + + +--libcurl with TLS version options + + +SSL_CERT_FILE= + + +http://moo/ --libcurl %LOGDIR/test%TESTNUMBER.c --tls-max 1.3 --proxy-tlsv1 -x http://%HOSTIP:%HTTPPORT + + + +# Verify data after the test has been "shot" + + +GET http://moo/ HTTP/1.1 +Host: moo +User-Agent: curl/%VERSION +Accept: */* +Proxy-Connection: Keep-Alive + + + +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/ + + +/********* 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 + +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 ****/ + + +