feat: rnex works, all major roadblocks are gone, the rnex rewrite is now in working state
This commit is contained in:
parent
803a98aa0b
commit
5e726fc9b0
12 changed files with 494 additions and 667 deletions
178
src/main.rs
178
src/main.rs
|
|
@ -7,33 +7,37 @@
|
|||
//! also the first and only current usage of rnex, expect this and rnex to be split into seperate
|
||||
//! repos soon.
|
||||
|
||||
use crate::rmc::protocols::auth::RemoteAuth;
|
||||
use crate::rmc::protocols::auth::RawAuthInfo;
|
||||
use crate::rmc::protocols::auth::RawAuth;
|
||||
use crate::nex::account::Account;
|
||||
use crate::nex::auth_handler::{AuthHandler, RemoteAuthClientProtocol};
|
||||
use crate::prudp::packet::VirtualPort;
|
||||
use crate::prudp::router::Router;
|
||||
use crate::prudp::secure::Secure;
|
||||
use crate::prudp::sockaddr::PRUDPSockAddr;
|
||||
use crate::prudp::socket::Unsecure;
|
||||
use chrono::{Local, SecondsFormat};
|
||||
use log::{error, info};
|
||||
use once_cell::sync::Lazy;
|
||||
use simplelog::{
|
||||
ColorChoice, CombinedLogger, Config, LevelFilter, TermLogger, TerminalMode, WriteLogger,
|
||||
};
|
||||
use std::fs::File;
|
||||
use std::net::{Ipv4Addr, SocketAddrV4};
|
||||
use std::{env, fs};
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::{BitAnd, BitOr};
|
||||
use std::str::FromStr;
|
||||
use macros::rmc_struct;
|
||||
use crate::prudp::unsecure::Unsecure;
|
||||
use crate::rmc::protocols::auth::Auth;
|
||||
use crate::rmc::protocols::auth::RawAuth;
|
||||
use crate::rmc::protocols::auth::RawAuthInfo;
|
||||
use crate::rmc::protocols::auth::RemoteAuth;
|
||||
use crate::rmc::protocols::{new_rmc_gateway_connection, OnlyRemote};
|
||||
use crate::rmc::response::ErrorCode;
|
||||
use crate::rmc::structures::any::Any;
|
||||
use crate::rmc::structures::connection_data::ConnectionData;
|
||||
use crate::rmc::structures::qresult::QResult;
|
||||
use chrono::{Local, SecondsFormat};
|
||||
use log::{error, info};
|
||||
use macros::rmc_struct;
|
||||
use once_cell::sync::Lazy;
|
||||
use simplelog::{
|
||||
ColorChoice, CombinedLogger, Config, LevelFilter, TermLogger, TerminalMode, WriteLogger,
|
||||
};
|
||||
use std::fs::File;
|
||||
use std::marker::PhantomData;
|
||||
use std::net::{Ipv4Addr, SocketAddrV4};
|
||||
use std::ops::{BitAnd, BitOr};
|
||||
use std::str::FromStr;
|
||||
use std::time::Duration;
|
||||
use std::{env, fs};
|
||||
use tokio::task::JoinHandle;
|
||||
|
||||
mod endianness;
|
||||
mod prudp;
|
||||
|
|
@ -43,9 +47,9 @@ pub mod rmc;
|
|||
mod grpc;
|
||||
mod kerberos;
|
||||
mod nex;
|
||||
mod web;
|
||||
mod versions;
|
||||
mod result;
|
||||
mod versions;
|
||||
mod web;
|
||||
|
||||
static KERBEROS_SERVER_PASSWORD: Lazy<String> = Lazy::new(|| {
|
||||
env::var("AUTH_SERVER_PASSWORD")
|
||||
|
|
@ -258,86 +262,112 @@ async fn start_secure_server() -> SecureServer{
|
|||
}
|
||||
}*/
|
||||
|
||||
async fn start_auth() -> JoinHandle<()> {
|
||||
tokio::spawn(async {
|
||||
let (router_secure, _) = Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *AUTH_SERVER_PORT))
|
||||
.await
|
||||
.expect("unable to start router");
|
||||
|
||||
impl Auth for AuthClient{
|
||||
async fn login(&self, name: String) -> Result<(), ErrorCode> {
|
||||
todo!()
|
||||
}
|
||||
let mut socket_secure = router_secure
|
||||
.add_socket(VirtualPort::new(1, 10), Unsecure("6f599f81"))
|
||||
.await
|
||||
.expect("unable to add socket");
|
||||
|
||||
async fn login_ex(&self, name: String, extra_data: Any) -> Result<(QResult, u32, Vec<u8>, ConnectionData, String), ErrorCode> {
|
||||
todo!()
|
||||
}
|
||||
// let conn = socket_secure.connect(auth_sockaddr).await.unwrap();
|
||||
|
||||
async fn request_ticket(&self, source_pid: u32, destination_pid: u32) -> Result<(QResult, Vec<u8>), ErrorCode> {
|
||||
todo!()
|
||||
}
|
||||
loop {
|
||||
let Some(conn) = socket_secure.accept().await else {
|
||||
error!("server crashed");
|
||||
return;
|
||||
};
|
||||
|
||||
async fn get_pid(&self, username: String) -> Result<u32, ErrorCode> {
|
||||
todo!()
|
||||
}
|
||||
info!("new connected user!");
|
||||
|
||||
async fn get_name(&self, pid: u32) -> Result<String, ErrorCode> {
|
||||
todo!()
|
||||
}
|
||||
let _ = new_rmc_gateway_connection(conn, |_| AuthHandler {
|
||||
destination_server_acct: &SECURE_SERVER_ACCOUNT,
|
||||
build_name: "branch:origin/project/wup-agmj build:3_8_15_2004_0",
|
||||
station_url: &SECURE_STATION_URL,
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[rmc_struct(AuthClientProtocol)]
|
||||
struct AuthClient {
|
||||
async fn start_secure() -> JoinHandle<()> {
|
||||
tokio::spawn(async {
|
||||
let (router_secure, _) =
|
||||
Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *SECURE_SERVER_PORT))
|
||||
.await
|
||||
.expect("unable to start router");
|
||||
|
||||
let mut socket_secure = router_secure
|
||||
.add_socket(
|
||||
VirtualPort::new(1, 10),
|
||||
Secure("6f599f81", &SECURE_SERVER_ACCOUNT),
|
||||
)
|
||||
.await
|
||||
.expect("unable to add socket");
|
||||
|
||||
// let conn = socket_secure.connect(auth_sockaddr).await.unwrap();
|
||||
|
||||
loop {
|
||||
let Some(conn) = socket_secure.accept().await else {
|
||||
error!("server crashed");
|
||||
return;
|
||||
};
|
||||
|
||||
info!("new connected user on secure :D!");
|
||||
|
||||
let _ = new_rmc_gateway_connection(conn, |_| AuthHandler {
|
||||
destination_server_acct: &SECURE_SERVER_ACCOUNT,
|
||||
build_name: "branch:origin/project/wup-agmj build:3_8_15_2004_0",
|
||||
station_url: &SECURE_STATION_URL,
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
define_rmc_proto!(
|
||||
proto AuthClientProtocol{
|
||||
Auth
|
||||
}
|
||||
);
|
||||
async fn start_test() {
|
||||
let addr = SocketAddrV4::new(*OWN_IP_PRIVATE, *AUTH_SERVER_PORT);
|
||||
|
||||
let virt_addr = VirtualPort::new(1, 10);
|
||||
let prudp_addr = PRUDPSockAddr::new(addr, virt_addr);
|
||||
|
||||
async fn start_servers() {
|
||||
|
||||
|
||||
//let auth_ip = SocketAddrV4::from_str("157.90.13.221:30039").unwrap();
|
||||
let auth_ip = SocketAddrV4::from_str("31.220.75.208:10000").unwrap();
|
||||
let auth_port = VirtualPort::new(1, 10);
|
||||
|
||||
let auth_sockaddr = PRUDPSockAddr::new(auth_ip, auth_port);
|
||||
|
||||
let (router_secure, _) = Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *AUTH_SERVER_PORT))
|
||||
let (router_test, _) = Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, 26969))
|
||||
.await
|
||||
.expect("unable to start router");
|
||||
|
||||
let mut socket_secure = router_secure
|
||||
let mut socket_secure = router_test
|
||||
.add_socket(VirtualPort::new(1, 10), Unsecure("6f599f81"))
|
||||
.await
|
||||
.expect("unable to add socket");
|
||||
|
||||
// let conn = socket_secure.connect(auth_sockaddr).await.unwrap();
|
||||
let conn = socket_secure.connect(prudp_addr).await.unwrap();
|
||||
|
||||
|
||||
loop {
|
||||
let Some(conn) = socket_secure.accept().await else {
|
||||
error!("server crashed");
|
||||
return;
|
||||
};
|
||||
let remote =
|
||||
new_rmc_gateway_connection(conn, |r| OnlyRemote::<RemoteAuthClientProtocol>::new(r));
|
||||
|
||||
info!("new connected user!");
|
||||
let v = remote
|
||||
.login_ex("1469690705".to_string(), Any::default())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let _ = new_rmc_gateway_connection(conn, |_| AuthClient {}); //OnlyRemote::<RemoteAuthClientProtocol>::new
|
||||
println!("got it");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
async fn start_servers() {
|
||||
#[cfg(feature = "auth")]
|
||||
let auth_server = start_auth_server().await;
|
||||
let auth_server = start_auth().await;
|
||||
#[cfg(feature = "secure")]
|
||||
let secure_server = start_secure_server().await;
|
||||
let web_server = web::start_web().await;
|
||||
let secure_server = start_secure().await;
|
||||
//let web_server = web::start_web().await;
|
||||
|
||||
//tokio::time::sleep(Duration::from_secs(1)).await;
|
||||
|
||||
//start_test().await;
|
||||
|
||||
#[cfg(feature = "auth")]
|
||||
auth_server.join_handle.await.expect("auth server crashed");
|
||||
auth_server.await.expect("auth server crashed");
|
||||
#[cfg(feature = "secure")]
|
||||
secure_server.join_handle.await.expect("auth server crashed");
|
||||
web_server.await.expect("webserver crashed");*/
|
||||
}
|
||||
secure_server.await.expect("auth server crashed");
|
||||
//web_server.await.expect("webserver crashed");
|
||||
}
|
||||
|
|
|
|||
167
src/nex/auth_handler.rs
Normal file
167
src/nex/auth_handler.rs
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
use crate::grpc::account;
|
||||
use crate::kerberos::{derive_key, KerberosDateTime, Ticket};
|
||||
use crate::nex::account::Account;
|
||||
use crate::rmc::protocols::auth::{Auth, RawAuth, RawAuthInfo, RemoteAuth};
|
||||
use crate::rmc::response::ErrorCode;
|
||||
use crate::rmc::response::ErrorCode::Core_Unknown;
|
||||
use crate::rmc::structures::any::Any;
|
||||
use crate::rmc::structures::connection_data::ConnectionData;
|
||||
use crate::rmc::structures::qresult::QResult;
|
||||
use crate::rmc::structures::RmcSerialize;
|
||||
use crate::{define_rmc_proto, kerberos, rmc};
|
||||
use macros::rmc_struct;
|
||||
|
||||
define_rmc_proto!(
|
||||
proto AuthClientProtocol{
|
||||
Auth
|
||||
}
|
||||
);
|
||||
|
||||
#[rmc_struct(AuthClientProtocol)]
|
||||
pub struct AuthHandler {
|
||||
pub destination_server_acct: &'static Account,
|
||||
pub build_name: &'static str,
|
||||
pub station_url: &'static str,
|
||||
}
|
||||
|
||||
pub fn generate_ticket(
|
||||
source_act_login_data: (u32, [u8; 16]),
|
||||
dest_act_login_data: (u32, [u8; 16]),
|
||||
) -> Box<[u8]> {
|
||||
let source_key = derive_key(source_act_login_data.0, source_act_login_data.1);
|
||||
let dest_key = derive_key(dest_act_login_data.0, dest_act_login_data.1);
|
||||
|
||||
let internal_data = kerberos::TicketInternalData::new(source_act_login_data.0);
|
||||
|
||||
let encrypted_inner = internal_data.encrypt(dest_key);
|
||||
let encrypted_session_ticket = Ticket {
|
||||
pid: dest_act_login_data.0,
|
||||
session_key: internal_data.session_key,
|
||||
}
|
||||
.encrypt(source_key, &encrypted_inner);
|
||||
|
||||
encrypted_session_ticket
|
||||
}
|
||||
|
||||
async fn get_login_data_by_pid(pid: u32) -> Option<(u32, [u8; 16])> {
|
||||
let Ok(mut client) = account::Client::new().await else {
|
||||
return None;
|
||||
};
|
||||
|
||||
let Ok(passwd) = client.get_nex_password(pid).await else {
|
||||
return None;
|
||||
};
|
||||
|
||||
Some((pid, passwd))
|
||||
}
|
||||
|
||||
impl Auth for AuthHandler {
|
||||
async fn login(&self, name: String) -> Result<(), ErrorCode> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn login_ex(
|
||||
&self,
|
||||
name: String,
|
||||
extra_data: Any,
|
||||
) -> Result<(QResult, u32, Vec<u8>, ConnectionData, String), ErrorCode> {
|
||||
let Ok(pid) = name.parse() else {
|
||||
return Err(ErrorCode::Core_InvalidArgument);
|
||||
};
|
||||
|
||||
let Ok(mut client) = account::Client::new().await else {
|
||||
return Err(ErrorCode::Core_Exception);
|
||||
};
|
||||
|
||||
let Ok(passwd) = client.get_nex_password(pid).await else {
|
||||
return Err(ErrorCode::Core_Exception);
|
||||
};
|
||||
|
||||
let source_login_data = (pid, passwd);
|
||||
let destination_login_data = self.destination_server_acct.get_login_data();
|
||||
|
||||
let ticket = generate_ticket(source_login_data, destination_login_data);
|
||||
|
||||
let result = QResult::success(Core_Unknown);
|
||||
|
||||
let connection_data = ConnectionData {
|
||||
station_url: self.station_url.to_string(),
|
||||
special_station_url: "".to_string(),
|
||||
//date_time: KerberosDateTime::new(1,1,1,1,1,1),
|
||||
date_time: KerberosDateTime::now(),
|
||||
special_protocols: Vec::new(),
|
||||
};
|
||||
|
||||
Ok((
|
||||
result,
|
||||
source_login_data.0,
|
||||
ticket.into(),
|
||||
connection_data,
|
||||
self.build_name.to_owned(),
|
||||
))
|
||||
}
|
||||
|
||||
async fn request_ticket(
|
||||
&self,
|
||||
source_pid: u32,
|
||||
destination_pid: u32,
|
||||
) -> Result<(QResult, Vec<u8>), ErrorCode> {
|
||||
let Some(source_login_data) = get_login_data_by_pid(source_pid).await else {
|
||||
return Err(ErrorCode::Core_Exception);
|
||||
};
|
||||
|
||||
let desgination_login_data = if destination_pid == self.destination_server_acct.pid {
|
||||
self.destination_server_acct.get_login_data()
|
||||
} else {
|
||||
let Some(login) = get_login_data_by_pid(destination_pid).await else {
|
||||
return Err(ErrorCode::Core_Exception);
|
||||
};
|
||||
login
|
||||
};
|
||||
|
||||
let result = QResult::success(Core_Unknown);
|
||||
|
||||
let ticket = generate_ticket(source_login_data, desgination_login_data);
|
||||
|
||||
Ok((result, ticket.into()))
|
||||
}
|
||||
|
||||
async fn get_pid(&self, username: String) -> Result<u32, ErrorCode> {
|
||||
Err(ErrorCode::Core_Exception)
|
||||
}
|
||||
|
||||
async fn get_name(&self, pid: u32) -> Result<String, ErrorCode> {
|
||||
Err(ErrorCode::Core_Exception)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::rmc::structures::connection_data::ConnectionData;
|
||||
use crate::rmc::structures::qresult::QResult;
|
||||
use crate::rmc::structures::RmcSerialize;
|
||||
use crate::rmc::response::RMCResponse;
|
||||
use std::io::Cursor;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
|
||||
let stuff = hex::decode("200100000a0106000000028000000100010051b3995774000000a6321c7f78847c1c5e9fb825eb26bd91841f1a40d92fc694159666119cb13527f1463ac48ad42a63e6613ede67041554b1770978112e6f1f3e177a2bfc75933216dbe38f70133a1eb28e2ae32a4b5c4b0c3e3efd4c02907992e259b257270b57a9dbe7792f4721b07f8fafb9e32d50f2555c616a015c0000004b007072756470733a2f5049443d323b7369643d313b73747265616d3d31303b747970653d323b616464726573733d322e3234332e39352e3131333b706f72743d31303030313b4349443d3100000000000100002c153ba51f00000033006272616e63683a6f726967696e2f70726f6a6563742f7775702d61676d6a206275696c643a335f385f31355f323030345f3000").unwrap();
|
||||
let stuff = RMCResponse::new(&mut Cursor::new(stuff)).unwrap();
|
||||
|
||||
let crate::rmc::response::RMCResponseResult::Success { call_id, method_id, data: stuff} = stuff.response_result else {
|
||||
panic!()
|
||||
};
|
||||
|
||||
|
||||
|
||||
// let stuff = hex::decode("0100010051B399577400000085F1736FCFBE93660275A3FE36FED6C2EFC57222AC99A9219CF54170A415B02DF1463AC48AD42A6307813FDE67041554B177097832ED000F892D9551A09F88E9CB0388DC1BC9527CC7384556A3287B2A349ABBF7E34A5A3EC14C2287CC7F78DA616BC3B03A035347FBD2E9A505C8EF42447CD809015F0000004E007072756470733A2F73747265616D3D31303B747970653D323B616464726573733D3139322E3136382E3137382E3132303B706F72743D31303030313B4349443D313B5049443D323B7369643D310000000000010000CDF53AA51F00000033006272616E63683A6F726967696E2F70726F6A6563742F7775702D61676D6A206275696C643A335F385F31355F323030345F3000").unwrap();
|
||||
// let stuff = hex::decode("0100010051b399577400000037d3d4814d2b16dd546c94a75d32637b45f856b5abe73cf26cfaa235c5f2c1cef1463ac48ad42a637d873fde67041554b177097880cfa7e10bb810eaf686bfb0a0cf3d65b1f476ebc046d0855327986f557dca14fbb8594883c186b863f2206f22baa0309dbcc81da2f883cb2cdc12628ec7fced015c0000004b007072756470733a2f5049443d323b7369643d313b73747265616d3d31303b747970653d323b616464726573733d322e3234332e39352e3131333b706f72743d31303030313b4349443d310000000000010000b7f33aa51f00000033006272616e63683a6f726967696e2f70726f6a6563742f7775702d61676d6a206275696c643a335f385f31355f323030345f3000").unwrap();
|
||||
|
||||
let data = <(QResult, u32, Vec<u8>, ConnectionData, String) as RmcSerialize>::deserialize(
|
||||
&mut Cursor::new(stuff),
|
||||
).unwrap();
|
||||
|
||||
println!("data: {:?}", data);
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +1,2 @@
|
|||
pub mod account;
|
||||
pub mod account;
|
||||
pub mod auth_handler;
|
||||
|
|
@ -3,5 +3,6 @@ pub mod router;
|
|||
pub mod socket;
|
||||
mod auth_module;
|
||||
pub mod sockaddr;
|
||||
//pub mod secure;
|
||||
pub mod station_url;
|
||||
pub mod station_url;
|
||||
pub mod secure;
|
||||
pub mod unsecure;
|
||||
|
|
@ -50,8 +50,7 @@ impl Router {
|
|||
trace!("got valid prudp packet from someone({}): \n{:?}", addr, packet);
|
||||
|
||||
let connection = packet.source_sockaddr(addr);
|
||||
|
||||
println!("data from {:?}", connection);
|
||||
|
||||
|
||||
let endpoints = self.endpoints.read().await;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,10 +4,13 @@ use log::error;
|
|||
use rc4::cipher::StreamCipherCoreWrapper;
|
||||
use rc4::{KeyInit, Rc4, Rc4Core, StreamCipher};
|
||||
use rc4::consts::U16;
|
||||
use typenum::U5;
|
||||
use crate::endianness::{IS_BIG_ENDIAN, ReadExtensions};
|
||||
use crate::kerberos::{derive_key, TicketInternalData};
|
||||
use crate::nex::account::Account;
|
||||
use crate::prudp::socket::EncryptionPair;
|
||||
use crate::prudp::packet::PRUDPPacket;
|
||||
use crate::prudp::socket::{CryptoHandler, CryptoHandlerConnectionInstance, EncryptionPair};
|
||||
use crate::prudp::unsecure::UnsecureInstance;
|
||||
use crate::rmc::structures::RmcSerialize;
|
||||
|
||||
pub fn read_secure_connection_data(data: &[u8], act: &Account) -> Option<([u8; 32], u32, u32)>{
|
||||
|
|
@ -97,4 +100,93 @@ pub fn generate_secure_encryption_pairs(mut session_key: [u8; 32], count: u8) ->
|
|||
}
|
||||
|
||||
vec
|
||||
}
|
||||
|
||||
|
||||
pub struct Secure(pub &'static str, pub &'static Account);
|
||||
|
||||
|
||||
pub struct SecureInstance {
|
||||
access_key: &'static str,
|
||||
session_key: [u8; 32],
|
||||
streams: Vec<EncryptionPair<Rc4<U32>>>,
|
||||
self_signature: [u8; 16],
|
||||
remote_signature: [u8; 16],
|
||||
pid: u32,
|
||||
}
|
||||
|
||||
impl CryptoHandler for Secure {
|
||||
type CryptoConnectionInstance = SecureInstance;
|
||||
|
||||
fn instantiate(
|
||||
&self,
|
||||
remote_signature: [u8; 16],
|
||||
self_signature: [u8; 16],
|
||||
payload: &[u8],
|
||||
substream_count: u8,
|
||||
) -> Option<(Vec<u8>, Self::CryptoConnectionInstance)> {
|
||||
let (session_key, pid, check_value) = read_secure_connection_data(payload, &self.1)?;
|
||||
|
||||
let check_value_response = check_value + 1;
|
||||
|
||||
let data = bytemuck::bytes_of(&check_value_response);
|
||||
|
||||
let mut response = Vec::new();
|
||||
|
||||
data.serialize(&mut response).ok()?;
|
||||
|
||||
let encryption_pairs = generate_secure_encryption_pairs(session_key, substream_count);
|
||||
|
||||
Some((
|
||||
response,
|
||||
SecureInstance {
|
||||
pid,
|
||||
streams: encryption_pairs,
|
||||
session_key,
|
||||
access_key: self.0,
|
||||
remote_signature,
|
||||
self_signature,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
fn sign_pre_handshake(&self, packet: &mut PRUDPPacket) {
|
||||
packet.set_sizes();
|
||||
packet.calculate_and_assign_signature(self.0, None, None);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl CryptoHandlerConnectionInstance for SecureInstance {
|
||||
type Encryption = Rc4<U5>;
|
||||
|
||||
fn decrypt_incoming(&mut self, substream: u8, data: &mut [u8]) {
|
||||
if let Some(crypt_pair) = self.streams.get_mut(substream as usize){
|
||||
crypt_pair.recv.apply_keystream(data);
|
||||
}
|
||||
}
|
||||
|
||||
fn encrypt_outgoing(&mut self, substream: u8, data: &mut [u8]) {
|
||||
if let Some(crypt_pair) = self.streams.get_mut(substream as usize){
|
||||
crypt_pair.send.apply_keystream(data);
|
||||
}
|
||||
}
|
||||
|
||||
fn get_user_id(&self) -> u32 {
|
||||
self.pid
|
||||
}
|
||||
|
||||
fn sign_connect(&self, packet: &mut PRUDPPacket) {
|
||||
packet.set_sizes();
|
||||
packet.calculate_and_assign_signature(self.access_key, None, Some(self.self_signature));
|
||||
}
|
||||
|
||||
fn sign_packet(&self, packet: &mut PRUDPPacket) {
|
||||
packet.set_sizes();
|
||||
packet.calculate_and_assign_signature(self.access_key, Some(self.session_key), Some(self.self_signature));
|
||||
}
|
||||
|
||||
fn verify_packet(&self, packet: &PRUDPPacket) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
|
@ -27,6 +27,7 @@ use tokio::net::UdpSocket;
|
|||
use tokio::sync::mpsc::{channel, Receiver, Sender};
|
||||
use tokio::sync::{Mutex, RwLock};
|
||||
use tokio_stream::Stream;
|
||||
use crate::nex::account::Account;
|
||||
// due to the way this is designed crashing the router thread causes deadlock, sorry ;-;
|
||||
// (maybe i will fix that some day)
|
||||
|
||||
|
|
@ -39,473 +40,13 @@ pub struct EncryptionPair<T: StreamCipher + Send> {
|
|||
}
|
||||
|
||||
impl<T: StreamCipher + Send> EncryptionPair<T> {
|
||||
fn init_both<F: Fn() -> T>(func: F) -> Self {
|
||||
pub fn init_both<F: Fn() -> T>(func: F) -> Self {
|
||||
Self {
|
||||
recv: func(),
|
||||
send: func(),
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
pub async fn process_packet(
|
||||
self: &Arc<Self>,
|
||||
client_address: PRUDPSockAddr,
|
||||
packet: &PRUDPPacket,
|
||||
) {
|
||||
let conn = self.connections.read().await;
|
||||
|
||||
if !conn.contains_key(&client_address) {
|
||||
drop(conn);
|
||||
|
||||
let mut conn = self.connections.write().await;
|
||||
//only insert if we STILL dont have the connection preventing double insertion
|
||||
if !conn.contains_key(&client_address) {
|
||||
conn.insert(
|
||||
client_address,
|
||||
(
|
||||
Arc::new(Mutex::new(ConnectionData {
|
||||
sock_addr: client_address,
|
||||
id: random(),
|
||||
signature: [0; 16],
|
||||
server_signature: [0; 16],
|
||||
|
||||
active_connection_data: None,
|
||||
})),
|
||||
Arc::new(Mutex::new(())),
|
||||
),
|
||||
);
|
||||
}
|
||||
drop(conn);
|
||||
} else {
|
||||
drop(conn);
|
||||
}
|
||||
|
||||
let connections = self.connections.read().await;
|
||||
|
||||
let Some(conn) = connections.get(&client_address) else {
|
||||
error!("connection is still not present after making sure connection is present, giving up.");
|
||||
return;
|
||||
};
|
||||
|
||||
let conn = conn.clone();
|
||||
|
||||
// dont keep holding the connections list unnescesarily
|
||||
drop(connections);
|
||||
|
||||
let mutual_exclusion_packet_handeling_mtx = conn.1.lock().await;
|
||||
let mut connection = conn.0.lock().await;
|
||||
|
||||
if (packet.header.types_and_flags.get_flags() & ACK) != 0 {
|
||||
//todo: handle acknowledgements and resending packets propperly
|
||||
println!("got ack");
|
||||
return;
|
||||
}
|
||||
|
||||
if (packet.header.types_and_flags.get_flags() & MULTI_ACK) != 0 {
|
||||
println!("got multi ack");
|
||||
return;
|
||||
}
|
||||
|
||||
match packet.header.types_and_flags.get_types() {
|
||||
SYN => {
|
||||
println!("got syn");
|
||||
// reset heartbeat?
|
||||
let mut response_packet = packet.base_response_packet();
|
||||
|
||||
response_packet.header.types_and_flags.set_types(SYN);
|
||||
response_packet.header.types_and_flags.set_flag(ACK);
|
||||
response_packet.header.types_and_flags.set_flag(HAS_SIZE);
|
||||
|
||||
connection.signature = client_address.calculate_connection_signature();
|
||||
|
||||
response_packet
|
||||
.options
|
||||
.push(ConnectionSignature(connection.signature));
|
||||
|
||||
for options in &packet.options {
|
||||
match options {
|
||||
SupportedFunctions(functions) => response_packet
|
||||
.options
|
||||
.push(SupportedFunctions(*functions & 0x04)),
|
||||
MaximumSubstreamId(max_substream) => response_packet
|
||||
.options
|
||||
.push(MaximumSubstreamId(*max_substream)),
|
||||
_ => { /* ??? */ }
|
||||
}
|
||||
}
|
||||
|
||||
response_packet.set_sizes();
|
||||
|
||||
response_packet.calculate_and_assign_signature(self.access_key, None, None);
|
||||
|
||||
let mut vec = Vec::new();
|
||||
|
||||
response_packet
|
||||
.write_to(&mut vec)
|
||||
.expect("somehow failed to convert backet to bytes");
|
||||
|
||||
self.socket
|
||||
.send_to(&vec, client_address.regular_socket_addr)
|
||||
.await
|
||||
.expect("failed to send data back");
|
||||
}
|
||||
CONNECT => {
|
||||
println!("got connect");
|
||||
let Some(MaximumSubstreamId(max_substream)) = packet
|
||||
.options
|
||||
.iter()
|
||||
.find(|v| matches!(v, MaximumSubstreamId(_)))
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
let Some((response_data, encryption_pairs, active_secure_connection_data)) =
|
||||
(self.on_connect_handler)(packet.clone(), *max_substream).await
|
||||
else {
|
||||
error!("invalid connection request");
|
||||
return;
|
||||
};
|
||||
|
||||
connection.active_connection_data = Some(ActiveConnectionData {
|
||||
encryption_pairs,
|
||||
reliable_client_queue: VecDeque::new(),
|
||||
reliable_client_counter: 2,
|
||||
reliable_server_counter: 1,
|
||||
server_session_id: packet.header.session_id,
|
||||
active_secure_connection_data,
|
||||
connection_id: random(),
|
||||
});
|
||||
|
||||
let mut response_packet = packet.base_response_packet();
|
||||
|
||||
response_packet.payload = response_data;
|
||||
|
||||
response_packet.header.types_and_flags.set_types(CONNECT);
|
||||
response_packet.header.types_and_flags.set_flag(ACK);
|
||||
response_packet.header.types_and_flags.set_flag(HAS_SIZE);
|
||||
|
||||
// todo: (or not) sliding windows and stuff
|
||||
|
||||
response_packet.header.session_id = packet.header.session_id;
|
||||
response_packet.header.sequence_id = 1;
|
||||
|
||||
response_packet
|
||||
.options
|
||||
.push(ConnectionSignature(Default::default()));
|
||||
|
||||
//let mut init_seq_id = 0;
|
||||
|
||||
for option in &packet.options {
|
||||
match option {
|
||||
MaximumSubstreamId(max_substream) => response_packet
|
||||
.options
|
||||
.push(MaximumSubstreamId(*max_substream)),
|
||||
SupportedFunctions(funcs) => {
|
||||
response_packet.options.push(SupportedFunctions(*funcs))
|
||||
}
|
||||
ConnectionSignature(sig) => connection.server_signature = *sig,
|
||||
PacketOption::InitialSequenceId(_id) => {
|
||||
//init_seq_id = *id;
|
||||
}
|
||||
_ => { /* ? */ }
|
||||
}
|
||||
}
|
||||
|
||||
// Splatoon doesnt use compression so we arent gonna compress unless i at some point
|
||||
// want to implement some server which requires it
|
||||
// No encryption here for the same reason
|
||||
|
||||
// todo: implement something to do secure servers
|
||||
|
||||
if connection.server_signature == <[u8; 16] as Default>::default() {
|
||||
error!("didn't get connection signature from client")
|
||||
}
|
||||
|
||||
response_packet.set_sizes();
|
||||
|
||||
response_packet.calculate_and_assign_signature(
|
||||
self.access_key,
|
||||
None,
|
||||
Some(connection.server_signature),
|
||||
);
|
||||
|
||||
let mut vec = Vec::new();
|
||||
response_packet
|
||||
.write_to(&mut vec)
|
||||
.expect("somehow failed to convert backet to bytes");
|
||||
|
||||
self.socket
|
||||
.send_to(&vec, client_address.regular_socket_addr)
|
||||
.await
|
||||
.expect("failed to send data back");
|
||||
}
|
||||
DATA => {
|
||||
if (packet.header.types_and_flags.get_flags() & RELIABLE) != 0 {
|
||||
let Some(active_connection) = connection.active_connection_data.as_mut() else {
|
||||
error!("got data packet on non active connection!");
|
||||
return;
|
||||
};
|
||||
|
||||
match active_connection
|
||||
.reliable_client_queue
|
||||
.binary_search_by_key(&packet.header.sequence_id, |p| p.header.sequence_id)
|
||||
{
|
||||
Ok(_) => warn!("recieved packet twice"),
|
||||
Err(position) => active_connection
|
||||
.reliable_client_queue
|
||||
.insert(position, packet.clone()),
|
||||
}
|
||||
|
||||
if (packet.header.types_and_flags.get_flags() & NEED_ACK) != 0 {
|
||||
let mut ack = packet.base_acknowledgement_packet();
|
||||
ack.header.session_id = active_connection.server_session_id;
|
||||
|
||||
ack.set_sizes();
|
||||
let potential_session_key = connection
|
||||
.active_connection_data
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.active_secure_connection_data
|
||||
.as_ref()
|
||||
.map(|s| s.session_key);
|
||||
|
||||
ack.calculate_and_assign_signature(
|
||||
self.access_key,
|
||||
potential_session_key,
|
||||
Some(connection.server_signature),
|
||||
);
|
||||
|
||||
let mut vec = Vec::new();
|
||||
ack.write_to(&mut vec)
|
||||
.expect("somehow failed to convert backet to bytes");
|
||||
|
||||
self.socket
|
||||
.send_to(&vec, client_address.regular_socket_addr)
|
||||
.await
|
||||
.expect("failed to send data back");
|
||||
}
|
||||
drop(connection);
|
||||
while let Some(mut packet) = {
|
||||
let mut locked = conn.0.lock().await;
|
||||
|
||||
let packet = locked
|
||||
.active_connection_data
|
||||
.as_mut()
|
||||
.map(|a| {
|
||||
a.reliable_client_queue
|
||||
.front()
|
||||
.is_some_and(|v| {
|
||||
v.header.sequence_id == a.reliable_client_counter
|
||||
})
|
||||
.then(|| a.reliable_client_queue.pop_front())
|
||||
})
|
||||
.flatten()
|
||||
.flatten();
|
||||
|
||||
drop(locked);
|
||||
packet
|
||||
} {
|
||||
if packet.options.iter().any(|v| match v {
|
||||
PacketOption::FragmentId(f) => *f != 0,
|
||||
_ => false,
|
||||
}) {
|
||||
error!("fragmented packets are unsupported right now")
|
||||
}
|
||||
|
||||
let mut locked = conn.0.lock().await;
|
||||
|
||||
let active_connection = locked.active_connection_data.as_mut()
|
||||
.expect("we litterally just recieved a packet which requires the connection to be active, failing this should be impossible");
|
||||
|
||||
active_connection.reliable_client_counter = active_connection
|
||||
.reliable_client_counter
|
||||
.overflowing_add(1)
|
||||
.0;
|
||||
|
||||
let Some(stream) = active_connection
|
||||
.encryption_pairs
|
||||
.get_mut(packet.header.substream_id as usize)
|
||||
.map(|e| &mut e.recv)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
stream.apply_keystream(&mut packet.payload);
|
||||
|
||||
drop(locked);
|
||||
// we cant divert this off to another thread we HAVE to process it now to keep order
|
||||
|
||||
(self.on_data_handler)(packet, self.clone(), conn.0.clone()).await;
|
||||
// ignored for now
|
||||
}
|
||||
} else {
|
||||
error!("unreliable packets are unimplemented");
|
||||
unimplemented!()
|
||||
}
|
||||
//info!("{:?}", packet);
|
||||
}
|
||||
PING => {
|
||||
let ConnectionData {
|
||||
active_connection_data,
|
||||
server_signature,
|
||||
..
|
||||
} = &mut *connection;
|
||||
|
||||
info!("got ping");
|
||||
|
||||
if (packet.header.types_and_flags.get_flags() & NEED_ACK) != 0 {
|
||||
let Some(active_connection) = active_connection_data.as_mut() else {
|
||||
error!("got data packet on non active connection!");
|
||||
return;
|
||||
};
|
||||
|
||||
let mut ack = packet.base_acknowledgement_packet();
|
||||
ack.header.session_id = active_connection.server_session_id;
|
||||
|
||||
ack.set_sizes();
|
||||
|
||||
let potential_session_key = active_connection
|
||||
.active_secure_connection_data
|
||||
.as_ref()
|
||||
.map(|s| s.session_key);
|
||||
|
||||
ack.calculate_and_assign_signature(
|
||||
self.access_key,
|
||||
potential_session_key,
|
||||
Some(*server_signature),
|
||||
);
|
||||
|
||||
let mut vec = Vec::new();
|
||||
ack.write_to(&mut vec)
|
||||
.expect("somehow failed to convert backet to bytes");
|
||||
|
||||
self.socket
|
||||
.send_to(&vec, client_address.regular_socket_addr)
|
||||
.await
|
||||
.expect("failed to send data back");
|
||||
}
|
||||
}
|
||||
DISCONNECT => {
|
||||
println!("got disconnect");
|
||||
let Some(active_connection) = &connection.active_connection_data else {
|
||||
return;
|
||||
};
|
||||
|
||||
let mut ack = packet.base_acknowledgement_packet();
|
||||
|
||||
ack.header.session_id = active_connection.server_session_id;
|
||||
|
||||
ack.set_sizes();
|
||||
|
||||
let potential_session_key = active_connection
|
||||
.active_secure_connection_data
|
||||
.as_ref()
|
||||
.map(|s| s.session_key);
|
||||
|
||||
ack.calculate_and_assign_signature(
|
||||
self.access_key,
|
||||
potential_session_key,
|
||||
Some(connection.server_signature),
|
||||
);
|
||||
|
||||
let mut vec = Vec::new();
|
||||
ack.write_to(&mut vec)
|
||||
.expect("somehow failed to convert backet to bytes");
|
||||
|
||||
self.socket
|
||||
.send_to(&vec, client_address.regular_socket_addr)
|
||||
.await
|
||||
.expect("failed to send data back");
|
||||
self.socket
|
||||
.send_to(&vec, client_address.regular_socket_addr)
|
||||
.await
|
||||
.expect("failed to send data back");
|
||||
self.socket
|
||||
.send_to(&vec, client_address.regular_socket_addr)
|
||||
.await
|
||||
.expect("failed to send data back");
|
||||
}
|
||||
_ => error!(
|
||||
"unimplemented packet type: {}",
|
||||
packet.header.types_and_flags.get_types()
|
||||
),
|
||||
}
|
||||
|
||||
drop(mutual_exclusion_packet_handeling_mtx)
|
||||
}*/
|
||||
/*
|
||||
impl ConnectionData {
|
||||
pub async fn finish_and_send_packet_to(
|
||||
&mut self,
|
||||
socket: &SocketData,
|
||||
mut packet: PRUDPPacket,
|
||||
) {
|
||||
let mut web = WEB_DATA.lock().await;
|
||||
web.data.push((
|
||||
self.sock_addr.regular_socket_addr,
|
||||
Outgoing(hex::encode(&packet.payload)),
|
||||
));
|
||||
drop(web);
|
||||
|
||||
if (packet.header.types_and_flags.get_flags() & RELIABLE) != 0 {
|
||||
let Some(active_connection) = self.active_connection_data.as_mut() else {
|
||||
error!("tried to send a secure packet to an inactive connection");
|
||||
return;
|
||||
};
|
||||
|
||||
packet.header.sequence_id = active_connection.reliable_server_counter;
|
||||
active_connection.reliable_server_counter += 1;
|
||||
|
||||
let Some(encryption) = active_connection
|
||||
.encryption_pairs
|
||||
.get_mut(packet.header.substream_id as usize)
|
||||
.map(|e| &mut e.send)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
encryption.apply_keystream(&mut packet.payload);
|
||||
}
|
||||
|
||||
packet.header.session_id = self
|
||||
.active_connection_data
|
||||
.as_ref()
|
||||
.map(|v| v.server_session_id)
|
||||
.unwrap_or_default();
|
||||
|
||||
packet.header.source_port = socket.virtual_port;
|
||||
packet.header.destination_port = self.sock_addr.virtual_port;
|
||||
|
||||
packet.set_sizes();
|
||||
|
||||
let potential_session_key = self
|
||||
.active_connection_data
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.active_secure_connection_data
|
||||
.as_ref()
|
||||
.map(|s| s.session_key);
|
||||
|
||||
packet.calculate_and_assign_signature(
|
||||
socket.access_key,
|
||||
potential_session_key,
|
||||
Some(self.server_signature),
|
||||
);
|
||||
let mut vec = Vec::new();
|
||||
|
||||
packet
|
||||
.write_to(&mut vec)
|
||||
.expect("somehow failed to convert backet to bytes");
|
||||
|
||||
if let Err(e) = socket
|
||||
.socket
|
||||
.send_to(&vec, self.sock_addr.regular_socket_addr)
|
||||
.await
|
||||
{
|
||||
error!("unable to send packet to destination: {}", e);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
pub struct NewEncryptionPair<E: StreamCipher> {
|
||||
pub send: E,
|
||||
|
|
@ -538,9 +79,11 @@ impl<E: CryptoHandlerConnectionInstance> Deref for InternalConnection<E>{
|
|||
|
||||
impl<E: CryptoHandlerConnectionInstance> InternalConnection<E>{
|
||||
fn next_server_count(&mut self) -> u16{
|
||||
let prev_val = self.reliable_server_counter;
|
||||
let (val, _) = self.reliable_server_counter.overflowing_add(1);
|
||||
self.reliable_server_counter = val;
|
||||
val
|
||||
println!("{}", prev_val);
|
||||
prev_val
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -645,14 +188,14 @@ impl<T: CryptoHandlerConnectionInstance> AnyInternalConnection for InternalConne
|
|||
|
||||
self.crypto_handler_instance.sign_packet(&mut packet);
|
||||
|
||||
packet.set_sizes();
|
||||
|
||||
let mut vec = Vec::new();
|
||||
|
||||
packet
|
||||
.write_to(&mut vec)
|
||||
.expect("somehow failed to convert backet to bytes");
|
||||
|
||||
println!("{}", hex::encode(&vec));
|
||||
|
||||
self.socket
|
||||
.send_to(&vec, self.socket_addr.regular_socket_addr)
|
||||
.await
|
||||
|
|
@ -670,8 +213,6 @@ impl<T: CryptoHandler> InternalSocket<T> {
|
|||
.write_to(&mut vec)
|
||||
.expect("somehow failed to convert backet to bytes");
|
||||
|
||||
println!("sent out: {}", hex::encode(&vec));
|
||||
|
||||
self.socket
|
||||
.send_to(&vec, dest.regular_socket_addr)
|
||||
.await
|
||||
|
|
@ -824,12 +365,15 @@ impl<T: CryptoHandler> InternalSocket<T> {
|
|||
|
||||
let session_id = packet.header.session_id;
|
||||
|
||||
let (return_data, crypto) = self.crypto_handler.instantiate(
|
||||
let Some((return_data, crypto)) = self.crypto_handler.instantiate(
|
||||
remote_signature,
|
||||
*own_signature,
|
||||
&packet.payload,
|
||||
1 + *max_substream,
|
||||
);
|
||||
) else {
|
||||
error!("someone attempted to connect with invalid data");
|
||||
return;
|
||||
};
|
||||
|
||||
let mut response = packet.base_response_packet();
|
||||
response.header.types_and_flags.set_types(CONNECT);
|
||||
|
|
@ -895,12 +439,6 @@ impl<T: CryptoHandler> InternalSocket<T> {
|
|||
|
||||
mem::swap(&mut data, &mut packet.payload);
|
||||
|
||||
conn.data_sender.send(data).await.expect("socket died");
|
||||
|
||||
if packet.header.types_and_flags.get_flags() & NEED_ACK == 0{
|
||||
return;
|
||||
}
|
||||
|
||||
let mut response = packet.base_acknowledgement_packet();
|
||||
response.header.types_and_flags.set_flag(HAS_SIZE | ACK);
|
||||
response.header.session_id = conn.session_id;
|
||||
|
|
@ -908,6 +446,10 @@ impl<T: CryptoHandler> InternalSocket<T> {
|
|||
conn.crypto_handler_instance.sign_packet(&mut response);
|
||||
|
||||
self.send_packet_unbuffered(address, response).await;
|
||||
|
||||
conn.data_sender.send(data).await.ok();
|
||||
|
||||
|
||||
}
|
||||
|
||||
async fn handle_ping(&self, address: PRUDPSockAddr, packet: PRUDPPacket){
|
||||
|
|
@ -993,6 +535,8 @@ impl<T: CryptoHandler> AnyInternalSocket for InternalSocket<T> {
|
|||
SYN => self.handle_syn(address, packet).await,
|
||||
CONNECT => self.handle_connect(address, packet).await,
|
||||
DATA => self.handle_data(address, packet).await,
|
||||
DISCONNECT => self.handle_disconnect(address, packet).await,
|
||||
PING => self.handle_ping(address, packet).await,
|
||||
_ => {
|
||||
error!(
|
||||
"unimplemented packet type: {}",
|
||||
|
|
@ -1068,7 +612,7 @@ impl<T: CryptoHandler> AnyInternalSocket for InternalSocket<T> {
|
|||
return None;
|
||||
};
|
||||
|
||||
let (_, crypt) = self.crypto_handler.instantiate(remote_signature, *own_signature, &[], 1);
|
||||
let (_, crypt) = self.crypto_handler.instantiate(remote_signature, *own_signature, &[], 1)?;
|
||||
|
||||
//todo: make this work for secure servers as well
|
||||
self.create_connection(crypt, address, 0).await;
|
||||
|
|
@ -1130,7 +674,7 @@ pub trait CryptoHandler: Send + Sync + 'static {
|
|||
own_signature: [u8; 16],
|
||||
_: &[u8],
|
||||
substream_count: u8,
|
||||
) -> (Vec<u8>, Self::CryptoConnectionInstance);
|
||||
) -> Option<(Vec<u8>, Self::CryptoConnectionInstance)>;
|
||||
|
||||
fn sign_pre_handshake(&self, packet: &mut PRUDPPacket);
|
||||
}
|
||||
|
|
@ -1162,6 +706,7 @@ impl ExternalConnection{
|
|||
|
||||
impl SendingConnection{
|
||||
pub async fn send(&self, data: Vec<u8>) -> Option<()> {
|
||||
println!("{}", hex::encode(&data));
|
||||
let internal = self.inernal.upgrade()?;
|
||||
|
||||
let mut internal = internal.lock().await;
|
||||
|
|
@ -1169,81 +714,4 @@ impl SendingConnection{
|
|||
internal.send_data_packet(data).await;
|
||||
Some(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Unsecure(pub &'static str);
|
||||
|
||||
pub struct UnsecureInstance {
|
||||
key: &'static str,
|
||||
streams: Vec<EncryptionPair<Rc4<U5>>>,
|
||||
self_signature: [u8; 16],
|
||||
remote_signature: [u8; 16],
|
||||
}
|
||||
|
||||
// my hand was forced to use lazy so that we can guarantee this code
|
||||
// only runs once and so that i can put it here as a "constant" (for performance and readability)
|
||||
// since for some reason rust crypto doesn't have any const time key initialization
|
||||
static DEFAULT_KEY: Lazy<Key<U5>> = Lazy::new(|| Key::from(*b"CD&ML"));
|
||||
|
||||
impl CryptoHandler for Unsecure {
|
||||
type CryptoConnectionInstance = UnsecureInstance;
|
||||
|
||||
fn instantiate(
|
||||
&self,
|
||||
remote_signature: [u8; 16],
|
||||
self_signature: [u8; 16],
|
||||
_: &[u8],
|
||||
substream_count: u8,
|
||||
) -> (Vec<u8>, Self::CryptoConnectionInstance) {
|
||||
(
|
||||
Vec::new(),
|
||||
UnsecureInstance {
|
||||
streams: (0..substream_count)
|
||||
.map(|_| EncryptionPair::init_both(|| Rc4::new(&DEFAULT_KEY)))
|
||||
.collect(),
|
||||
key: self.0,
|
||||
remote_signature,
|
||||
self_signature,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn sign_pre_handshake(&self, packet: &mut PRUDPPacket) {
|
||||
packet.set_sizes();
|
||||
packet.calculate_and_assign_signature(self.0, None, None);
|
||||
}
|
||||
}
|
||||
|
||||
impl CryptoHandlerConnectionInstance for UnsecureInstance {
|
||||
type Encryption = Rc4<U5>;
|
||||
|
||||
fn decrypt_incoming(&mut self, substream: u8, data: &mut [u8]) {
|
||||
if let Some(crypt_pair) = self.streams.get_mut(substream as usize){
|
||||
crypt_pair.recv.apply_keystream(data);
|
||||
}
|
||||
}
|
||||
|
||||
fn encrypt_outgoing(&mut self, substream: u8, data: &mut [u8]) {
|
||||
if let Some(crypt_pair) = self.streams.get_mut(substream as usize){
|
||||
crypt_pair.send.apply_keystream(data);
|
||||
}
|
||||
}
|
||||
|
||||
fn get_user_id(&self) -> u32 {
|
||||
0
|
||||
}
|
||||
|
||||
fn sign_connect(&self, packet: &mut PRUDPPacket) {
|
||||
packet.set_sizes();
|
||||
packet.calculate_and_assign_signature(self.key, None, Some(self.self_signature));
|
||||
}
|
||||
|
||||
fn sign_packet(&self, packet: &mut PRUDPPacket) {
|
||||
packet.set_sizes();
|
||||
packet.calculate_and_assign_signature(self.key, None, Some(self.self_signature));
|
||||
}
|
||||
|
||||
fn verify_packet(&self, packet: &PRUDPPacket) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
84
src/prudp/unsecure.rs
Normal file
84
src/prudp/unsecure.rs
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
use once_cell::sync::Lazy;
|
||||
use rc4::{Key, KeyInit, Rc4, StreamCipher};
|
||||
use typenum::U5;
|
||||
use crate::prudp::packet::PRUDPPacket;
|
||||
use crate::prudp::socket::{CryptoHandler, CryptoHandlerConnectionInstance, EncryptionPair};
|
||||
|
||||
pub struct Unsecure(pub &'static str);
|
||||
|
||||
|
||||
|
||||
pub struct UnsecureInstance {
|
||||
key: &'static str,
|
||||
streams: Vec<EncryptionPair<Rc4<U5>>>,
|
||||
self_signature: [u8; 16],
|
||||
remote_signature: [u8; 16],
|
||||
}
|
||||
|
||||
// my hand was forced to use lazy so that we can guarantee this code
|
||||
// only runs once and so that i can put it here as a "constant" (for performance and readability)
|
||||
// since for some reason rust crypto doesn't have any const time key initialization
|
||||
static DEFAULT_KEY: Lazy<Key<U5>> = Lazy::new(|| Key::from(*b"CD&ML"));
|
||||
|
||||
impl CryptoHandler for Unsecure {
|
||||
type CryptoConnectionInstance = UnsecureInstance;
|
||||
|
||||
fn instantiate(
|
||||
&self,
|
||||
remote_signature: [u8; 16],
|
||||
self_signature: [u8; 16],
|
||||
_: &[u8],
|
||||
substream_count: u8,
|
||||
) -> Option<(Vec<u8>, Self::CryptoConnectionInstance)> {
|
||||
Some((
|
||||
Vec::new(),
|
||||
UnsecureInstance {
|
||||
streams: (0..substream_count)
|
||||
.map(|_| EncryptionPair::init_both(|| Rc4::new(&DEFAULT_KEY)))
|
||||
.collect(),
|
||||
key: self.0,
|
||||
remote_signature,
|
||||
self_signature,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
fn sign_pre_handshake(&self, packet: &mut PRUDPPacket) {
|
||||
packet.set_sizes();
|
||||
packet.calculate_and_assign_signature(self.0, None, None);
|
||||
}
|
||||
}
|
||||
|
||||
impl CryptoHandlerConnectionInstance for UnsecureInstance {
|
||||
type Encryption = Rc4<U5>;
|
||||
|
||||
fn decrypt_incoming(&mut self, substream: u8, data: &mut [u8]) {
|
||||
if let Some(crypt_pair) = self.streams.get_mut(substream as usize){
|
||||
crypt_pair.recv.apply_keystream(data);
|
||||
}
|
||||
}
|
||||
|
||||
fn encrypt_outgoing(&mut self, substream: u8, data: &mut [u8]) {
|
||||
if let Some(crypt_pair) = self.streams.get_mut(substream as usize){
|
||||
crypt_pair.send.apply_keystream(data);
|
||||
}
|
||||
}
|
||||
|
||||
fn get_user_id(&self) -> u32 {
|
||||
0
|
||||
}
|
||||
|
||||
fn sign_connect(&self, packet: &mut PRUDPPacket) {
|
||||
packet.set_sizes();
|
||||
packet.calculate_and_assign_signature(self.key, None, Some(self.self_signature));
|
||||
}
|
||||
|
||||
fn sign_packet(&self, packet: &mut PRUDPPacket) {
|
||||
packet.set_sizes();
|
||||
packet.calculate_and_assign_signature(self.key, None, Some(self.self_signature));
|
||||
}
|
||||
|
||||
fn verify_packet(&self, packet: &PRUDPPacket) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
|
@ -34,7 +34,7 @@ pub enum RemoteCallError {
|
|||
ServerError(ErrorCode),
|
||||
#[error("Connection broke")]
|
||||
ConnectionBroke,
|
||||
#[error("Error reading response data")]
|
||||
#[error("Error reading response data: {0}")]
|
||||
InvalidResponse(#[from] structures::Error),
|
||||
}
|
||||
|
||||
|
|
@ -148,7 +148,7 @@ macro_rules! define_rmc_proto {
|
|||
$($protocol:path),*
|
||||
}) => {
|
||||
paste::paste!{
|
||||
trait [<Local $name>]: std::any::Any $( + [<Raw $protocol>] + $protocol)* {
|
||||
pub trait [<Local $name>]: std::any::Any $( + [<Raw $protocol>] + $protocol)* {
|
||||
async fn rmc_call(&self, remote_response_connection: &crate::prudp::socket::SendingConnection, protocol_id: u16, method_id: u32, call_id: u32, rest: Vec<u8>){
|
||||
match protocol_id{
|
||||
$(
|
||||
|
|
@ -159,7 +159,7 @@ macro_rules! define_rmc_proto {
|
|||
}
|
||||
}
|
||||
|
||||
struct [<Remote $name>](crate::rmc::protocols::RmcConnection);
|
||||
pub struct [<Remote $name>](crate::rmc::protocols::RmcConnection);
|
||||
|
||||
impl crate::rmc::protocols::RemoteInstantiatable for [<Remote $name>]{
|
||||
fn new(conn: crate::rmc::protocols::RmcConnection) -> Self{
|
||||
|
|
@ -235,7 +235,7 @@ async fn handle_incoming<T: RmcCallable + Send + Sync + 'static>(
|
|||
return
|
||||
};
|
||||
|
||||
if proto_id & 0x80 == 0{
|
||||
if (proto_id & 0x80) == 0{
|
||||
let Some(response) = RMCResponse::new(&mut Cursor::new(v)).display_err_or_some() else {
|
||||
error!("ending rmc gateway.");
|
||||
return
|
||||
|
|
@ -260,9 +260,11 @@ async fn handle_incoming<T: RmcCallable + Send + Sync + 'static>(
|
|||
rest_of_data
|
||||
} = message;
|
||||
|
||||
info!("got rmc request, handeling it now...");
|
||||
|
||||
remote.rmc_call(&sending_conn, protocol_id, method_id, call_id, rest_of_data).await;
|
||||
|
||||
info!("got rmc request");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ pub struct RMCResponse {
|
|||
impl RMCResponse {
|
||||
pub fn new(stream: &mut (impl Seek + Read)) -> io::Result<Self>{
|
||||
// ignore the size for now this will only be used for checking
|
||||
let _: u32 = stream.read_struct(IS_BIG_ENDIAN)?;
|
||||
let size: u32 = stream.read_struct(IS_BIG_ENDIAN)?;
|
||||
|
||||
let protocol_id: u8 = stream.read_struct(IS_BIG_ENDIAN)?;
|
||||
|
||||
|
|
@ -54,9 +54,9 @@ impl RMCResponse {
|
|||
let method_id: u32 = stream.read_struct(IS_BIG_ENDIAN)?;
|
||||
let method_id = method_id & (!0x8000);
|
||||
|
||||
let mut data: Vec<u8> = Vec::new();
|
||||
let mut data: Vec<u8> = vec![0u8; (size - 2 - 4 - 4) as _];
|
||||
|
||||
stream.read_to_end(&mut data)?;
|
||||
stream.read(&mut data)?;
|
||||
|
||||
|
||||
RMCResponseResult::Success {
|
||||
|
|
@ -154,15 +154,13 @@ pub async fn send_result(
|
|||
method_id: u32,
|
||||
call_id: u32,
|
||||
) {
|
||||
|
||||
println!("{}", hex::encode(result.clone().unwrap()));
|
||||
let response_result = match result {
|
||||
Ok(v) => RMCResponseResult::Success {
|
||||
call_id,
|
||||
method_id,
|
||||
data: {
|
||||
let mut vec = Vec::new();
|
||||
v.serialize(&mut vec).expect("serialization error");
|
||||
vec
|
||||
}
|
||||
data: v
|
||||
},
|
||||
Err(e) =>
|
||||
RMCResponseResult::Error {
|
||||
|
|
@ -187,7 +185,7 @@ pub async fn send_response(connection: &SendingConnection, rmcresponse: RMCRespo
|
|||
//taken from kinnays error list directly
|
||||
#[allow(nonstandard_style)]
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, EnumTryInto)]
|
||||
#[derive(Debug, EnumTryInto, Clone, Copy)]
|
||||
pub enum ErrorCode {
|
||||
Core_Unknown = 0x00010001,
|
||||
Core_NotImplemented = 0x00010002,
|
||||
|
|
|
|||
|
|
@ -1,30 +1,15 @@
|
|||
use std::io::{Read, Write};
|
||||
use bytemuck::bytes_of;
|
||||
use macros::RmcSerialize;
|
||||
use crate::kerberos::KerberosDateTime;
|
||||
use crate::rmc::structures::{rmc_struct, RmcSerialize};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ConnectionData<'a>{
|
||||
pub station_url: &'a str,
|
||||
#[derive(Debug, RmcSerialize)]
|
||||
#[rmc_struct(1)]
|
||||
pub struct ConnectionData{
|
||||
pub station_url: String,
|
||||
pub special_protocols: Vec<u8>,
|
||||
pub special_station_url: &'a str,
|
||||
pub special_station_url: String,
|
||||
pub date_time: KerberosDateTime
|
||||
}
|
||||
|
||||
impl<'a> RmcSerialize for ConnectionData<'a>{
|
||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||
rmc_struct::write_struct(writer, 1, |v|{
|
||||
self.station_url.serialize(v).expect("unable to write station url");
|
||||
self.special_protocols.serialize(v).expect("unable to write special protocols");
|
||||
self.special_station_url.serialize(v).expect("unable to write special station url");
|
||||
v.write_all(bytes_of(&self.date_time)).expect("unable to write date time");
|
||||
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
fn deserialize(_reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ pub fn write_struct(writer: &mut dyn Write, version: u8, pred: impl FnOnce(&mut
|
|||
|
||||
(pred)(&mut scratch_space)?;
|
||||
|
||||
let u32_size= scratch_space.len() as u32;
|
||||
let u32_size = scratch_space.len() as u32;
|
||||
|
||||
writer.write_all(bytes_of(&u32_size))?;
|
||||
writer.write_all(&scratch_space)?;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue