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) 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_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_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_secured = true;
m_cntInfos = vmime::create <tls::TLSSecuredConnectionInfos> m_cntInfos = vmime::create <tls::TLSSecuredConnectionInfos>
(m_cntInfos->getHost(), m_cntInfos->getPort(), tlsSession, tlsSocket); (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&) catch (exceptions::command_error&)
{ {
@ -491,6 +498,22 @@ void IMAPConnection::startTLS()
const std::vector <string> IMAPConnection::getCapabilities() 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); 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) POP3Connection::POP3Connection(ref <POP3Store> store, ref <security::authenticator> auth)
: m_store(store), m_auth(auth), m_socket(NULL), m_timeoutHandler(NULL), : 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_secured = true;
m_cntInfos = vmime::create <tls::TLSSecuredConnectionInfos> m_cntInfos = vmime::create <tls::TLSSecuredConnectionInfos>
(m_cntInfos->getHost(), m_cntInfos->getPort(), tlsSession, tlsSocket); (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&) catch (exceptions::command_error&)
{ {
@ -568,6 +575,22 @@ void POP3Connection::startTLS()
const std::vector <string> POP3Connection::getCapabilities() 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>()); POP3Command::CAPA()->send(thisRef().dynamicCast <POP3Connection>());
@ -582,7 +605,8 @@ const std::vector <string> POP3Connection::getCapabilities()
res.push_back(response->getLineAt(i)); res.push_back(response->getLineAt(i));
} }
return res; m_capabilities = res;
m_capabilitiesFetched = true;
} }

View File

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

View File

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