Blame SOURCES/0009-curl-7.76.1-CVE-2021-22947.patch

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