Add more messages

This commit is contained in:
Leon Grünewald 2024-09-16 17:20:41 +02:00
parent 61ee6fe05b
commit 9865c10f40
4 changed files with 216 additions and 44 deletions

93
Cargo.lock generated
View file

@ -206,18 +206,95 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
[[package]]
name = "futures"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-channel"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
dependencies = [
"futures-core",
"futures-sink",
]
[[package]] [[package]]
name = "futures-core" name = "futures-core"
version = "0.3.30" version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
[[package]]
name = "futures-executor"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-io"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
[[package]]
name = "futures-macro"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "futures-sink" name = "futures-sink"
version = "0.3.30" version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
[[package]]
name = "futures-task"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
[[package]]
name = "futures-util"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
dependencies = [
"futures-channel",
"futures-core",
"futures-io",
"futures-macro",
"futures-sink",
"futures-task",
"memchr",
"pin-project-lite",
"pin-utils",
"slab",
]
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.15" version = "0.2.15"
@ -405,6 +482,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytes", "bytes",
"futures",
"prost", "prost",
"prost-build", "prost-build",
"rustls-pki-types", "rustls-pki-types",
@ -495,6 +573,12 @@ version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]] [[package]]
name = "prettyplease" name = "prettyplease"
version = "0.2.20" version = "0.2.20"
@ -708,6 +792,15 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "slab"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
dependencies = [
"autocfg",
]
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.13.2" version = "1.13.2"

View file

@ -13,6 +13,7 @@ tokio-util = { version = "0.7", features = ["codec"] }
tokio-rustls = { version = "0.26" } tokio-rustls = { version = "0.26" }
webpki-roots = "0.26" webpki-roots = "0.26"
rustls-pki-types = { version = "1.7.0" , features = ["alloc", "std"]} rustls-pki-types = { version = "1.7.0" , features = ["alloc", "std"]}
futures = "0.3.30"
[build-dependencies] [build-dependencies]
prost-build = "0.13" prost-build = "0.13"

View file

@ -1,25 +1,20 @@
use anyhow::bail; use anyhow::bail;
use bytes::{Buf, BytesMut}; use bytes::{BufMut, BytesMut};
use prost::Message; use prost::Message;
use tokio_util::codec::Decoder; use tokio_util::codec::{Decoder, Encoder};
use crate::proto::Version; use crate::MumbleMessage;
use crate::proto::{Authenticate, Version, Ping};
pub enum MumbleMessages { pub struct MumbleTcpCodec {}
} impl MumbleTcpCodec {
pub struct MumbleCodec {
}
impl MumbleCodec {
pub fn new() -> Self { pub fn new() -> Self {
Self {} Self {}
} }
} }
impl Decoder for MumbleCodec { impl Decoder for MumbleTcpCodec {
type Item = (); type Item = MumbleMessage;
type Error = anyhow::Error; type Error = anyhow::Error;
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> { fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
@ -27,21 +22,67 @@ impl Decoder for MumbleCodec {
return Ok(None); return Ok(None);
} }
let message_type = u16::from_be_bytes(src[0..2].try_into()?) as usize; let (message_type, rest) = src.split_at(2);
let message_length = u32::from_be_bytes(src[2..6].try_into()?) as usize; let (message_length, rest) = rest.split_at(4);
let message_data = &src[6..message_length]; let message_type = u16::from_be_bytes(message_type.try_into()?) as usize;
let message_length = u32::from_be_bytes(message_length.try_into()?) as usize;
let mut mumble_message: Option<MumbleMessage> = None;
if message_length > src.len() {
src.reserve(message_length+6);
return Ok(None);
}
match message_type { match message_type {
0 => { 0 => {
//TODO: Version //TODO: Version
let version = Version::decode(message_data); let version = Version::decode(rest)?;
println!("{version:?}"); mumble_message = Some(MumbleMessage::Version {data: version});
Ok(Some(())) }
3 => {
let ping = Ping::decode(rest)?;
mumble_message = Some(MumbleMessage::Ping { data: ping });
} }
_ => { _ => {
eprintln!("Unknown message type {:?}", message_type); eprintln!("Unknown message type {:?}", message_type);
Ok(None)
} }
} }
let _ = src.split_to(message_length+6);
src.reserve(6);
Ok(mumble_message)
} }
} }
impl Encoder<MumbleMessage> for MumbleTcpCodec {
type Error = anyhow::Error;
fn encode(&mut self, item: MumbleMessage, dst: &mut BytesMut) -> Result<(), Self::Error> {
let mut message = BytesMut::new();
match item {
MumbleMessage::Version { data } => {
println!("Send Version");
Version::encode(&data, &mut message)?;
dst.put_u16(0);
}
MumbleMessage::Authenticate { data } => {
println!("Send Authenticate");
Authenticate::encode(&data, &mut message)?;
dst.put_u16(2);
},
MumbleMessage::Ping { data } => {
println!("Send Ping");
Ping::encode(&data, &mut message)?;
dst.put_u16(3);
}
_ => {
bail!("Could not encode unknown message")
}
}
dst.put_u32((message.len() as u32) + 6);
dst.extend_from_slice(&message);
println!("{dst:?}");
Ok(())
}
}

