update curl to 7.77.0
This commit is contained in:
parent
dd002d235f
commit
1e1a6740cd
@ -31,7 +31,7 @@ index 150004d..95d0759 100644
|
||||
- else
|
||||
- CURLLIBDIR=""
|
||||
- fi
|
||||
- if test "X@ENABLE_SHARED@" = "Xno" -o "X@REQUIRE_LIB_DEPS@" = "Xyes"; then
|
||||
- if test "X@ENABLE_SHARED@" = "Xno"; then
|
||||
- echo ${CURLLIBDIR}-lcurl @LIBCURL_LIBS@
|
||||
- else
|
||||
- echo ${CURLLIBDIR}-lcurl
|
||||
@ -83,7 +83,7 @@ index 2ba9c39..f8f8b00 100644
|
||||
+configure_options=@CONFIGURE_OPTIONS@
|
||||
|
||||
Name: libcurl
|
||||
URL: https://curl.haxx.se/
|
||||
URL: https://curl.se/
|
||||
--
|
||||
2.5.0
|
||||
|
||||
|
||||
@ -1,51 +0,0 @@
|
||||
diff --git a/tests/data/test1083 b/tests/data/test1083
|
||||
index e441278..b0958b6 100644
|
||||
--- a/tests/data/test1083
|
||||
+++ b/tests/data/test1083
|
||||
@@ -33,13 +33,13 @@ ipv6
|
||||
http-ipv6
|
||||
</server>
|
||||
<name>
|
||||
-HTTP-IPv6 GET with ip6-localhost --interface
|
||||
+HTTP-IPv6 GET with localhost6 --interface
|
||||
</name>
|
||||
<command>
|
||||
--g "http://%HOST6IP:%HTTP6PORT/1083" --interface ip6-localhost
|
||||
+-g "http://%HOST6IP:%HTTP6PORT/1083" --interface localhost6
|
||||
</command>
|
||||
<precheck>
|
||||
-perl -e "if ('%CLIENT6IP' ne '[::1]') {print 'Test requires default test client host address';} else {exec './server/resolve --ipv6 ip6-localhost'; print 'Cannot run precheck resolve';}"
|
||||
+perl -e "if ('%CLIENT6IP' ne '[::1]') {print 'Test requires default test client host address';} else {exec './server/resolve --ipv6 localhost6'; print 'Cannot run precheck resolve';}"
|
||||
</precheck>
|
||||
</client>
|
||||
|
||||
diff --git a/tests/data/test241 b/tests/data/test241
|
||||
index 46eae1f..4e1632c 100644
|
||||
--- a/tests/data/test241
|
||||
+++ b/tests/data/test241
|
||||
@@ -30,13 +30,13 @@ ipv6
|
||||
http-ipv6
|
||||
</server>
|
||||
<name>
|
||||
-HTTP-IPv6 GET (using ip6-localhost)
|
||||
+HTTP-IPv6 GET (using localhost6)
|
||||
</name>
|
||||
<command>
|
||||
--g "http://ip6-localhost:%HTTP6PORT/241"
|
||||
+-g "http://localhost6:%HTTP6PORT/241"
|
||||
</command>
|
||||
<precheck>
|
||||
-./server/resolve --ipv6 ip6-localhost
|
||||
+./server/resolve --ipv6 localhost6
|
||||
</precheck>
|
||||
</client>
|
||||
|
||||
@@ -48,7 +48,7 @@ HTTP-IPv6 GET (using ip6-localhost)
|
||||
</strip>
|
||||
<protocol>
|
||||
GET /241 HTTP/1.1
|
||||
-Host: ip6-localhost:%HTTP6PORT
|
||||
+Host: localhost6:%HTTP6PORT
|
||||
Accept: */*
|
||||
|
||||
</protocol>
|
||||
@ -21,9 +21,9 @@ index d349cd9..166931d 100644
|
||||
--- a/lib/file.c
|
||||
+++ b/lib/file.c
|
||||
@@ -136,7 +136,7 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
|
||||
struct Curl_easy *data = conn->data;
|
||||
{
|
||||
char *real_path;
|
||||
struct FILEPROTO *file = data->req.protop;
|
||||
struct FILEPROTO *file = data->req.p.file;
|
||||
- int fd;
|
||||
+ int fd = -1;
|
||||
#ifdef DOS_FILESYSTEM
|
||||
|
||||
@ -1,112 +0,0 @@
|
||||
From d5bb459ccf1fc5980ae4b95c05b4ecf6454a7599 Mon Sep 17 00:00:00 2001
|
||||
From: Marc Aldorasi <marc@groundctl.com>
|
||||
Date: Thu, 30 Jul 2020 14:16:17 -0400
|
||||
Subject: [PATCH] multi_remove_handle: close unused connect-only connections
|
||||
|
||||
Previously any connect-only connections in a multi handle would be kept
|
||||
alive until the multi handle was closed. Since these connections cannot
|
||||
be re-used, they can be marked for closure when the associated easy
|
||||
handle is removed from the multi handle.
|
||||
|
||||
Closes #5749
|
||||
---
|
||||
lib/multi.c | 34 ++++++++++++++++++++++++++++++----
|
||||
tests/data/test1554 | 6 ++++++
|
||||
2 files changed, 36 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/lib/multi.c b/lib/multi.c
|
||||
index 6b62ddaf7..1c3be72fe 100644
|
||||
--- a/lib/multi.c
|
||||
+++ b/lib/multi.c
|
||||
@@ -689,6 +689,26 @@ static CURLcode multi_done(struct Curl_easy *data,
|
||||
return result;
|
||||
}
|
||||
|
||||
+static int close_connect_only(struct connectdata *conn, void *param)
|
||||
+{
|
||||
+ struct Curl_easy *data = param;
|
||||
+
|
||||
+ if(data->state.lastconnect != conn)
|
||||
+ return 0;
|
||||
+
|
||||
+ if(conn->data != data)
|
||||
+ return 1;
|
||||
+ conn->data = NULL;
|
||||
+
|
||||
+ if(!conn->bits.connect_only)
|
||||
+ return 1;
|
||||
+
|
||||
+ connclose(conn, "Removing connect-only easy handle");
|
||||
+ conn->bits.connect_only = FALSE;
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
@@ -776,10 +796,6 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
|
||||
multi_done() as that may actually call Curl_expire that uses this */
|
||||
Curl_llist_destroy(&data->state.timeoutlist, NULL);
|
||||
|
||||
- /* as this was using a shared connection cache we clear the pointer to that
|
||||
- since we're not part of that multi handle anymore */
|
||||
- data->state.conn_cache = NULL;
|
||||
-
|
||||
/* change state without using multistate(), only to make singlesocket() do
|
||||
what we want */
|
||||
data->mstate = CURLM_STATE_COMPLETED;
|
||||
@@ -789,12 +805,22 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
|
||||
/* Remove the association between the connection and the handle */
|
||||
Curl_detach_connnection(data);
|
||||
|
||||
+ if(data->state.lastconnect) {
|
||||
+ /* Mark any connect-only connection for closure */
|
||||
+ Curl_conncache_foreach(data, data->state.conn_cache,
|
||||
+ data, &close_connect_only);
|
||||
+ }
|
||||
+
|
||||
#ifdef USE_LIBPSL
|
||||
/* Remove the PSL association. */
|
||||
if(data->psl == &multi->psl)
|
||||
data->psl = NULL;
|
||||
#endif
|
||||
|
||||
+ /* as this was using a shared connection cache we clear the pointer to that
|
||||
+ since we're not part of that multi handle anymore */
|
||||
+ data->state.conn_cache = NULL;
|
||||
+
|
||||
data->multi = NULL; /* clear the association to this multi handle */
|
||||
|
||||
/* make sure there's no pending message in the queue sent from this easy
|
||||
diff --git a/tests/data/test1554 b/tests/data/test1554
|
||||
index d3926d916..fffa6adb5 100644
|
||||
--- a/tests/data/test1554
|
||||
+++ b/tests/data/test1554
|
||||
@@ -50,6 +50,8 @@ run 1: foobar and so on fun!
|
||||
<- Mutex unlock
|
||||
-> Mutex lock
|
||||
<- Mutex unlock
|
||||
+-> Mutex lock
|
||||
+<- Mutex unlock
|
||||
run 1: foobar and so on fun!
|
||||
-> Mutex lock
|
||||
<- Mutex unlock
|
||||
@@ -65,6 +67,8 @@ run 1: foobar and so on fun!
|
||||
<- Mutex unlock
|
||||
-> Mutex lock
|
||||
<- Mutex unlock
|
||||
+-> Mutex lock
|
||||
+<- Mutex unlock
|
||||
run 1: foobar and so on fun!
|
||||
-> Mutex lock
|
||||
<- Mutex unlock
|
||||
@@ -74,6 +78,8 @@ run 1: foobar and so on fun!
|
||||
<- Mutex unlock
|
||||
-> Mutex lock
|
||||
<- Mutex unlock
|
||||
+-> Mutex lock
|
||||
+<- Mutex unlock
|
||||
</datacheck>
|
||||
</reply>
|
||||
|
||||
@ -1,155 +0,0 @@
|
||||
From 3c9e021f86872baae412a427e807fbfa2f3e8a22 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Stenberg <daniel@haxx.se>
|
||||
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
|
||||
---
|
||||
lib/connect.c | 19 ++++++++++---------
|
||||
lib/easy.c | 3 +--
|
||||
lib/multi.c | 9 +++++----
|
||||
lib/url.c | 2 +-
|
||||
lib/urldata.h | 2 +-
|
||||
5 files changed, 18 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/lib/connect.c b/lib/connect.c
|
||||
index 313c23315..b000b1b2c 100644
|
||||
--- a/lib/connect.c
|
||||
+++ b/lib/connect.c
|
||||
@@ -1363,15 +1363,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;
|
||||
@@ -1393,21 +1393,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 292cca7f6..a69eb9e56 100644
|
||||
--- a/lib/easy.c
|
||||
+++ b/lib/easy.c
|
||||
@@ -838,8 +838,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 b3a75e137..3c7fb85ed 100644
|
||||
--- a/lib/multi.c
|
||||
+++ b/lib/multi.c
|
||||
@@ -455,6 +455,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. */
|
||||
@@ -677,11 +678,11 @@ static CURLcode multi_done(struct Curl_easy *data,
|
||||
CONNCACHE_UNLOCK(data);
|
||||
if(Curl_conncache_return_conn(data, 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;
|
||||
}
|
||||
|
||||
Curl_safefree(data->state.buffer);
|
||||
@@ -693,7 +694,7 @@ static int close_connect_only(struct connectdata *conn, void *param)
|
||||
{
|
||||
struct Curl_easy *data = param;
|
||||
|
||||
- if(data->state.lastconnect != conn)
|
||||
+ if(data->state.lastconnect_id != conn->connection_id)
|
||||
return 0;
|
||||
|
||||
if(conn->data != data)
|
||||
@@ -805,7 +806,7 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
|
||||
/* Remove the association between the connection and the handle */
|
||||
Curl_detach_connnection(data);
|
||||
|
||||
- if(data->state.lastconnect) {
|
||||
+ if(data->state.lastconnect_id != -1) {
|
||||
/* Mark any connect-only connection for closure */
|
||||
Curl_conncache_foreach(data, data->state.conn_cache,
|
||||
data, &close_connect_only);
|
||||
diff --git a/lib/url.c b/lib/url.c
|
||||
index a98aab27f..150667aa9 100644
|
||||
--- a/lib/url.c
|
||||
+++ b/lib/url.c
|
||||
@@ -630,7 +630,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 8ddb580c8..0ae926927 100644
|
||||
--- a/lib/urldata.h
|
||||
+++ b/lib/urldata.h
|
||||
@@ -1300,7 +1300,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 */
|
||||
struct dynbuf headerb; /* buffer to store headers in */
|
||||
|
||||
char *buffer; /* download buffer */
|
||||
@ -1,204 +0,0 @@
|
||||
From ec9cc725d598ac77de7b6df8afeec292b3c8ad46 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Stenberg <daniel@haxx.se>
|
||||
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
|
||||
---
|
||||
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 +
|
||||
tests/data/test1465 | Bin 2909 -> 2964 bytes
|
||||
14 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 d6fd4589b1e..bcf4e7e62f2 100644
|
||||
--- a/docs/cmdline-opts/ftp-skip-pasv-ip.d
|
||||
+++ b/docs/cmdline-opts/ftp-skip-pasv-ip.d
|
||||
@@ -10,4 +10,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 d6217d0d8ca..fa87ddce769 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, <daniel@haxx.se>, et al.
|
||||
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
.\" *
|
||||
.\" * This software is licensed as described in the file COPYING, which
|
||||
.\" * you should have received as part of this distribution. The terms
|
||||
@@ -35,11 +35,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 f8b2a0030de..2b0ba87ba87 100644
|
||||
--- a/lib/url.c
|
||||
+++ b/lib/url.c
|
||||
@@ -497,6 +497,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 */
|
||||
#endif
|
||||
set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
|
||||
|
||||
diff --git a/src/tool_cfgable.c b/src/tool_cfgable.c
|
||||
index c52d8e1c6bb..4c06d3557b7 100644
|
||||
--- a/src/tool_cfgable.c
|
||||
+++ b/src/tool_cfgable.c
|
||||
@@ -44,6 +44,7 @@ void config_init(struct OperationConfig *config)
|
||||
config->tcp_nodelay = TRUE; /* enabled by default */
|
||||
config->happy_eyeballs_timeout_ms = CURL_HET_DEFAULT;
|
||||
config->http09_allowed = FALSE;
|
||||
+ config->ftp_skip_ip = TRUE;
|
||||
}
|
||||
|
||||
static void free_config_fields(struct OperationConfig *config)
|
||||
diff --git a/tests/data/test1400 b/tests/data/test1400
|
||||
index 812ad0b88d9..b7060eca58e 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 f93b3d637de..a2629683aff 100644
|
||||
--- a/tests/data/test1401
|
||||
+++ b/tests/data/test1401
|
||||
@@ -87,6 +87,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 7593c516da1..1bd55cb4e3b 100644
|
||||
--- a/tests/data/test1402
|
||||
+++ b/tests/data/test1402
|
||||
@@ -78,6 +78,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 ecb4dd3dcab..a7c9fcca322 100644
|
||||
--- a/tests/data/test1403
|
||||
+++ b/tests/data/test1403
|
||||
@@ -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/test1404 b/tests/data/test1404
|
||||
index 97622b63948..1d8e8cf7779 100644
|
||||
--- a/tests/data/test1404
|
||||
+++ b/tests/data/test1404
|
||||
@@ -147,6 +147,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 2bac79eda74..b4087704f7b 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 51a166adff2..38f68d11ee1 100644
|
||||
--- a/tests/data/test1406
|
||||
+++ b/tests/data/test1406
|
||||
@@ -79,6 +79,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 f6879008fb2..a7e13ba7585 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 057ecc4773a..4b8d7bbf418 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/;MAILINDEX=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
|
||||
|
||||
@ -1,248 +0,0 @@
|
||||
From 69a358f2186e04cf44698b5100332cbf1ee7f01d Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Stenberg <daniel@haxx.se>
|
||||
Date: Sat, 28 Nov 2020 00:27:21 +0100
|
||||
Subject: [PATCH] ftp: make wc_statemach loop instead of recurse
|
||||
|
||||
Fixes #6255
|
||||
Bug: https://curl.se/docs/CVE-2020-8285.html
|
||||
Reported-by: xnynx on github
|
||||
---
|
||||
lib/ftp.c | 202 +++++++++++++++++++++++++++---------------------------
|
||||
1 file changed, 102 insertions(+), 100 deletions(-)
|
||||
|
||||
diff --git a/lib/ftp.c b/lib/ftp.c
|
||||
index 50e7d7ddac9..bc355742172 100644
|
||||
--- a/lib/ftp.c
|
||||
+++ b/lib/ftp.c
|
||||
@@ -3800,129 +3800,131 @@ 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;
|
||||
- struct FTP *ftp = conn->data->req.protop;
|
||||
+ 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;
|
||||
+ struct FTP *ftp = conn->data->req.protop;
|
||||
|
||||
- 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 ftp->path and tmp_path */
|
||||
- free(ftp->pathalloc);
|
||||
- ftp->pathalloc = ftp->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 ftp->path and tmp_path */
|
||||
+ free(ftp->pathalloc);
|
||||
+ ftp->pathalloc = ftp->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 */
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@ -1,125 +0,0 @@
|
||||
From d9d01672785b8ac04aab1abb6de95fe3072ae199 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Stenberg <daniel@haxx.se>
|
||||
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
|
||||
---
|
||||
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 c905465a0..e9c535f8f 100644
|
||||
--- a/lib/vtls/openssl.c
|
||||
+++ b/lib/vtls/openssl.c
|
||||
@@ -1795,6 +1795,11 @@ static CURLcode verifystatus(struct connectdata *conn,
|
||||
X509_STORE *st = NULL;
|
||||
STACK_OF(X509) *ch = NULL;
|
||||
struct ssl_backend_data *backend = connssl->backend;
|
||||
+ 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, &status);
|
||||
|
||||
@@ -1863,43 +1868,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.17.1
|
||||
@ -1,150 +0,0 @@
|
||||
From 7214288898f5625a6cc196e22a74232eada7861c Mon Sep 17 00:00:00 2001
|
||||
From: Viktor Szakats <commit@vsz.me>
|
||||
Date: Tue, 23 Feb 2021 14:54:46 +0100
|
||||
Subject: [PATCH] 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
|
||||
---
|
||||
lib/transfer.c | 25 ++++++++++++++--
|
||||
tests/data/Makefile.inc | 2 +-
|
||||
tests/data/test2081 | 66 +++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 90 insertions(+), 3 deletions(-)
|
||||
create mode 100644 tests/data/test2081
|
||||
|
||||
diff --git a/lib/transfer.c b/lib/transfer.c
|
||||
index 1976bc033..a68c021c8 100644
|
||||
--- a/lib/transfer.c
|
||||
+++ b/lib/transfer.c
|
||||
@@ -1582,6 +1582,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 */
|
||||
@@ -1591,9 +1594,27 @@ 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 */
|
||||
}
|
||||
}
|
||||
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
|
||||
index 2c7a0ca89..ea52683d2 100644
|
||||
--- a/tests/data/Makefile.inc
|
||||
+++ b/tests/data/Makefile.inc
|
||||
@@ -221,7 +221,7 @@ test2064 test2065 test2066 test2067 test2068 test2069 \
|
||||
test2064 test2065 test2066 test2067 test2068 test2069 test2070 \
|
||||
test2071 test2072 test2073 test2074 test2075 test2076 test2077 \
|
||||
test2078 \
|
||||
-test2080 \
|
||||
+test2080 test2081 \
|
||||
test2100 \
|
||||
\
|
||||
test3000 test3001 \
|
||||
diff --git a/tests/data/test2081 b/tests/data/test2081
|
||||
new file mode 100644
|
||||
index 000000000..a6733e737
|
||||
--- /dev/null
|
||||
+++ b/tests/data/test2081
|
||||
@@ -0,0 +1,66 @@
|
||||
+<testcase>
|
||||
+<info>
|
||||
+<keywords>
|
||||
+HTTP
|
||||
+HTTP GET
|
||||
+referer
|
||||
+followlocation
|
||||
+--write-out
|
||||
+</keywords>
|
||||
+</info>
|
||||
+
|
||||
+# Server-side
|
||||
+<reply>
|
||||
+<data nocheck="yes">
|
||||
+HTTP/1.1 301 This is a weirdo text message swsclose
|
||||
+Location: data/%TESTNUMBER0002.txt?coolsite=yes
|
||||
+Content-Length: 62
|
||||
+Connection: close
|
||||
+
|
||||
+This server reply is for testing a simple Location: following
|
||||
+</data>
|
||||
+</reply>
|
||||
+
|
||||
+# Client-side
|
||||
+<client>
|
||||
+<server>
|
||||
+http
|
||||
+</server>
|
||||
+ <name>
|
||||
+Automatic referrer credential and anchor stripping check
|
||||
+ </name>
|
||||
+ <command>
|
||||
+http://user:pass@%HOSTIP:%HTTPPORT/we/want/our/%TESTNUMBER#anchor --location --referer ';auto' --write-out '%{referer}\n'
|
||||
+</command>
|
||||
+</client>
|
||||
+
|
||||
+# Verify data after the test has been "shot"
|
||||
+<verify>
|
||||
+<errorcode>
|
||||
+52
|
||||
+</errorcode>
|
||||
+<protocol>
|
||||
+GET /we/want/our/%TESTNUMBER HTTP/1.1
|
||||
+Host: %HOSTIP:%HTTPPORT
|
||||
+Authorization: Basic dXNlcjpwYXNz
|
||||
+User-Agent: curl/%VERSION
|
||||
+Accept: */*
|
||||
+
|
||||
+GET /we/want/our/data/%TESTNUMBER0002.txt?coolsite=yes HTTP/1.1
|
||||
+Host: %HOSTIP:%HTTPPORT
|
||||
+Authorization: Basic dXNlcjpwYXNz
|
||||
+User-Agent: curl/%VERSION
|
||||
+Accept: */*
|
||||
+Referer: http://%HOSTIP:%HTTPPORT/we/want/our/%TESTNUMBER
|
||||
+
|
||||
+</protocol>
|
||||
+<stdout>
|
||||
+HTTP/1.1 301 This is a weirdo text message swsclose
|
||||
+Location: data/%TESTNUMBER0002.txt?coolsite=yes
|
||||
+Content-Length: 62
|
||||
+Connection: close
|
||||
+
|
||||
+http://%HOSTIP:%HTTPPORT/we/want/our/%TESTNUMBER
|
||||
+</stdout>
|
||||
+</verify>
|
||||
+</testcase>
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -1,455 +0,0 @@
|
||||
Backport of:
|
||||
|
||||
From e9c835dbd51f482f5d572e6fb33a0e8ef60c846b Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Stenberg <daniel@haxx.se>
|
||||
Date: Fri, 19 Mar 2021 12:38:49 +0100
|
||||
Subject: [PATCH] vtls: add 'isproxy' argument to Curl_ssl_get/addsessionid()
|
||||
|
||||
To make sure we set and extract the correct session.
|
||||
|
||||
Reported-by: Mingtao Yang
|
||||
Bug: https://curl.se/docs/CVE-2021-22890.html
|
||||
|
||||
CVE-2021-22890
|
||||
---
|
||||
lib/vtls/bearssl.c | 8 +++++--
|
||||
lib/vtls/gtls.c | 12 ++++++----
|
||||
lib/vtls/mbedtls.c | 12 ++++++----
|
||||
lib/vtls/mesalink.c | 14 ++++++++----
|
||||
lib/vtls/openssl.c | 54 +++++++++++++++++++++++++++++++++-----------
|
||||
lib/vtls/schannel.c | 10 ++++----
|
||||
lib/vtls/sectransp.c | 10 ++++----
|
||||
lib/vtls/vtls.c | 12 +++++++---
|
||||
lib/vtls/vtls.h | 2 ++
|
||||
lib/vtls/wolfssl.c | 13 +++++++----
|
||||
10 files changed, 103 insertions(+), 44 deletions(-)
|
||||
|
||||
--- a/lib/vtls/bearssl.c
|
||||
+++ b/lib/vtls/bearssl.c
|
||||
@@ -375,7 +375,8 @@ static CURLcode bearssl_connect_step1(st
|
||||
void *session;
|
||||
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
- if(!Curl_ssl_getsessionid(conn, &session, NULL, sockindex)) {
|
||||
+ if(!Curl_ssl_getsessionid(conn, SSL_IS_PROXY() ? TRUE : FALSE,
|
||||
+ &session, NULL, sockindex)) {
|
||||
br_ssl_engine_set_session_parameters(&backend->ctx.eng, session);
|
||||
infof(data, "BearSSL: re-using session ID\n");
|
||||
}
|
||||
@@ -569,10 +570,12 @@ static CURLcode bearssl_connect_step3(st
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
br_ssl_engine_get_session_parameters(&backend->ctx.eng, session);
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
- incache = !(Curl_ssl_getsessionid(conn, &oldsession, NULL, sockindex));
|
||||
+ incache = !(Curl_ssl_getsessionid(conn, SSL_IS_PROXY() ? TRUE : FALSE,
|
||||
+ &oldsession, NULL, sockindex));
|
||||
if(incache)
|
||||
Curl_ssl_delsessionid(conn, oldsession);
|
||||
- ret = Curl_ssl_addsessionid(conn, session, 0, sockindex);
|
||||
+ ret = Curl_ssl_addsessionid(conn, SSL_IS_PROXY() ? TRUE : FALSE,
|
||||
+ session, 0, sockindex);
|
||||
Curl_ssl_sessionid_unlock(conn);
|
||||
if(ret) {
|
||||
free(session);
|
||||
--- a/lib/vtls/gtls.c
|
||||
+++ b/lib/vtls/gtls.c
|
||||
@@ -732,7 +732,8 @@ gtls_connect_step1(struct connectdata *c
|
||||
size_t ssl_idsize;
|
||||
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
- if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, &ssl_idsize, sockindex)) {
|
||||
+ if(!Curl_ssl_getsessionid(conn, SSL_IS_PROXY() ? TRUE : FALSE,
|
||||
+ &ssl_sessionid, &ssl_idsize, sockindex)) {
|
||||
/* we got a session id, use it! */
|
||||
gnutls_session_set_data(session, ssl_sessionid, ssl_idsize);
|
||||
|
||||
@@ -1291,7 +1292,8 @@ gtls_connect_step3(struct connectdata *c
|
||||
gnutls_session_get_data(session, connect_sessionid, &connect_idsize);
|
||||
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
- incache = !(Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL,
|
||||
+ incache = !(Curl_ssl_getsessionid(conn, SSL_IS_PROXY() ? TRUE : FALSE,
|
||||
+ &ssl_sessionid, NULL,
|
||||
sockindex));
|
||||
if(incache) {
|
||||
/* there was one before in the cache, so instead of risking that the
|
||||
@@ -1300,7 +1302,8 @@ gtls_connect_step3(struct connectdata *c
|
||||
}
|
||||
|
||||
/* store this session id */
|
||||
- result = Curl_ssl_addsessionid(conn, connect_sessionid, connect_idsize,
|
||||
+ result = Curl_ssl_addsessionid(conn, SSL_IS_PROXY() ? TRUE : FALSE,
|
||||
+ connect_sessionid, connect_idsize,
|
||||
sockindex);
|
||||
Curl_ssl_sessionid_unlock(conn);
|
||||
if(result) {
|
||||
--- a/lib/vtls/mbedtls.c
|
||||
+++ b/lib/vtls/mbedtls.c
|
||||
@@ -464,7 +464,8 @@ mbed_connect_step1(struct connectdata *c
|
||||
void *old_session = NULL;
|
||||
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
- if(!Curl_ssl_getsessionid(conn, &old_session, NULL, sockindex)) {
|
||||
+ if(!Curl_ssl_getsessionid(conn, SSL_IS_PROXY() ? TRUE : FALSE,
|
||||
+ &old_session, NULL, sockindex)) {
|
||||
ret = mbedtls_ssl_set_session(&backend->ssl, old_session);
|
||||
if(ret) {
|
||||
Curl_ssl_sessionid_unlock(conn);
|
||||
@@ -727,6 +728,7 @@ mbed_connect_step3(struct connectdata *c
|
||||
int ret;
|
||||
mbedtls_ssl_session *our_ssl_sessionid;
|
||||
void *old_ssl_sessionid = NULL;
|
||||
+ bool isproxy = SSL_IS_PROXY() ? TRUE : FALSE;
|
||||
|
||||
our_ssl_sessionid = malloc(sizeof(mbedtls_ssl_session));
|
||||
if(!our_ssl_sessionid)
|
||||
@@ -745,10 +747,10 @@ mbed_connect_step3(struct connectdata *c
|
||||
|
||||
/* If there's already a matching session in the cache, delete it */
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
- if(!Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, sockindex))
|
||||
+ if(!Curl_ssl_getsessionid(conn, isproxy, &old_ssl_sessionid, NULL, sockindex))
|
||||
Curl_ssl_delsessionid(conn, old_ssl_sessionid);
|
||||
|
||||
- retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0, sockindex);
|
||||
+ retcode = Curl_ssl_addsessionid(conn, isproxy, our_ssl_sessionid, 0, sockindex);
|
||||
Curl_ssl_sessionid_unlock(conn);
|
||||
if(retcode) {
|
||||
mbedtls_ssl_session_free(our_ssl_sessionid);
|
||||
--- a/lib/vtls/mesalink.c
|
||||
+++ b/lib/vtls/mesalink.c
|
||||
@@ -261,7 +261,8 @@ mesalink_connect_step1(struct connectdat
|
||||
void *ssl_sessionid = NULL;
|
||||
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
- if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) {
|
||||
+ if(!Curl_ssl_getsessionid(conn, SSL_IS_PROXY() ? TRUE : FALSE,
|
||||
+ &ssl_sessionid, NULL, sockindex)) {
|
||||
/* we got a session id, use it! */
|
||||
if(!SSL_set_session(BACKEND->handle, ssl_sessionid)) {
|
||||
Curl_ssl_sessionid_unlock(conn);
|
||||
@@ -345,12 +346,14 @@ mesalink_connect_step3(struct connectdat
|
||||
bool incache;
|
||||
SSL_SESSION *our_ssl_sessionid;
|
||||
void *old_ssl_sessionid = NULL;
|
||||
+ bool inproxy = SSL_IS_PROXY() ? TRUE : FALSE;
|
||||
|
||||
our_ssl_sessionid = SSL_get_session(BACKEND->handle);
|
||||
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
incache =
|
||||
- !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, sockindex));
|
||||
+ !(Curl_ssl_getsessionid(conn, isproxy, &old_ssl_sessionid,
|
||||
+ NULL, sockindex));
|
||||
if(incache) {
|
||||
if(old_ssl_sessionid != our_ssl_sessionid) {
|
||||
infof(data, "old SSL session ID is stale, removing\n");
|
||||
@@ -361,7 +364,7 @@ mesalink_connect_step3(struct connectdat
|
||||
|
||||
if(!incache) {
|
||||
result = Curl_ssl_addsessionid(
|
||||
- conn, our_ssl_sessionid, 0 /* unknown size */, sockindex);
|
||||
+ conn, isproxy, our_ssl_sessionid, 0 /* unknown size */, sockindex);
|
||||
if(result) {
|
||||
Curl_ssl_sessionid_unlock(conn);
|
||||
failf(data, "failed to store ssl session");
|
||||
--- a/lib/vtls/openssl.c
|
||||
+++ b/lib/vtls/openssl.c
|
||||
@@ -379,12 +379,23 @@ static int ossl_get_ssl_conn_index(void)
|
||||
*/
|
||||
static int ossl_get_ssl_sockindex_index(void)
|
||||
{
|
||||
- static int ssl_ex_data_sockindex_index = -1;
|
||||
- if(ssl_ex_data_sockindex_index < 0) {
|
||||
- ssl_ex_data_sockindex_index = SSL_get_ex_new_index(0, NULL, NULL, NULL,
|
||||
- NULL);
|
||||
+ static int sockindex_index = -1;
|
||||
+ if(sockindex_index < 0) {
|
||||
+ sockindex_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
- return ssl_ex_data_sockindex_index;
|
||||
+ return sockindex_index;
|
||||
+}
|
||||
+
|
||||
+/* Return an extra data index for proxy boolean.
|
||||
+ * This index can be used with SSL_get_ex_data() and SSL_set_ex_data().
|
||||
+ */
|
||||
+static int ossl_get_proxy_index(void)
|
||||
+{
|
||||
+ static int proxy_index = -1;
|
||||
+ if(proxy_index < 0) {
|
||||
+ proxy_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
|
||||
+ }
|
||||
+ return proxy_index;
|
||||
}
|
||||
|
||||
static int passwd_callback(char *buf, int num, int encrypting,
|
||||
@@ -1161,7 +1172,8 @@ static int Curl_ossl_init(void)
|
||||
Curl_tls_keylog_open();
|
||||
|
||||
/* Initialize the extra data indexes */
|
||||
- if(ossl_get_ssl_conn_index() < 0 || ossl_get_ssl_sockindex_index() < 0)
|
||||
+ if(ossl_get_ssl_conn_index() < 0 || ossl_get_ssl_sockindex_index() < 0 ||
|
||||
+ ossl_get_proxy_index() < 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
@@ -2445,8 +2457,10 @@ static int ossl_new_session_cb(SSL *ssl,
|
||||
curl_socket_t *sockindex_ptr;
|
||||
int connectdata_idx = ossl_get_ssl_conn_index();
|
||||
int sockindex_idx = ossl_get_ssl_sockindex_index();
|
||||
+ int proxy_idx = ossl_get_proxy_index();
|
||||
+ bool isproxy;
|
||||
|
||||
- if(connectdata_idx < 0 || sockindex_idx < 0)
|
||||
+ if(connectdata_idx < 0 || sockindex_idx < 0 || proxy_idx < 0)
|
||||
return 0;
|
||||
|
||||
conn = (struct connectdata*) SSL_get_ex_data(ssl, connectdata_idx);
|
||||
@@ -2459,13 +2473,18 @@ static int ossl_new_session_cb(SSL *ssl,
|
||||
sockindex_ptr = (curl_socket_t*) SSL_get_ex_data(ssl, sockindex_idx);
|
||||
sockindex = (int)(sockindex_ptr - conn->sock);
|
||||
|
||||
+ isproxy = SSL_get_ex_data(ssl, proxy_idx) ? TRUE : FALSE;
|
||||
+
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
bool incache;
|
||||
void *old_ssl_sessionid = NULL;
|
||||
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
- incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL,
|
||||
- sockindex));
|
||||
+ if(isproxy)
|
||||
+ incache = FALSE;
|
||||
+ else
|
||||
+ incache = !(Curl_ssl_getsessionid(conn, isproxy,
|
||||
+ &old_ssl_sessionid, NULL, sockindex));
|
||||
if(incache) {
|
||||
if(old_ssl_sessionid != ssl_sessionid) {
|
||||
infof(data, "old SSL session ID is stale, removing\n");
|
||||
@@ -2475,7 +2494,7 @@ static int ossl_new_session_cb(SSL *ssl,
|
||||
}
|
||||
|
||||
if(!incache) {
|
||||
- if(!Curl_ssl_addsessionid(conn, ssl_sessionid,
|
||||
+ if(!Curl_ssl_addsessionid(conn, isproxy, ssl_sessionid,
|
||||
0 /* unknown size */, sockindex)) {
|
||||
/* the session has been put into the session cache */
|
||||
res = 1;
|
||||
@@ -3189,16 +3208,24 @@ static CURLcode ossl_connect_step1(struc
|
||||
void *ssl_sessionid = NULL;
|
||||
int connectdata_idx = ossl_get_ssl_conn_index();
|
||||
int sockindex_idx = ossl_get_ssl_sockindex_index();
|
||||
+ int proxy_idx = ossl_get_proxy_index();
|
||||
|
||||
- if(connectdata_idx >= 0 && sockindex_idx >= 0) {
|
||||
+ if(connectdata_idx >= 0 && sockindex_idx >= 0 && proxy_idx >= 0) {
|
||||
/* Store the data needed for the "new session" callback.
|
||||
* The sockindex is stored as a pointer to an array element. */
|
||||
SSL_set_ex_data(backend->handle, connectdata_idx, conn);
|
||||
SSL_set_ex_data(backend->handle, sockindex_idx, conn->sock + sockindex);
|
||||
+#ifndef CURL_DISABLE_PROXY
|
||||
+ SSL_set_ex_data(backend->handle, proxy_idx, SSL_IS_PROXY() ? (void *) 1:
|
||||
+ NULL);
|
||||
+#else
|
||||
+ SSL_set_ex_data(backend->handle, proxy_idx, NULL);
|
||||
+#endif
|
||||
}
|
||||
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
- if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) {
|
||||
+ if(!Curl_ssl_getsessionid(conn, SSL_IS_PROXY() ? TRUE : FALSE,
|
||||
+ &ssl_sessionid, NULL, sockindex)) {
|
||||
/* we got a session id, use it! */
|
||||
if(!SSL_set_session(backend->handle, ssl_sessionid)) {
|
||||
Curl_ssl_sessionid_unlock(conn);
|
||||
--- a/lib/vtls/schannel.c
|
||||
+++ b/lib/vtls/schannel.c
|
||||
@@ -494,7 +494,8 @@ schannel_connect_step1(struct connectdat
|
||||
/* check for an existing re-usable credential handle */
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
- if(!Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL, sockindex)) {
|
||||
+ if(!Curl_ssl_getsessionid(conn, SSL_IS_PROXY() ? TRUE : FALSE,
|
||||
+ (void **)&old_cred, NULL, sockindex)) {
|
||||
BACKEND->cred = old_cred;
|
||||
DEBUGF(infof(data, "schannel: re-using existing credential handle\n"));
|
||||
|
||||
@@ -1334,8 +1335,9 @@ schannel_connect_step3(struct connectdat
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
SECURITY_STATUS sspi_status = SEC_E_OK;
|
||||
CERT_CONTEXT *ccert_context = NULL;
|
||||
+ bool isproxy = SSL_IS_PROXY();
|
||||
#ifdef DEBUGBUILD
|
||||
- const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
||||
+ const char * const hostname = isproxy ? conn->http_proxy.host.name :
|
||||
conn->host.name;
|
||||
#endif
|
||||
#ifdef HAS_ALPN
|
||||
@@ -1411,7 +1413,7 @@ schannel_connect_step3(struct connectdat
|
||||
struct curl_schannel_cred *old_cred = NULL;
|
||||
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
- incache = !(Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL,
|
||||
+ incache = !(Curl_ssl_getsessionid(conn, isproxy, (void **)&old_cred, NULL,
|
||||
sockindex));
|
||||
if(incache) {
|
||||
if(old_cred != BACKEND->cred) {
|
||||
@@ -1423,7 +1425,7 @@ schannel_connect_step3(struct connectdat
|
||||
}
|
||||
}
|
||||
if(!incache) {
|
||||
- result = Curl_ssl_addsessionid(conn, (void *)BACKEND->cred,
|
||||
+ result = Curl_ssl_addsessionid(conn, isproxy, (void *)BACKEND->cred,
|
||||
sizeof(struct curl_schannel_cred),
|
||||
sockindex);
|
||||
if(result) {
|
||||
--- a/lib/vtls/sectransp.c
|
||||
+++ b/lib/vtls/sectransp.c
|
||||
@@ -1400,7 +1400,8 @@ static CURLcode sectransp_connect_step1(
|
||||
const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
|
||||
char * const ssl_cert = SSL_SET_OPTION(cert);
|
||||
const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(cert_blob);
|
||||
- const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
||||
+ bool isproxy = SSL_IS_PROXY();
|
||||
+ const char * const hostname = isproxy ? conn->http_proxy.host.name :
|
||||
conn->host.name;
|
||||
const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
|
||||
#ifdef ENABLE_IPV6
|
||||
@@ -1613,7 +1615,7 @@ static CURLcode sectransp_connect_step1(
|
||||
|
||||
#ifdef USE_NGHTTP2
|
||||
if(data->set.httpversion >= CURL_HTTP_VERSION_2 &&
|
||||
- (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)) {
|
||||
+ (!isproxy || !conn->bits.tunnel_proxy) {
|
||||
CFArrayAppendValue(alpnArr, CFSTR(NGHTTP2_PROTO_VERSION_ID));
|
||||
infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
|
||||
}
|
||||
@@ -1953,7 +1955,7 @@ static CURLcode sectransp_connect_step1(
|
||||
size_t ssl_sessionid_len;
|
||||
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
- if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
|
||||
+ if(!Curl_ssl_getsessionid(conn, isproxy, (void **)&ssl_sessionid,
|
||||
&ssl_sessionid_len, sockindex)) {
|
||||
/* we got a session id, use it! */
|
||||
err = SSLSetPeerID(backend->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
|
||||
@@ -1981,7 +1983,7 @@ static CURLcode sectransp_connect_step1(
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
- result = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len,
|
||||
+ result = Curl_ssl_addsessionid(conn, isproxy, ssl_sessionid, ssl_sessionid_len,
|
||||
sockindex);
|
||||
Curl_ssl_sessionid_unlock(conn);
|
||||
if(result) {
|
||||
--- a/lib/vtls/vtls.c
|
||||
+++ b/lib/vtls/vtls.c
|
||||
@@ -361,6 +361,7 @@ void Curl_ssl_sessionid_unlock(struct co
|
||||
* there's one suitable, it is provided. Returns TRUE when no entry matched.
|
||||
*/
|
||||
bool Curl_ssl_getsessionid(struct connectdata *conn,
|
||||
+ const bool isProxy,
|
||||
void **ssl_sessionid,
|
||||
size_t *idsize, /* set 0 if unknown */
|
||||
int sockindex)
|
||||
@@ -372,7 +373,6 @@ bool Curl_ssl_getsessionid(struct connec
|
||||
bool no_match = TRUE;
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
- const bool isProxy = CONNECT_PROXY_SSL();
|
||||
struct ssl_primary_config * const ssl_config = isProxy ?
|
||||
&conn->proxy_ssl_config :
|
||||
&conn->ssl_config;
|
||||
@@ -384,10 +384,15 @@ bool Curl_ssl_getsessionid(struct connec
|
||||
struct ssl_primary_config * const ssl_config = &conn->ssl_config;
|
||||
const char * const name = conn->host.name;
|
||||
int port = conn->remote_port;
|
||||
- (void)sockindex;
|
||||
#endif
|
||||
+ (void)sockindex;
|
||||
*ssl_sessionid = NULL;
|
||||
|
||||
+#ifdef CURL_DISABLE_PROXY
|
||||
+ if(isProxy)
|
||||
+ return TRUE;
|
||||
+#endif
|
||||
+
|
||||
DEBUGASSERT(SSL_SET_OPTION(primary.sessionid));
|
||||
|
||||
if(!SSL_SET_OPTION(primary.sessionid))
|
||||
@@ -475,6 +480,7 @@ void Curl_ssl_delsessionid(struct connec
|
||||
* later on.
|
||||
*/
|
||||
CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
|
||||
+ bool isProxy,
|
||||
void *ssl_sessionid,
|
||||
size_t idsize,
|
||||
int sockindex)
|
||||
@@ -488,7 +494,6 @@ CURLcode Curl_ssl_addsessionid(struct co
|
||||
int conn_to_port;
|
||||
long *general_age;
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
- const bool isProxy = CONNECT_PROXY_SSL();
|
||||
struct ssl_primary_config * const ssl_config = isProxy ?
|
||||
&conn->proxy_ssl_config :
|
||||
&conn->ssl_config;
|
||||
@@ -501,6 +506,7 @@ CURLcode Curl_ssl_addsessionid(struct co
|
||||
const char *hostname = conn->host.name;
|
||||
(void)sockindex;
|
||||
#endif
|
||||
+ (void)sockindex;
|
||||
DEBUGASSERT(SSL_SET_OPTION(primary.sessionid));
|
||||
|
||||
clone_host = strdup(hostname);
|
||||
--- a/lib/vtls/vtls.h
|
||||
+++ b/lib/vtls/vtls.h
|
||||
@@ -217,6 +217,7 @@ void Curl_ssl_sessionid_unlock(struct co
|
||||
* under sessionid mutex).
|
||||
*/
|
||||
bool Curl_ssl_getsessionid(struct connectdata *conn,
|
||||
+ const bool isproxy,
|
||||
void **ssl_sessionid,
|
||||
size_t *idsize, /* set 0 if unknown */
|
||||
int sockindex);
|
||||
@@ -226,6 +227,7 @@ bool Curl_ssl_getsessionid(struct connec
|
||||
* object with cache (e.g. incrementing refcount on success)
|
||||
*/
|
||||
CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
|
||||
+ const bool isProxy,
|
||||
void *ssl_sessionid,
|
||||
size_t idsize,
|
||||
int sockindex);
|
||||
--- a/lib/vtls/wolfssl.c
|
||||
+++ b/lib/vtls/wolfssl.c
|
||||
@@ -505,7 +505,8 @@ wolfssl_connect_step1(struct connectdata
|
||||
void *ssl_sessionid = NULL;
|
||||
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
- if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) {
|
||||
+ if(!Curl_ssl_getsessionid(conn, SSL_IS_PROXY() ? TRUE : FALSE,
|
||||
+ &ssl_sessionid, NULL, sockindex)) {
|
||||
/* we got a session id, use it! */
|
||||
if(!SSL_set_session(backend->handle, ssl_sessionid)) {
|
||||
char error_buffer[WOLFSSL_MAX_ERROR_SZ];
|
||||
@@ -765,9 +766,10 @@ wolfssl_connect_step3(struct connectdata
|
||||
void *old_ssl_sessionid = NULL;
|
||||
|
||||
our_ssl_sessionid = SSL_get_session(backend->handle);
|
||||
+ bool isproxy = SSL_IS_PROXY() ? TRUE : FALSE;
|
||||
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
- incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL,
|
||||
+ incache = !(Curl_ssl_getsessionid(conn, isproxy, &old_ssl_sessionid, NULL,
|
||||
sockindex));
|
||||
if(incache) {
|
||||
if(old_ssl_sessionid != our_ssl_sessionid) {
|
||||
@@ -778,7 +780,7 @@ wolfssl_connect_step3(struct connectdata
|
||||
}
|
||||
|
||||
if(!incache) {
|
||||
- result = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
|
||||
+ result = Curl_ssl_addsessionid(conn, isproxy, our_ssl_sessionid,
|
||||
0 /* unknown size */, sockindex);
|
||||
if(result) {
|
||||
Curl_ssl_sessionid_unlock(conn);
|
||||
@ -1,65 +0,0 @@
|
||||
From bbb71507b7bab52002f9b1e0880bed6a32834511 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Stenberg <daniel@haxx.se>
|
||||
Date: Fri, 23 Apr 2021 10:54:10 +0200
|
||||
Subject: [PATCH] schannel: don't use static to store selected ciphers
|
||||
|
||||
CVE-2021-22897
|
||||
|
||||
Bug: https://curl.se/docs/CVE-2021-22897.html
|
||||
---
|
||||
lib/vtls/schannel.c | 9 +++++----
|
||||
lib/vtls/schannel.h | 3 +++
|
||||
2 files changed, 8 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c
|
||||
index 8c25ac5dd5a5..dba7072273a9 100644
|
||||
--- a/lib/vtls/schannel.c
|
||||
+++ b/lib/vtls/schannel.c
|
||||
@@ -328,12 +328,12 @@ get_alg_id_by_name(char *name)
|
||||
}
|
||||
|
||||
static CURLcode
|
||||
-set_ssl_ciphers(SCHANNEL_CRED *schannel_cred, char *ciphers)
|
||||
+set_ssl_ciphers(SCHANNEL_CRED *schannel_cred, char *ciphers,
|
||||
+ int *algIds)
|
||||
{
|
||||
char *startCur = ciphers;
|
||||
int algCount = 0;
|
||||
- static ALG_ID algIds[45]; /*There are 45 listed in the MS headers*/
|
||||
- while(startCur && (0 != *startCur) && (algCount < 45)) {
|
||||
+ while(startCur && (0 != *startCur) && (algCount < NUMOF_CIPHERS)) {
|
||||
long alg = strtol(startCur, 0, 0);
|
||||
if(!alg)
|
||||
alg = get_alg_id_by_name(startCur);
|
||||
@@ -593,7 +593,8 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
|
||||
}
|
||||
|
||||
if(SSL_CONN_CONFIG(cipher_list)) {
|
||||
- result = set_ssl_ciphers(&schannel_cred, SSL_CONN_CONFIG(cipher_list));
|
||||
+ result = set_ssl_ciphers(&schannel_cred, SSL_CONN_CONFIG(cipher_list),
|
||||
+ BACKEND->algIds);
|
||||
if(CURLE_OK != result) {
|
||||
failf(data, "Unable to set ciphers to passed via SSL_CONN_CONFIG");
|
||||
return result;
|
||||
diff --git a/lib/vtls/schannel.h b/lib/vtls/schannel.h
|
||||
index 2952caa1a5a1..77853aa30f96 100644
|
||||
--- a/lib/vtls/schannel.h
|
||||
+++ b/lib/vtls/schannel.h
|
||||
@@ -71,6 +71,8 @@ CURLcode Curl_verify_certificate(struct Curl_easy *data,
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+#define NUMOF_CIPHERS 45 /* There are 45 listed in the MS headers */
|
||||
+
|
||||
struct curl_schannel_cred {
|
||||
CredHandle cred_handle;
|
||||
TimeStamp time_stamp;
|
||||
@@ -102,6 +104,7 @@ struct ssl_backend_data {
|
||||
#ifdef HAS_MANUAL_VERIFY_API
|
||||
bool use_manual_cred_validation; /* true if manual cred validation is used */
|
||||
#endif
|
||||
+ ALG_ID algIds[NUMOF_CIPHERS];
|
||||
};
|
||||
#endif /* EXPOSE_SCHANNEL_INTERNAL_STRUCTS */
|
||||
|
||||
|
||||
@ -1,26 +0,0 @@
|
||||
From 39ce47f219b09c380b81f89fe54ac586c8db6bde Mon Sep 17 00:00:00 2001
|
||||
From: Harry Sintonen <sintonen@iki.fi>
|
||||
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
|
||||
---
|
||||
lib/telnet.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/telnet.c b/lib/telnet.c
|
||||
index 26e0658ba9cc..fdd137fb0c04 100644
|
||||
--- a/lib/telnet.c
|
||||
+++ b/lib/telnet.c
|
||||
@@ -922,7 +922,7 @@ static void suboption(struct Curl_easy *data)
|
||||
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) {
|
||||
msnprintf((char *)&temp[len], sizeof(temp) - len,
|
||||
"%c%s%c%s", CURL_NEW_ENV_VAR, varname,
|
||||
CURL_NEW_ENV_VALUE, varval);
|
||||
|
||||
Binary file not shown.
BIN
curl-7.77.0.tar.xz
Normal file
BIN
curl-7.77.0.tar.xz
Normal file
Binary file not shown.
42
curl.spec
42
curl.spec
@ -5,8 +5,8 @@
|
||||
%global _configure ../configure
|
||||
|
||||
Name: curl
|
||||
Version: 7.71.1
|
||||
Release: 9
|
||||
Version: 7.77.0
|
||||
Release: 1
|
||||
Summary: Curl is used in command lines or scripts to transfer data
|
||||
License: MIT
|
||||
URL: https://curl.haxx.se/
|
||||
@ -14,18 +14,8 @@ Source: https://curl.haxx.se/download/curl-%{version}.tar.xz
|
||||
|
||||
Patch101: 0101-curl-7.32.0-multilib.patch
|
||||
Patch102: 0102-curl-7.36.0-debug.patch
|
||||
Patch104: 0104-curl-7.19.7-localhost6.patch
|
||||
Patch105: 0105-curl-7.63.0-lib1560-valgrind.patch
|
||||
Patch106: 0106-curl-fix-CVE-2019-15601.patch
|
||||
Patch107: 0107-curl-close-unused-connect-only-connections.patch
|
||||
Patch108: 0108-curl-fix-CVE-2020-8231.patch
|
||||
Patch109: backport-CVE-2020-8284.patch
|
||||
Patch110: backport-CVE-2020-8285.patch
|
||||
Patch111: backport-CVE-2020-8286.patch
|
||||
Patch112: backport-CVE-2021-22876.patch
|
||||
Patch113: backport-CVE-2021-22890.patch
|
||||
Patch114: backport-CVE-2021-22897.patch
|
||||
Patch115: backport-CVE-2021-22898.patch
|
||||
|
||||
BuildRequires: automake brotli-devel coreutils gcc groff krb5-devel
|
||||
BuildRequires: libidn2-devel libmetalink-devel libnghttp2-devel libpsl-devel
|
||||
@ -41,7 +31,7 @@ BuildRequires: valgrind
|
||||
%endif
|
||||
|
||||
Requires: libcurl = %{version}-%{release}
|
||||
Provides: curl-full = %{version}-%{release} webclient
|
||||
Provides: curl-full = %{version}-%{release} webclient
|
||||
|
||||
%description
|
||||
cURL is a computer software project providing a library (libcurl) and
|
||||
@ -74,14 +64,22 @@ Header files for libcurl.
|
||||
# make tests/*.py use Python 3
|
||||
sed -e '1 s|^#!/.*python|#!%{__python3}|' -i tests/*.py
|
||||
|
||||
# regenerate Makefile.in files
|
||||
aclocal -I m4
|
||||
automake
|
||||
|
||||
printf "1112\n1455\n1801\n1900\n" >> tests/data/DISABLED
|
||||
|
||||
# adapt test 323 for updated OpenSSL
|
||||
sed -e 's/^35$/35,52/' -i tests/data/test323
|
||||
# use localhost6 instead of ip6-localhost in the curl test-suite
|
||||
(
|
||||
# avoid glob expansion in the trace output of `bash -x`
|
||||
{ set +x; } 2>/dev/null
|
||||
cmd="sed -e 's|ip6-localhost|localhost6|' -i tests/data/test[0-9]*"
|
||||
printf "+ %s\n" "$cmd" >&2
|
||||
eval "$cmd"
|
||||
)
|
||||
|
||||
# regenerate Makefile.in files
|
||||
aclocal -I m4
|
||||
automake
|
||||
|
||||
%build
|
||||
install -d build-full
|
||||
@ -160,13 +158,19 @@ rm -rf ${RPM_BUILD_ROOT}%{_libdir}/libcurl.la
|
||||
%files help
|
||||
%defattr(-,root,root)
|
||||
%doc CHANGES README*
|
||||
%doc docs/BUGS docs/FAQ docs/FEATURES docs/RESOURCES
|
||||
%doc docs/TheArtOfHttpScripting docs/TODO
|
||||
%doc docs/BUGS.md docs/FAQ docs/FEATURES.md
|
||||
%doc docs/TheArtOfHttpScripting.md docs/TODO
|
||||
%{_mandir}/man1/curl.1*
|
||||
%{_mandir}/man1/curl-config.1*
|
||||
%{_mandir}/man3/*
|
||||
|
||||
%changelog
|
||||
* Thu Jul 8 2021 gaihuiying <gaihuiying1@huawei.com> - 7.77.0-1
|
||||
- Type:requirement
|
||||
- CVE:NA
|
||||
- SUG:NA
|
||||
- DESC:update curl to 7.77.0
|
||||
|
||||
* Tue Jun 8 2021 gaihuiying <gaihuiying1@huawei.com> - 7.71.1-9
|
||||
- Type:CVE
|
||||
- CVE:CVE-2021-22897 CVE-2021-22898
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user