aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/imap/IMAPConnection.cpp
diff options
context:
space:
mode:
authorVincent Richard <[email protected]>2005-10-03 21:29:04 +0000
committerVincent Richard <[email protected]>2005-10-03 21:29:04 +0000
commit7d2d25da3eb891a70ec5dfd3b077b0e130571472 (patch)
tree44b1930480276fe83b6f94ecda308e5a9ceb3162 /src/net/imap/IMAPConnection.cpp
parentReduced waiting time. (diff)
downloadvmime-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.cpp112
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);