diff --git a/lib/http2.c b/lib/http2.c index c3157d1ef28d1105e17cb692e004fc28c2adbda1..d324ee8896f08abea07f7616557d1a8b8c54aaca 100644 --- a/lib/http2.c +++ b/lib/http2.c @@ -271,6 +271,15 @@ static CURLcode http2_data_setup(struct Curl_cfilter *cf, return CURLE_OK; } +static void free_push_headers(struct h2_stream_ctx *stream) +{ + size_t i; + for(i = 0; ipush_headers_used; i++) + free(stream->push_headers[i]); + Curl_safefree(stream->push_headers); + stream->push_headers_used = 0; +} + static void http2_data_done(struct Curl_cfilter *cf, struct Curl_easy *data, bool premature) { @@ -872,7 +881,6 @@ static int push_promise(struct Curl_cfilter *cf, struct curl_pushheaders heads; CURLMcode rc; CURLcode result; - size_t i; /* clone the parent */ struct Curl_easy *newhandle = h2_duphandle(cf, data); if(!newhandle) { @@ -917,11 +925,7 @@ static int push_promise(struct Curl_cfilter *cf, Curl_set_in_callback(data, false); /* free the headers again */ - for(i = 0; ipush_headers_used; i++) - free(stream->push_headers[i]); - free(stream->push_headers); - stream->push_headers = NULL; - stream->push_headers_used = 0; + free_push_headers(stream); if(rv) { DEBUGASSERT((rv > CURL_PUSH_OK) && (rv <= CURL_PUSH_ERROROUT)); @@ -1468,14 +1472,14 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame, if(stream->push_headers_alloc > 1000) { /* this is beyond crazy many headers, bail out */ failf(data_s, "Too many PUSH_PROMISE headers"); - Curl_safefree(stream->push_headers); + free_push_headers(stream); return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; } stream->push_headers_alloc *= 2; - headp = Curl_saferealloc(stream->push_headers, - stream->push_headers_alloc * sizeof(char *)); + headp = realloc(stream->push_headers, + stream->push_headers_alloc * sizeof(char *)); if(!headp) { - stream->push_headers = NULL; + free_push_headers(stream); return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; } stream->push_headers = headp; diff --git a/lib/http2.c.rej b/lib/http2.c.rej new file mode 100644 index 0000000000000000000000000000000000000000..b2410cc87f92b07f68cb3c072315b34b68b5a0a3 --- /dev/null +++ b/lib/http2.c.rej @@ -0,0 +1,18 @@ +diff a/lib/http2.c b/lib/http2.c (rejected hunks) +@@ -306,15 +315,7 @@ static void http2_data_done(struct Curl_cfilter *cf, + Curl_bufq_free(&stream->sendbuf); + Curl_h1_req_parse_free(&stream->h1); + Curl_dynhds_free(&stream->resp_trailers); +- if(stream->push_headers) { +- /* if they weren't used and then freed before */ +- for(; stream->push_headers_used > 0; --stream->push_headers_used) { +- free(stream->push_headers[stream->push_headers_used - 1]); +- } +- free(stream->push_headers); +- stream->push_headers = NULL; +- } +- ++ free_push_headers(stream); + free(stream); + H2_STREAM_LCTX(data) = NULL; + } diff --git a/lib/setopt.c b/lib/setopt.c index a5270773f39c80a9b13af28b7e31d61ffb2e4442..3891eb679625278e6333608a77a79ad5062a0b74 100644 --- a/lib/setopt.c +++ b/lib/setopt.c @@ -155,6 +155,12 @@ static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp) static CURLcode protocol2num(const char *str, curl_prot_t *val) { + /* + * We are asked to cherry-pick protocols, so play it safe and disallow all + * protocols to start with, and re-add the wanted ones back in. + */ + *val = 0; + if(!str) return CURLE_BAD_FUNCTION_ARGUMENT; @@ -163,8 +169,6 @@ static CURLcode protocol2num(const char *str, curl_prot_t *val) return CURLE_OK; } - *val = 0; - do { const char *token = str; size_t tlen; @@ -2657,22 +2661,18 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; case CURLOPT_PROTOCOLS_STR: { - curl_prot_t prot; argptr = va_arg(param, char *); - result = protocol2num(argptr, &prot); + result = protocol2num(argptr, &data->set.allowed_protocols); if(result) return result; - data->set.allowed_protocols = prot; break; } case CURLOPT_REDIR_PROTOCOLS_STR: { - curl_prot_t prot; argptr = va_arg(param, char *); - result = protocol2num(argptr, &prot); + result = protocol2num(argptr, &data->set.redir_protocols); if(result) return result; - data->set.redir_protocols = prot; break; } diff --git a/lib/vquic/vquic-tls.c b/lib/vquic/vquic-tls.c index cc7794e405a5f67c2f775024716c227487583100..dbde21f476f1dc52c68b367f89405a30987268ad 100644 --- a/lib/vquic/vquic-tls.c +++ b/lib/vquic/vquic-tls.c @@ -375,6 +375,7 @@ static CURLcode curl_wssl_init_ctx(struct quic_tls_ctx *ctx, char error_buffer[256]; ERR_error_string_n(ERR_get_error(), error_buffer, sizeof(error_buffer)); failf(data, "wolfSSL failed to set ciphers: %s", error_buffer); + result = CURLE_BAD_FUNCTION_ARGUMENT; goto out; } @@ -382,6 +383,7 @@ static CURLcode curl_wssl_init_ctx(struct quic_tls_ctx *ctx, conn_config->curves : (char *)QUIC_GROUPS) != 1) { failf(data, "wolfSSL failed to set curves"); + result = CURLE_BAD_FUNCTION_ARGUMENT; goto out; } @@ -392,6 +394,7 @@ static CURLcode curl_wssl_init_ctx(struct quic_tls_ctx *ctx, wolfSSL_CTX_set_keylog_callback(ctx->ssl_ctx, keylog_callback); #else failf(data, "wolfSSL was built without keylog callback"); + result = CURLE_NOT_BUILT_IN; goto out; #endif } @@ -414,6 +417,7 @@ static CURLcode curl_wssl_init_ctx(struct quic_tls_ctx *ctx, " CAfile: %s CApath: %s", ssl_cafile ? ssl_cafile : "none", ssl_capath ? ssl_capath : "none"); + result = CURLE_SSL_CACERT; goto out; } infof(data, " CAfile: %s", ssl_cafile ? ssl_cafile : "none"); diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c index 7d70de53bd24f2c2ebcbc0112f8421cdfb8cbf99..8e98b7d3a29b5d177f211d7c32fbc87175ee18ab 100644 --- a/lib/vtls/mbedtls.c +++ b/lib/vtls/mbedtls.c @@ -654,14 +654,13 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) &backend->clicert, &backend->pk); } - if(connssl->peer.sni) { - if(mbedtls_ssl_set_hostname(&backend->ssl, connssl->peer.sni)) { - /* mbedtls_ssl_set_hostname() sets the name to use in CN/SAN checks and - the name to set in the SNI extension. So even if curl connects to a - host specified as an IP address, this function must be used. */ - failf(data, "Failed to set SNI"); - return CURLE_SSL_CONNECT_ERROR; - } + if(mbedtls_ssl_set_hostname(&backend->ssl, connssl->peer.sni? + connssl->peer.sni : connssl->peer.hostname)) { + /* mbedtls_ssl_set_hostname() sets the name to use in CN/SAN checks and + the name to set in the SNI extension. So even if curl connects to a + host specified as an IP address, this function must be used. */ + failf(data, "Failed to set SNI"); + return CURLE_SSL_CONNECT_ERROR; } #ifdef HAS_ALPN diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc index c3d496f6468bb8a25d25c3c191aa94fdfed5717a..f6892464ed164403fe6b8db0df6e2c462a610e5d 100644 --- a/tests/data/Makefile.inc +++ b/tests/data/Makefile.inc @@ -186,7 +186,7 @@ test1439 test1440 test1441 test1442 test1443 test1444 test1445 test1446 \ 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 test1475 test1476 test1477 test1478 \ +test1471 test1472 test1473 test1474 test1475 test1476 test1477 test1478 \ \ test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \ test1508 test1509 test1510 test1511 test1512 test1513 test1514 test1515 \ diff --git a/tests/data/test1474 b/tests/data/test1474 new file mode 100644 index 0000000000000000000000000000000000000000..c66fa2810483f24d4799c4e7d6cb0651b3c5b42f --- /dev/null +++ b/tests/data/test1474 @@ -0,0 +1,42 @@ + + + +HTTP +HTTP GET +--proto + + + +# +# Server-side + + + + + +# +# Client-side + + +none + + +http + + +--proto -all disables all protocols + + +--proto -all http://%HOSTIP:%NOLISTENPORT/%TESTNUMBER + + + +# +# Verify data after the test has been "shot" + +# 1 - Protocol "http" disabled + +1 + + +