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);
/* peercert is set in peer_status() */
tlsp->peerdn = state->peerdn;
-tlsp->sni = state->received_sni;
+
+/* do not corrupt sni sent by client; record sni rxd by server */
+if (!state->host)
+ tlsp->sni = state->received_sni;
/* record our certificate */
{
/* If dane is flagged, have either request or require dane for this host, and
a TLSA record found. Therefore, dane verify required. Which implies cert must
be requested and supplied, dane verify must pass, and cert verify irrelevant
-(incl. hostnames), and (caller handled) require_tls */
+(incl. hostnames), and (caller handled) require_tls and sni=$domain */
if (conn_args->dane && ob->dane_require_tls_ciphers)
{
cipher_list, &state, tlsp, errstr) != OK)
return FALSE;
+
#ifdef MEASURE_TIMING
report_time_since(&t0, US"client tls_init (delta)");
#endif
sigalrm_seen = FALSE;
if (smtp_receive_timeout > 0) ALARM(smtp_receive_timeout);
+errno = 0;
do
inbytes = gnutls_record_recv(state->session, state->xfer_buffer,
MIN(ssl_xfer_buffer_size, lim));
debug_printf("Calling gnutls_record_recv(session=%p, buffer=%p, len=" SIZE_T_FMT ")\n",
state->session, buff, len);
+errno = 0;
do
inbytes = gnutls_record_recv(state->session, buff, len);
while (inbytes == GNUTLS_E_AGAIN);
DEBUG(D_tls) debug_printf("gnutls_record_send(session=%p, buffer=%p, left=" SIZE_T_FMT ")\n",
state->session, buff, left);
+ errno = 0;
do
outbytes = gnutls_record_send(state->session, buff, left);
while (outbytes == GNUTLS_E_AGAIN);
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)