mumble-rs/src/lib.rs
2024-08-25 21:37:52 +02:00

125 lines
No EOL
4.2 KiB
Rust

pub mod codec;
pub mod proto {
include!(concat!(env!("OUT_DIR"), "/mumble_proto.rs"));
}
pub mod udp {
include!(concat!(env!("OUT_DIR"), "/mumble_udp.rs"));
}
use std::fmt::{Debug, Formatter};
use std::net::SocketAddr;
use tokio::net::TcpStream;
use tokio::io::AsyncWriteExt;
use tokio_stream::StreamExt;
use prost::Message;
use tokio_rustls::rustls::{ClientConfig, DigitallySignedStruct, Error, RootCertStore, SignatureScheme};
use tokio_rustls::client::TlsStream;
use tokio_rustls::{TlsConnector};
use std::sync::Arc;
use rustls_pki_types::{CertificateDer, ServerName, UnixTime};
use tokio_util::codec::FramedRead;
use crate::codec::MumbleCodec;
use bytes::BytesMut;
use tokio_rustls::rustls::client::danger::{DangerousClientConfig, HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier};
pub struct MumbleClient {
host: SocketAddr,
}
pub(crate) struct NoVerifier;
impl Debug for NoVerifier {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
todo!()
}
}
impl ServerCertVerifier for NoVerifier {
fn verify_server_cert(&self, end_entity: &CertificateDer<'_>, intermediates: &[CertificateDer<'_>], server_name: &ServerName<'_>, ocsp_response: &[u8], now: UnixTime) -> Result<ServerCertVerified, Error> {
Ok(ServerCertVerified::assertion())
}
fn verify_tls12_signature(&self, message: &[u8], cert: &CertificateDer<'_>, dss: &DigitallySignedStruct) -> Result<HandshakeSignatureValid, Error> {
Ok(HandshakeSignatureValid::assertion())
}
fn verify_tls13_signature(&self, message: &[u8], cert: &CertificateDer<'_>, dss: &DigitallySignedStruct) -> Result<HandshakeSignatureValid, Error> {
Ok(HandshakeSignatureValid::assertion())
}
fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
vec![
SignatureScheme::RSA_PKCS1_SHA1,
SignatureScheme::ECDSA_SHA1_Legacy,
SignatureScheme::RSA_PKCS1_SHA256,
SignatureScheme::ECDSA_NISTP256_SHA256,
SignatureScheme::RSA_PKCS1_SHA384,
SignatureScheme::ECDSA_NISTP384_SHA384,
SignatureScheme::RSA_PKCS1_SHA512,
SignatureScheme::ECDSA_NISTP521_SHA512,
SignatureScheme::RSA_PSS_SHA256,
SignatureScheme::RSA_PSS_SHA384,
SignatureScheme::RSA_PSS_SHA512,
SignatureScheme::ED25519,
SignatureScheme::ED448,
]
}
}
impl MumbleClient {
pub fn new(host: SocketAddr) -> Self {
Self {
host
}
}
async fn create_tcp_connection(&mut self) -> anyhow::Result<TlsStream<TcpStream>> {
let mut root_cert_store = RootCertStore::empty();
root_cert_store.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
let mut config = ClientConfig::builder()
.with_root_certificates(root_cert_store)
.with_no_client_auth();
config
.dangerous()
.set_certificate_verifier(Arc::new(NoVerifier));
let connector = TlsConnector::from(Arc::new(config));
let dnsname = ServerName::try_from("127.0.0.1")?;
let stream = TcpStream::connect(&self.host).await?;
Ok(connector.connect(dnsname, stream).await?)
}
pub async fn connect(&mut self) -> anyhow::Result<()> {
let tcp_stream = self.create_tcp_connection().await?;
let mut framed_reader = FramedRead::new(tcp_stream, MumbleCodec::new());
let mut message_buffer: BytesMut = BytesMut::new();
let version = (proto::Version {
os: Some(String::from("Linux")),
os_version: None,
release: None,
version_v1: None,
version_v2: None
}).encode(&mut message_buffer)?;
// let mut complete_buffer = BytesMut::new();
// complete_buffer.extend((0u16).to_be_bytes());
// complete_buffer.extend(((2+4+message_buffer.len()) as u32).to_be_bytes());
// complete_buffer.extend(&message_buffer);
// println!("{complete_buffer:?}");
// tcp_stream.write_all(&complete_buffer).await?;
while let Some(frame_result) = framed_reader.next().await {
if let Ok(data) = frame_result {
println!("{data:?}");
}
}
Ok(())
}
}