import curl-7.61.1-34.el8

i8c-beta changed/i8c-beta/curl-7.61.1-34.el8
MSVSphere Packaging Team 9 months ago
commit 631350412f

@ -0,0 +1,2 @@
c4f38a84efdd1622213b3600168d6305d5c01a30 SOURCES/0043-curl-7.61.1-CVE-2022-35252.patch
8b56123714b4e061f0f71005c5be598b12f82483 SOURCES/curl-7.61.1.tar.xz

2
.gitignore vendored

@ -0,0 +1,2 @@
SOURCES/0043-curl-7.61.1-CVE-2022-35252.patch
SOURCES/curl-7.61.1.tar.xz

@ -0,0 +1,63 @@
From 3cd5b375e31fb98e4782dc3a77e7316ad9eb26cf Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 4 Oct 2018 15:34:13 +0200
Subject: [PATCH] test320: strip out more HTML when comparing
To make the test case work with different gnutls-serv versions better.
Reported-by: Kamil Dudka
Fixes #3093
Closes #3094
Upstream-commit: 94ad57b0246b5658c2a9139dbe6a80efa4c4e2f3
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
tests/data/test320 | 24 ++++--------------------
1 file changed, 4 insertions(+), 20 deletions(-)
diff --git a/tests/data/test320 b/tests/data/test320
index 457a11eb2..87311d4f2 100644
--- a/tests/data/test320
+++ b/tests/data/test320
@@ -62,34 +62,18 @@ simple TLS-SRP HTTPS GET, check user in response
HTTP/1.0 200 OK
Content-type: text/html
-
-<HTML><BODY>
-<CENTER><H1>This is <a href="http://www.gnu.org/software/gnutls">GnuTLS</a></H1></CENTER>
-
-
-
-<h5>If your browser supports session resuming, then you should see the same session ID, when you press the <b>reload</b> button.</h5>
-<p>Connected as user 'jsmith'.</p>
-<P>
-<TABLE border=1><TR><TD></TD></TR>
-<TR><TD>Key Exchange:</TD><TD>SRP</TD></TR>
-<TR><TD>Compression</TD><TD>NULL</TD></TR>
-<TR><TD>Cipher</TD><TD>AES-NNN-CBC</TD></TR>
-<TR><TD>MAC</TD><TD>SHA1</TD></TR>
-<TR><TD>Ciphersuite</TD><TD>SRP_SHA_AES_NNN_CBC_SHA1</TD></TR></p></TABLE>
-<hr><P>Your HTTP header was:<PRE>Host: %HOSTIP:%HTTPTLSPORT
+FINE
User-Agent: curl-test-suite
Accept: */*
-</PRE></P>
-</BODY></HTML>
-
</file>
<stripfile>
-s/^<p>Session ID:.*//
+s/^<p>Connected as user 'jsmith'.*/FINE/
s/Protocol version:.*[0-9]//
s/GNUTLS/GnuTLS/
s/(AES[-_])\d\d\d([-_]CBC)/$1NNN$2/
+s/^<.*\n//
+s/^\n//
</stripfile>
</verify>
--
2.17.1

@ -0,0 +1,28 @@
From c574e05b0035f0d78e6bf6040d3f80430112ab4f Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Fri, 7 Sep 2018 16:50:45 +0200
Subject: [PATCH] docs/cmdline-opts: update the documentation of --tlsv1.0
... to reflect the changes in 6015cefb1b2cfde4b4850121c42405275e5e77d9
Closes #2955
Upstream-commit: 9ba22ce6b52751ed1e2abdd177b0a1d241819b4e
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
docs/cmdline-opts/tlsv1.0.d | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/cmdline-opts/tlsv1.0.d b/docs/cmdline-opts/tlsv1.0.d
index 8789025e0..54e259682 100644
--- a/docs/cmdline-opts/tlsv1.0.d
+++ b/docs/cmdline-opts/tlsv1.0.d
@@ -3,4 +3,4 @@ Help: Use TLSv1.0
Protocols: TLS
Added: 7.34.0
---
-Forces curl to use TLS version 1.0 when connecting to a remote TLS server.
+Forces curl to use TLS version 1.0 or later when connecting to a remote TLS server.
--
2.17.1

