From 95ed6b3c0b3b10a8b59730459084906108bb6dcd Mon Sep 17 00:00:00 2001 From: "Bruno G. Albuquerque" Date: Tue, 8 Sep 2009 23:00:36 +0000 Subject: [PATCH] Patch by ArCePi. - Implements STARTTLS support to the SMTP add-on. - Untested, but implementation matches RFC. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33012 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../outbound_protocols/smtp/smtp.cpp | 53 ++++++++++++++++++- .../outbound_protocols/smtp/smtp.h | 1 + 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/add-ons/mail_daemon/outbound_protocols/smtp/smtp.cpp b/src/add-ons/mail_daemon/outbound_protocols/smtp/smtp.cpp index e96a3dc8d8..8386dbae76 100644 --- a/src/add-ons/mail_daemon/outbound_protocols/smtp/smtp.cpp +++ b/src/add-ons/mail_daemon/outbound_protocols/smtp/smtp.cpp @@ -358,6 +358,7 @@ SMTPProtocol::Open(const char *address, int port, bool esmtp) #ifdef USE_SSL use_ssl = (fSettings->FindInt32("flavor") == 1); + use_STARTTLS = (fSettings->FindInt32("flavor") == 2); ssl = NULL; ctx = NULL; #endif @@ -458,8 +459,57 @@ SMTPProtocol::Open(const char *address, int port, bool esmtp) return B_ERROR; } - delete[] cmd; + + + #ifdef USE_SSL + // Check for STARTTLS + if(use_STARTTLS) + { + const char *res = fLog.String(); + char *p; + + SSL_library_init(); + RAND_seed(this,sizeof(SMTPProtocol)); + ::sprintf(cmd, "STARTTLS"CRLF); + + if ((p = ::strstr(res, "STARTTLS")) != NULL) + { + // Server advertises STARTTLS support + if(SendCommand(cmd) != B_OK) + { + delete[] cmd; + return B_ERROR; + } + + // We should start TLS negotiation + use_ssl = true; + ctx = SSL_CTX_new(TLSv1_method()); + ssl = SSL_new(ctx); + sbio = BIO_new_socket(_fd,BIO_NOCLOSE); + BIO_set_nbio(sbio, 0); + SSL_set_bio(ssl, sbio, sbio); + SSL_set_connect_state(ssl); + if(SSL_do_handshake(ssl) != 1) + return B_ERROR; + + // Should send EHLO command again + if(!esmtp) + ::sprintf(cmd, "HELO %s"CRLF, localhost); + else + ::sprintf(cmd, "EHLO %s"CRLF, localhost); + + if(SendCommand(cmd) != B_OK) + { + delete[] cmd; + return B_ERROR; + } + } + } + #endif + + delete[] cmd; + // Check auth type if (esmtp) { const char *res = fLog.String(); @@ -1055,6 +1105,7 @@ instantiate_config_panel(BMessage *settings, BMessage *) B_MAIL_PROTOCOL_HAS_FLAVORS); view->AddFlavor("Unencrypted"); view->AddFlavor("SSL"); + view->AddFlavor("STARTTLS"); #else BMailProtocolConfigView *view = new BMailProtocolConfigView(B_MAIL_PROTOCOL_HAS_AUTH_METHODS | B_MAIL_PROTOCOL_HAS_USERNAME | diff --git a/src/add-ons/mail_daemon/outbound_protocols/smtp/smtp.h b/src/add-ons/mail_daemon/outbound_protocols/smtp/smtp.h index 57d1989d2a..7141951c96 100644 --- a/src/add-ons/mail_daemon/outbound_protocols/smtp/smtp.h +++ b/src/add-ons/mail_daemon/outbound_protocols/smtp/smtp.h @@ -51,6 +51,7 @@ class SMTPProtocol : public BMailFilter { BIO *sbio; bool use_ssl; + bool use_STARTTLS; #endif status_t fStatus;