diff --git a/src/imap/client.rs b/src/imap/client.rs index 1e6f03e6d..2034183a8 100644 --- a/src/imap/client.rs +++ b/src/imap/client.rs @@ -38,6 +38,16 @@ impl DerefMut for Client { } } +/// Converts port number to ALPN list. +fn alpn(port: u16) -> &'static [&'static str] { + if port == 993 { + // Do not request ALPN on standard port. + &[] + } else { + &["imap"] + } +} + /// Determine server capabilities. /// /// If server supports ID capability, send our client ID. @@ -157,7 +167,7 @@ impl Client { } async fn connect_secure(addr: SocketAddr, hostname: &str, strict_tls: bool) -> Result { - let tls_stream = connect_tls_inner(addr, hostname, strict_tls, "imap").await?; + let tls_stream = connect_tls_inner(addr, hostname, strict_tls, alpn(addr.port())).await?; let buffered_stream = BufWriter::new(tls_stream); let session_stream: Box = Box::new(buffered_stream); let mut client = Client::new(session_stream); @@ -197,7 +207,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, host, "imap", tcp_stream) + let tls_stream = wrap_tls(strict_tls, host, &[], tcp_stream) .await .context("STARTTLS upgrade failed")?; @@ -217,7 +227,7 @@ impl Client { let socks5_stream = socks5_config .connect(context, domain, port, strict_tls) .await?; - let tls_stream = wrap_tls(strict_tls, domain, "imap", socks5_stream).await?; + let tls_stream = wrap_tls(strict_tls, domain, alpn(port), 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); @@ -270,7 +280,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, "imap", socks5_stream) + let tls_stream = wrap_tls(strict_tls, hostname, &[], socks5_stream) .await .context("STARTTLS upgrade failed")?; let buffered_stream = BufWriter::new(tls_stream); diff --git a/src/net.rs b/src/net.rs index 25977de96..e8e167576 100644 --- a/src/net.rs +++ b/src/net.rs @@ -114,7 +114,7 @@ pub(crate) async fn connect_tls_inner( addr: SocketAddr, host: &str, strict_tls: bool, - alpn: &str, + alpn: &[&str], ) -> Result>>>> { let tcp_stream = connect_tcp_inner(addr).await?; let tls_stream = wrap_tls(strict_tls, host, alpn, tcp_stream).await?; diff --git a/src/net/tls.rs b/src/net/tls.rs index 5bd3902e7..232787b20 100644 --- a/src/net/tls.rs +++ b/src/net/tls.rs @@ -32,10 +32,10 @@ pub fn build_tls(strict_tls: bool, alpns: &[&str]) -> TlsConnector { pub async fn wrap_tls( strict_tls: bool, hostname: &str, - alpn: &str, + alpn: &[&str], stream: T, ) -> Result> { - let tls = build_tls(strict_tls, &[alpn]); + let tls = build_tls(strict_tls, alpn); let tls_stream = tls.connect(hostname, stream).await?; Ok(tls_stream) } diff --git a/src/smtp/connect.rs b/src/smtp/connect.rs index af8982248..788564e2d 100644 --- a/src/smtp/connect.rs +++ b/src/smtp/connect.rs @@ -16,6 +16,16 @@ use crate::provider::Socket; use crate::socks::Socks5Config; use crate::tools::time; +/// Converts port number to ALPN list. +fn alpn(port: u16) -> &'static [&'static str] { + if port == 465 { + // Do not request ALPN on standard port. + &[] + } else { + &["smtp"] + } +} + /// Returns TLS, STARTTLS or plaintext connection /// using SOCKS5 or direct connection depending on the given configuration. /// @@ -113,7 +123,7 @@ async fn connect_secure_socks5( let socks5_stream = socks5_config .connect(context, hostname, port, strict_tls) .await?; - let tls_stream = wrap_tls(strict_tls, hostname, "smtp", socks5_stream).await?; + let tls_stream = wrap_tls(strict_tls, hostname, alpn(port), socks5_stream).await?; let mut buffered_stream = BufStream::new(tls_stream); skip_smtp_greeting(&mut buffered_stream).await?; let session_stream: Box = Box::new(buffered_stream); @@ -135,7 +145,7 @@ async fn connect_starttls_socks5( let client = 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, "smtp", tcp_stream) + let tls_stream = wrap_tls(strict_tls, hostname, &[], tcp_stream) .await .context("STARTTLS upgrade failed")?; let buffered_stream = BufStream::new(tls_stream); @@ -163,7 +173,7 @@ async fn connect_secure( hostname: &str, strict_tls: bool, ) -> Result> { - let tls_stream = connect_tls_inner(addr, hostname, strict_tls, "smtp").await?; + let tls_stream = connect_tls_inner(addr, hostname, strict_tls, alpn(addr.port())).await?; let mut buffered_stream = BufStream::new(tls_stream); skip_smtp_greeting(&mut buffered_stream).await?; let session_stream: Box = Box::new(buffered_stream); @@ -181,7 +191,7 @@ async fn connect_starttls( let client = async_smtp::SmtpClient::new().smtp_utf8(true); let transport = async_smtp::SmtpTransport::new(client, BufStream::new(tcp_stream)).await?; let tcp_stream = transport.starttls().await?.into_inner(); - let tls_stream = wrap_tls(strict_tls, host, "smtp", tcp_stream) + let tls_stream = wrap_tls(strict_tls, host, &[], tcp_stream) .await .context("STARTTLS upgrade failed")?;