121 lines
4.1 KiB
Rust
121 lines
4.1 KiB
Rust
use crate::app::{Command, ConnectTarget, SharedState};
|
|
use color_eyre::eyre::{bail, Error};
|
|
use futures_channel::mpsc::UnboundedReceiver;
|
|
use mumble_protocol::control::ClientControlCodec;
|
|
use std::net::ToSocketAddrs;
|
|
use std::sync::Arc;
|
|
use tokio::net::TcpStream;
|
|
use tokio_rustls::rustls;
|
|
use tokio_rustls::rustls::client::danger::{HandshakeSignatureValid, ServerCertVerifier};
|
|
use tokio_rustls::rustls::pki_types::{CertificateDer, ServerName, UnixTime};
|
|
use tokio_rustls::rustls::ClientConfig;
|
|
use tokio_rustls::rustls::DigitallySignedStruct;
|
|
use tokio_rustls::TlsConnector;
|
|
use tokio_util::compat::{TokioAsyncReadCompatExt as _, TokioAsyncWriteCompatExt as _};
|
|
use tracing::{info, instrument};
|
|
|
|
use mumble_web2_common::ProxyOverrides;
|
|
|
|
#[derive(Debug)]
|
|
struct NoCertificateVerification;
|
|
|
|
impl ServerCertVerifier for NoCertificateVerification {
|
|
fn verify_server_cert(
|
|
&self,
|
|
_end_entity: &CertificateDer<'_>,
|
|
_intermediates: &[CertificateDer<'_>],
|
|
_server_name: &ServerName<'_>,
|
|
_ocsp: &[u8],
|
|
_now: UnixTime,
|
|
) -> Result<rustls::client::danger::ServerCertVerified, rustls::Error> {
|
|
Ok(rustls::client::danger::ServerCertVerified::assertion())
|
|
}
|
|
|
|
fn verify_tls12_signature(
|
|
&self,
|
|
_message: &[u8],
|
|
_cert: &CertificateDer<'_>,
|
|
_dss: &DigitallySignedStruct,
|
|
) -> Result<HandshakeSignatureValid, rustls::Error> {
|
|
Ok(HandshakeSignatureValid::assertion())
|
|
}
|
|
|
|
fn verify_tls13_signature(
|
|
&self,
|
|
_message: &[u8],
|
|
_cert: &CertificateDer<'_>,
|
|
_dss: &DigitallySignedStruct,
|
|
) -> Result<HandshakeSignatureValid, rustls::Error> {
|
|
Ok(HandshakeSignatureValid::assertion())
|
|
}
|
|
|
|
fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
|
|
vec![
|
|
rustls::SignatureScheme::RSA_PKCS1_SHA1,
|
|
rustls::SignatureScheme::ECDSA_SHA1_Legacy,
|
|
rustls::SignatureScheme::RSA_PKCS1_SHA256,
|
|
rustls::SignatureScheme::ECDSA_NISTP256_SHA256,
|
|
rustls::SignatureScheme::RSA_PKCS1_SHA384,
|
|
rustls::SignatureScheme::ECDSA_NISTP384_SHA384,
|
|
rustls::SignatureScheme::RSA_PKCS1_SHA512,
|
|
rustls::SignatureScheme::ECDSA_NISTP521_SHA512,
|
|
rustls::SignatureScheme::RSA_PSS_SHA256,
|
|
rustls::SignatureScheme::RSA_PSS_SHA384,
|
|
rustls::SignatureScheme::RSA_PSS_SHA512,
|
|
rustls::SignatureScheme::ED25519,
|
|
rustls::SignatureScheme::ED448,
|
|
]
|
|
}
|
|
}
|
|
|
|
#[instrument]
|
|
pub async fn network_connect(
|
|
target: ConnectTarget,
|
|
username: String,
|
|
event_rx: &mut UnboundedReceiver<Command>,
|
|
overrides: &ProxyOverrides,
|
|
state: SharedState,
|
|
) -> Result<(), Error> {
|
|
info!("connecting");
|
|
|
|
let (host, port) = match target {
|
|
ConnectTarget::Direct { host, port } => (host, port),
|
|
ConnectTarget::Proxy(_) => {
|
|
bail!("desktop/mobile platform requires a direct host:port, not a proxy URL")
|
|
}
|
|
};
|
|
|
|
let config = ClientConfig::builder()
|
|
.dangerous()
|
|
.with_custom_certificate_verifier(Arc::new(NoCertificateVerification))
|
|
.with_no_client_auth();
|
|
|
|
let connector = TlsConnector::from(Arc::new(config));
|
|
|
|
let addr = (&*host, port)
|
|
.to_socket_addrs()?
|
|
.next()
|
|
.unwrap();
|
|
|
|
let server_tcp = TcpStream::connect(addr).await?;
|
|
let server_stream = connector
|
|
.connect(host.try_into()?, server_tcp)
|
|
.await?;
|
|
let (read_server, write_server) = tokio::io::split(server_stream);
|
|
|
|
let read_codec = ClientControlCodec::new();
|
|
let write_codec = ClientControlCodec::new();
|
|
|
|
let reader = asynchronous_codec::FramedRead::new(read_server.compat(), read_codec);
|
|
let writer = asynchronous_codec::FramedWrite::new(write_server.compat_write(), write_codec);
|
|
|
|
let (outgoing_send, outgoing_recv) = futures_channel::mpsc::unbounded();
|
|
spawn(crate::sender_loop(outgoing_recv, writer));
|
|
crate::network_loop(username, state, event_rx, outgoing_send, reader).await
|
|
}
|
|
|
|
#[allow(unused)]
|
|
pub use tokio::spawn;
|
|
#[allow(unused)]
|
|
pub type SpawnHandle = tokio::runtime::Handle;
|