Merge pull request #425 from fufesou/refact/tls_fallback_rustls_native_tls
refact: tls fallback, rustls -> native-tls
This commit is contained in:
153
src/proxy.rs
153
src/proxy.rs
@@ -411,9 +411,9 @@ impl Proxy {
|
||||
let url = format!("https://{}", self.intercept.get_host_and_port()?);
|
||||
let tls_type = get_cached_tls_type(&url);
|
||||
let danger_accept_invalid_cert = get_cached_tls_accept_invalid_cert(&url);
|
||||
let stream = match tls_type.unwrap_or(TlsType::NativeTls) {
|
||||
TlsType::NativeTls => {
|
||||
self.https_connect_nativetls_wrap_danger(
|
||||
let stream = match tls_type.unwrap_or(TlsType::Rustls) {
|
||||
TlsType::Rustls => {
|
||||
self.https_connect_rustls_wrap_danger(
|
||||
&url,
|
||||
local,
|
||||
proxy,
|
||||
@@ -425,8 +425,8 @@ impl Proxy {
|
||||
)
|
||||
.await?
|
||||
}
|
||||
TlsType::Rustls => {
|
||||
self.https_connect_rustls_wrap_danger(
|
||||
TlsType::NativeTls => {
|
||||
self.https_connect_nativetls_wrap_danger(
|
||||
&url,
|
||||
local,
|
||||
proxy,
|
||||
@@ -477,77 +477,30 @@ impl Proxy {
|
||||
};
|
||||
}
|
||||
|
||||
#[async_recursion]
|
||||
async fn https_connect_nativetls_wrap_danger<'a>(
|
||||
&self,
|
||||
url: &str,
|
||||
local: SocketAddr,
|
||||
proxy: SocketAddr,
|
||||
stream: Option<tokio::net::TcpStream>,
|
||||
target_addr: &TargetAddr<'a>,
|
||||
is_tls_type_cached: bool,
|
||||
danger_accept_invalid_cert: Option<bool>,
|
||||
origin_danger_accept_invalid_cert: Option<bool>,
|
||||
) -> ResultType<DynTcpStream> {
|
||||
let stream = stream.unwrap_or(self.new_stream(local, proxy).await?);
|
||||
match super::timeout(
|
||||
let stream = self.new_stream(local, proxy).await?;
|
||||
let s = super::timeout(
|
||||
self.ms_timeout,
|
||||
self.https_connect_nativetls(
|
||||
stream,
|
||||
target_addr,
|
||||
&target_addr,
|
||||
danger_accept_invalid_cert.unwrap_or(false),
|
||||
),
|
||||
)
|
||||
.await?
|
||||
{
|
||||
Ok(s) => {
|
||||
upsert_tls_cache(
|
||||
&url,
|
||||
TlsType::NativeTls,
|
||||
danger_accept_invalid_cert.unwrap_or(false),
|
||||
);
|
||||
Ok(DynTcpStream(Box::new(s)))
|
||||
}
|
||||
Err(ProxyError::NativeTlsError(e)) => {
|
||||
let s = if danger_accept_invalid_cert.is_none() {
|
||||
log::warn!(
|
||||
"Falling back to native-tls (accept invalid cert) for HTTPS proxy server."
|
||||
);
|
||||
self.https_connect_nativetls_wrap_danger(
|
||||
&url,
|
||||
local,
|
||||
proxy,
|
||||
None,
|
||||
target_addr,
|
||||
is_tls_type_cached,
|
||||
Some(true),
|
||||
origin_danger_accept_invalid_cert,
|
||||
)
|
||||
.await?
|
||||
} else if !is_tls_type_cached {
|
||||
log::warn!("Falling back to rustls for HTTPS proxy server.");
|
||||
self.https_connect_rustls_wrap_danger(
|
||||
&url,
|
||||
local,
|
||||
proxy,
|
||||
&target_addr,
|
||||
origin_danger_accept_invalid_cert,
|
||||
)
|
||||
.await?
|
||||
} else {
|
||||
log::error!(
|
||||
"Failed to connect to HTTPS proxy server with native-tls: {:?}.",
|
||||
e
|
||||
);
|
||||
bail!(e)
|
||||
};
|
||||
Ok(s)
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Failed to connect to HTTPS proxy server: {:?}.", e);
|
||||
bail!(e)
|
||||
}
|
||||
}
|
||||
.await??;
|
||||
upsert_tls_cache(
|
||||
url,
|
||||
TlsType::NativeTls,
|
||||
danger_accept_invalid_cert.unwrap_or(false),
|
||||
);
|
||||
Ok(DynTcpStream(Box::new(s)))
|
||||
}
|
||||
|
||||
pub async fn https_connect_nativetls<'a, Input>(
|
||||
@@ -570,30 +523,86 @@ impl Proxy {
|
||||
self.http_connect(stream, target_addr).await
|
||||
}
|
||||
|
||||
#[async_recursion]
|
||||
async fn https_connect_rustls_wrap_danger<'a>(
|
||||
&self,
|
||||
url: &str,
|
||||
local: SocketAddr,
|
||||
proxy: SocketAddr,
|
||||
stream: Option<tokio::net::TcpStream>,
|
||||
target_addr: &TargetAddr<'a>,
|
||||
is_tls_type_cached: bool,
|
||||
danger_accept_invalid_cert: Option<bool>,
|
||||
origin_danger_accept_invalid_cert: Option<bool>,
|
||||
) -> ResultType<DynTcpStream> {
|
||||
let stream = self.new_stream(local, proxy).await?;
|
||||
let s = super::timeout(
|
||||
let stream = stream.unwrap_or(self.new_stream(local, proxy).await?);
|
||||
match super::timeout(
|
||||
self.ms_timeout,
|
||||
self.https_connect_rustls(
|
||||
stream,
|
||||
&target_addr,
|
||||
target_addr,
|
||||
danger_accept_invalid_cert.unwrap_or(false),
|
||||
),
|
||||
)
|
||||
.await??;
|
||||
upsert_tls_cache(
|
||||
url,
|
||||
TlsType::Rustls,
|
||||
danger_accept_invalid_cert.unwrap_or(false),
|
||||
);
|
||||
Ok(DynTcpStream(Box::new(s)))
|
||||
.await?
|
||||
{
|
||||
Ok(s) => {
|
||||
upsert_tls_cache(
|
||||
&url,
|
||||
TlsType::Rustls,
|
||||
danger_accept_invalid_cert.unwrap_or(false),
|
||||
);
|
||||
Ok(DynTcpStream(Box::new(s)))
|
||||
}
|
||||
Err(e) => {
|
||||
// NOTE: Maybe it's better to check if the error is related to TLS here. (ProxyError::IoError(e), or ProxyError::NativeTlsError(e))
|
||||
// But we can only get the error when the TLS protocol is TLSv1.1.
|
||||
// The error message of the following is unclear:
|
||||
// https://github.com/rustdesk/rustdesk-server-pro/issues/189#issuecomment-1895701480
|
||||
// So we just try to fallback unconditionally here.
|
||||
//
|
||||
// If the protocol is TLS 1.1, the error is:
|
||||
// 1. "IO Error: received fatal alert: ProtocolVersion"
|
||||
// 2. "IO Error: An existing connection was forcibly closed by the remote host. (os error 10054)" on Windows sometimes.
|
||||
//
|
||||
// If the cert verification fails, the error is:
|
||||
// "IO Error: invalid peer certificate: UnknownIssuer"
|
||||
|
||||
let s = if danger_accept_invalid_cert.is_none() {
|
||||
log::warn!(
|
||||
"Falling back to rustls-tls (accept invalid cert) for HTTPS proxy server."
|
||||
);
|
||||
self.https_connect_rustls_wrap_danger(
|
||||
&url,
|
||||
local,
|
||||
proxy,
|
||||
None,
|
||||
target_addr,
|
||||
is_tls_type_cached,
|
||||
Some(true),
|
||||
origin_danger_accept_invalid_cert,
|
||||
)
|
||||
.await?
|
||||
} else if !is_tls_type_cached {
|
||||
log::warn!("Falling back to native-tls for HTTPS proxy server.");
|
||||
self.https_connect_nativetls_wrap_danger(
|
||||
&url,
|
||||
local,
|
||||
proxy,
|
||||
&target_addr,
|
||||
origin_danger_accept_invalid_cert,
|
||||
)
|
||||
.await?
|
||||
} else {
|
||||
log::error!(
|
||||
"Failed to connect to HTTPS proxy server with native-tls: {:?}.",
|
||||
e
|
||||
);
|
||||
bail!(e)
|
||||
};
|
||||
Ok(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn https_connect_rustls<'a, Input>(
|
||||
|
||||
@@ -73,7 +73,7 @@ impl WsFramedStream {
|
||||
|
||||
let tls_type = get_cached_tls_type(url);
|
||||
let is_tls_type_cached = tls_type.is_some();
|
||||
let tls_type = tls_type.unwrap_or(TlsType::NativeTls);
|
||||
let tls_type = tls_type.unwrap_or(TlsType::Rustls);
|
||||
let danger_accept_invalid_cert = get_cached_tls_accept_invalid_cert(&url);
|
||||
Self::try_connect(
|
||||
url,
|
||||
@@ -113,9 +113,9 @@ impl WsFramedStream {
|
||||
Ok(ws_stream)
|
||||
}
|
||||
Err(e) => match (tls_type, is_tls_type_cached, danger_accept_invalid_cert) {
|
||||
(TlsType::NativeTls, _, None) => {
|
||||
(TlsType::Rustls, _, None) => {
|
||||
log::warn!(
|
||||
"WebSocket connection with native-tls failed, try accept invalid certs: {}, {:?}",
|
||||
"WebSocket connection with rustls-tls failed, try accept invalid certs: {}, {:?}",
|
||||
url,
|
||||
e
|
||||
);
|
||||
@@ -129,25 +129,25 @@ impl WsFramedStream {
|
||||
)
|
||||
.await
|
||||
}
|
||||
(TlsType::NativeTls, false, Some(_)) => {
|
||||
(TlsType::Rustls, false, Some(_)) => {
|
||||
log::warn!(
|
||||
"WebSocket connection with native-tls failed, try rustls: {}, {:?}",
|
||||
"WebSocket connection with rustls-tls failed, try native-tls: {}, {:?}",
|
||||
url,
|
||||
e
|
||||
);
|
||||
Self::try_connect(
|
||||
url,
|
||||
ms_timeout,
|
||||
TlsType::Rustls,
|
||||
TlsType::NativeTls,
|
||||
is_tls_type_cached,
|
||||
original_danger_accept_invalid_certs,
|
||||
original_danger_accept_invalid_certs,
|
||||
)
|
||||
.await
|
||||
}
|
||||
(TlsType::Rustls, _, None) => {
|
||||
(TlsType::NativeTls, _, None) => {
|
||||
log::warn!(
|
||||
"WebSocket connection with rustls failed, try accept invalid certs: {}, {:?}",
|
||||
"WebSocket connection with native-tls failed, try accept invalid certs: {}, {:?}",
|
||||
url,
|
||||
e
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user