diff options
Diffstat (limited to 'examples/example6.cpp')
-rw-r--r-- | examples/example6.cpp | 259 |
1 files changed, 41 insertions, 218 deletions
diff --git a/examples/example6.cpp b/examples/example6.cpp index 95019c03..5d8c7e64 100644 --- a/examples/example6.cpp +++ b/examples/example6.cpp @@ -31,178 +31,17 @@ #include "vmime/vmime.hpp" #include "vmime/platforms/posix/posixHandler.hpp" +#include "example6_tracer.hpp" +#include "example6_authenticator.hpp" +#include "example6_certificateVerifier.hpp" +#include "example6_timeoutHandler.hpp" + // Global session object static vmime::shared_ptr <vmime::net::session> g_session = vmime::make_shared <vmime::net::session>(); -#if VMIME_HAVE_SASL_SUPPORT - -// SASL authentication handler -class interactiveAuthenticator : public vmime::security::sasl::defaultSASLAuthenticator -{ - const std::vector <vmime::shared_ptr <vmime::security::sasl::SASLMechanism> > getAcceptableMechanisms - (const std::vector <vmime::shared_ptr <vmime::security::sasl::SASLMechanism> >& available, - vmime::shared_ptr <vmime::security::sasl::SASLMechanism> suggested) const - { - std::cout << std::endl << "Available SASL mechanisms:" << std::endl; - - for (unsigned int i = 0 ; i < available.size() ; ++i) - { - std::cout << " " << available[i]->getName(); - - if (suggested && available[i]->getName() == suggested->getName()) - std::cout << "(suggested)"; - } - - std::cout << std::endl << std::endl; - - return defaultSASLAuthenticator::getAcceptableMechanisms(available, suggested); - } - - void setSASLMechanism(vmime::shared_ptr <vmime::security::sasl::SASLMechanism> mech) - { - std::cout << "Trying '" << mech->getName() << "' authentication mechanism" << std::endl; - - defaultSASLAuthenticator::setSASLMechanism(mech); - } - - const vmime::string getUsername() const - { - if (m_username.empty()) - m_username = getUserInput("Username"); - - return m_username; - } - - const vmime::string getPassword() const - { - if (m_password.empty()) - m_password = getUserInput("Password"); - - return m_password; - } - - static const vmime::string getUserInput(const std::string& prompt) - { - std::cout << prompt << ": "; - std::cout.flush(); - - vmime::string res; - std::getline(std::cin, res); - - return res; - } - -private: - - mutable vmime::string m_username; - mutable vmime::string m_password; -}; - -#else // !VMIME_HAVE_SASL_SUPPORT - -// Simple authentication handler -class interactiveAuthenticator : public vmime::security::defaultAuthenticator -{ - const vmime::string getUsername() const - { - if (m_username.empty()) - m_username = getUserInput("Username"); - - return m_username; - } - - const vmime::string getPassword() const - { - if (m_password.empty()) - m_password = getUserInput("Password"); - - return m_password; - } - - static const vmime::string getUserInput(const std::string& prompt) - { - std::cout << prompt << ": "; - std::cout.flush(); - - vmime::string res; - std::getline(std::cin, res); - - return res; - } - -private: - - mutable vmime::string m_username; - mutable vmime::string m_password; -}; - -#endif // VMIME_HAVE_SASL_SUPPORT - - -#if VMIME_HAVE_TLS_SUPPORT - -// Certificate verifier (TLS/SSL) -class interactiveCertificateVerifier : public vmime::security::cert::defaultCertificateVerifier -{ -public: - - void verify(vmime::shared_ptr <vmime::security::cert::certificateChain> chain, const vmime::string& hostname) - { - try - { - setX509TrustedCerts(m_trustedCerts); - - defaultCertificateVerifier::verify(chain, hostname); - } - catch (vmime::exceptions::certificate_verification_exception&) - { - // Obtain subject's certificate - vmime::shared_ptr <vmime::security::cert::certificate> cert = chain->getAt(0); - - std::cout << std::endl; - std::cout << "Server sent a '" << cert->getType() << "'" << " certificate." << std::endl; - std::cout << "Do you want to accept this certificate? (Y/n) "; - std::cout.flush(); - - std::string answer; - std::getline(std::cin, answer); - - if (answer.length() != 0 && - (answer[0] == 'Y' || answer[0] == 'y')) - { - // Accept it, and remember user's choice for later - if (cert->getType() == "X.509") - { - m_trustedCerts.push_back(vmime::dynamicCast - <vmime::security::cert::X509Certificate>(cert)); - - setX509TrustedCerts(m_trustedCerts); - defaultCertificateVerifier::verify(chain, hostname); - } - - return; - } - - throw vmime::exceptions::certificate_verification_exception - ("User did not accept the certificate."); - } - } - -private: - - static std::vector <vmime::shared_ptr <vmime::security::cert::X509Certificate> > m_trustedCerts; -}; - - -std::vector <vmime::shared_ptr <vmime::security::cert::X509Certificate> > - interactiveCertificateVerifier::m_trustedCerts; - -#endif // VMIME_HAVE_TLS_SUPPORT - - /** Returns the messaging protocols supported by VMime. * * @param type service type (vmime::net::service::TYPE_STORE or @@ -290,53 +129,6 @@ static std::ostream& operator<<(std::ostream& os, const vmime::exception& e) } -/** Time out handler. - * Used to stop the current operation after too much time, or if the user - * requested cancellation. - */ -class timeoutHandler : public vmime::net::timeoutHandler -{ -public: - - bool isTimeOut() - { - // This is a cancellation point: return true if you want to cancel - // the current operation. If you return true, handleTimeOut() will - // be called just after this, and before actually cancelling the - // operation - return false; - } - - void resetTimeOut() - { - // Called at the beginning of an operation (eg. connecting, - // a read() or a write() on a socket...) - } - - bool handleTimeOut() - { - // If isTimeOut() returned true, this function will be called. This - // allows you to interact with the user, ie. display a prompt to - // know whether he wants to cancel the operation. - - // If you return true here, the operation will be actually cancelled. - // If not, the time out is reset and the operation continues. - return true; - } -}; - - -class timeoutHandlerFactory : public vmime::net::timeoutHandlerFactory -{ -public: - - vmime::shared_ptr <vmime::net::timeoutHandler> create() - { - return vmime::make_shared <timeoutHandler>(); - } -}; - - /** Print the MIME structure of a message on the standard output. * * @param s structure object @@ -445,8 +237,12 @@ static void sendMessage() vmime::utility::url url(urlString); - vmime::shared_ptr <vmime::net::transport> tr = - g_session->getTransport(url, vmime::make_shared <interactiveAuthenticator>()); + vmime::shared_ptr <vmime::net::transport> tr; + + if (url.getUsername().empty() || url.getPassword().empty()) + tr = g_session->getTransport(url, vmime::make_shared <interactiveAuthenticator>()); + else + tr = g_session->getTransport(url); #if VMIME_HAVE_TLS_SUPPORT @@ -465,7 +261,12 @@ static void sendMessage() // You can also set some properties (see example7 to know the properties // available for each service). For example, for SMTP: -// tr->setProperty("options.need-authentication", true); + if (!url.getUsername().empty() || !url.getPassword().empty()) + tr->setProperty("options.need-authentication", true); + + // Trace communication between client and server + vmime::shared_ptr <std::ostringstream> traceStream = vmime::make_shared <std::ostringstream>(); + tr->setTracerFactory(vmime::make_shared <myTracerFactory>(traceStream)); // Information about the mail std::cout << "Enter email of the expeditor (eg. [email protected]): "; @@ -520,6 +321,12 @@ static void sendMessage() // ... // tr->send(&msg); + // Display connection log + std::cout << std::endl; + std::cout << "Connection Trace:" << std::endl; + std::cout << "=================" << std::endl; + std::cout << traceStream->str(); + tr->disconnect(); } catch (vmime::exception& e) @@ -580,6 +387,10 @@ static void connectStore() #endif // VMIME_HAVE_TLS_SUPPORT + // Trace communication between client and server + vmime::shared_ptr <std::ostringstream> traceStream = vmime::make_shared <std::ostringstream>(); + st->setTracerFactory(vmime::make_shared <myTracerFactory>(traceStream)); + // Connect to the mail store st->connect(); @@ -621,6 +432,7 @@ static void connectStore() choices.push_back("Change folder"); choices.push_back("Add message (to the current folder)"); choices.push_back("Copy message (into the current folder)"); + choices.push_back("Display trace output"); choices.push_back("Return to main menu"); const int choice = printMenu(choices); @@ -928,9 +740,18 @@ static void connectStore() break; } - // Main menu + // Display trace output case 12: + std::cout << std::endl; + std::cout << "Connection Trace:" << std::endl; + std::cout << "=================" << std::endl; + std::cout << traceStream->str(); + break; + + // Main menu + case 13: + f->close(true); // 'true' to expunge deleted messages cont = false; break; @@ -979,7 +800,9 @@ static void connectStore() std::cerr << std::endl; std::cerr << "std::exception: " << e.what() << std::endl; } - } + } // for(cont) + + st->disconnect(); } catch (vmime::exception& e) { |