From bd83fb3d38bce1c0404b278d4e7c48bf2e09f336 Mon Sep 17 00:00:00 2001 From: link2xt Date: Wed, 10 Jul 2024 23:20:41 +0000 Subject: [PATCH] feat: set imap ALPN when connecting to IMAP servers IMAP has a registered protocol ID listed at Requesting specific ALPN on the client should allow the server to multiplex multiple protocols on the same port and dispatch requests to the correct backend on the proxy such as HAProxy. --- src/imap/client.rs | 8 ++++---- src/net/tls.rs | 10 ++++++---- src/smtp.rs | 8 ++++---- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/imap/client.rs b/src/imap/client.rs index 1bd546e74..db9c8e353 100644 --- a/src/imap/client.rs +++ b/src/imap/client.rs @@ -105,7 +105,7 @@ impl Client { strict_tls: bool, ) -> Result { let tcp_stream = connect_tcp(context, hostname, port, IMAP_TIMEOUT, strict_tls).await?; - let tls_stream = wrap_tls(strict_tls, hostname, tcp_stream).await?; + let tls_stream = wrap_tls(strict_tls, hostname, &["imap"], tcp_stream).await?; let buffered_stream = BufWriter::new(tls_stream); let session_stream: Box = Box::new(buffered_stream); let mut client = Client::new(session_stream); @@ -150,7 +150,7 @@ impl Client { let buffered_tcp_stream = client.into_inner(); let tcp_stream = buffered_tcp_stream.into_inner(); - let tls_stream = wrap_tls(strict_tls, hostname, tcp_stream) + let tls_stream = wrap_tls(strict_tls, hostname, &["imap"], tcp_stream) .await .context("STARTTLS upgrade failed")?; @@ -170,7 +170,7 @@ impl Client { let socks5_stream = socks5_config .connect(context, domain, port, IMAP_TIMEOUT, strict_tls) .await?; - let tls_stream = wrap_tls(strict_tls, domain, socks5_stream).await?; + let tls_stream = wrap_tls(strict_tls, domain, &["imap"], socks5_stream).await?; let buffered_stream = BufWriter::new(tls_stream); let session_stream: Box = Box::new(buffered_stream); let mut client = Client::new(session_stream); @@ -225,7 +225,7 @@ impl Client { let buffered_socks5_stream = client.into_inner(); let socks5_stream: Socks5Stream<_> = buffered_socks5_stream.into_inner(); - let tls_stream = wrap_tls(strict_tls, hostname, socks5_stream) + let tls_stream = wrap_tls(strict_tls, hostname, &["imap"], socks5_stream) .await .context("STARTTLS upgrade failed")?; let buffered_stream = BufWriter::new(tls_stream); diff --git a/src/net/tls.rs b/src/net/tls.rs index 7bb6badfe..b2080dba2 100644 --- a/src/net/tls.rs +++ b/src/net/tls.rs @@ -14,9 +14,10 @@ static LETSENCRYPT_ROOT: Lazy = Lazy::new(|| { .unwrap() }); -pub fn build_tls(strict_tls: bool) -> TlsConnector { +pub fn build_tls(strict_tls: bool, alpns: &[&str]) -> TlsConnector { let tls_builder = TlsConnector::new() .min_protocol_version(Some(Protocol::Tlsv12)) + .request_alpns(alpns) .add_root_certificate(LETSENCRYPT_ROOT.clone()); if strict_tls { @@ -31,9 +32,10 @@ pub fn build_tls(strict_tls: bool) -> TlsConnector { pub async fn wrap_tls( strict_tls: bool, hostname: &str, + alpns: &[&str], stream: T, ) -> Result> { - let tls = build_tls(strict_tls); + let tls = build_tls(strict_tls, alpns); let tls_stream = tls.connect(hostname, stream).await?; Ok(tls_stream) } @@ -46,7 +48,7 @@ mod tests { fn test_build_tls() { // we are using some additional root certificates. // make sure, they do not break construction of TlsConnector - let _ = build_tls(true); - let _ = build_tls(false); + let _ = build_tls(true, &[]); + let _ = build_tls(false, &[]); } } diff --git a/src/smtp.rs b/src/smtp.rs index af7e38873..ab9ce0685 100644 --- a/src/smtp.rs +++ b/src/smtp.rs @@ -120,7 +120,7 @@ impl Smtp { let socks5_stream = socks5_config .connect(context, hostname, port, SMTP_TIMEOUT, strict_tls) .await?; - let tls_stream = wrap_tls(strict_tls, hostname, socks5_stream).await?; + let tls_stream = wrap_tls(strict_tls, hostname, &[], socks5_stream).await?; let buffered_stream = BufStream::new(tls_stream); let session_stream: Box = Box::new(buffered_stream); let client = smtp::SmtpClient::new().smtp_utf8(true); @@ -144,7 +144,7 @@ impl Smtp { let client = smtp::SmtpClient::new().smtp_utf8(true); let transport = SmtpTransport::new(client, BufStream::new(socks5_stream)).await?; let tcp_stream = transport.starttls().await?.into_inner(); - let tls_stream = wrap_tls(strict_tls, hostname, tcp_stream) + let tls_stream = wrap_tls(strict_tls, hostname, &[], tcp_stream) .await .context("STARTTLS upgrade failed")?; let buffered_stream = BufStream::new(tls_stream); @@ -179,7 +179,7 @@ impl Smtp { strict_tls: bool, ) -> Result>> { let tcp_stream = connect_tcp(context, hostname, port, SMTP_TIMEOUT, false).await?; - let tls_stream = wrap_tls(strict_tls, hostname, tcp_stream).await?; + let tls_stream = wrap_tls(strict_tls, hostname, &[], tcp_stream).await?; let buffered_stream = BufStream::new(tls_stream); let session_stream: Box = Box::new(buffered_stream); let client = smtp::SmtpClient::new().smtp_utf8(true); @@ -200,7 +200,7 @@ impl Smtp { let client = smtp::SmtpClient::new().smtp_utf8(true); let transport = SmtpTransport::new(client, BufStream::new(tcp_stream)).await?; let tcp_stream = transport.starttls().await?.into_inner(); - let tls_stream = wrap_tls(strict_tls, hostname, tcp_stream) + let tls_stream = wrap_tls(strict_tls, hostname, &[], tcp_stream) .await .context("STARTTLS upgrade failed")?; let buffered_stream = BufStream::new(tls_stream);