From 03ca8c6faca7de6628f9cbec3001ec6466c88d07 Mon Sep 17 00:00:00 2001 From: Patrick Monnerat 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 --- 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 @@ + + + +IMAP +STARTTLS + + + +# +# Server-side + + +REPLY CAPABILITY A001 BAD Not implemented + + + +# +# Client-side + + +SSL + + +imap + + +IMAP require STARTTLS with failing capabilities + + +imap://%HOSTIP:%IMAPPORT/%TESTNUMBER -T log/upload%TESTNUMBER -u user:secret --ssl-reqd + + +Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST) +From: Fred Foobar +Subject: afternoon meeting +To: joe@example.com +Message-Id: +MIME-Version: 1.0 +Content-Type: TEXT/PLAIN; CHARSET=US-ASCII + +Hello Joe, do you think we can meet at 3:30 tomorrow? + + + +# +# Verify data after the test has been "shot" + +# 64 is CURLE_USE_SSL_FAILED + +64 + + +A001 CAPABILITY + + + 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 @@ + + + +POP3 +STARTTLS + + + +# +# Server-side + + +REPLY CAPA -ERR Not implemented + + +From: me@somewhere +To: fake@nowhere + +body + +-- + yours sincerely + + + +# +# Client-side + + +SSL + + +pop3 + + +POP3 require STARTTLS with failing capabilities + + +pop3://%HOSTIP:%POP3PORT/%TESTNUMBER -u user:secret --ssl-reqd + + + +# +# Verify data after the test has been "shot" + +# 64 is CURLE_USE_SSL_FAILED + +64 + + +CAPA + + + 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 @@ + + + +FTP +STARTTLS + + + +# +# Server-side + + +REPLY welcome 230 Welcome +REPLY AUTH 500 unknown command + + + +# Client-side + + +SSL + + +ftp + + +FTP require STARTTLS while preauthenticated + + +data + to + see +that FTPS +works + so does it? + + +--ssl-reqd --ftp-ssl-control ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -T log/test%TESTNUMBER.txt -u user:secret + + + +# Verify data after the test has been "shot" + +# 64 is CURLE_USE_SSL_FAILED + +64 + + +AUTH SSL +AUTH TLS + + + -- 2.31.1