Blame SOURCES/0034-curl-7.61.1-CVE-2021-22946.patch

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