From 0d7b37f8150bd8d668fbe92aca675b1a58b59e3c Mon Sep 17 00:00:00 2001 From: Brendan Cully Date: Sat, 24 Apr 2010 16:10:43 -0700 Subject: [PATCH] openssl: only call SSL_shutdown during clean shutdown (closes #3407) --- ChangeLog | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++- mutt_ssl.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 178 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 431d663e..024506f9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,98 @@ -2010-03-22 20:02 -0700 marcel (f544730656c1) +2010-04-22 09:14 -0700 Vincent Lefevre (6ebdfd09abc1) + + * po/fr.po: updated French translation + +2010-04-14 15:47 -0700 Michael Elkins (15b9d6f3284f) + + * pgp.c: remove toggle and replace with format in pgp-menu + +2010-04-12 15:13 -0500 David Champion (41a46373ddd9) + + * compose.c: Improve clarity/uniformity in compose menu's crypto + display + + Incorporates feedback on "Security: None" key hints. + +2010-04-13 06:49 -0700 Michael Elkins (4d798ee2898e) + + * muttlib.c: fix bug handling wide pad char in soft-fill mode + +2010-04-11 20:00 -0700 Michael Elkins (2cd62f40d840) + + * compose.c: increase size of buffer used for displaying addresses in + the compose menu to avoid truncating on widescreen displays + + * curs_lib.c: clear prompt when user cancels with ^G from a yes/no + prompt + + * muttlib.c: Fix bug in soft-fill (%*) in $index_format not accounting + for 'set arrow_cursor' + + * pgp.c: Remove the (i) option from the PGP-menu when encryption or + signing is not yet selected. The toggle between PGP/MIME and + Traditional doesn't make sense unless some type of security has been + requested. + + Closes #3402. + +2010-04-06 09:47 -0700 Michael Elkins (889aa698cc49) + + * configure.ac, muttlib.c: fix for compiling Mutt with clang: check + for wchar_h prior to wctype_h in check for wc funcs + +2010-04-05 11:12 -0700 Michael Elkins (844174efa648) + + * doc/manual.xml.head: [doc] Remove bogus -group parameter from + unlists and unsubscribe commands; add links to address group section + for context. + +2010-04-03 20:34 -0700 Michael Elkins (cf97505addf8) + + * init.c: prevent user from setting $charset to an empty string since + other code requires it to be set to a valid string + + closes #3326 + + * pager.c: allow regexps to match on continuation header lines in + 'color header' commands. + + closes #3373 + + * pattern.c: Fix crash on invalid regexp in search string due to + uninitialized BUFFER variable. + + Closes #3401 + +2010-04-01 10:10 -0700 Simon Ruderich (b9baa0234846) + + * attach.c, commands.c, filter.c, muttlib.c, send.c: fix comment typos + +2010-04-01 09:59 -0700 Michael Elkins (96ed7cdacdc6) + + * init.h: Improve documentation for $query_command to note that Mutt + automatically adds quotes according to shell quoting rules (thx: + Simon Ruderich). + + * doc/manual.xml.head: Clarify the documentation on what the line- + editor is (thx: Simon Ruderich) + +2010-03-31 08:50 -0700 Michael Elkins (7e9e31b1bd7b) + + * muttlib.c: avoid buffer overflow when expanding the format string + associated with a 'spam' command. + + closes #3397 + +2010-03-23 16:03 -0700 Michael Elkins (fe29d691deff) + + * doc/muttrc.man.head: remove errant commands in secton on setting + alternates + +2010-03-22 22:16 -0700 Brendan Cully (69e9a1a0ba2f) + + * sendlib.c: Fix a format string warning + +2010-03-22 20:02 -0700 Marcel Telka (f544730656c1) * compose.c: redraw entire screen when exiting editor after re-editing the message body in the send menu. diff --git a/mutt_ssl.c b/mutt_ssl.c index f66c0149..1a45672d 100644 --- a/mutt_ssl.c +++ b/mutt_ssl.c @@ -64,11 +64,12 @@ static int entropy_byte_count = 0; * open up another connection to the same server in this session */ static STACK_OF(X509) *SslSessionCerts = NULL; -typedef struct _sslsockdata +typedef struct { SSL_CTX *ctx; SSL *ssl; X509 *cert; + unsigned char isopen; } sslsockdata; @@ -80,6 +81,7 @@ static int ssl_socket_write (CONNECTION* conn, const char* buf, size_t len); static int ssl_socket_open (CONNECTION * conn); static int ssl_socket_close (CONNECTION * conn); static int tls_close (CONNECTION* conn); +static void ssl_err (sslsockdata *data, int err); static int ssl_cache_trusted_cert (X509 *cert); static int ssl_check_certificate (CONNECTION *conn, sslsockdata * data); static int interactive_check_cert (X509 *cert, int idx, int len); @@ -122,6 +124,8 @@ int mutt_ssl_starttls (CONNECTION* conn) if (ssl_negotiate (conn, ssldata)) goto bail_ssl; + ssldata->isopen = 1; + /* hmm. watch out if we're starting TLS over any method other than raw. */ conn->sockdata = ssldata; conn->conn_read = ssl_socket_read; @@ -257,13 +261,28 @@ int mutt_ssl_socket_setup (CONNECTION * conn) static int ssl_socket_read (CONNECTION* conn, char* buf, size_t len) { sslsockdata *data = conn->sockdata; - return SSL_read (data->ssl, buf, len); + int rc; + + rc = SSL_read (data->ssl, buf, len); + if (rc <= 0) + { + data->isopen = 0; + ssl_err (data, rc); + } + + return rc; } static int ssl_socket_write (CONNECTION* conn, const char* buf, size_t len) { sslsockdata *data = conn->sockdata; - return SSL_write (data->ssl, buf, len); + int rc; + + rc = SSL_write (data->ssl, buf, len); + if (rc <= 0) + ssl_err (data, rc); + + return rc; } static int ssl_socket_open (CONNECTION * conn) @@ -304,6 +323,8 @@ static int ssl_socket_open (CONNECTION * conn) return -1; } + data->isopen = 1; + conn->ssf = SSL_CIPHER_get_bits (SSL_get_current_cipher (data->ssl), &maxbits); @@ -366,7 +387,8 @@ static int ssl_socket_close (CONNECTION * conn) sslsockdata *data = conn->sockdata; if (data) { - SSL_shutdown (data->ssl); + if (data->isopen) + SSL_shutdown (data->ssl); /* hold onto this for the life of mutt, in case we want to reconnect. * The purist in me wants a mutt_exit hook. */ @@ -393,6 +415,63 @@ static int tls_close (CONNECTION* conn) return rc; } +static void ssl_err (sslsockdata *data, int err) +{ + const char* errmsg; + unsigned long sslerr; + + switch (SSL_get_error (data->ssl, err)) + { + case SSL_ERROR_NONE: + return; + case SSL_ERROR_ZERO_RETURN: + errmsg = "SSL connection closed"; + data->isopen = 0; + break; + case SSL_ERROR_WANT_READ: + errmsg = "retry read"; + break; + case SSL_ERROR_WANT_WRITE: + errmsg = "retry write"; + break; + case SSL_ERROR_WANT_CONNECT: + errmsg = "retry connect"; + break; + case SSL_ERROR_WANT_ACCEPT: + errmsg = "retry accept"; + break; + case SSL_ERROR_WANT_X509_LOOKUP: + errmsg = "retry x509 lookup"; + break; + case SSL_ERROR_SYSCALL: + errmsg = "I/O error"; + data->isopen = 0; + break; + case SSL_ERROR_SSL: + sslerr = ERR_get_error (); + switch (sslerr) + { + case 0: + switch (err) + { + case 0: + errmsg = "EOF"; + break; + default: + errmsg = strerror(errno); + } + break; + default: + errmsg = ERR_error_string (sslerr, NULL); + } + break; + default: + errmsg = "unknown error"; + } + + dprint (1, (debugfile, "SSL error: %s\n", errmsg)); +} + static char *x509_get_part (char *line, const char *ndx) { static char ret[SHORT_STRING]; -- 2.40.0