From c3d52cd6ff9e3f607da071777f0dccc9f540bbca Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Apr 13 2022 13:43:18 +0000 Subject: import rh-dotnet31-curl-7.61.1-22.el7_9 --- diff --git a/SOURCES/0017-curl-7.64.0-CVE-2019-5436.patch b/SOURCES/0017-curl-7.64.0-CVE-2019-5436.patch new file mode 100644 index 0000000..8b0e453 --- /dev/null +++ b/SOURCES/0017-curl-7.64.0-CVE-2019-5436.patch @@ -0,0 +1,31 @@ +From 55a27027d5f024a0ecc2c23c81ed99de6192c9f3 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Fri, 3 May 2019 22:20:37 +0200 +Subject: [PATCH] tftp: use the current blksize for recvfrom() + +bug: https://curl.haxx.se/docs/CVE-2019-5436.html +Reported-by: l00p3r on hackerone +CVE-2019-5436 + +Upstream-commit: 2576003415625d7b5f0e390902f8097830b82275 +Signed-off-by: Kamil Dudka +--- + lib/tftp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/tftp.c b/lib/tftp.c +index 269b3cd..4f2a131 100644 +--- a/lib/tftp.c ++++ b/lib/tftp.c +@@ -1005,7 +1005,7 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done) + state->sockfd = state->conn->sock[FIRSTSOCKET]; + state->state = TFTP_STATE_START; + state->error = TFTP_ERR_NONE; +- state->blksize = TFTP_BLKSIZE_DEFAULT; ++ state->blksize = blksize; + state->requested_blksize = blksize; + + ((struct sockaddr *)&state->local_addr)->sa_family = +-- +2.20.1 + diff --git a/SOURCES/0018-curl-7.65.3-CVE-2019-5482.patch b/SOURCES/0018-curl-7.65.3-CVE-2019-5482.patch new file mode 100644 index 0000000..f3785ec --- /dev/null +++ b/SOURCES/0018-curl-7.65.3-CVE-2019-5482.patch @@ -0,0 +1,158 @@ +From 63f9837b4ccf600da79314e8667f91bda69988fc Mon Sep 17 00:00:00 2001 +From: Thomas Vegas <> +Date: Sat, 31 Aug 2019 16:59:56 +0200 +Subject: [PATCH 1/2] tftp: return error when packet is too small for options + +Upstream-commit: 82f3ba3806a34fe94dcf9e5c9b88deda6679ca1b +Signed-off-by: Kamil Dudka +--- + lib/tftp.c | 53 +++++++++++++++++++++++++++++++++-------------------- + 1 file changed, 33 insertions(+), 20 deletions(-) + +diff --git a/lib/tftp.c b/lib/tftp.c +index 289cda2..4532170 100644 +--- a/lib/tftp.c ++++ b/lib/tftp.c +@@ -404,13 +404,14 @@ static CURLcode tftp_parse_option_ack(tftp_state_data_t *state, + return CURLE_OK; + } + +-static size_t tftp_option_add(tftp_state_data_t *state, size_t csize, +- char *buf, const char *option) ++static CURLcode tftp_option_add(tftp_state_data_t *state, size_t *csize, ++ char *buf, const char *option) + { +- if(( strlen(option) + csize + 1) > (size_t)state->blksize) +- return 0; ++ if(( strlen(option) + *csize + 1) > (size_t)state->blksize) ++ return CURLE_TFTP_ILLEGAL; + strcpy(buf, option); +- return strlen(option) + 1; ++ *csize += strlen(option) + 1; ++ return CURLE_OK; + } + + static CURLcode tftp_connect_for_tx(tftp_state_data_t *state, +@@ -511,26 +512,38 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event) + else + strcpy(buf, "0"); /* the destination is large enough */ + +- sbytes += tftp_option_add(state, sbytes, +- (char *)state->spacket.data + sbytes, +- TFTP_OPTION_TSIZE); +- sbytes += tftp_option_add(state, sbytes, +- (char *)state->spacket.data + sbytes, buf); ++ result = tftp_option_add(state, &sbytes, ++ (char *)state->spacket.data + sbytes, ++ TFTP_OPTION_TSIZE); ++ if(result == CURLE_OK) ++ result = tftp_option_add(state, &sbytes, ++ (char *)state->spacket.data + sbytes, buf); ++ + /* add blksize option */ + snprintf(buf, sizeof(buf), "%d", state->requested_blksize); +- sbytes += tftp_option_add(state, sbytes, +- (char *)state->spacket.data + sbytes, +- TFTP_OPTION_BLKSIZE); +- sbytes += tftp_option_add(state, sbytes, +- (char *)state->spacket.data + sbytes, buf); ++ if(result == CURLE_OK) ++ result = tftp_option_add(state, &sbytes, ++ (char *)state->spacket.data + sbytes, ++ TFTP_OPTION_BLKSIZE); ++ if(result == CURLE_OK) ++ result = tftp_option_add(state, &sbytes, ++ (char *)state->spacket.data + sbytes, buf); + + /* add timeout option */ + snprintf(buf, sizeof(buf), "%d", state->retry_time); +- sbytes += tftp_option_add(state, sbytes, +- (char *)state->spacket.data + sbytes, +- TFTP_OPTION_INTERVAL); +- sbytes += tftp_option_add(state, sbytes, +- (char *)state->spacket.data + sbytes, buf); ++ if(result == CURLE_OK) ++ result = tftp_option_add(state, &sbytes, ++ (char *)state->spacket.data + sbytes, ++ TFTP_OPTION_INTERVAL); ++ if(result == CURLE_OK) ++ result = tftp_option_add(state, &sbytes, ++ (char *)state->spacket.data + sbytes, buf); ++ ++ if(result != CURLE_OK) { ++ failf(data, "TFTP buffer too small for options"); ++ free(filename); ++ return CURLE_TFTP_ILLEGAL; ++ } + } + + /* the typecase for the 3rd argument is mostly for systems that do +-- +2.20.1 + + +From b6b12a4cfe00c4850a1d6cee4cf267f00dee5987 Mon Sep 17 00:00:00 2001 +From: Thomas Vegas <> +Date: Sat, 31 Aug 2019 17:30:51 +0200 +Subject: [PATCH 2/2] tftp: Alloc maximum blksize, and use default unless OACK + is received + +Fixes potential buffer overflow from 'recvfrom()', should the server +return an OACK without blksize. + +Bug: https://curl.haxx.se/docs/CVE-2019-5482.html +CVE-2019-5482 + +Upstream-commit: facb0e4662415b5f28163e853dc6742ac5fafb3d +Signed-off-by: Kamil Dudka +--- + lib/tftp.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/lib/tftp.c b/lib/tftp.c +index 4532170..5651b62 100644 +--- a/lib/tftp.c ++++ b/lib/tftp.c +@@ -982,6 +982,7 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done) + { + tftp_state_data_t *state; + int blksize; ++ int need_blksize; + + blksize = TFTP_BLKSIZE_DEFAULT; + +@@ -996,15 +997,20 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done) + return CURLE_TFTP_ILLEGAL; + } + ++ need_blksize = blksize; ++ /* default size is the fallback when no OACK is received */ ++ if(need_blksize < TFTP_BLKSIZE_DEFAULT) ++ need_blksize = TFTP_BLKSIZE_DEFAULT; ++ + if(!state->rpacket.data) { +- state->rpacket.data = calloc(1, blksize + 2 + 2); ++ state->rpacket.data = calloc(1, need_blksize + 2 + 2); + + if(!state->rpacket.data) + return CURLE_OUT_OF_MEMORY; + } + + if(!state->spacket.data) { +- state->spacket.data = calloc(1, blksize + 2 + 2); ++ state->spacket.data = calloc(1, need_blksize + 2 + 2); + + if(!state->spacket.data) + return CURLE_OUT_OF_MEMORY; +@@ -1018,7 +1024,7 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done) + state->sockfd = state->conn->sock[FIRSTSOCKET]; + state->state = TFTP_STATE_START; + state->error = TFTP_ERR_NONE; +- state->blksize = blksize; ++ state->blksize = TFTP_BLKSIZE_DEFAULT; /* Unless updated by OACK response */ + state->requested_blksize = blksize; + + ((struct sockaddr *)&state->local_addr)->sa_family = +-- +2.20.1 + diff --git a/SOURCES/0019-curl-7.65.3-CVE-2019-5481.patch b/SOURCES/0019-curl-7.65.3-CVE-2019-5481.patch new file mode 100644 index 0000000..2cd79df --- /dev/null +++ b/SOURCES/0019-curl-7.65.3-CVE-2019-5481.patch @@ -0,0 +1,46 @@ +From 13de299b112a59c373b330f0539166ecc9a7627b Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 3 Sep 2019 22:59:32 +0200 +Subject: [PATCH] security:read_data fix bad realloc() + +... that could end up a double-free + +CVE-2019-5481 +Bug: https://curl.haxx.se/docs/CVE-2019-5481.html + +Upstream-commit: 9069838b30fb3b48af0123e39f664cea683254a5 +Signed-off-by: Kamil Dudka +--- + lib/security.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/lib/security.c b/lib/security.c +index 550ea2d..c5e4e13 100644 +--- a/lib/security.c ++++ b/lib/security.c +@@ -191,7 +191,6 @@ static CURLcode read_data(struct connectdata *conn, + struct krb5buffer *buf) + { + int len; +- void *tmp = NULL; + CURLcode result; + + result = socket_read(fd, &len, sizeof(len)); +@@ -201,12 +200,11 @@ static CURLcode read_data(struct connectdata *conn, + if(len) { + /* only realloc if there was a length */ + len = ntohl(len); +- tmp = Curl_saferealloc(buf->data, len); ++ buf->data = Curl_saferealloc(buf->data, len); + } +- if(tmp == NULL) ++ if(!len || !buf->data) + return CURLE_OUT_OF_MEMORY; + +- buf->data = tmp; + result = socket_read(fd, buf->data, len); + if(result) + return result; +-- +2.20.1 + diff --git a/SOURCES/0020-curl-7.61.1-openssl-engines.patch b/SOURCES/0020-curl-7.61.1-openssl-engines.patch new file mode 100644 index 0000000..d8c5579 --- /dev/null +++ b/SOURCES/0020-curl-7.61.1-openssl-engines.patch @@ -0,0 +1,33 @@ +From 032843be4cefcb163d15573d15a228680e771106 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 24 Sep 2018 08:26:58 +0200 +Subject: [PATCH] openssl: load built-in engines too + +Regression since 38203f1 + +Reported-by: Jean Fabrice +Fixes #3023 +Closes #3040 + +Upstream-commit: e2dd435d473cdc97785df95d032276fafb4b7746 +Signed-off-by: Kamil Dudka +--- + lib/vtls/openssl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c +index 78970d1..d8bcc4f 100644 +--- a/lib/vtls/openssl.c ++++ b/lib/vtls/openssl.c +@@ -979,7 +979,7 @@ static int Curl_ossl_init(void) + + OPENSSL_load_builtin_modules(); + +-#ifdef HAVE_ENGINE_LOAD_BUILTIN_ENGINES ++#ifdef USE_OPENSSL_ENGINE + ENGINE_load_builtin_engines(); + #endif + +-- +2.25.4 + diff --git a/SOURCES/0021-curl-7.61.1-CVE-2020-8177.patch b/SOURCES/0021-curl-7.61.1-CVE-2020-8177.patch new file mode 100644 index 0000000..388e0c4 --- /dev/null +++ b/SOURCES/0021-curl-7.61.1-CVE-2020-8177.patch @@ -0,0 +1,59 @@ +From a6fcd8a32f3b1c5d80e524f8b2c1de32e6ecdb2b Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sun, 31 May 2020 23:09:59 +0200 +Subject: [PATCH] tool_getparam: -i is not OK if -J is used + +Reported-by: sn on hackerone +Bug: https://curl.haxx.se/docs/CVE-2020-8177.html + +Upstream-commit: 8236aba58542c5f89f1d41ca09d84579efb05e22 +Signed-off-by: Kamil Dudka +--- + src/tool_cb_hdr.c | 13 ++++--------- + src/tool_getparam.c | 5 +++++ + 2 files changed, 9 insertions(+), 9 deletions(-) + +diff --git a/src/tool_cb_hdr.c b/src/tool_cb_hdr.c +index 3b10238..b80707f 100644 +--- a/src/tool_cb_hdr.c ++++ b/src/tool_cb_hdr.c +@@ -132,16 +132,11 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) + filename = parse_filename(p, len); + if(filename) { + if(outs->stream) { +- /* already opened and possibly written to */ +- if(outs->fopened) +- fclose(outs->stream); +- outs->stream = NULL; +- +- /* rename the initial file name to the new file name */ +- rename(outs->filename, filename); +- if(outs->alloc_filename) +- free(outs->filename); ++ /* indication of problem, get out! */ ++ free(filename); ++ return failure; + } ++ + outs->is_cd_filename = TRUE; + outs->s_isreg = TRUE; + outs->fopened = FALSE; +diff --git a/src/tool_getparam.c b/src/tool_getparam.c +index 764caa2..c5c7429 100644 +--- a/src/tool_getparam.c ++++ b/src/tool_getparam.c +@@ -1745,6 +1745,11 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ + } + break; + case 'i': ++ if(config->content_disposition) { ++ warnf(global, ++ "--include and --remote-header-name cannot be combined.\n"); ++ return PARAM_BAD_USE; ++ } + config->show_headers = toggle; /* show the headers as well in the + general output stream */ + break; +-- +2.21.3 + diff --git a/SOURCES/0022-curl-7.61.1-CVE-2020-8231.patch b/SOURCES/0022-curl-7.61.1-CVE-2020-8231.patch new file mode 100644 index 0000000..6d0c10c --- /dev/null +++ b/SOURCES/0022-curl-7.61.1-CVE-2020-8231.patch @@ -0,0 +1,143 @@ +From 7a26092a9e21f1e0dc3cad69a580a7e2c7822ad0 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sun, 16 Aug 2020 11:34:35 +0200 +Subject: [PATCH] Curl_easy: remember last connection by id, not by pointer + +CVE-2020-8231 + +Bug: https://curl.haxx.se/docs/CVE-2020-8231.html + +Reported-by: Marc Aldorasi +Closes #5824 + +Upstream-commit: 3c9e021f86872baae412a427e807fbfa2f3e8a22 +Signed-off-by: Kamil Dudka +--- + lib/connect.c | 19 ++++++++++--------- + lib/easy.c | 3 +-- + lib/multi.c | 5 +++-- + lib/url.c | 2 +- + lib/urldata.h | 2 +- + 5 files changed, 16 insertions(+), 15 deletions(-) + +diff --git a/lib/connect.c b/lib/connect.c +index 41f2202..f724646 100644 +--- a/lib/connect.c ++++ b/lib/connect.c +@@ -1214,15 +1214,15 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */ + } + + struct connfind { +- struct connectdata *tofind; +- bool found; ++ long id_tofind; ++ struct connectdata *found; + }; + + static int conn_is_conn(struct connectdata *conn, void *param) + { + struct connfind *f = (struct connfind *)param; +- if(conn == f->tofind) { +- f->found = TRUE; ++ if(conn->connection_id == f->id_tofind) { ++ f->found = conn; + return 1; + } + return 0; +@@ -1244,21 +1244,22 @@ curl_socket_t Curl_getconnectinfo(struct Curl_easy *data, + * - that is associated with a multi handle, and whose connection + * was detached with CURLOPT_CONNECT_ONLY + */ +- if(data->state.lastconnect && (data->multi_easy || data->multi)) { +- struct connectdata *c = data->state.lastconnect; ++ if((data->state.lastconnect_id != -1) && (data->multi_easy || data->multi)) { ++ struct connectdata *c; + struct connfind find; +- find.tofind = data->state.lastconnect; +- find.found = FALSE; ++ find.id_tofind = data->state.lastconnect_id; ++ find.found = NULL; + + Curl_conncache_foreach(data, data->multi_easy? + &data->multi_easy->conn_cache: + &data->multi->conn_cache, &find, conn_is_conn); + + if(!find.found) { +- data->state.lastconnect = NULL; ++ data->state.lastconnect_id = -1; + return CURL_SOCKET_BAD; + } + ++ c = find.found; + if(connp) { + /* only store this if the caller cares for it */ + *connp = c; +diff --git a/lib/easy.c b/lib/easy.c +index 027d0be..fe61cdd 100644 +--- a/lib/easy.c ++++ b/lib/easy.c +@@ -919,8 +919,7 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data) + + /* the connection cache is setup on demand */ + outcurl->state.conn_cache = NULL; +- +- outcurl->state.lastconnect = NULL; ++ outcurl->state.lastconnect_id = -1; + + outcurl->progress.flags = data->progress.flags; + outcurl->progress.callback = data->progress.callback; +diff --git a/lib/multi.c b/lib/multi.c +index 0caf943..0f57fd5 100644 +--- a/lib/multi.c ++++ b/lib/multi.c +@@ -427,6 +427,7 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi, + data->state.conn_cache = &data->share->conn_cache; + else + data->state.conn_cache = &multi->conn_cache; ++ data->state.lastconnect_id = -1; + + #ifdef USE_LIBPSL + /* Do the same for PSL. */ +@@ -644,11 +645,11 @@ static CURLcode multi_done(struct connectdata **connp, + /* the connection is no longer in use by this transfer */ + if(Curl_conncache_return_conn(conn)) { + /* remember the most recently used connection */ +- data->state.lastconnect = conn; ++ data->state.lastconnect_id = conn->connection_id; + infof(data, "%s\n", buffer); + } + else +- data->state.lastconnect = NULL; ++ data->state.lastconnect_id = -1; + } + + *connp = NULL; /* to make the caller of this function better detect that +diff --git a/lib/url.c b/lib/url.c +index dcc6cc8..d65d17d 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -592,7 +592,7 @@ CURLcode Curl_open(struct Curl_easy **curl) + Curl_initinfo(data); + + /* most recent connection is not yet defined */ +- data->state.lastconnect = NULL; ++ data->state.lastconnect_id = -1; + + data->progress.flags |= PGRS_HIDE; + data->state.current_speed = -1; /* init to negative == impossible */ +diff --git a/lib/urldata.h b/lib/urldata.h +index 67db3b2..4b70cc5 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -1219,7 +1219,7 @@ struct UrlState { + /* buffers to store authentication data in, as parsed from input options */ + struct curltime keeps_speed; /* for the progress meter really */ + +- struct connectdata *lastconnect; /* The last connection, NULL if undefined */ ++ long lastconnect_id; /* The last connection, -1 if undefined */ + + char *headerbuff; /* allocated buffer to store headers in */ + size_t headersize; /* size of the allocation */ +-- +2.25.4 + diff --git a/SOURCES/0023-curl-7.61.1-no-https-proxy-crash.patch b/SOURCES/0023-curl-7.61.1-no-https-proxy-crash.patch new file mode 100644 index 0000000..f6bcb01 --- /dev/null +++ b/SOURCES/0023-curl-7.61.1-no-https-proxy-crash.patch @@ -0,0 +1,60 @@ +From 9d5903ebcbcbcc4f3a997ec7d5552721c5383b9f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Martin=20Ba=C5=A1ti?= +Date: Thu, 27 Aug 2020 23:09:56 +0200 +Subject: [PATCH] http_proxy: do not crash with HTTPS_PROXY and NO_PROXY set + +... in case NO_PROXY takes an effect + +Without this patch, the following command crashes: + + $ GIT_CURL_VERBOSE=1 NO_PROXY=github.com HTTPS_PROXY=https://example.com \ + git clone https://github.com/curl/curl.git + +Minimal libcurl-based reproducer: + + #include + + int main() { + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_URL, "https://github.com/"); + curl_easy_setopt(curl, CURLOPT_PROXY, "example.com"); + /* set the proxy type */ + curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTPS); + curl_easy_setopt(curl, CURLOPT_NOPROXY, "github.com"); + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + ret = curl_easy_perform(curl); + curl_easy_cleanup(curl); + return ret; + } + return -1; + } + +Assisted-by: Kamil Dudka +Bug: https://bugzilla.redhat.com/1873327 +Closes #5902 + +Upstream-commit: 3eff1c5092e542819ac7e6454a70c94b36ab2a40 +Signed-off-by: Kamil Dudka +--- + lib/url.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/lib/url.c b/lib/url.c +index d65d17d..e77f391 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -3074,6 +3074,9 @@ static CURLcode create_conn_helper_init_proxy(struct connectdata *conn) + conn->bits.socksproxy = FALSE; + conn->bits.proxy_user_passwd = FALSE; + conn->bits.tunnel_proxy = FALSE; ++ /* CURLPROXY_HTTPS does not have its own flag in conn->bits, yet we need ++ to signal that CURLPROXY_HTTPS is not used for this connection */ ++ conn->http_proxy.proxytype = CURLPROXY_HTTP; + } + + out: +-- +2.25.4 + diff --git a/SOURCES/0024-curl-7.61.1-openssl-partial-chain.patch b/SOURCES/0024-curl-7.61.1-openssl-partial-chain.patch new file mode 100644 index 0000000..5b7044c --- /dev/null +++ b/SOURCES/0024-curl-7.61.1-openssl-partial-chain.patch @@ -0,0 +1,291 @@ +From 673adb0a7a21ca3a877ee03dc9e197d5be15a9d3 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 2 Dec 2019 10:45:55 +0100 +Subject: [PATCH 1/3] openssl: set X509_V_FLAG_PARTIAL_CHAIN + +Have intermediate certificates in the trust store be treated as +trust-anchors, in the same way as self-signed root CA certificates +are. This allows users to verify servers using the intermediate cert +only, instead of needing the whole chain. + +Other TLS backends already accept partial chains. + +Reported-by: Jeffrey Walton +Bug: https://curl.haxx.se/mail/lib-2019-11/0094.html + +Upstream-commit: 94f1f771586913addf5c68f9219e176036c50115 +Signed-off-by: Kamil Dudka +--- + lib/vtls/openssl.c | 26 +++++++++++++++++--------- + 1 file changed, 17 insertions(+), 9 deletions(-) + +diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c +index d8bcc4f..8e791b9 100644 +--- a/lib/vtls/openssl.c ++++ b/lib/vtls/openssl.c +@@ -2551,19 +2551,27 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) + infof(data, " CRLfile: %s\n", ssl_crlfile); + } + +- /* Try building a chain using issuers in the trusted store first to avoid +- problems with server-sent legacy intermediates. +- Newer versions of OpenSSL do alternate chain checking by default which +- gives us the same fix without as much of a performance hit (slight), so we +- prefer that if available. +- https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest +- */ +-#if defined(X509_V_FLAG_TRUSTED_FIRST) && !defined(X509_V_FLAG_NO_ALT_CHAINS) + if(verifypeer) { ++ /* Try building a chain using issuers in the trusted store first to avoid ++ problems with server-sent legacy intermediates. Newer versions of ++ OpenSSL do alternate chain checking by default which gives us the same ++ fix without as much of a performance hit (slight), so we prefer that if ++ available. ++ https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest ++ */ ++#if defined(X509_V_FLAG_TRUSTED_FIRST) && !defined(X509_V_FLAG_NO_ALT_CHAINS) + X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx), + X509_V_FLAG_TRUSTED_FIRST); +- } + #endif ++#ifdef X509_V_FLAG_PARTIAL_CHAIN ++ /* Have intermediate certificates in the trust store be treated as ++ trust-anchors, in the same way as self-signed root CA certificates ++ are. This allows users to verify servers using the intermediate cert ++ only, instead of needing the whole chain. */ ++ X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx), ++ X509_V_FLAG_PARTIAL_CHAIN); ++#endif ++ } + + /* SSL always tries to verify the peer, this only says whether it should + * fail to connect if the verification fails, or if it should continue +-- +2.26.2 + + +From b2e6e39b60e1722aecf250ff79a69867df5d3aa8 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 2 Dec 2019 10:55:33 +0100 +Subject: [PATCH 2/3] openssl: CURLSSLOPT_NO_PARTIALCHAIN can disable partial + cert chains + +Closes #4655 + +Upstream-commit: 564d88a8bd190a21b362d6da535fccf74d33394d +Signed-off-by: Kamil Dudka +--- + docs/libcurl/opts/CURLOPT_SSL_OPTIONS.3 | 40 +++++++++++++------------ + docs/libcurl/symbols-in-versions | 1 + + include/curl/curl.h | 4 +++ + lib/setopt.c | 1 + + lib/urldata.h | 1 + + lib/vtls/openssl.c | 14 +++++---- + 6 files changed, 36 insertions(+), 25 deletions(-) + +diff --git a/docs/libcurl/opts/CURLOPT_SSL_OPTIONS.3 b/docs/libcurl/opts/CURLOPT_SSL_OPTIONS.3 +index d781434..6286a64 100644 +--- a/docs/libcurl/opts/CURLOPT_SSL_OPTIONS.3 ++++ b/docs/libcurl/opts/CURLOPT_SSL_OPTIONS.3 +@@ -29,25 +29,27 @@ CURLOPT_SSL_OPTIONS \- set SSL behavior options + + CURLcode curl_easy_setopt(CURL *handle, CURLOPT_SSL_OPTIONS, long bitmask); + .SH DESCRIPTION +-Pass a long with a bitmask to tell libcurl about specific SSL behaviors. +- +-\fICURLSSLOPT_ALLOW_BEAST\fP tells libcurl to not attempt to use any +-workarounds for a security flaw in the SSL3 and TLS1.0 protocols. If this +-option isn't used or this bit is set to 0, the SSL layer libcurl uses may use a +-work-around for this flaw although it might cause interoperability problems +-with some (older) SSL implementations. WARNING: avoiding this work-around +-lessens the security, and by setting this option to 1 you ask for exactly that. +-This option is only supported for DarwinSSL, NSS and OpenSSL. +- +-Added in 7.44.0: +- +-\fICURLSSLOPT_NO_REVOKE\fP tells libcurl to disable certificate revocation +-checks for those SSL backends where such behavior is present. \fBCurrently this +-option is only supported for WinSSL (the native Windows SSL library), with an +-exception in the case of Windows' Untrusted Publishers blacklist which it seems +-can't be bypassed.\fP This option may have broader support to accommodate other +-SSL backends in the future. +-https://curl.haxx.se/docs/ssl-compared.html ++Pass a long with a bitmask to tell libcurl about specific SSL ++behaviors. Available bits: ++.IP CURLSSLOPT_ALLOW_BEAST ++Tells libcurl to not attempt to use any workarounds for a security flaw in the ++SSL3 and TLS1.0 protocols. If this option isn't used or this bit is set to 0, ++the SSL layer libcurl uses may use a work-around for this flaw although it ++might cause interoperability problems with some (older) SSL ++implementations. WARNING: avoiding this work-around lessens the security, and ++by setting this option to 1 you ask for exactly that. This option is only ++supported for DarwinSSL, NSS and OpenSSL. ++.IP CURLSSLOPT_NO_REVOKE ++Tells libcurl to disable certificate revocation checks for those SSL backends ++where such behavior is present. This option is only supported for Schannel ++(the native Windows SSL library), with an exception in the case of Windows' ++Untrusted Publishers blacklist which it seems can't be bypassed. (Added in ++7.44.0) ++.IP CURLSSLOPT_NO_PARTIALCHAIN ++Tells libcurl to not accept "partial" certificate chains, which it otherwise ++does by default. This option is only supported for OpenSSL and will fail the ++certificate verification if the chain ends with an intermediate certificate ++and not with a root cert. (Added in 7.68.0) + .SH DEFAULT + 0 + .SH PROTOCOLS +diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions +index 3b3861f..54923d0 100644 +--- a/docs/libcurl/symbols-in-versions ++++ b/docs/libcurl/symbols-in-versions +@@ -713,6 +713,7 @@ CURLSSLBACKEND_QSOSSL 7.34.0 - 7.38.1 + CURLSSLBACKEND_SCHANNEL 7.34.0 + CURLSSLBACKEND_WOLFSSL 7.49.0 + CURLSSLOPT_ALLOW_BEAST 7.25.0 ++CURLSSLOPT_NO_PARTIALCHAIN 7.68.0 + CURLSSLOPT_NO_REVOKE 7.44.0 + CURLSSLSET_NO_BACKENDS 7.56.0 + CURLSSLSET_OK 7.56.0 +diff --git a/include/curl/curl.h b/include/curl/curl.h +index 8f473e2..75f9384 100644 +--- a/include/curl/curl.h ++++ b/include/curl/curl.h +@@ -795,6 +795,10 @@ typedef enum { + SSL backends where such behavior is present. */ + #define CURLSSLOPT_NO_REVOKE (1<<1) + ++/* - NO_PARTIALCHAIN tells libcurl to *NOT* accept a partial certificate chain ++ if possible. The OpenSSL backend has this ability. */ ++#define CURLSSLOPT_NO_PARTIALCHAIN (1<<2) ++ + /* The default connection attempt delay in milliseconds for happy eyeballs. + CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 and happy-eyeballs-timeout-ms.d document + this value, keep them in sync. */ +diff --git a/lib/setopt.c b/lib/setopt.c +index 5c5f4b3..4f04962 100644 +--- a/lib/setopt.c ++++ b/lib/setopt.c +@@ -2046,6 +2046,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + arg = va_arg(param, long); + data->set.ssl.enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE; + data->set.ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE); ++ data->set.ssl.no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN); + break; + + case CURLOPT_PROXY_SSL_OPTIONS: +diff --git a/lib/urldata.h b/lib/urldata.h +index 4b70cc5..c70290a 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -235,6 +235,7 @@ struct ssl_config_data { + bool enable_beast; /* especially allow this flaw for interoperability's + sake*/ + bool no_revoke; /* disable SSL certificate revocation checks */ ++ bool no_partialchain; /* don't accept partial certificate chains */ + long certverifyresult; /* result from the certificate verification */ + char *CRLfile; /* CRL to check certificate revocation */ + char *issuercert;/* optional issuer certificate filename */ +diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c +index 8e791b9..87f6c4c 100644 +--- a/lib/vtls/openssl.c ++++ b/lib/vtls/openssl.c +@@ -2564,12 +2564,14 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) + X509_V_FLAG_TRUSTED_FIRST); + #endif + #ifdef X509_V_FLAG_PARTIAL_CHAIN +- /* Have intermediate certificates in the trust store be treated as +- trust-anchors, in the same way as self-signed root CA certificates +- are. This allows users to verify servers using the intermediate cert +- only, instead of needing the whole chain. */ +- X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx), +- X509_V_FLAG_PARTIAL_CHAIN); ++ if(!SSL_SET_OPTION(no_partialchain)) { ++ /* Have intermediate certificates in the trust store be treated as ++ trust-anchors, in the same way as self-signed root CA certificates ++ are. This allows users to verify servers using the intermediate cert ++ only, instead of needing the whole chain. */ ++ X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx), ++ X509_V_FLAG_PARTIAL_CHAIN); ++ } + #endif + } + +-- +2.26.2 + + +From d149ba12f302e5275b408d82ffb349eac16b9226 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 11 May 2020 23:00:31 +0200 +Subject: [PATCH 3/3] OpenSSL: have CURLOPT_CRLFILE imply + CURLSSLOPT_NO_PARTIALCHAIN + +... to avoid an OpenSSL bug that otherwise makes the CRL check to fail. + +Reported-by: Michael Kaufmann +Fixes #5374 +Closes #5376 + +Upstream-commit: 81a54b12c631e8126e3eb484c74040b991e78f0c +Signed-off-by: Kamil Dudka +--- + docs/libcurl/opts/CURLOPT_CRLFILE.3 | 13 ++++++++----- + lib/vtls/openssl.c | 8 ++++++-- + 2 files changed, 14 insertions(+), 7 deletions(-) + +diff --git a/docs/libcurl/opts/CURLOPT_CRLFILE.3 b/docs/libcurl/opts/CURLOPT_CRLFILE.3 +index 080caa7..f111585 100644 +--- a/docs/libcurl/opts/CURLOPT_CRLFILE.3 ++++ b/docs/libcurl/opts/CURLOPT_CRLFILE.3 +@@ -5,7 +5,7 @@ + .\" * | (__| |_| | _ <| |___ + .\" * \___|\___/|_| \_\_____| + .\" * +-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. ++.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. + .\" * + .\" * This software is licensed as described in the file COPYING, which + .\" * you should have received as part of this distribution. The terms +@@ -34,10 +34,13 @@ concatenation of CRL (in PEM format) to use in the certificate validation that + occurs during the SSL exchange. + + When curl is built to use NSS or GnuTLS, there is no way to influence the use +-of CRL passed to help in the verification process. When libcurl is built with +-OpenSSL support, X509_V_FLAG_CRL_CHECK and X509_V_FLAG_CRL_CHECK_ALL are both +-set, requiring CRL check against all the elements of the certificate chain if +-a CRL file is passed. ++of CRL passed to help in the verification process. ++ ++When libcurl is built with OpenSSL support, X509_V_FLAG_CRL_CHECK and ++X509_V_FLAG_CRL_CHECK_ALL are both set, requiring CRL check against all the ++elements of the certificate chain if a CRL file is passed. Also note that ++\fICURLOPT_CRLFILE(3)\fP will imply \fBCURLSSLOPT_NO_PARTIALCHAIN\fP (see ++\fICURLOPT_SSL_OPTIONS(3)\fP) since curl 7.71.0 due to an OpenSSL bug. + + This option makes sense only when used in combination with the + \fICURLOPT_SSL_VERIFYPEER(3)\fP option. +diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c +index 87f6c4c..9476773 100644 +--- a/lib/vtls/openssl.c ++++ b/lib/vtls/openssl.c +@@ -2564,11 +2564,15 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) + X509_V_FLAG_TRUSTED_FIRST); + #endif + #ifdef X509_V_FLAG_PARTIAL_CHAIN +- if(!SSL_SET_OPTION(no_partialchain)) { ++ if(!SSL_SET_OPTION(no_partialchain) && !ssl_crlfile) { + /* Have intermediate certificates in the trust store be treated as + trust-anchors, in the same way as self-signed root CA certificates + are. This allows users to verify servers using the intermediate cert +- only, instead of needing the whole chain. */ ++ only, instead of needing the whole chain. ++ ++ Due to OpenSSL bug https://github.com/openssl/openssl/issues/5081 we ++ cannot do partial chains with CRL check. ++ */ + X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx), + X509_V_FLAG_PARTIAL_CHAIN); + } +-- +2.26.2 + diff --git a/SOURCES/0025-curl-7.61.1-CVE-2020-8284.patch b/SOURCES/0025-curl-7.61.1-CVE-2020-8284.patch new file mode 100644 index 0000000..674753e --- /dev/null +++ b/SOURCES/0025-curl-7.61.1-CVE-2020-8284.patch @@ -0,0 +1,208 @@ +From 2629f42d4cfdd04df0544007b03161e3d5d52d54 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 24 Nov 2020 14:56:57 +0100 +Subject: [PATCH] ftp: CURLOPT_FTP_SKIP_PASV_IP by default + +The command line tool also independently sets --ftp-skip-pasv-ip by +default. + +Ten test cases updated to adapt the modified --libcurl output. + +Bug: https://curl.se/docs/CVE-2020-8284.html +CVE-2020-8284 + +Reported-by: Varnavas Papaioannou + +Upstream-commit: ec9cc725d598ac77de7b6df8afeec292b3c8ad46 +Signed-off-by: Kamil Dudka +--- + docs/cmdline-opts/ftp-skip-pasv-ip.d | 2 ++ + docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.3 | 8 +++++--- + lib/url.c | 1 + + src/tool_cfgable.c | 1 + + tests/data/test1400 | 1 + + tests/data/test1401 | 1 + + tests/data/test1402 | 1 + + tests/data/test1403 | 1 + + tests/data/test1404 | 1 + + tests/data/test1405 | 1 + + tests/data/test1406 | 1 + + tests/data/test1407 | 1 + + tests/data/test1420 | 1 + + 13 files changed, 18 insertions(+), 3 deletions(-) + +diff --git a/docs/cmdline-opts/ftp-skip-pasv-ip.d b/docs/cmdline-opts/ftp-skip-pasv-ip.d +index da6ab11..4be8b43 100644 +--- a/docs/cmdline-opts/ftp-skip-pasv-ip.d ++++ b/docs/cmdline-opts/ftp-skip-pasv-ip.d +@@ -9,4 +9,6 @@ to curl's PASV command when curl connects the data connection. Instead curl + will re-use the same IP address it already uses for the control + connection. + ++Since curl 7.74.0 this option is enabled by default. ++ + This option has no effect if PORT, EPRT or EPSV is used instead of PASV. +diff --git a/docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.3 b/docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.3 +index 4d3026a..4227ed6 100644 +--- a/docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.3 ++++ b/docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.3 +@@ -5,7 +5,7 @@ + .\" * | (__| |_| | _ <| |___ + .\" * \___|\___/|_| \_\_____| + .\" * +-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. ++.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. + .\" * + .\" * This software is licensed as described in the file COPYING, which + .\" * you should have received as part of this distribution. The terms +@@ -36,11 +36,13 @@ address it already uses for the control connection. But it will use the port + number from the 227-response. + + This option thus allows libcurl to work around broken server installations +-that due to NATs, firewalls or incompetence report the wrong IP address back. ++that due to NATs, firewalls or incompetence report the wrong IP address ++back. Setting the option also reduces the risk for various sorts of client ++abuse by malicious servers. + + This option has no effect if PORT, EPRT or EPSV is used instead of PASV. + .SH DEFAULT +-0 ++1 since 7.74.0, was 0 before then. + .SH PROTOCOLS + FTP + .SH EXAMPLE +diff --git a/lib/url.c b/lib/url.c +index e77f391..b18db25 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -434,6 +434,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) + set->ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */ + set->ftp_use_pret = FALSE; /* mainly useful for drftpd servers */ + set->ftp_filemethod = FTPFILE_MULTICWD; ++ set->ftp_skip_ip = TRUE; /* skip PASV IP by default */ + + set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */ + +diff --git a/src/tool_cfgable.c b/src/tool_cfgable.c +index 81e16c1..110191e 100644 +--- a/src/tool_cfgable.c ++++ b/src/tool_cfgable.c +@@ -43,6 +43,7 @@ void config_init(struct OperationConfig* config) + config->proto_default = NULL; + config->tcp_nodelay = TRUE; /* enabled by default */ + config->happy_eyeballs_timeout_ms = CURL_HET_DEFAULT; ++ config->ftp_skip_ip = TRUE; + } + + static void free_config_fields(struct OperationConfig *config) +diff --git a/tests/data/test1400 b/tests/data/test1400 +index 10faef3..9d18a30 100644 +--- a/tests/data/test1400 ++++ b/tests/data/test1400 +@@ -73,6 +73,7 @@ int main(int argc, char *argv[]) + curl_easy_setopt(hnd, CURLOPT_USERAGENT, "stripped"); + curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L); + curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); ++ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); + curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); + + /* Here is a list of options the curl code used that cannot get generated +diff --git a/tests/data/test1401 b/tests/data/test1401 +index f330931..99cb0cb 100644 +--- a/tests/data/test1401 ++++ b/tests/data/test1401 +@@ -89,6 +89,7 @@ int main(int argc, char *argv[]) + curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L); + curl_easy_setopt(hnd, CURLOPT_COOKIE, "chocolate=chip"); + curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); ++ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); + curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); + curl_easy_setopt(hnd, CURLOPT_PROTOCOLS, (long)CURLPROTO_FILE | + (long)CURLPROTO_FTP | +diff --git a/tests/data/test1402 b/tests/data/test1402 +index 9a94283..ef55bd6 100644 +--- a/tests/data/test1402 ++++ b/tests/data/test1402 +@@ -80,6 +80,7 @@ int main(int argc, char *argv[]) + curl_easy_setopt(hnd, CURLOPT_USERAGENT, "stripped"); + curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L); + curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); ++ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); + curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); + + /* Here is a list of options the curl code used that cannot get generated +diff --git a/tests/data/test1403 b/tests/data/test1403 +index 79cdf49..78932c2 100644 +--- a/tests/data/test1403 ++++ b/tests/data/test1403 +@@ -75,6 +75,7 @@ int main(int argc, char *argv[]) + curl_easy_setopt(hnd, CURLOPT_USERAGENT, "stripped"); + curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L); + curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); ++ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); + curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); + + /* Here is a list of options the curl code used that cannot get generated +diff --git a/tests/data/test1404 b/tests/data/test1404 +index 9c6f2e7..8ea5e04 100644 +--- a/tests/data/test1404 ++++ b/tests/data/test1404 +@@ -144,6 +144,7 @@ int main(int argc, char *argv[]) + curl_easy_setopt(hnd, CURLOPT_USERAGENT, "stripped"); + curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L); + curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); ++ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); + curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); + + /* Here is a list of options the curl code used that cannot get generated +diff --git a/tests/data/test1405 b/tests/data/test1405 +index 73769ee..5a83b6e 100644 +--- a/tests/data/test1405 ++++ b/tests/data/test1405 +@@ -89,6 +89,7 @@ int main(int argc, char *argv[]) + curl_easy_setopt(hnd, CURLOPT_POSTQUOTE, slist2); + curl_easy_setopt(hnd, CURLOPT_PREQUOTE, slist3); + curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); ++ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); + curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); + + /* Here is a list of options the curl code used that cannot get generated +diff --git a/tests/data/test1406 b/tests/data/test1406 +index 796dd22..c941e00 100644 +--- a/tests/data/test1406 ++++ b/tests/data/test1406 +@@ -80,6 +80,7 @@ int main(int argc, char *argv[]) + curl_easy_setopt(hnd, CURLOPT_URL, "smtp://%HOSTIP:%SMTPPORT/1406"); + curl_easy_setopt(hnd, CURLOPT_UPLOAD, 1L); + curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); ++ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); + curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); + curl_easy_setopt(hnd, CURLOPT_MAIL_FROM, "sender@example.com"); + curl_easy_setopt(hnd, CURLOPT_MAIL_RCPT, slist1); +diff --git a/tests/data/test1407 b/tests/data/test1407 +index 9800eee..ddba7b7 100644 +--- a/tests/data/test1407 ++++ b/tests/data/test1407 +@@ -62,6 +62,7 @@ int main(int argc, char *argv[]) + curl_easy_setopt(hnd, CURLOPT_DIRLISTONLY, 1L); + curl_easy_setopt(hnd, CURLOPT_USERPWD, "user:secret"); + curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); ++ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); + curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); + + /* Here is a list of options the curl code used that cannot get generated +diff --git a/tests/data/test1420 b/tests/data/test1420 +index a5e1c52..72fb353 100644 +--- a/tests/data/test1420 ++++ b/tests/data/test1420 +@@ -67,6 +67,7 @@ int main(int argc, char *argv[]) + curl_easy_setopt(hnd, CURLOPT_URL, "imap://%HOSTIP:%IMAPPORT/1420/;UID=1"); + curl_easy_setopt(hnd, CURLOPT_USERPWD, "user:secret"); + curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); ++ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); + curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); + + /* Here is a list of options the curl code used that cannot get generated +-- +2.26.2 + diff --git a/SOURCES/0026-curl-7.61.1-CVE-2020-8285.patch b/SOURCES/0026-curl-7.61.1-CVE-2020-8285.patch new file mode 100644 index 0000000..703287e --- /dev/null +++ b/SOURCES/0026-curl-7.61.1-CVE-2020-8285.patch @@ -0,0 +1,258 @@ +From 22b3d1cf0216f4369f01678c587da265c2e465af Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sat, 28 Nov 2020 00:27:21 +0100 +Subject: [PATCH] ftp: make wc_statemach loop instead of recurse + +CVE-2020-8285 + +Fixes #6255 +Bug: https://curl.se/docs/CVE-2020-8285.html +Reported-by: xnynx on github + +Upstream-commit: 69a358f2186e04cf44698b5100332cbf1ee7f01d +Signed-off-by: Kamil Dudka +--- + lib/ftp.c | 204 +++++++++++++++++++++++++++--------------------------- + 1 file changed, 103 insertions(+), 101 deletions(-) + +diff --git a/lib/ftp.c b/lib/ftp.c +index 7dbf080..482ab3a 100644 +--- a/lib/ftp.c ++++ b/lib/ftp.c +@@ -3786,130 +3786,132 @@ static CURLcode init_wc_data(struct connectdata *conn) + return result; + } + +-/* This is called recursively */ + static CURLcode wc_statemach(struct connectdata *conn) + { + struct WildcardData * const wildcard = &(conn->data->wildcard); + CURLcode result = CURLE_OK; + +- switch(wildcard->state) { +- case CURLWC_INIT: +- result = init_wc_data(conn); +- if(wildcard->state == CURLWC_CLEAN) +- /* only listing! */ +- break; +- wildcard->state = result ? CURLWC_ERROR : CURLWC_MATCHING; +- break; ++ for(;;) { ++ switch(wildcard->state) { ++ case CURLWC_INIT: ++ result = init_wc_data(conn); ++ if(wildcard->state == CURLWC_CLEAN) ++ /* only listing! */ ++ return result; ++ wildcard->state = result ? CURLWC_ERROR : CURLWC_MATCHING; ++ return result; + +- case CURLWC_MATCHING: { +- /* In this state is LIST response successfully parsed, so lets restore +- previous WRITEFUNCTION callback and WRITEDATA pointer */ +- struct ftp_wc *ftpwc = wildcard->protdata; +- conn->data->set.fwrite_func = ftpwc->backup.write_function; +- conn->data->set.out = ftpwc->backup.file_descriptor; +- ftpwc->backup.write_function = ZERO_NULL; +- ftpwc->backup.file_descriptor = NULL; +- wildcard->state = CURLWC_DOWNLOADING; +- +- if(Curl_ftp_parselist_geterror(ftpwc->parser)) { +- /* error found in LIST parsing */ +- wildcard->state = CURLWC_CLEAN; +- return wc_statemach(conn); +- } +- if(wildcard->filelist.size == 0) { +- /* no corresponding file */ +- wildcard->state = CURLWC_CLEAN; +- return CURLE_REMOTE_FILE_NOT_FOUND; ++ case CURLWC_MATCHING: { ++ /* In this state is LIST response successfully parsed, so lets restore ++ previous WRITEFUNCTION callback and WRITEDATA pointer */ ++ struct ftp_wc *ftpwc = wildcard->protdata; ++ conn->data->set.fwrite_func = ftpwc->backup.write_function; ++ conn->data->set.out = ftpwc->backup.file_descriptor; ++ ftpwc->backup.write_function = ZERO_NULL; ++ ftpwc->backup.file_descriptor = NULL; ++ wildcard->state = CURLWC_DOWNLOADING; ++ ++ if(Curl_ftp_parselist_geterror(ftpwc->parser)) { ++ /* error found in LIST parsing */ ++ wildcard->state = CURLWC_CLEAN; ++ continue; ++ } ++ if(wildcard->filelist.size == 0) { ++ /* no corresponding file */ ++ wildcard->state = CURLWC_CLEAN; ++ return CURLE_REMOTE_FILE_NOT_FOUND; ++ } ++ continue; + } +- return wc_statemach(conn); +- } + +- case CURLWC_DOWNLOADING: { +- /* filelist has at least one file, lets get first one */ +- struct ftp_conn *ftpc = &conn->proto.ftpc; +- struct curl_fileinfo *finfo = wildcard->filelist.head->ptr; ++ case CURLWC_DOWNLOADING: { ++ /* filelist has at least one file, lets get first one */ ++ struct ftp_conn *ftpc = &conn->proto.ftpc; ++ struct curl_fileinfo *finfo = wildcard->filelist.head->ptr; + +- char *tmp_path = aprintf("%s%s", wildcard->path, finfo->filename); +- if(!tmp_path) +- return CURLE_OUT_OF_MEMORY; ++ char *tmp_path = aprintf("%s%s", wildcard->path, finfo->filename); ++ if(!tmp_path) ++ return CURLE_OUT_OF_MEMORY; + +- /* switch default "state.pathbuffer" and tmp_path, good to see +- ftp_parse_url_path function to understand this trick */ +- Curl_safefree(conn->data->state.pathbuffer); +- conn->data->state.pathbuffer = tmp_path; +- conn->data->state.path = tmp_path; +- +- infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename); +- if(conn->data->set.chunk_bgn) { +- long userresponse; +- Curl_set_in_callback(conn->data, true); +- userresponse = conn->data->set.chunk_bgn( +- finfo, wildcard->customptr, (int)wildcard->filelist.size); +- Curl_set_in_callback(conn->data, false); +- switch(userresponse) { +- case CURL_CHUNK_BGN_FUNC_SKIP: +- infof(conn->data, "Wildcard - \"%s\" skipped by user\n", +- finfo->filename); +- wildcard->state = CURLWC_SKIP; +- return wc_statemach(conn); +- case CURL_CHUNK_BGN_FUNC_FAIL: +- return CURLE_CHUNK_FAILED; ++ /* switch default "state.pathbuffer" and tmp_path, good to see ++ ftp_parse_url_path function to understand this trick */ ++ Curl_safefree(conn->data->state.pathbuffer); ++ conn->data->state.pathbuffer = tmp_path; ++ conn->data->state.path = tmp_path; ++ ++ infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename); ++ if(conn->data->set.chunk_bgn) { ++ long userresponse; ++ Curl_set_in_callback(conn->data, true); ++ userresponse = conn->data->set.chunk_bgn( ++ finfo, wildcard->customptr, (int)wildcard->filelist.size); ++ Curl_set_in_callback(conn->data, false); ++ switch(userresponse) { ++ case CURL_CHUNK_BGN_FUNC_SKIP: ++ infof(conn->data, "Wildcard - \"%s\" skipped by user\n", ++ finfo->filename); ++ wildcard->state = CURLWC_SKIP; ++ continue; ++ case CURL_CHUNK_BGN_FUNC_FAIL: ++ return CURLE_CHUNK_FAILED; ++ } + } +- } + +- if(finfo->filetype != CURLFILETYPE_FILE) { +- wildcard->state = CURLWC_SKIP; +- return wc_statemach(conn); +- } ++ if(finfo->filetype != CURLFILETYPE_FILE) { ++ wildcard->state = CURLWC_SKIP; ++ continue; ++ } + +- if(finfo->flags & CURLFINFOFLAG_KNOWN_SIZE) +- ftpc->known_filesize = finfo->size; ++ if(finfo->flags & CURLFINFOFLAG_KNOWN_SIZE) ++ ftpc->known_filesize = finfo->size; + +- result = ftp_parse_url_path(conn); +- if(result) +- return result; ++ result = ftp_parse_url_path(conn); ++ if(result) ++ return result; + +- /* we don't need the Curl_fileinfo of first file anymore */ +- Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL); ++ /* we don't need the Curl_fileinfo of first file anymore */ ++ Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL); + +- if(wildcard->filelist.size == 0) { /* remains only one file to down. */ +- wildcard->state = CURLWC_CLEAN; +- /* after that will be ftp_do called once again and no transfer +- will be done because of CURLWC_CLEAN state */ +- return CURLE_OK; ++ if(wildcard->filelist.size == 0) { /* remains only one file to down. */ ++ wildcard->state = CURLWC_CLEAN; ++ /* after that will be ftp_do called once again and no transfer ++ will be done because of CURLWC_CLEAN state */ ++ return CURLE_OK; ++ } ++ return result; + } +- } break; + +- case CURLWC_SKIP: { +- if(conn->data->set.chunk_end) { +- Curl_set_in_callback(conn->data, true); +- conn->data->set.chunk_end(conn->data->wildcard.customptr); +- Curl_set_in_callback(conn->data, false); ++ case CURLWC_SKIP: { ++ if(conn->data->set.chunk_end) { ++ Curl_set_in_callback(conn->data, true); ++ conn->data->set.chunk_end(conn->data->wildcard.customptr); ++ Curl_set_in_callback(conn->data, false); ++ } ++ Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL); ++ wildcard->state = (wildcard->filelist.size == 0) ? ++ CURLWC_CLEAN : CURLWC_DOWNLOADING; ++ continue; + } +- Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL); +- wildcard->state = (wildcard->filelist.size == 0) ? +- CURLWC_CLEAN : CURLWC_DOWNLOADING; +- return wc_statemach(conn); +- } + +- case CURLWC_CLEAN: { +- struct ftp_wc *ftpwc = wildcard->protdata; +- result = CURLE_OK; +- if(ftpwc) +- result = Curl_ftp_parselist_geterror(ftpwc->parser); ++ case CURLWC_CLEAN: { ++ struct ftp_wc *ftpwc = wildcard->protdata; ++ result = CURLE_OK; ++ if(ftpwc) ++ result = Curl_ftp_parselist_geterror(ftpwc->parser); + +- wildcard->state = result ? CURLWC_ERROR : CURLWC_DONE; +- } break; ++ wildcard->state = result ? CURLWC_ERROR : CURLWC_DONE; ++ return result; ++ } + +- case CURLWC_DONE: +- case CURLWC_ERROR: +- case CURLWC_CLEAR: +- if(wildcard->dtor) +- wildcard->dtor(wildcard->protdata); +- break; ++ case CURLWC_DONE: ++ case CURLWC_ERROR: ++ case CURLWC_CLEAR: ++ if(wildcard->dtor) ++ wildcard->dtor(wildcard->protdata); ++ return result; ++ } + } +- +- return result; ++ /* UNREACHABLE */ + } + + /*********************************************************************** +-- +2.26.2 + diff --git a/SOURCES/0027-curl-7.61.1-CVE-2020-8286.patch b/SOURCES/0027-curl-7.61.1-CVE-2020-8286.patch new file mode 100644 index 0000000..5180971 --- /dev/null +++ b/SOURCES/0027-curl-7.61.1-CVE-2020-8286.patch @@ -0,0 +1,129 @@ +From 2470bc91f62cc9b0ab1deac60a67f87b7cc95f6e Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Wed, 2 Dec 2020 23:01:11 +0100 +Subject: [PATCH] openssl: make the OCSP verification verify the certificate id + +CVE-2020-8286 + +Reported by anonymous + +Bug: https://curl.se/docs/CVE-2020-8286.html + +Upstream-commit: d9d01672785b8ac04aab1abb6de95fe3072ae199 +Signed-off-by: Kamil Dudka +--- + lib/vtls/openssl.c | 83 ++++++++++++++++++++++++++++++---------------- + 1 file changed, 54 insertions(+), 29 deletions(-) + +diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c +index 9476773..35cd652 100644 +--- a/lib/vtls/openssl.c ++++ b/lib/vtls/openssl.c +@@ -1659,6 +1659,11 @@ static CURLcode verifystatus(struct connectdata *conn, + OCSP_BASICRESP *br = NULL; + X509_STORE *st = NULL; + STACK_OF(X509) *ch = NULL; ++ X509 *cert; ++ OCSP_CERTID *id = NULL; ++ int cert_status, crl_reason; ++ ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; ++ int ret; + + long len = SSL_get_tlsext_status_ocsp_resp(BACKEND->handle, &p); + +@@ -1727,43 +1732,63 @@ static CURLcode verifystatus(struct connectdata *conn, + goto end; + } + +- for(i = 0; i < OCSP_resp_count(br); i++) { +- int cert_status, crl_reason; +- OCSP_SINGLERESP *single = NULL; +- +- ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; ++ /* Compute the certificate's ID */ ++ cert = SSL_get_peer_certificate(BACKEND->handle); ++ if(!cert) { ++ failf(data, "Error getting peer certficate"); ++ result = CURLE_SSL_INVALIDCERTSTATUS; ++ goto end; ++ } + +- single = OCSP_resp_get0(br, i); +- if(!single) +- continue; ++ for(i = 0; i < sk_X509_num(ch); i++) { ++ X509 *issuer = sk_X509_value(ch, i); ++ if(X509_check_issued(issuer, cert) == X509_V_OK) { ++ id = OCSP_cert_to_id(EVP_sha1(), cert, issuer); ++ break; ++ } ++ } ++ X509_free(cert); + +- cert_status = OCSP_single_get0_status(single, &crl_reason, &rev, +- &thisupd, &nextupd); ++ if(!id) { ++ failf(data, "Error computing OCSP ID"); ++ result = CURLE_SSL_INVALIDCERTSTATUS; ++ goto end; ++ } + +- if(!OCSP_check_validity(thisupd, nextupd, 300L, -1L)) { +- failf(data, "OCSP response has expired"); +- result = CURLE_SSL_INVALIDCERTSTATUS; +- goto end; +- } ++ /* Find the single OCSP response corresponding to the certificate ID */ ++ ret = OCSP_resp_find_status(br, id, &cert_status, &crl_reason, &rev, ++ &thisupd, &nextupd); ++ OCSP_CERTID_free(id); ++ if(ret != 1) { ++ failf(data, "Could not find certificate ID in OCSP response"); ++ result = CURLE_SSL_INVALIDCERTSTATUS; ++ goto end; ++ } + +- infof(data, "SSL certificate status: %s (%d)\n", +- OCSP_cert_status_str(cert_status), cert_status); ++ /* Validate the corresponding single OCSP response */ ++ if(!OCSP_check_validity(thisupd, nextupd, 300L, -1L)) { ++ failf(data, "OCSP response has expired"); ++ result = CURLE_SSL_INVALIDCERTSTATUS; ++ goto end; ++ } + +- switch(cert_status) { +- case V_OCSP_CERTSTATUS_GOOD: +- break; ++ infof(data, "SSL certificate status: %s (%d)\n", ++ OCSP_cert_status_str(cert_status), cert_status); + +- case V_OCSP_CERTSTATUS_REVOKED: +- result = CURLE_SSL_INVALIDCERTSTATUS; ++ switch(cert_status) { ++ case V_OCSP_CERTSTATUS_GOOD: ++ break; + +- failf(data, "SSL certificate revocation reason: %s (%d)", +- OCSP_crl_reason_str(crl_reason), crl_reason); +- goto end; ++ case V_OCSP_CERTSTATUS_REVOKED: ++ result = CURLE_SSL_INVALIDCERTSTATUS; ++ failf(data, "SSL certificate revocation reason: %s (%d)", ++ OCSP_crl_reason_str(crl_reason), crl_reason); ++ goto end; + +- case V_OCSP_CERTSTATUS_UNKNOWN: +- result = CURLE_SSL_INVALIDCERTSTATUS; +- goto end; +- } ++ case V_OCSP_CERTSTATUS_UNKNOWN: ++ default: ++ result = CURLE_SSL_INVALIDCERTSTATUS; ++ goto end; + } + + end: +-- +2.26.2 + diff --git a/SOURCES/0028-curl-7.61.1-http-auth-payload.patch b/SOURCES/0028-curl-7.61.1-http-auth-payload.patch new file mode 100644 index 0000000..c4662b4 --- /dev/null +++ b/SOURCES/0028-curl-7.61.1-http-auth-payload.patch @@ -0,0 +1,63 @@ +From 5a51924c2505c1d5616904aa732fdaedd74d3ffe Mon Sep 17 00:00:00 2001 +From: Marc Schlatter +Date: Mon, 11 Mar 2019 17:15:34 +0100 +Subject: [PATCH] http: send payload when (proxy) authentication is done + +The check that prevents payload from sending in case of authentication +doesn't check properly if the authentication is done or not. + +They're cases where the proxy respond "200 OK" before sending +authentication challenge. This change takes care of that. + +Fixes #2431 +Closes #3669 + +Upstream-commit: dd8a19f8a05b59394d1ab33c09497e8db884742a +Signed-off-by: Kamil Dudka +--- + lib/http.c | 3 ++- + tests/data/test1097 | 5 +++-- + 2 files changed, 5 insertions(+), 3 deletions(-) + +diff --git a/lib/http.c b/lib/http.c +index e727ed8..26eb52d 100644 +--- a/lib/http.c ++++ b/lib/http.c +@@ -1991,7 +1991,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) + if(result) + return result; + +- if((data->state.authhost.multipass || data->state.authproxy.multipass) && ++ if(((data->state.authhost.multipass && !data->state.authhost.done) ++ || (data->state.authproxy.multipass && !data->state.authproxy.done)) && + (httpreq != HTTPREQ_GET) && + (httpreq != HTTPREQ_HEAD)) { + /* Auth is required and we are not authenticated yet. Make a PUT or POST +diff --git a/tests/data/test1097 b/tests/data/test1097 +index 7512a2e..7eb7b5f 100644 +--- a/tests/data/test1097 ++++ b/tests/data/test1097 +@@ -60,7 +60,7 @@ http://test.a.galaxy.far.far.away.1097:%HTTPPORT/1097 --proxy http://%HOSTIP:%HT + + ^User-Agent: curl/.* + +- ++ + CONNECT test.a.galaxy.far.far.away.1097:%HTTPPORT HTTP/1.1 + Host: test.a.galaxy.far.far.away.1097:%HTTPPORT + Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA= +@@ -71,9 +71,10 @@ POST /1097 HTTP/1.1 + User-Agent: curl/7.19.5-CVS (i686-pc-linux-gnu) libcurl/7.19.5-CVS OpenSSL/0.9.8g zlib/1.2.3.3 c-ares/1.6.1-CVS libidn/1.12 libssh2/1.0.1_CVS + Host: test.a.galaxy.far.far.away.1097:%HTTPPORT + Accept: */* +-Content-Length: 0 ++Content-Length: 11 + Content-Type: application/x-www-form-urlencoded + ++dummy=value + + + +-- +2.26.2 + diff --git a/SOURCES/0029-curl-7.61.1-CVE-2021-22876.patch b/SOURCES/0029-curl-7.61.1-CVE-2021-22876.patch new file mode 100644 index 0000000..dbd2496 --- /dev/null +++ b/SOURCES/0029-curl-7.61.1-CVE-2021-22876.patch @@ -0,0 +1,116 @@ +From 239f8d93866605b05f4e6b551f4327dc7fcb922b Mon Sep 17 00:00:00 2001 +From: Viktor Szakats +Date: Tue, 23 Feb 2021 14:54:46 +0100 +Subject: [PATCH 1/2] transfer: strip credentials from the auto-referer header + field + +Added test 2081 to verify. + +CVE-2021-22876 + +Bug: https://curl.se/docs/CVE-2021-22876.html + +Upstream-commit: 7214288898f5625a6cc196e22a74232eada7861c +Signed-off-by: Kamil Dudka +--- + lib/transfer.c | 25 +++++++++++++++++++++++-- + 1 file changed, 23 insertions(+), 2 deletions(-) + +diff --git a/lib/transfer.c b/lib/transfer.c +index ecd1063..263b178 100644 +--- a/lib/transfer.c ++++ b/lib/transfer.c +@@ -1473,6 +1473,7 @@ CURLcode Curl_follow(struct Curl_easy *data, + /* Location: redirect */ + bool disallowport = FALSE; + bool reachedmax = FALSE; ++ CURLUcode uc; + + if(type == FOLLOW_REDIR) { + if((data->set.maxredirs != -1) && +@@ -1488,6 +1489,9 @@ CURLcode Curl_follow(struct Curl_easy *data, + data->set.followlocation++; /* count location-followers */ + + if(data->set.http_auto_referer) { ++ CURLU *u; ++ char *referer; ++ + /* We are asked to automatically set the previous URL as the referer + when we get the next URL. We pick the ->url field, which may or may + not be 100% correct */ +@@ -1497,9 +1501,26 @@ CURLcode Curl_follow(struct Curl_easy *data, + data->change.referer_alloc = FALSE; + } + +- data->change.referer = strdup(data->change.url); +- if(!data->change.referer) ++ /* Make a copy of the URL without crenditals and fragment */ ++ u = curl_url(); ++ if(!u) ++ return CURLE_OUT_OF_MEMORY; ++ ++ uc = curl_url_set(u, CURLUPART_URL, data->change.url, 0); ++ if(!uc) ++ uc = curl_url_set(u, CURLUPART_FRAGMENT, NULL, 0); ++ if(!uc) ++ uc = curl_url_set(u, CURLUPART_USER, NULL, 0); ++ if(!uc) ++ uc = curl_url_set(u, CURLUPART_PASSWORD, NULL, 0); ++ if(!uc) ++ uc = curl_url_get(u, CURLUPART_URL, &referer, 0); ++ ++ curl_url_cleanup(u); ++ ++ if(uc || referer == NULL) + return CURLE_OUT_OF_MEMORY; ++ data->change.referer = referer; + data->change.referer_alloc = TRUE; /* yes, free this later */ + } + } +-- +2.30.2 + + +From f7d1d478b87499ce31d6aa3251830b78447ad952 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 29 Mar 2021 09:32:14 +0200 +Subject: [PATCH 2/2] transfer: clear 'referer' in declaration + +To silence (false positive) compiler warnings about it. + +Follow-up to 7214288898f5625 + +Reviewed-by: Marcel Raad +Closes #6810 + +Upstream-commit: 6bb028dbda6cbfe83f66de773544f71e4813160f +Signed-off-by: Kamil Dudka +--- + lib/transfer.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/lib/transfer.c b/lib/transfer.c +index 263b178..ad5a7ba 100644 +--- a/lib/transfer.c ++++ b/lib/transfer.c +@@ -1490,7 +1490,7 @@ CURLcode Curl_follow(struct Curl_easy *data, + + if(data->set.http_auto_referer) { + CURLU *u; +- char *referer; ++ char *referer = NULL; + + /* We are asked to automatically set the previous URL as the referer + when we get the next URL. We pick the ->url field, which may or may +@@ -1518,7 +1518,7 @@ CURLcode Curl_follow(struct Curl_easy *data, + + curl_url_cleanup(u); + +- if(uc || referer == NULL) ++ if(uc || !referer) + return CURLE_OUT_OF_MEMORY; + data->change.referer = referer; + data->change.referer_alloc = TRUE; /* yes, free this later */ +-- +2.30.2 + diff --git a/SOURCES/0030-curl-7.61.1-file-head.patch b/SOURCES/0030-curl-7.61.1-file-head.patch new file mode 100644 index 0000000..e545e8e --- /dev/null +++ b/SOURCES/0030-curl-7.61.1-file-head.patch @@ -0,0 +1,693 @@ +From 87e3d094e0dc00efc1abeb2b142d453024cbca69 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Thu, 4 Oct 2018 23:53:32 +0200 +Subject: [PATCH] FILE: fix CURLOPT_NOBODY and CURLOPT_HEADER output + +Now FILE transfers send headers to the header callback like HTTP and +other protocols. Also made curl_easy_getinfo(...CURLINFO_PROTOCOL...) +work for FILE in the callbacks. + +Makes "curl -i file://.." and "curl -I file://.." work like before +again. Applied the bold header logic to them too. + +Regression from c1c2762 (7.61.0) + +Reported-by: Shaun Jackman +Fixes #3083 +Closes #3101 + +Upstream-commit: e50a2002bd450a4800a165d2874ed79c95b33a07 +Signed-off-by: Kamil Dudka +--- + lib/file.c | 27 +++++++++++++-------------- + lib/getinfo.c | 1 - + lib/url.c | 1 + + src/tool_cb_hdr.c | 5 +++-- + tests/data/test1016 | 2 +- + tests/data/test1017 | 2 +- + tests/data/test1018 | 2 +- + tests/data/test1019 | 2 +- + tests/data/test1020 | 2 +- + tests/data/test1029 | 2 +- + tests/data/test1146 | 2 +- + tests/data/test1220 | 2 +- + tests/data/test200 | 2 +- + tests/data/test2000 | 2 +- + tests/data/test2001 | 13 +------------ + tests/data/test2002 | 13 +------------ + tests/data/test2003 | 26 ++------------------------ + tests/data/test2004 | 2 +- + tests/data/test2006 | 8 ++++++++ + tests/data/test2007 | 8 ++++++++ + tests/data/test2008 | 8 ++++++++ + tests/data/test2009 | 8 ++++++++ + tests/data/test2010 | 8 ++++++++ + tests/data/test202 | 2 +- + tests/data/test203 | 2 +- + tests/data/test204 | 2 +- + tests/data/test205 | 2 +- + tests/data/test2070 | 2 +- + tests/data/test2071 | 2 +- + tests/data/test2072 | 2 +- + tests/data/test210 | 2 +- + tests/data/test231 | 2 +- + tests/data/test288 | 2 +- + 33 files changed, 82 insertions(+), 86 deletions(-) + +diff --git a/lib/file.c b/lib/file.c +index e50e988..f780658 100644 +--- a/lib/file.c ++++ b/lib/file.c +@@ -386,7 +386,6 @@ static CURLcode file_do(struct connectdata *conn, bool *done) + + *done = TRUE; /* unconditionally */ + +- Curl_initinfo(data); + Curl_pgrsStartNow(data); + + if(data->set.upload) +@@ -413,21 +412,18 @@ static CURLcode file_do(struct connectdata *conn, bool *done) + } + } + +- /* If we have selected NOBODY and HEADER, it means that we only want file +- information. Which for FILE can't be much more than the file size and +- date. */ +- if(data->set.opt_no_body && data->set.include_header && fstated) { ++ if(fstated) { + time_t filetime; + struct tm buffer; + const struct tm *tm = &buffer; + char header[80]; + snprintf(header, sizeof(header), + "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", expected_size); +- result = Curl_client_write(conn, CLIENTWRITE_BOTH, header, 0); ++ result = Curl_client_write(conn, CLIENTWRITE_HEADER, header, 0); + if(result) + return result; + +- result = Curl_client_write(conn, CLIENTWRITE_BOTH, ++ result = Curl_client_write(conn, CLIENTWRITE_HEADER, + (char *)"Accept-ranges: bytes\r\n", 0); + if(result) + return result; +@@ -439,19 +435,22 @@ static CURLcode file_do(struct connectdata *conn, bool *done) + + /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */ + snprintf(header, sizeof(header), +- "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n", ++ "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n%s", + Curl_wkday[tm->tm_wday?tm->tm_wday-1:6], + tm->tm_mday, + Curl_month[tm->tm_mon], + tm->tm_year + 1900, + tm->tm_hour, + tm->tm_min, +- tm->tm_sec); +- result = Curl_client_write(conn, CLIENTWRITE_BOTH, header, 0); +- if(!result) +- /* set the file size to make it available post transfer */ +- Curl_pgrsSetDownloadSize(data, expected_size); +- return result; ++ tm->tm_sec, ++ data->set.opt_no_body ? "": "\r\n"); ++ result = Curl_client_write(conn, CLIENTWRITE_HEADER, header, 0); ++ if(result) ++ return result; ++ /* set the file size to make it available post transfer */ ++ Curl_pgrsSetDownloadSize(data, expected_size); ++ if(data->set.opt_no_body) ++ return result; + } + + /* Check whether file range has been specified */ +diff --git a/lib/getinfo.c b/lib/getinfo.c +index 14b4562..54c2c2f 100644 +--- a/lib/getinfo.c ++++ b/lib/getinfo.c +@@ -85,7 +85,6 @@ CURLcode Curl_initinfo(struct Curl_easy *data) + #ifdef USE_SSL + Curl_ssl_free_certinfo(data); + #endif +- + return CURLE_OK; + } + +diff --git a/lib/url.c b/lib/url.c +index b18db25..bb9d107 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -4290,6 +4290,7 @@ static CURLcode create_conn(struct Curl_easy *data, + /* this is supposed to be the connect function so we better at least check + that the file is present here! */ + DEBUGASSERT(conn->handler->connect_it); ++ Curl_persistconninfo(conn); + result = conn->handler->connect_it(conn, &done); + + /* Setup a "faked" transfer that'll do nothing */ +diff --git a/src/tool_cb_hdr.c b/src/tool_cb_hdr.c +index e91e8ac..4f21221 100644 +--- a/src/tool_cb_hdr.c ++++ b/src/tool_cb_hdr.c +@@ -153,8 +153,9 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) + } + + if(hdrcbdata->config->show_headers && +- (protocol & (CURLPROTO_HTTP|CURLPROTO_HTTPS|CURLPROTO_RTSP))) { +- /* bold headers only happen for HTTP(S) and RTSP */ ++ (protocol & ++ (CURLPROTO_HTTP|CURLPROTO_HTTPS|CURLPROTO_RTSP|CURLPROTO_FILE))) { ++ /* bold headers only for selected protocols */ + char *value = NULL; + + if(!outs->stream && !tool_create_output_file(outs)) +diff --git a/tests/data/test1016 b/tests/data/test1016 +index b404cac..4927f9e 100644 +--- a/tests/data/test1016 ++++ b/tests/data/test1016 +@@ -22,7 +22,7 @@ file + + X-Y range on a file:// URL to stdout + +- ++ + -r 1-4 file://localhost/%PWD/log/test1016.txt + + +diff --git a/tests/data/test1017 b/tests/data/test1017 +index 6fbc38a..cfdd80f 100644 +--- a/tests/data/test1017 ++++ b/tests/data/test1017 +@@ -23,7 +23,7 @@ file + + 0-Y range on a file:// URL to stdout + +- ++ + -r 0-3 file://localhost/%PWD/log/test1017.txt + + +diff --git a/tests/data/test1018 b/tests/data/test1018 +index 28a7027..5748701 100644 +--- a/tests/data/test1018 ++++ b/tests/data/test1018 +@@ -22,7 +22,7 @@ file + + X-X range on a file:// URL to stdout + +- ++ + -r 4-4 file://localhost/%PWD/log/test1018.txt + + +diff --git a/tests/data/test1019 b/tests/data/test1019 +index 4d9872a..054e38d 100644 +--- a/tests/data/test1019 ++++ b/tests/data/test1019 +@@ -23,7 +23,7 @@ file + + X- range on a file:// URL to stdout + +- ++ + -r 7- file://localhost/%PWD/log/test1019.txt + + +diff --git a/tests/data/test1020 b/tests/data/test1020 +index 735871d..e924529 100644 +--- a/tests/data/test1020 ++++ b/tests/data/test1020 +@@ -23,7 +23,7 @@ file + + -Y range on a file:// URL to stdout + +- ++ + -r -9 file://localhost/%PWD/log/test1020.txt + + +diff --git a/tests/data/test1029 b/tests/data/test1029 +index 2ffc7c6..c77209c 100644 +--- a/tests/data/test1029 ++++ b/tests/data/test1029 +@@ -29,7 +29,7 @@ http + + HTTP Location: and 'redirect_url' check + +- ++ + http://%HOSTIP:%HTTPPORT/we/want/our/1029 -w '%{redirect_url}\n' + + +diff --git a/tests/data/test1146 b/tests/data/test1146 +index 43f33b7..636748e 100644 +--- a/tests/data/test1146 ++++ b/tests/data/test1146 +@@ -24,7 +24,7 @@ file + + --proto-default file + +- ++ + --proto-default file %PWD/log/test1146.txt + + +diff --git a/tests/data/test1220 b/tests/data/test1220 +index 959abbf..6752eb5 100644 +--- a/tests/data/test1220 ++++ b/tests/data/test1220 +@@ -20,7 +20,7 @@ file + + file:// URLs with query string + +- ++ + file://localhost/%PWD/log/test1220.txt?a_query=foobar#afragment + + +diff --git a/tests/data/test200 b/tests/data/test200 +index 8be1de0..c27f7c0 100644 +--- a/tests/data/test200 ++++ b/tests/data/test200 +@@ -23,7 +23,7 @@ file + + basic file:// file + +- ++ + file://localhost/%PWD/log/test200.txt + + +diff --git a/tests/data/test2000 b/tests/data/test2000 +index d3edb16..db1ba13 100644 +--- a/tests/data/test2000 ++++ b/tests/data/test2000 +@@ -31,7 +31,7 @@ file + + FTP RETR followed by FILE + +- ++ + ftp://%HOSTIP:%FTPPORT/2000 file://localhost/%PWD/log/test2000.txt + + +diff --git a/tests/data/test2001 b/tests/data/test2001 +index 68c0df7..88a258e 100644 +--- a/tests/data/test2001 ++++ b/tests/data/test2001 +@@ -48,7 +48,7 @@ file + + HTTP GET followed by FTP RETR followed by FILE + +- ++ + http://%HOSTIP:%HTTPPORT/20010001 ftp://%HOSTIP:%FTPPORT/20010002 file://localhost/%PWD/log/test2001.txt + + +@@ -81,17 +81,6 @@ RETR 20010002 + QUIT + + +-HTTP/1.1 200 OK +-Date: Thu, 09 Nov 2010 14:49:00 GMT +-Server: test-server/fake +-Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT +-ETag: "21025-dc7-39462498" +-Accept-Ranges: bytes +-Content-Length: 6 +-Connection: close +-Content-Type: text/html +-Funny-head: yesyes +- + -foo- + data + to +diff --git a/tests/data/test2002 b/tests/data/test2002 +index db96bfe..6dd2f93 100644 +--- a/tests/data/test2002 ++++ b/tests/data/test2002 +@@ -57,7 +57,7 @@ tftp + + HTTP GET followed by FTP RETR followed by FILE followed by TFTP RRQ + +- ++ + http://%HOSTIP:%HTTPPORT/20020001 ftp://%HOSTIP:%FTPPORT/20020002 file://localhost/%PWD/log/test2002.txt tftp://%HOSTIP:%TFTPPORT//20020003 + + +@@ -96,17 +96,6 @@ filename: /20020003 + QUIT + + +-HTTP/1.1 200 OK +-Date: Thu, 09 Nov 2010 14:49:00 GMT +-Server: test-server/fake +-Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT +-ETag: "21025-dc7-39462498" +-Accept-Ranges: bytes +-Content-Length: 6 +-Connection: close +-Content-Type: text/html +-Funny-head: yesyes +- + -foo- + data + to +diff --git a/tests/data/test2003 b/tests/data/test2003 +index 59a743f..09bee8e 100644 +--- a/tests/data/test2003 ++++ b/tests/data/test2003 +@@ -57,8 +57,8 @@ tftp + + HTTP GET followed by FTP RETR followed by FILE followed by TFTP RRQ then again in reverse order + +- +-http://%HOSTIP:%HTTPPORT/20030001 ftp://%HOSTIP:%FTPPORT/20030002 file://localhost/%PWD/log/test2003.txt tftp://%HOSTIP:%TFTPPORT//20030003 tftp://%HOSTIP:%TFTPPORT//20030003 file://localhost/%PWD/log/test2003.txt ftp://%HOSTIP:%FTPPORT/20030002 http://%HOSTIP:%HTTPPORT/20030001 ++ ++http://%HOSTIP:%HTTPPORT/20030001 ftp://%HOSTIP:%FTPPORT/20030002 file://localhost/%PWD/log/test2003.txt tftp://%HOSTIP:%TFTPPORT//20030003 tftp://%HOSTIP:%TFTPPORT//20030003 file://localhost/%PWD/log/test2003.txt ftp://%HOSTIP:%FTPPORT/20030002 http://%HOSTIP:%HTTPPORT/20030001 + + + foo +@@ -109,17 +109,6 @@ Accept: */* + QUIT + + +-HTTP/1.1 200 OK +-Date: Thu, 09 Nov 2010 14:49:00 GMT +-Server: test-server/fake +-Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT +-ETag: "21025-dc7-39462498" +-Accept-Ranges: bytes +-Content-Length: 6 +-Connection: close +-Content-Type: text/html +-Funny-head: yesyes +- + -foo- + data + to +@@ -151,17 +140,6 @@ data + that FTP + works + so does it? +-HTTP/1.1 200 OK +-Date: Thu, 09 Nov 2010 14:49:00 GMT +-Server: test-server/fake +-Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT +-ETag: "21025-dc7-39462498" +-Accept-Ranges: bytes +-Content-Length: 6 +-Connection: close +-Content-Type: text/html +-Funny-head: yesyes +- + -foo- + + +diff --git a/tests/data/test2004 b/tests/data/test2004 +index 4773f69..b17890b 100644 +--- a/tests/data/test2004 ++++ b/tests/data/test2004 +@@ -29,7 +29,7 @@ sftp + + TFTP RRQ followed by SFTP retrieval followed by FILE followed by SCP retrieval then again in reverse order + +- ++ + --key curl_client_key --pubkey curl_client_key.pub -u %USER: tftp://%HOSTIP:%TFTPPORT//2004 sftp://%HOSTIP:%SSHPORT%POSIX_PWD/log/test2004.txt file://localhost/%PWD/log/test2004.txt scp://%HOSTIP:%SSHPORT%POSIX_PWD/log/test2004.txt file://localhost/%PWD/log/test2004.txt sftp://%HOSTIP:%SSHPORT%POSIX_PWD/log/test2004.txt tftp://%HOSTIP:%TFTPPORT//2004 --insecure + + +diff --git a/tests/data/test2006 b/tests/data/test2006 +index e25556f..3acbdae 100644 +--- a/tests/data/test2006 ++++ b/tests/data/test2006 +@@ -4,6 +4,7 @@ + Metalink + HTTP + HTTP GET ++FILE + + + +@@ -85,6 +86,10 @@ Accept: */* + Some data delivered from an HTTP resource + + ++Content-Length: 496 ++Accept-ranges: bytes ++ ++ + HTTP/1.1 200 OK + Date: Thu, 21 Jun 2012 14:49:01 GMT + Server: test-server/fake +@@ -105,6 +110,9 @@ Metalink: fetching (log/download2006) from (http://%HOSTIP:%HTTPPORT/2006) OK + Metalink: validating (log/download2006)... + Metalink: validating (log/download2006) [sha-256] OK + ++ ++s/Last-Modified:.*// ++ + + $_ = '' if (($_ !~ /^Metalink: /) && ($_ !~ /error/i) && ($_ !~ /warn/i)) + +diff --git a/tests/data/test2007 b/tests/data/test2007 +index cc4bd8c..b169c49 100644 +--- a/tests/data/test2007 ++++ b/tests/data/test2007 +@@ -5,6 +5,7 @@ Metalink + HTTP + HTTP GET + -J ++FILE + + + +@@ -85,7 +86,14 @@ Accept: */* + + Something delivered from an HTTP resource + ++ ++s/Last-Modified:.*// ++ + ++Content-Length: 496 ++Accept-ranges: bytes ++ ++ + HTTP/1.1 200 OK + Date: Thu, 21 Jun 2012 14:50:02 GMT + Server: test-server/fake +diff --git a/tests/data/test2008 b/tests/data/test2008 +index 5843792..012f221 100644 +--- a/tests/data/test2008 ++++ b/tests/data/test2008 +@@ -4,6 +4,7 @@ + Metalink + HTTP + HTTP GET ++FILE + + + +@@ -77,7 +78,14 @@ Accept: */* + + Some stuff delivered from an HTTP resource + ++ ++s/Last-Modified:.*// ++ + ++Content-Length: 496 ++Accept-ranges: bytes ++ ++ + HTTP/1.1 200 OK + Date: Thu, 21 Jun 2012 15:23:48 GMT + Server: test-server/fake +diff --git a/tests/data/test2009 b/tests/data/test2009 +index 84482ce..b0e5c6c 100644 +--- a/tests/data/test2009 ++++ b/tests/data/test2009 +@@ -5,6 +5,7 @@ Metalink + HTTP + HTTP GET + -J ++FILE + + + +@@ -78,7 +79,14 @@ Accept: */* + + Some contents delivered from an HTTP resource + ++ ++s/Last-Modified:.*// ++ + ++Content-Length: 496 ++Accept-ranges: bytes ++ ++ + HTTP/1.1 200 OK + Date: Thu, 21 Jun 2012 16:27:17 GMT + Server: test-server/fake +diff --git a/tests/data/test2010 b/tests/data/test2010 +index 91a83f4..33bb309 100644 +--- a/tests/data/test2010 ++++ b/tests/data/test2010 +@@ -4,6 +4,7 @@ + Metalink + HTTP + HTTP GET ++FILE + + + +@@ -77,7 +78,14 @@ Accept: */* + + Contents delivered from an HTTP resource + ++ ++s/Last-Modified:.*// ++ + ++Content-Length: 496 ++Accept-ranges: bytes ++ ++ + HTTP/1.1 200 OK + Date: Thu, 21 Jun 2012 17:37:27 GMT + Server: test-server/fake +diff --git a/tests/data/test202 b/tests/data/test202 +index f863ec5..0b324b1 100644 +--- a/tests/data/test202 ++++ b/tests/data/test202 +@@ -19,7 +19,7 @@ file + + two file:// URLs to stdout + +- ++ + file://localhost/%PWD/log/test202.txt FILE://localhost/%PWD/log/test202.txt + + +diff --git a/tests/data/test203 b/tests/data/test203 +index 366cc2c..3938426 100644 +--- a/tests/data/test203 ++++ b/tests/data/test203 +@@ -24,7 +24,7 @@ file + + file:/path URL with a single slash + +- ++ + file:%PWD/log/test203.txt + + +diff --git a/tests/data/test204 b/tests/data/test204 +index 9cc7b01..0ed9451 100644 +--- a/tests/data/test204 ++++ b/tests/data/test204 +@@ -15,7 +15,7 @@ file + + "upload" with file:// + +- ++ + file://localhost/%PWD/log/result204.txt -T log/upload204.txt + + +diff --git a/tests/data/test205 b/tests/data/test205 +index 4af93f6..f83c531 100644 +--- a/tests/data/test205 ++++ b/tests/data/test205 +@@ -16,7 +16,7 @@ file + + "upload" with file:// + +- ++ + file://localhost/%PWD/log/nonexisting/result205.txt -T log/upload205.txt + + +diff --git a/tests/data/test2070 b/tests/data/test2070 +index bc3898a..655cd8a 100644 +--- a/tests/data/test2070 ++++ b/tests/data/test2070 +@@ -23,7 +23,7 @@ file + + basic file:// file with no authority + +- ++ + file:%PWD/log/test2070.txt + + +diff --git a/tests/data/test2071 b/tests/data/test2071 +index 997dfff..eddfa4d 100644 +--- a/tests/data/test2071 ++++ b/tests/data/test2071 +@@ -23,7 +23,7 @@ file + + basic file:// file with "127.0.0.1" hostname + +- ++ + file://127.0.0.1/%PWD/log/test2070.txt + + +diff --git a/tests/data/test2072 b/tests/data/test2072 +index cd26f22..1bab158 100644 +--- a/tests/data/test2072 ++++ b/tests/data/test2072 +@@ -23,7 +23,7 @@ file + + file:// with unix path resolution behavior for the case of extra slashes + +- ++ + file:////%PWD/log/test2072.txt + + +diff --git a/tests/data/test210 b/tests/data/test210 +index e904567..c6fb703 100644 +--- a/tests/data/test210 ++++ b/tests/data/test210 +@@ -22,7 +22,7 @@ ftp + + Get two FTP files from the same remote dir: no second CWD + +- ++ + ftp://%HOSTIP:%FTPPORT/a/path/210 ftp://%HOSTIP:%FTPPORT/a/path/210 + + +diff --git a/tests/data/test231 b/tests/data/test231 +index 6994957..3d4bc77 100644 +--- a/tests/data/test231 ++++ b/tests/data/test231 +@@ -22,7 +22,7 @@ file + + file:// with resume + +- ++ + file://localhost/%PWD/log/test231.txt -C 10 + + +diff --git a/tests/data/test288 b/tests/data/test288 +index ff4db6a..9f8f6e1 100644 +--- a/tests/data/test288 ++++ b/tests/data/test288 +@@ -30,7 +30,7 @@ file:// with (unsupported) proxy, authentication and range + + all_proxy=http://fake:user@%HOSTIP:%HTTPPORT/ + +- ++ + file://localhost/%PWD/log/test288.txt + + +-- +2.30.2 + diff --git a/SOURCES/0031-curl-7.61.1-CVE-2021-22924.patch b/SOURCES/0031-curl-7.61.1-CVE-2021-22924.patch new file mode 100644 index 0000000..990d32f --- /dev/null +++ b/SOURCES/0031-curl-7.61.1-CVE-2021-22924.patch @@ -0,0 +1,662 @@ +From 74ba80e293eb2521d28916b24c3be59b3baf688a Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Thu, 18 Feb 2021 10:13:56 +0100 +Subject: [PATCH 1/2] urldata: remove the _ORIG suffix from string names + +It doesn't provide any useful info but only makes the names longer. + +Closes #6624 + +Upstream-commit: 70472a44deaff387cf8c8c197e04f3add2a96e2e +Signed-off-by: Kamil Dudka +--- + lib/setopt.c | 32 ++++++++++++++++---------------- + lib/url.c | 32 ++++++++++++++++---------------- + lib/urldata.h | 28 ++++++++++++++-------------- + lib/vtls/cyassl.c | 2 +- + lib/vtls/darwinssl.c | 4 ++-- + lib/vtls/gskit.c | 2 +- + lib/vtls/gtls.c | 2 +- + lib/vtls/mbedtls.c | 2 +- + lib/vtls/nss.c | 2 +- + lib/vtls/openssl.c | 2 +- + lib/vtls/polarssl.c | 2 +- + lib/vtls/schannel.c | 2 +- + 12 files changed, 56 insertions(+), 56 deletions(-) + +diff --git a/lib/setopt.c b/lib/setopt.c +index 4f04962..b07ccfe 100644 +--- a/lib/setopt.c ++++ b/lib/setopt.c +@@ -133,7 +133,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + break; + case CURLOPT_SSL_CIPHER_LIST: + /* set a list of cipher we want to use in the SSL connection */ +- result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST], + va_arg(param, char *)); + break; + case CURLOPT_PROXY_SSL_CIPHER_LIST: +@@ -145,7 +145,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + case CURLOPT_TLS13_CIPHERS: + if(Curl_ssl_tls13_ciphersuites()) { + /* set preferred list of TLS 1.3 cipher suites */ +- result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER13_LIST_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER13_LIST], + va_arg(param, char *)); + } + else +@@ -1532,7 +1532,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + /* + * String that holds file name of the SSL certificate to use + */ +- result = Curl_setstropt(&data->set.str[STRING_CERT_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_CERT], + va_arg(param, char *)); + break; + case CURLOPT_PROXY_SSLCERT: +@@ -1546,7 +1546,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + /* + * String that holds file type of the SSL certificate to use + */ +- result = Curl_setstropt(&data->set.str[STRING_CERT_TYPE_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_CERT_TYPE], + va_arg(param, char *)); + break; + case CURLOPT_PROXY_SSLCERTTYPE: +@@ -1560,7 +1560,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + /* + * String that holds file name of the SSL key to use + */ +- result = Curl_setstropt(&data->set.str[STRING_KEY_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_KEY], + va_arg(param, char *)); + break; + case CURLOPT_PROXY_SSLKEY: +@@ -1574,7 +1574,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + /* + * String that holds file type of the SSL key to use + */ +- result = Curl_setstropt(&data->set.str[STRING_KEY_TYPE_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_KEY_TYPE], + va_arg(param, char *)); + break; + case CURLOPT_PROXY_SSLKEYTYPE: +@@ -1588,7 +1588,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + /* + * String that holds the SSL or SSH private key password. + */ +- result = Curl_setstropt(&data->set.str[STRING_KEY_PASSWD_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_KEY_PASSWD], + va_arg(param, char *)); + break; + case CURLOPT_PROXY_KEYPASSWD: +@@ -1815,7 +1815,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + */ + #ifdef USE_SSL + if(Curl_ssl->supports & SSLSUPP_PINNEDPUBKEY) +- result = Curl_setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY], + va_arg(param, char *)); + else + #endif +@@ -1838,7 +1838,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + /* + * Set CA info for SSL connection. Specify file name of the CA certificate + */ +- result = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE], + va_arg(param, char *)); + break; + case CURLOPT_PROXY_CAINFO: +@@ -1857,7 +1857,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + #ifdef USE_SSL + if(Curl_ssl->supports & SSLSUPP_CA_PATH) + /* This does not work on windows. */ +- result = Curl_setstropt(&data->set.str[STRING_SSL_CAPATH_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_SSL_CAPATH], + va_arg(param, char *)); + else + #endif +@@ -1882,7 +1882,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + * Set CRL file info for SSL connection. Specify file name of the CRL + * to check certificates revocation + */ +- result = Curl_setstropt(&data->set.str[STRING_SSL_CRLFILE_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_SSL_CRLFILE], + va_arg(param, char *)); + break; + case CURLOPT_PROXY_CRLFILE: +@@ -1898,7 +1898,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + * Set Issuer certificate file + * to check certificates issuer + */ +- result = Curl_setstropt(&data->set.str[STRING_SSL_ISSUERCERT_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_SSL_ISSUERCERT], + va_arg(param, char *)); + break; + case CURLOPT_TELNETOPTIONS: +@@ -2449,9 +2449,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + break; + #ifdef USE_TLS_SRP + case CURLOPT_TLSAUTH_USERNAME: +- result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME], + va_arg(param, char *)); +- if(data->set.str[STRING_TLSAUTH_USERNAME_ORIG] && !data->set.ssl.authtype) ++ if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype) + data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ + break; + case CURLOPT_PROXY_TLSAUTH_USERNAME: +@@ -2462,9 +2462,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ + break; + case CURLOPT_TLSAUTH_PASSWORD: +- result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD], + va_arg(param, char *)); +- if(data->set.str[STRING_TLSAUTH_USERNAME_ORIG] && !data->set.ssl.authtype) ++ if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype) + data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ + break; + case CURLOPT_PROXY_TLSAUTH_PASSWORD: +diff --git a/lib/url.c b/lib/url.c +index bb9d107..a6bc012 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -496,7 +496,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) + */ + if(Curl_ssl_backend() != CURLSSLBACKEND_SCHANNEL) { + #if defined(CURL_CA_BUNDLE) +- result = Curl_setstropt(&set->str[STRING_SSL_CAFILE_ORIG], CURL_CA_BUNDLE); ++ result = Curl_setstropt(&set->str[STRING_SSL_CAFILE], CURL_CA_BUNDLE); + if(result) + return result; + +@@ -506,7 +506,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) + return result; + #endif + #if defined(CURL_CA_PATH) +- result = Curl_setstropt(&set->str[STRING_SSL_CAPATH_ORIG], CURL_CA_PATH); ++ result = Curl_setstropt(&set->str[STRING_SSL_CAPATH], CURL_CA_PATH); + if(result) + return result; + +@@ -4333,9 +4333,9 @@ static CURLcode create_conn(struct Curl_easy *data, + that will be freed as part of the Curl_easy struct, but all cloned + copies will be separately allocated. + */ +- data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_ORIG]; ++ data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH]; + data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY]; +- data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_ORIG]; ++ data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE]; + data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY]; + data->set.ssl.primary.random_file = data->set.str[STRING_SSL_RANDOM_FILE]; + data->set.proxy_ssl.primary.random_file = +@@ -4343,34 +4343,34 @@ static CURLcode create_conn(struct Curl_easy *data, + data->set.ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET]; + data->set.proxy_ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET]; + data->set.ssl.primary.cipher_list = +- data->set.str[STRING_SSL_CIPHER_LIST_ORIG]; ++ data->set.str[STRING_SSL_CIPHER_LIST]; + data->set.proxy_ssl.primary.cipher_list = + data->set.str[STRING_SSL_CIPHER_LIST_PROXY]; + data->set.ssl.primary.cipher_list13 = +- data->set.str[STRING_SSL_CIPHER13_LIST_ORIG]; ++ data->set.str[STRING_SSL_CIPHER13_LIST]; + data->set.proxy_ssl.primary.cipher_list13 = + data->set.str[STRING_SSL_CIPHER13_LIST_PROXY]; + +- data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG]; ++ data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE]; + data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY]; +- data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_ORIG]; ++ data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT]; + data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY]; +- data->set.ssl.cert = data->set.str[STRING_CERT_ORIG]; ++ data->set.ssl.cert = data->set.str[STRING_CERT]; + data->set.proxy_ssl.cert = data->set.str[STRING_CERT_PROXY]; +- data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE_ORIG]; ++ data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE]; + data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY]; +- data->set.ssl.key = data->set.str[STRING_KEY_ORIG]; ++ data->set.ssl.key = data->set.str[STRING_KEY]; + data->set.proxy_ssl.key = data->set.str[STRING_KEY_PROXY]; +- data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE_ORIG]; ++ data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE]; + data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY]; +- data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_ORIG]; ++ data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD]; + data->set.proxy_ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY]; +- data->set.ssl.primary.clientcert = data->set.str[STRING_CERT_ORIG]; ++ data->set.ssl.primary.clientcert = data->set.str[STRING_CERT]; + data->set.proxy_ssl.primary.clientcert = data->set.str[STRING_CERT_PROXY]; + #ifdef USE_TLS_SRP +- data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_ORIG]; ++ data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME]; + data->set.proxy_ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_PROXY]; +- data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_ORIG]; ++ data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD]; + data->set.proxy_ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_PROXY]; + #endif + +diff --git a/lib/urldata.h b/lib/urldata.h +index c70290a..1f8f364 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -1366,9 +1366,9 @@ struct DynamicStatic { + struct Curl_multi; /* declared and used only in multi.c */ + + enum dupstring { +- STRING_CERT_ORIG, /* client certificate file name */ ++ STRING_CERT, /* client certificate file name */ + STRING_CERT_PROXY, /* client certificate file name */ +- STRING_CERT_TYPE_ORIG, /* format for certificate (default: PEM)*/ ++ STRING_CERT_TYPE, /* format for certificate (default: PEM)*/ + STRING_CERT_TYPE_PROXY, /* format for certificate (default: PEM)*/ + STRING_COOKIE, /* HTTP cookie string to send */ + STRING_COOKIEJAR, /* dump all cookies to this file */ +@@ -1379,11 +1379,11 @@ enum dupstring { + STRING_FTP_ACCOUNT, /* ftp account data */ + STRING_FTP_ALTERNATIVE_TO_USER, /* command to send if USER/PASS fails */ + STRING_FTPPORT, /* port to send with the FTP PORT command */ +- STRING_KEY_ORIG, /* private key file name */ ++ STRING_KEY, /* private key file name */ + STRING_KEY_PROXY, /* private key file name */ +- STRING_KEY_PASSWD_ORIG, /* plain text private key password */ ++ STRING_KEY_PASSWD, /* plain text private key password */ + STRING_KEY_PASSWD_PROXY, /* plain text private key password */ +- STRING_KEY_TYPE_ORIG, /* format for private key (default: PEM) */ ++ STRING_KEY_TYPE, /* format for private key (default: PEM) */ + STRING_KEY_TYPE_PROXY, /* format for private key (default: PEM) */ + STRING_KRB_LEVEL, /* krb security level */ + STRING_NETRC_FILE, /* if not NULL, use this instead of trying to find +@@ -1393,22 +1393,22 @@ enum dupstring { + STRING_SET_RANGE, /* range, if used */ + STRING_SET_REFERER, /* custom string for the HTTP referer field */ + STRING_SET_URL, /* what original URL to work on */ +- STRING_SSL_CAPATH_ORIG, /* CA directory name (doesn't work on windows) */ ++ STRING_SSL_CAPATH, /* CA directory name (doesn't work on windows) */ + STRING_SSL_CAPATH_PROXY, /* CA directory name (doesn't work on windows) */ +- STRING_SSL_CAFILE_ORIG, /* certificate file to verify peer against */ ++ STRING_SSL_CAFILE, /* certificate file to verify peer against */ + STRING_SSL_CAFILE_PROXY, /* certificate file to verify peer against */ +- STRING_SSL_PINNEDPUBLICKEY_ORIG, /* public key file to verify peer against */ ++ STRING_SSL_PINNEDPUBLICKEY, /* public key file to verify peer against */ + STRING_SSL_PINNEDPUBLICKEY_PROXY, /* public key file to verify proxy */ +- STRING_SSL_CIPHER_LIST_ORIG, /* list of ciphers to use */ ++ STRING_SSL_CIPHER_LIST, /* list of ciphers to use */ + STRING_SSL_CIPHER_LIST_PROXY, /* list of ciphers to use */ +- STRING_SSL_CIPHER13_LIST_ORIG, /* list of TLS 1.3 ciphers to use */ ++ STRING_SSL_CIPHER13_LIST, /* list of TLS 1.3 ciphers to use */ + STRING_SSL_CIPHER13_LIST_PROXY, /* list of TLS 1.3 ciphers to use */ + STRING_SSL_EGDSOCKET, /* path to file containing the EGD daemon socket */ + STRING_SSL_RANDOM_FILE, /* path to file containing "random" data */ + STRING_USERAGENT, /* User-Agent string */ +- STRING_SSL_CRLFILE_ORIG, /* crl file to check certificate */ ++ STRING_SSL_CRLFILE, /* crl file to check certificate */ + STRING_SSL_CRLFILE_PROXY, /* crl file to check certificate */ +- STRING_SSL_ISSUERCERT_ORIG, /* issuer cert file to check certificate */ ++ STRING_SSL_ISSUERCERT, /* issuer cert file to check certificate */ + STRING_SSL_ISSUERCERT_PROXY, /* issuer cert file to check certificate */ + STRING_SSL_ENGINE, /* name of ssl engine */ + STRING_USERNAME, /* , if used */ +@@ -1433,9 +1433,9 @@ enum dupstring { + STRING_MAIL_AUTH, + + #ifdef USE_TLS_SRP +- STRING_TLSAUTH_USERNAME_ORIG, /* TLS auth */ ++ STRING_TLSAUTH_USERNAME, /* TLS auth */ + STRING_TLSAUTH_USERNAME_PROXY, /* TLS auth */ +- STRING_TLSAUTH_PASSWORD_ORIG, /* TLS auth */ ++ STRING_TLSAUTH_PASSWORD, /* TLS auth */ + STRING_TLSAUTH_PASSWORD_PROXY, /* TLS auth */ + #endif + STRING_BEARER, /* , if used */ +diff --git a/lib/vtls/cyassl.c b/lib/vtls/cyassl.c +index e10398a..ffd116d 100644 +--- a/lib/vtls/cyassl.c ++++ b/lib/vtls/cyassl.c +@@ -474,7 +474,7 @@ cyassl_connect_step2(struct connectdata *conn, + conn->http_proxy.host.dispname : conn->host.dispname; + const char * const pinnedpubkey = SSL_IS_PROXY() ? + data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : +- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; ++ data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + + conn->recv[sockindex] = cyassl_recv; + conn->send[sockindex] = cyassl_send; +diff --git a/lib/vtls/darwinssl.c b/lib/vtls/darwinssl.c +index 1aea0dc..572e8bf 100644 +--- a/lib/vtls/darwinssl.c ++++ b/lib/vtls/darwinssl.c +@@ -2449,9 +2449,9 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex) + connssl->connecting_state = ssl_connect_3; + + #ifdef DARWIN_SSL_PINNEDPUBKEY +- if(data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]) { ++ if(data->set.str[STRING_SSL_PINNEDPUBLICKEY]) { + CURLcode result = pkp_pin_peer_pubkey(data, BACKEND->ssl_ctx, +- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]); ++ data->set.str[STRING_SSL_PINNEDPUBLICKEY]); + if(result) { + failf(data, "SSL: public key does not match pinned public key!"); + return result; +diff --git a/lib/vtls/gskit.c b/lib/vtls/gskit.c +index a0b4960..b4c7b8a 100644 +--- a/lib/vtls/gskit.c ++++ b/lib/vtls/gskit.c +@@ -1136,7 +1136,7 @@ static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex) + + /* Check pinned public key. */ + ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : +- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; ++ data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + if(!result && ptr) { + curl_X509certificate x509; + curl_asn1Element *p; +diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c +index 207b0fd..c5eb948 100644 +--- a/lib/vtls/gtls.c ++++ b/lib/vtls/gtls.c +@@ -1329,7 +1329,7 @@ gtls_connect_step3(struct connectdata *conn, + } + + ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : +- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; ++ data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + if(ptr) { + result = pkp_pin_peer_pubkey(data, x509_cert, ptr); + if(result != CURLE_OK) { +diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c +index d7759dc..48010ae 100644 +--- a/lib/vtls/mbedtls.c ++++ b/lib/vtls/mbedtls.c +@@ -540,7 +540,7 @@ mbed_connect_step2(struct connectdata *conn, + const mbedtls_x509_crt *peercert; + const char * const pinnedpubkey = SSL_IS_PROXY() ? + data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : +- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; ++ data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + + #ifdef HAS_ALPN + const char *next_protocol; +diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c +index 89f8183..366bf9e 100644 +--- a/lib/vtls/nss.c ++++ b/lib/vtls/nss.c +@@ -2067,7 +2067,7 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex) + &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult; + const char * const pinnedpubkey = SSL_IS_PROXY() ? + data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : +- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; ++ data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + + + /* check timeout situation */ +diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c +index 35cd652..8c97c1d 100644 +--- a/lib/vtls/openssl.c ++++ b/lib/vtls/openssl.c +@@ -3388,7 +3388,7 @@ static CURLcode servercert(struct connectdata *conn, + result = CURLE_OK; + + ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : +- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; ++ data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + if(!result && ptr) { + result = pkp_pin_peer_pubkey(data, BACKEND->server_cert, ptr); + if(result) +diff --git a/lib/vtls/polarssl.c b/lib/vtls/polarssl.c +index 604cb4c..f284ad1 100644 +--- a/lib/vtls/polarssl.c ++++ b/lib/vtls/polarssl.c +@@ -459,7 +459,7 @@ polarssl_connect_step2(struct connectdata *conn, + char buffer[1024]; + const char * const pinnedpubkey = SSL_IS_PROXY() ? + data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : +- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; ++ data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + + + char errorbuf[128]; +diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c +index 8f6c301..95c060b 100644 +--- a/lib/vtls/schannel.c ++++ b/lib/vtls/schannel.c +@@ -1060,7 +1060,7 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) + + pubkey_ptr = SSL_IS_PROXY() ? + data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : +- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; ++ data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + if(pubkey_ptr) { + result = pkp_pin_peer_pubkey(conn, sockindex, pubkey_ptr); + if(result) { +-- +2.31.1 + + +From 040fa4f60f9b809972d51184dfa4980ba44d8b6b Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sat, 19 Jun 2021 00:42:28 +0200 +Subject: [PATCH 2/2] vtls: fix connection reuse checks for issuer cert and + case sensitivity + +CVE-2021-22924 + +Reported-by: Harry Sintonen +Bug: https://curl.se/docs/CVE-2021-22924.html + +Upstream-commit: 5ea3145850ebff1dc2b13d17440300a01ca38161 +Signed-off-by: Kamil Dudka +--- + lib/url.c | 5 +++-- + lib/urldata.h | 2 +- + lib/vtls/gtls.c | 10 +++++----- + lib/vtls/nss.c | 4 ++-- + lib/vtls/openssl.c | 12 ++++++------ + lib/vtls/vtls.c | 21 ++++++++++++++++----- + 6 files changed, 33 insertions(+), 21 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index a6bc012..4803653 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -4337,6 +4337,9 @@ static CURLcode create_conn(struct Curl_easy *data, + data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY]; + data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE]; + data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY]; ++ data->set.ssl.primary.issuercert = data->set.str[STRING_SSL_ISSUERCERT]; ++ data->set.proxy_ssl.primary.issuercert = ++ data->set.str[STRING_SSL_ISSUERCERT_PROXY]; + data->set.ssl.primary.random_file = data->set.str[STRING_SSL_RANDOM_FILE]; + data->set.proxy_ssl.primary.random_file = + data->set.str[STRING_SSL_RANDOM_FILE]; +@@ -4353,8 +4356,6 @@ static CURLcode create_conn(struct Curl_easy *data, + + data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE]; + data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY]; +- data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT]; +- data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY]; + data->set.ssl.cert = data->set.str[STRING_CERT]; + data->set.proxy_ssl.cert = data->set.str[STRING_CERT_PROXY]; + data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE]; +diff --git a/lib/urldata.h b/lib/urldata.h +index 1f8f364..72a36fb 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -223,6 +223,7 @@ struct ssl_primary_config { + bool sessionid; /* cache session IDs or not */ + char *CApath; /* certificate dir (doesn't work on windows) */ + char *CAfile; /* certificate to verify peer against */ ++ char *issuercert; /* optional issuer certificate filename */ + char *clientcert; + char *random_file; /* path to file containing "random" data */ + char *egdsocket; /* path to file containing the EGD daemon socket */ +@@ -238,7 +239,6 @@ struct ssl_config_data { + bool no_partialchain; /* don't accept partial certificate chains */ + long certverifyresult; /* result from the certificate verification */ + char *CRLfile; /* CRL to check certificate revocation */ +- char *issuercert;/* optional issuer certificate filename */ + curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */ + void *fsslctxp; /* parameter for call back */ + bool certinfo; /* gather lots of certificate info */ +diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c +index c5eb948..0cb59c8 100644 +--- a/lib/vtls/gtls.c ++++ b/lib/vtls/gtls.c +@@ -1002,7 +1002,7 @@ gtls_connect_step3(struct connectdata *conn, + if(!chainp) { + if(SSL_CONN_CONFIG(verifypeer) || + SSL_CONN_CONFIG(verifyhost) || +- SSL_SET_OPTION(issuercert)) { ++ SSL_CONN_CONFIG(issuercert)) { + #ifdef USE_TLS_SRP + if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP + && SSL_SET_OPTION(username) != NULL +@@ -1184,21 +1184,21 @@ gtls_connect_step3(struct connectdata *conn, + gnutls_x509_crt_t format */ + gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER); + +- if(SSL_SET_OPTION(issuercert)) { ++ if(SSL_CONN_CONFIG(issuercert)) { + gnutls_x509_crt_init(&x509_issuer); +- issuerp = load_file(SSL_SET_OPTION(issuercert)); ++ issuerp = load_file(SSL_CONN_CONFIG(issuercert)); + gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM); + rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer); + gnutls_x509_crt_deinit(x509_issuer); + unload_file(issuerp); + if(rc <= 0) { + failf(data, "server certificate issuer check failed (IssuerCert: %s)", +- SSL_SET_OPTION(issuercert)?SSL_SET_OPTION(issuercert):"none"); ++ SSL_CONN_CONFIG(issuercert)?SSL_CONN_CONFIG(issuercert):"none"); + gnutls_x509_crt_deinit(x509_cert); + return CURLE_SSL_ISSUER_ERROR; + } + infof(data, "\t server certificate issuer check OK (Issuer Cert: %s)\n", +- SSL_SET_OPTION(issuercert)?SSL_SET_OPTION(issuercert):"none"); ++ SSL_CONN_CONFIG(issuercert)?SSL_CONN_CONFIG(issuercert):"none"); + } + + size = sizeof(certbuf); +diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c +index 366bf9e..2d9581d 100644 +--- a/lib/vtls/nss.c ++++ b/lib/vtls/nss.c +@@ -2095,9 +2095,9 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex) + if(result) + goto error; + +- if(SSL_SET_OPTION(issuercert)) { ++ if(SSL_CONN_CONFIG(issuercert)) { + SECStatus ret = SECFailure; +- char *nickname = dup_nickname(data, SSL_SET_OPTION(issuercert)); ++ char *nickname = dup_nickname(data, SSL_CONN_CONFIG(issuercert)); + if(nickname) { + /* we support only nicknames in case of issuercert for now */ + ret = check_issuer_cert(BACKEND->handle, nickname); +diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c +index 8c97c1d..28eaa6d 100644 +--- a/lib/vtls/openssl.c ++++ b/lib/vtls/openssl.c +@@ -3311,11 +3311,11 @@ static CURLcode servercert(struct connectdata *conn, + deallocating the certificate. */ + + /* e.g. match issuer name with provided issuer certificate */ +- if(SSL_SET_OPTION(issuercert)) { +- if(BIO_read_filename(fp, SSL_SET_OPTION(issuercert)) <= 0) { ++ if(SSL_CONN_CONFIG(issuercert)) { ++ if(BIO_read_filename(fp, SSL_CONN_CONFIG(issuercert)) <= 0) { + if(strict) + failf(data, "SSL: Unable to open issuer cert (%s)", +- SSL_SET_OPTION(issuercert)); ++ SSL_CONN_CONFIG(issuercert)); + BIO_free(fp); + X509_free(BACKEND->server_cert); + BACKEND->server_cert = NULL; +@@ -3326,7 +3326,7 @@ static CURLcode servercert(struct connectdata *conn, + if(!issuer) { + if(strict) + failf(data, "SSL: Unable to read issuer cert (%s)", +- SSL_SET_OPTION(issuercert)); ++ SSL_CONN_CONFIG(issuercert)); + BIO_free(fp); + X509_free(issuer); + X509_free(BACKEND->server_cert); +@@ -3337,7 +3337,7 @@ static CURLcode servercert(struct connectdata *conn, + if(X509_check_issued(issuer, BACKEND->server_cert) != X509_V_OK) { + if(strict) + failf(data, "SSL: Certificate issuer check failed (%s)", +- SSL_SET_OPTION(issuercert)); ++ SSL_CONN_CONFIG(issuercert)); + BIO_free(fp); + X509_free(issuer); + X509_free(BACKEND->server_cert); +@@ -3346,7 +3346,7 @@ static CURLcode servercert(struct connectdata *conn, + } + + infof(data, " SSL certificate issuer check ok (%s)\n", +- SSL_SET_OPTION(issuercert)); ++ SSL_CONN_CONFIG(issuercert)); + X509_free(issuer); + } + +diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c +index b61c640..18672a5 100644 +--- a/lib/vtls/vtls.c ++++ b/lib/vtls/vtls.c +@@ -82,6 +82,15 @@ + else \ + dest->var = NULL; + ++static bool safecmp(char *a, char *b) ++{ ++ if(a && b) ++ return !strcmp(a, b); ++ else if(!a && !b) ++ return TRUE; /* match */ ++ return FALSE; /* no match */ ++} ++ + bool + Curl_ssl_config_matches(struct ssl_primary_config* data, + struct ssl_primary_config* needle) +@@ -91,11 +100,11 @@ Curl_ssl_config_matches(struct ssl_primary_config* data, + (data->verifypeer == needle->verifypeer) && + (data->verifyhost == needle->verifyhost) && + (data->verifystatus == needle->verifystatus) && +- Curl_safe_strcasecompare(data->CApath, needle->CApath) && +- Curl_safe_strcasecompare(data->CAfile, needle->CAfile) && +- Curl_safe_strcasecompare(data->clientcert, needle->clientcert) && +- Curl_safe_strcasecompare(data->random_file, needle->random_file) && +- Curl_safe_strcasecompare(data->egdsocket, needle->egdsocket) && ++ safecmp(data->CApath, needle->CApath) && ++ safecmp(data->CAfile, needle->CAfile) && ++ safecmp(data->clientcert, needle->clientcert) && ++ safecmp(data->random_file, needle->random_file) && ++ safecmp(data->egdsocket, needle->egdsocket) && + Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list) && + Curl_safe_strcasecompare(data->cipher_list13, needle->cipher_list13)) + return TRUE; +@@ -116,6 +125,7 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source, + + CLONE_STRING(CApath); + CLONE_STRING(CAfile); ++ CLONE_STRING(issuercert); + CLONE_STRING(clientcert); + CLONE_STRING(random_file); + CLONE_STRING(egdsocket); +@@ -129,6 +139,7 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config* sslc) + { + Curl_safefree(sslc->CApath); + Curl_safefree(sslc->CAfile); ++ Curl_safefree(sslc->issuercert); + Curl_safefree(sslc->clientcert); + Curl_safefree(sslc->random_file); + Curl_safefree(sslc->egdsocket); +-- +2.31.1 + diff --git a/SOURCES/0032-curl-7.61.1-CVE-2021-22898.patch b/SOURCES/0032-curl-7.61.1-CVE-2021-22898.patch new file mode 100644 index 0000000..42e1ccd --- /dev/null +++ b/SOURCES/0032-curl-7.61.1-CVE-2021-22898.patch @@ -0,0 +1,31 @@ +From ae2dc830fb37e9243dbdaf8b92e41df91f43b3f2 Mon Sep 17 00:00:00 2001 +From: Harry Sintonen +Date: Fri, 7 May 2021 13:09:57 +0200 +Subject: [PATCH] telnet: check sscanf() for correct number of matches + +CVE-2021-22898 + +Bug: https://curl.se/docs/CVE-2021-22898.html + +Upstream-commit: 39ce47f219b09c380b81f89fe54ac586c8db6bde +Signed-off-by: Kamil Dudka +--- + lib/telnet.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/telnet.c b/lib/telnet.c +index 1fc5af1..ea6bc71 100644 +--- a/lib/telnet.c ++++ b/lib/telnet.c +@@ -967,7 +967,7 @@ static void suboption(struct connectdata *conn) + size_t tmplen = (strlen(v->data) + 1); + /* Add the variable only if it fits */ + if(len + tmplen < (int)sizeof(temp)-6) { +- if(sscanf(v->data, "%127[^,],%127s", varname, varval)) { ++ if(sscanf(v->data, "%127[^,],%127s", varname, varval) == 2) { + snprintf((char *)&temp[len], sizeof(temp) - len, + "%c%s%c%s", CURL_NEW_ENV_VAR, varname, + CURL_NEW_ENV_VALUE, varval); +-- +2.31.1 + diff --git a/SOURCES/0033-curl-7.61.1-CVE-2021-22925.patch b/SOURCES/0033-curl-7.61.1-CVE-2021-22925.patch new file mode 100644 index 0000000..391abbd --- /dev/null +++ b/SOURCES/0033-curl-7.61.1-CVE-2021-22925.patch @@ -0,0 +1,47 @@ +From 2fbbf282e42ae476459f7efe68a88dcb63dcc43b Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sat, 12 Jun 2021 18:25:15 +0200 +Subject: [PATCH] telnet: fix option parser to not send uninitialized contents + +CVE-2021-22925 + +Reported-by: Red Hat Product Security +Bug: https://curl.se/docs/CVE-2021-22925.html + +Upstream-commit: 894f6ec730597eb243618d33cc84d71add8d6a8a +Signed-off-by: Kamil Dudka +--- + lib/telnet.c | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +diff --git a/lib/telnet.c b/lib/telnet.c +index ea6bc71..f8428b8 100644 +--- a/lib/telnet.c ++++ b/lib/telnet.c +@@ -967,12 +967,17 @@ static void suboption(struct connectdata *conn) + size_t tmplen = (strlen(v->data) + 1); + /* Add the variable only if it fits */ + if(len + tmplen < (int)sizeof(temp)-6) { +- if(sscanf(v->data, "%127[^,],%127s", varname, varval) == 2) { +- snprintf((char *)&temp[len], sizeof(temp) - len, +- "%c%s%c%s", CURL_NEW_ENV_VAR, varname, +- CURL_NEW_ENV_VALUE, varval); +- len += tmplen; +- } ++ int rv; ++ char sep[2] = ""; ++ varval[0] = 0; ++ rv = sscanf(v->data, "%127[^,]%1[,]%127s", varname, sep, varval); ++ if(rv == 1) ++ len += snprintf((char *)&temp[len], sizeof(temp) - len, ++ "%c%s", CURL_NEW_ENV_VAR, varname); ++ else if(rv >= 2) ++ len += snprintf((char *)&temp[len], sizeof(temp) - len, ++ "%c%s%c%s", CURL_NEW_ENV_VAR, varname, ++ CURL_NEW_ENV_VALUE, varval); + } + } + snprintf((char *)&temp[len], sizeof(temp) - len, +-- +2.31.1 + diff --git a/SOURCES/0034-curl-7.61.1-CVE-2021-22946.patch b/SOURCES/0034-curl-7.61.1-CVE-2021-22946.patch new file mode 100644 index 0000000..3eec2ee --- /dev/null +++ b/SOURCES/0034-curl-7.61.1-CVE-2021-22946.patch @@ -0,0 +1,331 @@ +From 03ca8c6faca7de6628f9cbec3001ec6466c88d07 Mon Sep 17 00:00:00 2001 +From: Patrick Monnerat +Date: Wed, 8 Sep 2021 11:56:22 +0200 +Subject: [PATCH] ftp,imap,pop3: do not ignore --ssl-reqd + +In imap and pop3, check if TLS is required even when capabilities +request has failed. + +In ftp, ignore preauthentication (230 status of server greeting) if TLS +is required. + +Bug: https://curl.se/docs/CVE-2021-22946.html + +CVE-2021-22946 + +Upstream-commit: 364f174724ef115c63d5e5dc1d3342c8a43b1cca +Signed-off-by: Kamil Dudka +--- + lib/ftp.c | 9 ++++--- + lib/imap.c | 24 ++++++++---------- + lib/pop3.c | 33 +++++++++++------------- + tests/data/Makefile.inc | 2 ++ + tests/data/test984 | 56 +++++++++++++++++++++++++++++++++++++++++ + tests/data/test985 | 54 +++++++++++++++++++++++++++++++++++++++ + tests/data/test986 | 53 ++++++++++++++++++++++++++++++++++++++ + 7 files changed, 195 insertions(+), 36 deletions(-) + create mode 100644 tests/data/test984 + create mode 100644 tests/data/test985 + create mode 100644 tests/data/test986 + +diff --git a/lib/ftp.c b/lib/ftp.c +index 71c9642..30ebeaa 100644 +--- a/lib/ftp.c ++++ b/lib/ftp.c +@@ -2621,9 +2621,12 @@ static CURLcode ftp_statemach_act(struct connectdata *conn) + /* we have now received a full FTP server response */ + switch(ftpc->state) { + case FTP_WAIT220: +- if(ftpcode == 230) +- /* 230 User logged in - already! */ +- return ftp_state_user_resp(conn, ftpcode, ftpc->state); ++ if(ftpcode == 230) { ++ /* 230 User logged in - already! Take as 220 if TLS required. */ ++ if(data->set.use_ssl <= CURLUSESSL_TRY || ++ conn->ssl[FIRSTSOCKET].use) ++ return ftp_state_user_resp(conn, ftpcode, ftpc->state); ++ } + else if(ftpcode != 220) { + failf(data, "Got a %03d ftp-server response when 220 was expected", + ftpcode); +diff --git a/lib/imap.c b/lib/imap.c +index bda23a5..7e159d4 100644 +--- a/lib/imap.c ++++ b/lib/imap.c +@@ -910,22 +910,18 @@ static CURLcode imap_state_capability_resp(struct connectdata *conn, + line += wordlen; + } + } +- else if(imapcode == IMAP_RESP_OK) { +- if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) { +- /* We don't have a SSL/TLS connection yet, but SSL is requested */ +- if(imapc->tls_supported) +- /* Switch to TLS connection now */ +- result = imap_perform_starttls(conn); +- else if(data->set.use_ssl == CURLUSESSL_TRY) +- /* Fallback and carry on with authentication */ +- result = imap_perform_authentication(conn); +- else { +- failf(data, "STARTTLS not supported."); +- result = CURLE_USE_SSL_FAILED; +- } ++ else if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) { ++ /* PREAUTH is not compatible with STARTTLS. */ ++ if(imapcode == IMAP_RESP_OK && imapc->tls_supported && !imapc->preauth) { ++ /* Switch to TLS connection now */ ++ result = imap_perform_starttls(conn); + } +- else ++ else if(data->set.use_ssl <= CURLUSESSL_TRY) + result = imap_perform_authentication(conn); ++ else { ++ failf(data, "STARTTLS not available."); ++ result = CURLE_USE_SSL_FAILED; ++ } + } + else + result = imap_perform_authentication(conn); +diff --git a/lib/pop3.c b/lib/pop3.c +index 04cc887..3e916ce 100644 +--- a/lib/pop3.c ++++ b/lib/pop3.c +@@ -718,28 +718,23 @@ static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code, + } + } + } +- else if(pop3code == '+') { +- if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) { +- /* We don't have a SSL/TLS connection yet, but SSL is requested */ +- if(pop3c->tls_supported) +- /* Switch to TLS connection now */ +- result = pop3_perform_starttls(conn); +- else if(data->set.use_ssl == CURLUSESSL_TRY) +- /* Fallback and carry on with authentication */ +- result = pop3_perform_authentication(conn); +- else { +- failf(data, "STLS not supported."); +- result = CURLE_USE_SSL_FAILED; +- } +- } +- else +- result = pop3_perform_authentication(conn); +- } + else { + /* Clear text is supported when CAPA isn't recognised */ +- pop3c->authtypes |= POP3_TYPE_CLEARTEXT; ++ if(pop3code != '+') ++ pop3c->authtypes |= POP3_TYPE_CLEARTEXT; + +- result = pop3_perform_authentication(conn); ++ if(!data->set.use_ssl || conn->ssl[FIRSTSOCKET].use) ++ result = pop3_perform_authentication(conn); ++ else if(pop3code == '+' && pop3c->tls_supported) ++ /* Switch to TLS connection now */ ++ result = pop3_perform_starttls(conn); ++ else if(data->set.use_ssl <= CURLUSESSL_TRY) ++ /* Fallback and carry on with authentication */ ++ result = pop3_perform_authentication(conn); ++ else { ++ failf(data, "STLS not supported."); ++ result = CURLE_USE_SSL_FAILED; ++ } + } + + return result; +diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc +index ef9252b..1ba482b 100644 +--- a/tests/data/Makefile.inc ++++ b/tests/data/Makefile.inc +@@ -108,6 +108,8 @@ test927 test928 test929 test930 test931 test932 test933 test934 test935 \ + test936 test937 test938 test939 test940 test941 test942 test943 test944 \ + test945 test946 test947 test948 test949 test950 test951 test952 \ + \ ++test984 test985 test986 \ ++\ + test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 \ + test1008 test1009 test1010 test1011 test1012 test1013 test1014 test1015 \ + test1016 test1017 test1018 test1019 test1020 test1021 test1022 test1023 \ +diff --git a/tests/data/test984 b/tests/data/test984 +new file mode 100644 +index 0000000..e573f23 +--- /dev/null ++++ b/tests/data/test984 +@@ -0,0 +1,56 @@ ++ ++ ++ ++IMAP ++STARTTLS ++ ++ ++ ++# ++# Server-side ++ ++ ++REPLY CAPABILITY A001 BAD Not implemented ++ ++ ++ ++# ++# Client-side ++ ++ ++SSL ++ ++ ++imap ++ ++ ++IMAP require STARTTLS with failing capabilities ++ ++ ++imap://%HOSTIP:%IMAPPORT/%TESTNUMBER -T log/upload%TESTNUMBER -u user:secret --ssl-reqd ++ ++ ++Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST) ++From: Fred Foobar ++Subject: afternoon meeting ++To: joe@example.com ++Message-Id: ++MIME-Version: 1.0 ++Content-Type: TEXT/PLAIN; CHARSET=US-ASCII ++ ++Hello Joe, do you think we can meet at 3:30 tomorrow? ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++# 64 is CURLE_USE_SSL_FAILED ++ ++64 ++ ++ ++A001 CAPABILITY ++ ++ ++ +diff --git a/tests/data/test985 b/tests/data/test985 +new file mode 100644 +index 0000000..d0db4aa +--- /dev/null ++++ b/tests/data/test985 +@@ -0,0 +1,54 @@ ++ ++ ++ ++POP3 ++STARTTLS ++ ++ ++ ++# ++# Server-side ++ ++ ++REPLY CAPA -ERR Not implemented ++ ++ ++From: me@somewhere ++To: fake@nowhere ++ ++body ++ ++-- ++ yours sincerely ++ ++ ++ ++# ++# Client-side ++ ++ ++SSL ++ ++ ++pop3 ++ ++ ++POP3 require STARTTLS with failing capabilities ++ ++ ++pop3://%HOSTIP:%POP3PORT/%TESTNUMBER -u user:secret --ssl-reqd ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++# 64 is CURLE_USE_SSL_FAILED ++ ++64 ++ ++ ++CAPA ++ ++ ++ +diff --git a/tests/data/test986 b/tests/data/test986 +new file mode 100644 +index 0000000..a709437 +--- /dev/null ++++ b/tests/data/test986 +@@ -0,0 +1,53 @@ ++ ++ ++ ++FTP ++STARTTLS ++ ++ ++ ++# ++# Server-side ++ ++ ++REPLY welcome 230 Welcome ++REPLY AUTH 500 unknown command ++ ++ ++ ++# Client-side ++ ++ ++SSL ++ ++ ++ftp ++ ++ ++FTP require STARTTLS while preauthenticated ++ ++ ++data ++ to ++ see ++that FTPS ++works ++ so does it? ++ ++ ++--ssl-reqd --ftp-ssl-control ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -T log/test%TESTNUMBER.txt -u user:secret ++ ++ ++ ++# Verify data after the test has been "shot" ++ ++# 64 is CURLE_USE_SSL_FAILED ++ ++64 ++ ++ ++AUTH SSL ++AUTH TLS ++ ++ ++ +-- +2.31.1 + diff --git a/SOURCES/0035-curl-7.61.1-CVE-2021-22947.patch b/SOURCES/0035-curl-7.61.1-CVE-2021-22947.patch new file mode 100644 index 0000000..13eb441 --- /dev/null +++ b/SOURCES/0035-curl-7.61.1-CVE-2021-22947.patch @@ -0,0 +1,354 @@ +From a1ec463c8207bde97b3575d12e396e999a55a8d0 Mon Sep 17 00:00:00 2001 +From: Patrick Monnerat +Date: Tue, 7 Sep 2021 13:26:42 +0200 +Subject: [PATCH] ftp,imap,pop3,smtp: reject STARTTLS server response + pipelining + +If a server pipelines future responses within the STARTTLS response, the +former are preserved in the pingpong cache across TLS negotiation and +used as responses to the encrypted commands. + +This fix detects pipelined STARTTLS responses and rejects them with an +error. + +CVE-2021-22947 + +Bug: https://curl.se/docs/CVE-2021-22947.html + +Upstream-commit: 8ef147c43646e91fdaad5d0e7b60351f842e5c68 +Signed-off-by: Kamil Dudka +--- + lib/ftp.c | 3 +++ + lib/imap.c | 4 +++ + lib/pop3.c | 4 +++ + lib/smtp.c | 4 +++ + tests/data/Makefile.inc | 2 +- + tests/data/test980 | 52 ++++++++++++++++++++++++++++++++++++ + tests/data/test981 | 59 +++++++++++++++++++++++++++++++++++++++++ + tests/data/test982 | 57 +++++++++++++++++++++++++++++++++++++++ + tests/data/test983 | 52 ++++++++++++++++++++++++++++++++++++ + 9 files changed, 236 insertions(+), 1 deletion(-) + create mode 100644 tests/data/test980 + create mode 100644 tests/data/test981 + create mode 100644 tests/data/test982 + create mode 100644 tests/data/test983 + +diff --git a/lib/ftp.c b/lib/ftp.c +index 71f998e..e920138 100644 +--- a/lib/ftp.c ++++ b/lib/ftp.c +@@ -2688,6 +2688,9 @@ static CURLcode ftp_statemach_act(struct connectdata *conn) + case FTP_AUTH: + /* we have gotten the response to a previous AUTH command */ + ++ if(pp->cache_size) ++ return CURLE_WEIRD_SERVER_REPLY; /* Forbid pipelining in response. */ ++ + /* RFC2228 (page 5) says: + * + * If the server is willing to accept the named security mechanism, +diff --git a/lib/imap.c b/lib/imap.c +index feb7445..09bc5d6 100644 +--- a/lib/imap.c ++++ b/lib/imap.c +@@ -939,6 +939,10 @@ static CURLcode imap_state_starttls_resp(struct connectdata *conn, + + (void)instate; /* no use for this yet */ + ++ /* Pipelining in response is forbidden. */ ++ if(conn->proto.imapc.pp.cache_size) ++ return CURLE_WEIRD_SERVER_REPLY; ++ + if(imapcode != IMAP_RESP_OK) { + if(data->set.use_ssl != CURLUSESSL_TRY) { + failf(data, "STARTTLS denied"); +diff --git a/lib/pop3.c b/lib/pop3.c +index 7698d1c..dccfced 100644 +--- a/lib/pop3.c ++++ b/lib/pop3.c +@@ -750,6 +750,10 @@ static CURLcode pop3_state_starttls_resp(struct connectdata *conn, + + (void)instate; /* no use for this yet */ + ++ /* Pipelining in response is forbidden. */ ++ if(conn->proto.pop3c.pp.cache_size) ++ return CURLE_WEIRD_SERVER_REPLY; ++ + if(pop3code != '+') { + if(data->set.use_ssl != CURLUSESSL_TRY) { + failf(data, "STARTTLS denied"); +diff --git a/lib/smtp.c b/lib/smtp.c +index 1defb25..1f89777 100644 +--- a/lib/smtp.c ++++ b/lib/smtp.c +@@ -685,6 +685,10 @@ static CURLcode smtp_state_starttls_resp(struct connectdata *conn, + + (void)instate; /* no use for this yet */ + ++ /* Pipelining in response is forbidden. */ ++ if(conn->proto.smtpc.pp.cache_size) ++ return CURLE_WEIRD_SERVER_REPLY; ++ + if(smtpcode != 220) { + if(data->set.use_ssl != CURLUSESSL_TRY) { + failf(data, "STARTTLS denied, code %d", smtpcode); +diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc +index 163ce59..42b0569 100644 +--- a/tests/data/Makefile.inc ++++ b/tests/data/Makefile.inc +@@ -108,7 +108,7 @@ test927 test928 test929 test930 test931 test932 test933 test934 test935 \ + test936 test937 test938 test939 test940 test941 test942 test943 test944 \ + test945 test946 test947 test948 test949 test950 test951 test952 \ + \ +-test984 test985 test986 \ ++test980 test981 test982 test983 test984 test985 test986 \ + \ + test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 \ + test1008 test1009 test1010 test1011 test1012 test1013 test1014 test1015 \ +diff --git a/tests/data/test980 b/tests/data/test980 +new file mode 100644 +index 0000000..97567f8 +--- /dev/null ++++ b/tests/data/test980 +@@ -0,0 +1,52 @@ ++ ++ ++ ++SMTP ++STARTTLS ++ ++ ++ ++# ++# Server-side ++ ++ ++CAPA STARTTLS ++AUTH PLAIN ++REPLY STARTTLS 454 currently unavailable\r\n235 Authenticated\r\n250 2.1.0 Sender ok\r\n250 2.1.5 Recipient ok\r\n354 Enter mail\r\n250 2.0.0 Accepted ++REPLY AUTH 535 5.7.8 Authentication credentials invalid ++ ++ ++ ++# ++# Client-side ++ ++ ++SSL ++ ++ ++smtp ++ ++ ++SMTP STARTTLS pipelined server response ++ ++ ++mail body ++ ++ ++smtp://%HOSTIP:%SMTPPORT/%TESTNUMBER --mail-rcpt recipient@example.com --mail-from sender@example.com -u user:secret --ssl --sasl-ir -T - ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++# 8 is CURLE_WEIRD_SERVER_REPLY ++ ++8 ++ ++ ++EHLO %TESTNUMBER ++STARTTLS ++ ++ ++ +diff --git a/tests/data/test981 b/tests/data/test981 +new file mode 100644 +index 0000000..2b98ce4 +--- /dev/null ++++ b/tests/data/test981 +@@ -0,0 +1,59 @@ ++ ++ ++ ++IMAP ++STARTTLS ++ ++ ++ ++# ++# Server-side ++ ++ ++CAPA STARTTLS ++REPLY STARTTLS A002 BAD currently unavailable\r\nA003 OK Authenticated\r\nA004 OK Accepted ++REPLY LOGIN A003 BAD Authentication credentials invalid ++ ++ ++ ++# ++# Client-side ++ ++ ++SSL ++ ++ ++imap ++ ++ ++IMAP STARTTLS pipelined server response ++ ++ ++imap://%HOSTIP:%IMAPPORT/%TESTNUMBER -T log/upload%TESTNUMBER -u user:secret --ssl ++ ++ ++Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST) ++From: Fred Foobar ++Subject: afternoon meeting ++To: joe@example.com ++Message-Id: ++MIME-Version: 1.0 ++Content-Type: TEXT/PLAIN; CHARSET=US-ASCII ++ ++Hello Joe, do you think we can meet at 3:30 tomorrow? ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++# 8 is CURLE_WEIRD_SERVER_REPLY ++ ++8 ++ ++ ++A001 CAPABILITY ++A002 STARTTLS ++ ++ ++ +diff --git a/tests/data/test982 b/tests/data/test982 +new file mode 100644 +index 0000000..9e07cc0 +--- /dev/null ++++ b/tests/data/test982 +@@ -0,0 +1,57 @@ ++ ++ ++ ++POP3 ++STARTTLS ++ ++ ++ ++# ++# Server-side ++ ++ ++CAPA STLS USER ++REPLY STLS -ERR currently unavailable\r\n+OK user accepted\r\n+OK authenticated ++REPLY PASS -ERR Authentication credentials invalid ++ ++ ++From: me@somewhere ++To: fake@nowhere ++ ++body ++ ++-- ++ yours sincerely ++ ++ ++ ++# ++# Client-side ++ ++ ++SSL ++ ++ ++pop3 ++ ++ ++POP3 STARTTLS pipelined server response ++ ++ ++pop3://%HOSTIP:%POP3PORT/%TESTNUMBER -u user:secret --ssl ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++# 8 is CURLE_WEIRD_SERVER_REPLY ++ ++8 ++ ++ ++CAPA ++STLS ++ ++ ++ +diff --git a/tests/data/test983 b/tests/data/test983 +new file mode 100644 +index 0000000..300ec45 +--- /dev/null ++++ b/tests/data/test983 +@@ -0,0 +1,52 @@ ++ ++ ++ ++FTP ++STARTTLS ++ ++ ++ ++# ++# Server-side ++ ++ ++REPLY AUTH 500 unknown command\r\n500 unknown command\r\n331 give password\r\n230 Authenticated\r\n257 "/"\r\n200 OK\r\n200 OK\r\n200 OK\r\n226 Transfer complete ++REPLY PASS 530 Login incorrect ++ ++ ++ ++# Client-side ++ ++ ++SSL ++ ++ ++ftp ++ ++ ++FTP STARTTLS pipelined server response ++ ++ ++data ++ to ++ see ++that FTPS ++works ++ so does it? ++ ++ ++--ssl --ftp-ssl-control ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -T log/test%TESTNUMBER.txt -u user:secret -P %CLIENTIP ++ ++ ++ ++# Verify data after the test has been "shot" ++ ++# 8 is CURLE_WEIRD_SERVER_REPLY ++ ++8 ++ ++ ++AUTH SSL ++ ++ ++ +-- +2.31.1 + diff --git a/SOURCES/0105-curl-7.61.1-test-ports.patch b/SOURCES/0105-curl-7.61.1-test-ports.patch new file mode 100644 index 0000000..e536586 --- /dev/null +++ b/SOURCES/0105-curl-7.61.1-test-ports.patch @@ -0,0 +1,71 @@ +From e6507a9abbfd4ac93ea3053c8f3385a2405f19d8 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Fri, 29 Jan 2021 11:34:49 +0100 +Subject: [PATCH] tests: do not hard-wire ports of test servers + +--- + tests/data/test1448 | 4 ++-- + tests/data/test651 | 2 +- + tests/data/test653 | 4 ++-- + 3 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/tests/data/test1448 b/tests/data/test1448 +index e04f47b..5022ef9 100644 +--- a/tests/data/test1448 ++++ b/tests/data/test1448 +@@ -17,7 +17,7 @@ HTTP/1.1 302 OK swsbounce + Date: Thu, 09 Nov 2010 14:49:00 GMT + Content-Length: 9 + Content-Type: text/plain +-Location: http://åäö.se:8990/14480001 ++Location: http://åäö.se:%HTTPPORT/14480001 + + redirect + +@@ -52,7 +52,7 @@ Redirect following to UTF-8 IDN host name + + + +-http://åäö.se:%HTTPPORT/1448 --resolve xn--4cab6c.se:%HTTPPORT:%HOSTIP -L --connect-to %HOSTIP:8990:%HOSTIP:%HTTPPORT ++http://åäö.se:%HTTPPORT/1448 --resolve xn--4cab6c.se:%HTTPPORT:%HOSTIP -L --connect-to %HOSTIP:%HTTPPORT:%HOSTIP:%HTTPPORT + + + +diff --git a/tests/data/test651 b/tests/data/test651 +index b00ca5d..8d47c9f 100644 +--- a/tests/data/test651 ++++ b/tests/data/test651 +@@ -57,7 +57,7 @@ s/boundary=------------------------[a-z0-9]*/boundary=-------------------------- + # (5*12) == 60 bytes less + + POST /651 HTTP/1.1 +-Host: 127.0.0.1:8990 ++Host: 127.0.0.1:%HTTPPORT + Accept: */* + Content-Length: 17139 + Content-Type: multipart/form-data; boundary=---------------------------- +diff --git a/tests/data/test653 b/tests/data/test653 +index d620b57..492d551 100644 +--- a/tests/data/test653 ++++ b/tests/data/test653 +@@ -67,7 +67,7 @@ s/boundary=------------------------[a-z0-9]*/boundary=-------------------------- + # (5*12) == 60 bytes less + + POST /653 HTTP/1.1 +-Host: 127.0.0.1:8990 ++Host: 127.0.0.1:%HTTPPORT + Accept: */* + Content-Length: 150 + Content-Type: multipart/form-data; boundary=---------------------------- +@@ -78,7 +78,7 @@ Content-Disposition: form-data; name="name" + short value + -------------------------------- + POST /653 HTTP/1.1 +-Host: 127.0.0.1:8990 ++Host: 127.0.0.1:%HTTPPORT + Accept: */* + Content-Length: 167 + Content-Type: multipart/form-data; boundary=---------------------------- +-- +2.26.2 + diff --git a/SPECS/curl.spec b/SPECS/curl.spec index f9a3dc7..81fb8a1 100644 --- a/SPECS/curl.spec +++ b/SPECS/curl.spec @@ -7,7 +7,7 @@ Summary: A utility for getting files from remote servers (FTP, HTTP, and others) Name: %{?scl_prefix}curl Version: 7.61.1 -Release: 11%{?dist} +Release: 22%{?dist} License: MIT Source: https://curl.haxx.se/download/%{pkg_name}-%{version}.tar.xz @@ -49,6 +49,63 @@ Patch11: 0011-curl-7.61.1-CVE-2019-3823.patch # do not let libssh create a new socket for SCP/SFTP (#1669156) Patch14: 0014-curl-7.61.1-libssh-socket.patch +# fix TFTP receive buffer overflow (CVE-2019-5436) +Patch17: 0017-curl-7.64.0-CVE-2019-5436.patch + +# fix heap buffer overflow in function tftp_receive_packet() (CVE-2019-5482) +Patch18: 0018-curl-7.65.3-CVE-2019-5482.patch + +# double free due to subsequent call of realloc() (CVE-2019-5481) +Patch19: 0019-curl-7.65.3-CVE-2019-5481.patch + +# load built-in openssl engines (#1854369) +Patch20: 0020-curl-7.61.1-openssl-engines.patch + +# avoid overwriting a local file with -J (CVE-2020-8177) +Patch21: 0021-curl-7.61.1-CVE-2020-8177.patch + +# libcurl: wrong connect-only connection (CVE-2020-8231) +Patch22: 0022-curl-7.61.1-CVE-2020-8231.patch + +# do not crash when HTTPS_PROXY and NO_PROXY are used together (#1873327) +Patch23: 0023-curl-7.61.1-no-https-proxy-crash.patch + +# validate an ssl connection using an intermediate certificate (#1895355) +Patch24: 0024-curl-7.61.1-openssl-partial-chain.patch + +# curl: trusting FTP PASV responses (CVE-2020-8284) +Patch25: 0025-curl-7.61.1-CVE-2020-8284.patch + +# libcurl: FTP wildcard stack overflow (CVE-2020-8285) +Patch26: 0026-curl-7.61.1-CVE-2020-8285.patch + +# curl: Inferior OCSP verification (CVE-2020-8286) +Patch27: 0027-curl-7.61.1-CVE-2020-8286.patch + +# http: send payload when (proxy) authentication is done (#1918692) +Patch28: 0028-curl-7.61.1-http-auth-payload.patch + +# prevent automatic referer from leaking credentials (CVE-2021-22876) +Patch29: 0029-curl-7.61.1-CVE-2021-22876.patch + +# make `curl --head file://` work as expected (#1947493) +Patch30: 0030-curl-7.61.1-file-head.patch + +# fix bad connection reuse due to flawed path name checks (CVE-2021-22924) +Patch31: 0031-curl-7.61.1-CVE-2021-22924.patch + +# fix TELNET stack contents disclosure (CVE-2021-22898) +Patch32: 0032-curl-7.61.1-CVE-2021-22898.patch + +# fix TELNET stack contents disclosure again (CVE-2021-22925) +Patch33: 0033-curl-7.61.1-CVE-2021-22925.patch + +# fix protocol downgrade required TLS bypass (CVE-2021-22946) +Patch34: 0034-curl-7.61.1-CVE-2021-22946.patch + +# fix STARTTLS protocol injection via MITM (CVE-2021-22947) +Patch35: 0035-curl-7.61.1-CVE-2021-22947.patch + # patch making libcurl multilib ready Patch101: 0101-curl-7.32.0-multilib.patch @@ -61,11 +118,15 @@ Patch103: 0103-curl-7.59.0-python3.patch # use localhost6 instead of ip6-localhost in the curl test-suite Patch104: 0104-curl-7.19.7-localhost6.patch +# tests: do not hard-wire ports of test servers +Patch105: 0105-curl-7.61.1-test-ports.patch + # migrate more to Python3 -Patch105: python-2-to-3.patch +Patch106: python-2-to-3.patch Provides: %{?scl_prefix}curl-full = %{version}-%{release} Provides: %{?scl_prefix}webclient + URL: https://curl.haxx.se/ BuildRequires: automake #BuildRequires: brotli-devel @@ -148,7 +209,7 @@ resume, proxy tunneling and a busload of other useful tricks. %package -n %{?scl_prefix}libcurl Summary: A library for getting files from web servers -#Requires: libpsl%{?_isa} >= %{libpsl_version} +#Requires: libpsl%%{?_isa} >= %%{libpsl_version} Requires: libssh2%{?_isa} >= %{libssh_version} Requires: openssl-libs%{?_isa} >= 1:%{openssl_version} Provides: %{?scl_prefix}libcurl-full = %{version}-%{release} @@ -199,7 +260,34 @@ git apply %{PATCH4} %patch102 -p1 %patch103 -p1 %patch104 -p1 + +# use different port range for 32bit and 64bit builds, thus make it possible +# to run both the builds in parallel on the same machine %patch105 -p1 +sed -e 's|%%HTTPPORT|%{?__isa_bits}90|g' -i tests/data/test1448 + +%patch106 -p1 + +# upstream patches +%patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 +%patch21 -p1 +%patch22 -p1 +%patch23 -p1 +%patch24 -p1 +%patch25 -p1 +%patch26 -p1 +%patch27 -p1 +%patch28 -p1 +%patch29 -p1 +%patch30 -p1 +%patch31 -p1 +%patch32 -p1 +%patch33 -p1 +%patch34 -p1 +%patch35 -p1 # make tests/*.py use Python 3 sed -e '1 s|^#!/.*python|#!%{__python3}|' -i tests/*.py @@ -236,6 +324,7 @@ export common_configure_opts=" \ --enable-symbol-hiding \ --enable-ipv6 \ --enable-threaded-resolver \ + --without-libmetalink \ --with-gssapi \ --with-ssl --with-ca-bundle=%{_root_sysconfdir}/pki/tls/certs/ca-bundle.crt" @@ -278,7 +367,10 @@ export OPENSSL_SYSTEM_CIPHERS_OVERRIDE=XXX export OPENSSL_CONF= # run the upstream test-suite -srcdir=../../tests perl -I../../tests ../../tests/runtests.pl -a -p -v '!flaky' +# use different port range for 32bit and 64bit builds, thus make it possible +# to run both the builds in parallel on the same machine +export srcdir=../../tests +perl -I${srcdir} ${srcdir}/runtests.pl -b%{?__isa_bits}90 -a -p -v '!flaky' %install # install libcurl.m4 @@ -326,6 +418,47 @@ rm -f ${RPM_BUILD_ROOT}%{_libdir}/libcurl.la %{_datadir}/aclocal/libcurl.m4 %changelog +* Fri Sep 17 2021 Kamil Dudka - 7.61.1-22 +- fix STARTTLS protocol injection via MITM (CVE-2021-22947) +- fix protocol downgrade required TLS bypass (CVE-2021-22946) + +* Thu Aug 05 2021 Kamil Dudka - 7.61.1-21 +- fix TELNET stack contents disclosure again (CVE-2021-22925) +- fix TELNET stack contents disclosure (CVE-2021-22898) +- fix bad connection reuse due to flawed path name checks (CVE-2021-22924) +- disable metalink support to fix the following vulnerabilities + CVE-2021-22923 - metalink download sends credentials + CVE-2021-22922 - wrong content via metalink not discarded + +* Fri Apr 23 2021 Kamil Dudka - 7.61.1-20 +- fix a cppcheck's false positive in 0029-curl-7.61.1-CVE-2021-22876.patch + +* Fri Apr 23 2021 Kamil Dudka - 7.61.1-19 +- make `curl --head file://` work as expected (#1947493) +- prevent automatic referer from leaking credentials (CVE-2021-22876) + +* Thu Jan 28 2021 Kamil Dudka - 7.61.1-18 +- http: send payload when (proxy) authentication is done (#1918692) +- curl: Inferior OCSP verification (CVE-2020-8286) +- libcurl: FTP wildcard stack overflow (CVE-2020-8285) +- curl: trusting FTP PASV responses (CVE-2020-8284) + +* Thu Nov 12 2020 Kamil Dudka - 7.61.1-17 +- validate an ssl connection using an intermediate certificate (#1895355) + +* Fri Nov 06 2020 Kamil Dudka - 7.61.1-16 +- fix multiarch conflicts in libcurl-minimal (#1895391) + +* Tue Nov 03 2020 Kamil Dudka - 7.61.1-15 +- do not crash when HTTPS_PROXY and NO_PROXY are used together (#1873327) +- libcurl: wrong connect-only connection (CVE-2020-8231) + +* Tue Jul 28 2020 Kamil Dudka - 7.61.1-14 +- avoid overwriting a local file with -J (CVE-2020-8177) + +* Wed Jul 15 2020 Kamil Dudka - 7.61.1-13 +- load built-in openssl engines (#1854369) + * Mon Nov 18 2019 Omair Majid - 7.61.1-11 - Update for .NET Core 3.1 - Resolves: RHBZ#1767056 @@ -345,6 +478,11 @@ rm -f ${RPM_BUILD_ROOT}%{_libdir}/libcurl.la - Fix dependencies to work on RHEL 7 - Resolves: RHBZ#1746116 +* Wed Sep 11 2019 Kamil Dudka - 7.61.1-12 +- double free due to subsequent call of realloc() (CVE-2019-5481) +- fix heap buffer overflow in function tftp_receive_packet() (CVE-2019-5482) +- fix TFTP receive buffer overflow (CVE-2019-5436) + * Mon May 13 2019 Kamil Dudka - 7.61.1-11 - rebuild with updated annobin to prevent Execshield RPMDiff check from failing