@ -0,0 +1,46 @@
From bb8ad3da3fb4ab3f6556daa1f67b259c12a3c7de Mon Sep 17 00:00:00 2001
From: Christian Heimes <christian@python.org>
Date: Fri, 21 Sep 2018 10:37:43 +0200
Subject: [PATCH] OpenSSL: enable TLS 1.3 post-handshake auth
OpenSSL 1.1.1 requires clients to opt-in for post-handshake
authentication.
Fixes: https://github.com/curl/curl/issues/3026
Signed-off-by: Christian Heimes <christian@python.org>
Closes https://github.com/curl/curl/pull/3027
Upstream-commit: b939bc47b27cd57c6ebb852ad653933e4124b452
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/vtls/openssl.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index a487f55..78970d1 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -178,6 +178,7 @@ static unsigned long OpenSSL_version_num(void)
!defined(LIBRESSL_VERSION_NUMBER) && \
!defined(OPENSSL_IS_BORINGSSL))
#define HAVE_SSL_CTX_SET_CIPHERSUITES
+#define HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH
#endif
#if defined(LIBRESSL_VERSION_NUMBER)
@@ -2467,6 +2468,11 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
}
#endif
+#ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH
+ /* OpenSSL 1.1.1 requires clients to opt-in for PHA */
+ SSL_CTX_set_post_handshake_auth(BACKEND->ctx, 1);
+#endif
+
#ifdef USE_TLS_SRP
if(ssl_authtype == CURL_TLSAUTH_SRP) {
char * const ssl_username = SSL_SET_OPTION(username);
--
2.17.1

@ -0,0 +1,81 @@
From 27d6c92acdac671ddf8f77f72956b2181561f774 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Sun, 28 Oct 2018 01:33:23 +0200
Subject: [PATCH 1/2] voutf: fix bad arethmetic when outputting warnings to
stderr
CVE-2018-16842
Reported-by: Brian Carpenter
Bug: https://curl.haxx.se/docs/CVE-2018-16842.html
Upstream-commit: d530e92f59ae9bb2d47066c3c460b25d2ffeb211
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
src/tool_msgs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/tool_msgs.c b/src/tool_msgs.c
index 9cce806..05bec39 100644
--- a/src/tool_msgs.c
+++ b/src/tool_msgs.c
@@ -67,7 +67,7 @@ static void voutf(struct GlobalConfig *config,
(void)fwrite(ptr, cut + 1, 1, config->errors);
fputs("\n", config->errors);
ptr += cut + 1; /* skip the space too */
- len -= cut;
+ len -= cut + 1;
}
else {
fputs(ptr, config->errors);
--
2.17.2
From 23f8c641b02e6c302d0e8cc5a5ee225a33b01f28 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Sun, 28 Oct 2018 10:43:57 +0100
Subject: [PATCH 2/2] test2080: verify the fix for CVE-2018-16842
Upstream-commit: 350306e4726b71b5b386fc30e3fecc039a807157
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
tests/data/Makefile.inc | 4 ++--
tests/data/test2080 | Bin 0 -> 20659 bytes
2 files changed, 2 insertions(+), 2 deletions(-)
create mode 100644 tests/data/test2080
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index e045748..aa5fff0 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -198,7 +198,7 @@ test2048 test2049 test2050 test2051 test2052 test2053 test2054 test2055 \
test2056 test2057 test2058 test2059 test2060 test2061 test2062 test2063 \
test2064 test2065 test2066 test2067 test2068 test2069 \
\
-test2070 test2071 test2072 test2073 \
-test2074 test2075 \
+test2070 test2071 test2072 test2073 test2074 test2075 \
+test2080 \
\
test3000 test3001
diff --git a/tests/data/test2080 b/tests/data/test2080
new file mode 100644
index 0000000000000000000000000000000000000000..47e376ecb5d7879c0a98e392bff48ccc52e9db0a
GIT binary patch
literal 20659
zcmeI)Pj3@35QkyT{uI*`iBshYE(n>u@JB+F3kdG+t~asjwJY0gl}``eO+)FONU8ef
zl6Ca+%<OZ|nCeRHZE>A4K8~q<UAgUD%0ubY=PwtZRG;GL*UIRJ-;Lfy)u}p_A1>dz
zd{+G6l*#ToY+DU||F9%J1n*+KPxQ;7MapuoQ!&MMQSXmpqMh0_yS6g=;N;HNjilBk
zY$c?)mULZxib{;$g~jw~nrs|8b@sJI)_QmS_4(WLrNld}2Y0LEO$e>m->_NA&o$n!
z9^YDZ>cvMs2q1s}0tg_000PG)@a?$9VHyMwKmY**5I_I{1Q0m1z~!MEP#*yV5I_I{
z1Q0*~0R#|0009ILKmY**4ldvh-hl=PAb<b@2q1s}0tg`Rgaqum{m<+P&C93=Ab<b@
z2q1s}0tg_0z|jf3Ji3V(2mu5TK;StGoIK~3=iL!N0D=D{@VjlsoA=?(>-+Xw`j-8D
zzg+g?Rt8(G*s;1Sb>n1S94H%G<kGn)tFlRTrA%AW*RoyP3pi(fe!mc3WU^sQd2)l4
jB)+~1L0rx$OS-AbERTH}TH`mZ^*=|W_vMU!*i-li)g+9V
literal 0
HcmV?d00001
--
2.17.2

@ -0,0 +1,39 @@
From 235f209a0e62edee654be441a50bb0c154edeaa5 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 18 Oct 2018 15:07:15 +0200
Subject: [PATCH] Curl_close: clear data->multi_easy on free to avoid
use-after-free
Regression from b46cfbc068 (7.59.0)
CVE-2018-16840
Reported-by: Brian Carpenter (Geeknik Labs)
Bug: https://curl.haxx.se/docs/CVE-2018-16840.html
Upstream-commit: 81d135d67155c5295b1033679c606165d4e28f3f
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/url.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lib/url.c b/lib/url.c
index f159008..dcc1ecc 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -319,10 +319,12 @@ CURLcode Curl_close(struct Curl_easy *data)
and detach this handle from there. */
curl_multi_remove_handle(data->multi, data);
- if(data->multi_easy)
+ if(data->multi_easy) {
/* when curl_easy_perform() is used, it creates its own multi handle to
use and this is the one */
curl_multi_cleanup(data->multi_easy);
+ data->multi_easy = NULL;
+ }
/* Destroy the timeout list that is held in the easy handle. It is
/normally/ done by curl_multi_remove_handle() but this is "just in
--
2.17.2

@ -0,0 +1,31 @@
From ad9943254ded9a983af7d581e8a1f3317e8a8781 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Fri, 28 Sep 2018 16:08:16 +0200
Subject: [PATCH] Curl_auth_create_plain_message: fix too-large-input-check
CVE-2018-16839
Reported-by: Harry Sintonen
Bug: https://curl.haxx.se/docs/CVE-2018-16839.html
Upstream-commit: f3a24d7916b9173c69a3e0ee790102993833d6c5
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/vauth/cleartext.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/vauth/cleartext.c b/lib/vauth/cleartext.c
index 5d61ce6..1367143 100644
--- a/lib/vauth/cleartext.c
+++ b/lib/vauth/cleartext.c
@@ -74,7 +74,7 @@ CURLcode Curl_auth_create_plain_message(struct Curl_easy *data,
plen = strlen(passwdp);
/* Compute binary message length. Check for overflows. */
- if((ulen > SIZE_T_MAX/2) || (plen > (SIZE_T_MAX/2 - 2)))
+ if((ulen > SIZE_T_MAX/4) || (plen > (SIZE_T_MAX/2 - 2)))
return CURLE_OUT_OF_MEMORY;
plainlen = 2 * ulen + plen + 2;
--
2.17.2

@ -0,0 +1,116 @@
From ff74657fb645e7175971128a171ef7d5ece40d77 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 17 Dec 2018 12:51:51 +0100
Subject: [PATCH] curl -J: do not append to the destination file
Reported-by: Kamil Dudka
Fixes #3380
Closes #3381
Upstream-commit: 4849267197682e69cfa056c2bd7a44acd123a917
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
src/tool_cb_hdr.c | 6 +++---
src/tool_cb_wrt.c | 9 ++++-----
src/tool_cb_wrt.h | 2 +-
src/tool_operate.c | 2 +-
4 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/src/tool_cb_hdr.c b/src/tool_cb_hdr.c
index 84b0d9c..3844904 100644
--- a/src/tool_cb_hdr.c
+++ b/src/tool_cb_hdr.c
@@ -148,12 +148,12 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata)
outs->filename = filename;
outs->alloc_filename = TRUE;
hdrcbdata->honor_cd_filename = FALSE; /* done now! */
- if(!tool_create_output_file(outs, TRUE))
+ if(!tool_create_output_file(outs))
return failure;
}
break;
}
- if(!outs->stream && !tool_create_output_file(outs, FALSE))
+ if(!outs->stream && !tool_create_output_file(outs))
return failure;
}
@@ -162,7 +162,7 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata)
/* bold headers only happen for HTTP(S) and RTSP */
char *value = NULL;
- if(!outs->stream && !tool_create_output_file(outs, FALSE))
+ if(!outs->stream && !tool_create_output_file(outs))
return failure;
if(hdrcbdata->global->isatty && hdrcbdata->global->styled_output)
diff --git a/src/tool_cb_wrt.c b/src/tool_cb_wrt.c
index 2cb5e1b..195d6e7 100644
--- a/src/tool_cb_wrt.c
+++ b/src/tool_cb_wrt.c
@@ -32,8 +32,7 @@
#include "memdebug.h" /* keep this as LAST include */
/* create a local file for writing, return TRUE on success */
-bool tool_create_output_file(struct OutStruct *outs,
- bool append)
+bool tool_create_output_file(struct OutStruct *outs)
{
struct GlobalConfig *global = outs->config->global;
FILE *file;
@@ -43,7 +42,7 @@ bool tool_create_output_file(struct OutStruct *outs,
return FALSE;
}
- if(outs->is_cd_filename && !append) {
+ if(outs->is_cd_filename) {
/* don't overwrite existing files */
file = fopen(outs->filename, "rb");
if(file) {
@@ -55,7 +54,7 @@ bool tool_create_output_file(struct OutStruct *outs,
}
/* open file for writing */
- file = fopen(outs->filename, append?"ab":"wb");
+ file = fopen(outs->filename, "wb");
if(!file) {
warnf(global, "Failed to create the file %s: %s\n", outs->filename,
strerror(errno));
@@ -142,7 +141,7 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata)
}
#endif
- if(!outs->stream && !tool_create_output_file(outs, FALSE))
+ if(!outs->stream && !tool_create_output_file(outs))
return failure;
if(is_tty && (outs->bytes < 2000) && !config->terminal_binary_ok) {
diff --git a/src/tool_cb_wrt.h b/src/tool_cb_wrt.h
index 51e002b..188d3ea 100644
--- a/src/tool_cb_wrt.h
+++ b/src/tool_cb_wrt.h
@@ -30,7 +30,7 @@
size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata);
/* create a local file for writing, return TRUE on success */
-bool tool_create_output_file(struct OutStruct *outs, bool append);
+bool tool_create_output_file(struct OutStruct *outs);
#endif /* HEADER_CURL_TOOL_CB_WRT_H */
diff --git a/src/tool_operate.c b/src/tool_operate.c
index e53a9d8..429e9cf 100644
--- a/src/tool_operate.c
+++ b/src/tool_operate.c
@@ -1581,7 +1581,7 @@ static CURLcode operate_do(struct GlobalConfig *global,
/* do not create (or even overwrite) the file in case we get no
data because of unmet condition */
curl_easy_getinfo(curl, CURLINFO_CONDITION_UNMET, &cond_unmet);
- if(!cond_unmet && !tool_create_output_file(&outs, FALSE))
+ if(!cond_unmet && !tool_create_output_file(&outs))
result = CURLE_WRITE_ERROR;
}
--
2.17.2

File diff suppressed because it is too large Load Diff

@ -0,0 +1,36 @@
From 81c0e81531623251a0e78f7779c049f530abe733 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Wed, 2 Jan 2019 20:33:08 +0100
Subject: [PATCH] NTLM: fix size check condition for type2 received data
Bug: https://curl.haxx.se/docs/CVE-2018-16890.html
Reported-by: Wenxiang Qian
CVE-2018-16890
Upstream-commit: b780b30d1377adb10bbe774835f49e9b237fb9bb
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/vauth/ntlm.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/lib/vauth/ntlm.c b/lib/vauth/ntlm.c
index cdb8d8f..b614cda 100644
--- a/lib/vauth/ntlm.c
+++ b/lib/vauth/ntlm.c
@@ -182,10 +182,11 @@ static CURLcode ntlm_decode_type2_target(struct Curl_easy *data,
target_info_len = Curl_read16_le(&buffer[40]);
target_info_offset = Curl_read32_le(&buffer[44]);
if(target_info_len > 0) {
- if(((target_info_offset + target_info_len) > size) ||
+ if((target_info_offset >= size) ||
+ ((target_info_offset + target_info_len) > size) ||
(target_info_offset < 48)) {
infof(data, "NTLM handshake failure (bad type-2 message). "
- "Target Info Offset Len is set incorrect by the peer\n");
+ "Target Info Offset Len is set incorrect by the peer\n");
return CURLE_BAD_CONTENT_ENCODING;
}
--
2.17.2

@ -0,0 +1,41 @@
From ab22e3a00f04b458039c21111cfa448051e5777d Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 3 Jan 2019 12:59:28 +0100
Subject: [PATCH] ntlm: fix *_type3_message size check to avoid buffer overflow
Bug: https://curl.haxx.se/docs/CVE-2019-3822.html
Reported-by: Wenxiang Qian
CVE-2019-3822
Upstream-commit: 50c9484278c63b958655a717844f0721263939cc
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/vauth/ntlm.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/lib/vauth/ntlm.c b/lib/vauth/ntlm.c
index b614cda..a3a55d9 100644
--- a/lib/vauth/ntlm.c
+++ b/lib/vauth/ntlm.c
@@ -777,11 +777,14 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
});
#ifdef USE_NTRESPONSES
- if(size < (NTLM_BUFSIZE - ntresplen)) {
- DEBUGASSERT(size == (size_t)ntrespoff);
- memcpy(&ntlmbuf[size], ptr_ntresp, ntresplen);
- size += ntresplen;
+ /* ntresplen + size should not be risking an integer overflow here */
+ if(ntresplen + size > sizeof(ntlmbuf)) {
+ failf(data, "incoming NTLM message too big");
+ return CURLE_OUT_OF_MEMORY;
}
+ DEBUGASSERT(size == (size_t)ntrespoff);
+ memcpy(&ntlmbuf[size], ptr_ntresp, ntresplen);
+ size += ntresplen;
DEBUG_OUT({
fprintf(stderr, "\n ntresp=");
--
2.17.2

@ -0,0 +1,50 @@
From d26f1025d0a0a6c602d758a2e0917759492473e9 Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <daniel@yesql.se>
Date: Sat, 19 Jan 2019 00:42:47 +0100
Subject: [PATCH] smtp: avoid risk of buffer overflow in strtol
If the incoming len 5, but the buffer does not have a termination
after 5 bytes, the strtol() call may keep reading through the line
buffer until is exceeds its boundary. Fix by ensuring that we are
using a bounded read with a temporary buffer on the stack.
Bug: https://curl.haxx.se/docs/CVE-2019-3823.html
Reported-by: Brian Carpenter (Geeknik Labs)
CVE-2019-3823
Upstream-commit: 39df4073e5413fcdbb5a38da0c1ce6f1c0ceb484
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/smtp.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/lib/smtp.c b/lib/smtp.c
index ecf10a4..1b9f92d 100644
--- a/lib/smtp.c
+++ b/lib/smtp.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, 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
@@ -207,8 +207,12 @@ static bool smtp_endofresp(struct connectdata *conn, char *line, size_t len,
Section 4. Examples of RFC-4954 but some e-mail servers ignore this and
only send the response code instead as per Section 4.2. */
if(line[3] == ' ' || len == 5) {
+ char tmpline[6];
+
result = TRUE;
- *resp = curlx_sltosi(strtol(line, NULL, 10));
+ memset(tmpline, '\0', sizeof(tmpline));
+ memcpy(tmpline, line, (len == 5 ? 5 : 3));
+ *resp = curlx_sltosi(strtol(tmpline, NULL, 10));
/* Make sure real server never sends internal value */
if(*resp == 1)
--
2.17.2

@ -0,0 +1,66 @@
From 095d4cf3b1c388b2871e3783f8c41b1e01200a25 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Felix=20H=C3=A4dicke?= <felixhaedicke@web.de>
Date: Wed, 23 Jan 2019 23:47:55 +0100
Subject: [PATCH] libssh: do not let libssh create socket
By default, libssh creates a new socket, instead of using the socket
created by curl for SSH connections.
Pass the socket created by curl to libssh using ssh_options_set() with
SSH_OPTIONS_FD directly after ssh_new(). So libssh uses our socket
instead of creating a new one.
This approach is very similar to what is done in the libssh2 code, where
the socket created by curl is passed to libssh2 when
libssh2_session_startup() is called.
Fixes #3491
Closes #3495
Upstream-commit: 15c94b310bf9e0c92d71fca5a88eb67a1e2548a6
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/ssh-libssh.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/lib/ssh-libssh.c b/lib/ssh-libssh.c
index 7d59089..4110be2 100644
--- a/lib/ssh-libssh.c
+++ b/lib/ssh-libssh.c
@@ -549,6 +549,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
struct Curl_easy *data = conn->data;
struct SSHPROTO *protop = data->req.protop;
struct ssh_conn *sshc = &conn->proto.sshc;
+ curl_socket_t sock = conn->sock[FIRSTSOCKET];
int rc = SSH_NO_ERROR, err;
char *new_readdir_line;
int seekerr = CURL_SEEKFUNC_OK;
@@ -792,7 +793,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
- conn->sockfd = ssh_get_fd(sshc->ssh_session);
+ conn->sockfd = sock;
conn->writesockfd = CURL_SOCKET_BAD;
if(conn->handler->protocol == CURLPROTO_SFTP) {
@@ -2048,6 +2049,7 @@ static CURLcode myssh_connect(struct connectdata *conn, bool *done)
{
struct ssh_conn *ssh;
CURLcode result;
+ curl_socket_t sock = conn->sock[FIRSTSOCKET];
struct Curl_easy *data = conn->data;
int rc;
@@ -2076,6 +2078,8 @@ static CURLcode myssh_connect(struct connectdata *conn, bool *done)
return CURLE_FAILED_INIT;
}
+ ssh_options_set(ssh->ssh_session, SSH_OPTIONS_FD, &sock);
+
if(conn->user) {
infof(data, "User: %s\n", conn->user);
ssh_options_set(ssh->ssh_session, SSH_OPTIONS_USER, conn->user);
--
2.17.2

@ -0,0 +1,31 @@
From 55a27027d5f024a0ecc2c23c81ed99de6192c9f3 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Fri, 3 May 2019 22:20:37 +0200
Subject: [PATCH] tftp: use the current blksize for recvfrom()
bug: https://curl.haxx.se/docs/CVE-2019-5436.html
Reported-by: l00p3r on hackerone
CVE-2019-5436
Upstream-commit: 2576003415625d7b5f0e390902f8097830b82275
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/tftp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/tftp.c b/lib/tftp.c
index 269b3cd..4f2a131 100644
--- a/lib/tftp.c
+++ b/lib/tftp.c
@@ -1005,7 +1005,7 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done)
state->sockfd = state->conn->sock[FIRSTSOCKET];
state->state = TFTP_STATE_START;
state->error = TFTP_ERR_NONE;
- state->blksize = TFTP_BLKSIZE_DEFAULT;
+ state->blksize = blksize;
state->requested_blksize = blksize;
((struct sockaddr *)&state->local_addr)->sa_family =
--
2.20.1

@ -0,0 +1,158 @@
From 63f9837b4ccf600da79314e8667f91bda69988fc Mon Sep 17 00:00:00 2001
From: Thomas Vegas <>
Date: Sat, 31 Aug 2019 16:59:56 +0200
Subject: [PATCH 1/2] tftp: return error when packet is too small for options
Upstream-commit: 82f3ba3806a34fe94dcf9e5c9b88deda6679ca1b
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/tftp.c | 53 +++++++++++++++++++++++++++++++++--------------------
1 file changed, 33 insertions(+), 20 deletions(-)
diff --git a/lib/tftp.c b/lib/tftp.c
index 289cda2..4532170 100644
--- a/lib/tftp.c
+++ b/lib/tftp.c
@@ -404,13 +404,14 @@ static CURLcode tftp_parse_option_ack(tftp_state_data_t *state,
return CURLE_OK;
}
-static size_t tftp_option_add(tftp_state_data_t *state, size_t csize,
- char *buf, const char *option)
+static CURLcode tftp_option_add(tftp_state_data_t *state, size_t *csize,
+ char *buf, const char *option)
{
- if(( strlen(option) + csize + 1) > (size_t)state->blksize)
- return 0;
+ if(( strlen(option) + *csize + 1) > (size_t)state->blksize)
+ return CURLE_TFTP_ILLEGAL;
strcpy(buf, option);
- return strlen(option) + 1;
+ *csize += strlen(option) + 1;
+ return CURLE_OK;
}
static CURLcode tftp_connect_for_tx(tftp_state_data_t *state,
@@ -511,26 +512,38 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
else
strcpy(buf, "0"); /* the destination is large enough */
- sbytes += tftp_option_add(state, sbytes,
- (char *)state->spacket.data + sbytes,
- TFTP_OPTION_TSIZE);
- sbytes += tftp_option_add(state, sbytes,
- (char *)state->spacket.data + sbytes, buf);
+ result = tftp_option_add(state, &sbytes,
+ (char *)state->spacket.data + sbytes,
+ TFTP_OPTION_TSIZE);
+ if(result == CURLE_OK)
+ result = tftp_option_add(state, &sbytes,
+ (char *)state->spacket.data + sbytes, buf);
+
/* add blksize option */
snprintf(buf, sizeof(buf), "%d", state->requested_blksize);
- sbytes += tftp_option_add(state, sbytes,
- (char *)state->spacket.data + sbytes,
- TFTP_OPTION_BLKSIZE);
- sbytes += tftp_option_add(state, sbytes,
- (char *)state->spacket.data + sbytes, buf);
+ if(result == CURLE_OK)
+ result = tftp_option_add(state, &sbytes,
+ (char *)state->spacket.data + sbytes,
+ TFTP_OPTION_BLKSIZE);
+ if(result == CURLE_OK)
+ result = tftp_option_add(state, &sbytes,
+ (char *)state->spacket.data + sbytes, buf);
/* add timeout option */
snprintf(buf, sizeof(buf), "%d", state->retry_time);
- sbytes += tftp_option_add(state, sbytes,
- (char *)state->spacket.data + sbytes,
- TFTP_OPTION_INTERVAL);
- sbytes += tftp_option_add(state, sbytes,
- (char *)state->spacket.data + sbytes, buf);
+ if(result == CURLE_OK)
+ result = tftp_option_add(state, &sbytes,
+ (char *)state->spacket.data + sbytes,
+ TFTP_OPTION_INTERVAL);
+ if(result == CURLE_OK)
+ result = tftp_option_add(state, &sbytes,
+ (char *)state->spacket.data + sbytes, buf);
+
+ if(result != CURLE_OK) {
+ failf(data, "TFTP buffer too small for options");
+ free(filename);
+ return CURLE_TFTP_ILLEGAL;
+ }
}
/* the typecase for the 3rd argument is mostly for systems that do
--
2.20.1
From b6b12a4cfe00c4850a1d6cee4cf267f00dee5987 Mon Sep 17 00:00:00 2001
From: Thomas Vegas <>
Date: Sat, 31 Aug 2019 17:30:51 +0200
Subject: [PATCH 2/2] tftp: Alloc maximum blksize, and use default unless OACK
is received
Fixes potential buffer overflow from 'recvfrom()', should the server
return an OACK without blksize.
Bug: https://curl.haxx.se/docs/CVE-2019-5482.html
CVE-2019-5482
Upstream-commit: facb0e4662415b5f28163e853dc6742ac5fafb3d
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/tftp.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/lib/tftp.c b/lib/tftp.c
index 4532170..5651b62 100644
--- a/lib/tftp.c
+++ b/lib/tftp.c
@@ -982,6 +982,7 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done)
{
tftp_state_data_t *state;
int blksize;
+ int need_blksize;
blksize = TFTP_BLKSIZE_DEFAULT;
@@ -996,15 +997,20 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done)
return CURLE_TFTP_ILLEGAL;
}
+ need_blksize = blksize;
+ /* default size is the fallback when no OACK is received */
+ if(need_blksize < TFTP_BLKSIZE_DEFAULT)
+ need_blksize = TFTP_BLKSIZE_DEFAULT;
+
if(!state->rpacket.data) {
- state->rpacket.data = calloc(1, blksize + 2 + 2);
+ state->rpacket.data = calloc(1, need_blksize + 2 + 2);
if(!state->rpacket.data)
return CURLE_OUT_OF_MEMORY;
}
if(!state->spacket.data) {
- state->spacket.data = calloc(1, blksize + 2 + 2);
+ state->spacket.data = calloc(1, need_blksize + 2 + 2);
if(!state->spacket.data)
return CURLE_OUT_OF_MEMORY;
@@ -1018,7 +1024,7 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done)
state->sockfd = state->conn->sock[FIRSTSOCKET];
state->state = TFTP_STATE_START;
state->error = TFTP_ERR_NONE;
- state->blksize = blksize;
+ state->blksize = TFTP_BLKSIZE_DEFAULT; /* Unless updated by OACK response */
state->requested_blksize = blksize;
((struct sockaddr *)&state->local_addr)->sa_family =
--
2.20.1

@ -0,0 +1,46 @@
From 13de299b112a59c373b330f0539166ecc9a7627b Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Tue, 3 Sep 2019 22:59:32 +0200
Subject: [PATCH] security:read_data fix bad realloc()
... that could end up a double-free
CVE-2019-5481
Bug: https://curl.haxx.se/docs/CVE-2019-5481.html
Upstream-commit: 9069838b30fb3b48af0123e39f664cea683254a5
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/security.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/lib/security.c b/lib/security.c
index 550ea2d..c5e4e13 100644
--- a/lib/security.c
+++ b/lib/security.c
@@ -191,7 +191,6 @@ static CURLcode read_data(struct connectdata *conn,
struct krb5buffer *buf)
{
int len;
- void *tmp = NULL;
CURLcode result;
result = socket_read(fd, &len, sizeof(len));
@@ -201,12 +200,11 @@ static CURLcode read_data(struct connectdata *conn,
if(len) {
/* only realloc if there was a length */
len = ntohl(len);
- tmp = Curl_saferealloc(buf->data, len);
+ buf->data = Curl_saferealloc(buf->data, len);
}
- if(tmp == NULL)
+ if(!len || !buf->data)
return CURLE_OUT_OF_MEMORY;
- buf->data = tmp;
result = socket_read(fd, buf->data, len);
if(result)
return result;
--
2.20.1

@ -0,0 +1,33 @@
From 032843be4cefcb163d15573d15a228680e771106 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
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 <kdudka@redhat.com>
---
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

@ -0,0 +1,59 @@
From a6fcd8a32f3b1c5d80e524f8b2c1de32e6ecdb2b Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
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 <kdudka@redhat.com>
---
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

@ -0,0 +1,143 @@
From 7a26092a9e21f1e0dc3cad69a580a7e2c7822ad0 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
Upstream-commit: 3c9e021f86872baae412a427e807fbfa2f3e8a22
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
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

@ -0,0 +1,60 @@
From 9d5903ebcbcbcc4f3a997ec7d5552721c5383b9f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Ba=C5=A1ti?= <mbasti@redhat.com>
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 <curl/curl.h>
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 <kdudka@redhat.com>
---
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

@ -0,0 +1,291 @@
From 673adb0a7a21ca3a877ee03dc9e197d5be15a9d3 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
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 <kdudka@redhat.com>
---
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 <daniel@haxx.se>
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 <kdudka@redhat.com>
---
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 <daniel@haxx.se>
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 <kdudka@redhat.com>
---
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, <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
@@ -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

@ -0,0 +1,208 @@
From 2629f42d4cfdd04df0544007b03161e3d5d52d54 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
Upstream-commit: ec9cc725d598ac77de7b6df8afeec292b3c8ad46
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
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, <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
@@ -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

@ -0,0 +1,258 @@
From 22b3d1cf0216f4369f01678c587da265c2e465af 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
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 <kdudka@redhat.com>
---
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

@ -0,0 +1,129 @@
From 2470bc91f62cc9b0ab1deac60a67f87b7cc95f6e 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
Upstream-commit: d9d01672785b8ac04aab1abb6de95fe3072ae199
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
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

@ -0,0 +1,63 @@
From 5a51924c2505c1d5616904aa732fdaedd74d3ffe Mon Sep 17 00:00:00 2001
From: Marc Schlatter <mschlatter@gestour.com>
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 <kdudka@redhat.com>
---
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
<strip>
^User-Agent: curl/.*
</strip>
-<protocol>
+<protocol nonewline="yes">
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
</protocol>
</verify>
--
2.26.2

@ -0,0 +1,116 @@
From 239f8d93866605b05f4e6b551f4327dc7fcb922b Mon Sep 17 00:00:00 2001
From: Viktor Szakats <commit@vsz.me>
Date: Tue, 23 Feb 2021 14:54:46 +0100
Subject: [PATCH 1/2] transfer: strip credentials from the auto-referer header
field
Added test 2081 to verify.
CVE-2021-22876
Bug: https://curl.se/docs/CVE-2021-22876.html
Upstream-commit: 7214288898f5625a6cc196e22a74232eada7861c
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/transfer.c | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/lib/transfer.c b/lib/transfer.c
index ecd1063..263b178 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -1473,6 +1473,7 @@ CURLcode Curl_follow(struct Curl_easy *data,
/* Location: redirect */
bool disallowport = FALSE;
bool reachedmax = FALSE;
+ CURLUcode uc;
if(type == FOLLOW_REDIR) {
if((data->set.maxredirs != -1) &&
@@ -1488,6 +1489,9 @@ CURLcode Curl_follow(struct Curl_easy *data,
data->set.followlocation++; /* count location-followers */
if(data->set.http_auto_referer) {
+ CURLU *u;
+ char *referer;
+
/* We are asked to automatically set the previous URL as the referer
when we get the next URL. We pick the ->url field, which may or may
not be 100% correct */
@@ -1497,9 +1501,26 @@ CURLcode Curl_follow(struct Curl_easy *data,
data->change.referer_alloc = FALSE;
}
- data->change.referer = strdup(data->change.url);
- if(!data->change.referer)
+ /* Make a copy of the URL without crenditals and fragment */
+ u = curl_url();
+ if(!u)
+ return CURLE_OUT_OF_MEMORY;
+
+ uc = curl_url_set(u, CURLUPART_URL, data->change.url, 0);
+ if(!uc)
+ uc = curl_url_set(u, CURLUPART_FRAGMENT, NULL, 0);
+ if(!uc)
+ uc = curl_url_set(u, CURLUPART_USER, NULL, 0);
+ if(!uc)
+ uc = curl_url_set(u, CURLUPART_PASSWORD, NULL, 0);
+ if(!uc)
+ uc = curl_url_get(u, CURLUPART_URL, &referer, 0);
+
+ curl_url_cleanup(u);
+
+ if(uc || referer == NULL)
return CURLE_OUT_OF_MEMORY;
+ data->change.referer = referer;
data->change.referer_alloc = TRUE; /* yes, free this later */
}
}
--
2.30.2
From f7d1d478b87499ce31d6aa3251830b78447ad952 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 29 Mar 2021 09:32:14 +0200
Subject: [PATCH 2/2] transfer: clear 'referer' in declaration
To silence (false positive) compiler warnings about it.
Follow-up to 7214288898f5625
Reviewed-by: Marcel Raad
Closes #6810
Upstream-commit: 6bb028dbda6cbfe83f66de773544f71e4813160f
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/transfer.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/transfer.c b/lib/transfer.c
index 263b178..ad5a7ba 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -1490,7 +1490,7 @@ CURLcode Curl_follow(struct Curl_easy *data,
if(data->set.http_auto_referer) {
CURLU *u;
- char *referer;
+ char *referer = NULL;
/* We are asked to automatically set the previous URL as the referer
when we get the next URL. We pick the ->url field, which may or may
@@ -1518,7 +1518,7 @@ CURLcode Curl_follow(struct Curl_easy *data,
curl_url_cleanup(u);
- if(uc || referer == NULL)
+ if(uc || !referer)
return CURLE_OUT_OF_MEMORY;
data->change.referer = referer;
data->change.referer_alloc = TRUE; /* yes, free this later */
--
2.30.2

@ -0,0 +1,693 @@
From 87e3d094e0dc00efc1abeb2b142d453024cbca69 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 4 Oct 2018 23:53:32 +0200
Subject: [PATCH] FILE: fix CURLOPT_NOBODY and CURLOPT_HEADER output
Now FILE transfers send headers to the header callback like HTTP and
other protocols. Also made curl_easy_getinfo(...CURLINFO_PROTOCOL...)
work for FILE in the callbacks.
Makes "curl -i file://.." and "curl -I file://.." work like before
again. Applied the bold header logic to them too.
Regression from c1c2762 (7.61.0)
Reported-by: Shaun Jackman
Fixes #3083
Closes #3101
Upstream-commit: e50a2002bd450a4800a165d2874ed79c95b33a07
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/file.c | 27 +++++++++++++--------------
lib/getinfo.c | 1 -
lib/url.c | 1 +
src/tool_cb_hdr.c | 5 +++--
tests/data/test1016 | 2 +-
tests/data/test1017 | 2 +-
tests/data/test1018 | 2 +-
tests/data/test1019 | 2 +-
tests/data/test1020 | 2 +-
tests/data/test1029 | 2 +-
tests/data/test1146 | 2 +-
tests/data/test1220 | 2 +-
tests/data/test200 | 2 +-
tests/data/test2000 | 2 +-
tests/data/test2001 | 13 +------------
tests/data/test2002 | 13 +------------
tests/data/test2003 | 26 ++------------------------
tests/data/test2004 | 2 +-
tests/data/test2006 | 8 ++++++++
tests/data/test2007 | 8 ++++++++
tests/data/test2008 | 8 ++++++++
tests/data/test2009 | 8 ++++++++
tests/data/test2010 | 8 ++++++++
tests/data/test202 | 2 +-
tests/data/test203 | 2 +-
tests/data/test204 | 2 +-
tests/data/test205 | 2 +-
tests/data/test2070 | 2 +-
tests/data/test2071 | 2 +-
tests/data/test2072 | 2 +-
tests/data/test210 | 2 +-
tests/data/test231 | 2 +-
tests/data/test288 | 2 +-
33 files changed, 82 insertions(+), 86 deletions(-)
diff --git a/lib/file.c b/lib/file.c
index e50e988..f780658 100644
--- a/lib/file.c
+++ b/lib/file.c
@@ -386,7 +386,6 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
*done = TRUE; /* unconditionally */
- Curl_initinfo(data);
Curl_pgrsStartNow(data);
if(data->set.upload)
@@ -413,21 +412,18 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
}
}
- /* If we have selected NOBODY and HEADER, it means that we only want file
- information. Which for FILE can't be much more than the file size and
- date. */
- if(data->set.opt_no_body && data->set.include_header && fstated) {
+ if(fstated) {
time_t filetime;
struct tm buffer;
const struct tm *tm = &buffer;
char header[80];
snprintf(header, sizeof(header),
"Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", expected_size);
- result = Curl_client_write(conn, CLIENTWRITE_BOTH, header, 0);
+ result = Curl_client_write(conn, CLIENTWRITE_HEADER, header, 0);
if(result)
return result;
- result = Curl_client_write(conn, CLIENTWRITE_BOTH,
+ result = Curl_client_write(conn, CLIENTWRITE_HEADER,
(char *)"Accept-ranges: bytes\r\n", 0);
if(result)
return result;
@@ -439,19 +435,22 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
/* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
snprintf(header, sizeof(header),
- "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
+ "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n%s",
Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
tm->tm_mday,
Curl_month[tm->tm_mon],
tm->tm_year + 1900,
tm->tm_hour,
tm->tm_min,
- tm->tm_sec);
- result = Curl_client_write(conn, CLIENTWRITE_BOTH, header, 0);
- if(!result)
- /* set the file size to make it available post transfer */
- Curl_pgrsSetDownloadSize(data, expected_size);
- return result;
+ tm->tm_sec,
+ data->set.opt_no_body ? "": "\r\n");
+ result = Curl_client_write(conn, CLIENTWRITE_HEADER, header, 0);
+ if(result)
+ return result;
+ /* set the file size to make it available post transfer */
+ Curl_pgrsSetDownloadSize(data, expected_size);
+ if(data->set.opt_no_body)
+ return result;
}
/* Check whether file range has been specified */
diff --git a/lib/getinfo.c b/lib/getinfo.c
index 14b4562..54c2c2f 100644
--- a/lib/getinfo.c
+++ b/lib/getinfo.c
@@ -85,7 +85,6 @@ CURLcode Curl_initinfo(struct Curl_easy *data)
#ifdef USE_SSL
Curl_ssl_free_certinfo(data);
#endif
-
return CURLE_OK;
}
diff --git a/lib/url.c b/lib/url.c
index b18db25..bb9d107 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -4290,6 +4290,7 @@ static CURLcode create_conn(struct Curl_easy *data,
/* this is supposed to be the connect function so we better at least check
that the file is present here! */
DEBUGASSERT(conn->handler->connect_it);
+ Curl_persistconninfo(conn);
result = conn->handler->connect_it(conn, &done);
/* Setup a "faked" transfer that'll do nothing */
diff --git a/src/tool_cb_hdr.c b/src/tool_cb_hdr.c
index e91e8ac..4f21221 100644
--- a/src/tool_cb_hdr.c
+++ b/src/tool_cb_hdr.c
@@ -153,8 +153,9 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata)
}
if(hdrcbdata->config->show_headers &&
- (protocol & (CURLPROTO_HTTP|CURLPROTO_HTTPS|CURLPROTO_RTSP))) {
- /* bold headers only happen for HTTP(S) and RTSP */
+ (protocol &
+ (CURLPROTO_HTTP|CURLPROTO_HTTPS|CURLPROTO_RTSP|CURLPROTO_FILE))) {
+ /* bold headers only for selected protocols */
char *value = NULL;
if(!outs->stream && !tool_create_output_file(outs))
diff --git a/tests/data/test1016 b/tests/data/test1016
index b404cac..4927f9e 100644
--- a/tests/data/test1016
+++ b/tests/data/test1016
@@ -22,7 +22,7 @@ file
<name>
X-Y range on a file:// URL to stdout
</name>
- <command>
+<command option="no-include">
-r 1-4 file://localhost/%PWD/log/test1016.txt
</command>
<file name="log/test1016.txt">
diff --git a/tests/data/test1017 b/tests/data/test1017
index 6fbc38a..cfdd80f 100644
--- a/tests/data/test1017
+++ b/tests/data/test1017
@@ -23,7 +23,7 @@ file
<name>
0-Y range on a file:// URL to stdout
</name>
- <command>
+<command option="no-include">
-r 0-3 file://localhost/%PWD/log/test1017.txt
</command>
<file name="log/test1017.txt">
diff --git a/tests/data/test1018 b/tests/data/test1018
index 28a7027..5748701 100644
--- a/tests/data/test1018
+++ b/tests/data/test1018
@@ -22,7 +22,7 @@ file
<name>
X-X range on a file:// URL to stdout
</name>
- <command>
+<command option="no-include">
-r 4-4 file://localhost/%PWD/log/test1018.txt
</command>
<file name="log/test1018.txt">
diff --git a/tests/data/test1019 b/tests/data/test1019
index 4d9872a..054e38d 100644
--- a/tests/data/test1019
+++ b/tests/data/test1019
@@ -23,7 +23,7 @@ file
<name>
X- range on a file:// URL to stdout
</name>
- <command>
+<command option="no-include">
-r 7- file://localhost/%PWD/log/test1019.txt
</command>
<file name="log/test1019.txt">
diff --git a/tests/data/test1020 b/tests/data/test1020
index 735871d..e924529 100644
--- a/tests/data/test1020
+++ b/tests/data/test1020
@@ -23,7 +23,7 @@ file
<name>
-Y range on a file:// URL to stdout
</name>
- <command>
+<command option="no-include">
-r -9 file://localhost/%PWD/log/test1020.txt
</command>
<file name="log/test1020.txt">
diff --git a/tests/data/test1029 b/tests/data/test1029
index 2ffc7c6..c77209c 100644
--- a/tests/data/test1029
+++ b/tests/data/test1029
@@ -29,7 +29,7 @@ http
<name>
HTTP Location: and 'redirect_url' check
</name>
- <command>
+<command>
http://%HOSTIP:%HTTPPORT/we/want/our/1029 -w '%{redirect_url}\n'
</command>
</client>
diff --git a/tests/data/test1146 b/tests/data/test1146
index 43f33b7..636748e 100644
--- a/tests/data/test1146
+++ b/tests/data/test1146
@@ -24,7 +24,7 @@ file
<name>
--proto-default file
</name>
-<command>
+<command option="no-include">
--proto-default file %PWD/log/test1146.txt
</command>
<file name="log/test1146.txt">
diff --git a/tests/data/test1220 b/tests/data/test1220
index 959abbf..6752eb5 100644
--- a/tests/data/test1220
+++ b/tests/data/test1220
@@ -20,7 +20,7 @@ file
<name>
file:// URLs with query string
</name>
- <command>
+<command option="no-include">
file://localhost/%PWD/log/test1220.txt?a_query=foobar#afragment
</command>
<file name="log/test1220.txt">
diff --git a/tests/data/test200 b/tests/data/test200
index 8be1de0..c27f7c0 100644
--- a/tests/data/test200
+++ b/tests/data/test200
@@ -23,7 +23,7 @@ file
<name>
basic file:// file
</name>
- <command>
+<command option="no-include">
file://localhost/%PWD/log/test200.txt
</command>
<file name="log/test200.txt">
diff --git a/tests/data/test2000 b/tests/data/test2000
index d3edb16..db1ba13 100644
--- a/tests/data/test2000
+++ b/tests/data/test2000
@@ -31,7 +31,7 @@ file
<name>
FTP RETR followed by FILE
</name>
- <command>
+<command option="no-include">
ftp://%HOSTIP:%FTPPORT/2000 file://localhost/%PWD/log/test2000.txt
</command>
<file name="log/test2000.txt">
diff --git a/tests/data/test2001 b/tests/data/test2001
index 68c0df7..88a258e 100644
--- a/tests/data/test2001
+++ b/tests/data/test2001
@@ -48,7 +48,7 @@ file
<name>
HTTP GET followed by FTP RETR followed by FILE
</name>
- <command>
+<command option="no-include">
http://%HOSTIP:%HTTPPORT/20010001 ftp://%HOSTIP:%FTPPORT/20010002 file://localhost/%PWD/log/test2001.txt
</command>
<file name="log/test2001.txt">
@@ -81,17 +81,6 @@ RETR 20010002
QUIT
</protocol>
<stdout>
-HTTP/1.1 200 OK
-Date: Thu, 09 Nov 2010 14:49:00 GMT
-Server: test-server/fake
-Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
-ETag: "21025-dc7-39462498"
-Accept-Ranges: bytes
-Content-Length: 6
-Connection: close
-Content-Type: text/html
-Funny-head: yesyes
-
-foo-
data
to
diff --git a/tests/data/test2002 b/tests/data/test2002
index db96bfe..6dd2f93 100644
--- a/tests/data/test2002
+++ b/tests/data/test2002
@@ -57,7 +57,7 @@ tftp
<name>
HTTP GET followed by FTP RETR followed by FILE followed by TFTP RRQ
</name>
- <command>
+<command option="no-include">
http://%HOSTIP:%HTTPPORT/20020001 ftp://%HOSTIP:%FTPPORT/20020002 file://localhost/%PWD/log/test2002.txt tftp://%HOSTIP:%TFTPPORT//20020003
</command>
<file name="log/test2002.txt">
@@ -96,17 +96,6 @@ filename: /20020003
QUIT
</protocol>
<stdout>
-HTTP/1.1 200 OK
-Date: Thu, 09 Nov 2010 14:49:00 GMT
-Server: test-server/fake
-Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
-ETag: "21025-dc7-39462498"
-Accept-Ranges: bytes
-Content-Length: 6
-Connection: close
-Content-Type: text/html
-Funny-head: yesyes
-
-foo-
data
to
diff --git a/tests/data/test2003 b/tests/data/test2003
index 59a743f..09bee8e 100644
--- a/tests/data/test2003
+++ b/tests/data/test2003
@@ -57,8 +57,8 @@ tftp
<name>
HTTP GET followed by FTP RETR followed by FILE followed by TFTP RRQ then again in reverse order
</name>
- <command>
-http://%HOSTIP:%HTTPPORT/20030001 ftp://%HOSTIP:%FTPPORT/20030002 file://localhost/%PWD/log/test2003.txt tftp://%HOSTIP:%TFTPPORT//20030003 tftp://%HOSTIP:%TFTPPORT//20030003 file://localhost/%PWD/log/test2003.txt ftp://%HOSTIP:%FTPPORT/20030002 http://%HOSTIP:%HTTPPORT/20030001
+<command option="no-include">
+http://%HOSTIP:%HTTPPORT/20030001 ftp://%HOSTIP:%FTPPORT/20030002 file://localhost/%PWD/log/test2003.txt tftp://%HOSTIP:%TFTPPORT//20030003 tftp://%HOSTIP:%TFTPPORT//20030003 file://localhost/%PWD/log/test2003.txt ftp://%HOSTIP:%FTPPORT/20030002 http://%HOSTIP:%HTTPPORT/20030001
</command>
<file name="log/test2003.txt">
foo
@@ -109,17 +109,6 @@ Accept: */*
QUIT
</protocol>
<stdout>
-HTTP/1.1 200 OK
-Date: Thu, 09 Nov 2010 14:49:00 GMT
-Server: test-server/fake
-Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
-ETag: "21025-dc7-39462498"
-Accept-Ranges: bytes
-Content-Length: 6
-Connection: close
-Content-Type: text/html
-Funny-head: yesyes
-
-foo-
data
to
@@ -151,17 +140,6 @@ data
that FTP
works
so does it?
-HTTP/1.1 200 OK
-Date: Thu, 09 Nov 2010 14:49:00 GMT
-Server: test-server/fake
-Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
-ETag: "21025-dc7-39462498"
-Accept-Ranges: bytes
-Content-Length: 6
-Connection: close
-Content-Type: text/html
-Funny-head: yesyes
-
-foo-
</stdout>
</verify>
diff --git a/tests/data/test2004 b/tests/data/test2004
index 4773f69..b17890b 100644
--- a/tests/data/test2004
+++ b/tests/data/test2004
@@ -29,7 +29,7 @@ sftp
<name>
TFTP RRQ followed by SFTP retrieval followed by FILE followed by SCP retrieval then again in reverse order
</name>
- <command>
+<command option="no-include">
--key curl_client_key --pubkey curl_client_key.pub -u %USER: tftp://%HOSTIP:%TFTPPORT//2004 sftp://%HOSTIP:%SSHPORT%POSIX_PWD/log/test2004.txt file://localhost/%PWD/log/test2004.txt scp://%HOSTIP:%SSHPORT%POSIX_PWD/log/test2004.txt file://localhost/%PWD/log/test2004.txt sftp://%HOSTIP:%SSHPORT%POSIX_PWD/log/test2004.txt tftp://%HOSTIP:%TFTPPORT//2004 --insecure
</command>
<file name="log/test2004.txt">
diff --git a/tests/data/test2006 b/tests/data/test2006
index e25556f..3acbdae 100644
--- a/tests/data/test2006
+++ b/tests/data/test2006
@@ -4,6 +4,7 @@
Metalink
HTTP
HTTP GET
+FILE
</keywords>
</info>
@@ -85,6 +86,10 @@ Accept: */*
Some data delivered from an HTTP resource
</file1>
<file2 name="log/heads2006">
+Content-Length: 496
+Accept-ranges: bytes
+
+
HTTP/1.1 200 OK
Date: Thu, 21 Jun 2012 14:49:01 GMT
Server: test-server/fake
@@ -105,6 +110,9 @@ Metalink: fetching (log/download2006) from (http://%HOSTIP:%HTTPPORT/2006) OK
Metalink: validating (log/download2006)...
Metalink: validating (log/download2006) [sha-256] OK
</file4>
+<stripfile2>
+s/Last-Modified:.*//
+</stripfile2>
<stripfile4>
$_ = '' if (($_ !~ /^Metalink: /) && ($_ !~ /error/i) && ($_ !~ /warn/i))
</stripfile4>
diff --git a/tests/data/test2007 b/tests/data/test2007
index cc4bd8c..b169c49 100644
--- a/tests/data/test2007
+++ b/tests/data/test2007
@@ -5,6 +5,7 @@ Metalink
HTTP
HTTP GET
-J
+FILE
</keywords>
</info>
@@ -85,7 +86,14 @@ Accept: */*
<file1 name="log/download2007">
Something delivered from an HTTP resource
</file1>
+<stripfile2>
+s/Last-Modified:.*//
+</stripfile2>
<file2 name="log/heads2007">
+Content-Length: 496
+Accept-ranges: bytes
+
+
HTTP/1.1 200 OK
Date: Thu, 21 Jun 2012 14:50:02 GMT
Server: test-server/fake
diff --git a/tests/data/test2008 b/tests/data/test2008
index 5843792..012f221 100644
--- a/tests/data/test2008
+++ b/tests/data/test2008
@@ -4,6 +4,7 @@
Metalink
HTTP
HTTP GET
+FILE
</keywords>
</info>
@@ -77,7 +78,14 @@ Accept: */*
<file1 name="log/download2008">
Some stuff delivered from an HTTP resource
</file1>
+<stripfile2>
+s/Last-Modified:.*//
+</stripfile2>
<file2 name="log/heads2008">
+Content-Length: 496
+Accept-ranges: bytes
+
+
HTTP/1.1 200 OK
Date: Thu, 21 Jun 2012 15:23:48 GMT
Server: test-server/fake
diff --git a/tests/data/test2009 b/tests/data/test2009
index 84482ce..b0e5c6c 100644
--- a/tests/data/test2009
+++ b/tests/data/test2009
@@ -5,6 +5,7 @@ Metalink
HTTP
HTTP GET
-J
+FILE
</keywords>
</info>
@@ -78,7 +79,14 @@ Accept: */*
<file1 name="log/download2009">
Some contents delivered from an HTTP resource
</file1>
+<stripfile2>
+s/Last-Modified:.*//
+</stripfile2>
<file2 name="log/heads2009">
+Content-Length: 496
+Accept-ranges: bytes
+
+
HTTP/1.1 200 OK
Date: Thu, 21 Jun 2012 16:27:17 GMT
Server: test-server/fake
diff --git a/tests/data/test2010 b/tests/data/test2010
index 91a83f4..33bb309 100644
--- a/tests/data/test2010
+++ b/tests/data/test2010
@@ -4,6 +4,7 @@
Metalink
HTTP
HTTP GET
+FILE
</keywords>
</info>
@@ -77,7 +78,14 @@ Accept: */*
<file1 name="log/download2010">
Contents delivered from an HTTP resource
</file1>
+<stripfile2>
+s/Last-Modified:.*//
+</stripfile2>
<file2 name="log/heads2010">
+Content-Length: 496
+Accept-ranges: bytes
+
+
HTTP/1.1 200 OK
Date: Thu, 21 Jun 2012 17:37:27 GMT
Server: test-server/fake
diff --git a/tests/data/test202 b/tests/data/test202
index f863ec5..0b324b1 100644
--- a/tests/data/test202
+++ b/tests/data/test202
@@ -19,7 +19,7 @@ file
<name>
two file:// URLs to stdout
</name>
- <command>
+<command option="no-include">
file://localhost/%PWD/log/test202.txt FILE://localhost/%PWD/log/test202.txt
</command>
<file name="log/test202.txt">
diff --git a/tests/data/test203 b/tests/data/test203
index 366cc2c..3938426 100644
--- a/tests/data/test203
+++ b/tests/data/test203
@@ -24,7 +24,7 @@ file
<name>
file:/path URL with a single slash
</name>
- <command>
+<command option="no-include">
file:%PWD/log/test203.txt
</command>
<file name="log/test203.txt">
diff --git a/tests/data/test204 b/tests/data/test204
index 9cc7b01..0ed9451 100644
--- a/tests/data/test204
+++ b/tests/data/test204
@@ -15,7 +15,7 @@ file
<name>
"upload" with file://
</name>
- <command>
+<command option="no-include">
file://localhost/%PWD/log/result204.txt -T log/upload204.txt
</command>
<file name="log/upload204.txt">
diff --git a/tests/data/test205 b/tests/data/test205
index 4af93f6..f83c531 100644
--- a/tests/data/test205
+++ b/tests/data/test205
@@ -16,7 +16,7 @@ file
<name>
"upload" with file://
</name>
- <command>
+<command option="no-include">
file://localhost/%PWD/log/nonexisting/result205.txt -T log/upload205.txt
</command>
<file name="log/upload205.txt">
diff --git a/tests/data/test2070 b/tests/data/test2070
index bc3898a..655cd8a 100644
--- a/tests/data/test2070
+++ b/tests/data/test2070
@@ -23,7 +23,7 @@ file
<name>
basic file:// file with no authority
</name>
- <command>
+<command option="no-include">
file:%PWD/log/test2070.txt
</command>
<file name="log/test2070.txt">
diff --git a/tests/data/test2071 b/tests/data/test2071
index 997dfff..eddfa4d 100644
--- a/tests/data/test2071
+++ b/tests/data/test2071
@@ -23,7 +23,7 @@ file
<name>
basic file:// file with "127.0.0.1" hostname
</name>
- <command>
+<command option="no-include">
file://127.0.0.1/%PWD/log/test2070.txt
</command>
<file name="log/test2070.txt">
diff --git a/tests/data/test2072 b/tests/data/test2072
index cd26f22..1bab158 100644
--- a/tests/data/test2072
+++ b/tests/data/test2072
@@ -23,7 +23,7 @@ file
<name>
file:// with unix path resolution behavior for the case of extra slashes
</name>
-<command>
+<command option="no-include">
file:////%PWD/log/test2072.txt
</command>
<precheck>
diff --git a/tests/data/test210 b/tests/data/test210
index e904567..c6fb703 100644
--- a/tests/data/test210
+++ b/tests/data/test210
@@ -22,7 +22,7 @@ ftp
<name>
Get two FTP files from the same remote dir: no second CWD
</name>
- <command>
+<command option="no-include">
ftp://%HOSTIP:%FTPPORT/a/path/210 ftp://%HOSTIP:%FTPPORT/a/path/210
</command>
<stdout>
diff --git a/tests/data/test231 b/tests/data/test231
index 6994957..3d4bc77 100644
--- a/tests/data/test231
+++ b/tests/data/test231
@@ -22,7 +22,7 @@ file
<name>
file:// with resume
</name>
- <command>
+<command option="no-include">
file://localhost/%PWD/log/test231.txt -C 10
</command>
<file name="log/test231.txt">
diff --git a/tests/data/test288 b/tests/data/test288
index ff4db6a..9f8f6e1 100644
--- a/tests/data/test288
+++ b/tests/data/test288
@@ -30,7 +30,7 @@ file:// with (unsupported) proxy, authentication and range
<setenv>
all_proxy=http://fake:user@%HOSTIP:%HTTPPORT/
</setenv>
- <command>
+<command option="no-include">
file://localhost/%PWD/log/test288.txt
</command>
<file name="log/test288.txt">
--
2.30.2

@ -0,0 +1,662 @@
From 74ba80e293eb2521d28916b24c3be59b3baf688a Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 18 Feb 2021 10:13:56 +0100
Subject: [PATCH 1/2] urldata: remove the _ORIG suffix from string names
It doesn't provide any useful info but only makes the names longer.
Closes #6624
Upstream-commit: 70472a44deaff387cf8c8c197e04f3add2a96e2e
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/setopt.c | 32 ++++++++++++++++----------------
lib/url.c | 32 ++++++++++++++++----------------
lib/urldata.h | 28 ++++++++++++++--------------
lib/vtls/cyassl.c | 2 +-
lib/vtls/darwinssl.c | 4 ++--
lib/vtls/gskit.c | 2 +-
lib/vtls/gtls.c | 2 +-
lib/vtls/mbedtls.c | 2 +-
lib/vtls/nss.c | 2 +-
lib/vtls/openssl.c | 2 +-
lib/vtls/polarssl.c | 2 +-
lib/vtls/schannel.c | 2 +-
12 files changed, 56 insertions(+), 56 deletions(-)
diff --git a/lib/setopt.c b/lib/setopt.c
index 4f04962..b07ccfe 100644
--- a/lib/setopt.c
+++ b/lib/setopt.c
@@ -133,7 +133,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
break;
case CURLOPT_SSL_CIPHER_LIST:
/* set a list of cipher we want to use in the SSL connection */
- result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_ORIG],
+ result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST],
va_arg(param, char *));
break;
case CURLOPT_PROXY_SSL_CIPHER_LIST:
@@ -145,7 +145,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
case CURLOPT_TLS13_CIPHERS:
if(Curl_ssl_tls13_ciphersuites()) {
/* set preferred list of TLS 1.3 cipher suites */
- result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER13_LIST_ORIG],
+ result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER13_LIST],
va_arg(param, char *));
}
else
@@ -1532,7 +1532,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
/*
* String that holds file name of the SSL certificate to use
*/
- result = Curl_setstropt(&data->set.str[STRING_CERT_ORIG],
+ result = Curl_setstropt(&data->set.str[STRING_CERT],
va_arg(param, char *));
break;
case CURLOPT_PROXY_SSLCERT:
@@ -1546,7 +1546,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
/*
* String that holds file type of the SSL certificate to use
*/
- result = Curl_setstropt(&data->set.str[STRING_CERT_TYPE_ORIG],
+ result = Curl_setstropt(&data->set.str[STRING_CERT_TYPE],
va_arg(param, char *));
break;
case CURLOPT_PROXY_SSLCERTTYPE:
@@ -1560,7 +1560,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
/*
* String that holds file name of the SSL key to use
*/
- result = Curl_setstropt(&data->set.str[STRING_KEY_ORIG],
+ result = Curl_setstropt(&data->set.str[STRING_KEY],
va_arg(param, char *));
break;
case CURLOPT_PROXY_SSLKEY:
@@ -1574,7 +1574,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
/*
* String that holds file type of the SSL key to use
*/
- result = Curl_setstropt(&data->set.str[STRING_KEY_TYPE_ORIG],
+ result = Curl_setstropt(&data->set.str[STRING_KEY_TYPE],
va_arg(param, char *));
break;
case CURLOPT_PROXY_SSLKEYTYPE:
@@ -1588,7 +1588,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
/*
* String that holds the SSL or SSH private key password.
*/
- result = Curl_setstropt(&data->set.str[STRING_KEY_PASSWD_ORIG],
+ result = Curl_setstropt(&data->set.str[STRING_KEY_PASSWD],
va_arg(param, char *));
break;
case CURLOPT_PROXY_KEYPASSWD:
@@ -1815,7 +1815,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
*/
#ifdef USE_SSL
if(Curl_ssl->supports & SSLSUPP_PINNEDPUBKEY)
- result = Curl_setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG],
+ result = Curl_setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY],
va_arg(param, char *));
else
#endif
@@ -1838,7 +1838,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
/*
* Set CA info for SSL connection. Specify file name of the CA certificate
*/
- result = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE_ORIG],
+ result = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE],
va_arg(param, char *));
break;
case CURLOPT_PROXY_CAINFO:
@@ -1857,7 +1857,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
#ifdef USE_SSL
if(Curl_ssl->supports & SSLSUPP_CA_PATH)
/* This does not work on windows. */
- result = Curl_setstropt(&data->set.str[STRING_SSL_CAPATH_ORIG],
+ result = Curl_setstropt(&data->set.str[STRING_SSL_CAPATH],
va_arg(param, char *));
else
#endif
@@ -1882,7 +1882,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
* Set CRL file info for SSL connection. Specify file name of the CRL
* to check certificates revocation
*/
- result = Curl_setstropt(&data->set.str[STRING_SSL_CRLFILE_ORIG],
+ result = Curl_setstropt(&data->set.str[STRING_SSL_CRLFILE],
va_arg(param, char *));
break;
case CURLOPT_PROXY_CRLFILE:
@@ -1898,7 +1898,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
* Set Issuer certificate file
* to check certificates issuer
*/
- result = Curl_setstropt(&data->set.str[STRING_SSL_ISSUERCERT_ORIG],
+ result = Curl_setstropt(&data->set.str[STRING_SSL_ISSUERCERT],
va_arg(param, char *));
break;
case CURLOPT_TELNETOPTIONS:
@@ -2449,9 +2449,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
break;
#ifdef USE_TLS_SRP
case CURLOPT_TLSAUTH_USERNAME:
- result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_ORIG],
+ result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME],
va_arg(param, char *));
- if(data->set.str[STRING_TLSAUTH_USERNAME_ORIG] && !data->set.ssl.authtype)
+ if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
break;
case CURLOPT_PROXY_TLSAUTH_USERNAME:
@@ -2462,9 +2462,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
break;
case CURLOPT_TLSAUTH_PASSWORD:
- result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_ORIG],
+ result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD],
va_arg(param, char *));
- if(data->set.str[STRING_TLSAUTH_USERNAME_ORIG] && !data->set.ssl.authtype)
+ if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
break;
case CURLOPT_PROXY_TLSAUTH_PASSWORD:
diff --git a/lib/url.c b/lib/url.c
index bb9d107..a6bc012 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -496,7 +496,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
*/
if(Curl_ssl_backend() != CURLSSLBACKEND_SCHANNEL) {
#if defined(CURL_CA_BUNDLE)
- result = Curl_setstropt(&set->str[STRING_SSL_CAFILE_ORIG], CURL_CA_BUNDLE);
+ result = Curl_setstropt(&set->str[STRING_SSL_CAFILE], CURL_CA_BUNDLE);
if(result)
return result;
@@ -506,7 +506,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
return result;
#endif
#if defined(CURL_CA_PATH)
- result = Curl_setstropt(&set->str[STRING_SSL_CAPATH_ORIG], CURL_CA_PATH);
+ result = Curl_setstropt(&set->str[STRING_SSL_CAPATH], CURL_CA_PATH);
if(result)
return result;
@@ -4333,9 +4333,9 @@ static CURLcode create_conn(struct Curl_easy *data,
that will be freed as part of the Curl_easy struct, but all cloned
copies will be separately allocated.
*/
- data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_ORIG];
+ data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH];
data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY];
- data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_ORIG];
+ data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE];
data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY];
data->set.ssl.primary.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
data->set.proxy_ssl.primary.random_file =
@@ -4343,34 +4343,34 @@ static CURLcode create_conn(struct Curl_easy *data,
data->set.ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
data->set.proxy_ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
data->set.ssl.primary.cipher_list =
- data->set.str[STRING_SSL_CIPHER_LIST_ORIG];
+ data->set.str[STRING_SSL_CIPHER_LIST];
data->set.proxy_ssl.primary.cipher_list =
data->set.str[STRING_SSL_CIPHER_LIST_PROXY];
data->set.ssl.primary.cipher_list13 =
- data->set.str[STRING_SSL_CIPHER13_LIST_ORIG];
+ data->set.str[STRING_SSL_CIPHER13_LIST];
data->set.proxy_ssl.primary.cipher_list13 =
data->set.str[STRING_SSL_CIPHER13_LIST_PROXY];
- data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG];
+ data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE];
data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY];
- data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_ORIG];
+ data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT];
data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY];
- data->set.ssl.cert = data->set.str[STRING_CERT_ORIG];
+ data->set.ssl.cert = data->set.str[STRING_CERT];
data->set.proxy_ssl.cert = data->set.str[STRING_CERT_PROXY];
- data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE_ORIG];
+ data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE];
data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY];
- data->set.ssl.key = data->set.str[STRING_KEY_ORIG];
+ data->set.ssl.key = data->set.str[STRING_KEY];
data->set.proxy_ssl.key = data->set.str[STRING_KEY_PROXY];
- data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE_ORIG];
+ data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE];
data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY];
- data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_ORIG];
+ data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD];
data->set.proxy_ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY];
- data->set.ssl.primary.clientcert = data->set.str[STRING_CERT_ORIG];
+ data->set.ssl.primary.clientcert = data->set.str[STRING_CERT];
data->set.proxy_ssl.primary.clientcert = data->set.str[STRING_CERT_PROXY];
#ifdef USE_TLS_SRP
- data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_ORIG];
+ data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME];
data->set.proxy_ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_PROXY];
- data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_ORIG];
+ data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD];
data->set.proxy_ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_PROXY];
#endif
diff --git a/lib/urldata.h b/lib/urldata.h
index c70290a..1f8f364 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1366,9 +1366,9 @@ struct DynamicStatic {
struct Curl_multi; /* declared and used only in multi.c */
enum dupstring {
- STRING_CERT_ORIG, /* client certificate file name */
+ STRING_CERT, /* client certificate file name */
STRING_CERT_PROXY, /* client certificate file name */
- STRING_CERT_TYPE_ORIG, /* format for certificate (default: PEM)*/
+ STRING_CERT_TYPE, /* format for certificate (default: PEM)*/
STRING_CERT_TYPE_PROXY, /* format for certificate (default: PEM)*/
STRING_COOKIE, /* HTTP cookie string to send */
STRING_COOKIEJAR, /* dump all cookies to this file */
@@ -1379,11 +1379,11 @@ enum dupstring {
STRING_FTP_ACCOUNT, /* ftp account data */
STRING_FTP_ALTERNATIVE_TO_USER, /* command to send if USER/PASS fails */
STRING_FTPPORT, /* port to send with the FTP PORT command */
- STRING_KEY_ORIG, /* private key file name */
+ STRING_KEY, /* private key file name */
STRING_KEY_PROXY, /* private key file name */
- STRING_KEY_PASSWD_ORIG, /* plain text private key password */
+ STRING_KEY_PASSWD, /* plain text private key password */
STRING_KEY_PASSWD_PROXY, /* plain text private key password */
- STRING_KEY_TYPE_ORIG, /* format for private key (default: PEM) */
+ STRING_KEY_TYPE, /* format for private key (default: PEM) */
STRING_KEY_TYPE_PROXY, /* format for private key (default: PEM) */
STRING_KRB_LEVEL, /* krb security level */
STRING_NETRC_FILE, /* if not NULL, use this instead of trying to find
@@ -1393,22 +1393,22 @@ enum dupstring {
STRING_SET_RANGE, /* range, if used */
STRING_SET_REFERER, /* custom string for the HTTP referer field */
STRING_SET_URL, /* what original URL to work on */
- STRING_SSL_CAPATH_ORIG, /* CA directory name (doesn't work on windows) */
+ STRING_SSL_CAPATH, /* CA directory name (doesn't work on windows) */
STRING_SSL_CAPATH_PROXY, /* CA directory name (doesn't work on windows) */
- STRING_SSL_CAFILE_ORIG, /* certificate file to verify peer against */
+ STRING_SSL_CAFILE, /* certificate file to verify peer against */
STRING_SSL_CAFILE_PROXY, /* certificate file to verify peer against */
- STRING_SSL_PINNEDPUBLICKEY_ORIG, /* public key file to verify peer against */
+ STRING_SSL_PINNEDPUBLICKEY, /* public key file to verify peer against */
STRING_SSL_PINNEDPUBLICKEY_PROXY, /* public key file to verify proxy */
- STRING_SSL_CIPHER_LIST_ORIG, /* list of ciphers to use */
+ STRING_SSL_CIPHER_LIST, /* list of ciphers to use */
STRING_SSL_CIPHER_LIST_PROXY, /* list of ciphers to use */
- STRING_SSL_CIPHER13_LIST_ORIG, /* list of TLS 1.3 ciphers to use */
+ STRING_SSL_CIPHER13_LIST, /* list of TLS 1.3 ciphers to use */
STRING_SSL_CIPHER13_LIST_PROXY, /* list of TLS 1.3 ciphers to use */
STRING_SSL_EGDSOCKET, /* path to file containing the EGD daemon socket */
STRING_SSL_RANDOM_FILE, /* path to file containing "random" data */
STRING_USERAGENT, /* User-Agent string */
- STRING_SSL_CRLFILE_ORIG, /* crl file to check certificate */
+ STRING_SSL_CRLFILE, /* crl file to check certificate */
STRING_SSL_CRLFILE_PROXY, /* crl file to check certificate */
- STRING_SSL_ISSUERCERT_ORIG, /* issuer cert file to check certificate */
+ STRING_SSL_ISSUERCERT, /* issuer cert file to check certificate */
STRING_SSL_ISSUERCERT_PROXY, /* issuer cert file to check certificate */
STRING_SSL_ENGINE, /* name of ssl engine */
STRING_USERNAME, /* <username>, if used */
@@ -1433,9 +1433,9 @@ enum dupstring {
STRING_MAIL_AUTH,
#ifdef USE_TLS_SRP
- STRING_TLSAUTH_USERNAME_ORIG, /* TLS auth <username> */
+ STRING_TLSAUTH_USERNAME, /* TLS auth <username> */
STRING_TLSAUTH_USERNAME_PROXY, /* TLS auth <username> */
- STRING_TLSAUTH_PASSWORD_ORIG, /* TLS auth <password> */
+ STRING_TLSAUTH_PASSWORD, /* TLS auth <password> */
STRING_TLSAUTH_PASSWORD_PROXY, /* TLS auth <password> */
#endif
STRING_BEARER, /* <bearer>, if used */
diff --git a/lib/vtls/cyassl.c b/lib/vtls/cyassl.c
index e10398a..ffd116d 100644
--- a/lib/vtls/cyassl.c
+++ b/lib/vtls/cyassl.c
@@ -474,7 +474,7 @@ cyassl_connect_step2(struct connectdata *conn,
conn->http_proxy.host.dispname : conn->host.dispname;
const char * const pinnedpubkey = SSL_IS_PROXY() ?
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY];
conn->recv[sockindex] = cyassl_recv;
conn->send[sockindex] = cyassl_send;
diff --git a/lib/vtls/darwinssl.c b/lib/vtls/darwinssl.c
index 1aea0dc..572e8bf 100644
--- a/lib/vtls/darwinssl.c
+++ b/lib/vtls/darwinssl.c
@@ -2449,9 +2449,9 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
connssl->connecting_state = ssl_connect_3;
#ifdef DARWIN_SSL_PINNEDPUBKEY
- if(data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]) {
+ if(data->set.str[STRING_SSL_PINNEDPUBLICKEY]) {
CURLcode result = pkp_pin_peer_pubkey(data, BACKEND->ssl_ctx,
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]);
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY]);
if(result) {
failf(data, "SSL: public key does not match pinned public key!");
return result;
diff --git a/lib/vtls/gskit.c b/lib/vtls/gskit.c
index a0b4960..b4c7b8a 100644
--- a/lib/vtls/gskit.c
+++ b/lib/vtls/gskit.c
@@ -1136,7 +1136,7 @@ static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex)
/* Check pinned public key. */
ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY];
if(!result && ptr) {
curl_X509certificate x509;
curl_asn1Element *p;
diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c
index 207b0fd..c5eb948 100644
--- a/lib/vtls/gtls.c
+++ b/lib/vtls/gtls.c
@@ -1329,7 +1329,7 @@ gtls_connect_step3(struct connectdata *conn,
}
ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY];
if(ptr) {
result = pkp_pin_peer_pubkey(data, x509_cert, ptr);
if(result != CURLE_OK) {
diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c
index d7759dc..48010ae 100644
--- a/lib/vtls/mbedtls.c
+++ b/lib/vtls/mbedtls.c
@@ -540,7 +540,7 @@ mbed_connect_step2(struct connectdata *conn,
const mbedtls_x509_crt *peercert;
const char * const pinnedpubkey = SSL_IS_PROXY() ?
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY];
#ifdef HAS_ALPN
const char *next_protocol;
diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c
index 89f8183..366bf9e 100644
--- a/lib/vtls/nss.c
+++ b/lib/vtls/nss.c
@@ -2067,7 +2067,7 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
&data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
const char * const pinnedpubkey = SSL_IS_PROXY() ?
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY];
/* check timeout situation */
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index 35cd652..8c97c1d 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -3388,7 +3388,7 @@ static CURLcode servercert(struct connectdata *conn,
result = CURLE_OK;
ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY];
if(!result && ptr) {
result = pkp_pin_peer_pubkey(data, BACKEND->server_cert, ptr);
if(result)
diff --git a/lib/vtls/polarssl.c b/lib/vtls/polarssl.c
index 604cb4c..f284ad1 100644
--- a/lib/vtls/polarssl.c
+++ b/lib/vtls/polarssl.c
@@ -459,7 +459,7 @@ polarssl_connect_step2(struct connectdata *conn,
char buffer[1024];
const char * const pinnedpubkey = SSL_IS_PROXY() ?
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY];
char errorbuf[128];
diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c
index 8f6c301..95c060b 100644
--- a/lib/vtls/schannel.c
+++ b/lib/vtls/schannel.c
@@ -1060,7 +1060,7 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
pubkey_ptr = SSL_IS_PROXY() ?
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY];
if(pubkey_ptr) {
result = pkp_pin_peer_pubkey(conn, sockindex, pubkey_ptr);
if(result) {
--
2.31.1
From 040fa4f60f9b809972d51184dfa4980ba44d8b6b Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Sat, 19 Jun 2021 00:42:28 +0200
Subject: [PATCH 2/2] vtls: fix connection reuse checks for issuer cert and
case sensitivity
CVE-2021-22924
Reported-by: Harry Sintonen
Bug: https://curl.se/docs/CVE-2021-22924.html
Upstream-commit: 5ea3145850ebff1dc2b13d17440300a01ca38161
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/url.c | 5 +++--
lib/urldata.h | 2 +-
lib/vtls/gtls.c | 10 +++++-----
lib/vtls/nss.c | 4 ++--
lib/vtls/openssl.c | 12 ++++++------
lib/vtls/vtls.c | 21 ++++++++++++++++-----
6 files changed, 33 insertions(+), 21 deletions(-)
diff --git a/lib/url.c b/lib/url.c
index a6bc012..4803653 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -4337,6 +4337,9 @@ static CURLcode create_conn(struct Curl_easy *data,
data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY];
data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE];
data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY];
+ data->set.ssl.primary.issuercert = data->set.str[STRING_SSL_ISSUERCERT];
+ data->set.proxy_ssl.primary.issuercert =
+ data->set.str[STRING_SSL_ISSUERCERT_PROXY];
data->set.ssl.primary.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
data->set.proxy_ssl.primary.random_file =
data->set.str[STRING_SSL_RANDOM_FILE];
@@ -4353,8 +4356,6 @@ static CURLcode create_conn(struct Curl_easy *data,
data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE];
data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY];
- data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT];
- data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY];
data->set.ssl.cert = data->set.str[STRING_CERT];
data->set.proxy_ssl.cert = data->set.str[STRING_CERT_PROXY];
data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE];
diff --git a/lib/urldata.h b/lib/urldata.h
index 1f8f364..72a36fb 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -223,6 +223,7 @@ struct ssl_primary_config {
bool sessionid; /* cache session IDs or not */
char *CApath; /* certificate dir (doesn't work on windows) */
char *CAfile; /* certificate to verify peer against */
+ char *issuercert; /* optional issuer certificate filename */
char *clientcert;
char *random_file; /* path to file containing "random" data */
char *egdsocket; /* path to file containing the EGD daemon socket */
@@ -238,7 +239,6 @@ struct ssl_config_data {
bool no_partialchain; /* don't accept partial certificate chains */
long certverifyresult; /* result from the certificate verification */
char *CRLfile; /* CRL to check certificate revocation */
- char *issuercert;/* optional issuer certificate filename */
curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */
void *fsslctxp; /* parameter for call back */
bool certinfo; /* gather lots of certificate info */
diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c
index c5eb948..0cb59c8 100644
--- a/lib/vtls/gtls.c
+++ b/lib/vtls/gtls.c
@@ -1002,7 +1002,7 @@ gtls_connect_step3(struct connectdata *conn,
if(!chainp) {
if(SSL_CONN_CONFIG(verifypeer) ||
SSL_CONN_CONFIG(verifyhost) ||
- SSL_SET_OPTION(issuercert)) {
+ SSL_CONN_CONFIG(issuercert)) {
#ifdef USE_TLS_SRP
if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP
&& SSL_SET_OPTION(username) != NULL
@@ -1184,21 +1184,21 @@ gtls_connect_step3(struct connectdata *conn,
gnutls_x509_crt_t format */
gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER);
- if(SSL_SET_OPTION(issuercert)) {
+ if(SSL_CONN_CONFIG(issuercert)) {
gnutls_x509_crt_init(&x509_issuer);
- issuerp = load_file(SSL_SET_OPTION(issuercert));
+ issuerp = load_file(SSL_CONN_CONFIG(issuercert));
gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM);
rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer);
gnutls_x509_crt_deinit(x509_issuer);
unload_file(issuerp);
if(rc <= 0) {
failf(data, "server certificate issuer check failed (IssuerCert: %s)",
- SSL_SET_OPTION(issuercert)?SSL_SET_OPTION(issuercert):"none");
+ SSL_CONN_CONFIG(issuercert)?SSL_CONN_CONFIG(issuercert):"none");
gnutls_x509_crt_deinit(x509_cert);
return CURLE_SSL_ISSUER_ERROR;
}
infof(data, "\t server certificate issuer check OK (Issuer Cert: %s)\n",
- SSL_SET_OPTION(issuercert)?SSL_SET_OPTION(issuercert):"none");
+ SSL_CONN_CONFIG(issuercert)?SSL_CONN_CONFIG(issuercert):"none");
}
size = sizeof(certbuf);
diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c
index 366bf9e..2d9581d 100644
--- a/lib/vtls/nss.c
+++ b/lib/vtls/nss.c
@@ -2095,9 +2095,9 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
if(result)
goto error;
- if(SSL_SET_OPTION(issuercert)) {
+ if(SSL_CONN_CONFIG(issuercert)) {
SECStatus ret = SECFailure;
- char *nickname = dup_nickname(data, SSL_SET_OPTION(issuercert));
+ char *nickname = dup_nickname(data, SSL_CONN_CONFIG(issuercert));
if(nickname) {
/* we support only nicknames in case of issuercert for now */
ret = check_issuer_cert(BACKEND->handle, nickname);
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index 8c97c1d..28eaa6d 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -3311,11 +3311,11 @@ static CURLcode servercert(struct connectdata *conn,
deallocating the certificate. */
/* e.g. match issuer name with provided issuer certificate */
- if(SSL_SET_OPTION(issuercert)) {
- if(BIO_read_filename(fp, SSL_SET_OPTION(issuercert)) <= 0) {
+ if(SSL_CONN_CONFIG(issuercert)) {
+ if(BIO_read_filename(fp, SSL_CONN_CONFIG(issuercert)) <= 0) {
if(strict)
failf(data, "SSL: Unable to open issuer cert (%s)",
- SSL_SET_OPTION(issuercert));
+ SSL_CONN_CONFIG(issuercert));
BIO_free(fp);
X509_free(BACKEND->server_cert);
BACKEND->server_cert = NULL;
@@ -3326,7 +3326,7 @@ static CURLcode servercert(struct connectdata *conn,
if(!issuer) {
if(strict)
failf(data, "SSL: Unable to read issuer cert (%s)",
- SSL_SET_OPTION(issuercert));
+ SSL_CONN_CONFIG(issuercert));
BIO_free(fp);
X509_free(issuer);
X509_free(BACKEND->server_cert);
@@ -3337,7 +3337,7 @@ static CURLcode servercert(struct connectdata *conn,
if(X509_check_issued(issuer, BACKEND->server_cert) != X509_V_OK) {
if(strict)
failf(data, "SSL: Certificate issuer check failed (%s)",
- SSL_SET_OPTION(issuercert));
+ SSL_CONN_CONFIG(issuercert));
BIO_free(fp);
X509_free(issuer);
X509_free(BACKEND->server_cert);
@@ -3346,7 +3346,7 @@ static CURLcode servercert(struct connectdata *conn,
}
infof(data, " SSL certificate issuer check ok (%s)\n",
- SSL_SET_OPTION(issuercert));
+ SSL_CONN_CONFIG(issuercert));
X509_free(issuer);
}
diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c
index b61c640..18672a5 100644
--- a/lib/vtls/vtls.c
+++ b/lib/vtls/vtls.c
@@ -82,6 +82,15 @@
else \
dest->var = NULL;
+static bool safecmp(char *a, char *b)
+{
+ if(a && b)
+ return !strcmp(a, b);
+ else if(!a && !b)
+ return TRUE; /* match */
+ return FALSE; /* no match */
+}
+
bool
Curl_ssl_config_matches(struct ssl_primary_config* data,
struct ssl_primary_config* needle)
@@ -91,11 +100,11 @@ Curl_ssl_config_matches(struct ssl_primary_config* data,
(data->verifypeer == needle->verifypeer) &&
(data->verifyhost == needle->verifyhost) &&
(data->verifystatus == needle->verifystatus) &&
- Curl_safe_strcasecompare(data->CApath, needle->CApath) &&
- Curl_safe_strcasecompare(data->CAfile, needle->CAfile) &&
- Curl_safe_strcasecompare(data->clientcert, needle->clientcert) &&
- Curl_safe_strcasecompare(data->random_file, needle->random_file) &&
- Curl_safe_strcasecompare(data->egdsocket, needle->egdsocket) &&
+ safecmp(data->CApath, needle->CApath) &&
+ safecmp(data->CAfile, needle->CAfile) &&
+ safecmp(data->clientcert, needle->clientcert) &&
+ safecmp(data->random_file, needle->random_file) &&
+ safecmp(data->egdsocket, needle->egdsocket) &&
Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list) &&
Curl_safe_strcasecompare(data->cipher_list13, needle->cipher_list13))
return TRUE;
@@ -116,6 +125,7 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
CLONE_STRING(CApath);
CLONE_STRING(CAfile);
+ CLONE_STRING(issuercert);
CLONE_STRING(clientcert);
CLONE_STRING(random_file);
CLONE_STRING(egdsocket);
@@ -129,6 +139,7 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config* sslc)
{
Curl_safefree(sslc->CApath);
Curl_safefree(sslc->CAfile);
+ Curl_safefree(sslc->issuercert);
Curl_safefree(sslc->clientcert);
Curl_safefree(sslc->random_file);
Curl_safefree(sslc->egdsocket);
--
2.31.1

@ -0,0 +1,31 @@
From ae2dc830fb37e9243dbdaf8b92e41df91f43b3f2 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
Upstream-commit: 39ce47f219b09c380b81f89fe54ac586c8db6bde
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/telnet.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/telnet.c b/lib/telnet.c
index 1fc5af1..ea6bc71 100644
--- a/lib/telnet.c
+++ b/lib/telnet.c
@@ -967,7 +967,7 @@ static void suboption(struct connectdata *conn)
size_t tmplen = (strlen(v->data) + 1);
/* Add the variable only if it fits */
if(len + tmplen < (int)sizeof(temp)-6) {
- if(sscanf(v->data, "%127[^,],%127s", varname, varval)) {
+ if(sscanf(v->data, "%127[^,],%127s", varname, varval) == 2) {
snprintf((char *)&temp[len], sizeof(temp) - len,
"%c%s%c%s", CURL_NEW_ENV_VAR, varname,
CURL_NEW_ENV_VALUE, varval);
--
2.31.1

@ -0,0 +1,47 @@
From 2fbbf282e42ae476459f7efe68a88dcb63dcc43b Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Sat, 12 Jun 2021 18:25:15 +0200
Subject: [PATCH] telnet: fix option parser to not send uninitialized contents
CVE-2021-22925
Reported-by: Red Hat Product Security
Bug: https://curl.se/docs/CVE-2021-22925.html
Upstream-commit: 894f6ec730597eb243618d33cc84d71add8d6a8a
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/telnet.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/lib/telnet.c b/lib/telnet.c
index ea6bc71..f8428b8 100644
--- a/lib/telnet.c
+++ b/lib/telnet.c
@@ -967,12 +967,17 @@ static void suboption(struct connectdata *conn)
size_t tmplen = (strlen(v->data) + 1);
/* Add the variable only if it fits */
if(len + tmplen < (int)sizeof(temp)-6) {
- if(sscanf(v->data, "%127[^,],%127s", varname, varval) == 2) {
- snprintf((char *)&temp[len], sizeof(temp) - len,
- "%c%s%c%s", CURL_NEW_ENV_VAR, varname,
- CURL_NEW_ENV_VALUE, varval);
- len += tmplen;
- }
+ int rv;
+ char sep[2] = "";
+ varval[0] = 0;
+ rv = sscanf(v->data, "%127[^,]%1[,]%127s", varname, sep, varval);
+ if(rv == 1)
+ len += snprintf((char *)&temp[len], sizeof(temp) - len,
+ "%c%s", CURL_NEW_ENV_VAR, varname);
+ else if(rv >= 2)
+ len += snprintf((char *)&temp[len], sizeof(temp) - len,
+ "%c%s%c%s", CURL_NEW_ENV_VAR, varname,
+ CURL_NEW_ENV_VALUE, varval);
}
}
snprintf((char *)&temp[len], sizeof(temp) - len,
--
2.31.1

@ -0,0 +1,331 @@
From 03ca8c6faca7de6628f9cbec3001ec6466c88d07 Mon Sep 17 00:00:00 2001
From: Patrick Monnerat <patrick@monnerat.net>
Date: Wed, 8 Sep 2021 11:56:22 +0200
Subject: [PATCH] ftp,imap,pop3: do not ignore --ssl-reqd
In imap and pop3, check if TLS is required even when capabilities
request has failed.
In ftp, ignore preauthentication (230 status of server greeting) if TLS
is required.
Bug: https://curl.se/docs/CVE-2021-22946.html
CVE-2021-22946
Upstream-commit: 364f174724ef115c63d5e5dc1d3342c8a43b1cca
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/ftp.c | 9 ++++---
lib/imap.c | 24 ++++++++----------
lib/pop3.c | 33 +++++++++++-------------
tests/data/Makefile.inc | 2 ++
tests/data/test984 | 56 +++++++++++++++++++++++++++++++++++++++++
tests/data/test985 | 54 +++++++++++++++++++++++++++++++++++++++
tests/data/test986 | 53 ++++++++++++++++++++++++++++++++++++++
7 files changed, 195 insertions(+), 36 deletions(-)
create mode 100644 tests/data/test984
create mode 100644 tests/data/test985
create mode 100644 tests/data/test986
diff --git a/lib/ftp.c b/lib/ftp.c
index 71c9642..30ebeaa 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -2621,9 +2621,12 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
/* we have now received a full FTP server response */
switch(ftpc->state) {
case FTP_WAIT220:
- if(ftpcode == 230)
- /* 230 User logged in - already! */
- return ftp_state_user_resp(conn, ftpcode, ftpc->state);
+ if(ftpcode == 230) {
+ /* 230 User logged in - already! Take as 220 if TLS required. */
+ if(data->set.use_ssl <= CURLUSESSL_TRY ||
+ conn->ssl[FIRSTSOCKET].use)
+ return ftp_state_user_resp(conn, ftpcode, ftpc->state);
+ }
else if(ftpcode != 220) {
failf(data, "Got a %03d ftp-server response when 220 was expected",
ftpcode);
diff --git a/lib/imap.c b/lib/imap.c
index bda23a5..7e159d4 100644
--- a/lib/imap.c
+++ b/lib/imap.c
@@ -910,22 +910,18 @@ static CURLcode imap_state_capability_resp(struct connectdata *conn,
line += wordlen;
}
}
- else if(imapcode == IMAP_RESP_OK) {
- if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
- /* We don't have a SSL/TLS connection yet, but SSL is requested */
- if(imapc->tls_supported)
- /* Switch to TLS connection now */
- result = imap_perform_starttls(conn);
- else if(data->set.use_ssl == CURLUSESSL_TRY)
- /* Fallback and carry on with authentication */
- result = imap_perform_authentication(conn);
- else {
- failf(data, "STARTTLS not supported.");
- result = CURLE_USE_SSL_FAILED;
- }
+ else if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
+ /* PREAUTH is not compatible with STARTTLS. */
+ if(imapcode == IMAP_RESP_OK && imapc->tls_supported && !imapc->preauth) {
+ /* Switch to TLS connection now */
+ result = imap_perform_starttls(conn);
}
- else
+ else if(data->set.use_ssl <= CURLUSESSL_TRY)
result = imap_perform_authentication(conn);
+ else {
+ failf(data, "STARTTLS not available.");
+ result = CURLE_USE_SSL_FAILED;
+ }
}
else
result = imap_perform_authentication(conn);
diff --git a/lib/pop3.c b/lib/pop3.c
index 04cc887..3e916ce 100644
--- a/lib/pop3.c
+++ b/lib/pop3.c
@@ -718,28 +718,23 @@ static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code,
}
}
}
- else if(pop3code == '+') {
- if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
- /* We don't have a SSL/TLS connection yet, but SSL is requested */
- if(pop3c->tls_supported)
- /* Switch to TLS connection now */
- result = pop3_perform_starttls(conn);
- else if(data->set.use_ssl == CURLUSESSL_TRY)
- /* Fallback and carry on with authentication */
- result = pop3_perform_authentication(conn);
- else {
- failf(data, "STLS not supported.");
- result = CURLE_USE_SSL_FAILED;
- }
- }
- else
- result = pop3_perform_authentication(conn);
- }
else {
/* Clear text is supported when CAPA isn't recognised */
- pop3c->authtypes |= POP3_TYPE_CLEARTEXT;
+ if(pop3code != '+')
+ pop3c->authtypes |= POP3_TYPE_CLEARTEXT;
- result = pop3_perform_authentication(conn);
+ if(!data->set.use_ssl || conn->ssl[FIRSTSOCKET].use)
+ result = pop3_perform_authentication(conn);
+ else if(pop3code == '+' && pop3c->tls_supported)
+ /* Switch to TLS connection now */
+ result = pop3_perform_starttls(conn);
+ else if(data->set.use_ssl <= CURLUSESSL_TRY)
+ /* Fallback and carry on with authentication */
+ result = pop3_perform_authentication(conn);
+ else {
+ failf(data, "STLS not supported.");
+ result = CURLE_USE_SSL_FAILED;
+ }
}
return result;
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index ef9252b..1ba482b 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -108,6 +108,8 @@ test927 test928 test929 test930 test931 test932 test933 test934 test935 \
test936 test937 test938 test939 test940 test941 test942 test943 test944 \
test945 test946 test947 test948 test949 test950 test951 test952 \
\
+test984 test985 test986 \
+\
test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 \
test1008 test1009 test1010 test1011 test1012 test1013 test1014 test1015 \
test1016 test1017 test1018 test1019 test1020 test1021 test1022 test1023 \
diff --git a/tests/data/test984 b/tests/data/test984
new file mode 100644
index 0000000..e573f23
--- /dev/null
+++ b/tests/data/test984
@@ -0,0 +1,56 @@
+<testcase>
+<info>
+<keywords>
+IMAP
+STARTTLS
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<servercmd>
+REPLY CAPABILITY A001 BAD Not implemented
+</servercmd>
+</reply>
+
+#
+# Client-side
+<client>
+<features>
+SSL
+</features>
+<server>
+imap
+</server>
+ <name>
+IMAP require STARTTLS with failing capabilities
+ </name>
+ <command>
+imap://%HOSTIP:%IMAPPORT/%TESTNUMBER -T log/upload%TESTNUMBER -u user:secret --ssl-reqd
+</command>
+<file name="log/upload%TESTNUMBER">
+Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST)
+From: Fred Foobar <foobar@example.COM>
+Subject: afternoon meeting
+To: joe@example.com
+Message-Id: <B27397-0100000@example.COM>
+MIME-Version: 1.0
+Content-Type: TEXT/PLAIN; CHARSET=US-ASCII
+
+Hello Joe, do you think we can meet at 3:30 tomorrow?
+</file>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+# 64 is CURLE_USE_SSL_FAILED
+<errorcode>
+64
+</errorcode>
+<protocol>
+A001 CAPABILITY
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test985 b/tests/data/test985
new file mode 100644
index 0000000..d0db4aa
--- /dev/null
+++ b/tests/data/test985
@@ -0,0 +1,54 @@
+<testcase>
+<info>
+<keywords>
+POP3
+STARTTLS
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<servercmd>
+REPLY CAPA -ERR Not implemented
+</servercmd>
+<data nocheck="yes">
+From: me@somewhere
+To: fake@nowhere
+
+body
+
+--
+ yours sincerely
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<features>
+SSL
+</features>
+<server>
+pop3
+</server>
+ <name>
+POP3 require STARTTLS with failing capabilities
+ </name>
+ <command>
+pop3://%HOSTIP:%POP3PORT/%TESTNUMBER -u user:secret --ssl-reqd
+ </command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+# 64 is CURLE_USE_SSL_FAILED
+<errorcode>
+64
+</errorcode>
+<protocol>
+CAPA
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test986 b/tests/data/test986
new file mode 100644
index 0000000..a709437
--- /dev/null
+++ b/tests/data/test986
@@ -0,0 +1,53 @@
+<testcase>
+<info>
+<keywords>
+FTP
+STARTTLS
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<servercmd>
+REPLY welcome 230 Welcome
+REPLY AUTH 500 unknown command
+</servercmd>
+</reply>
+
+# Client-side
+<client>
+<features>
+SSL
+</features>
+<server>
+ftp
+</server>
+ <name>
+FTP require STARTTLS while preauthenticated
+ </name>
+<file name="log/test%TESTNUMBER.txt">
+data
+ to
+ see
+that FTPS
+works
+ so does it?
+</file>
+ <command>
+--ssl-reqd --ftp-ssl-control ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -T log/test%TESTNUMBER.txt -u user:secret
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+# 64 is CURLE_USE_SSL_FAILED
+<errorcode>
+64
+</errorcode>
+<protocol>
+AUTH SSL
+AUTH TLS
+</protocol>
+</verify>
+</testcase>
--
2.31.1

@ -0,0 +1,354 @@
From a1ec463c8207bde97b3575d12e396e999a55a8d0 Mon Sep 17 00:00:00 2001
From: Patrick Monnerat <patrick@monnerat.net>
Date: Tue, 7 Sep 2021 13:26:42 +0200
Subject: [PATCH] ftp,imap,pop3,smtp: reject STARTTLS server response
pipelining
If a server pipelines future responses within the STARTTLS response, the
former are preserved in the pingpong cache across TLS negotiation and
used as responses to the encrypted commands.
This fix detects pipelined STARTTLS responses and rejects them with an
error.
CVE-2021-22947
Bug: https://curl.se/docs/CVE-2021-22947.html
Upstream-commit: 8ef147c43646e91fdaad5d0e7b60351f842e5c68
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/ftp.c | 3 +++
lib/imap.c | 4 +++
lib/pop3.c | 4 +++
lib/smtp.c | 4 +++
tests/data/Makefile.inc | 2 +-
tests/data/test980 | 52 ++++++++++++++++++++++++++++++++++++
tests/data/test981 | 59 +++++++++++++++++++++++++++++++++++++++++
tests/data/test982 | 57 +++++++++++++++++++++++++++++++++++++++
tests/data/test983 | 52 ++++++++++++++++++++++++++++++++++++
9 files changed, 236 insertions(+), 1 deletion(-)
create mode 100644 tests/data/test980
create mode 100644 tests/data/test981
create mode 100644 tests/data/test982
create mode 100644 tests/data/test983
diff --git a/lib/ftp.c b/lib/ftp.c
index 71f998e..e920138 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -2688,6 +2688,9 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
case FTP_AUTH:
/* we have gotten the response to a previous AUTH command */
+ if(pp->cache_size)
+ return CURLE_WEIRD_SERVER_REPLY; /* Forbid pipelining in response. */
+
/* RFC2228 (page 5) says:
*
* If the server is willing to accept the named security mechanism,
diff --git a/lib/imap.c b/lib/imap.c
index feb7445..09bc5d6 100644
--- a/lib/imap.c
+++ b/lib/imap.c
@@ -939,6 +939,10 @@ static CURLcode imap_state_starttls_resp(struct connectdata *conn,
(void)instate; /* no use for this yet */
+ /* Pipelining in response is forbidden. */
+ if(conn->proto.imapc.pp.cache_size)
+ return CURLE_WEIRD_SERVER_REPLY;
+
if(imapcode != IMAP_RESP_OK) {
if(data->set.use_ssl != CURLUSESSL_TRY) {
failf(data, "STARTTLS denied");
diff --git a/lib/pop3.c b/lib/pop3.c
index 7698d1c..dccfced 100644
--- a/lib/pop3.c
+++ b/lib/pop3.c
@@ -750,6 +750,10 @@ static CURLcode pop3_state_starttls_resp(struct connectdata *conn,
(void)instate; /* no use for this yet */
+ /* Pipelining in response is forbidden. */
+ if(conn->proto.pop3c.pp.cache_size)
+ return CURLE_WEIRD_SERVER_REPLY;
+
if(pop3code != '+') {
if(data->set.use_ssl != CURLUSESSL_TRY) {
failf(data, "STARTTLS denied");
diff --git a/lib/smtp.c b/lib/smtp.c
index 1defb25..1f89777 100644
--- a/lib/smtp.c
+++ b/lib/smtp.c
@@ -685,6 +685,10 @@ static CURLcode smtp_state_starttls_resp(struct connectdata *conn,
(void)instate; /* no use for this yet */
+ /* Pipelining in response is forbidden. */
+ if(conn->proto.smtpc.pp.cache_size)
+ return CURLE_WEIRD_SERVER_REPLY;
+
if(smtpcode != 220) {
if(data->set.use_ssl != CURLUSESSL_TRY) {
failf(data, "STARTTLS denied, code %d", smtpcode);
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index 163ce59..42b0569 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -108,7 +108,7 @@ test927 test928 test929 test930 test931 test932 test933 test934 test935 \
test936 test937 test938 test939 test940 test941 test942 test943 test944 \
test945 test946 test947 test948 test949 test950 test951 test952 \
\
-test984 test985 test986 \
+test980 test981 test982 test983 test984 test985 test986 \
\
test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 \
test1008 test1009 test1010 test1011 test1012 test1013 test1014 test1015 \
diff --git a/tests/data/test980 b/tests/data/test980
new file mode 100644
index 0000000..97567f8
--- /dev/null
+++ b/tests/data/test980
@@ -0,0 +1,52 @@
+<testcase>
+<info>
+<keywords>
+SMTP
+STARTTLS
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<servercmd>
+CAPA STARTTLS
+AUTH PLAIN
+REPLY STARTTLS 454 currently unavailable\r\n235 Authenticated\r\n250 2.1.0 Sender ok\r\n250 2.1.5 Recipient ok\r\n354 Enter mail\r\n250 2.0.0 Accepted
+REPLY AUTH 535 5.7.8 Authentication credentials invalid
+</servercmd>
+</reply>
+
+#
+# Client-side
+<client>
+<features>
+SSL
+</features>
+<server>
+smtp
+</server>
+ <name>
+SMTP STARTTLS pipelined server response
+ </name>
+<stdin>
+mail body
+</stdin>
+ <command>
+smtp://%HOSTIP:%SMTPPORT/%TESTNUMBER --mail-rcpt recipient@example.com --mail-from sender@example.com -u user:secret --ssl --sasl-ir -T -
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+# 8 is CURLE_WEIRD_SERVER_REPLY
+<errorcode>
+8
+</errorcode>
+<protocol>
+EHLO %TESTNUMBER
+STARTTLS
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test981 b/tests/data/test981
new file mode 100644
index 0000000..2b98ce4
--- /dev/null
+++ b/tests/data/test981
@@ -0,0 +1,59 @@
+<testcase>
+<info>
+<keywords>
+IMAP
+STARTTLS
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<servercmd>
+CAPA STARTTLS
+REPLY STARTTLS A002 BAD currently unavailable\r\nA003 OK Authenticated\r\nA004 OK Accepted
+REPLY LOGIN A003 BAD Authentication credentials invalid
+</servercmd>
+</reply>
+
+#
+# Client-side
+<client>
+<features>
+SSL
+</features>
+<server>
+imap
+</server>
+ <name>
+IMAP STARTTLS pipelined server response
+ </name>
+ <command>
+imap://%HOSTIP:%IMAPPORT/%TESTNUMBER -T log/upload%TESTNUMBER -u user:secret --ssl
+</command>
+<file name="log/upload%TESTNUMBER">
+Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST)
+From: Fred Foobar <foobar@example.COM>
+Subject: afternoon meeting
+To: joe@example.com
+Message-Id: <B27397-0100000@example.COM>
+MIME-Version: 1.0
+Content-Type: TEXT/PLAIN; CHARSET=US-ASCII
+
+Hello Joe, do you think we can meet at 3:30 tomorrow?
+</file>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+# 8 is CURLE_WEIRD_SERVER_REPLY
+<errorcode>
+8
+</errorcode>
+<protocol>
+A001 CAPABILITY
+A002 STARTTLS
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test982 b/tests/data/test982
new file mode 100644
index 0000000..9e07cc0
--- /dev/null
+++ b/tests/data/test982
@@ -0,0 +1,57 @@
+<testcase>
+<info>
+<keywords>
+POP3
+STARTTLS
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<servercmd>
+CAPA STLS USER
+REPLY STLS -ERR currently unavailable\r\n+OK user accepted\r\n+OK authenticated
+REPLY PASS -ERR Authentication credentials invalid
+</servercmd>
+<data nocheck="yes">
+From: me@somewhere
+To: fake@nowhere
+
+body
+
+--
+ yours sincerely
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<features>
+SSL
+</features>
+<server>
+pop3
+</server>
+ <name>
+POP3 STARTTLS pipelined server response
+ </name>
+ <command>
+pop3://%HOSTIP:%POP3PORT/%TESTNUMBER -u user:secret --ssl
+ </command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+# 8 is CURLE_WEIRD_SERVER_REPLY
+<errorcode>
+8
+</errorcode>
+<protocol>
+CAPA
+STLS
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test983 b/tests/data/test983
new file mode 100644
index 0000000..300ec45
--- /dev/null
+++ b/tests/data/test983
@@ -0,0 +1,52 @@
+<testcase>
+<info>
+<keywords>
+FTP
+STARTTLS
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<servercmd>
+REPLY AUTH 500 unknown command\r\n500 unknown command\r\n331 give password\r\n230 Authenticated\r\n257 "/"\r\n200 OK\r\n200 OK\r\n200 OK\r\n226 Transfer complete
+REPLY PASS 530 Login incorrect
+</servercmd>
+</reply>
+
+# Client-side
+<client>
+<features>
+SSL
+</features>
+<server>
+ftp
+</server>
+ <name>
+FTP STARTTLS pipelined server response
+ </name>
+<file name="log/test%TESTNUMBER.txt">
+data
+ to
+ see
+that FTPS
+works
+ so does it?
+</file>
+ <command>
+--ssl --ftp-ssl-control ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -T log/test%TESTNUMBER.txt -u user:secret -P %CLIENTIP
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+# 8 is CURLE_WEIRD_SERVER_REPLY
+<errorcode>
+8
+</errorcode>
+<protocol>
+AUTH SSL
+</protocol>
+</verify>
+</testcase>
--
2.31.1

@ -0,0 +1,338 @@
From 295124c256ed25f097192cfa9a67e460f7bb587f Mon Sep 17 00:00:00 2001
From: nao <naost3rn@gmail.com>
Date: Tue, 21 Jan 2020 10:30:37 +0100
Subject: [PATCH 1/2] http: move "oauth_bearer" from connectdata to Curl_easy
Fixes the bug where oauth_bearer gets deallocated when we re-use a
connection.
Closes #4824
Upstream-commit: dea17b519dc1d83265ca6aa9a484a2cf242db3b9
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/curl_sasl.c | 14 ++++++++------
lib/http.c | 12 +++++-------
lib/url.c | 9 ---------
lib/urldata.h | 2 --
4 files changed, 13 insertions(+), 24 deletions(-)
diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c
index 354bc54..c767bef 100644
--- a/lib/curl_sasl.c
+++ b/lib/curl_sasl.c
@@ -269,6 +269,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
data->set.str[STRING_SERVICE_NAME] :
sasl->params->service;
#endif
+ const char *oauth_bearer = data->set.str[STRING_BEARER];
sasl->force_ir = force_ir; /* Latch for future use */
sasl->authused = 0; /* No mechanism used yet */
@@ -339,7 +340,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
}
else
#endif
- if((enabledmechs & SASL_MECH_OAUTHBEARER) && conn->oauth_bearer) {
+ if((enabledmechs & SASL_MECH_OAUTHBEARER) && oauth_bearer) {
mech = SASL_MECH_STRING_OAUTHBEARER;
state1 = SASL_OAUTH2;
state2 = SASL_OAUTH2_RESP;
@@ -349,10 +350,10 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
result = Curl_auth_create_oauth_bearer_message(data, conn->user,
hostname,
port,
- conn->oauth_bearer,
+ oauth_bearer,
&resp, &len);
}
- else if((enabledmechs & SASL_MECH_XOAUTH2) && conn->oauth_bearer) {
+ else if((enabledmechs & SASL_MECH_XOAUTH2) && oauth_bearer) {
mech = SASL_MECH_STRING_XOAUTH2;
state1 = SASL_OAUTH2;
sasl->authused = SASL_MECH_XOAUTH2;
@@ -360,7 +361,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
if(force_ir || data->set.sasl_ir)
result = Curl_auth_create_oauth_bearer_message(data, conn->user,
NULL, 0,
- conn->oauth_bearer,
+ oauth_bearer,
&resp, &len);
}
else if(enabledmechs & SASL_MECH_PLAIN) {
@@ -429,6 +430,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
char *serverdata;
#endif
size_t len = 0;
+ const char *oauth_bearer = data->set.str[STRING_BEARER];
*progress = SASL_INPROGRESS;
@@ -556,7 +558,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
result = Curl_auth_create_oauth_bearer_message(data, conn->user,
hostname,
port,
- conn->oauth_bearer,
+ oauth_bearer,
&resp, &len);
/* Failures maybe sent by the server as continuations for OAUTHBEARER */
@@ -565,7 +567,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
else
result = Curl_auth_create_oauth_bearer_message(data, conn->user,
NULL, 0,
- conn->oauth_bearer,
+ oauth_bearer,
&resp, &len);
break;
diff --git a/lib/http.c b/lib/http.c
index 26eb52d..bf19077 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -326,7 +326,7 @@ static CURLcode http_output_bearer(struct connectdata *conn)
userp = &conn->allocptr.userpwd;
free(*userp);
*userp = aprintf("Authorization: Bearer %s\r\n",
- conn->oauth_bearer);
+ conn->data->set.str[STRING_BEARER]);
if(!*userp) {
result = CURLE_OUT_OF_MEMORY;
@@ -510,7 +510,7 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
CURLcode result = CURLE_OK;
unsigned long authmask = ~0ul;
- if(!conn->oauth_bearer)
+ if(!data->set.str[STRING_BEARER])
authmask &= (unsigned long)~CURLAUTH_BEARER;
if(100 <= data->req.httpcode && 199 >= data->req.httpcode)
@@ -520,7 +520,7 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
if(data->state.authproblem)
return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
- if((conn->bits.user_passwd || conn->oauth_bearer) &&
+ if((conn->bits.user_passwd || data->set.str[STRING_BEARER]) &&
((data->req.httpcode == 401) ||
(conn->bits.authneg && data->req.httpcode < 300))) {
pickhost = pickoneauth(&data->state.authhost, authmask);
@@ -590,9 +590,7 @@ output_auth_headers(struct connectdata *conn,
{
const char *auth = NULL;
CURLcode result = CURLE_OK;
-#if !defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_SPNEGO)
struct Curl_easy *data = conn->data;
-#endif
#ifdef USE_SPNEGO
struct negotiatedata *negdata = proxy ?
&data->state.proxyneg : &data->state.negotiate;
@@ -664,7 +662,7 @@ output_auth_headers(struct connectdata *conn,
}
if(authstatus->picked == CURLAUTH_BEARER) {
/* Bearer */
- if((!proxy && conn->oauth_bearer &&
+ if((!proxy && data->set.str[STRING_BEARER] &&
!Curl_checkheaders(conn, "Authorization:"))) {
auth = "Bearer";
result = http_output_bearer(conn);
@@ -722,7 +720,7 @@ Curl_http_output_auth(struct connectdata *conn,
authproxy = &data->state.authproxy;
if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
- conn->bits.user_passwd || conn->oauth_bearer)
+ conn->bits.user_passwd || data->set.str[STRING_BEARER])
/* continue please */;
else {
authhost->done = TRUE;
diff --git a/lib/url.c b/lib/url.c
index 4803653..fca0855 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -686,7 +686,6 @@ static void conn_free(struct connectdata *conn)
Curl_safefree(conn->user);
Curl_safefree(conn->passwd);
- Curl_safefree(conn->oauth_bearer);
Curl_safefree(conn->options);
Curl_safefree(conn->http_proxy.user);
Curl_safefree(conn->socks_proxy.user);
@@ -4161,14 +4160,6 @@ static CURLcode create_conn(struct Curl_easy *data,
}
}
- if(data->set.str[STRING_BEARER]) {
- conn->oauth_bearer = strdup(data->set.str[STRING_BEARER]);
- if(!conn->oauth_bearer) {
- result = CURLE_OUT_OF_MEMORY;
- goto out;
- }
- }
-
#ifdef USE_UNIX_SOCKETS
if(data->set.str[STRING_UNIX_SOCKET_PATH]) {
conn->unix_domain_socket = strdup(data->set.str[STRING_UNIX_SOCKET_PATH]);
diff --git a/lib/urldata.h b/lib/urldata.h
index 72a36fb..73a185c 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -850,8 +850,6 @@ struct connectdata {
char *passwd; /* password string, allocated */
char *options; /* options string, allocated */
- char *oauth_bearer; /* bearer token for OAuth 2.0, allocated */
-
int httpversion; /* the HTTP version*10 reported by the server */
int rtspversion; /* the RTSP version*10 reported by the server */
--
2.34.1
From 85d1103c2fc0c9b1bdfae470dbafd45758e1c2f0 Mon Sep 17 00:00:00 2001
From: Patrick Monnerat <patrick@monnerat.net>
Date: Mon, 25 Apr 2022 11:44:05 +0200
Subject: [PATCH 2/2] url: check sasl additional parameters for connection
reuse.
Also move static function safecmp() as non-static Curl_safecmp() since
its purpose is needed at several places.
Bug: https://curl.se/docs/CVE-2022-22576.html
CVE-2022-22576
Closes #8746
Upstream-commit: 852aa5ad351ea53e5f01d2f44b5b4370c2bf5425
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/strcase.c | 10 ++++++++++
lib/strcase.h | 2 ++
lib/url.c | 12 +++++++++++-
lib/urldata.h | 2 ++
lib/vtls/vtls.c | 19 +++++--------------
5 files changed, 30 insertions(+), 15 deletions(-)
diff --git a/lib/strcase.c b/lib/strcase.c
index dd46ca1..692a3f1 100644
--- a/lib/strcase.c
+++ b/lib/strcase.c
@@ -165,6 +165,16 @@ void Curl_strntoupper(char *dest, const char *src, size_t n)
} while(*src++ && --n);
}
+/* Compare case-sensitive NUL-terminated strings, taking care of possible
+ * null pointers. Return true if arguments match.
+ */
+bool Curl_safecmp(char *a, char *b)
+{
+ if(a && b)
+ return !strcmp(a, b);
+ return !a && !b;
+}
+
/* --- public functions --- */
int curl_strequal(const char *first, const char *second)
diff --git a/lib/strcase.h b/lib/strcase.h
index b628656..382b80a 100644
--- a/lib/strcase.h
+++ b/lib/strcase.h
@@ -47,4 +47,6 @@ char Curl_raw_toupper(char in);
void Curl_strntoupper(char *dest, const char *src, size_t n);
+bool Curl_safecmp(char *a, char *b);
+
#endif /* HEADER_CURL_STRCASE_H */
diff --git a/lib/url.c b/lib/url.c
index adef2cd..94e3406 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -701,6 +701,7 @@ static void conn_free(struct connectdata *conn)
Curl_safefree(conn->allocptr.host);
Curl_safefree(conn->allocptr.cookiehost);
Curl_safefree(conn->allocptr.rtsp_transport);
+ Curl_safefree(conn->oauth_bearer);
Curl_safefree(conn->trailer);
Curl_safefree(conn->host.rawalloc); /* host name buffer */
Curl_safefree(conn->conn_to_host.rawalloc); /* host name buffer */
@@ -1291,7 +1292,8 @@ ConnectionExists(struct Curl_easy *data,
/* This protocol requires credentials per connection,
so verify that we're using the same name and password as well */
if(strcmp(needle->user, check->user) ||
- strcmp(needle->passwd, check->passwd)) {
+ strcmp(needle->passwd, check->passwd) ||
+ !Curl_safecmp(needle->oauth_bearer, check->oauth_bearer)) {
/* one of them was different */
continue;
}
@@ -4160,6 +4162,14 @@ static CURLcode create_conn(struct Curl_easy *data,
}
}
+ if(data->set.str[STRING_BEARER]) {
+ conn->oauth_bearer = strdup(data->set.str[STRING_BEARER]);
+ if(!conn->oauth_bearer) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto out;
+ }
+ }
+
#ifdef USE_UNIX_SOCKETS
if(data->set.str[STRING_UNIX_SOCKET_PATH]) {
conn->unix_domain_socket = strdup(data->set.str[STRING_UNIX_SOCKET_PATH]);
diff --git a/lib/urldata.h b/lib/urldata.h
index cc8a600..03da59a 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -850,6 +850,8 @@ struct connectdata {
char *passwd; /* password string, allocated */
char *options; /* options string, allocated */
+ char *oauth_bearer; /* OAUTH2 bearer, allocated */
+
int httpversion; /* the HTTP version*10 reported by the server */
int rtspversion; /* the RTSP version*10 reported by the server */
diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c
index 03b85ba..a40ac06 100644
--- a/lib/vtls/vtls.c
+++ b/lib/vtls/vtls.c
@@ -82,15 +82,6 @@
else \
dest->var = NULL;
-static bool safecmp(char *a, char *b)
-{
- if(a && b)
- return !strcmp(a, b);
- else if(!a && !b)
- return TRUE; /* match */
- return FALSE; /* no match */
-}
-
bool
Curl_ssl_config_matches(struct ssl_primary_config* data,
struct ssl_primary_config* needle)
@@ -100,11 +91,11 @@ Curl_ssl_config_matches(struct ssl_primary_config* data,
(data->verifypeer == needle->verifypeer) &&
(data->verifyhost == needle->verifyhost) &&
(data->verifystatus == needle->verifystatus) &&
- safecmp(data->CApath, needle->CApath) &&
- safecmp(data->CAfile, needle->CAfile) &&
- safecmp(data->clientcert, needle->clientcert) &&
- safecmp(data->random_file, needle->random_file) &&
- safecmp(data->egdsocket, needle->egdsocket) &&
+ Curl_safecmp(data->CApath, needle->CApath) &&
+ Curl_safecmp(data->CAfile, needle->CAfile) &&
+ Curl_safecmp(data->clientcert, needle->clientcert) &&
+ Curl_safecmp(data->random_file, needle->random_file) &&
+ Curl_safecmp(data->egdsocket, needle->egdsocket) &&
Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list) &&
Curl_safe_strcasecompare(data->cipher_list13, needle->cipher_list13))
return TRUE;
--
2.34.1

@ -0,0 +1,710 @@
From 24ff6b126726201cf778038c332b3b921c7f5b2f Mon Sep 17 00:00:00 2001
From: Katsuhiko YOSHIDA <claddvd@gmail.com>
Date: Sun, 30 Dec 2018 09:44:30 +0900
Subject: [PATCH 1/6] cookies: skip custom cookies when redirecting cross-site
Closes #3417
Upstream-commit: 1f30dc886d1a4a6e81599a9f5f5e9f60d97801d4
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
docs/libcurl/opts/CURLOPT_HTTPHEADER.3 | 4 ++
lib/http.c | 3 +-
tests/data/Makefile.inc | 2 +-
tests/data/test330 | 90 ++++++++++++++++++++++++++
4 files changed, 97 insertions(+), 2 deletions(-)
create mode 100644 tests/data/test330
diff --git a/docs/libcurl/opts/CURLOPT_HTTPHEADER.3 b/docs/libcurl/opts/CURLOPT_HTTPHEADER.3
index f5826e1..4af69f4 100644
--- a/docs/libcurl/opts/CURLOPT_HTTPHEADER.3
+++ b/docs/libcurl/opts/CURLOPT_HTTPHEADER.3
@@ -88,6 +88,10 @@ those servers will get all the contents of your custom headers too.
Starting in 7.58.0, libcurl will specifically prevent "Authorization:" headers
from being sent to other hosts than the first used one, unless specifically
permitted with the \fICURLOPT_UNRESTRICTED_AUTH(3)\fP option.
+
+Starting in 7.64.0, libcurl will specifically prevent "Cookie:" headers
+from being sent to other hosts than the first used one, unless specifically
+permitted with the \fICURLOPT_UNRESTRICTED_AUTH(3)\fP option.
.SH DEFAULT
NULL
.SH PROTOCOLS
diff --git a/lib/http.c b/lib/http.c
index bf19077..0b5e476 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -1774,7 +1774,8 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
checkprefix("Transfer-Encoding:", headers->data))
/* HTTP/2 doesn't support chunked requests */
;
- else if(checkprefix("Authorization:", headers->data) &&
+ else if((checkprefix("Authorization:", headers->data) ||
+ checkprefix("Cookie:", headers->data)) &&
/* be careful of sending this potentially sensitive header to
other hosts */
(data->state.this_is_a_follow &&
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index e0f1ef4..77e85fd 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -56,7 +56,7 @@ test289 test290 test291 test292 test293 test294 test295 test296 test297 \
test298 test299 test300 test301 test302 test303 test304 test305 test306 \
test307 test308 test309 test310 test311 test312 test313 test314 test315 \
test316 test317 test318 test319 test320 test321 test322 test323 test324 \
-test325 test326 \
+test325 test326 test330 \
\
test340 \
\
diff --git a/tests/data/test330 b/tests/data/test330
new file mode 100644
index 0000000..74607d5
--- /dev/null
+++ b/tests/data/test330
@@ -0,0 +1,90 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+followlocation
+cookies
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+<data>
+HTTP/1.1 302 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake swsclose
+Content-Type: text/html
+Funny-head: yesyes
+Location: http://goto.second.host.now/3170002
+Content-Length: 8
+Connection: close
+
+contents
+</data>
+<data2>
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake swsclose
+Content-Type: text/html
+Funny-head: yesyes
+Content-Length: 9
+
+contents
+</data2>
+
+<datacheck>
+HTTP/1.1 302 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake swsclose
+Content-Type: text/html
+Funny-head: yesyes
+Location: http://goto.second.host.now/3170002
+Content-Length: 8
+Connection: close
+
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake swsclose
+Content-Type: text/html
+Funny-head: yesyes
+Content-Length: 9
+
+contents
+</datacheck>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+ <name>
+HTTP with custom Cookie: and redirect to new host
+ </name>
+ <command>
+http://first.host.it.is/we/want/that/page/317 -x %HOSTIP:%HTTPPORT -H "Cookie: test=yes" --location
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET http://first.host.it.is/we/want/that/page/317 HTTP/1.1
+Host: first.host.it.is
+Accept: */*
+Proxy-Connection: Keep-Alive
+Cookie: test=yes
+
+GET http://goto.second.host.now/3170002 HTTP/1.1
+Host: goto.second.host.now
+Accept: */*
+Proxy-Connection: Keep-Alive
+
+</protocol>
+</verify>
+</testcase>
--
2.34.1
From a3f3855c8bf3a39ef0d86ef04087c200bca765f1 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 19 Dec 2019 16:45:53 +0100
Subject: [PATCH 2/6] sws: search for "Testno:" header uncondtionally if no
testno
Even if the initial request line wasn't found. With the fix to 1455, the
test number is now detected correctly.
(Problem found when running tests in random order.)
Closes #4744
Upstream-commit: 25b69c482f45c7acd817920bd8fdf68887be51a2
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
tests/data/test1455 | 3 ++-
tests/server/sws.c | 40 +++++++++++++++++++++++-----------------
2 files changed, 25 insertions(+), 18 deletions(-)
diff --git a/tests/data/test1455 b/tests/data/test1455
index 0b77dc4..25f742e 100644
--- a/tests/data/test1455
+++ b/tests/data/test1455
@@ -35,7 +35,7 @@ http
HTTP GET when PROXY Protocol enabled
</name>
<command>
-http://%HOSTIP:%HTTPPORT/1455 --haproxy-protocol
+http://%HOSTIP:%HTTPPORT/1455 --haproxy-protocol -H "Testno: 1455"
</command>
</client>
@@ -53,6 +53,7 @@ proxy-line
GET /1455 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Accept: */*
+Testno: 1455
</protocol>
</verify>
diff --git a/tests/server/sws.c b/tests/server/sws.c
index fbe7761..4ece830 100644
--- a/tests/server/sws.c
+++ b/tests/server/sws.c
@@ -367,6 +367,8 @@ static int parse_servercmd(struct httprequest *req)
filename = test2file(req->testno);
req->close = FALSE;
+ req->connmon = FALSE;
+
stream = fopen(filename, "rb");
if(!stream) {
error = errno;
@@ -391,8 +393,6 @@ static int parse_servercmd(struct httprequest *req)
return 1; /* done */
}
- req->connmon = FALSE;
-
cmd = orgcmd;
while(cmd && cmdsize) {
char *check;
@@ -548,12 +548,11 @@ static int ProcessRequest(struct httprequest *req)
snprintf(logbuf, sizeof(logbuf), "Requested test number %ld part %ld",
req->testno, req->partno);
logmsg("%s", logbuf);
-
- /* find and parse <servercmd> for this test */
- parse_servercmd(req);
}
- else
+ else {
+ logmsg("No test number");
req->testno = DOCNUMBER_NOTHING;
+ }
}
@@ -613,14 +612,6 @@ static int ProcessRequest(struct httprequest *req)
}
}
- if(req->testno == DOCNUMBER_NOTHING) {
- /* check for a Testno: header with the test case number */
- char *testno = strstr(line, "\nTestno: ");
- if(testno) {
- req->testno = strtol(&testno[9], NULL, 10);
- logmsg("Found test number %d in Testno: header!", req->testno);
- }
- }
if(req->testno == DOCNUMBER_NOTHING) {
/* Still no test case number. Try to get the the number off the last dot
instead, IE we consider the TLD to be the test number. Test 123 can
@@ -661,8 +652,8 @@ static int ProcessRequest(struct httprequest *req)
}
}
else if((req->offset >= 3) && (req->testno == DOCNUMBER_NOTHING)) {
- logmsg("** Unusual request. Starts with %02x %02x %02x",
- line[0], line[1], line[2]);
+ logmsg("** Unusual request. Starts with %02x %02x %02x (%c%c%c)",
+ line[0], line[1], line[2], line[0], line[1], line[2]);
}
if(!end) {
@@ -670,7 +661,22 @@ static int ProcessRequest(struct httprequest *req)
logmsg("request not complete yet");
return 0; /* not complete yet */
}
- logmsg("- request found to be complete");
+ logmsg("- request found to be complete (%d)", req->testno);
+
+ if(req->testno == DOCNUMBER_NOTHING) {
+ /* check for a Testno: header with the test case number */
+ char *testno = strstr(line, "\nTestno: ");
+ if(testno) {
+ req->testno = strtol(&testno[9], NULL, 10);
+ logmsg("Found test number %d in Testno: header!", req->testno);
+ }
+ else {
+ logmsg("No Testno: header");
+ }
+ }
+
+ /* find and parse <servercmd> for this test */
+ parse_servercmd(req);
if(use_gopher) {
/* when using gopher we cannot check the request until the entire
--
2.34.1
From 3772ea764c05a1cf37b96c091ae266138e8a2867 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 16 Apr 2020 14:16:22 +0200
Subject: [PATCH 3/6] runtests: always put test number in servercmd file
Upstream-commit: d1a2816b4128faa8ebc50ce93285c7364652856e
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
tests/runtests.pl | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/tests/runtests.pl b/tests/runtests.pl
index a0fd991..8d8ed81 100755
--- a/tests/runtests.pl
+++ b/tests/runtests.pl
@@ -3878,10 +3878,9 @@ sub singletest {
unlink($SERVER2IN);
unlink($PROXYIN);
- if(@ftpservercmd) {
- # write the instructions to file
- writearray($FTPDCMD, \@ftpservercmd);
- }
+ push @ftpservercmd, "Testnum $testnum\n";
+ # write the instructions to file
+ writearray($FTPDCMD, \@ftpservercmd);
# get the command line options to use
my @blaha;
@@ -4222,9 +4221,6 @@ sub singletest {
}
}
- # remove the test server commands file after each test
- unlink($FTPDCMD) if(-f $FTPDCMD);
-
# run the postcheck command
my @postcheck= getpart("client", "postcheck");
if(@postcheck) {
--
2.34.1
From ac04f6feaa19c636aa09a1b50643d70a77be4465 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 14 May 2020 17:45:40 +0200
Subject: [PATCH 4/6] sws: as last resort, get test number from server cmd file
If it can't be found in the request. Also support --cmdfile to set it to
a custom file name.
runtests.pl always writes this file with the test number in it since a
while back.
Upstream-commit: a3b0699d5c110270f09ac51b5b465ca8753b35a9
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
tests/server/sws.c | 68 ++++++++++++++++++++++++++++++++++------------
1 file changed, 51 insertions(+), 17 deletions(-)
diff --git a/tests/server/sws.c b/tests/server/sws.c
index 4ece830..2696872 100644
--- a/tests/server/sws.c
+++ b/tests/server/sws.c
@@ -155,6 +155,10 @@ const char *serverlogfile = DEFAULT_LOGFILE;
#define REQUEST_PROXY_DUMP "log/proxy.input"
#define RESPONSE_PROXY_DUMP "log/proxy.response"
+/* file in which additional instructions may be found */
+#define DEFAULT_CMDFILE "log/ftpserver.cmd"
+const char *cmdfile = DEFAULT_CMDFILE;
+
/* very-big-path support */
#define MAXDOCNAMELEN 140000
#define MAXDOCNAMELEN_TXT "139999"
@@ -358,6 +362,24 @@ static bool socket_domain_is_ip(void)
}
}
+/* parse the file on disk that might have a test number for us */
+static int parse_cmdfile(struct httprequest *req)
+{
+ int testnum = DOCNUMBER_NOTHING;
+ char buf[256];
+ FILE *f = fopen(cmdfile, FOPEN_READTEXT);
+ if(f) {
+ while(fgets(buf, sizeof(buf), f)) {
+ if(1 == sscanf(buf, "Testnum %d", &testnum)) {
+ logmsg("[%s] cmdfile says testnum %d", cmdfile, testnum);
+ req->testno = testnum;
+ }
+ }
+ fclose(f);
+ }
+ return 0;
+}
+
/* based on the testno, parse the correct server commands */
static int parse_servercmd(struct httprequest *req)
{
@@ -622,34 +644,41 @@ static int ProcessRequest(struct httprequest *req)
/* get the number after it */
if(ptr) {
+ long num;
ptr++; /* skip the dot */
- req->testno = strtol(ptr, &ptr, 10);
+ num = strtol(ptr, &ptr, 10);
- if(req->testno > 10000) {
- req->partno = req->testno % 10000;
- req->testno /= 10000;
+ if(num) {
+ req->testno = num;
+ if(req->testno > 10000) {
+ req->partno = req->testno % 10000;
+ req->testno /= 10000;
- logmsg("found test %d in requested host name", req->testno);
+ logmsg("found test %d in requested host name", req->testno);
+ }
+ else
+ req->partno = 0;
}
- else
- req->partno = 0;
- snprintf(logbuf, sizeof(logbuf),
- "Requested test number %ld part %ld (from host name)",
+ if(req->testno != DOCNUMBER_NOTHING) {
+ logmsg("Requested test number %ld part %ld (from host name)",
req->testno, req->partno);
- logmsg("%s", logbuf);
-
+ }
}
+ }
- if(!req->testno) {
- logmsg("Did not find test number in PATH");
- req->testno = DOCNUMBER_404;
- }
- else
- parse_servercmd(req);
+ if(req->testno == DOCNUMBER_NOTHING)
+ /* might get the test number */
+ parse_cmdfile(req);
+
+ if(req->testno == DOCNUMBER_NOTHING) {
+ logmsg("Did not find test number in PATH");
+ req->testno = DOCNUMBER_404;
}
+ else
+ parse_servercmd(req);
}
else if((req->offset >= 3) && (req->testno == DOCNUMBER_NOTHING)) {
logmsg("** Unusual request. Starts with %02x %02x %02x (%c%c%c)",
@@ -2038,6 +2067,11 @@ int main(int argc, char *argv[])
if(argc>arg)
serverlogfile = argv[arg++];
}
+ else if(!strcmp("--cmdfile", argv[arg])) {
+ arg++;
+ if(argc>arg)
+ cmdfile = argv[arg++];
+ }
else if(!strcmp("--gopher", argv[arg])) {
arg++;
use_gopher = TRUE;
--
2.34.1
From 9fa56a1e3ae7feff14668d8abd892fa028a9f32e Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 25 Apr 2022 13:05:40 +0200
Subject: [PATCH 5/6] http: avoid auth/cookie on redirects same host diff port
CVE-2022-27776
Reported-by: Harry Sintonen
Bug: https://curl.se/docs/CVE-2022-27776.html
Closes #8749
Upstream-commit: 6e659993952aa5f90f48864be84a1bbb047fc258
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/http.c | 33 +++++++++++++++++++++------------
lib/urldata.h | 16 +++++++++-------
2 files changed, 30 insertions(+), 19 deletions(-)
diff --git a/lib/http.c b/lib/http.c
index 0b5e476..39fc7aa 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -688,6 +688,21 @@ output_auth_headers(struct connectdata *conn,
return CURLE_OK;
}
+/*
+ * allow_auth_to_host() tells if autentication, cookies or other "sensitive
+ * data" can (still) be sent to this host.
+ */
+static bool allow_auth_to_host(struct connectdata *conn)
+{
+ struct Curl_easy *data = conn->data;
+ return (!data->state.this_is_a_follow ||
+ data->set.allow_auth_to_other_hosts ||
+ (data->state.first_host &&
+ strcasecompare(data->state.first_host, conn->host.name) &&
+ (data->state.first_remote_port == conn->remote_port) &&
+ (data->state.first_remote_protocol == conn->handler->protocol)));
+}
+
/**
* Curl_http_output_auth() setups the authentication headers for the
* host/proxy and the correct authentication
@@ -756,15 +771,11 @@ Curl_http_output_auth(struct connectdata *conn,
with it */
authproxy->done = TRUE;
- /* To prevent the user+password to get sent to other than the original
- host due to a location-follow, we do some weirdo checks here */
- if(!data->state.this_is_a_follow ||
- conn->bits.netrc ||
- !data->state.first_host ||
- data->set.allow_auth_to_other_hosts ||
- strcasecompare(data->state.first_host, conn->host.name)) {
+ /* To prevent the user+password to get sent to other than the original host
+ due to a location-follow */
+ if(allow_auth_to_host(conn)
+ || conn->bits.netrc)
result = output_auth_headers(conn, authhost, request, path, FALSE);
- }
else
authhost->done = TRUE;
@@ -1778,10 +1789,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
checkprefix("Cookie:", headers->data)) &&
/* be careful of sending this potentially sensitive header to
other hosts */
- (data->state.this_is_a_follow &&
- data->state.first_host &&
- !data->set.allow_auth_to_other_hosts &&
- !strcasecompare(data->state.first_host, conn->host.name)))
+ !allow_auth_to_host(conn))
;
else {
result = Curl_add_bufferf(req_buffer, "%s\r\n", headers->data);
@@ -1937,6 +1945,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
return CURLE_OUT_OF_MEMORY;
data->state.first_remote_port = conn->remote_port;
+ data->state.first_remote_protocol = conn->handler->protocol;
}
http->writebytecount = http->readbytecount = 0;
diff --git a/lib/urldata.h b/lib/urldata.h
index d3b971c..4bb0a84 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1231,13 +1231,15 @@ struct UrlState {
bytes / second */
bool this_is_a_follow; /* this is a followed Location: request */
bool refused_stream; /* this was refused, try again */
- char *first_host; /* host name of the first (not followed) request.
- if set, this should be the host name that we will
- sent authorization to, no else. Used to make Location:
- following not keep sending user+password... This is
- strdup() data.
- */
- int first_remote_port; /* remote port of the first (not followed) request */
+
+ /* host name, port number and protocol of the first (not followed) request.
+ if set, this should be the host name that we will sent authorization to,
+ no else. Used to make Location: following not keep sending user+password.
+ This is strdup()ed data. */
+ char *first_host;
+ int first_remote_port;
+ unsigned int first_remote_protocol;
+
struct curl_ssl_session *session; /* array of 'max_ssl_sessions' size */
long sessionage; /* number of the most recent session */
unsigned int tempcount; /* number of entries in use in tempwrite, 0 - 3 */
--
2.34.1
From a8bb1e37e22788abaca37c59cf447d690fdcdfa4 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 25 Apr 2022 13:05:47 +0200
Subject: [PATCH 6/6] test898: verify the fix for CVE-2022-27776
Do not pass on Authorization headers on redirects to another port
Upstream-commit: afe752e0504ab60bf63787ede0b992cbe1065f78
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
tests/data/Makefile.inc | 2 +-
tests/data/test898 | 91 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 92 insertions(+), 1 deletion(-)
create mode 100644 tests/data/test898
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index 77e85fd..58c9e31 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -99,7 +99,7 @@ test850 test851 test852 test853 test854 test855 test856 test857 test858 \
test859 test860 test861 test862 test863 test864 test865 test866 test867 \
test868 test869 test870 test871 test872 test873 test874 test875 test876 \
test877 test878 test879 test880 test881 test882 test883 test884 test885 \
-test886 test887 test888 test889 test890 test891 \
+test886 test887 test888 test889 test890 test891 test898 \
\
test900 test901 test902 test903 test904 test905 test906 test907 test908 \
test909 test910 test911 test912 test913 test914 test915 test916 test917 \
diff --git a/tests/data/test898 b/tests/data/test898
new file mode 100644
index 0000000..e295c26
--- /dev/null
+++ b/tests/data/test898
@@ -0,0 +1,91 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+--location
+Authorization
+Cookie
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data>
+HTTP/1.1 301 redirect
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 0
+Connection: close
+Content-Type: text/html
+Location: http://firsthost.com:9999/a/path/8980002
+
+</data>
+<data2>
+HTTP/1.1 200 OK
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 4
+Connection: close
+Content-Type: text/html
+
+hey
+</data2>
+
+<datacheck>
+HTTP/1.1 301 redirect
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 0
+Connection: close
+Content-Type: text/html
+Location: http://firsthost.com:9999/a/path/8980002
+
+HTTP/1.1 200 OK
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 4
+Connection: close
+Content-Type: text/html
+
+hey
+</datacheck>
+
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+ <name>
+HTTP with custom auth and cookies redirected to HTTP on a diff port
+ </name>
+ <command>
+-x http://%HOSTIP:%HTTPPORT http://firsthost.com -L -H "Authorization: Basic am9lOnNlY3JldA==" -H "Cookie: userpwd=am9lOnNlY3JldA=="
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET http://firsthost.com/ HTTP/1.1
+Host: firsthost.com
+Accept: */*
+Proxy-Connection: Keep-Alive
+Authorization: Basic am9lOnNlY3JldA==
+Cookie: userpwd=am9lOnNlY3JldA==
+
+GET http://firsthost.com:9999/a/path/8980002 HTTP/1.1
+Host: firsthost.com:9999
+Accept: */*
+Proxy-Connection: Keep-Alive
+
+</protocol>
+</verify>
+</testcase>
--
2.34.1

@ -0,0 +1,714 @@
From 48f126157d36962e458bf12f90b50cfcef26eee9 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 25 Apr 2022 16:24:33 +0200
Subject: [PATCH 1/4] connect: store "conn_remote_port" in the info struct
To make it available after the connection ended.
Upstream-commit: 08b8ef4e726ba10f45081ecda5b3cea788d3c839
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/connect.c | 1 +
lib/urldata.h | 6 +++++-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/lib/connect.c b/lib/connect.c
index f724646..12a8aae 100644
--- a/lib/connect.c
+++ b/lib/connect.c
@@ -614,6 +614,7 @@ void Curl_persistconninfo(struct connectdata *conn)
conn->data->info.conn_scheme = conn->handler->scheme;
conn->data->info.conn_protocol = conn->handler->protocol;
conn->data->info.conn_primary_port = conn->primary_port;
+ conn->data->info.conn_remote_port = conn->remote_port;
conn->data->info.conn_local_port = conn->local_port;
}
diff --git a/lib/urldata.h b/lib/urldata.h
index 4bb0a84..cadf0e5 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1050,7 +1050,11 @@ struct PureInfo {
reused, in the connection cache. */
char conn_primary_ip[MAX_IPADR_LEN];
- long conn_primary_port;
+ long conn_primary_port;/* this is the destination port to the connection,
+ which might have been a proxy */
+ int conn_remote_port; /* this is the "remote port", which is the port
+ number of the used URL, independent of proxy or
+ not */
char conn_local_ip[MAX_IPADR_LEN];
long conn_local_port;
--
2.34.1
From 6307fa6f9784402ba58697f46ba04354225391b7 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 25 Apr 2022 16:24:33 +0200
Subject: [PATCH 2/4] transfer: redirects to other protocols or ports clear
auth
... unless explicitly permitted.
Bug: https://curl.se/docs/CVE-2022-27774.html
Reported-by: Harry Sintonen
Closes #8748
Upstream-commit: 620ea21410030a9977396b4661806bc187231b79
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/transfer.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++
lib/url.c | 27 ++++++++++++++--------
lib/urldata.h | 1 +
3 files changed, 81 insertions(+), 10 deletions(-)
diff --git a/lib/transfer.c b/lib/transfer.c
index ad5a7ba..2022cba 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -1370,6 +1370,7 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
data->state.wildcardmatch = data->set.wildcard_enabled;
data->set.followlocation = 0; /* reset the location-follow counter */
data->state.this_is_a_follow = FALSE; /* reset this */
+ data->state.this_is_a_follow_without_auth = FALSE;
data->state.errorbuf = FALSE; /* no error has occurred */
data->state.httpversion = 0; /* don't assume any particular server version */
@@ -1554,6 +1555,68 @@ CURLcode Curl_follow(struct Curl_easy *data,
}
+ /* Clear auth if this redirects to a different port number or protocol,
+ unless permitted */
+ if(!data->set.allow_auth_to_other_hosts && (type != FOLLOW_FAKE)) {
+ int port;
+ bool clear = FALSE;
+
+ CURLU *u = curl_url();
+ if(!u)
+ return CURLE_OUT_OF_MEMORY;
+
+ uc = curl_url_set(u, CURLUPART_URL, newurl,
+ ((type == FOLLOW_REDIR) ? CURLU_URLENCODE : 0));
+ if(uc) {
+ infof(data, "Clear auth, curl_url_set() failed\n");
+ clear = TRUE;
+ }
+
+ if(!clear) {
+ if(data->set.use_port && data->state.allow_port)
+ /* a custom port is used */
+ port = (int)data->set.use_port;
+ else {
+ char *portnum;
+ uc = curl_url_get(u, CURLUPART_PORT, &portnum, CURLU_DEFAULT_PORT);
+ if(uc) {
+ infof(data, "Clear auth, failed to parse port number\n");
+ clear = TRUE;
+ }
+ else {
+ port = atoi(portnum);
+ free(portnum);
+ }
+ }
+ }
+ if(!clear && port != data->info.conn_remote_port) {
+ infof(data, "Clear auth, redirects to port from %u to %u\n",
+ data->info.conn_remote_port, port);
+ clear = TRUE;
+ }
+ if(!clear) {
+ char *scheme;
+ const struct Curl_handler *p;
+ uc = curl_url_get(u, CURLUPART_SCHEME, &scheme, 0);
+ if(uc) {
+ infof(data, "Clear auth, failed to parse scheme\n");
+ clear = TRUE;
+ }
+ else {
+ p = Curl_builtin_scheme(scheme);
+ if(p && (p->protocol != data->info.conn_protocol)) {
+ infof(data, "Clear auth, redirects scheme from %s to %s\n",
+ data->info.conn_scheme, scheme);
+ clear = TRUE;
+ }
+ free(scheme);
+ }
+ }
+ if(clear)
+ data->state.this_is_a_follow_without_auth = TRUE;
+ curl_url_cleanup(u);
+ }
+
if(type == FOLLOW_FAKE) {
/* we're only figuring out the new url if we would've followed locations
but now we're done so we can get out! */
diff --git a/lib/url.c b/lib/url.c
index ed3c933..7dd5267 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -3483,18 +3483,25 @@ static CURLcode override_login(struct Curl_easy *data,
struct connectdata *conn,
char **userp, char **passwdp, char **optionsp)
{
- if(data->set.str[STRING_USERNAME]) {
- free(*userp);
- *userp = strdup(data->set.str[STRING_USERNAME]);
- if(!*userp)
- return CURLE_OUT_OF_MEMORY;
+ if(data->state.this_is_a_follow
+ && data->state.this_is_a_follow_without_auth)
+ {
+ conn->bits.user_passwd = FALSE;
}
+ else {
+ if(data->set.str[STRING_USERNAME]) {
+ free(*userp);
+ *userp = strdup(data->set.str[STRING_USERNAME]);
+ if(!*userp)
+ return CURLE_OUT_OF_MEMORY;
+ }
- if(data->set.str[STRING_PASSWORD]) {
- free(*passwdp);
- *passwdp = strdup(data->set.str[STRING_PASSWORD]);
- if(!*passwdp)
- return CURLE_OUT_OF_MEMORY;
+ if(data->set.str[STRING_PASSWORD]) {
+ free(*passwdp);
+ *passwdp = strdup(data->set.str[STRING_PASSWORD]);
+ if(!*passwdp)
+ return CURLE_OUT_OF_MEMORY;
+ }
}
if(data->set.str[STRING_OPTIONS]) {
diff --git a/lib/urldata.h b/lib/urldata.h
index cadf0e5..026684b 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1234,6 +1234,7 @@ struct UrlState {
curl_off_t current_speed; /* the ProgressShow() function sets this,
bytes / second */
bool this_is_a_follow; /* this is a followed Location: request */
+ bool this_is_a_follow_without_auth;
bool refused_stream; /* this was refused, try again */
/* host name, port number and protocol of the first (not followed) request.
--
2.34.1
From b142f97840dfb033a1776d5a2986385da7753224 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 25 Apr 2022 16:24:33 +0200
Subject: [PATCH 3/4] tests: verify the fix for CVE-2022-27774
- Test 973 redirects from HTTP to FTP, clear auth
- Test 974 redirects from HTTP to HTTP different port, clear auth
- Test 975 redirects from HTTP to FTP, permitted to keep auth
- Test 976 redirects from HTTP to HTTP different port, permitted to keep
auth
Upstream-commit: 5295e8d64ac6949ecb3f9e564317a608f51b90d8
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
tests/data/Makefile.inc | 1 +
tests/data/test973 | 90 +++++++++++++++++++++++++++++++++++++++++
tests/data/test974 | 88 ++++++++++++++++++++++++++++++++++++++++
tests/data/test975 | 90 +++++++++++++++++++++++++++++++++++++++++
tests/data/test976 | 89 ++++++++++++++++++++++++++++++++++++++++
5 files changed, 358 insertions(+)
create mode 100644 tests/data/test973
create mode 100644 tests/data/test974
create mode 100644 tests/data/test975
create mode 100644 tests/data/test976
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index 58c9e31..6c920ff 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -108,6 +108,7 @@ test927 test928 test929 test930 test931 test932 test933 test934 test935 \
test936 test937 test938 test939 test940 test941 test942 test943 test944 \
test945 test946 test947 test948 test949 test950 test951 test952 \
\
+test973 test974 test975 test976 \
test980 test981 test982 test983 test984 test985 test986 \
\
test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 \
diff --git a/tests/data/test973 b/tests/data/test973
new file mode 100644
index 0000000..6fe6ce0
--- /dev/null
+++ b/tests/data/test973
@@ -0,0 +1,90 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+FTP
+--location
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data>
+HTTP/1.1 301 redirect
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 0
+Connection: close
+Content-Type: text/html
+Location: ftp://127.0.0.1:8992/a/path/9730002
+
+</data>
+<data2>
+data
+ to
+ see
+that FTP
+works
+ so does it?
+</data2>
+
+<datacheck>
+HTTP/1.1 301 redirect
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 0
+Connection: close
+Content-Type: text/html
+Location: ftp://127.0.0.1:8992/a/path/9730002
+
+data
+ to
+ see
+that FTP
+works
+ so does it?
+</datacheck>
+
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+ftp
+</server>
+ <name>
+HTTP with auth redirected to FTP w/o auth
+ </name>
+ <command>
+http://%HOSTIP:%HTTPPORT/973 -L -u joe:secret
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET /973 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Authorization: Basic am9lOnNlY3JldA==
+Accept: */*
+
+USER anonymous
+PASS ftp@example.com
+PWD
+CWD a
+CWD path
+EPSV
+TYPE I
+SIZE 9730002
+RETR 9730002
+QUIT
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test974 b/tests/data/test974
new file mode 100644
index 0000000..de02d89
--- /dev/null
+++ b/tests/data/test974
@@ -0,0 +1,88 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+--location
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data>
+HTTP/1.1 301 redirect
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 0
+Connection: close
+Content-Type: text/html
+Location: http://firsthost.com:9999/a/path/9740002
+
+</data>
+<data2>
+HTTP/1.1 200 OK
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 4
+Connection: close
+Content-Type: text/html
+
+hey
+</data2>
+
+<datacheck>
+HTTP/1.1 301 redirect
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 0
+Connection: close
+Content-Type: text/html
+Location: http://firsthost.com:9999/a/path/9740002
+
+HTTP/1.1 200 OK
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 4
+Connection: close
+Content-Type: text/html
+
+hey
+</datacheck>
+
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+ <name>
+HTTP with auth redirected to HTTP on a diff port w/o auth
+ </name>
+ <command>
+-x http://%HOSTIP:%HTTPPORT http://firsthost.com -L -u joe:secret
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET http://firsthost.com/ HTTP/1.1
+Host: firsthost.com
+Authorization: Basic am9lOnNlY3JldA==
+Accept: */*
+Proxy-Connection: Keep-Alive
+
+GET http://firsthost.com:9999/a/path/9740002 HTTP/1.1
+Host: firsthost.com:9999
+Accept: */*
+Proxy-Connection: Keep-Alive
+
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test975 b/tests/data/test975
new file mode 100644
index 0000000..3a4eccf
--- /dev/null
+++ b/tests/data/test975
@@ -0,0 +1,90 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+FTP
+--location-trusted
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data>
+HTTP/1.1 301 redirect
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 0
+Connection: close
+Content-Type: text/html
+Location: ftp://127.0.0.1:8992/a/path/9750002
+
+</data>
+<data2>
+data
+ to
+ see
+that FTP
+works
+ so does it?
+</data2>
+
+<datacheck>
+HTTP/1.1 301 redirect
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 0
+Connection: close
+Content-Type: text/html
+Location: ftp://127.0.0.1:8992/a/path/9750002
+
+data
+ to
+ see
+that FTP
+works
+ so does it?
+</datacheck>
+
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+ftp
+</server>
+ <name>
+HTTP with auth redirected to FTP allowing auth to continue
+ </name>
+ <command>
+http://%HOSTIP:%HTTPPORT/975 --location-trusted -u joe:secret
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET /975 HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Authorization: Basic am9lOnNlY3JldA==
+Accept: */*
+
+USER joe
+PASS secret
+PWD
+CWD a
+CWD path
+EPSV
+TYPE I
+SIZE 9750002
+RETR 9750002
+QUIT
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test976 b/tests/data/test976
new file mode 100644
index 0000000..3b6fac7
--- /dev/null
+++ b/tests/data/test976
@@ -0,0 +1,89 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+--location-trusted
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data>
+HTTP/1.1 301 redirect
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 0
+Connection: close
+Content-Type: text/html
+Location: http://firsthost.com:9999/a/path/9760002
+
+</data>
+<data2>
+HTTP/1.1 200 OK
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 4
+Connection: close
+Content-Type: text/html
+
+hey
+</data2>
+
+<datacheck>
+HTTP/1.1 301 redirect
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 0
+Connection: close
+Content-Type: text/html
+Location: http://firsthost.com:9999/a/path/9760002
+
+HTTP/1.1 200 OK
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 4
+Connection: close
+Content-Type: text/html
+
+hey
+</datacheck>
+
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+ <name>
+HTTP with auth redirected to HTTP on a diff port --location-trusted
+ </name>
+ <command>
+-x http://%HOSTIP:%HTTPPORT http://firsthost.com --location-trusted -u joe:secret
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET http://firsthost.com/ HTTP/1.1
+Host: firsthost.com
+Authorization: Basic am9lOnNlY3JldA==
+Accept: */*
+Proxy-Connection: Keep-Alive
+
+GET http://firsthost.com:9999/a/path/9760002 HTTP/1.1
+Host: firsthost.com:9999
+Authorization: Basic am9lOnNlY3JldA==
+Accept: */*
+Proxy-Connection: Keep-Alive
+
+</protocol>
+</verify>
+</testcase>
--
2.34.1
From cf98bd64b9949c50d4726eb26745c2f7fdf3a075 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 25 Apr 2022 17:59:15 +0200
Subject: [PATCH 4/4] openssl: don't leak the SRP credentials in redirects
either
Follow-up to 620ea21410030
Reported-by: Harry Sintonen
Closes #8751
Upstream-commit: 139a54ed0a172adaaf1a78d6f4fff50b2c3f9e08
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/http.c | 10 +++++-----
lib/http.h | 6 ++++++
lib/vtls/openssl.c | 3 ++-
3 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/lib/http.c b/lib/http.c
index 39fc7aa..d413738 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -689,10 +689,10 @@ output_auth_headers(struct connectdata *conn,
}
/*
- * allow_auth_to_host() tells if autentication, cookies or other "sensitive
- * data" can (still) be sent to this host.
+ * Curl_allow_auth_to_host() tells if authentication, cookies or other
+ * "sensitive data" can (still) be sent to this host.
*/
-static bool allow_auth_to_host(struct connectdata *conn)
+bool Curl_allow_auth_to_host(struct connectdata *conn)
{
struct Curl_easy *data = conn->data;
return (!data->state.this_is_a_follow ||
@@ -773,7 +773,7 @@ Curl_http_output_auth(struct connectdata *conn,
/* To prevent the user+password to get sent to other than the original host
due to a location-follow */
- if(allow_auth_to_host(conn)
+ if(Curl_allow_auth_to_host(conn)
|| conn->bits.netrc)
result = output_auth_headers(conn, authhost, request, path, FALSE);
else
@@ -1789,7 +1789,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
checkprefix("Cookie:", headers->data)) &&
/* be careful of sending this potentially sensitive header to
other hosts */
- !allow_auth_to_host(conn))
+ !Curl_allow_auth_to_host(conn))
;
else {
result = Curl_add_bufferf(req_buffer, "%s\r\n", headers->data);
diff --git a/lib/http.h b/lib/http.h
index 1d373e8..56a6061 100644
--- a/lib/http.h
+++ b/lib/http.h
@@ -252,5 +252,11 @@ Curl_http_output_auth(struct connectdata *conn,
bool proxytunnel); /* TRUE if this is the request setting
up the proxy tunnel */
+/*
+ * Curl_allow_auth_to_host() tells if authentication, cookies or other
+ * "sensitive data" can (still) be sent to this host.
+ */
+bool Curl_allow_auth_to_host(struct connectdata *conn);
+
#endif /* HEADER_CURL_HTTP_H */
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index 28eaa6d..6c8faa2 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -2499,7 +2499,8 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
#endif
#ifdef USE_TLS_SRP
- if(ssl_authtype == CURL_TLSAUTH_SRP) {
+ if((ssl_authtype == CURL_TLSAUTH_SRP) &&
+ Curl_allow_auth_to_host(conn)) {
char * const ssl_username = SSL_SET_OPTION(username);
infof(data, "Using TLS-SRP username: %s\n", ssl_username);
--
2.34.1

@ -0,0 +1,364 @@
From d4247fa7baf0859729fff2fe5cf0bfab8322d1a5 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 9 May 2022 23:13:53 +0200
Subject: [PATCH 1/2] tls: check more TLS details for connection reuse
CVE-2022-27782
Reported-by: Harry Sintonen
Bug: https://curl.se/docs/CVE-2022-27782.html
Closes #8825
Upstream-commit: f18af4f874cecab82a9797e8c7541e0990c7a64c
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/setopt.c | 29 +++++++++++++++++------------
lib/url.c | 19 ++++++++++++-------
lib/urldata.h | 14 +++++++-------
lib/vtls/openssl.c | 10 +++++-----
lib/vtls/vtls.c | 21 +++++++++++++++++++++
5 files changed, 62 insertions(+), 31 deletions(-)
diff --git a/lib/setopt.c b/lib/setopt.c
index b07ccfe..319a010 100644
--- a/lib/setopt.c
+++ b/lib/setopt.c
@@ -2044,6 +2044,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
case CURLOPT_SSL_OPTIONS:
arg = va_arg(param, long);
+ data->set.ssl.primary.ssl_options = (unsigned char)(arg & 0xff);
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);
@@ -2051,6 +2052,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
case CURLOPT_PROXY_SSL_OPTIONS:
arg = va_arg(param, long);
+ data->set.proxy_ssl.primary.ssl_options = (unsigned char)(arg & 0xff);
data->set.proxy_ssl.enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE;
data->set.proxy_ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
break;
@@ -2451,44 +2453,47 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
case CURLOPT_TLSAUTH_USERNAME:
result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME],
va_arg(param, char *));
- if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
- data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
+ if(data->set.str[STRING_TLSAUTH_USERNAME] &&
+ !data->set.ssl.primary.authtype)
+ data->set.ssl.primary.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
break;
case CURLOPT_PROXY_TLSAUTH_USERNAME:
result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_PROXY],
va_arg(param, char *));
if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] &&
- !data->set.proxy_ssl.authtype)
- data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
+ !data->set.proxy_ssl.primary.authtype)
+ data->set.proxy_ssl.primary.authtype = CURL_TLSAUTH_SRP; /* default to
+ SRP */
break;
case CURLOPT_TLSAUTH_PASSWORD:
result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD],
va_arg(param, char *));
- if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
- data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
+ if(data->set.str[STRING_TLSAUTH_USERNAME] &&
+ !data->set.ssl.primary.authtype)
+ data->set.ssl.primary.authtype = CURL_TLSAUTH_SRP; /* default */
break;
case CURLOPT_PROXY_TLSAUTH_PASSWORD:
result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_PROXY],
va_arg(param, char *));
if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] &&
- !data->set.proxy_ssl.authtype)
- data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
+ !data->set.proxy_ssl.primary.authtype)
+ data->set.proxy_ssl.primary.authtype = CURL_TLSAUTH_SRP; /* default */
break;
case CURLOPT_TLSAUTH_TYPE:
argptr = va_arg(param, char *);
if(!argptr ||
strncasecompare(argptr, "SRP", strlen("SRP")))
- data->set.ssl.authtype = CURL_TLSAUTH_SRP;
+ data->set.ssl.primary.authtype = CURL_TLSAUTH_SRP;
else
- data->set.ssl.authtype = CURL_TLSAUTH_NONE;
+ data->set.ssl.primary.authtype = CURL_TLSAUTH_NONE;
break;
case CURLOPT_PROXY_TLSAUTH_TYPE:
argptr = va_arg(param, char *);
if(!argptr ||
strncasecompare(argptr, "SRP", strlen("SRP")))
- data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP;
+ data->set.proxy_ssl.primary.authtype = CURL_TLSAUTH_SRP;
else
- data->set.proxy_ssl.authtype = CURL_TLSAUTH_NONE;
+ data->set.proxy_ssl.primary.authtype = CURL_TLSAUTH_NONE;
break;
#endif
case CURLOPT_DNS_SERVERS:
diff --git a/lib/url.c b/lib/url.c
index 7dd5267..30fc5ad 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -461,7 +461,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
set->ssl.primary.verifypeer = TRUE;
set->ssl.primary.verifyhost = TRUE;
#ifdef USE_TLS_SRP
- set->ssl.authtype = CURL_TLSAUTH_NONE;
+ set->ssl.primary.authtype = CURL_TLSAUTH_NONE;
#endif
set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
type */
@@ -1881,10 +1881,12 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
conn->ssl_config.verifystatus = data->set.ssl.primary.verifystatus;
conn->ssl_config.verifypeer = data->set.ssl.primary.verifypeer;
conn->ssl_config.verifyhost = data->set.ssl.primary.verifyhost;
+ conn->ssl_config.ssl_options = data->set.ssl.primary.ssl_options;
conn->proxy_ssl_config.verifystatus =
data->set.proxy_ssl.primary.verifystatus;
conn->proxy_ssl_config.verifypeer = data->set.proxy_ssl.primary.verifypeer;
conn->proxy_ssl_config.verifyhost = data->set.proxy_ssl.primary.verifyhost;
+ conn->proxy_ssl_config.ssl_options = data->set.proxy_ssl.primary.ssl_options;
conn->ip_version = data->set.ipver;
@@ -4362,8 +4364,9 @@ static CURLcode create_conn(struct Curl_easy *data,
data->set.proxy_ssl.primary.cipher_list13 =
data->set.str[STRING_SSL_CIPHER13_LIST_PROXY];
- data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE];
- data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY];
+ data->set.ssl.primary.CRLfile = data->set.str[STRING_SSL_CRLFILE];
+ data->set.proxy_ssl.primary.CRLfile =
+ data->set.str[STRING_SSL_CRLFILE_PROXY];
data->set.ssl.cert = data->set.str[STRING_CERT];
data->set.proxy_ssl.cert = data->set.str[STRING_CERT_PROXY];
data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE];
@@ -4377,10 +4380,12 @@ static CURLcode create_conn(struct Curl_easy *data,
data->set.ssl.primary.clientcert = data->set.str[STRING_CERT];
data->set.proxy_ssl.primary.clientcert = data->set.str[STRING_CERT_PROXY];
#ifdef USE_TLS_SRP
- data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME];
- data->set.proxy_ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_PROXY];
- data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD];
- data->set.proxy_ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_PROXY];
+ data->set.ssl.primary.username = data->set.str[STRING_TLSAUTH_USERNAME];
+ data->set.ssl.primary.password = data->set.str[STRING_TLSAUTH_PASSWORD];
+ data->set.proxy_ssl.primary.username =
+ data->set.str[STRING_TLSAUTH_USERNAME_PROXY];
+ data->set.proxy_ssl.primary.password =
+ data->set.str[STRING_TLSAUTH_PASSWORD_PROXY];
#endif
if(!Curl_clone_primary_ssl_config(&data->set.ssl.primary,
diff --git a/lib/urldata.h b/lib/urldata.h
index 026684b..0e48841 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -229,6 +229,13 @@ struct ssl_primary_config {
char *egdsocket; /* path to file containing the EGD daemon socket */
char *cipher_list; /* list of ciphers to use */
char *cipher_list13; /* list of TLS 1.3 cipher suites to use */
+ char *CRLfile; /* CRL to check certificate revocation */
+#ifdef USE_TLS_SRP
+ char *username; /* TLS username (for, e.g., SRP) */
+ char *password; /* TLS password (for, e.g., SRP) */
+ enum CURL_TLSAUTH authtype; /* TLS authentication type (default SRP) */
+#endif
+ unsigned char ssl_options; /* the CURLOPT_SSL_OPTIONS bitmask */
};
struct ssl_config_data {
@@ -238,7 +245,6 @@ struct ssl_config_data {
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 */
curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */
void *fsslctxp; /* parameter for call back */
bool certinfo; /* gather lots of certificate info */
@@ -249,12 +255,6 @@ struct ssl_config_data {
char *key; /* private key file name */
char *key_type; /* format for private key (default: PEM) */
char *key_passwd; /* plain text private key password */
-
-#ifdef USE_TLS_SRP
- char *username; /* TLS username (for, e.g., SRP) */
- char *password; /* TLS password (for, e.g., SRP) */
- enum CURL_TLSAUTH authtype; /* TLS authentication type (default SRP) */
-#endif
};
struct ssl_general_config {
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index 6c8faa2..75ff8d8 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -2232,14 +2232,14 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
&data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
const long int ssl_version = SSL_CONN_CONFIG(version);
#ifdef USE_TLS_SRP
- const enum CURL_TLSAUTH ssl_authtype = SSL_SET_OPTION(authtype);
+ const enum CURL_TLSAUTH ssl_authtype = SSL_SET_OPTION(primary.authtype);
#endif
char * const ssl_cert = SSL_SET_OPTION(cert);
const char * const ssl_cert_type = SSL_SET_OPTION(cert_type);
const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
const char * const ssl_capath = SSL_CONN_CONFIG(CApath);
const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
- const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile);
+ const char * const ssl_crlfile = SSL_SET_OPTION(primary.CRLfile);
char error_buffer[256];
DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
@@ -2501,15 +2501,15 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
#ifdef USE_TLS_SRP
if((ssl_authtype == CURL_TLSAUTH_SRP) &&
Curl_allow_auth_to_host(conn)) {
- char * const ssl_username = SSL_SET_OPTION(username);
-
+ char * const ssl_username = SSL_SET_OPTION(primary.username);
+ char * const ssl_password = SSL_SET_OPTION(primary.password);
infof(data, "Using TLS-SRP username: %s\n", ssl_username);
if(!SSL_CTX_set_srp_username(BACKEND->ctx, ssl_username)) {
failf(data, "Unable to set SRP user name");
return CURLE_BAD_FUNCTION_ARGUMENT;
}
- if(!SSL_CTX_set_srp_password(BACKEND->ctx, SSL_SET_OPTION(password))) {
+ if(!SSL_CTX_set_srp_password(BACKEND->ctx, ssl_password)) {
failf(data, "failed setting SRP password");
return CURLE_BAD_FUNCTION_ARGUMENT;
}
diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c
index bdff93f..2b14fa6 100644
--- a/lib/vtls/vtls.c
+++ b/lib/vtls/vtls.c
@@ -88,6 +88,7 @@ Curl_ssl_config_matches(struct ssl_primary_config* data,
{
if((data->version == needle->version) &&
(data->version_max == needle->version_max) &&
+ (data->ssl_options == needle->ssl_options) &&
(data->verifypeer == needle->verifypeer) &&
(data->verifyhost == needle->verifyhost) &&
(data->verifystatus == needle->verifystatus) &&
@@ -96,6 +97,12 @@ Curl_ssl_config_matches(struct ssl_primary_config* data,
Curl_safecmp(data->clientcert, needle->clientcert) &&
Curl_safecmp(data->random_file, needle->random_file) &&
Curl_safecmp(data->egdsocket, needle->egdsocket) &&
+#ifdef USE_TLS_SRP
+ Curl_safecmp(data->username, needle->username) &&
+ Curl_safecmp(data->password, needle->password) &&
+ (data->authtype == needle->authtype) &&
+#endif
+ Curl_safe_strcasecompare(data->CRLfile, needle->CRLfile) &&
Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list) &&
Curl_safe_strcasecompare(data->cipher_list13, needle->cipher_list13))
return TRUE;
@@ -113,6 +120,10 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
dest->verifyhost = source->verifyhost;
dest->verifystatus = source->verifystatus;
dest->sessionid = source->sessionid;
+ dest->ssl_options = source->ssl_options;
+#ifdef USE_TLS_SRP
+ dest->authtype = source->authtype;
+#endif
CLONE_STRING(CApath);
CLONE_STRING(CAfile);
@@ -122,6 +133,11 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
CLONE_STRING(egdsocket);
CLONE_STRING(cipher_list);
CLONE_STRING(cipher_list13);
+ CLONE_STRING(CRLfile);
+#ifdef USE_TLS_SRP
+ CLONE_STRING(username);
+ CLONE_STRING(password);
+#endif
return TRUE;
}
@@ -136,6 +152,11 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config* sslc)
Curl_safefree(sslc->egdsocket);
Curl_safefree(sslc->cipher_list);
Curl_safefree(sslc->cipher_list13);
+ Curl_safefree(sslc->CRLfile);
+#ifdef USE_TLS_SRP
+ Curl_safefree(sslc->username);
+ Curl_safefree(sslc->password);
+#endif
}
#ifdef USE_SSL
--
2.34.1
From a9cf46e6c6c9a4261f3ea8500dfef87c1436908b Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 9 May 2022 23:13:53 +0200
Subject: [PATCH 2/2] url: check SSH config match on connection reuse
CVE-2022-27782
Reported-by: Harry Sintonen
Bug: https://curl.se/docs/CVE-2022-27782.html
Closes #8825
Upstream-commit: 1645e9b44505abd5cbaf65da5282c3f33b5924a5
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/ssh.h | 4 ++--
lib/url.c | 11 +++++++++++
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/lib/ssh.h b/lib/ssh.h
index 0620aac..1114f8a 100644
--- a/lib/ssh.h
+++ b/lib/ssh.h
@@ -117,8 +117,8 @@ struct ssh_conn {
/* common */
const char *passphrase; /* pass-phrase to use */
- char *rsa_pub; /* path name */
- char *rsa; /* path name */
+ char *rsa_pub; /* strdup'ed public key file */
+ char *rsa; /* strdup'ed private key file */
bool authed; /* the connection has been authenticated fine */
sshstate state; /* always use ssh.c:state() to change state! */
sshstate nextstate; /* the state to goto after stopping */
diff --git a/lib/url.c b/lib/url.c
index 30fc5ad..8653ebb 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -1030,6 +1030,12 @@ static size_t max_pipeline_length(struct Curl_multi *multi)
}
+static bool ssh_config_matches(struct connectdata *one,
+ struct connectdata *two)
+{
+ return (Curl_safecmp(one->proto.sshc.rsa, two->proto.sshc.rsa) &&
+ Curl_safecmp(one->proto.sshc.rsa_pub, two->proto.sshc.rsa_pub));
+}
/*
* Given one filled in connection struct (named needle), this function should
* detect if there already is one that has all the significant details
@@ -1299,6 +1305,11 @@ ConnectionExists(struct Curl_easy *data,
}
}
+ if(needle->handler->protocol & (CURLPROTO_SCP|CURLPROTO_SFTP)) {
+ if(!ssh_config_matches(needle, check))
+ continue;
+ }
+
if(!needle->bits.httpproxy || (needle->handler->flags&PROTOPT_SSL) ||
needle->bits.tunnel_proxy) {
/* The requested connection does not use a HTTP proxy or it uses SSL or
--
2.34.1

@ -0,0 +1,86 @@
From d36661703e16bd740a3a928041b1e697a6617b98 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 9 Jun 2022 09:27:24 +0200
Subject: [PATCH] krb5: return error properly on decode errors
Bug: https://curl.se/docs/CVE-2022-32208.html
CVE-2022-32208
Reported-by: Harry Sintonen
Closes #9051
Upstream-commit: 6ecdf5136b52af747e7bda08db9a748256b1cd09
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/krb5.c | 5 +----
lib/security.c | 19 +++++++++++++++----
2 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/lib/krb5.c b/lib/krb5.c
index 787137c..6f9e1f7 100644
--- a/lib/krb5.c
+++ b/lib/krb5.c
@@ -86,11 +86,8 @@ krb5_decode(void *app_data, void *buf, int len,
enc.value = buf;
enc.length = len;
maj = gss_unwrap(&min, *context, &enc, &dec, NULL, NULL);
- if(maj != GSS_S_COMPLETE) {
- if(len >= 4)
- strcpy(buf, "599 ");
+ if(maj != GSS_S_COMPLETE)
return -1;
- }
memcpy(buf, dec.value, dec.length);
len = curlx_uztosi(dec.length);
diff --git a/lib/security.c b/lib/security.c
index 52cce97..c95f290 100644
--- a/lib/security.c
+++ b/lib/security.c
@@ -64,6 +64,10 @@
/* The last #include file should be: */
#include "memdebug.h"
+/* Max string input length is a precaution against abuse and to detect junk
+ input easier and better. */
+#define CURL_MAX_INPUT_LENGTH 8000000
+
static const struct {
enum protection_level level;
const char *name;
@@ -192,6 +196,7 @@ static CURLcode read_data(struct connectdata *conn,
{
int len;
CURLcode result;
+ int nread;
result = socket_read(fd, &len, sizeof(len));
if(result)
@@ -200,7 +205,10 @@ static CURLcode read_data(struct connectdata *conn,
if(len) {
/* only realloc if there was a length */
len = ntohl(len);
- buf->data = Curl_saferealloc(buf->data, len);
+ if(len > CURL_MAX_INPUT_LENGTH)
+ len = 0;
+ else
+ buf->data = Curl_saferealloc(buf->data, len);
}
if(!len || !buf->data)
return CURLE_OUT_OF_MEMORY;
@@ -208,8 +216,11 @@ static CURLcode read_data(struct connectdata *conn,
result = socket_read(fd, buf->data, len);
if(result)
return result;
- buf->size = conn->mech->decode(conn->app_data, buf->data, len,
- conn->data_prot, conn);
+ nread = conn->mech->decode(conn->app_data, buf->data, len,
+ conn->data_prot, conn);
+ if(nread < 0)
+ return CURLE_RECV_ERROR;
+ buf->size = (size_t)nread;
buf->index = 0;
return CURLE_OK;
}
--
2.35.3

@ -0,0 +1,144 @@
From 24dedf9b260eebb7feae6fc273208b551fe54a79 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 16 May 2022 16:28:13 +0200
Subject: [PATCH 1/2] content_encoding: return error on too many compression
steps
The max allowed steps is arbitrarily set to 5.
Bug: https://curl.se/docs/CVE-2022-32206.html
CVE-2022-32206
Reported-by: Harry Sintonen
Closes #9049
Upstream-commit: 3a09fbb7f264c67c438d01a30669ce325aa508e2
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/content_encoding.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/lib/content_encoding.c b/lib/content_encoding.c
index c03637a..6f994b3 100644
--- a/lib/content_encoding.c
+++ b/lib/content_encoding.c
@@ -934,6 +934,9 @@ static const content_encoding *find_encoding(const char *name, size_t len)
return NULL;
}
+/* allow no more than 5 "chained" compression steps */
+#define MAX_ENCODE_STACK 5
+
/* Set-up the unencoding stack from the Content-Encoding header value.
* See RFC 7231 section 3.1.2.2. */
CURLcode Curl_build_unencoding_stack(struct connectdata *conn,
@@ -941,6 +944,7 @@ CURLcode Curl_build_unencoding_stack(struct connectdata *conn,
{
struct Curl_easy *data = conn->data;
struct SingleRequest *k = &data->req;
+ int counter = 0;
do {
const char *name;
@@ -975,6 +979,11 @@ CURLcode Curl_build_unencoding_stack(struct connectdata *conn,
if(!encoding)
encoding = &error_encoding; /* Defer error at stack use. */
+ if(++counter >= MAX_ENCODE_STACK) {
+ failf(data, "Reject response due to %u content encodings",
+ counter);
+ return CURLE_BAD_CONTENT_ENCODING;
+ }
/* Stack the unencoding stage. */
writer = new_unencoding_writer(conn, encoding, k->writer_stack);
if(!writer)
--
2.35.3
From b3cd74f01871281f0989860e04c546d896f0e72f Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 16 May 2022 16:29:07 +0200
Subject: [PATCH 2/2] test387: verify rejection of compression chain attack
Upstream-commit: 7230b19a2e17a164f61f82e4e409a9777ea2421a
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
tests/data/Makefile.inc | 1 +
tests/data/test387 | 53 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 54 insertions(+)
create mode 100644 tests/data/test387
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index 98d5516..9b5f4fb 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -61,6 +61,7 @@ test325 test326 test330 \
test340 \
\
test350 test351 test352 test353 test354 \
+test387 \
test393 test394 test395 \
\
test400 test401 test402 test403 test404 test405 test406 test407 test408 \
diff --git a/tests/data/test387 b/tests/data/test387
new file mode 100644
index 0000000..015ec25
--- /dev/null
+++ b/tests/data/test387
@@ -0,0 +1,53 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+gzip
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data nocheck="yes">
+HTTP/1.1 200 OK
+Transfer-Encoding: gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip
+
+-foo-
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+ <name>
+Response with overly long compression chain
+ </name>
+ <command>
+http://%HOSTIP:%HTTPPORT/%TESTNUMBER -sS
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/7.61.1
+Accept: */*
+
+</protocol>
+
+# CURLE_BAD_CONTENT_ENCODING is 61
+<errorcode>
+61
+</errorcode>
+<stderr mode="text">
+curl: (61) Reject response due to 5 content encodings
+</stderr>
+</verify>
+</testcase>
--
2.35.3

@ -0,0 +1,43 @@
From 9ea407a0476d22cde575826c18b5aa56b57ac9b4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Felix=20H=C3=A4dicke?= <felixhaedicke@web.de>
Date: Wed, 23 Jan 2019 23:10:39 +0100
Subject: [PATCH] setopt: enable CURLOPT_SSH_KNOWNHOSTS and
CURLOPT_SSH_KEYFUNCTION for libssh
CURLOPT_SSH_KNOWNHOSTS and CURLOPT_SSH_KEYFUNCTION are supported for
libssh as well. So accepting these options only when compiling with
libssh2 is wrong here.
Fixes #3493
Closes #3494
Upstream-commit: 3cbf731d9ec7146f9f1a6ac0fbd9af7fe358f5bb
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/setopt.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/lib/setopt.c b/lib/setopt.c
index b07ccfe..88a05ff 100644
--- a/lib/setopt.c
+++ b/lib/setopt.c
@@ -2208,7 +2208,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
result = Curl_setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5],
va_arg(param, char *));
break;
-#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+
case CURLOPT_SSH_KNOWNHOSTS:
/*
* Store the file name to read known hosts from.
@@ -2229,7 +2229,6 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
*/
data->set.ssh_keyfunc_userp = va_arg(param, void *);
break;
-#endif /* HAVE_LIBSSH2_KNOWNHOST_API */
#endif /* USE_LIBSSH2 */
case CURLOPT_HTTP_TRANSFER_DECODING:
--
2.34.1

@ -0,0 +1,112 @@
From 78b62ef1206621e8f4f1628ad4eb0a7be877c96f Mon Sep 17 00:00:00 2001
From: Johannes Schindelin <johannes.schindelin@gmx.de>
Date: Fri, 7 Dec 2018 17:04:39 +0100
Subject: [PATCH] Upon HTTP_1_1_REQUIRED, retry the request with HTTP/1.1
This is a companion patch to cbea2fd2c (NTLM: force the connection to
HTTP/1.1, 2018-12-06): with NTLM, we can switch to HTTP/1.1
preemptively. However, with other (Negotiate) authentication it is not
clear to this developer whether there is a way to make it work with
HTTP/2, so let's try HTTP/2 first and fall back in case we encounter the
error HTTP_1_1_REQUIRED.
Note: we will still keep the NTLM workaround, as it avoids an extra
round trip.
Daniel Stenberg helped a lot with this patch, in particular by
suggesting to introduce the Curl_h2_http_1_1_error() function.
Closes #3349
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Upstream-commit: d997aa0e963c5be5de100dccdc5208d39bd3d62b
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/http2.c | 8 ++++++++
lib/http2.h | 4 ++++
lib/multi.c | 20 ++++++++++++++++++++
3 files changed, 32 insertions(+)
diff --git a/lib/http2.c b/lib/http2.c
index d769193..3071097 100644
--- a/lib/http2.c
+++ b/lib/http2.c
@@ -2300,6 +2300,14 @@ void Curl_http2_cleanup_dependencies(struct Curl_easy *data)
Curl_http2_remove_child(data->set.stream_depends_on, data);
}
+/* Only call this function for a transfer that already got a HTTP/2
+ CURLE_HTTP2_STREAM error! */
+bool Curl_h2_http_1_1_error(struct connectdata *conn)
+{
+ struct http_conn *httpc = &conn->proto.httpc;
+ return (httpc->error_code == NGHTTP2_HTTP_1_1_REQUIRED);
+}
+
#else /* !USE_NGHTTP2 */
/* Satisfy external references even if http2 is not compiled in. */
diff --git a/lib/http2.h b/lib/http2.h
index 21cd9b8..91e504c 100644
--- a/lib/http2.h
+++ b/lib/http2.h
@@ -59,6 +59,9 @@ CURLcode Curl_http2_add_child(struct Curl_easy *parent,
void Curl_http2_remove_child(struct Curl_easy *parent,
struct Curl_easy *child);
void Curl_http2_cleanup_dependencies(struct Curl_easy *data);
+
+/* returns true if the HTTP/2 stream error was HTTP_1_1_REQUIRED */
+bool Curl_h2_http_1_1_error(struct connectdata *conn);
#else /* USE_NGHTTP2 */
#define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL
#define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL
@@ -74,6 +77,7 @@ void Curl_http2_cleanup_dependencies(struct Curl_easy *data);
#define Curl_http2_add_child(x, y, z)
#define Curl_http2_remove_child(x, y)
#define Curl_http2_cleanup_dependencies(x)
+#define Curl_h2_http_1_1_error(x) 0
#endif
#endif /* HEADER_CURL_HTTP2_H */
diff --git a/lib/multi.c b/lib/multi.c
index 0f57fd5..d64ba94 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -46,6 +46,7 @@
#include "vtls/vtls.h"
#include "connect.h"
#include "http_proxy.h"
+#include "http2.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
@@ -1943,6 +1944,25 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
done = TRUE;
}
}
+ else if((CURLE_HTTP2_STREAM == result) &&
+ Curl_h2_http_1_1_error(data->easy_conn)) {
+ CURLcode ret = Curl_retry_request(data->easy_conn, &newurl);
+
+ infof(data, "Forcing HTTP/1.1 for NTLM");
+ data->set.httpversion = CURL_HTTP_VERSION_1_1;
+
+ if(!ret)
+ retry = (newurl)?TRUE:FALSE;
+ else
+ result = ret;
+
+ if(retry) {
+ /* if we are to retry, set the result to OK and consider the
+ request as done */
+ result = CURLE_OK;
+ done = TRUE;
+ }
+ }
if(result) {
/*
--
2.37.3

@ -0,0 +1,81 @@
From 5cdcf1dbd39c64e18a81fc912a36942a3ec87565 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 19 Dec 2022 08:38:37 +0100
Subject: [PATCH] smb/telnet: do not free the protocol struct in *_done()
It is managed by the generic layer.
Reported-by: Trail of Bits
Closes #10112
Upstream-commit: 4f20188ac644afe174be6005ef4f6ffba232b8b2
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/smb.c | 14 ++------------
lib/telnet.c | 3 ---
2 files changed, 2 insertions(+), 15 deletions(-)
diff --git a/lib/smb.c b/lib/smb.c
index 039d680..f682c1f 100644
--- a/lib/smb.c
+++ b/lib/smb.c
@@ -61,8 +61,6 @@ static CURLcode smb_connect(struct connectdata *conn, bool *done);
static CURLcode smb_connection_state(struct connectdata *conn, bool *done);
static CURLcode smb_do(struct connectdata *conn, bool *done);
static CURLcode smb_request_state(struct connectdata *conn, bool *done);
-static CURLcode smb_done(struct connectdata *conn, CURLcode status,
- bool premature);
static CURLcode smb_disconnect(struct connectdata *conn, bool dead);
static int smb_getsock(struct connectdata *conn, curl_socket_t *socks,
int numsocks);
@@ -75,7 +73,7 @@ const struct Curl_handler Curl_handler_smb = {
"SMB", /* scheme */
smb_setup_connection, /* setup_connection */
smb_do, /* do_it */
- smb_done, /* done */
+ ZERO_NULL, /* done */
ZERO_NULL, /* do_more */
smb_connect, /* connect_it */
smb_connection_state, /* connecting */
@@ -100,7 +98,7 @@ const struct Curl_handler Curl_handler_smbs = {
"SMBS", /* scheme */
smb_setup_connection, /* setup_connection */
smb_do, /* do_it */
- smb_done, /* done */
+ ZERO_NULL, /* done */
ZERO_NULL, /* do_more */
smb_connect, /* connect_it */
smb_connection_state, /* connecting */
@@ -915,14 +913,6 @@ static CURLcode smb_request_state(struct connectdata *conn, bool *done)
return CURLE_OK;
}
-static CURLcode smb_done(struct connectdata *conn, CURLcode status,
- bool premature)
-{
- (void) premature;
- Curl_safefree(conn->data->req.protop);
- return status;
-}
-
static CURLcode smb_disconnect(struct connectdata *conn, bool dead)
{
struct smb_conn *smbc = &conn->proto.smbc;
diff --git a/lib/telnet.c b/lib/telnet.c
index 923c7f8..48cd0d7 100644
--- a/lib/telnet.c
+++ b/lib/telnet.c
@@ -1294,9 +1294,6 @@ static CURLcode telnet_done(struct connectdata *conn,
curl_slist_free_all(tn->telnet_vars);
tn->telnet_vars = NULL;
-
- Curl_safefree(conn->data->req.protop);
-
return CURLE_OK;
}
--
2.38.1

@ -0,0 +1,44 @@
From 4bbd1947aeb26d5dbcddbb058652e0e64771b71d Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 6 Feb 2023 17:46:36 +0100
Subject: [PATCH] h2: lower initial window size to 32 MiB
Cherry-picked from upstream commit
15f51474c837679c0b79825c23356ac681ffabde which was focused on paused
transfers but required an update of nghttp2 to work properly.
Bug: https://bugzilla.redhat.com/2166254
---
lib/http2.c | 2 +-
tests/data/test1800 | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/http2.c b/lib/http2.c
index 3071097..1fd2233 100644
--- a/lib/http2.c
+++ b/lib/http2.c
@@ -63,7 +63,7 @@
#define NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE 1
#endif
-#define HTTP2_HUGE_WINDOW_SIZE (1 << 30)
+#define HTTP2_HUGE_WINDOW_SIZE (32 * 1024 * 1024) /* 32 MB */
#ifdef DEBUG_HTTP2
#define H2BUGF(x) x
diff --git a/tests/data/test1800 b/tests/data/test1800
index 0110184..c308c99 100644
--- a/tests/data/test1800
+++ b/tests/data/test1800
@@ -48,7 +48,7 @@ Host: %HOSTIP:%HTTPPORT
Accept: */*
Connection: Upgrade, HTTP2-Settings
Upgrade: %H2CVER
-HTTP2-Settings: AAMAAABkAARAAAAAAAIAAAAA
+HTTP2-Settings: AAMAAABkAAQCAAAAAAIAAAAA
</protocol>
</verify>
--
2.39.1

@ -0,0 +1,331 @@
From 95f873ff983a1ae57415b3c16a881e74432cf8b8 Mon Sep 17 00:00:00 2001
From: Fabian Keil <fk@fabiankeil.de>
Date: Tue, 9 Feb 2021 14:04:32 +0100
Subject: [PATCH 1/2] runtests.pl: support the nonewline attribute for the data
part
Closes #8239
Upstream-commit: 736847611a40c01e7c290407e22e2f0f5f8efd6a
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
tests/runtests.pl | 7 +++++++
tests/server/getpart.c | 11 ++++++++++-
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/tests/runtests.pl b/tests/runtests.pl
index 40315aa..2e1500d 100755
--- a/tests/runtests.pl
+++ b/tests/runtests.pl
@@ -3817,6 +3817,13 @@ sub singletest {
else {
# check against the data section
@reply = getpart("reply", "data");
+ if(@reply) {
+ my %hash = getpartattr("reply", "data");
+ if($hash{'nonewline'}) {
+ # cut off the final newline from the final line of the data
+ chomp($reply[$#reply]);
+ }
+ }
# get the mode attribute
my $filemode=$replyattr{'mode'};
if($filemode && ($filemode eq "text") && $has_textaware) {
diff --git a/tests/server/getpart.c b/tests/server/getpart.c
index 32b55bc..f8fe3f6 100644
--- a/tests/server/getpart.c
+++ b/tests/server/getpart.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, 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
@@ -295,6 +295,7 @@ int getpart(char **outbuf, size_t *outlen,
size_t outalloc = 256;
int in_wanted_part = 0;
int base64 = 0;
+ int nonewline = 0;
int error;
enum {
@@ -360,6 +361,8 @@ int getpart(char **outbuf, size_t *outlen,
if(error)
return error;
}
+ if(nonewline)
+ (*outlen)--;
break;
}
}
@@ -377,6 +380,8 @@ int getpart(char **outbuf, size_t *outlen,
if(error)
return error;
}
+ if(nonewline)
+ (*outlen)--;
break;
}
}
@@ -451,6 +456,10 @@ int getpart(char **outbuf, size_t *outlen,
/* bit rough test, but "mostly" functional, */
/* treat wanted part data as base64 encoded */
base64 = 1;
+ if(strstr(patt, "nonewline=")) {
+ show(("* setting nonewline\n"));
+ nonewline = 1;
+ }
}
continue;
}
--
2.39.1
From bc5fc958b017895728962c9d44c469418cbec1a0 Mon Sep 17 00:00:00 2001
From: Patrick Monnerat <patrick@monnerat.net>
Date: Mon, 13 Feb 2023 08:33:09 +0100
Subject: [PATCH 2/2] content_encoding: do not reset stage counter for each
header
Test 418 verifies
Closes #10492
Upstream-commit: 119fb187192a9ea13dc90d9d20c215fc82799ab9
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/content_encoding.c | 7 +-
lib/urldata.h | 1 +
tests/data/Makefile.inc | 1 +
tests/data/test387 | 2 +-
tests/data/test418 | 152 ++++++++++++++++++++++++++++++++++++++++
5 files changed, 158 insertions(+), 5 deletions(-)
create mode 100644 tests/data/test418
diff --git a/lib/content_encoding.c b/lib/content_encoding.c
index bfc13e2..94344d6 100644
--- a/lib/content_encoding.c
+++ b/lib/content_encoding.c
@@ -944,7 +944,6 @@ CURLcode Curl_build_unencoding_stack(struct connectdata *conn,
{
struct Curl_easy *data = conn->data;
struct SingleRequest *k = &data->req;
- int counter = 0;
do {
const char *name;
@@ -979,9 +978,9 @@ CURLcode Curl_build_unencoding_stack(struct connectdata *conn,
if(!encoding)
encoding = &error_encoding; /* Defer error at stack use. */
- if(++counter >= MAX_ENCODE_STACK) {
- failf(data, "Reject response due to %u content encodings",
- counter);
+ if(k->writer_stack_depth++ >= MAX_ENCODE_STACK) {
+ failf(data, "Reject response due to more than %u content encodings",
+ MAX_ENCODE_STACK);
return CURLE_BAD_CONTENT_ENCODING;
}
/* Stack the unencoding stage. */
diff --git a/lib/urldata.h b/lib/urldata.h
index 5b4b34f..8c8c20b 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -539,6 +539,7 @@ struct SingleRequest {
struct curltime start; /* transfer started at this time */
struct curltime now; /* current time */
+ unsigned char writer_stack_depth; /* Unencoding stack depth. */
bool header; /* incoming data has HTTP header */
enum {
HEADER_NORMAL, /* no bad header at all */
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index fb51cd6..86b6f85 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -66,6 +66,7 @@ test393 test394 test395 \
\
test400 test401 test402 test403 test404 test405 test406 test407 test408 \
test409 \
+test418 \
\
test500 test501 test502 test503 test504 test505 test506 test507 test508 \
test509 test510 test511 test512 test513 test514 test515 test516 test517 \
diff --git a/tests/data/test387 b/tests/data/test387
index 015ec25..644fc7f 100644
--- a/tests/data/test387
+++ b/tests/data/test387
@@ -47,7 +47,7 @@ Accept: */*
61
</errorcode>
<stderr mode="text">
-curl: (61) Reject response due to 5 content encodings
+curl: (61) Reject response due to more than 5 content encodings
</stderr>
</verify>
</testcase>
diff --git a/tests/data/test418 b/tests/data/test418
new file mode 100644
index 0000000..50e974e
--- /dev/null
+++ b/tests/data/test418
@@ -0,0 +1,152 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+gzip
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data nocheck="yes">
+HTTP/1.1 200 OK
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+Transfer-Encoding: gzip
+
+-foo-
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+ <name>
+Response with multiple Transfer-Encoding headers
+ </name>
+ <command>
+http://%HOSTIP:%HTTPPORT/%TESTNUMBER -sS
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/7.61.1
+Accept: */*
+
+</protocol>
+
+# CURLE_BAD_CONTENT_ENCODING is 61
+<errorcode>
+61
+</errorcode>
+<stderr mode="text">
+curl: (61) Reject response due to more than 5 content encodings
+</stderr>
+</verify>
+</testcase>
--
2.39.1

@ -0,0 +1,231 @@
From e8705acd69383c13191c9dd4867d5118e58c54ba Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 6 Oct 2022 00:49:10 +0200
Subject: [PATCH 1/2] strcase: add Curl_timestrcmp
This is a strcmp() alternative function for comparing "secrets",
designed to take the same time no matter the content to not leak
match/non-match info to observers based on how fast it is.
The time this function takes is only a function of the shortest input
string.
Reported-by: Trail of Bits
Closes #9658
Upstream-commit: ed5095ed94281989e103c72e032200b83be37878
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/strcase.c | 22 ++++++++++++++++++++++
lib/strcase.h | 1 +
2 files changed, 23 insertions(+)
diff --git a/lib/strcase.c b/lib/strcase.c
index f932485..c73907d 100644
--- a/lib/strcase.c
+++ b/lib/strcase.c
@@ -175,6 +175,28 @@ bool Curl_safecmp(char *a, char *b)
return !a && !b;
}
+/*
+ * Curl_timestrcmp() returns 0 if the two strings are identical. The time this
+ * function spends is a function of the shortest string, not of the contents.
+ */
+int Curl_timestrcmp(const char *a, const char *b)
+{
+ int match = 0;
+ int i = 0;
+
+ if(a && b) {
+ while(1) {
+ match |= a[i]^b[i];
+ if(!a[i] || !b[i])
+ break;
+ i++;
+ }
+ }
+ else
+ return a || b;
+ return match;
+}
+
/* --- public functions --- */
int curl_strequal(const char *first, const char *second)
diff --git a/lib/strcase.h b/lib/strcase.h
index d245929..11a67a1 100644
--- a/lib/strcase.h
+++ b/lib/strcase.h
@@ -48,5 +48,6 @@ char Curl_raw_toupper(char in);
void Curl_strntoupper(char *dest, const char *src, size_t n);
bool Curl_safecmp(char *a, char *b);
+int Curl_timestrcmp(const char *first, const char *second);
#endif /* HEADER_CURL_STRCASE_H */
--
2.39.2
From 9cfaea212ff347937a38f6b5d6b885ed8ba1b931 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 9 Mar 2023 17:47:06 +0100
Subject: [PATCH 2/2] ftp: add more conditions for connection reuse
Reported-by: Harry Sintonen
Closes #10730
Upstream-commit: 8f4608468b890dce2dad9f91d5607ee7e9c1aba1
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/ftp.c | 28 ++++++++++++++++++++++++++--
lib/ftp.h | 5 +++++
lib/setopt.c | 2 +-
lib/url.c | 13 ++++++++++++-
lib/urldata.h | 4 ++--
5 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/lib/ftp.c b/lib/ftp.c
index 9442832..df15bc0 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -4080,6 +4080,8 @@ static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection)
}
freedirs(ftpc);
+ Curl_safefree(ftpc->account);
+ Curl_safefree(ftpc->alternative_to_user);
free(ftpc->prevpath);
ftpc->prevpath = NULL;
free(ftpc->server_os);
@@ -4391,11 +4393,31 @@ static CURLcode ftp_setup_connection(struct connectdata *conn)
struct Curl_easy *data = conn->data;
char *type;
struct FTP *ftp;
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
- conn->data->req.protop = ftp = malloc(sizeof(struct FTP));
+ ftp = calloc(sizeof(struct FTP), 1);
if(NULL == ftp)
return CURLE_OUT_OF_MEMORY;
+ /* clone connection related data that is FTP specific */
+ if(data->set.str[STRING_FTP_ACCOUNT]) {
+ ftpc->account = strdup(data->set.str[STRING_FTP_ACCOUNT]);
+ if(!ftpc->account) {
+ free(ftp);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ }
+ if(data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]) {
+ ftpc->alternative_to_user =
+ strdup(data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]);
+ if(!ftpc->alternative_to_user) {
+ Curl_safefree(ftpc->account);
+ free(ftp);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ }
+ data->req.protop = ftp;
+
data->state.path++; /* don't include the initial slash */
data->state.slash_removed = TRUE; /* we've skipped the slash */
@@ -4445,7 +4467,9 @@ static CURLcode ftp_setup_connection(struct connectdata *conn)
if(isBadFtpString(ftp->passwd))
return CURLE_URL_MALFORMAT;
- conn->proto.ftpc.known_filesize = -1; /* unknown size for now */
+ ftpc->known_filesize = -1; /* unknown size for now */
+ ftpc->use_ssl = data->set.use_ssl;
+ ftpc->ccc = data->set.ftp_ccc;
return CURLE_OK;
}
diff --git a/lib/ftp.h b/lib/ftp.h
index 7f6f432..3f33e27 100644
--- a/lib/ftp.h
+++ b/lib/ftp.h
@@ -117,6 +117,8 @@ struct FTP {
struct */
struct ftp_conn {
struct pingpong pp;
+ char *account;
+ char *alternative_to_user;
char *entrypath; /* the PWD reply when we logged on */
char **dirs; /* realloc()ed array for path components */
int dirdepth; /* number of entries used in the 'dirs' array */
@@ -144,6 +146,9 @@ struct ftp_conn {
ftpstate state; /* always use ftp.c:state() to change state! */
ftpstate state_saved; /* transfer type saved to be reloaded after
data connection is established */
+ unsigned char use_ssl; /* if AUTH TLS is to be attempted etc, for FTP or
+ IMAP or POP3 or others! (type: curl_usessl)*/
+ unsigned char ccc; /* ccc level for this connection */
curl_off_t retr_size_saved; /* Size of retrieved file saved */
char *server_os; /* The target server operating system. */
curl_off_t known_filesize; /* file size is different from -1, if wildcard
diff --git a/lib/setopt.c b/lib/setopt.c
index 3339a67..6fc111d 100644
--- a/lib/setopt.c
+++ b/lib/setopt.c
@@ -2039,7 +2039,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
arg = va_arg(param, long);
if((arg < CURLUSESSL_NONE) || (arg > CURLUSESSL_ALL))
return CURLE_BAD_FUNCTION_ARGUMENT;
- data->set.use_ssl = (curl_usessl)arg;
+ data->set.use_ssl = (unsigned char)arg;
break;
case CURLOPT_SSL_OPTIONS:
diff --git a/lib/url.c b/lib/url.c
index 61ba832..4e21838 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -1309,7 +1309,18 @@ ConnectionExists(struct Curl_easy *data,
if(!ssh_config_matches(needle, check))
continue;
}
-
+#ifndef CURL_DISABLE_FTP
+ if(needle->handler->protocol & (CURLPROTO_FTP|CURLPROTO_FTPS)) {
+ /* Also match ACCOUNT, ALTERNATIVE-TO-USER, USE_SSL and CCC options */
+ if(Curl_timestrcmp(needle->proto.ftpc.account,
+ check->proto.ftpc.account) ||
+ Curl_timestrcmp(needle->proto.ftpc.alternative_to_user,
+ check->proto.ftpc.alternative_to_user) ||
+ (needle->proto.ftpc.use_ssl != check->proto.ftpc.use_ssl) ||
+ (needle->proto.ftpc.ccc != check->proto.ftpc.ccc))
+ continue;
+ }
+#endif
if(!needle->bits.httpproxy || (needle->handler->flags&PROTOPT_SSL) ||
needle->bits.tunnel_proxy) {
/* The requested connection does not use a HTTP proxy or it uses SSL or
diff --git a/lib/urldata.h b/lib/urldata.h
index 9d9ca92..4e2f5b9 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1498,6 +1498,8 @@ struct UserDefined {
curl_write_callback fwrite_header; /* function that stores headers */
curl_write_callback fwrite_rtp; /* function that stores interleaved RTP */
curl_read_callback fread_func_set; /* function that reads the input */
+ unsigned char use_ssl; /* if AUTH TLS is to be attempted etc, for FTP or
+ IMAP or POP3 or others! (type: curl_usessl)*/
int is_fread_set; /* boolean, has read callback been set to non-NULL? */
int is_fwrite_set; /* boolean, has write callback been set to non-NULL? */
curl_progress_callback fprogress; /* OLD and deprecated progress callback */
@@ -1622,8 +1624,6 @@ struct UserDefined {
bool ftp_use_eprt; /* if EPRT is to be attempted or not */
bool ftp_use_pret; /* if PRET is to be used before PASV or not */
- curl_usessl use_ssl; /* if AUTH TLS is to be attempted etc, for FTP or
- IMAP or POP3 or others! */
curl_ftpauth ftpsslauth; /* what AUTH XXX to be attempted */
curl_ftpccc ftp_ccc; /* FTP CCC options */
bool no_signal; /* do not use any signal/alarm handler */
--
2.39.2

@ -0,0 +1,55 @@
From 9d6dd7bc1dea42ae8e710aeae714e2a2c290de61 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Fri, 10 Mar 2023 09:22:43 +0100
Subject: [PATCH] url: only reuse connections with same GSS delegation
Reported-by: Harry Sintonen
Closes #10731
Upstream-commit: cb49e67303dbafbab1cebf4086e3ec15b7d56ee5
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/url.c | 6 ++++++
lib/urldata.h | 2 ++
2 files changed, 8 insertions(+)
diff --git a/lib/url.c b/lib/url.c
index 3b11b7e..cbbc7f3 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -1305,6 +1305,11 @@ ConnectionExists(struct Curl_easy *data,
}
}
+ /* GSS delegation differences do not actually affect every connection
+ and auth method, but this check takes precaution before efficiency */
+ if(needle->gssapi_delegation != check->gssapi_delegation)
+ continue;
+
if(needle->handler->protocol & (CURLPROTO_SCP|CURLPROTO_SFTP)) {
if(!ssh_config_matches(needle, check))
continue;
@@ -1949,6 +1954,7 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
it may live on without (this specific) Curl_easy */
conn->fclosesocket = data->set.fclosesocket;
conn->closesocket_client = data->set.closesocket_client;
+ conn->gssapi_delegation = data->set.gssapi_delegation;
return conn;
error:
diff --git a/lib/urldata.h b/lib/urldata.h
index ce90304..9e16f26 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -856,6 +856,8 @@ struct connectdata {
int httpversion; /* the HTTP version*10 reported by the server */
int rtspversion; /* the RTSP version*10 reported by the server */
+ unsigned char gssapi_delegation; /* inherited from set.gssapi_delegation */
+
struct curltime now; /* "current" time */
struct curltime created; /* creation time */
curl_socket_t sock[2]; /* two sockets, the second is used for the data
--
2.39.2

@ -0,0 +1,34 @@
From cc52b2d89397ff26b01d791cd1c605cba741aaa4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Felix=20H=C3=A4dicke?= <felixhaedicke@web.de>
Date: Wed, 24 Jul 2019 11:47:51 +0200
Subject: [PATCH] ssh-libssh: do not specify O_APPEND when not in append mode
Specifying O_APPEND in conjunction with O_TRUNC and O_CREAT does not
make much sense. And this combination of flags is not accepted by all
SFTP servers (at least not Apache SSHD).
Fixes #4147
Closes #4148
Upstream-commit: 62617495102c60124db8a909f592f063e38a89aa
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/ssh-libssh.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/ssh-libssh.c b/lib/ssh-libssh.c
index 4110be2..2414173 100644
--- a/lib/ssh-libssh.c
+++ b/lib/ssh-libssh.c
@@ -1112,7 +1112,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
flags = O_WRONLY|O_APPEND;
else
/* Clear file before writing (normal behaviour) */
- flags = O_WRONLY|O_APPEND|O_CREAT|O_TRUNC;
+ flags = O_WRONLY|O_CREAT|O_TRUNC;
if(sshc->sftp_file)
sftp_close(sshc->sftp_file);
--
2.39.2

@ -0,0 +1,305 @@
From 199f2d440d8659b42670c1b796220792b01a97bf Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 24 Apr 2023 21:07:02 +0200
Subject: [PATCH] hostcheck: fix host name wildcard checking
The leftmost "label" of the host name can now only match against single
'*'. Like the browsers have worked for a long time.
- extended unit test 1397 for this
- move some SOURCE variables from unit/Makefile.am to unit/Makefile.inc
Reported-by: Hiroki Kurosawa
Closes #11018
---
lib/hostcheck.c | 50 +++++++--------
tests/data/test1397 | 10 ++-
tests/unit/Makefile.am | 94 ----------------------------
tests/unit/Makefile.inc | 94 ++++++++++++++++++++++++++++
tests/unit/unit1397.c | 134 ++++++++++++++++++++++++----------------
5 files changed, 202 insertions(+), 180 deletions(-)
diff --git a/lib/hostcheck.c b/lib/hostcheck.c
index e827dc58f378c..d061c6356f97f 100644
--- a/lib/hostcheck.c
+++ b/lib/hostcheck.c
@@ -43,6 +43,17 @@
/* The last #include file should be: */
#include "memdebug.h"
+/* check the two input strings with given length, but do not
+ assume they end in nul-bytes */
+static int pmatch(const char *hostname, size_t hostlen,
+ const char *pattern, size_t patternlen)
+{
+ if(hostlen != patternlen)
+ return CURL_HOST_NOMATCH;
+ return strncasecompare(hostname, pattern, hostlen) ?
+ CURL_HOST_MATCH : CURL_HOST_NOMATCH;
+}
+
/*
* Match a hostname against a wildcard pattern.
* E.g.
@@ -65,26 +76,27 @@
static int hostmatch(char *hostname, char *pattern)
{
- const char *pattern_label_end, *pattern_wildcard, *hostname_label_end;
- int wildcard_enabled;
- size_t prefixlen, suffixlen;
+ size_t hostlen, patternlen;
+ const char *pattern_label_end;
struct in_addr ignored;
#ifdef ENABLE_IPV6
struct sockaddr_in6 si6;
#endif
+ DEBUGASSERT(pattern);
+ DEBUGASSERT(hostname);
+
+ hostlen = strlen(hostname);
+ patternlen = strlen(pattern);
+
/* normalize pattern and hostname by stripping off trailing dots */
- size_t len = strlen(hostname);
- if(hostname[len-1]=='.')
- hostname[len-1] = 0;
- len = strlen(pattern);
- if(pattern[len-1]=='.')
- pattern[len-1] = 0;
-
- pattern_wildcard = strchr(pattern, '*');
- if(pattern_wildcard == NULL)
- return strcasecompare(pattern, hostname) ?
- CURL_HOST_MATCH : CURL_HOST_NOMATCH;
+ if(hostname[hostlen-1]=='.')
+ hostname[hostlen-1] = 0;
+ if(pattern[patternlen-1]=='.')
+ pattern[patternlen-1] = 0;
+
+ if(strncmp(pattern, "*.", 2))
+ return pmatch(hostname, hostlen, pattern, patternlen);
/* detect IP address as hostname and fail the match if so */
if(Curl_inet_pton(AF_INET, hostname, &ignored) > 0)
@@ -96,34 +108,20 @@ static int hostmatch(char *hostname, char *pattern)
/* We require at least 2 dots in pattern to avoid too wide wildcard
match. */
- wildcard_enabled = 1;
pattern_label_end = strchr(pattern, '.');
- if(pattern_label_end == NULL || strchr(pattern_label_end + 1, '.') == NULL ||
- pattern_wildcard > pattern_label_end ||
- strncasecompare(pattern, "xn--", 4)) {
- wildcard_enabled = 0;
+ if(pattern_label_end == NULL ||
+ (strrchr(pattern, '.') == pattern_label_end))
+ return pmatch(pattern, patternlen, hostname, hostlen);
+
+ const char *hostname_label_end = strchr(hostname, '.');
+ if(hostname_label_end != NULL) {
+ size_t skiphost = hostname_label_end - hostname;
+ size_t skiplen = pattern_label_end - pattern;
+ return pmatch(hostname_label_end, hostlen - skiphost,
+ pattern_label_end, patternlen - skiplen);
}
- if(!wildcard_enabled)
- return strcasecompare(pattern, hostname) ?
- CURL_HOST_MATCH : CURL_HOST_NOMATCH;
-
- hostname_label_end = strchr(hostname, '.');
- if(hostname_label_end == NULL ||
- !strcasecompare(pattern_label_end, hostname_label_end))
- return CURL_HOST_NOMATCH;
- /* The wildcard must match at least one character, so the left-most
- label of the hostname is at least as large as the left-most label
- of the pattern. */
- if(hostname_label_end - hostname < pattern_label_end - pattern)
- return CURL_HOST_NOMATCH;
-
- prefixlen = pattern_wildcard - pattern;
- suffixlen = pattern_label_end - (pattern_wildcard + 1);
- return strncasecompare(pattern, hostname, prefixlen) &&
- strncasecompare(pattern_wildcard + 1, hostname_label_end - suffixlen,
- suffixlen) ?
- CURL_HOST_MATCH : CURL_HOST_NOMATCH;
+ return CURL_HOST_NOMATCH;
}
int Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
diff --git a/tests/data/test1397 b/tests/data/test1397
index 84f962abebee3..f31b2c2a3f330 100644
--- a/tests/data/test1397
+++ b/tests/data/test1397
@@ -2,8 +2,7 @@
<info>
<keywords>
unittest
-ssl
-wildcard
+Curl_cert_hostcheck
</keywords>
</info>
@@ -15,10 +14,10 @@ none
<features>
unittest
</features>
- <name>
-Check wildcard certificate matching function Curl_cert_hostcheck
- </name>
+<name>
+Curl_cert_hostcheck unit tests
+</name>
<tool>
unit1397
</tool>
</client>
diff --git a/tests/unit/unit1397.c b/tests/unit/unit1397.c
index 2f3d3aa4d09e1..3ae75618d5d10 100644
--- a/tests/unit/unit1397.c
+++ b/tests/unit/unit1397.c
@@ -21,8 +21,6 @@
***************************************************************************/
#include "curlcheck.h"
-#include "hostcheck.h" /* from the lib dir */
-
static CURLcode unit_setup(void)
{
return CURLE_OK;
@@ -30,50 +28,93 @@ static CURLcode unit_setup(void)
static void unit_stop(void)
{
- /* done before shutting down and exiting */
}
-UNITTEST_START
-
/* only these backends define the tested functions */
-#if defined(USE_OPENSSL) || defined(USE_AXTLS) || defined(USE_GSKIT)
-
- /* here you start doing things and checking that the results are good */
+#if defined(USE_OPENSSL) || defined(USE_GSKIT) || defined(USE_SCHANNEL)
+#include "hostcheck.h"
+struct testcase {
+ const char *host;
+ const char *pattern;
+ bool match;
+};
-fail_unless(Curl_cert_hostcheck("www.example.com", "www.example.com"),
- "good 1");
-fail_unless(Curl_cert_hostcheck("*.example.com", "www.example.com"),
- "good 2");
-fail_unless(Curl_cert_hostcheck("xxx*.example.com", "xxxwww.example.com"),
- "good 3");
-fail_unless(Curl_cert_hostcheck("f*.example.com", "foo.example.com"),
- "good 4");
-fail_unless(Curl_cert_hostcheck("192.168.0.0", "192.168.0.0"),
- "good 5");
-
-fail_if(Curl_cert_hostcheck("xxx.example.com", "www.example.com"), "bad 1");
-fail_if(Curl_cert_hostcheck("*", "www.example.com"), "bad 2");
-fail_if(Curl_cert_hostcheck("*.*.com", "www.example.com"), "bad 3");
-fail_if(Curl_cert_hostcheck("*.example.com", "baa.foo.example.com"), "bad 4");
-fail_if(Curl_cert_hostcheck("f*.example.com", "baa.example.com"), "bad 5");
-fail_if(Curl_cert_hostcheck("*.com", "example.com"), "bad 6");
-fail_if(Curl_cert_hostcheck("*fail.com", "example.com"), "bad 7");
-fail_if(Curl_cert_hostcheck("*.example.", "www.example."), "bad 8");
-fail_if(Curl_cert_hostcheck("*.example.", "www.example"), "bad 9");
-fail_if(Curl_cert_hostcheck("", "www"), "bad 10");
-fail_if(Curl_cert_hostcheck("*", "www"), "bad 11");
-fail_if(Curl_cert_hostcheck("*.168.0.0", "192.168.0.0"), "bad 12");
-fail_if(Curl_cert_hostcheck("www.example.com", "192.168.0.0"), "bad 13");
-
-#ifdef ENABLE_IPV6
-fail_if(Curl_cert_hostcheck("*::3285:a9ff:fe46:b619",
- "fe80::3285:a9ff:fe46:b619"), "bad 14");
-fail_unless(Curl_cert_hostcheck("fe80::3285:a9ff:fe46:b619",
- "fe80::3285:a9ff:fe46:b619"), "good 6");
-#endif
+static struct testcase tests[] = {
+ {"", "", FALSE},
+ {"a", "", FALSE},
+ {"", "b", FALSE},
+ {"a", "b", FALSE},
+ {"aa", "bb", FALSE},
+ {"\xff", "\xff", TRUE},
+ {"aa.aa.aa", "aa.aa.bb", FALSE},
+ {"aa.aa.aa", "aa.aa.aa", TRUE},
+ {"aa.aa.aa", "*.aa.bb", FALSE},
+ {"aa.aa.aa", "*.aa.aa", TRUE},
+ {"192.168.0.1", "192.168.0.1", TRUE},
+ {"192.168.0.1", "*.168.0.1", FALSE},
+ {"192.168.0.1", "*.0.1", FALSE},
+ {"h.ello", "*.ello", FALSE},
+ {"h.ello.", "*.ello", FALSE},
+ {"h.ello", "*.ello.", FALSE},
+ {"h.e.llo", "*.e.llo", TRUE},
+ {"h.e.llo", " *.e.llo", FALSE},
+ {" h.e.llo", "*.e.llo", TRUE},
+ {"h.e.llo.", "*.e.llo", TRUE},
+ {"*.e.llo.", "*.e.llo", TRUE},
+ {"************.e.llo.", "*.e.llo", TRUE},
+ {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
+ "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
+ "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
+ "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
+ ".e.llo.", "*.e.llo", TRUE},
+ {"\xfe\xfe.e.llo.", "*.e.llo", TRUE},
+ {"h.e.llo.", "*.e.llo.", TRUE},
+ {"h.e.llo", "*.e.llo.", TRUE},
+ {".h.e.llo", "*.e.llo.", FALSE},
+ {"h.e.llo", "*.*.llo.", FALSE},
+ {"h.e.llo", "h.*.llo", FALSE},
+ {"h.e.llo", "h.e.*", FALSE},
+ {"hello", "*.ello", FALSE},
+ {"hello", "**llo", FALSE},
+ {"bar.foo.example.com", "*.example.com", FALSE},
+ {"foo.example.com", "*.example.com", TRUE},
+ {"baz.example.net", "b*z.example.net", FALSE},
+ {"foobaz.example.net", "*baz.example.net", FALSE},
+ {"xn--l8j.example.local", "x*.example.local", FALSE},
+ {"xn--l8j.example.net", "*.example.net", TRUE},
+ {"xn--l8j.example.net", "*j.example.net", FALSE},
+ {"xn--l8j.example.net", "xn--l8j.example.net", TRUE},
+ {"xn--l8j.example.net", "xn--l8j.*.net", FALSE},
+ {"xl8j.example.net", "*.example.net", TRUE},
+ {"fe80::3285:a9ff:fe46:b619", "*::3285:a9ff:fe46:b619", FALSE},
+ {"fe80::3285:a9ff:fe46:b619", "fe80::3285:a9ff:fe46:b619", TRUE},
+ {NULL, NULL, FALSE}
+};
-#endif
+UNITTEST_START
+{
+ int i;
+ for(i = 0; tests[i].host; i++) {
+ if(tests[i].match != Curl_cert_hostcheck(tests[i].pattern,
+ strlen(tests[i].pattern),
+ tests[i].host,
+ strlen(tests[i].host))) {
+ fprintf(stderr,
+ "HOST: %s\n"
+ "PTRN: %s\n"
+ "did %sMATCH\n",
+ tests[i].host,
+ tests[i].pattern,
+ tests[i].match ? "NOT ": "");
+ unitfail++;
+ }
+ }
+}
+UNITTEST_STOP
+#else
- /* you end the test code like this: */
+UNITTEST_START
UNITTEST_STOP
+#endif

File diff suppressed because it is too large Load Diff

@ -0,0 +1,169 @@
From be17dc9d31e805c03372b690dde67838b3bfc12d Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Wed, 24 May 2023 16:34:11 +0200
Subject: [PATCH] libssh: when keyboard-interactive auth fails, try password
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The state machine had a mistake in that it would not carry on to that
next step.
This also adds a verbose output what methods that are available from the
server and renames the macros that change to the next auth methods to
try.
Reported-by: 左潇峰
Fixes #11196
Closes #11197
---
lib/ssh-libssh.c | 43 +++++++++++++++++++++++++++----------------
1 file changed, 27 insertions(+), 16 deletions(-)
diff --git a/lib/ssh-libssh.c b/lib/ssh-libssh.c
index 7ebe61321419f..1cecb649cb623 100644
--- a/lib/ssh-libssh.c
+++ b/lib/ssh-libssh.c
@@ -442,7 +442,7 @@ static int myssh_is_known(struct Curl_easy *data)
break; \
}
-#define MOVE_TO_LAST_AUTH \
+#define MOVE_TO_PASSWD_AUTH \
if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { \
rc = SSH_OK; \
state(conn, SSH_AUTH_PASS_INIT); \
@@ -452,25 +452,25 @@ static int myssh_is_known(struct Curl_easy *data)
MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); \
}
-#define MOVE_TO_TERTIARY_AUTH \
+#define MOVE_TO_KEY_AUTH \
if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { \
rc = SSH_OK; \
state(conn, SSH_AUTH_KEY_INIT); \
break; \
} \
else { \
- MOVE_TO_LAST_AUTH; \
+ MOVE_TO_PASSWD_AUTH; \
}
-#define MOVE_TO_SECONDARY_AUTH \
+#define MOVE_TO_GSSAPI_AUTH \
if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { \
rc = SSH_OK; \
state(conn, SSH_AUTH_GSSAPI); \
break; \
} \
else { \
- MOVE_TO_TERTIARY_AUTH; \
+ MOVE_TO_KEY_AUTH; \
}
static
int myssh_auth_interactive(struct connectdata *conn)
@@ -617,6 +617,16 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
}
sshc->auth_methods = ssh_userauth_list(sshc->ssh_session, NULL);
+ if(sshc->auth_methods)
+ infof(data, "SSH authentication methods available: %s%s%s%s",
+ sshc->auth_methods & SSH_AUTH_METHOD_PUBLICKEY ?
+ "public key, ": "",
+ sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC ?
+ "GSSAPI, " : "",
+ sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE ?
+ "keyboard-interactive, " : "",
+ sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD ?
+ "password": "");
if(sshc->auth_methods & SSH_AUTH_METHOD_PUBLICKEY) {
state(conn, SSH_AUTH_PKEY_INIT);
infof(data, "Authentication using SSH public key file\n");
@@ -761,8 +761,8 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
}
case SSH_AUTH_PKEY_INIT:
if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY)) {
- MOVE_TO_SECONDARY_AUTH;
+ MOVE_TO_GSSAPI_AUTH;
}
/* Two choices, (1) private key was given on CMD,
* (2) use the "default" keys. */
@@ -776,7 +776,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
}
if(rc != SSH_OK) {
- MOVE_TO_SECONDARY_AUTH;
+ MOVE_TO_GSSAPI_AUTH;
}
}
@@ -826,7 +836,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
break;
}
- MOVE_TO_SECONDARY_AUTH;
+ MOVE_TO_GSSAPI_AUTH;
}
break;
case SSH_AUTH_PKEY:
@@ -828,13 +828,13 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
}
else {
infof(data, "Failed public key authentication (rc: %d)\n", rc);
- MOVE_TO_SECONDARY_AUTH;
+ MOVE_TO_GSSAPI_AUTH;
}
break;
case SSH_AUTH_GSSAPI:
if(!(data->set.ssh_auth_types & CURLSSH_AUTH_GSSAPI)) {
- MOVE_TO_TERTIARY_AUTH;
+ MOVE_TO_KEY_AUTH;
}
rc = ssh_userauth_gssapi(sshc->ssh_session);
@@ -851,7 +851,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
break;
}
- MOVE_TO_TERTIARY_AUTH;
+ MOVE_TO_KEY_AUTH;
break;
case SSH_AUTH_KEY_INIT:
@@ -736,13 +736,12 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
state(conn, SSH_AUTH_KEY);
}
else {
- MOVE_TO_LAST_AUTH;
+ MOVE_TO_PASSWD_AUTH;
}
break;
case SSH_AUTH_KEY:
-
- /* Authentication failed. Continue with keyboard-interactive now. */
+ /* keyboard-interactive authentication */
rc = myssh_auth_interactive(conn);
if(rc == SSH_AGAIN) {
break;
@@ -759,13 +759,15 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
if(rc == SSH_OK) {
sshc->authed = TRUE;
infof(data, "completed keyboard interactive authentication\n");
+ state(data, SSH_AUTH_DONE);
+ }
+ else {
+ MOVE_TO_PASSWD_AUTH;
}
- state(conn, SSH_AUTH_DONE);
break;
case SSH_AUTH_PASS_INIT:
if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD)) {
- /* Host key authentication is intentionally not implemented */
MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
}
state(conn, SSH_AUTH_PASS);

@ -0,0 +1,31 @@
From 35eb2614d86316ba9f5a6806ce64f56680fa1e97 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Tue, 5 Sep 2023 17:33:41 +0200
Subject: [PATCH] libssh: cap SFTP packet size sent
Due to libssh limitations
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Closes #11804
---
lib/ssh-libssh.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/lib/ssh-libssh.c b/lib/ssh-libssh.c
index dea0084575859..7c6a2e53f338f 100644
--- a/lib/ssh-libssh.c
+++ b/lib/ssh-libssh.c
@@ -2412,6 +2412,12 @@ static ssize_t sftp_send(struct Curl_easy *data, int sockindex,
ssize_t nwrite;
(void)sockindex;
+ /* limit the writes to the maximum specified in Section 3 of
+ * https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02
+ */
+ if(len > 32768)
+ len = 32768;
+
nwrite = sftp_write(conn->proto.sshc.sftp_file, mem, len);
myssh_block2waitfor(conn, FALSE);

@ -0,0 +1,388 @@
From 47f0d37bfc008c088416f3dcca802c9e087d9bf1 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Tue, 25 Apr 2023 08:28:01 +0200
Subject: [PATCH] lib: unify the upload/method handling
By making sure we set state.upload based on the set.method value and not
independently as set.upload, we reduce confusion and mixup risks, both
internally and externally.
---
lib/curl_rtmp.c | 4 ++--
lib/file.c | 4 ++--
lib/ftp.c | 8 ++++----
lib/http.c | 4 ++--
lib/imap.c | 6 +++---
lib/rtsp.c | 4 ++--
lib/setopt.c | 6 ++----
lib/smb.c | 6 +++---
lib/smtp.c | 4 ++--
lib/tftp.c | 8 ++++----
lib/transfer.c | 4 ++--
lib/urldata.h | 2 +-
lib/ssh-libssh.c | 6 +++---
lib/ssh.c | 6 +++---
14 files changed, 36 insertions(+), 38 deletions(-)
diff --git a/lib/curl_rtmp.c b/lib/curl_rtmp.c
index 2679a2cdc1afe..406fb42ac0f44 100644
--- a/lib/curl_rtmp.c
+++ b/lib/curl_rtmp.c
@@ -231,7 +231,7 @@ static CURLcode rtmp_connect(struct Curl_easy *data, bool *done)
/* We have to know if it's a write before we send the
* connect request packet
*/
- if(conn->data->set.upload)
+ if(conn->data->state.upload)
r->Link.protocol |= RTMP_FEATURE_WRITE;
/* For plain streams, use the buffer toggle trick to keep data flowing */
@@ -263,7 +263,7 @@ static CURLcode rtmp_do(struct Curl_easy *data, bool *done)
if(!RTMP_ConnectStream(r, 0))
return CURLE_FAILED_INIT;
- if(conn->data->set.upload) {
+ if(conn->data->state.upload) {
Curl_pgrsSetUploadSize(conn->data, conn->data->state.infilesize);
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
}
diff --git a/lib/file.c b/lib/file.c
index 51c5d07ce40ab..c751e8861a99b 100644
--- a/lib/file.c
+++ b/lib/file.c
@@ -240,7 +240,7 @@ static CURLcode file_connect(struct Curl_easy *data, bool *done)
file->freepath = real_path; /* free this when done */
file->fd = fd;
- if(!data->set.upload && (fd == -1)) {
+ if(!data->state.upload && (fd == -1)) {
failf(data, "Couldn't open file %s", data->state.path);
file_done(conn, CURLE_FILE_COULDNT_READ_FILE, FALSE);
return CURLE_FILE_COULDNT_READ_FILE;
@@ -422,7 +422,7 @@ static CURLcode file_do(struct Curl_easy *data, bool *done)
Curl_pgrsStartNow(data);
- if(data->set.upload)
+ if(data->state.upload)
return file_upload(conn);
file = conn->data->req.protop;
diff --git a/lib/ftp.c b/lib/ftp.c
index f50d7baf622f8..4ff68cc454cbc 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -1381,7 +1381,7 @@ static CURLcode ftp_state_prepare_transfer(struct Curl_easy *data)
data->set.str[STRING_CUSTOMREQUEST]:
(data->set.ftp_list_only?"NLST":"LIST"));
}
- else if(data->set.upload) {
+ else if(data->state.upload) {
PPSENDF(&conn->proto.ftpc.pp, "PRET STOR %s", conn->proto.ftpc.file);
}
else {
@@ -3368,7 +3368,7 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status,
/* the response code from the transfer showed an error already so no
use checking further */
;
- else if(data->set.upload) {
+ else if(data->state.upload) {
if((-1 != data->state.infilesize) &&
(data->state.infilesize != *ftp->bytecountp) &&
!data->set.crlf &&
@@ -3640,7 +3640,7 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep)
connected back to us */
}
}
- else if(data->set.upload) {
+ else if(data->state.upload) {
result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_STOR_TYPE);
if(result)
return result;
@@ -4217,7 +4217,7 @@ CURLcode ftp_parse_url_path(struct Curl_easy *data)
ftpc->file = NULL; /* instead of point to a zero byte, we make it a NULL
pointer */
- if(data->set.upload && !ftpc->file && (ftp->transfer == FTPTRANSFER_BODY)) {
+ if(data->state.upload && !ftpc->file && (ftp->transfer == FTPTRANSFER_BODY)) {
/* We need a file name when uploading. Return error! */
failf(data, "Uploading to a URL without a file name!");
return CURLE_URL_MALFORMAT;
diff --git a/lib/http.c b/lib/http.c
index 80e43f6f361e8..bffdd3468536d 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -2112,7 +2112,7 @@ void Curl_http_method(struct Curl_easy *data, struct connectdata *conn,
http->writebytecount = http->readbytecount = 0;
if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) &&
- data->set.upload) {
+ data->state.upload) {
httpreq = HTTPREQ_PUT;
}
@@ -2423,7 +2423,7 @@ CURLcode Curl_http_body(struct Curl_easy *data, struct connectdata *conn,
if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
(((httpreq == HTTPREQ_POST_MIME || httpreq == HTTPREQ_POST_FORM) &&
http->postsize < 0) ||
- (data->set.upload && data->state.infilesize == -1))) {
+ (data->state.upload && data->state.infilesize == -1))) {
if(conn->bits.authneg)
/* don't enable chunked during auth neg */
;
diff --git a/lib/imap.c b/lib/imap.c
index c2f675d4b2618..1952e66a1efcd 100644
--- a/lib/imap.c
+++ b/lib/imap.c
@@ -1511,10 +1511,10 @@ static CURLcode imap_done(struct Curl_easy *data, CURLcode status,
result = status; /* use the already set error code */
}
else if(!data->set.connect_only && !imap->custom &&
- (imap->uid || data->set.upload ||
+ (imap->uid || data->state.upload ||
data->set.mimepost.kind != MIMEKIND_NONE)) {
/* Handle responses after FETCH or APPEND transfer has finished */
- if(!data->set.upload && data->set.mimepost.kind == MIMEKIND_NONE)
+ if(!data->state.upload && data->set.mimepost.kind == MIMEKIND_NONE)
state(conn, IMAP_FETCH_FINAL);
else {
/* End the APPEND command first by sending an empty line */
@@ -1581,7 +1581,7 @@ static CURLcode imap_perform(struct Curl_easy *data, bool *connected,
selected = TRUE;
/* Start the first command in the DO phase */
- if(conn->data->set.upload || data->set.mimepost.kind != MIMEKIND_NONE)
+ if(conn->data->state.upload || data->set.mimepost.kind != MIMEKIND_NONE)
/* APPEND can be executed directly */
result = imap_perform_append(conn);
else if(imap->custom && (selected || !imap->mailbox))
index ea99d720ec4eb..ccd7264b00e74 100644
--- a/lib/rtsp.c
+++ b/lib/rtsp.c
@@ -493,7 +493,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
rtspreq == RTSPREQ_SET_PARAMETER ||
rtspreq == RTSPREQ_GET_PARAMETER) {
- if(data->set.upload) {
+ if(data->state.upload) {
putsize = data->state.infilesize;
data->set.httpreq = HTTPREQ_PUT;
@@ -512,7 +512,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
if(!Curl_checkheaders(conn, "Content-Length")) {
result = Curl_add_bufferf(req_buffer,
"Content-Length: %" CURL_FORMAT_CURL_OFF_T"\r\n",
- (data->set.upload ? putsize : postsize));
+ (data->state.upload ? putsize : postsize));
if(result)
return result;
}
diff --git a/lib/setopt.c b/lib/setopt.c
index 38f5711e44191..0c3b9634d1192 100644
--- a/lib/setopt.c
+++ b/lib/setopt.c
@@ -333,8 +333,8 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
* We want to sent data to the remote host. If this is HTTP, that equals
* using the PUT request.
*/
- data->set.upload = (0 != va_arg(param, long)) ? TRUE : FALSE;
- if(data->set.upload) {
+ arg = va_arg(param, long);
+ if(arg) {
/* If this is HTTP, PUT is what's needed to "upload" */
data->set.httpreq = HTTPREQ_PUT;
data->set.opt_no_body = FALSE; /* this is implied */
@@ -888,7 +887,6 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
*/
if(va_arg(param, long)) {
data->set.httpreq = HTTPREQ_GET;
- data->set.upload = FALSE; /* switch off upload */
data->set.opt_no_body = FALSE; /* this is implied */
}
break;
diff --git a/lib/smb.c b/lib/smb.c
index a1e444ee6b97e..d6822213529bc 100644
--- a/lib/smb.c
+++ b/lib/smb.c
@@ -530,7 +530,7 @@ static CURLcode smb_send_open(struct Curl_easy *data)
byte_count = strlen(req->path);
msg.name_length = smb_swap16((unsigned short)byte_count);
msg.share_access = smb_swap32(SMB_FILE_SHARE_ALL);
- if(conn->data->set.upload) {
+ if(conn->data->state.upload) {
msg.access = smb_swap32(SMB_GENERIC_READ | SMB_GENERIC_WRITE);
msg.create_disposition = smb_swap32(SMB_FILE_OVERWRITE_IF);
}
@@ -813,7 +813,7 @@ static CURLcode smb_request_state(struct Curl_easy *data, bool *done)
smb_m = (const struct smb_nt_create_response*) msg;
req->fid = smb_swap16(smb_m->fid);
conn->data->req.offset = 0;
- if(conn->data->set.upload) {
+ if(conn->data->state.upload) {
conn->data->req.size = conn->data->state.infilesize;
Curl_pgrsSetUploadSize(conn->data, conn->data->req.size);
next_state = SMB_UPLOAD;
diff --git a/lib/smtp.c b/lib/smtp.c
index 7a030308d4689..c182cace742d7 100644
--- a/lib/smtp.c
+++ b/lib/smtp.c
@@ -1419,7 +1419,7 @@ static CURLcode smtp_done(struct Curl_easy *data, CURLcode status,
result = status; /* use the already set error code */
}
else if(!data->set.connect_only && data->set.mail_rcpt &&
- (data->set.upload || data->set.mimepost.kind)) {
+ (data->state.upload || data->set.mimepost.kind)) {
/* Calculate the EOB taking into account any terminating CRLF from the
previous line of the email or the CRLF of the DATA command when there
is "no mail data". RFC-5321, sect. 4.1.1.4.
@@ -1511,7 +1511,7 @@ static CURLcode smtp_perform(struct Curl_easy *data, bool *connected,
smtp->eob = 2;
/* Start the first command in the DO phase */
- if((data->set.upload || data->set.mimepost.kind) && data->set.mail_rcpt)
+ if((data->state.upload || data->set.mimepost.kind) && data->set.mail_rcpt)
/* MAIL transfer */
result = smtp_perform_mail(conn);
else
diff --git a/lib/tftp.c b/lib/tftp.c
index 164d3c723c5b9..8ed1b887b4d21 100644
--- a/lib/tftp.c
+++ b/lib/tftp.c
@@ -370,7 +370,7 @@ static CURLcode tftp_parse_option_ack(struct tftp_state_data *state,
/* tsize should be ignored on upload: Who cares about the size of the
remote file? */
- if(!data->set.upload) {
+ if(!data->state.upload) {
if(!tsize) {
failf(data, "invalid tsize -:%s:- value in OACK packet", value);
return CURLE_TFTP_ILLEGAL;
@@ -451,7 +451,7 @@ static CURLcode tftp_send_first(struct tftp_state_data *state,
return result;
}
- if(data->set.upload) {
+ if(data->state.upload) {
/* If we are uploading, send an WRQ */
setpacketevent(&state->spacket, TFTP_EVENT_WRQ);
state->conn->data->req.upload_fromhere =
@@ -486,7 +486,7 @@ static CURLcode tftp_send_first(struct tftp_state_data *state,
if(!data->set.tftp_no_options) {
char buf[64];
/* add tsize option */
- if(data->set.upload && (data->state.infilesize != -1))
+ if(data->state.upload && (data->state.infilesize != -1))
snprintf(buf, sizeof(buf), "%" CURL_FORMAT_CURL_OFF_T,
data->state.infilesize);
else
@@ -540,7 +540,7 @@ static CURLcode tftp_send_first(struct tftp_state_data *state,
break;
case TFTP_EVENT_OACK:
- if(data->set.upload) {
+ if(data->state.upload) {
result = tftp_connect_for_tx(state, event);
}
else {
diff --git a/lib/transfer.c b/lib/transfer.c
index e9ab8fbf09510..cb69f3365855a 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -1293,6 +1293,7 @@ void Curl_init_CONNECT(struct Curl_easy *data)
{
data->state.fread_func = data->set.fread_func_set;
data->state.in = data->set.in_set;
+ data->state.upload = (data->set.httpreq == HTTPREQ_PUT);
}
/*
@@ -1770,7 +1770,7 @@ CURLcode Curl_retry_request(struct Curl_easy *data, char **url)
/* if we're talking upload, we can't do the checks below, unless the protocol
is HTTP as when uploading over HTTP we will still get a response */
- if(data->set.upload &&
+ if(data->state.upload &&
!(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)))
return CURLE_OK;
diff --git a/lib/urldata.h b/lib/urldata.h
index cca992a0295aa..a8580bdb66fe8 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1494,6 +1494,7 @@ struct UrlState {
#ifdef CURLDEBUG
bool conncache_lock;
#endif
+ bool upload; /* upload request */
};
@@ -1838,7 +1839,6 @@ struct UserDefined {
bool http_set_referer; /* is a custom referer used */
bool http_auto_referer; /* set "correct" referer when following location: */
bool opt_no_body; /* as set with CURLOPT_NOBODY */
- bool upload; /* upload request */
enum CURL_NETRC_OPTION
use_netrc; /* defined in include/curl.h */
bool verbose; /* output verbosity */
diff --git a/lib/ssh-libssh.c b/lib/ssh-libssh.c
index b31f741ba9492..d60edaa303642 100644
--- a/lib/ssh-libssh.c
+++ b/lib/ssh-libssh.c
@@ -1209,7 +1209,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
}
case SSH_SFTP_TRANS_INIT:
- if(data->set.upload)
+ if(data->state.upload)
state(conn, SSH_SFTP_UPLOAD_INIT);
else {
if(protop->path[strlen(protop->path)-1] == '/')
@@ -1802,7 +1802,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
/* Functions from the SCP subsystem cannot handle/return SSH_AGAIN */
ssh_set_blocking(sshc->ssh_session, 1);
- if(data->set.upload) {
+ if(data->state.upload) {
if(data->state.infilesize < 0) {
failf(data, "SCP requires a known file size for upload");
sshc->actualcode = CURLE_UPLOAD_FAILED;
@@ -1907,7 +1907,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
break;
}
case SSH_SCP_DONE:
- if(data->set.upload)
+ if(data->state.upload)
state(conn, SSH_SCP_SEND_EOF);
else
state(conn, SSH_SCP_CHANNEL_FREE);
diff --git a/lib/ssh.c b/lib/ssh.c
index f1154dc47a74e..f2e5352d1fd3a 100644
--- a/lib/ssh.c
+++ b/lib/ssh.c
@@ -2019,7 +2019,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
}
case SSH_SFTP_TRANS_INIT:
- if(data->set.upload)
+ if(data->state.upload)
state(conn, SSH_SFTP_UPLOAD_INIT);
else {
if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
@@ -2691,7 +2691,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
break;
}
- if(data->set.upload) {
+ if(data->state.upload) {
if(data->state.infilesize < 0) {
failf(data, "SCP requires a known file size for upload");
sshc->actualcode = CURLE_UPLOAD_FAILED;
@@ -2831,7 +2831,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
break;
case SSH_SCP_DONE:
- if(data->set.upload)
+ if(data->state.upload)
state(conn, SSH_SCP_SEND_EOF);
else
state(conn, SSH_SCP_CHANNEL_FREE);

@ -0,0 +1,124 @@
From 61275672b46d9abb3285740467b882e22ed75da8 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 14 Sep 2023 23:28:32 +0200
Subject: [PATCH] cookie: remove unnecessary struct fields
Plus: reduce the hash table size from 256 to 63. It seems unlikely to
make much of a speed difference for most use cases but saves 1.5KB of
data per instance.
Closes #11862
---
lib/cookie.c | 13 +------------
lib/cookie.h | 13 ++++---------
lib/easy.c | 4 +---
3 files changed, 6 insertions(+), 24 deletions(-)
diff --git a/lib/cookie.c b/lib/cookie.c
index 4345a84c6fd9d..e39c89a94a960 100644
--- a/lib/cookie.c
+++ b/lib/cookie.c
@@ -119,7 +119,6 @@ static void freecookie(struct Cookie *co)
free(co->name);
free(co->value);
free(co->maxage);
- free(co->version);
free(co);
}
@@ -717,11 +716,7 @@ Curl_cookie_add(struct Curl_easy *data,
}
}
else if(strcasecompare("version", name)) {
- strstore(&co->version, whatptr);
- if(!co->version) {
- badcookie = TRUE;
- break;
- }
+ /* just ignore */
}
else if(strcasecompare("max-age", name)) {
/* Defined in RFC2109:
@@ -1159,7 +1154,6 @@ Curl_cookie_add(struct Curl_easy *data,
free(clist->path);
free(clist->spath);
free(clist->expirestr);
- free(clist->version);
free(clist->maxage);
*clist = *co; /* then store all the new data */
@@ -1223,9 +1217,6 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
c = calloc(1, sizeof(struct CookieInfo));
if(!c)
return NULL; /* failed to get memory */
- c->filename = strdup(file?file:"none"); /* copy the name just in case */
- if(!c->filename)
- goto fail; /* failed to get memory */
}
else {
/* we got an already existing one, use that */
@@ -1378,7 +1369,6 @@ static struct Cookie *dup_cookie(struct Cookie *src)
CLONE(name);
CLONE(value);
CLONE(maxage);
- CLONE(version);
d->expires = src->expires;
d->tailmatch = src->tailmatch;
d->secure = src->secure;
@@ -1595,7 +1585,6 @@ void Curl_cookie_cleanup(struct CookieInfo *c)
{
if(c) {
unsigned int i;
- free(c->filename);
for(i = 0; i < COOKIE_HASH_SIZE; i++)
Curl_cookie_freelist(c->cookies[i]);
free(c); /* free the base struct as well */
diff --git a/lib/cookie.h b/lib/cookie.h
index b3c0063b2cfb2..41e9e7a6914e0 100644
--- a/lib/cookie.h
+++ b/lib/cookie.h
@@ -36,11 +36,7 @@ struct Cookie {
curl_off_t expires; /* expires = <this> */
char *expirestr; /* the plain text version */
bool tailmatch; /* whether we do tail-matching of the domain name */
-
- /* RFC 2109 keywords. Version=1 means 2109-compliant cookie sending */
- char *version; /* Version = <value> */
char *maxage; /* Max-Age = <value> */
-
bool secure; /* whether the 'secure' keyword was used */
bool livecookie; /* updated from a server, not a stored file */
bool httponly; /* true if the httponly directive is present */
@@ -56,15 +52,14 @@ struct Cookie {
int creationtime; /* time when the cookie was written */
};
-#define COOKIE_HASH_SIZE 256
+#define COOKIE_HASH_SIZE 63
struct CookieInfo {
/* linked list of cookies we know of */
struct Cookie *cookies[COOKIE_HASH_SIZE];
- char *filename; /* file we read from/write to */
bool running; /* state info, for cookie adding information */
- long numcookies; /* number of cookies in the "jar" */
+ int numcookies; /* number of cookies in the "jar" */
bool newsession; /* new session, discard session cookies on load */
int lastct; /* last creation-time used in the jar */
};
diff --git a/lib/easy.c b/lib/easy.c
index 16bbd35251d40..03195481f9780 100644
--- a/lib/easy.c
+++ b/lib/easy.c
@@ -925,9 +925,7 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
if(data->cookies) {
/* If cookies are enabled in the parent handle, we enable them
in the clone as well! */
- outcurl->cookies = Curl_cookie_init(data,
- data->cookies->filename,
- outcurl->cookies,
+ outcurl->cookies = Curl_cookie_init(data, NULL, outcurl->cookies,
data->set.cookiesession);
if(!outcurl->cookies)
goto fail;

@ -0,0 +1,193 @@
diff -up curl-7.61.1/lib/http2.c.25a25f45 curl-7.61.1/lib/http2.c
--- curl-7.61.1/lib/http2.c.25a25f45 2023-08-07 14:03:42.043463284 +0200
+++ curl-7.61.1/lib/http2.c 2023-08-07 14:10:24.769489855 +0200
@@ -1202,7 +1202,7 @@ CURLcode Curl_http2_request_upgrade(Curl
binlen = nghttp2_pack_settings_payload(binsettings, H2_BINSETTINGS_LEN,
httpc->local_settings,
httpc->local_settings_num);
- if(!binlen) {
+ if(binlen <= 0) {
failf(conn->data, "nghttp2 unexpectedly failed on pack_settings_payload");
Curl_add_buffer_free(req);
return CURLE_FAILED_INIT;
@@ -1285,6 +1285,14 @@ static int h2_process_pending_input(stru
return -1;
}
+ if(nghttp2_session_check_request_allowed(httpc->h2) == 0) {
+ /* No more requests are allowed in the current session, so
+ the connection may not be reused. This is set when a
+ GOAWAY frame has been received or when the limit of stream
+ identifiers has been reached. */
+ connclose(conn, "http/2: No new requests allowed");
+ }
+
if(should_close_session(httpc)) {
H2BUGF(infof(data,
"h2_process_pending_input: nothing to do in this session\n"));
@@ -1297,7 +1305,6 @@ static int h2_process_pending_input(stru
}
return -1;
}
-
return 0;
}
@@ -1455,8 +1462,6 @@ static int h2_session_send(struct Curl_e
static ssize_t http2_recv(struct connectdata *conn, int sockindex,
char *mem, size_t len, CURLcode *err)
{
- CURLcode result = CURLE_OK;
- ssize_t rv;
ssize_t nread;
struct http_conn *httpc = &conn->proto.httpc;
struct Curl_easy *data = conn->data;
@@ -1519,8 +1524,7 @@ static ssize_t http2_recv(struct connect
/* We have paused nghttp2, but we have no pause data (see
on_data_chunk_recv). */
httpc->pause_stream_id = 0;
- if(h2_process_pending_input(conn, httpc, &result) != 0) {
- *err = result;
+ if(h2_process_pending_input(conn, httpc, err) != 0) {
return -1;
}
}
@@ -1549,8 +1553,7 @@ static ssize_t http2_recv(struct connect
frames, then we have to call it again with 0-length data.
Without this, on_stream_close callback will not be called,
and stream could be hanged. */
- if(h2_process_pending_input(conn, httpc, &result) != 0) {
- *err = result;
+ if(h2_process_pending_input(conn, httpc, err) != 0) {
return -1;
}
}
@@ -1573,7 +1576,6 @@ static ssize_t http2_recv(struct connect
return -1;
}
else {
- char *inbuf;
/* remember where to store incoming data for this stream and how big the
buffer is */
stream->mem = mem;
@@ -1582,16 +1584,15 @@ static ssize_t http2_recv(struct connect
if(httpc->inbuflen == 0) {
nread = ((Curl_recv *)httpc->recv_underlying)(
- conn, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, &result);
+ conn, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, err);
if(nread == -1) {
- if(result != CURLE_AGAIN)
+ if(*err != CURLE_AGAIN)
failf(data, "Failed receiving HTTP2 data");
else if(stream->closed)
/* received when the stream was already closed! */
return http2_handle_stream_close(conn, data, stream, err);
- *err = result;
return -1;
}
@@ -1604,47 +1605,17 @@ static ssize_t http2_recv(struct connect
H2BUGF(infof(data, "nread=%zd\n", nread));
httpc->inbuflen = nread;
- inbuf = httpc->inbuf;
+
+ DEBUGASSERT(httpc->nread_inbuf == 0);
}
else {
nread = httpc->inbuflen - httpc->nread_inbuf;
- inbuf = httpc->inbuf + httpc->nread_inbuf;
-
+ (void)nread; /* silence warning, used in debug */
H2BUGF(infof(data, "Use data left in connection buffer, nread=%zd\n",
nread));
}
- rv = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)inbuf, nread);
-
- if(nghttp2_is_fatal((int)rv)) {
- failf(data, "nghttp2_session_mem_recv() returned %zd:%s\n",
- rv, nghttp2_strerror((int)rv));
- *err = CURLE_RECV_ERROR;
- return -1;
- }
- H2BUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", rv));
- if(nread == rv) {
- H2BUGF(infof(data, "All data in connection buffer processed\n"));
- httpc->inbuflen = 0;
- httpc->nread_inbuf = 0;
- }
- else {
- httpc->nread_inbuf += rv;
- H2BUGF(infof(data, "%zu bytes left in connection buffer\n",
- httpc->inbuflen - httpc->nread_inbuf));
- }
- /* Always send pending frames in nghttp2 session, because
- nghttp2_session_mem_recv() may queue new frame */
- rv = h2_session_send(data, httpc->h2);
- if(rv != 0) {
- *err = CURLE_SEND_ERROR;
- return -1;
- }
-
- if(should_close_session(httpc)) {
- H2BUGF(infof(data, "http2_recv: nothing to do in this session\n"));
- *err = CURLE_HTTP2;
+ if(h2_process_pending_input(conn, httpc, err) != 0)
return -1;
- }
}
if(stream->memlen) {
ssize_t retlen = stream->memlen;
@@ -2108,7 +2079,6 @@ CURLcode Curl_http2_switched(struct conn
CURLcode result;
struct http_conn *httpc = &conn->proto.httpc;
int rv;
- ssize_t nproc;
struct Curl_easy *data = conn->data;
struct HTTP *stream = conn->data->req.protop;
@@ -2186,39 +2156,10 @@ CURLcode Curl_http2_switched(struct conn
memcpy(httpc->inbuf, mem, nread);
httpc->inbuflen = nread;
- nproc = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)httpc->inbuf,
- httpc->inbuflen);
+ DEBUGASSERT(httpc->nread_inbuf == 0);
- if(nghttp2_is_fatal((int)nproc)) {
- failf(data, "nghttp2_session_mem_recv() failed: %s(%d)",
- nghttp2_strerror((int)nproc), (int)nproc);
+ if(-1 == h2_process_pending_input(conn, httpc, &result))
return CURLE_HTTP2;
- }
-
- H2BUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", nproc));
-
- if((ssize_t)nread == nproc) {
- httpc->inbuflen = 0;
- httpc->nread_inbuf = 0;
- }
- else {
- httpc->nread_inbuf += nproc;
- }
-
- /* Try to send some frames since we may read SETTINGS already. */
- rv = h2_session_send(data, httpc->h2);
-
- if(rv != 0) {
- failf(data, "nghttp2_session_send() failed: %s(%d)",
- nghttp2_strerror(rv), rv);
- return CURLE_HTTP2;
- }
-
- if(should_close_session(httpc)) {
- H2BUGF(infof(data,
- "nghttp2_session_send(): nothing to do in this session\n"));
- return CURLE_HTTP2;
- }
return CURLE_OK;
}

@ -0,0 +1,15 @@
diff -up curl-7.61.1/lib/http2.c.c1b6a384 curl-7.61.1/lib/http2.c
--- curl-7.61.1/lib/http2.c.c1b6a384 2023-08-07 13:59:18.482137005 +0200
+++ curl-7.61.1/lib/http2.c 2023-08-07 14:03:42.043463284 +0200
@@ -1467,6 +1467,11 @@ static ssize_t http2_recv(struct connect
if(should_close_session(httpc)) {
H2BUGF(infof(data,
"http2_recv: nothing to do in this session\n"));
+ if(conn->bits.close) {
+ /* already marked for closure, return OK and we're done */
+ *err = CURLE_OK;
+ return 0;
+ }
*err = CURLE_HTTP2;
return -1;
}

@ -0,0 +1,48 @@
From 2b0994c29a721c91c572cff7808c572a24d251eb Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 23 Nov 2023 08:15:47 +0100
Subject: [PATCH] cookie: lowercase the domain names before PSL checks
Reported-by: Harry Sintonen
Closes #12387
---
lib/cookie.c | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/lib/cookie.c b/lib/cookie.c
index 568cf537ad1b1f..9095cea3e97f22 100644
--- a/lib/cookie.c
+++ b/lib/cookie.c
@@ -1027,15 +1027,23 @@ Curl_cookie_add(struct Curl_easy *data,
#ifdef USE_LIBPSL
/* Check if the domain is a Public Suffix and if yes, ignore the cookie. */
if(domain && co->domain && !isip(co->domain)) {
- const psl_ctx_t *psl = Curl_psl_use(data);
- int acceptable;
-
- if(psl) {
- acceptable = psl_is_cookie_domain_acceptable(psl, domain, co->domain);
- Curl_psl_release(data);
+ bool acceptable = FALSE;
+ char lcase[256];
+ char lcookie[256];
+ size_t dlen = strlen(domain);
+ size_t clen = strlen(co->domain);
+ if((dlen < sizeof(lcase)) && (clen < sizeof(lcookie))) {
+ const psl_ctx_t *psl = Curl_psl_use(data);
+ if(psl) {
+ /* the PSL check requires lowercase domain name and pattern */
+ Curl_strntolower(lcase, domain, dlen + 1);
+ Curl_strntolower(lcookie, co->domain, clen + 1);
+ acceptable = psl_is_cookie_domain_acceptable(psl, lcase, lcookie);
+ Curl_psl_release(data);
+ }
+ else
+ acceptable = !bad_domain(domain);
}
- else
- acceptable = !bad_domain(domain);
if(!acceptable) {
infof(data, "cookie '%s' dropped, domain '%s' must not "

@ -0,0 +1,136 @@
From 0023fce38d3bd6ee0e9b6ff8708fee1195057846 Mon Sep 17 00:00:00 2001
From: Barry Pollard <barry_pollard@hotmail.com>
Date: Sun, 22 Sep 2019 21:17:12 +0100
Subject: [PATCH] http: lowercase headernames for HTTP/2 and HTTP/3
Closes #4401
Fixes #4400
---
lib/strcase.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++
lib/strcase.h | 2 ++
5 files changed, 95 insertions(+), 3 deletions(-)
diff --git a/lib/strcase.c b/lib/strcase.c
index 24bcca932..098cec7a8 100644
--- a/lib/strcase.c
+++ b/lib/strcase.c
@@ -93,6 +93,75 @@ char Curl_raw_toupper(char in)
return in;
}
+
+/* Portable, consistent tolower (remember EBCDIC). Do not use tolower() because
+ its behavior is altered by the current locale. */
+char Curl_raw_tolower(char in)
+{
+#if !defined(CURL_DOES_CONVERSIONS)
+ if(in >= 'A' && in <= 'Z')
+ return (char)('a' + in - 'A');
+#else
+ switch(in) {
+ case 'A':
+ return 'a';
+ case 'B':
+ return 'b';
+ case 'C':
+ return 'c';
+ case 'D':
+ return 'd';
+ case 'E':
+ return 'e';
+ case 'F':
+ return 'f';
+ case 'G':
+ return 'g';
+ case 'H':
+ return 'h';
+ case 'I':
+ return 'i';
+ case 'J':
+ return 'j';
+ case 'K':
+ return 'k';
+ case 'L':
+ return 'l';
+ case 'M':
+ return 'm';
+ case 'N':
+ return 'n';
+ case 'O':
+ return 'o';
+ case 'P':
+ return 'p';
+ case 'Q':
+ return 'q';
+ case 'R':
+ return 'r';
+ case 'S':
+ return 's';
+ case 'T':
+ return 't';
+ case 'U':
+ return 'u';
+ case 'V':
+ return 'v';
+ case 'W':
+ return 'w';
+ case 'X':
+ return 'X';
+ case 'Y':
+ return 'y';
+ case 'Z':
+ return 'z';
+ }
+#endif
+
+ return in;
+}
+
+
/*
* Curl_strcasecompare() is for doing "raw" case insensitive strings. This is
* meant to be locale independent and only compare strings we know are safe
@@ -234,6 +303,21 @@ void Curl_strntoupper(char *dest, const char *src, size_t n)
} while(*src++ && --n);
}
+/* Copy a lower case version of the string from src to dest. The
+ * strings may overlap. No more than n characters of the string are copied
+ * (including any NUL) and the destination string will NOT be
+ * NUL-terminated if that limit is reached.
+ */
+void Curl_strntolower(char *dest, const char *src, size_t n)
+{
+ if(n < 1)
+ return;
+
+ do {
+ *dest++ = Curl_raw_tolower(*src);
+ } while(*src++ && --n);
+}
+
/* Compare case-sensitive NUL-terminated strings, taking care of possible
* null pointers. Return true if arguments match.
*/
diff --git a/lib/strcase.h b/lib/strcase.h
index 6fee3840e..2f07a74c9 100644
--- a/lib/strcase.h
+++ b/lib/strcase.h
@@ -40,12 +40,14 @@ int Curl_safe_strcasecompare(const char *first, const char *second);
int Curl_strncasecompare(const char *first, const char *second, size_t max);
char Curl_raw_toupper(char in);
+char Curl_raw_tolower(char in);
/* checkprefix() is a shorter version of the above, used when the first
argument is zero-byte terminated */
#define checkprefix(a,b) curl_strnequal(a,b,strlen(a))
void Curl_strntoupper(char *dest, const char *src, size_t n);
+void Curl_strntolower(char *dest, const char *src, size_t n);
bool Curl_safecmp(char *a, char *b);
int Curl_timestrcmp(const char *first, const char *second);
--
2.43.0

@ -0,0 +1,89 @@
From 2a4754a3a7cf60ecc36d83cbe50b8c337cb87632 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Fri, 12 Apr 2013 12:04:05 +0200
Subject: [PATCH] prevent multilib conflicts on the curl-config script
---
curl-config.in | 21 +++------------------
docs/curl-config.1 | 4 +++-
libcurl.pc.in | 1 +
3 files changed, 7 insertions(+), 19 deletions(-)
diff --git a/curl-config.in b/curl-config.in
index 150004d..95d0759 100644
--- a/curl-config.in
+++ b/curl-config.in
@@ -76,7 +76,7 @@ while test $# -gt 0; do
;;
--cc)
- echo "@CC@"
+ echo "gcc"
;;
--prefix)
@@ -143,32 +143,17 @@ while test $# -gt 0; do
;;
--libs)
- if test "X@libdir@" != "X/usr/lib" -a "X@libdir@" != "X/usr/lib64"; then
- CURLLIBDIR="-L@libdir@ "
- else
- CURLLIBDIR=""
- fi
- if test "X@REQUIRE_LIB_DEPS@" = "Xyes"; then
- echo ${CURLLIBDIR}-lcurl @LIBCURL_LIBS@
- else
- echo ${CURLLIBDIR}-lcurl
- fi
+ echo -lcurl
;;
--ssl-backends)
echo "@SSL_BACKENDS@"
;;
--static-libs)
- if test "X@ENABLE_STATIC@" != "Xno" ; then
- echo @libdir@/libcurl.@libext@ @LDFLAGS@ @LIBCURL_LIBS@
- else
- echo "curl was built with static libraries disabled" >&2
- exit 1
- fi
;;
--configure)
- echo @CONFIGURE_OPTIONS@
+ pkg-config libcurl --variable=configure_options | sed 's/^"//;s/"$//'
;;
*)
diff --git a/docs/curl-config.1 b/docs/curl-config.1
index 14a9d2b..ffcc004 100644
--- a/docs/curl-config.1
+++ b/docs/curl-config.1
@@ -70,7 +70,9 @@ no, one or several names. If more than one name, they will appear
comma-separated. (Added in 7.58.0)
.IP "--static-libs"
Shows the complete set of libs and other linker options you will need in order
-to link your application with libcurl statically. (Added in 7.17.1)
+to link your application with libcurl statically. Note that Fedora/RHEL libcurl
+packages do not provide any static libraries, thus cannot be linked statically.
+(Added in 7.17.1)
.IP "--version"
Outputs version information about the installed libcurl.
.IP "--vernum"
diff --git a/libcurl.pc.in b/libcurl.pc.in
index 2ba9c39..f8f8b00 100644
--- a/libcurl.pc.in
+++ b/libcurl.pc.in
@@ -29,6 +29,7 @@ libdir=@libdir@
includedir=@includedir@
supported_protocols="@SUPPORT_PROTOCOLS@"
supported_features="@SUPPORT_FEATURES@"
+configure_options=@CONFIGURE_OPTIONS@
Name: libcurl
URL: https://curl.haxx.se/
--
2.5.0

@ -0,0 +1,65 @@
From 6710648c2b270c9ce68a7d9f1bba1222c7be8b58 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Wed, 31 Oct 2012 11:38:30 +0100
Subject: [PATCH] prevent configure script from discarding -g in CFLAGS (#496778)
---
configure | 13 +++----------
m4/curl-compilers.m4 | 13 +++----------
2 files changed, 6 insertions(+), 20 deletions(-)
diff --git a/configure b/configure
index 8f079a3..53b4774 100755
--- a/configure
+++ b/configure
@@ -16414,18 +16414,11 @@ $as_echo "yes" >&6; }
gccvhi=`echo $gccver | cut -d . -f1`
gccvlo=`echo $gccver | cut -d . -f2`
compiler_num=`(expr $gccvhi "*" 100 + $gccvlo) 2>/dev/null`
- flags_dbg_all="-g -g0 -g1 -g2 -g3"
- flags_dbg_all="$flags_dbg_all -ggdb"
- flags_dbg_all="$flags_dbg_all -gstabs"
- flags_dbg_all="$flags_dbg_all -gstabs+"
- flags_dbg_all="$flags_dbg_all -gcoff"
- flags_dbg_all="$flags_dbg_all -gxcoff"
- flags_dbg_all="$flags_dbg_all -gdwarf-2"
- flags_dbg_all="$flags_dbg_all -gvms"
+ flags_dbg_all=""
flags_dbg_yes="-g"
flags_dbg_off=""
- flags_opt_all="-O -O0 -O1 -O2 -O3 -Os -Og -Ofast"
- flags_opt_yes="-O2"
+ flags_opt_all=""
+ flags_opt_yes=""
flags_opt_off="-O0"
OLDCPPFLAGS=$CPPFLAGS
diff --git a/m4/curl-compilers.m4 b/m4/curl-compilers.m4
index 0cbba7a..9175b5b 100644
--- a/m4/curl-compilers.m4
+++ b/m4/curl-compilers.m4
@@ -157,18 +157,11 @@ AC_DEFUN([CURL_CHECK_COMPILER_GNU_C], [
gccvhi=`echo $gccver | cut -d . -f1`
gccvlo=`echo $gccver | cut -d . -f2`
compiler_num=`(expr $gccvhi "*" 100 + $gccvlo) 2>/dev/null`
- flags_dbg_all="-g -g0 -g1 -g2 -g3"
- flags_dbg_all="$flags_dbg_all -ggdb"
- flags_dbg_all="$flags_dbg_all -gstabs"
- flags_dbg_all="$flags_dbg_all -gstabs+"
- flags_dbg_all="$flags_dbg_all -gcoff"
- flags_dbg_all="$flags_dbg_all -gxcoff"
- flags_dbg_all="$flags_dbg_all -gdwarf-2"
- flags_dbg_all="$flags_dbg_all -gvms"
+ flags_dbg_all=""
flags_dbg_yes="-g"
flags_dbg_off=""
- flags_opt_all="-O -O0 -O1 -O2 -O3 -Os -Og -Ofast"
- flags_opt_yes="-O2"
+ flags_opt_all=""
+ flags_opt_yes=""
flags_opt_off="-O0"
CURL_CHECK_DEF([_WIN32], [], [silent])
else
--
1.7.1

@ -0,0 +1,140 @@
From bdba7b54224814055185513de1e7ff6619031553 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Thu, 15 Mar 2018 13:21:40 +0100
Subject: [PATCH 1/2] tests/http_pipe.py: migrate to Python 3
---
tests/http_pipe.py | 4 ++--
tests/runtests.pl | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/tests/http_pipe.py b/tests/http_pipe.py
index bc32173..75ac165 100755
--- a/tests/http_pipe.py
+++ b/tests/http_pipe.py
@@ -383,13 +383,13 @@ class PipelineRequestHandler(socketserver.BaseRequestHandler):
self.request.setblocking(True)
if not new_data:
return
- new_requests = self._request_parser.ParseAdditionalData(new_data)
+ new_requests = self._request_parser.ParseAdditionalData(new_data.decode('utf8'))
self._response_builder.QueueRequests(
new_requests, self._request_parser.were_all_requests_http_1_1)
self._num_queued += len(new_requests)
self._last_queued_time = time.time()
elif fileno in wlist:
- num_bytes_sent = self.request.send(self._send_buffer[0:4096])
+ num_bytes_sent = self.request.send(self._send_buffer[0:4096].encode('utf8'))
self._send_buffer = self._send_buffer[num_bytes_sent:]
time.sleep(0.05)
diff --git a/tests/runtests.pl b/tests/runtests.pl
index d6aa5ca..4d395ef 100755
--- a/tests/runtests.pl
+++ b/tests/runtests.pl
@@ -1439,7 +1439,7 @@ sub runhttpserver {
elsif($alt eq "pipe") {
# basically the same, but another ID
$idnum = 3;
- $exe = "python $srcdir/http_pipe.py";
+ $exe = "python3 $srcdir/http_pipe.py";
$verbose_flag .= "1 ";
}
elsif($alt eq "unix") {
--
2.14.3
From 3c4c7340e455b7256c0786759422f34ec3e2d440 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Thu, 15 Mar 2018 14:49:56 +0100
Subject: [PATCH 2/2] tests/{negtelnet,smb}server.py: migrate to Python 3
Unfortunately, smbserver.py does not work with Python 3 because
there is no 'impacket' module available for Python 3:
https://github.com/CoreSecurity/impacket/issues/61
---
tests/negtelnetserver.py | 12 ++++++------
tests/smbserver.py | 4 ++--
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/tests/negtelnetserver.py b/tests/negtelnetserver.py
index 8cfd409..72ee771 100755
--- a/tests/negtelnetserver.py
+++ b/tests/negtelnetserver.py
@@ -23,7 +23,7 @@ IDENT = "NTEL"
# The strings that indicate the test framework is checking our aliveness
VERIFIED_REQ = b"verifiedserver"
-VERIFIED_RSP = b"WE ROOLZ: {pid}"
+VERIFIED_RSP = "WE ROOLZ: {pid}"
def telnetserver(options):
@@ -34,7 +34,7 @@ def telnetserver(options):
if options.pidfile:
pid = os.getpid()
with open(options.pidfile, "w") as f:
- f.write(b"{0}".format(pid))
+ f.write("{0}".format(pid))
local_bind = (HOST, options.port)
log.info("Listening on %s", local_bind)
@@ -73,11 +73,11 @@ class NegotiatingTelnetHandler(socketserver.BaseRequestHandler):
response_data = VERIFIED_RSP.format(pid=os.getpid())
else:
log.debug("Received normal request - echoing back")
- response_data = data.strip()
+ response_data = data.decode('utf8').strip()
if response_data:
log.debug("Sending %r", response_data)
- self.request.sendall(response_data)
+ self.request.sendall(response_data.encode('utf8'))
except IOError:
log.exception("IOError hit during request")
@@ -132,7 +132,7 @@ class Negotiator(object):
return buffer
def byte_to_int(self, byte):
- return struct.unpack(b'B', byte)[0]
+ return int(byte)
def no_neg(self, byte, byte_int, buffer):
# Not negotiating anything thus far. Check to see if we
@@ -197,7 +197,7 @@ class Negotiator(object):
self.tcp.sendall(packed_message)
def pack(self, arr):
- return struct.pack(b'{0}B'.format(len(arr)), *arr)
+ return struct.pack('{0}B'.format(len(arr)), *arr)
def send_iac(self, arr):
message = [NegTokens.IAC]
diff --git a/tests/smbserver.py b/tests/smbserver.py
index 195ae39..b09cd44 100755
--- a/tests/smbserver.py
+++ b/tests/smbserver.py
@@ -24,7 +24,7 @@
from __future__ import (absolute_import, division, print_function)
# unicode_literals)
import argparse
-import ConfigParser
+import configparser
import os
import sys
import logging
@@ -58,7 +58,7 @@ def smbserver(options):
f.write("{0}".format(pid))
# Here we write a mini config for the server
- smb_config = ConfigParser.ConfigParser()
+ smb_config = configparser.ConfigParser()
smb_config.add_section("global")
smb_config.set("global", "server_name", "SERVICE")
smb_config.set("global", "server_os", "UNIX")
--
2.14.3

@ -0,0 +1,51 @@
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 server 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 server 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>

@ -0,0 +1,71 @@
From e6507a9abbfd4ac93ea3053c8f3385a2405f19d8 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
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
</data>
@@ -52,7 +52,7 @@ Redirect following to UTF-8 IDN host name
</name>
<command>
-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
</command>
</client>
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
<protocol>
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
<protocol>
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

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save