180 lines
5.2 KiB
Rust
180 lines
5.2 KiB
Rust
use crate::app::Command;
|
|
use anyhow::Result;
|
|
use dioxus::hooks::{UnboundedReceiver, UnboundedSender};
|
|
use futures::io::{AsyncRead, AsyncWrite};
|
|
use mumble_protocol::control::{ClientControlCodec, ControlPacket};
|
|
use mumble_protocol::Serverbound;
|
|
use std::net::ToSocketAddrs;
|
|
use std::{fmt, io, sync::Arc};
|
|
use tokio::net::TcpStream;
|
|
use tokio::task::LocalSet;
|
|
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 _};
|
|
|
|
pub use tokio::task::spawn;
|
|
pub use tokio::time::sleep;
|
|
|
|
pub struct Error(anyhow::Error);
|
|
|
|
pub trait ImpRead: AsyncRead + Unpin + Send + 'static {}
|
|
impl<T: AsyncRead + Unpin + Send + 'static> ImpRead for T {}
|
|
|
|
pub trait ImpWrite: AsyncWrite + Unpin + Send + 'static {}
|
|
impl<T: AsyncWrite + Unpin + Send + 'static> ImpWrite for T {}
|
|
|
|
impl From<anyhow::Error> for Error {
|
|
fn from(value: anyhow::Error) -> Self {
|
|
Error(value)
|
|
}
|
|
}
|
|
|
|
impl From<io::Error> for Error {
|
|
fn from(value: io::Error) -> Self {
|
|
Error(value.into())
|
|
}
|
|
}
|
|
|
|
impl Error {
|
|
pub fn new(text: String) -> Self {
|
|
Self(anyhow::Error::msg(text))
|
|
}
|
|
|
|
pub fn log(&self) {
|
|
eprintln!("{}", self.0);
|
|
}
|
|
}
|
|
|
|
impl std::error::Error for Error {}
|
|
|
|
impl fmt::Display for Error {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
fmt::Display::fmt(&self.0, f)
|
|
}
|
|
}
|
|
|
|
impl fmt::Debug for Error {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
fmt::Debug::fmt(&self.0, f)
|
|
}
|
|
}
|
|
|
|
pub struct AudioSystem();
|
|
|
|
impl AudioSystem {
|
|
pub fn new(sender: UnboundedSender<ControlPacket<Serverbound>>) -> Result<Self, Error> {
|
|
// dbg!("todo");
|
|
Ok(AudioSystem())
|
|
}
|
|
|
|
pub fn create_player(&mut self) -> Result<AudioPlayer, Error> {
|
|
// dbg!("todo");
|
|
Ok(AudioPlayer())
|
|
}
|
|
}
|
|
|
|
pub struct AudioPlayer();
|
|
|
|
impl AudioPlayer {
|
|
pub fn play_opus(&mut self, payload: &[u8]) {
|
|
// dbg!("todo");
|
|
}
|
|
}
|
|
|
|
#[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,
|
|
]
|
|
}
|
|
}
|
|
|
|
pub async fn network_connect(
|
|
address: String,
|
|
username: String,
|
|
event_rx: &mut UnboundedReceiver<Command>,
|
|
) -> Result<(), Error> {
|
|
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 = format!("{}:{}", address, 64738)
|
|
.to_socket_addrs()?
|
|
.next()
|
|
.unwrap();
|
|
|
|
let server_tcp = TcpStream::connect(addr).await?;
|
|
let server_stream = connector
|
|
//.connect("127.0.0.1".try_into()?, server_tcp)
|
|
.connect(address.try_into().map_err(anyhow::Error::from)?, server_tcp)
|
|
.await?;
|
|
let (read_server, write_server) = tokio::io::split(server_stream);
|
|
|
|
let read_codec = ClientControlCodec::new();
|
|
let write_codec = ClientControlCodec::new();
|
|
|
|
let mut reader = asynchronous_codec::FramedRead::new(read_server.compat(), read_codec);
|
|
let mut writer = asynchronous_codec::FramedWrite::new(write_server.compat_write(), write_codec);
|
|
|
|
super::network_loop(username, event_rx, reader, writer).await
|
|
}
|
|
|
|
pub fn set_default_username(username: &str) -> Option<()> {
|
|
None
|
|
}
|
|
|
|
pub fn load_username() -> Option<String> {
|
|
return None;
|
|
}
|