diff options
author | Vincent Richard <[email protected]> | 2005-10-03 21:29:04 +0000 |
---|---|---|
committer | Vincent Richard <[email protected]> | 2005-10-03 21:29:04 +0000 |
commit | 7d2d25da3eb891a70ec5dfd3b077b0e130571472 (patch) | |
tree | 44b1930480276fe83b6f94ecda308e5a9ceb3162 /src/net/imap/IMAPConnection.cpp | |
parent | Reduced waiting time. (diff) | |
download | vmime-7d2d25da3eb891a70ec5dfd3b077b0e130571472.tar.gz vmime-7d2d25da3eb891a70ec5dfd3b077b0e130571472.zip |
Added TLS/SSL support.
Diffstat (limited to 'src/net/imap/IMAPConnection.cpp')
-rw-r--r-- | src/net/imap/IMAPConnection.cpp | 112 |
1 files changed, 109 insertions, 3 deletions
diff --git a/src/net/imap/IMAPConnection.cpp b/src/net/imap/IMAPConnection.cpp index 6d2a4a4e..b0716f45 100644 --- a/src/net/imap/IMAPConnection.cpp +++ b/src/net/imap/IMAPConnection.cpp @@ -29,16 +29,20 @@ #include "vmime/security/sasl/SASLContext.hpp" #endif // VMIME_HAVE_SASL_SUPPORT +#if VMIME_HAVE_TLS_SUPPORT + #include "vmime/net/tls/TLSSession.hpp" +#endif // VMIME_HAVE_TLS_SUPPORT + #include <sstream> // Helpers for service properties #define GET_PROPERTY(type, prop) \ (m_store->getInfos().getPropertyValue <type>(getSession(), \ - dynamic_cast <const IMAPStore::_infos&>(m_store->getInfos()).getProperties().prop)) + dynamic_cast <const IMAPServiceInfos&>(m_store->getInfos()).getProperties().prop)) #define HAS_PROPERTY(prop) \ (m_store->getInfos().hasProperty(getSession(), \ - dynamic_cast <const IMAPStore::_infos&>(m_store->getInfos()).getProperties().prop)) + dynamic_cast <const IMAPServiceInfos&>(m_store->getInfos()).getProperties().prop)) namespace vmime { @@ -94,6 +98,20 @@ void IMAPConnection::connect() getSocketFactory(GET_PROPERTY(string, PROPERTY_SERVER_SOCKETFACTORY)); m_socket = sf->create(); + +#if VMIME_HAVE_TLS_SUPPORT + if (m_store->isSecuredConnection()) // dedicated port/IMAPS + { + ref <tls::TLSSession> tlsSession = + vmime::create <tls::TLSSession>(m_store->getCertificateVerifier()); + + ref <tls::TLSSocket> tlsSocket = + tlsSession->getSocket(m_socket); + + m_socket = tlsSocket; + } +#endif // VMIME_HAVE_TLS_SUPPORT + m_socket->connect(address, port); @@ -110,6 +128,7 @@ void IMAPConnection::connect() // --- S: * OK mydomain.org IMAP4rev1 v12.256 server ready utility::auto_ptr <IMAPParser::greeting> greet(m_parser->readGreeting()); + bool needAuth = false; if (greet->resp_cond_bye()) { @@ -118,6 +137,47 @@ void IMAPConnection::connect() } else if (greet->resp_cond_auth()->condition() != IMAPParser::resp_cond_auth::PREAUTH) { + needAuth = true; + } + +#if VMIME_HAVE_TLS_SUPPORT + // Setup secured connection, if requested + const bool tls = HAS_PROPERTY(PROPERTY_CONNECTION_TLS) + && GET_PROPERTY(bool, PROPERTY_CONNECTION_TLS); + const bool tlsRequired = HAS_PROPERTY(PROPERTY_CONNECTION_TLS_REQUIRED) + && GET_PROPERTY(bool, PROPERTY_CONNECTION_TLS_REQUIRED); + + if (!m_store->isSecuredConnection() && tls) // only if not IMAPS + { + try + { + startTLS(); + } + // Non-fatal error + catch (exceptions::command_error&) + { + if (tlsRequired) + { + m_state = STATE_NONE; + throw; + } + else + { + // TLS is not required, so don't bother + } + } + // Fatal error + catch (...) + { + m_state = STATE_NONE; + throw; + } + } +#endif // VMIME_HAVE_TLS_SUPPORT + + // Authentication + if (needAuth) + { try { authenticate(); @@ -287,17 +347,19 @@ void IMAPConnection::authenticateSASL() respDataList = resp->continue_req_or_response_data(); string response; + bool hasResponse = false; for (unsigned int i = 0 ; i < respDataList.size() ; ++i) { if (respDataList[i]->continue_req()) { response = respDataList[i]->continue_req()->resp_text()->text(); + hasResponse = true; break; } } - if (response.empty()) + if (!hasResponse) { cont = false; continue; @@ -365,6 +427,50 @@ void IMAPConnection::authenticateSASL() #endif // VMIME_HAVE_SASL_SUPPORT +#if VMIME_HAVE_TLS_SUPPORT + +void IMAPConnection::startTLS() +{ + try + { + send(true, "STARTTLS", true); + + utility::auto_ptr <IMAPParser::response> resp(m_parser->readResponse()); + + if (resp->isBad() || resp->response_done()->response_tagged()-> + resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) + { + throw exceptions::command_error + ("STARTTLS", m_parser->lastLine(), "bad response"); + } + + ref <tls::TLSSession> tlsSession = + vmime::create <tls::TLSSession>(m_store->getCertificateVerifier()); + + ref <tls::TLSSocket> tlsSocket = + tlsSession->getSocket(m_socket); + + tlsSocket->handshake(m_timeoutHandler); + + m_socket = tlsSocket; + m_parser->setSocket(m_socket); + } + catch (exceptions::command_error&) + { + // Non-fatal error + throw; + } + catch (exception&) + { + // Fatal error + internalDisconnect(); + throw; + } +} + +#endif // VMIME_HAVE_TLS_SUPPORT + + const std::vector <string> IMAPConnection::getCapabilities() { send(true, "CAPABILITY", true); |