Blame SOURCES/0008-curl-7.76.1-CVE-2021-22946.patch

b5a08f
From 64f8bdbf7da9e6b65716ce0d020c6c01d0aba77d Mon Sep 17 00:00:00 2001
b5a08f
From: Patrick Monnerat <patrick@monnerat.net>
b5a08f
Date: Wed, 8 Sep 2021 11:56:22 +0200
b5a08f
Subject: [PATCH] ftp,imap,pop3: do not ignore --ssl-reqd
b5a08f
b5a08f
In imap and pop3, check if TLS is required even when capabilities
b5a08f
request has failed.
b5a08f
b5a08f
In ftp, ignore preauthentication (230 status of server greeting) if TLS
b5a08f
is required.
b5a08f
b5a08f
Bug: https://curl.se/docs/CVE-2021-22946.html
b5a08f
b5a08f
CVE-2021-22946
b5a08f
b5a08f
Upstream-commit: 364f174724ef115c63d5e5dc1d3342c8a43b1cca
b5a08f
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
b5a08f
---
b5a08f
 lib/ftp.c               |  9 ++++---
b5a08f
 lib/imap.c              | 24 ++++++++----------
b5a08f
 lib/pop3.c              | 33 +++++++++++-------------
b5a08f
 tests/data/Makefile.inc |  2 ++
b5a08f
 tests/data/test984      | 56 +++++++++++++++++++++++++++++++++++++++++
b5a08f
 tests/data/test985      | 54 +++++++++++++++++++++++++++++++++++++++
b5a08f
 tests/data/test986      | 53 ++++++++++++++++++++++++++++++++++++++
b5a08f
 7 files changed, 195 insertions(+), 36 deletions(-)
b5a08f
 create mode 100644 tests/data/test984
b5a08f
 create mode 100644 tests/data/test985
b5a08f
 create mode 100644 tests/data/test986
b5a08f
b5a08f
diff --git a/lib/ftp.c b/lib/ftp.c
b5a08f
index 5ef1e2e..71f998e 100644
b5a08f
--- a/lib/ftp.c
b5a08f
+++ b/lib/ftp.c
b5a08f
@@ -2678,9 +2678,12 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
b5a08f
     /* we have now received a full FTP server response */
b5a08f
     switch(ftpc->state) {
b5a08f
     case FTP_WAIT220:
b5a08f
-      if(ftpcode == 230)
b5a08f
-        /* 230 User logged in - already! */
b5a08f
-        return ftp_state_user_resp(data, ftpcode, ftpc->state);
b5a08f
+      if(ftpcode == 230) {
b5a08f
+        /* 230 User logged in - already! Take as 220 if TLS required. */
b5a08f
+        if(data->set.use_ssl <= CURLUSESSL_TRY ||
b5a08f
+           conn->bits.ftp_use_control_ssl)
b5a08f
+          return ftp_state_user_resp(data, ftpcode, ftpc->state);
b5a08f
+      }
b5a08f
       else if(ftpcode != 220) {
b5a08f
         failf(data, "Got a %03d ftp-server response when 220 was expected",
b5a08f
               ftpcode);
b5a08f
diff --git a/lib/imap.c b/lib/imap.c
b5a08f
index e50d7fd..feb7445 100644
b5a08f
--- a/lib/imap.c
b5a08f
+++ b/lib/imap.c
b5a08f
@@ -935,22 +935,18 @@ static CURLcode imap_state_capability_resp(struct Curl_easy *data,
b5a08f
       line += wordlen;
b5a08f
     }
b5a08f
   }
b5a08f
-  else if(imapcode == IMAP_RESP_OK) {
b5a08f
-    if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
b5a08f
-      /* We don't have a SSL/TLS connection yet, but SSL is requested */
b5a08f
-      if(imapc->tls_supported)
b5a08f
-        /* Switch to TLS connection now */
b5a08f
-        result = imap_perform_starttls(data, conn);
b5a08f
-      else if(data->set.use_ssl == CURLUSESSL_TRY)
b5a08f
-        /* Fallback and carry on with authentication */
b5a08f
-        result = imap_perform_authentication(data, conn);
b5a08f
-      else {
b5a08f
-        failf(data, "STARTTLS not supported.");
b5a08f
-        result = CURLE_USE_SSL_FAILED;
b5a08f
-      }
b5a08f
+  else if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
b5a08f
+    /* PREAUTH is not compatible with STARTTLS. */
b5a08f
+    if(imapcode == IMAP_RESP_OK && imapc->tls_supported && !imapc->preauth) {
b5a08f
+      /* Switch to TLS connection now */
b5a08f
+      result = imap_perform_starttls(data, conn);
b5a08f
     }
b5a08f
-    else
b5a08f
+    else if(data->set.use_ssl <= CURLUSESSL_TRY)
b5a08f
       result = imap_perform_authentication(data, conn);
b5a08f
+    else {
b5a08f
+      failf(data, "STARTTLS not available.");
b5a08f
+      result = CURLE_USE_SSL_FAILED;
b5a08f
+    }
b5a08f
   }
b5a08f
   else
b5a08f
     result = imap_perform_authentication(data, conn);
b5a08f
diff --git a/lib/pop3.c b/lib/pop3.c
b5a08f
index 6168b12..7698d1c 100644
b5a08f
--- a/lib/pop3.c
b5a08f
+++ b/lib/pop3.c
b5a08f
@@ -740,28 +740,23 @@ static CURLcode pop3_state_capa_resp(struct Curl_easy *data, int pop3code,
b5a08f
       }
b5a08f
     }
