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/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 707664f..8f28ad1 100644 --- a/SPECS/curl.spec +++ b/SPECS/curl.spec @@ -1,7 +1,7 @@ Summary: A utility for getting files from remote servers (FTP, HTTP, and others) Name: curl Version: 7.61.1 -Release: 12%{?dist} +Release: 18%{?dist} License: MIT Source: https://curl.haxx.se/download/%{name}-%{version}.tar.xz @@ -52,6 +52,33 @@ 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 + # patch making libcurl multilib ready Patch101: 0101-curl-7.32.0-multilib.patch @@ -64,6 +91,9 @@ 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 + Provides: curl-full = %{version}-%{release} Provides: webclient URL: https://curl.haxx.se/ @@ -195,7 +225,7 @@ Summary: Conservatively configured build of libcurl for minimal installations Requires: openssl-libs%{?_isa} >= 1:%{openssl_version} Provides: libcurl = %{version}-%{release} Provides: libcurl%{?_isa} = %{version}-%{release} -Conflicts: libcurl +Conflicts: libcurl%{?_isa} RemovePathPostfixes: .minimal # needed for RemovePathPostfixes to work with shared libraries %undefine __brp_ldconfig @@ -230,10 +260,24 @@ git apply %{PATCH4} %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 + # 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 # make tests/*.py use Python 3 sed -e '1 s|^#!/.*python|#!%{__python3}|' -i tests/*.py @@ -326,7 +370,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 and rename the library that will be packaged as libcurl-minimal @@ -394,6 +441,28 @@ rm -f ${RPM_BUILD_ROOT}%{_libdir}/libcurl.la %{_libdir}/libcurl.so.4.[0-9].[0-9].minimal %changelog +* 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) + * 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)