From eaa5da6e9ed90536d12d0a779b664ed4ff0cfa97 Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Wed, 21 Jun 2023 07:03:11 -0700 Subject: [PATCH] re-ehlo when using OpportunisticInsecure and STARTTLS failed We were previously only re-doing the EHLO in the success case, but there are some receiving implementations that seem to roll the TLS failure error forward, returning an error during MAIL FROM: ``` TLS connection failed: error:1408A0C1:SSL routines:ssl3_get_client_hello:no shared cipher (#4.3.0) ``` we want that error to show up while we're considering the connection, so that we can fail over to the next candidate in our list, rather than having it generate a transient failure for the message and stopping there. refs: https://github.com/KumoCorp/kumomta/issues/67 --- crates/kumod/src/smtp_dispatcher.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/crates/kumod/src/smtp_dispatcher.rs b/crates/kumod/src/smtp_dispatcher.rs index 68fdc61f..ea661925 100644 --- a/crates/kumod/src/smtp_dispatcher.rs +++ b/crates/kumod/src/smtp_dispatcher.rs @@ -230,7 +230,9 @@ impl QueueDispatcher for SmtpDispatcher { false } (Tls::OpportunisticInsecure, true) => { - if let Some(handshake_error) = client.starttls(enable_tls.allow_insecure()).await? { + let enabled = if let Some(handshake_error) = + client.starttls(enable_tls.allow_insecure()).await? + { tracing::debug!( "TLS handshake with {address:?}:{port} failed: \ {handshake_error}, but continuing in clear text because \ @@ -239,10 +241,15 @@ impl QueueDispatcher for SmtpDispatcher { // We did not enable TLS false } else { - client.ehlo(&ehlo_name).await.context("EHLO")?; // TLS is available true - } + }; + // Re-EHLO even if we didn't enable TLS, as some implementations + // incorrectly roll over failed TLS into the following command, + // and we want to consider those as connection errors rather than + // having them show up per-message in MAIL FROM + client.ehlo(&ehlo_name).await.context("EHLO")?; + enabled } (Tls::Opportunistic | Tls::Required | Tls::RequiredInsecure, true) => { if let Some(handshake_error) = client.starttls(enable_tls.allow_insecure()).await? {