b5a08f
   }
b5a08f
-  else if(pop3code == '+') {
b5a08f
-    if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
b5a08f
-      /* We don't have a SSL/TLS connection yet, but SSL is requested */
b5a08f
-      if(pop3c->tls_supported)
b5a08f
-        /* Switch to TLS connection now */
b5a08f
-        result = pop3_perform_starttls(data, conn);
b5a08f
-      else if(data->set.use_ssl == CURLUSESSL_TRY)
b5a08f
-        /* Fallback and carry on with authentication */
b5a08f
-        result = pop3_perform_authentication(data, conn);
b5a08f
-      else {
b5a08f
-        failf(data, "STLS not supported.");
b5a08f
-        result = CURLE_USE_SSL_FAILED;
b5a08f
-      }
b5a08f
-    }
b5a08f
-    else
b5a08f
-      result = pop3_perform_authentication(data, conn);
b5a08f
-  }
b5a08f
   else {
b5a08f
     /* Clear text is supported when CAPA isn't recognised */
b5a08f
-    pop3c->authtypes |= POP3_TYPE_CLEARTEXT;
b5a08f
+    if(pop3code != '+')
b5a08f
+      pop3c->authtypes |= POP3_TYPE_CLEARTEXT;
b5a08f
 
b5a08f
-    result = pop3_perform_authentication(data, conn);
b5a08f
+    if(!data->set.use_ssl || conn->ssl[FIRSTSOCKET].use)
b5a08f
+      result = pop3_perform_authentication(data, conn);
b5a08f
+    else if(pop3code == '+' && pop3c->tls_supported)
b5a08f
+      /* Switch to TLS connection now */
b5a08f
+      result = pop3_perform_starttls(data, conn);
b5a08f
+    else if(data->set.use_ssl <= CURLUSESSL_TRY)
b5a08f
+      /* Fallback and carry on with authentication */
b5a08f
+      result = pop3_perform_authentication(data, conn);
b5a08f
+    else {
b5a08f
+      failf(data, "STLS not supported.");
b5a08f
+      result = CURLE_USE_SSL_FAILED;
b5a08f
+    }
b5a08f
   }
b5a08f
 
b5a08f
   return result;
b5a08f
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
b5a08f
index d083baf..163ce59 100644
b5a08f
--- a/tests/data/Makefile.inc
b5a08f
+++ b/tests/data/Makefile.inc
b5a08f
@@ -117,6 +117,8 @@ 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
+\
b5a08f
 test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 \
b5a08f
 test1008 test1009 test1010 test1011 test1012 test1013 test1014 test1015 \
