Cargo Format
This commit is contained in:
parent
2b1e16e1cb
commit
57c048ab83
3 changed files with 159 additions and 75 deletions
7
build.rs
7
build.rs
|
@ -1,4 +1,7 @@
|
||||||
fn main() {
|
fn main() {
|
||||||
prost_build::compile_protos(&["src/protos/Mumble.proto", "src/protos/MumbleUDP.proto"], &["src/protos"])
|
prost_build::compile_protos(
|
||||||
.expect("Could not build protobuf files")
|
&["src/protos/Mumble.proto", "src/protos/MumbleUDP.proto"],
|
||||||
|
&["src/protos"],
|
||||||
|
)
|
||||||
|
.expect("Could not build protobuf files")
|
||||||
}
|
}
|
||||||
|
|
128
src/codec.rs
128
src/codec.rs
|
@ -1,9 +1,9 @@
|
||||||
|
use crate::proto::*;
|
||||||
|
use crate::MumbleMessage;
|
||||||
use anyhow::bail;
|
use anyhow::bail;
|
||||||
use bytes::{Buf, BufMut, BytesMut};
|
use bytes::{Buf, BufMut, BytesMut};
|
||||||
use prost::Message;
|
use prost::Message;
|
||||||
use tokio_util::codec::{Decoder, Encoder};
|
use tokio_util::codec::{Decoder, Encoder};
|
||||||
use crate::MumbleMessage;
|
|
||||||
use crate::proto::*;
|
|
||||||
|
|
||||||
pub struct MumbleTcpCodec {}
|
pub struct MumbleTcpCodec {}
|
||||||
|
|
||||||
|
@ -27,8 +27,8 @@ impl Decoder for MumbleTcpCodec {
|
||||||
let message_type = u16::from_be_bytes(message_type.try_into()?) as usize;
|
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 message_length = u32::from_be_bytes(message_length.try_into()?) as usize;
|
||||||
|
|
||||||
if message_length+6 > src.len() {
|
if message_length + 6 > src.len() {
|
||||||
src.reserve(message_length+6-src.len());
|
src.reserve(message_length + 6 - src.len());
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,89 +37,139 @@ impl Decoder for MumbleTcpCodec {
|
||||||
|
|
||||||
match message_type {
|
match message_type {
|
||||||
0 => {
|
0 => {
|
||||||
mumble_message = Some(MumbleMessage::Version { data: Version::decode(message_data)? });
|
mumble_message = Some(MumbleMessage::Version {
|
||||||
|
data: Version::decode(message_data)?,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
1 => {
|
1 => {
|
||||||
mumble_message = Some(MumbleMessage::UdpTunnel { data: UdpTunnel::decode(message_data)? });
|
mumble_message = Some(MumbleMessage::UdpTunnel {
|
||||||
|
data: UdpTunnel::decode(message_data)?,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
2 => {
|
2 => {
|
||||||
bail!("The server should never send Authenticate")
|
bail!("The server should never send Authenticate")
|
||||||
},
|
}
|
||||||
3 => {
|
3 => {
|
||||||
mumble_message = Some(MumbleMessage::Ping { data: Ping::decode(message_data)? });
|
mumble_message = Some(MumbleMessage::Ping {
|
||||||
},
|
data: Ping::decode(message_data)?,
|
||||||
|
});
|
||||||
|
}
|
||||||
4 => {
|
4 => {
|
||||||
mumble_message = Some(MumbleMessage::Reject { data: Reject::decode(message_data)? });
|
mumble_message = Some(MumbleMessage::Reject {
|
||||||
|
data: Reject::decode(message_data)?,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
5 => {
|
5 => {
|
||||||
mumble_message = Some(MumbleMessage::ServerSync { data: ServerSync::decode(message_data)? });
|
mumble_message = Some(MumbleMessage::ServerSync {
|
||||||
|
data: ServerSync::decode(message_data)?,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
6 => {
|
6 => {
|
||||||
mumble_message = Some(MumbleMessage::ChannelRemove { data: ChannelRemove::decode(message_data)? });
|
mumble_message = Some(MumbleMessage::ChannelRemove {
|
||||||
|
data: ChannelRemove::decode(message_data)?,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
7 => {
|
7 => {
|
||||||
mumble_message = Some(MumbleMessage::ChannelState { data: ChannelState::decode(message_data)? });
|
mumble_message = Some(MumbleMessage::ChannelState {
|
||||||
|
data: ChannelState::decode(message_data)?,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
8 => {
|
8 => {
|
||||||
mumble_message = Some(MumbleMessage::UserRemove { data: UserRemove::decode(message_data)? });
|
mumble_message = Some(MumbleMessage::UserRemove {
|
||||||
|
data: UserRemove::decode(message_data)?,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
9 => {
|
9 => {
|
||||||
mumble_message = Some(MumbleMessage::UserState { data: UserState::decode(message_data)? });
|
mumble_message = Some(MumbleMessage::UserState {
|
||||||
},
|
data: UserState::decode(message_data)?,
|
||||||
|
});
|
||||||
|
}
|
||||||
10 => {
|
10 => {
|
||||||
mumble_message = Some(MumbleMessage::BanList { data: BanList::decode(message_data)? });
|
mumble_message = Some(MumbleMessage::BanList {
|
||||||
},
|
data: BanList::decode(message_data)?,
|
||||||
|
});
|
||||||
|
}
|
||||||
11 => {
|
11 => {
|
||||||
mumble_message = Some(MumbleMessage::TextMessage { data: TextMessage::decode(message_data)? });
|
mumble_message = Some(MumbleMessage::TextMessage {
|
||||||
},
|
data: TextMessage::decode(message_data)?,
|
||||||
|
});
|
||||||
|
}
|
||||||
12 => {
|
12 => {
|
||||||
mumble_message = Some(MumbleMessage::PermissionDenied { data: PermissionDenied::decode(message_data)? });
|
mumble_message = Some(MumbleMessage::PermissionDenied {
|
||||||
},
|
data: PermissionDenied::decode(message_data)?,
|
||||||
|
});
|
||||||
|
}
|
||||||
13 => {
|
13 => {
|
||||||
mumble_message = Some(MumbleMessage::Acl { data: Acl::decode(message_data)? });
|
mumble_message = Some(MumbleMessage::Acl {
|
||||||
|
data: Acl::decode(message_data)?,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
14 => {
|
14 => {
|
||||||
mumble_message = Some(MumbleMessage::QueryUsers { data: QueryUsers::decode(message_data)? });
|
mumble_message = Some(MumbleMessage::QueryUsers {
|
||||||
|
data: QueryUsers::decode(message_data)?,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
15 => {
|
15 => {
|
||||||
mumble_message = Some(MumbleMessage::CryptSetup { data: CryptSetup::decode(message_data)? });
|
mumble_message = Some(MumbleMessage::CryptSetup {
|
||||||
|
data: CryptSetup::decode(message_data)?,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
16 => {
|
16 => {
|
||||||
mumble_message = Some(MumbleMessage::ContextActionModify { data: ContextActionModify::decode(message_data)? });
|
mumble_message = Some(MumbleMessage::ContextActionModify {
|
||||||
|
data: ContextActionModify::decode(message_data)?,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
17 => {
|
17 => {
|
||||||
mumble_message = Some(MumbleMessage::ContextAction { data: ContextAction::decode(message_data)? });
|
mumble_message = Some(MumbleMessage::ContextAction {
|
||||||
|
data: ContextAction::decode(message_data)?,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
18 => {
|
18 => {
|
||||||
mumble_message = Some(MumbleMessage::UserList { data: UserList::decode(message_data)? });
|
mumble_message = Some(MumbleMessage::UserList {
|
||||||
|
data: UserList::decode(message_data)?,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
19 => {
|
19 => {
|
||||||
mumble_message = Some(MumbleMessage::VoiceTarget { data: VoiceTarget::decode(message_data)? });
|
mumble_message = Some(MumbleMessage::VoiceTarget {
|
||||||
|
data: VoiceTarget::decode(message_data)?,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
20 => {
|
20 => {
|
||||||
mumble_message = Some(MumbleMessage::PermissionQuery {data: PermissionQuery::decode(message_data)?});
|
mumble_message = Some(MumbleMessage::PermissionQuery {
|
||||||
|
data: PermissionQuery::decode(message_data)?,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
21 => {
|
21 => {
|
||||||
mumble_message = Some(MumbleMessage::CodecVersion {data: CodecVersion::decode(message_data)?});
|
mumble_message = Some(MumbleMessage::CodecVersion {
|
||||||
},
|
data: CodecVersion::decode(message_data)?,
|
||||||
|
});
|
||||||
|
}
|
||||||
22 => {
|
22 => {
|
||||||
mumble_message = Some(MumbleMessage::UserStats {data: UserStats::decode(message_data)?});
|
mumble_message = Some(MumbleMessage::UserStats {
|
||||||
|
data: UserStats::decode(message_data)?,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
23 => {
|
23 => {
|
||||||
mumble_message = Some(MumbleMessage::RequestBlob {data: RequestBlob::decode(message_data)?});
|
mumble_message = Some(MumbleMessage::RequestBlob {
|
||||||
|
data: RequestBlob::decode(message_data)?,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
24 => {
|
24 => {
|
||||||
mumble_message = Some(MumbleMessage::ServerConfig {data: ServerConfig::decode(message_data)?});
|
mumble_message = Some(MumbleMessage::ServerConfig {
|
||||||
|
data: ServerConfig::decode(message_data)?,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
25 => {
|
25 => {
|
||||||
mumble_message = Some(MumbleMessage::SuggestConfig {data: SuggestConfig::decode(message_data)?});
|
mumble_message = Some(MumbleMessage::SuggestConfig {
|
||||||
|
data: SuggestConfig::decode(message_data)?,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
eprintln!("Unknown message type {:?}", message_type);
|
eprintln!("Unknown message type {:?}", message_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
src.advance(message_length+6);
|
src.advance(message_length + 6);
|
||||||
Ok(mumble_message)
|
Ok(mumble_message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,7 +187,7 @@ impl Encoder<MumbleMessage> for MumbleTcpCodec {
|
||||||
MumbleMessage::Authenticate { data } => {
|
MumbleMessage::Authenticate { data } => {
|
||||||
Authenticate::encode(&data, &mut message)?;
|
Authenticate::encode(&data, &mut message)?;
|
||||||
dst.put_u16(2);
|
dst.put_u16(2);
|
||||||
},
|
}
|
||||||
MumbleMessage::Ping { data } => {
|
MumbleMessage::Ping { data } => {
|
||||||
Ping::encode(&data, &mut message)?;
|
Ping::encode(&data, &mut message)?;
|
||||||
dst.put_u16(3);
|
dst.put_u16(3);
|
||||||
|
@ -151,4 +201,4 @@ impl Encoder<MumbleMessage> for MumbleTcpCodec {
|
||||||
dst.extend_from_slice(&message);
|
dst.extend_from_slice(&message);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
99
src/lib.rs
99
src/lib.rs
|
@ -9,26 +9,30 @@ pub mod udp {
|
||||||
include!(concat!(env!("OUT_DIR"), "/mumble_udp.rs"));
|
include!(concat!(env!("OUT_DIR"), "/mumble_udp.rs"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use crate::codec::MumbleTcpCodec;
|
||||||
|
use crate::proto::*;
|
||||||
|
use rustls_pki_types::{CertificateDer, ServerName, UnixTime};
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
use tokio::net::{TcpStream, UdpSocket};
|
|
||||||
use tokio_rustls::rustls::{ClientConfig, DigitallySignedStruct, Error, RootCertStore, SignatureScheme};
|
|
||||||
use tokio_rustls::client::TlsStream;
|
|
||||||
use tokio_rustls::{TlsConnector};
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use rustls_pki_types::{CertificateDer, ServerName, UnixTime};
|
use tokio::net::{TcpStream, UdpSocket};
|
||||||
|
use tokio_rustls::client::TlsStream;
|
||||||
|
use tokio_rustls::rustls::client::danger::{
|
||||||
|
HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier,
|
||||||
|
};
|
||||||
|
use tokio_rustls::rustls::{
|
||||||
|
ClientConfig, DigitallySignedStruct, Error, RootCertStore, SignatureScheme,
|
||||||
|
};
|
||||||
|
use tokio_rustls::TlsConnector;
|
||||||
use tokio_util::codec::Framed;
|
use tokio_util::codec::Framed;
|
||||||
use crate::codec::MumbleTcpCodec;
|
|
||||||
use tokio_rustls::rustls::client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier};
|
|
||||||
use crate::proto::*;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum MumbleMessage {
|
pub enum MumbleMessage {
|
||||||
Version {data: Version},
|
Version { data: Version },
|
||||||
UdpTunnel { data: UdpTunnel },
|
UdpTunnel { data: UdpTunnel },
|
||||||
Ping { data: Ping },
|
Ping { data: Ping },
|
||||||
Reject { data: Reject },
|
Reject { data: Reject },
|
||||||
Authenticate {data: Authenticate},
|
Authenticate { data: Authenticate },
|
||||||
ServerSync { data: ServerSync },
|
ServerSync { data: ServerSync },
|
||||||
ChannelRemove { data: ChannelRemove },
|
ChannelRemove { data: ChannelRemove },
|
||||||
ChannelState { data: ChannelState },
|
ChannelState { data: ChannelState },
|
||||||
|
@ -49,34 +53,51 @@ pub enum MumbleMessage {
|
||||||
UserStats { data: UserStats },
|
UserStats { data: UserStats },
|
||||||
RequestBlob { data: RequestBlob },
|
RequestBlob { data: RequestBlob },
|
||||||
ServerConfig { data: ServerConfig },
|
ServerConfig { data: ServerConfig },
|
||||||
SuggestConfig { data: SuggestConfig }
|
SuggestConfig { data: SuggestConfig },
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MumbleClient {
|
pub struct MumbleClient {
|
||||||
host: String,
|
host: String,
|
||||||
name: String,
|
name: String,
|
||||||
port: u16,
|
port: u16,
|
||||||
password: Option<String>
|
password: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct NoVerifier;
|
pub(crate) struct NoVerifier;
|
||||||
|
|
||||||
impl Debug for NoVerifier {
|
impl Debug for NoVerifier {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(f, "NoVerifier")
|
write!(f, "NoVerifier")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServerCertVerifier for NoVerifier {
|
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> {
|
fn verify_server_cert(
|
||||||
|
&self,
|
||||||
|
_end_entity: &CertificateDer<'_>,
|
||||||
|
_intermediates: &[CertificateDer<'_>],
|
||||||
|
_server_name: &ServerName<'_>,
|
||||||
|
_ocsp_response: &[u8],
|
||||||
|
_now: UnixTime,
|
||||||
|
) -> Result<ServerCertVerified, Error> {
|
||||||
Ok(ServerCertVerified::assertion())
|
Ok(ServerCertVerified::assertion())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_tls12_signature(&self, _message: &[u8], _cert: &CertificateDer<'_>, _dss: &DigitallySignedStruct) -> Result<HandshakeSignatureValid, Error> {
|
fn verify_tls12_signature(
|
||||||
|
&self,
|
||||||
|
_message: &[u8],
|
||||||
|
_cert: &CertificateDer<'_>,
|
||||||
|
_dss: &DigitallySignedStruct,
|
||||||
|
) -> Result<HandshakeSignatureValid, Error> {
|
||||||
Ok(HandshakeSignatureValid::assertion())
|
Ok(HandshakeSignatureValid::assertion())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_tls13_signature(&self, _message: &[u8], _cert: &CertificateDer<'_>, _dss: &DigitallySignedStruct) -> Result<HandshakeSignatureValid, Error> {
|
fn verify_tls13_signature(
|
||||||
|
&self,
|
||||||
|
_message: &[u8],
|
||||||
|
_cert: &CertificateDer<'_>,
|
||||||
|
_dss: &DigitallySignedStruct,
|
||||||
|
) -> Result<HandshakeSignatureValid, Error> {
|
||||||
Ok(HandshakeSignatureValid::assertion())
|
Ok(HandshakeSignatureValid::assertion())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,7 +126,7 @@ impl MumbleClient {
|
||||||
host,
|
host,
|
||||||
port: port.unwrap_or(64738),
|
port: port.unwrap_or(64738),
|
||||||
name,
|
name,
|
||||||
password
|
password,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,27 +155,37 @@ impl MumbleClient {
|
||||||
Ok(sock)
|
Ok(sock)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn connect(&mut self) -> anyhow::Result<Framed<TlsStream<TcpStream>, MumbleTcpCodec>> {
|
pub async fn connect(
|
||||||
|
&mut self,
|
||||||
|
) -> anyhow::Result<Framed<TlsStream<TcpStream>, MumbleTcpCodec>> {
|
||||||
let mut framed = Framed::new(self.create_tcp_connection().await?, MumbleTcpCodec::new());
|
let mut framed = Framed::new(self.create_tcp_connection().await?, MumbleTcpCodec::new());
|
||||||
let version_v1 = (1u16 as u32) << 16 | (5u8 as u32) << 8 | (1u8 as u32);
|
let version_v1 = (1u16 as u32) << 16 | (5u8 as u32) << 8 | (1u8 as u32);
|
||||||
let version_v2 = 1u64 << 48 | 5u64 << 32 | 0u64 << 16 | 1u64;
|
let version_v2 = 1u64 << 48 | 5u64 << 32 | 0u64 << 16 | 1u64;
|
||||||
framed.send(MumbleMessage::Version { data: Version {
|
framed
|
||||||
os: Some(String::from("Linux")),
|
.send(MumbleMessage::Version {
|
||||||
os_version: Some(String::from("os version")),
|
data: Version {
|
||||||
release: Some(String::from("release")),
|
os: Some(String::from("Linux")),
|
||||||
version_v1: Some(version_v1),
|
os_version: Some(String::from("os version")),
|
||||||
version_v2: Some(version_v2)
|
release: Some(String::from("release")),
|
||||||
}}).await?;
|
version_v1: Some(version_v1),
|
||||||
|
version_v2: Some(version_v2),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
framed.send(MumbleMessage::Authenticate { data: Authenticate {
|
framed
|
||||||
username: Some(self.name.clone()),
|
.send(MumbleMessage::Authenticate {
|
||||||
password: self.password.clone(),
|
data: Authenticate {
|
||||||
tokens: vec![],
|
username: Some(self.name.clone()),
|
||||||
celt_versions: vec![],
|
password: self.password.clone(),
|
||||||
opus: Some(true),
|
tokens: vec![],
|
||||||
client_type: Some(1),
|
celt_versions: vec![],
|
||||||
}}).await?;
|
opus: Some(true),
|
||||||
|
client_type: Some(1),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
Ok(framed)
|
Ok(framed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue