From: Jeremy Harris Date: Sat, 25 Jul 2020 22:58:32 +0000 (+0100) Subject: GnuTLS: in server, detect TCP RST from client after QUIT under SSL, X-Git-Url: https://git.exim.org/users/heiko/exim.git/commitdiff_plain/f1e494e0021f2efbc346a24727b8ebc66733e4b2?ds=sidebyside GnuTLS: in server, detect TCP RST from client after QUIT under SSL, and log different message (under new log_selector) --- diff --git a/doc/doc-txt/experimental-spec.txt b/doc/doc-txt/experimental-spec.txt index e4a9301c3..47cd93f3d 100644 --- a/doc/doc-txt/experimental-spec.txt +++ b/doc/doc-txt/experimental-spec.txt @@ -672,7 +672,7 @@ Logging protocol unusual states An extra log_selector, "protocol_detail" has been added in the default build. The name may change in future, hence the Experimenal status. -Currrently the only effect is to enable logging, under OpenSSL, +Currrently the only effect is to enable logging, under TLS, of a TCP RST received directly after a QUIT (in server mode). Outlook is consistently doing this; not waiting for the SMTP response diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index 6308f10df..013d9c0e8 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -429,9 +429,7 @@ msg = rc == GNUTLS_E_FATAL_ALERT_RECEIVED US gnutls_alert_get_name(gnutls_alert_get(state->session))) #ifdef GNUTLS_E_PREMATURE_TERMINATION : rc == GNUTLS_E_PREMATURE_TERMINATION && errno - ? errno == ECONNRESET /* Outlook does this to us right after sending us QUIT */ - ? string_sprintf("syscall: %s", strerror(errno)) - : string_sprintf("%s: syscall: %s", US gnutls_strerror(rc), strerror(errno)) + ? string_sprintf("%s: syscall: %s", US gnutls_strerror(rc), strerror(errno)) #endif : US gnutls_strerror(rc); @@ -3396,8 +3394,24 @@ while (left > 0) if (outbytes < 0) { - DEBUG(D_tls) debug_printf("%s: gnutls_record_send err\n", __FUNCTION__); - record_io_error(state, outbytes, US"send", NULL); +#ifdef GNUTLS_E_PREMATURE_TERMINATION + if ( outbytes == GNUTLS_E_PREMATURE_TERMINATION && errno == ECONNRESET + && !ct_ctx && f.smtp_in_quit + ) + { /* Outlook, dammit */ + if (LOGGING(protocol_detail)) + log_write(0, LOG_MAIN, "[%s] after QUIT, client reset TCP before" + " SMTP response and TLS close\n", sender_host_address); + else + DEBUG(D_tls) debug_printf("[%s] SSL_write: after QUIT," + " client reset TCP before TLS close\n", sender_host_address); + } + else +#endif + { + DEBUG(D_tls) debug_printf("%s: gnutls_record_send err\n", __FUNCTION__); + record_io_error(state, outbytes, US"send", NULL); + } return -1; } if (outbytes == 0)