mirror of
https://github.com/rustdesk/hbb_common.git
synced 2026-04-23 08:36:56 +00:00
mobile wss use rustls_platform_verifier
Signed-off-by: 21pages <sunboeasy@gmail.com>
This commit is contained in:
@@ -59,7 +59,7 @@ tokio-rustls = { version = "0.26", features = [
|
|||||||
"tls12",
|
"tls12",
|
||||||
"ring",
|
"ring",
|
||||||
], default-features = false }
|
], default-features = false }
|
||||||
rustls-platform-verifier = "0.5"
|
rustls-platform-verifier = "0.6"
|
||||||
rustls-pki-types = "1.11"
|
rustls-pki-types = "1.11"
|
||||||
tokio-tungstenite = { version = "0.26", features = ["rustls-tls-native-roots", "rustls-tls-webpki-roots"] }
|
tokio-tungstenite = { version = "0.26", features = ["rustls-tls-native-roots", "rustls-tls-webpki-roots"] }
|
||||||
tungstenite = { version = "0.26", features = ["rustls-tls-native-roots", "rustls-tls-webpki-roots"] }
|
tungstenite = { version = "0.26", features = ["rustls-tls-native-roots", "rustls-tls-webpki-roots"] }
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use std::{
|
|||||||
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
|
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
|
||||||
ops::{Deref, DerefMut},
|
ops::{Deref, DerefMut},
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::{Mutex, RwLock},
|
sync::{atomic::AtomicBool, Mutex, RwLock},
|
||||||
time::{Duration, Instant, SystemTime},
|
time::{Duration, Instant, SystemTime},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -70,6 +70,7 @@ lazy_static::lazy_static! {
|
|||||||
pub static ref OVERWRITE_LOCAL_SETTINGS: RwLock<HashMap<String, String>> = Default::default();
|
pub static ref OVERWRITE_LOCAL_SETTINGS: RwLock<HashMap<String, String>> = Default::default();
|
||||||
pub static ref HARD_SETTINGS: RwLock<HashMap<String, String>> = Default::default();
|
pub static ref HARD_SETTINGS: RwLock<HashMap<String, String>> = Default::default();
|
||||||
pub static ref BUILTIN_SETTINGS: RwLock<HashMap<String, String>> = Default::default();
|
pub static ref BUILTIN_SETTINGS: RwLock<HashMap<String, String>> = Default::default();
|
||||||
|
pub static ref RUSTLS_PLATFORM_VERIFIER_INITIALIZED: AtomicBool = AtomicBool::new(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
|
|||||||
@@ -57,8 +57,10 @@ pub use toml;
|
|||||||
pub use uuid;
|
pub use uuid;
|
||||||
pub mod fingerprint;
|
pub mod fingerprint;
|
||||||
pub use flexi_logger;
|
pub use flexi_logger;
|
||||||
pub mod websocket;
|
|
||||||
pub mod stream;
|
pub mod stream;
|
||||||
|
pub mod websocket;
|
||||||
|
#[cfg(not(any(target_os = "macos", target_os = "windows")))]
|
||||||
|
pub use rustls_platform_verifier;
|
||||||
pub use stream::Stream;
|
pub use stream::Stream;
|
||||||
pub use whoami;
|
pub use whoami;
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ const MAXIMUM_RESPONSE_HEADERS: usize = 16;
|
|||||||
const DEFINE_TIME_OUT: u64 = 600;
|
const DEFINE_TIME_OUT: u64 = 600;
|
||||||
|
|
||||||
pub trait IntoUrl {
|
pub trait IntoUrl {
|
||||||
|
|
||||||
// Besides parsing as a valid `Url`, the `Url` must be a valid
|
// Besides parsing as a valid `Url`, the `Url` must be a valid
|
||||||
// `http::Uri`, in that it makes sense to use in a network request.
|
// `http::Uri`, in that it makes sense to use in a network request.
|
||||||
fn into_url(self) -> Result<Url, ProxyError>;
|
fn into_url(self) -> Result<Url, ProxyError>;
|
||||||
@@ -455,8 +454,10 @@ impl Proxy {
|
|||||||
Input: AsyncRead + AsyncWrite + Unpin,
|
Input: AsyncRead + AsyncWrite + Unpin,
|
||||||
T: IntoTargetAddr<'a>,
|
T: IntoTargetAddr<'a>,
|
||||||
{
|
{
|
||||||
|
use rustls_platform_verifier::ConfigVerifierExt;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
let verifier = rustls_platform_verifier::tls_config();
|
let verifier = tokio_rustls::rustls::ClientConfig::with_platform_verifier()
|
||||||
|
.map_err(|e| ProxyError::IoError(std::io::Error::other(e)))?;
|
||||||
let url_domain = self.intercept.get_domain()?;
|
let url_domain = self.intercept.get_domain()?;
|
||||||
|
|
||||||
let domain = rustls_pki_types::ServerName::try_from(url_domain.as_str())
|
let domain = rustls_pki_types::ServerName::try_from(url_domain.as_str())
|
||||||
|
|||||||
@@ -8,7 +8,11 @@ use crate::{
|
|||||||
ResultType,
|
ResultType,
|
||||||
};
|
};
|
||||||
use bytes::{Bytes, BytesMut};
|
use bytes::{Bytes, BytesMut};
|
||||||
|
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||||
|
use futures::future::{select_ok, FutureExt};
|
||||||
use futures::{SinkExt, StreamExt};
|
use futures::{SinkExt, StreamExt};
|
||||||
|
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||||
|
use std::future::Future;
|
||||||
use std::{
|
use std::{
|
||||||
io::{Error, ErrorKind},
|
io::{Error, ErrorKind},
|
||||||
net::SocketAddr,
|
net::SocketAddr,
|
||||||
@@ -28,6 +32,19 @@ pub struct WsFramedStream {
|
|||||||
send_timeout: u64,
|
send_timeout: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||||
|
async fn await_timeout_result<F, T, E>(future: F) -> ResultType<T>
|
||||||
|
where
|
||||||
|
F: Future<Output = Result<Result<T, E>, tokio::time::error::Elapsed>>,
|
||||||
|
E: std::error::Error + Send + Sync + 'static,
|
||||||
|
{
|
||||||
|
match future.await {
|
||||||
|
Ok(Ok(result)) => Ok(result),
|
||||||
|
Ok(Err(e)) => Err(e.into()),
|
||||||
|
Err(elapsed) => Err(Error::new(ErrorKind::TimedOut, elapsed).into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl WsFramedStream {
|
impl WsFramedStream {
|
||||||
pub async fn new<T: AsRef<str>>(
|
pub async fn new<T: AsRef<str>>(
|
||||||
url: T,
|
url: T,
|
||||||
@@ -43,8 +60,57 @@ impl WsFramedStream {
|
|||||||
.into_client_request()
|
.into_client_request()
|
||||||
.map_err(|e| Error::new(ErrorKind::Other, e))?;
|
.map_err(|e| Error::new(ErrorKind::Other, e))?;
|
||||||
|
|
||||||
let (stream, _) =
|
let stream;
|
||||||
timeout(Duration::from_millis(ms_timeout), connect_async(request)).await??;
|
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||||
|
{
|
||||||
|
let mut futures = vec![];
|
||||||
|
|
||||||
|
let is_wss = url_str.starts_with("wss://");
|
||||||
|
let rustls_platform_verifier_initialized = !cfg!(target_os = "android")
|
||||||
|
|| crate::config::RUSTLS_PLATFORM_VERIFIER_INITIALIZED
|
||||||
|
.load(std::sync::atomic::Ordering::Relaxed);
|
||||||
|
if is_wss && rustls_platform_verifier_initialized {
|
||||||
|
use rustls_platform_verifier::ConfigVerifierExt;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use tokio_rustls::rustls::ClientConfig;
|
||||||
|
use tokio_tungstenite::{connect_async_tls_with_config, Connector};
|
||||||
|
match ClientConfig::with_platform_verifier() {
|
||||||
|
Ok(config) => {
|
||||||
|
let connector = Connector::Rustls(Arc::new(config));
|
||||||
|
futures.push(
|
||||||
|
await_timeout_result(timeout(
|
||||||
|
Duration::from_millis(ms_timeout),
|
||||||
|
connect_async_tls_with_config(
|
||||||
|
request.clone(),
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
Some(connector),
|
||||||
|
),
|
||||||
|
))
|
||||||
|
.boxed(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("with_platform_verifier failed: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
futures.push(
|
||||||
|
await_timeout_result(timeout(
|
||||||
|
Duration::from_millis(ms_timeout),
|
||||||
|
connect_async(request),
|
||||||
|
))
|
||||||
|
.boxed(),
|
||||||
|
);
|
||||||
|
let ((s, _), _) = select_ok(futures).await?;
|
||||||
|
stream = s;
|
||||||
|
}
|
||||||
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
|
{
|
||||||
|
let (s, _) =
|
||||||
|
timeout(Duration::from_millis(ms_timeout), connect_async(request)).await??;
|
||||||
|
stream = s;
|
||||||
|
}
|
||||||
|
|
||||||
let addr = match stream.get_ref() {
|
let addr = match stream.get_ref() {
|
||||||
MaybeTlsStream::Plain(tcp) => tcp.peer_addr()?,
|
MaybeTlsStream::Plain(tcp) => tcp.peer_addr()?,
|
||||||
|
|||||||
Reference in New Issue
Block a user