From c3c106aceaf735c80d71b8bfc1c9927d39ed587e Mon Sep 17 00:00:00 2001 From: Matthias Andree Date: Wed, 8 Apr 2015 01:50:47 +0200 Subject: Detect/report server hang-up in SSL_connect(). This condition does not leave traces in the SSL error queue, and must be checked explicitly. Result from debugging Jerry Seibert's issue with outlook.com/pop3.live.com. --- NEWS | 5 ++++- socket.c | 13 ++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 8911d990..905c2566 100644 --- a/NEWS +++ b/NEWS @@ -81,10 +81,13 @@ fetchmail-6.4.0 (not yet released): tls1.2+ (case insensitively). ## CHANGES +* fetchmail 6.3.X is unsupported. * Fetchmail now supports --sslproto auto and --sslproto tls1+ (same as ssl23). * --sslproto tls1.1+ and tls1.2+ are now supported for auto-negotiation with a minimum specified TLS protocol version. -* fetchmail 6.3.X is unsupported. +* Fetchmail now detects if the server hangs up prematurely during SSL_connect() + and reports this condition as such, and not just as SSL connection failure. + (OpenSSL 1.0.2 reported incompatible with pop3.live.com by Jerry Seibert). ## FIXES * Fix a typo in the FAQ. Submitted by David Lawyer, Debian Bug#706776. diff --git a/socket.c b/socket.c index 5b25ac08..5ed62546 100644 --- a/socket.c +++ b/socket.c @@ -878,6 +878,7 @@ int SSLOpen(int sock, char *mycert, char *mykey, const char *myproto, int certck int i; int avoid_ssl_versions = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; long sslopts = SSL_OP_ALL; + int ssle_connect = 0; SSL_load_error_strings(); SSL_library_init(); @@ -1019,8 +1020,18 @@ int SSLOpen(int sock, char *mycert, char *mykey, const char *myproto, int certck } if (SSL_set_fd(_ssl_context[sock], sock) == 0 - || SSL_connect(_ssl_context[sock]) < 1) { + || (ssle_connect = SSL_connect(_ssl_context[sock])) < 1) { + int e = errno; + unsigned long ssle_err_from_queue = ERR_peek_error(); + unsigned long ssle_err_from_get_error = SSL_get_error(_ssl_context[sock], ssle_connect); ERR_print_errors_fp(stderr); + if (SSL_ERROR_SYSCALL == ssle_err_from_get_error && 0 == ssle_err_from_queue) { + if (0 == ssle_connect) { + report(stderr, GT_("Server shut down connection prematurely during SSL_connect().\n")); + } else if (ssle_connect < 0) { + report(stderr, GT_("System error during SSL_connect(): %s\n"), strerror(e)); + } + } SSL_free( _ssl_context[sock] ); _ssl_context[sock] = NULL; SSL_CTX_free(_ctx[sock]); -- cgit v1.2.3