Permalink
Browse files

Connection trace facility.

  • Loading branch information...
1 parent cfe9c6b commit 84e570bbbb1188d2bcd3f03ff519fbc9217e624a @vincent-richard vincent-richard committed Mar 16, 2014
Showing with 810 additions and 287 deletions.
  1. +41 −218 examples/example6.cpp
  2. +106 −0 examples/example6_authenticator.hpp
  3. +62 −0 examples/example6_certificateVerifier.hpp
  4. +48 −0 examples/example6_timeoutHandler.hpp
  5. +53 −0 examples/example6_tracer.hpp
  6. +1 −1 src/vmime/net/imap/IMAPCommand.cpp
  7. +1 −1 src/vmime/net/imap/IMAPCommand.hpp
  8. +26 −0 src/vmime/net/imap/IMAPConnection.cpp
  9. +5 −0 src/vmime/net/imap/IMAPConnection.hpp
  10. +3 −0 src/vmime/net/imap/IMAPFolder.cpp
  11. +21 −0 src/vmime/net/imap/IMAPParser.hpp
  12. +27 −6 src/vmime/net/pop3/POP3Command.cpp
  13. +11 −2 src/vmime/net/pop3/POP3Command.hpp
  14. +18 −1 src/vmime/net/pop3/POP3Connection.cpp
  15. +3 −0 src/vmime/net/pop3/POP3Connection.hpp
  16. +1 −1 src/vmime/net/pop3/POP3Message.cpp
  17. +32 −8 src/vmime/net/pop3/POP3Response.cpp
  18. +4 −2 src/vmime/net/pop3/POP3Response.hpp
  19. +12 −0 src/vmime/net/service.cpp
  20. +7 −1 src/vmime/net/service.hpp
  21. +6 −0 src/vmime/net/smtp/SMTPChunkingOutputStreamAdapter.cpp
  22. +18 −5 src/vmime/net/smtp/SMTPCommand.cpp
  23. +13 −3 src/vmime/net/smtp/SMTPCommand.hpp
  24. +19 −4 src/vmime/net/smtp/SMTPCommandSet.cpp
  25. +2 −1 src/vmime/net/smtp/SMTPCommandSet.hpp
  26. +20 −3 src/vmime/net/smtp/SMTPConnection.cpp
  27. +3 −0 src/vmime/net/smtp/SMTPConnection.hpp
  28. +12 −4 src/vmime/net/smtp/SMTPResponse.cpp
  29. +7 −2 src/vmime/net/smtp/SMTPResponse.hpp
  30. +10 −4 src/vmime/net/smtp/SMTPTransport.cpp
  31. +72 −0 src/vmime/net/tracer.cpp
  32. +109 −0 src/vmime/net/tracer.hpp
  33. +16 −10 tests/net/smtp/SMTPCommandSetTest.cpp
  34. +3 −1 tests/net/smtp/SMTPCommandTest.cpp
  35. +18 −9 tests/net/smtp/SMTPResponseTest.cpp
View
@@ -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. me@somewhere.com): ";
@@ -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)
{
Oops, something went wrong.

0 comments on commit 84e570b

Please sign in to comment.