mirror of
https://github.com/chatmail/core.git
synced 2026-04-28 10:56:29 +03:00
feat: Disable SNI for STARTTLS (#7499)
Many clients don't send it currently, so it is unlikely that servers depend on it: https://mastodon.social/@cks/114690055923939576. For "implicit TLS", do not turn it off yet, it will serve as a fallback in case of rare server that needs it. If the server only supports STARTTLS and requires SNI then it is really weird, likely should not happen.
This commit is contained in:
@@ -207,6 +207,7 @@ impl Client {
|
|||||||
hostname: &str,
|
hostname: &str,
|
||||||
strict_tls: bool,
|
strict_tls: bool,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
|
let use_sni = true;
|
||||||
let tcp_stream = connect_tcp_inner(addr).await?;
|
let tcp_stream = connect_tcp_inner(addr).await?;
|
||||||
let account_id = context.get_id();
|
let account_id = context.get_id();
|
||||||
let events = context.events.clone();
|
let events = context.events.clone();
|
||||||
@@ -215,6 +216,7 @@ impl Client {
|
|||||||
strict_tls,
|
strict_tls,
|
||||||
hostname,
|
hostname,
|
||||||
addr.port(),
|
addr.port(),
|
||||||
|
use_sni,
|
||||||
alpn(addr.port()),
|
alpn(addr.port()),
|
||||||
logging_stream,
|
logging_stream,
|
||||||
&context.tls_session_store,
|
&context.tls_session_store,
|
||||||
@@ -251,6 +253,7 @@ impl Client {
|
|||||||
host: &str,
|
host: &str,
|
||||||
strict_tls: bool,
|
strict_tls: bool,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
|
let use_sni = false;
|
||||||
let tcp_stream = connect_tcp_inner(addr).await?;
|
let tcp_stream = connect_tcp_inner(addr).await?;
|
||||||
|
|
||||||
let account_id = context.get_id();
|
let account_id = context.get_id();
|
||||||
@@ -275,6 +278,7 @@ impl Client {
|
|||||||
strict_tls,
|
strict_tls,
|
||||||
host,
|
host,
|
||||||
addr.port(),
|
addr.port(),
|
||||||
|
use_sni,
|
||||||
"",
|
"",
|
||||||
tcp_stream,
|
tcp_stream,
|
||||||
&context.tls_session_store,
|
&context.tls_session_store,
|
||||||
@@ -294,6 +298,7 @@ impl Client {
|
|||||||
strict_tls: bool,
|
strict_tls: bool,
|
||||||
proxy_config: ProxyConfig,
|
proxy_config: ProxyConfig,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
|
let use_sni = true;
|
||||||
let proxy_stream = proxy_config
|
let proxy_stream = proxy_config
|
||||||
.connect(context, domain, port, strict_tls)
|
.connect(context, domain, port, strict_tls)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -301,6 +306,7 @@ impl Client {
|
|||||||
strict_tls,
|
strict_tls,
|
||||||
domain,
|
domain,
|
||||||
port,
|
port,
|
||||||
|
use_sni,
|
||||||
alpn(port),
|
alpn(port),
|
||||||
proxy_stream,
|
proxy_stream,
|
||||||
&context.tls_session_store,
|
&context.tls_session_store,
|
||||||
@@ -340,6 +346,7 @@ impl Client {
|
|||||||
proxy_config: ProxyConfig,
|
proxy_config: ProxyConfig,
|
||||||
strict_tls: bool,
|
strict_tls: bool,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
|
let use_sni = false;
|
||||||
let proxy_stream = proxy_config
|
let proxy_stream = proxy_config
|
||||||
.connect(context, hostname, port, strict_tls)
|
.connect(context, hostname, port, strict_tls)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -362,6 +369,7 @@ impl Client {
|
|||||||
strict_tls,
|
strict_tls,
|
||||||
hostname,
|
hostname,
|
||||||
port,
|
port,
|
||||||
|
use_sni,
|
||||||
"",
|
"",
|
||||||
proxy_stream,
|
proxy_stream,
|
||||||
&context.tls_session_store,
|
&context.tls_session_store,
|
||||||
|
|||||||
@@ -131,11 +131,13 @@ pub(crate) async fn connect_tls_inner(
|
|||||||
alpn: &str,
|
alpn: &str,
|
||||||
tls_session_store: &TlsSessionStore,
|
tls_session_store: &TlsSessionStore,
|
||||||
) -> Result<impl SessionStream + 'static> {
|
) -> Result<impl SessionStream + 'static> {
|
||||||
|
let use_sni = true;
|
||||||
let tcp_stream = connect_tcp_inner(addr).await?;
|
let tcp_stream = connect_tcp_inner(addr).await?;
|
||||||
let tls_stream = wrap_tls(
|
let tls_stream = wrap_tls(
|
||||||
strict_tls,
|
strict_tls,
|
||||||
host,
|
host,
|
||||||
addr.port(),
|
addr.port(),
|
||||||
|
use_sni,
|
||||||
alpn,
|
alpn,
|
||||||
tcp_stream,
|
tcp_stream,
|
||||||
tls_session_store,
|
tls_session_store,
|
||||||
|
|||||||
@@ -74,19 +74,33 @@ where
|
|||||||
}
|
}
|
||||||
"https" => {
|
"https" => {
|
||||||
let port = parsed_url.port_u16().unwrap_or(443);
|
let port = parsed_url.port_u16().unwrap_or(443);
|
||||||
let load_cache = true;
|
let (use_sni, load_cache) = (true, true);
|
||||||
|
|
||||||
if let Some(proxy_config) = proxy_config_opt {
|
if let Some(proxy_config) = proxy_config_opt {
|
||||||
let proxy_stream = proxy_config
|
let proxy_stream = proxy_config
|
||||||
.connect(context, host, port, load_cache)
|
.connect(context, host, port, load_cache)
|
||||||
.await?;
|
.await?;
|
||||||
let tls_stream =
|
let tls_stream = wrap_rustls(
|
||||||
wrap_rustls(host, port, "", proxy_stream, &context.tls_session_store).await?;
|
host,
|
||||||
|
port,
|
||||||
|
use_sni,
|
||||||
|
"",
|
||||||
|
proxy_stream,
|
||||||
|
&context.tls_session_store,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
Box::new(tls_stream)
|
Box::new(tls_stream)
|
||||||
} else {
|
} else {
|
||||||
let tcp_stream = crate::net::connect_tcp(context, host, port, load_cache).await?;
|
let tcp_stream = crate::net::connect_tcp(context, host, port, load_cache).await?;
|
||||||
let tls_stream =
|
let tls_stream = wrap_rustls(
|
||||||
wrap_rustls(host, port, "", tcp_stream, &context.tls_session_store).await?;
|
host,
|
||||||
|
port,
|
||||||
|
use_sni,
|
||||||
|
"",
|
||||||
|
tcp_stream,
|
||||||
|
&context.tls_session_store,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
Box::new(tls_stream)
|
Box::new(tls_stream)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -429,9 +429,11 @@ impl ProxyConfig {
|
|||||||
load_cache,
|
load_cache,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
let use_sni = true;
|
||||||
let tls_stream = wrap_rustls(
|
let tls_stream = wrap_rustls(
|
||||||
&https_config.host,
|
&https_config.host,
|
||||||
https_config.port,
|
https_config.port,
|
||||||
|
use_sni,
|
||||||
"",
|
"",
|
||||||
tcp_stream,
|
tcp_stream,
|
||||||
&context.tls_session_store,
|
&context.tls_session_store,
|
||||||
|
|||||||
@@ -13,12 +13,14 @@ pub async fn wrap_tls<'a>(
|
|||||||
strict_tls: bool,
|
strict_tls: bool,
|
||||||
hostname: &str,
|
hostname: &str,
|
||||||
port: u16,
|
port: u16,
|
||||||
|
use_sni: bool,
|
||||||
alpn: &str,
|
alpn: &str,
|
||||||
stream: impl SessionStream + 'static,
|
stream: impl SessionStream + 'static,
|
||||||
tls_session_store: &TlsSessionStore,
|
tls_session_store: &TlsSessionStore,
|
||||||
) -> Result<impl SessionStream + 'a> {
|
) -> Result<impl SessionStream + 'a> {
|
||||||
if strict_tls {
|
if strict_tls {
|
||||||
let tls_stream = wrap_rustls(hostname, port, alpn, stream, tls_session_store).await?;
|
let tls_stream =
|
||||||
|
wrap_rustls(hostname, port, use_sni, alpn, stream, tls_session_store).await?;
|
||||||
let boxed_stream: Box<dyn SessionStream> = Box::new(tls_stream);
|
let boxed_stream: Box<dyn SessionStream> = Box::new(tls_stream);
|
||||||
Ok(boxed_stream)
|
Ok(boxed_stream)
|
||||||
} else {
|
} else {
|
||||||
@@ -32,6 +34,7 @@ pub async fn wrap_tls<'a>(
|
|||||||
};
|
};
|
||||||
let tls = async_native_tls::TlsConnector::new()
|
let tls = async_native_tls::TlsConnector::new()
|
||||||
.min_protocol_version(Some(async_native_tls::Protocol::Tlsv12))
|
.min_protocol_version(Some(async_native_tls::Protocol::Tlsv12))
|
||||||
|
.use_sni(use_sni)
|
||||||
.request_alpns(&alpns)
|
.request_alpns(&alpns)
|
||||||
.danger_accept_invalid_hostnames(true)
|
.danger_accept_invalid_hostnames(true)
|
||||||
.danger_accept_invalid_certs(true);
|
.danger_accept_invalid_certs(true);
|
||||||
@@ -90,6 +93,7 @@ impl TlsSessionStore {
|
|||||||
pub async fn wrap_rustls<'a>(
|
pub async fn wrap_rustls<'a>(
|
||||||
hostname: &str,
|
hostname: &str,
|
||||||
port: u16,
|
port: u16,
|
||||||
|
use_sni: bool,
|
||||||
alpn: &str,
|
alpn: &str,
|
||||||
stream: impl SessionStream + 'a,
|
stream: impl SessionStream + 'a,
|
||||||
tls_session_store: &TlsSessionStore,
|
tls_session_store: &TlsSessionStore,
|
||||||
@@ -117,6 +121,7 @@ pub async fn wrap_rustls<'a>(
|
|||||||
let resumption = tokio_rustls::rustls::client::Resumption::store(resumption_store)
|
let resumption = tokio_rustls::rustls::client::Resumption::store(resumption_store)
|
||||||
.tls12_resumption(tokio_rustls::rustls::client::Tls12Resumption::Disabled);
|
.tls12_resumption(tokio_rustls::rustls::client::Tls12Resumption::Disabled);
|
||||||
config.resumption = resumption;
|
config.resumption = resumption;
|
||||||
|
config.enable_sni = use_sni;
|
||||||
|
|
||||||
let tls = tokio_rustls::TlsConnector::from(Arc::new(config));
|
let tls = tokio_rustls::TlsConnector::from(Arc::new(config));
|
||||||
let name = rustls_pki_types::ServerName::try_from(hostname)?.to_owned();
|
let name = rustls_pki_types::ServerName::try_from(hostname)?.to_owned();
|
||||||
|
|||||||
@@ -228,6 +228,7 @@ async fn connect_secure_proxy(
|
|||||||
strict_tls: bool,
|
strict_tls: bool,
|
||||||
proxy_config: ProxyConfig,
|
proxy_config: ProxyConfig,
|
||||||
) -> Result<Box<dyn SessionBufStream>> {
|
) -> Result<Box<dyn SessionBufStream>> {
|
||||||
|
let use_sni = true;
|
||||||
let proxy_stream = proxy_config
|
let proxy_stream = proxy_config
|
||||||
.connect(context, hostname, port, strict_tls)
|
.connect(context, hostname, port, strict_tls)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -235,6 +236,7 @@ async fn connect_secure_proxy(
|
|||||||
strict_tls,
|
strict_tls,
|
||||||
hostname,
|
hostname,
|
||||||
port,
|
port,
|
||||||
|
use_sni,
|
||||||
alpn(port),
|
alpn(port),
|
||||||
proxy_stream,
|
proxy_stream,
|
||||||
&context.tls_session_store,
|
&context.tls_session_store,
|
||||||
@@ -253,6 +255,7 @@ async fn connect_starttls_proxy(
|
|||||||
strict_tls: bool,
|
strict_tls: bool,
|
||||||
proxy_config: ProxyConfig,
|
proxy_config: ProxyConfig,
|
||||||
) -> Result<Box<dyn SessionBufStream>> {
|
) -> Result<Box<dyn SessionBufStream>> {
|
||||||
|
let use_sni = false;
|
||||||
let proxy_stream = proxy_config
|
let proxy_stream = proxy_config
|
||||||
.connect(context, hostname, port, strict_tls)
|
.connect(context, hostname, port, strict_tls)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -266,6 +269,7 @@ async fn connect_starttls_proxy(
|
|||||||
strict_tls,
|
strict_tls,
|
||||||
hostname,
|
hostname,
|
||||||
port,
|
port,
|
||||||
|
use_sni,
|
||||||
"",
|
"",
|
||||||
tcp_stream,
|
tcp_stream,
|
||||||
&context.tls_session_store,
|
&context.tls_session_store,
|
||||||
@@ -316,6 +320,7 @@ async fn connect_starttls(
|
|||||||
strict_tls: bool,
|
strict_tls: bool,
|
||||||
tls_session_store: &TlsSessionStore,
|
tls_session_store: &TlsSessionStore,
|
||||||
) -> Result<Box<dyn SessionBufStream>> {
|
) -> Result<Box<dyn SessionBufStream>> {
|
||||||
|
let use_sni = false;
|
||||||
let tcp_stream = connect_tcp_inner(addr).await?;
|
let tcp_stream = connect_tcp_inner(addr).await?;
|
||||||
|
|
||||||
// Run STARTTLS command and convert the client back into a stream.
|
// Run STARTTLS command and convert the client back into a stream.
|
||||||
@@ -327,6 +332,7 @@ async fn connect_starttls(
|
|||||||
strict_tls,
|
strict_tls,
|
||||||
host,
|
host,
|
||||||
addr.port(),
|
addr.port(),
|
||||||
|
use_sni,
|
||||||
"",
|
"",
|
||||||
tcp_stream,
|
tcp_stream,
|
||||||
tls_session_store,
|
tls_session_store,
|
||||||
|
|||||||
Reference in New Issue
Block a user