From 17c3e8818f544a89c845331886c322049c7d2fa6 Mon Sep 17 00:00:00 2001 From: pdmef Date: Thu, 11 Aug 2005 15:22:45 +0000 Subject: [PATCH] Rocco Rutte: - add StartTLS support via libESMTP, thanks to a patch by Christian Gall (slightly edited) git-svn-id: svn://svn.berlios.de/mutt-ng/trunk@389 e385b8ad-14ed-0310-8656-cc95a2468c6d --- ChangeLog | 4 +++ UPGRADING | 4 ++- globals.h | 1 + init.h | 11 ++++++ mutt_libesmtp.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 110 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1fd2cfe..0e0ffcc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ Changes specific to mutt-ng: +2005-08-11: + * Christian Gall kindly contributed a patch to add support + for using TLS via the libESMTP library + 2005-07-24: * restoring xterm's title is possible (with some shell magic, see manual) diff --git a/UPGRADING b/UPGRADING index ffcbba2..0e22ced 100644 --- a/UPGRADING +++ b/UPGRADING @@ -12,7 +12,9 @@ sources of information. 2005-08-11: - The $imap_check_subscribed option has been added. + The $smtp_use_tls option has been added. + + The $imap_check_subscribed option has been added in muttng and mutt. 2005-08-08: diff --git a/globals.h b/globals.h index 0626062..593a76f 100644 --- a/globals.h +++ b/globals.h @@ -146,6 +146,7 @@ WHERE char *SmtpAuthUser; WHERE char *SmtpAuthPass; WHERE char *SmtpHost; WHERE unsigned short SmtpPort; +WHERE char *SmtpUseTLS; #endif WHERE char *Spoolfile; WHERE char *SpamSep; diff --git a/init.h b/init.h index 4ff0020..9f04305 100644 --- a/init.h +++ b/init.h @@ -2388,6 +2388,17 @@ struct option_t MuttVars[] = { ** Defaults to 25, the standard SMTP port, but RFC 2476-compliant SMTP ** servers will probably desire 587, the mail submission port. */ + {"smtp_use_tls", DT_STR, R_NONE, UL &SmtpUseTLS, 0}, + /* + ** .pp + ** Availability: SMTP + ** + ** .pp + ** Defines wether to use STARTTLS. If this option is set to ``required'' + ** and the server does not support STARTTLS or there is an error in the + ** TLS Handshake, the connection will fail. Setting this to ``enabled'' + ** will try to start TLS and continue without TLS in case of an error. + */ #endif #if defined(USE_SSL) || defined(USE_GNUTLS) #ifdef USE_SSL diff --git a/mutt_libesmtp.c b/mutt_libesmtp.c index 93bfd96..37b4f88 100644 --- a/mutt_libesmtp.c +++ b/mutt_libesmtp.c @@ -11,12 +11,19 @@ #endif #include "mutt.h" +#include "ascii.h" +#include "enter.h" #include "lib/mem.h" #include "lib/intl.h" #include "lib/str.h" +#if defined (USE_SSL) || (defined (USE_GNUTLS) && defined (HAVE_GNUTLS_OPENSSL_H)) +#include +#endif + #include + #include #include @@ -118,7 +125,8 @@ _mutt_libesmtp_auth_interact (auth_client_request_t request, snprintf (prompt, sizeof (prompt), "%s%s: ", request[i].prompt, (request[i]. flags & AUTH_CLEARTEXT) ? " (not encrypted)" : ""); - mutt_get_password (prompt, authpass, sizeof (authpass)); + mutt_get_field_unbuffered (prompt, authpass, sizeof (authpass), + M_PASS); } result[i] = authpass; } @@ -160,6 +168,71 @@ static const char *_mutt_libesmtp_messagefp_cb (void **buf, int *len, return *buf; } +#if defined (USE_SSL) || (defined (USE_GNUTLS) && defined (HAVE_GNUTLS_OPENSSL_H)) +static int handle_invalid_peer_certificate (long vfy_result) { + mutt_error (_("Error verifying certificate: %s"), + NONULL (X509_verify_cert_error_string (vfy_result))); + sleep(2); + return 1; /* Accept the problem */ +} +#endif + +void event_cb (smtp_session_t session, int event_no, void *arg,...) +{ + va_list alist; + int *ok; + + va_start(alist, arg); + switch(event_no) { + case SMTP_EV_CONNECT: + case SMTP_EV_MAILSTATUS: + case SMTP_EV_RCPTSTATUS: + case SMTP_EV_MESSAGEDATA: + case SMTP_EV_MESSAGESENT: + case SMTP_EV_DISCONNECT: break; + case SMTP_EV_WEAK_CIPHER: { + int bits; + bits = va_arg(alist, long); ok = va_arg(alist, int*); + mutt_message (_("SMTP_EV_WEAK_CIPHER, bits=%d - accepted."), bits); + sleep(1); + *ok = 1; break; + } + case SMTP_EV_STARTTLS_OK: + mutt_message (_("Using TLS")); + sleep(1); + break; + case SMTP_EV_INVALID_PEER_CERTIFICATE: { + long vfy_result; + vfy_result = va_arg(alist, long); ok = va_arg(alist, int*); + *ok = handle_invalid_peer_certificate(vfy_result); + sleep(1); + break; + } + case SMTP_EV_NO_PEER_CERTIFICATE: { + ok = va_arg(alist, int*); + mutt_message (_("SMTP_EV_NO_PEER_CERTIFICATE - accepted.")); + sleep(1); + *ok = 1; break; + } + case SMTP_EV_WRONG_PEER_CERTIFICATE: { + ok = va_arg(alist, int*); + mutt_message (_("SMTP_EV_WRONG_PEER_CERTIFICATE - accepted.")); + sleep(1); + *ok = 1; break; + } + case SMTP_EV_NO_CLIENT_CERTIFICATE: { + ok = va_arg(alist, int*); + mutt_message (_("SMTP_EV_NO_CLIENT_CERTIFICATE - accepted.")); + sleep(1); + *ok = 1; break; + } + default: + mutt_message(_("Got event: %d - ignored."), event_no); + sleep(1); + } + va_end(alist); +} + /* * mutt_invoke_libesmtp * Sends a mail message to the provided recipients using libesmtp. @@ -185,6 +258,14 @@ int mutt_invoke_libesmtp (ADDRESS * from, /* the sender */ if ((session = smtp_create_session ()) == NULL) SMTPFAIL ("smtp_create_session"); +#if defined (USE_SSL) || (defined (USE_GNUTLS) && defined (HAVE_GNUTLS_OPENSSL_H)) + if (SmtpUseTLS != NULL && ascii_strncasecmp("enabled", SmtpUseTLS, 7) == 0) { + smtp_starttls_enable(session, Starttls_ENABLED); + } else if (SmtpUseTLS != NULL && ascii_strncasecmp("required", SmtpUseTLS, 8) == 0) { + smtp_starttls_enable(session, Starttls_REQUIRED); + } +#endif + /* Create hostname:port string and tell libesmtp */ /* len = SmtpHost len + colon + max port (65536 => 5 chars) + terminator */ hostportlen = str_len (SmtpHost) + 7; @@ -196,13 +277,22 @@ int mutt_invoke_libesmtp (ADDRESS * from, /* the sender */ if (SmtpAuthUser) { if ((authctx = auth_create_context ()) == NULL) MSGFAIL ("auth_create_context failed"); +#if defined (USE_SSL) || (defined (USE_GNUTLS) && defined (HAVE_GNUTLS_OPENSSL_H)) + auth_set_mechanism_flags (authctx, AUTH_PLUGIN_EXTERNAL, 0); +#else auth_set_mechanism_flags (authctx, AUTH_PLUGIN_PLAIN, 0); +#endif auth_set_interact_cb (authctx, _mutt_libesmtp_auth_interact, NULL); if (!smtp_auth_set_context (session, authctx)) SMTPFAIL ("smtp_auth_set_context"); } +#if defined (USE_SSL) || (defined (USE_GNUTLS) && defined (HAVE_GNUTLS_OPENSSL_H)) + smtp_starttls_set_ctx (session, NULL); +#endif + smtp_set_eventcb (session, event_cb, NULL); + if ((message = smtp_add_message (session)) == NULL) SMTPFAIL ("smtp_add_message"); /* Initialize envelope sender */ -- 2.20.1