b5a08f
 test1016 test1017 test1018 test1019 test1020 test1021 test1022 test1023 \
b5a08f
diff --git a/tests/data/test984 b/tests/data/test984
b5a08f
new file mode 100644
b5a08f
index 0000000..e573f23
b5a08f
--- /dev/null
b5a08f
+++ b/tests/data/test984
b5a08f
@@ -0,0 +1,56 @@
b5a08f
+<testcase>
b5a08f
+<info>
b5a08f
+<keywords>
b5a08f
+IMAP
b5a08f
+STARTTLS
b5a08f
+</keywords>
b5a08f
+</info>
b5a08f
+
b5a08f
+#
b5a08f
+# Server-side
b5a08f
+<reply>
b5a08f
+<servercmd>
b5a08f
+REPLY CAPABILITY A001 BAD Not implemented
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 require STARTTLS with failing capabilities
b5a08f
+ </name>
b5a08f
+ <command>
b5a08f
+imap://%HOSTIP:%IMAPPORT/%TESTNUMBER -T log/upload%TESTNUMBER -u user:secret --ssl-reqd
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
+# 64 is CURLE_USE_SSL_FAILED
b5a08f
+<errorcode>
b5a08f
+64
b5a08f
+</errorcode>
b5a08f
+<protocol>
b5a08f
+A001 CAPABILITY
b5a08f
+</protocol>
b5a08f
+</verify>
b5a08f
+</testcase>
b5a08f
diff --git a/tests/data/test985 b/tests/data/test985
b5a08f
new file mode 100644
b5a08f
index 0000000..d0db4aa
b5a08f
--- /dev/null
b5a08f
+++ b/tests/data/test985
b5a08f
@@ -0,0 +1,54 @@
b5a08f
+<testcase>
b5a08f
+<info>
b5a08f
+<keywords>
b5a08f
+POP3
b5a08f
+STARTTLS
b5a08f
+</keywords>
b5a08f
+</info>
b5a08f
+
b5a08f
+#
b5a08f
+# Server-side
b5a08f
+<reply>
b5a08f
+<servercmd>
b5a08f
+REPLY CAPA -ERR Not implemented
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 require STARTTLS with failing capabilities
b5a08f
+ </name>
b5a08f
+ <command>
b5a08f
+pop3://%HOSTIP:%POP3PORT/%TESTNUMBER -u user:secret --ssl-reqd
b5a08f
+ </command>
b5a08f
+</client>
b5a08f
+
b5a08f
+#
b5a08f
+# Verify data after the test has been "shot"
b5a08f
+<verify>
b5a08f
+# 64 is CURLE_USE_SSL_FAILED
b5a08f
+<errorcode>
b5a08f
+64
b5a08f
+</errorcode>
b5a08f
+<protocol>
b5a08f
+CAPA
b5a08f
+</protocol>
b5a08f
+</verify>
b5a08f
+</testcase>
b5a08f
diff --git a/tests/data/test986 b/tests/data/test986
b5a08f
new file mode 100644
b5a08f
index 0000000..a709437
b5a08f
--- /dev/null
b5a08f
+++ b/tests/data/test986
b5a08f
@@ -0,0 +1,53 @@
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 welcome 230 Welcome
b5a08f
+REPLY AUTH 500 unknown command
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 require STARTTLS while preauthenticated
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-reqd --ftp-ssl-control ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -T log/test%TESTNUMBER.txt -u user:secret
b5a08f
+</command>
b5a08f
+</client>
b5a08f
+
b5a08f
+# Verify data after the test has been "shot"
b5a08f
+<verify>
b5a08f
+# 64 is CURLE_USE_SSL_FAILED
b5a08f
+<errorcode>
b5a08f
+64
b5a08f
+</errorcode>
b5a08f
+<protocol>
b5a08f
+AUTH SSL
b5a08f
+AUTH TLS
b5a08f
+</protocol>
b5a08f
+</verify>
b5a08f
+</testcase>
b5a08f
-- 
b5a08f
2.31.1
b5a08f