Skip to content
Permalink
Browse files Browse the repository at this point in the history
IMAP: refuse to work when STARTTLS is required but server sends PREAUTH
Oops, we cannot send STARTTLS when the connection is already authenticated.
This is serious enough to warrant an error; an attacker might be going after a
plaintext of a message we're going to APPEND, etc.

Thanks to Arnt Gulbrandsen on the imap-protocol ML for asking what happens when
we're configured to request STARTTLS and a PREAUTH is received, and to Michael M
Slusarz for starting that discussion.

Hope the error message is readable enough.

CVE: CVE-2014-2567
  • Loading branch information
jktjkt committed Mar 20, 2014
1 parent 11eb011 commit 25fffa3
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/Imap/Tasks/OpenConnectionTask.cpp
Expand Up @@ -153,6 +153,17 @@ bool OpenConnectionTask::handleStateHelper(const Imap::Responses::State *const r
{
switch (resp->kind) {
case PREAUTH:
if (model->m_startTls) {
// Oops, we cannot send STARTTLS when the connection is already authenticated.
// This is serious enough to warrant an error; an attacker might be going after a plaintext
// of a message we're going to APPEND, etc.
// Thanks to Arnt Gulbrandsen on the imap-protocol ML for asking what happens when we're configured
// to request STARTTLS and a PREAUTH is received, and to Michael M Slusarz for starting that discussion.
logout(tr("Configuration requires sending STARTTLS, but the IMAP server greets us with PREAUTH. "
"Encryption cannot be established. If this configuration worked previously, someone "
"is after your data and they are pretty smart."));
return true;
}
// Cool, we're already authenticated. Now, let's see if we have to issue CAPABILITY or if we already know that
if (model->accessParser(parser).capabilitiesFresh) {
// We're alsmost done here, apart from compression
Expand Down
13 changes: 13 additions & 0 deletions tests/Imap/test_Imap_Tasks_OpenConnection.cpp
Expand Up @@ -129,6 +129,19 @@ void ImapModelOpenConnectionTest::testPreauthWithCapability()
QVERIFY(startTlsUpgradeSpy->isEmpty());
}

/** @short What happens when the server responds with PREAUTH and we want STARTTLS? */
void ImapModelOpenConnectionTest::testPreauthWithStartTlsWanted()
{
cleanup(); init(true); // yuck, but I can't come up with anything better...

cEmpty();
cServer("* PREAUTH hi there\r\n");
QCOMPARE(failedSpy->size(), 1);
QVERIFY(completedSpy->isEmpty());
QVERIFY(authSpy->isEmpty());
QVERIFY(startTlsUpgradeSpy->isEmpty());
}

/** @short Test for obtaining capability and logging in without any STARTTLS */
void ImapModelOpenConnectionTest::testOk()
{
Expand Down
1 change: 1 addition & 0 deletions tests/Imap/test_Imap_Tasks_OpenConnection.h
Expand Up @@ -39,6 +39,7 @@ private slots:

void testPreauth();
void testPreauthWithCapability();
void testPreauthWithStartTlsWanted();

void testOk();
void testOkWithCapability();
Expand Down

0 comments on commit 25fffa3

Please sign in to comment.