Re-issue CAPA command once TLS has been started (POP3, IMAP).

This commit is contained in:
Vincent Richard 2013-06-17 15:04:37 +02:00
parent 2e5574b146
commit 01fd896e3c
4 changed files with 62 additions and 4 deletions

View File

@ -66,7 +66,7 @@ namespace imap {
IMAPConnection::IMAPConnection(ref <IMAPStore> store, ref <security::authenticator> auth)
: m_store(store), m_auth(auth), m_socket(NULL), m_parser(NULL), m_tag(NULL),
m_hierarchySeparator('\0'), m_state(STATE_NONE), m_timeoutHandler(NULL),
m_secured(false), m_firstTag(true)
m_secured(false), m_firstTag(true), m_capabilitiesFetched(false)
{
}
@ -473,6 +473,13 @@ void IMAPConnection::startTLS()
m_secured = true;
m_cntInfos = vmime::create <tls::TLSSecuredConnectionInfos>
(m_cntInfos->getHost(), m_cntInfos->getPort(), tlsSession, tlsSocket);
// " Once TLS has been started, the client MUST discard cached
// information about server capabilities and SHOULD re-issue the
// CAPABILITY command. This is necessary to protect against
// man-in-the-middle attacks which alter the capabilities list prior
// to STARTTLS. " (RFC-2595)
invalidateCapabilities();
}
catch (exceptions::command_error&)
{
@ -491,6 +498,22 @@ void IMAPConnection::startTLS()
const std::vector <string> IMAPConnection::getCapabilities()
{
if (!m_capabilitiesFetched)
fetchCapabilities();
return m_capabilities;
}
void IMAPConnection::invalidateCapabilities()
{
m_capabilities.clear();
m_capabilitiesFetched = false;
}
void IMAPConnection::fetchCapabilities()
{
send(true, "CAPABILITY", true);
@ -527,7 +550,8 @@ const std::vector <string> IMAPConnection::getCapabilities()
}
}
return res;
m_capabilities = res;
m_capabilitiesFetched = true;
}

View File

@ -65,7 +65,7 @@ namespace pop3 {
POP3Connection::POP3Connection(ref <POP3Store> store, ref <security::authenticator> auth)
: m_store(store), m_auth(auth), m_socket(NULL), m_timeoutHandler(NULL),
m_authenticated(false), m_secured(false)
m_authenticated(false), m_secured(false), m_capabilitiesFetched(false)
{
}
@ -550,6 +550,13 @@ void POP3Connection::startTLS()
m_secured = true;
m_cntInfos = vmime::create <tls::TLSSecuredConnectionInfos>
(m_cntInfos->getHost(), m_cntInfos->getPort(), tlsSession, tlsSocket);
// " Once TLS has been started, the client MUST discard cached
// information about server capabilities and SHOULD re-issue
// the CAPA command. This is necessary to protect against
// man-in-the-middle attacks which alter the capabilities list
// prior to STLS. " (RFC-2595)
invalidateCapabilities();
}
catch (exceptions::command_error&)
{
@ -568,6 +575,22 @@ void POP3Connection::startTLS()
const std::vector <string> POP3Connection::getCapabilities()
{
if (!m_capabilitiesFetched)
fetchCapabilities();
return m_capabilities;
}
void POP3Connection::invalidateCapabilities()
{
m_capabilities.clear();
m_capabilitiesFetched = false;
}
void POP3Connection::fetchCapabilities()
{
POP3Command::CAPA()->send(thisRef().dynamicCast <POP3Connection>());
@ -582,7 +605,8 @@ const std::vector <string> POP3Connection::getCapabilities()
res.push_back(response->getLineAt(i));
}
return res;
m_capabilities = res;
m_capabilitiesFetched = true;
}

View File

@ -93,6 +93,8 @@ public:
ref <session> getSession();
void fetchCapabilities();
void invalidateCapabilities();
const std::vector <string> getCapabilities();
ref <security::authenticator> getAuthenticator();
@ -135,6 +137,9 @@ private:
bool m_firstTag;
std::vector <string> m_capabilities;
bool m_capabilitiesFetched;
void internalDisconnect();

View File

@ -94,6 +94,8 @@ private:
void startTLS();
#endif // VMIME_HAVE_TLS_SUPPORT
void fetchCapabilities();
void invalidateCapabilities();
const std::vector <string> getCapabilities();
void internalDisconnect();
@ -109,6 +111,9 @@ private:
bool m_secured;
ref <connectionInfos> m_cntInfos;
std::vector <string> m_capabilities;
bool m_capabilitiesFetched;
};