View file

@ -1,4 +1,5 @@
pub mod codec; pub mod codec;
use futures::sink::SinkExt;
pub mod proto { pub mod proto {
include!(concat!(env!("OUT_DIR"), "/mumble_proto.rs")); include!(concat!(env!("OUT_DIR"), "/mumble_proto.rs"));
@ -9,8 +10,8 @@ pub mod udp {
} }
use std::fmt::{Debug, Formatter}; use std::fmt::{Debug, Formatter};
use std::net::SocketAddr; use std::net::{Ipv4Addr, SocketAddr};
use tokio::net::TcpStream; use tokio::net::{TcpStream, UdpSocket};
use tokio::io::AsyncWriteExt; use tokio::io::AsyncWriteExt;
use tokio_stream::StreamExt; use tokio_stream::StreamExt;
use prost::Message; use prost::Message;
@ -19,10 +20,18 @@ use tokio_rustls::client::TlsStream;
use tokio_rustls::{TlsConnector}; use tokio_rustls::{TlsConnector};
use std::sync::Arc; use std::sync::Arc;
use rustls_pki_types::{CertificateDer, ServerName, UnixTime}; use rustls_pki_types::{CertificateDer, ServerName, UnixTime};
use tokio_util::codec::FramedRead; use tokio_util::codec::Framed;
use crate::codec::MumbleCodec; use crate::codec::MumbleTcpCodec;
use bytes::BytesMut; use tokio_rustls::rustls::client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier};
use tokio_rustls::rustls::client::danger::{DangerousClientConfig, HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier}; use crate::proto::{Authenticate, Version, Ping};
#[derive(Debug)]
pub enum MumbleMessage {
Version {data: Version},
Authenticate {data: Authenticate},
Ping { data: Ping },
UnknownMessage
}
pub struct MumbleClient { pub struct MumbleClient {
host: SocketAddr, host: SocketAddr,
@ -94,29 +103,57 @@ impl MumbleClient {
Ok(connector.connect(dnsname, stream).await?) Ok(connector.connect(dnsname, stream).await?)
} }
pub async fn create_udp_connection(&mut self) -> anyhow::Result<UdpSocket> {
let sock = UdpSocket::bind((Ipv4Addr::UNSPECIFIED, 0)).await?;
println!("UDP Connect");
sock.connect(&self.host).await?;
Ok(sock)
}
pub async fn connect(&mut self) -> anyhow::Result<()> { pub async fn connect(&mut self) -> anyhow::Result<()> {
let tcp_stream = self.create_tcp_connection().await?; let mut framed = Framed::new(self.create_tcp_connection().await?, MumbleTcpCodec::new());
let mut framed_reader = FramedRead::new(tcp_stream, MumbleCodec::new()); framed.send(MumbleMessage::Version { data: Version {
let mut message_buffer: BytesMut = BytesMut::new();
let version = (proto::Version {
os: Some(String::from("Linux")), os: Some(String::from("Linux")),
os_version: None, os_version: Some(String::from("os version")),
release: None, release: Some(String::from("release")),
version_v1: None, version_v1: None,
version_v2: None version_v2: Some(0)
}).encode(&mut message_buffer)?; }}).await?;
// let mut complete_buffer = BytesMut::new(); let udp_sock = self.create_udp_connection().await?;
// complete_buffer.extend((0u16).to_be_bytes()); let mut buf = [0; 1024];
// complete_buffer.extend(((2+4+message_buffer.len()) as u32).to_be_bytes());
// complete_buffer.extend(&message_buffer);
// println!("{complete_buffer:?}"); while let Some(frame_result) = framed.next().await {
// tcp_stream.write_all(&complete_buffer).await?; if let Ok(message) = frame_result {
println!("Receive: {message:?}");
while let Some(frame_result) = framed_reader.next().await { match message {
if let Ok(data) = frame_result { MumbleMessage::Version { data } => {
println!("{data:?}"); framed.send(MumbleMessage::Authenticate { data: Authenticate {
username:Some(String::from("Bot")),
password: None,
tokens: vec![],
celt_versions: vec![],
opus: Some(true),
client_type: Some(1),
}}).await?;
/*framed.send(MumbleMessage::Ping {data: Ping {
good: None,
late: None,
lost: None,
resync: None,
tcp_packets: None,
tcp_ping_avg: None,
tcp_ping_var: None,
timestamp: None,
udp_packets: None,
udp_ping_avg: None,
udp_ping_var: None
}}).await?;*/
}
_ => {
println!("{message:?}");
}
}
} }
} }