diff options
Diffstat (limited to '')
-rw-r--r-- | src/net/imap/IMAPConnection.cpp | 112 | ||||
-rw-r--r-- | src/net/imap/IMAPSStore.cpp | 65 | ||||
-rw-r--r-- | src/net/imap/IMAPServiceInfos.cpp | 133 | ||||
-rw-r--r-- | src/net/imap/IMAPStore.cpp | 73 |
4 files changed, 318 insertions, 65 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); diff --git a/src/net/imap/IMAPSStore.cpp b/src/net/imap/IMAPSStore.cpp new file mode 100644 index 00000000..ed637c43 --- /dev/null +++ b/src/net/imap/IMAPSStore.cpp @@ -0,0 +1,65 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2005 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along along +// with this program; if not, write to the Free Software Foundation, Inc., Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.. +// + +#include "vmime/net/imap/IMAPSStore.hpp" + + +namespace vmime { +namespace net { +namespace imap { + + +IMAPSStore::IMAPSStore(ref <session> sess, ref <security::authenticator> auth) + : IMAPStore(sess, auth, true) +{ +} + + +IMAPSStore::~IMAPSStore() +{ +} + + +const string IMAPSStore::getProtocolName() const +{ + return "imaps"; +} + + + +// Service infos + +IMAPServiceInfos IMAPSStore::sm_infos(true); + + +const serviceInfos& IMAPSStore::getInfosInstance() +{ + return sm_infos; +} + + +const serviceInfos& IMAPSStore::getInfos() const +{ + return sm_infos; +} + + +} // imap +} // net +} // vmime diff --git a/src/net/imap/IMAPServiceInfos.cpp b/src/net/imap/IMAPServiceInfos.cpp new file mode 100644 index 00000000..d8164ce1 --- /dev/null +++ b/src/net/imap/IMAPServiceInfos.cpp @@ -0,0 +1,133 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2005 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along along +// with this program; if not, write to the Free Software Foundation, Inc., Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.. +// + +#include "vmime/net/imap/IMAPServiceInfos.hpp" + + +namespace vmime { +namespace net { +namespace imap { + + +IMAPServiceInfos::IMAPServiceInfos(const bool imaps) + : m_imaps(imaps) +{ +} + + +const string IMAPServiceInfos::getPropertyPrefix() const +{ + if (m_imaps) + return "store.imaps."; + else + return "store.imap."; +} + + +const IMAPServiceInfos::props& IMAPServiceInfos::getProperties() const +{ + static props imapProps = + { + // IMAP-specific options +#if VMIME_HAVE_SASL_SUPPORT + property("options.sasl", serviceInfos::property::TYPE_BOOL, "true"), + property("options.sasl.fallback", serviceInfos::property::TYPE_BOOL, "true"), +#endif // VMIME_HAVE_SASL_SUPPORT + + // Common properties + property(serviceInfos::property::AUTH_USERNAME, serviceInfos::property::FLAG_REQUIRED), + property(serviceInfos::property::AUTH_PASSWORD, serviceInfos::property::FLAG_REQUIRED), + +#if VMIME_HAVE_TLS_SUPPORT + property(serviceInfos::property::CONNECTION_TLS), + property(serviceInfos::property::CONNECTION_TLS_REQUIRED), +#endif // VMIME_HAVE_TLS_SUPPORT + + property(serviceInfos::property::SERVER_ADDRESS, serviceInfos::property::FLAG_REQUIRED), + property(serviceInfos::property::SERVER_PORT, "143"), + property(serviceInfos::property::SERVER_SOCKETFACTORY), + + property(serviceInfos::property::TIMEOUT_FACTORY) + }; + + static props imapsProps = + { + // IMAP-specific options +#if VMIME_HAVE_SASL_SUPPORT + property("options.sasl", serviceInfos::property::TYPE_BOOL, "true"), + property("options.sasl.fallback", serviceInfos::property::TYPE_BOOL, "true"), +#endif // VMIME_HAVE_SASL_SUPPORT + + // Common properties + property(serviceInfos::property::AUTH_USERNAME, serviceInfos::property::FLAG_REQUIRED), + property(serviceInfos::property::AUTH_PASSWORD, serviceInfos::property::FLAG_REQUIRED), + +#if VMIME_HAVE_TLS_SUPPORT + property(serviceInfos::property::CONNECTION_TLS), + property(serviceInfos::property::CONNECTION_TLS_REQUIRED), +#endif // VMIME_HAVE_TLS_SUPPORT + + property(serviceInfos::property::SERVER_ADDRESS, serviceInfos::property::FLAG_REQUIRED), + property(serviceInfos::property::SERVER_PORT, "993"), + property(serviceInfos::property::SERVER_SOCKETFACTORY), + + property(serviceInfos::property::TIMEOUT_FACTORY) + }; + + return m_imaps ? imapsProps : imapProps; +} + + +const std::vector <serviceInfos::property> IMAPServiceInfos::getAvailableProperties() const +{ + std::vector <property> list; + const props& p = getProperties(); + + // IMAP-specific options +#if VMIME_HAVE_SASL_SUPPORT + list.push_back(p.PROPERTY_OPTIONS_SASL); + list.push_back(p.PROPERTY_OPTIONS_SASL_FALLBACK); +#endif // VMIME_HAVE_SASL_SUPPORT + + // Common properties + list.push_back(p.PROPERTY_AUTH_USERNAME); + list.push_back(p.PROPERTY_AUTH_PASSWORD); + +#if VMIME_HAVE_TLS_SUPPORT + if (!m_imaps) + { + list.push_back(p.PROPERTY_CONNECTION_TLS); + list.push_back(p.PROPERTY_CONNECTION_TLS_REQUIRED); + } +#endif // VMIME_HAVE_TLS_SUPPORT + + list.push_back(p.PROPERTY_SERVER_ADDRESS); + list.push_back(p.PROPERTY_SERVER_PORT); + list.push_back(p.PROPERTY_SERVER_SOCKETFACTORY); + + list.push_back(p.PROPERTY_TIMEOUT_FACTORY); + + return list; +} + + +} // imap +} // net +} // vmime + diff --git a/src/net/imap/IMAPStore.cpp b/src/net/imap/IMAPStore.cpp index d4f18e7c..95f96276 100644 --- a/src/net/imap/IMAPStore.cpp +++ b/src/net/imap/IMAPStore.cpp @@ -32,8 +32,8 @@ namespace net { namespace imap { -IMAPStore::IMAPStore(ref <session> sess, ref <security::authenticator> auth) - : store(sess, getInfosInstance(), auth), m_connection(NULL) +IMAPStore::IMAPStore(ref <session> sess, ref <security::authenticator> auth, const bool secured) + : store(sess, getInfosInstance(), auth), m_connection(NULL), m_secured(secured) { } @@ -91,6 +91,12 @@ const bool IMAPStore::isValidFolderName(const folder::path::component& /* name * } +const bool IMAPStore::isSecuredConnection() const +{ + return m_secured; +} + + void IMAPStore::connect() { if (isConnected()) @@ -189,78 +195,21 @@ const int IMAPStore::getCapabilities() const // Service infos -IMAPStore::_infos IMAPStore::sm_infos; +IMAPServiceInfos IMAPStore::sm_infos(false); const serviceInfos& IMAPStore::getInfosInstance() { - return (sm_infos); + return sm_infos; } const serviceInfos& IMAPStore::getInfos() const { - return (sm_infos); -} - - -const string IMAPStore::_infos::getPropertyPrefix() const -{ - return "store.imap."; + return sm_infos; } -const IMAPStore::_infos::props& IMAPStore::_infos::getProperties() const -{ - static props p = - { - // IMAP-specific options -#if VMIME_HAVE_SASL_SUPPORT - property("options.sasl", serviceInfos::property::TYPE_BOOL, "true"), - property("options.sasl.fallback", serviceInfos::property::TYPE_BOOL, "true"), -#endif // VMIME_HAVE_SASL_SUPPORT - - // Common properties - property(serviceInfos::property::AUTH_USERNAME, serviceInfos::property::FLAG_REQUIRED), - property(serviceInfos::property::AUTH_PASSWORD, serviceInfos::property::FLAG_REQUIRED), - - property(serviceInfos::property::SERVER_ADDRESS, serviceInfos::property::FLAG_REQUIRED), - property(serviceInfos::property::SERVER_PORT, "143"), - property(serviceInfos::property::SERVER_SOCKETFACTORY), - - property(serviceInfos::property::TIMEOUT_FACTORY) - }; - - return p; -} - - -const std::vector <serviceInfos::property> IMAPStore::_infos::getAvailableProperties() const -{ - std::vector <property> list; - const props& p = getProperties(); - - // IMAP-specific options -#if VMIME_HAVE_SASL_SUPPORT - list.push_back(p.PROPERTY_OPTIONS_SASL); - list.push_back(p.PROPERTY_OPTIONS_SASL_FALLBACK); -#endif // VMIME_HAVE_SASL_SUPPORT - - // Common properties - list.push_back(p.PROPERTY_AUTH_USERNAME); - list.push_back(p.PROPERTY_AUTH_PASSWORD); - - list.push_back(p.PROPERTY_SERVER_ADDRESS); - list.push_back(p.PROPERTY_SERVER_PORT); - list.push_back(p.PROPERTY_SERVER_SOCKETFACTORY); - - list.push_back(p.PROPERTY_TIMEOUT_FACTORY); - - return (list); -} - - - } // imap } // net } // vmime |