diff options
-rw-r--r-- | mutt_socket.c | 30 | ||||
-rw-r--r-- | mutt_socket.h | 2 | ||||
-rw-r--r-- | mutt_ssl.c | 12 | ||||
-rw-r--r-- | mutt_ssl_gnutls.c | 12 |
4 files changed, 56 insertions, 0 deletions
diff --git a/mutt_socket.c b/mutt_socket.c index 83d8ddf7..5a2800b8 100644 --- a/mutt_socket.c +++ b/mutt_socket.c @@ -129,6 +129,36 @@ int mutt_socket_write_d (CONNECTION *conn, const char *buf, int len, int dbg) return sent; } +/* Checks if the CONNECTION input buffer has unread data. + * + * NOTE: for general use, the function needs to expand to poll nested + * connections. It currently does not to make backporting a security + * fix easier. + * + * STARTTLS occurs before SASL and COMPRESS=DEFLATE processing, and + * mutt_tunnel() does not wrap the connection. So this and the next + * function are safe for current usage in mutt_ssl_starttls(). + */ +int mutt_socket_has_buffered_input (CONNECTION *conn) +{ + return conn->bufpos < conn->available; +} + +/* Clears buffered input from a connection. + * + * NOTE: for general use, the function needs to expand to call nested + * connections. It currently does not to make backporting a security + * fix easier. + * + * STARTTLS occurs before SASL and COMPRESS=DEFLATE processing, and + * mutt_tunnel() does not wrap the connection. So this and the previous + * function are safe for current usage in mutt_ssl_starttls(). + */ +void mutt_socket_clear_buffered_input (CONNECTION *conn) +{ + conn->bufpos = conn->available = 0; +} + /* poll whether reads would block. * Returns: >0 if there is data to read, * 0 if a read would block, diff --git a/mutt_socket.h b/mutt_socket.h index 68f158e0..b0b27ee8 100644 --- a/mutt_socket.h +++ b/mutt_socket.h @@ -53,6 +53,8 @@ typedef struct _connection int mutt_socket_open (CONNECTION* conn); int mutt_socket_close (CONNECTION* conn); +int mutt_socket_has_buffered_input (CONNECTION *conn); +void mutt_socket_clear_buffered_input (CONNECTION *conn); int mutt_socket_poll (CONNECTION* conn, time_t wait_secs); int mutt_socket_readchar (CONNECTION *conn, char *c); #define mutt_socket_readln(A,B,C) mutt_socket_readln_d(A,B,C,MUTT_SOCK_LOG_CMD) @@ -199,6 +199,18 @@ int mutt_ssl_starttls (CONNECTION* conn) int maxbits; long ssl_options = 0; + if (mutt_socket_has_buffered_input (conn)) + { + /* L10N: + The server is not supposed to send data immediately after + confirming STARTTLS. This warns the user that something + weird is going on. + */ + mutt_error _("Warning: clearing unexpected buffered data before STARTTLS"); + mutt_sleep (0); + mutt_socket_clear_buffered_input (conn); + } + if (ssl_init()) goto bail; diff --git a/mutt_ssl_gnutls.c b/mutt_ssl_gnutls.c index 693311f9..3eb276d5 100644 --- a/mutt_ssl_gnutls.c +++ b/mutt_ssl_gnutls.c @@ -218,6 +218,18 @@ static int tls_socket_open (CONNECTION* conn) int mutt_ssl_starttls (CONNECTION* conn) { + if (mutt_socket_has_buffered_input (conn)) + { + /* L10N: + The server is not supposed to send data immediately after + confirming STARTTLS. This warns the user that something + weird is going on. + */ + mutt_error _("Warning: clearing unexpected buffered data before STARTTLS"); + mutt_sleep (0); + mutt_socket_clear_buffered_input (conn); + } + if (tls_init() < 0) return -1; |