fix forgetting to save file

This commit is contained in:
Maple 2026-02-01 21:10:03 +01:00
commit 7e3cade00e
11 changed files with 124 additions and 121 deletions

View file

@ -65,11 +65,14 @@ impl Crypto for Insecure {
packet_data: &[u8],
self_signat: [u8; 4],
remote_signat: [u8; 4],
) -> Self::Instance {
InsecureInstance {
pair: EncryptionPair::init_both(|| Rc4::new(&DEFAULT_KEY)),
self_signat,
remote_signat,
}
) -> Option<(Self::Instance, Vec<u8>)> {
Some((
InsecureInstance {
pair: EncryptionPair::init_both(|| Rc4::new(&DEFAULT_KEY)),
self_signat,
remote_signat,
},
vec![],
))
}
}

View file

@ -1,10 +1,18 @@
use hmac::Mac;
use rc4::{Rc4, StreamCipher};
use rnex_core::prudp::{
encryption::EncryptionPair,
types_flags::{TypesFlags, types::DATA},
use md5::{Digest, Md5};
use rc4::{KeyInit, Rc4, StreamCipher};
use rnex_core::{
executables::common::SECURE_SERVER_ACCOUNT,
nex::account::Account,
prudp::{
encryption::EncryptionPair,
ticket::read_secure_connection_data,
types_flags::{TypesFlags, types::DATA},
},
rmc::structures::RmcSerialize,
};
use typenum::U32;
use std::io::Write;
use typenum::U16;
use crate::crypto::{
Crypto, CryptoInstance,
@ -13,7 +21,7 @@ use crate::crypto::{
};
pub struct SecureInstance {
pair: EncryptionPair<Rc4<U32>>,
pair: EncryptionPair<Rc4<U16>>,
uid: u32,
self_signat: [u8; 4],
remote_signat: [u8; 4],
@ -34,7 +42,9 @@ impl CryptoInstance for SecureInstance {
if data.len() == 0 {
[0x78, 0x56, 0x34, 0x12]
} else {
let mut hmac = <HmacMd5 as Mac>::new_from_slice(ACCESS_KEY.as_bytes())
let mut hash = Md5::new();
hash.write(ACCESS_KEY.as_bytes()).unwrap();
let mut hmac = <HmacMd5 as Mac>::new_from_slice(&hash.finalize().as_slice())
.expect("unable to create hmac md5");
hmac.update(data);
hmac.finalize().into_bytes()[0..4].try_into().unwrap()
@ -45,12 +55,12 @@ impl CryptoInstance for SecureInstance {
}
}
pub struct Secure();
pub struct Secure(&'static Account);
impl Crypto for Secure {
type Instance = SecureInstance;
fn new() -> Self {
Self()
Self(&SECURE_SERVER_ACCOUNT)
}
fn calculate_checksum(&self, data: &[u8]) -> u8 {
common_checksum(ACCESS_KEY, data)
@ -60,7 +70,27 @@ impl Crypto for Secure {
data: &[u8],
self_signat: [u8; 4],
remote_signat: [u8; 4],
) -> Self::Instance {
todo!()
) -> Option<(Self::Instance, Vec<u8>)> {
let (session_key, pid, check_value) = read_secure_connection_data(data, &self.0)?;
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()?;
Some((
SecureInstance {
pair: EncryptionPair::init_both(|| {
Rc4::new_from_slice(&session_key).expect("unable to initialize rc4 stream")
}),
self_signat,
remote_signat,
uid: pid,
},
response,
))
}
}

View file

@ -19,7 +19,7 @@ pub trait Crypto: Send + Sync + 'static {
data: &[u8],
self_signat: [u8; 4],
remote_signat: [u8; 4],
) -> Self::Instance;
) -> Option<(Self::Instance, Vec<u8>)>;
}
cfg_if! {

View file

@ -1,7 +1,7 @@
use std::mem::transmute;
use bytemuck::{Pod, Zeroable, try_from_bytes, try_from_bytes_mut};
use log::{error, info};
use log::{error, info, warn};
use rnex_core::prudp::{
types_flags::{
self, TypesFlags,
@ -146,6 +146,15 @@ impl<T: AsRef<[u8]>> PRUDPV0Packet<T> {
let Some(checksum) = self.checksum() else {
return false;
};
if checksum != crypto.calculate_checksum(data) {
warn!(
"checksum doesnt match expected checksum: {} != {}",
checksum,
crypto.calculate_checksum(data)
)
}
checksum == crypto.calculate_checksum(data)
}
@ -230,7 +239,7 @@ pub fn new_connect_packet(
) -> Vec<u8> {
let type_flags = TypesFlags::default().types(CONNECT).flags(flags);
let vec = vec![0; precalc_size(type_flags, 0)];
let vec = vec![0; precalc_size(type_flags, data.len())];
let mut packet = PRUDPV0Packet::new(vec);
let header = packet.header_mut().expect("packet malformed in creation");
@ -245,6 +254,12 @@ pub fn new_connect_packet(
*packet
.connection_signature_mut()
.expect("packet malformed in creation") = remote_signat;
packet
.payload_mut()
.expect("packet malformed in creation")
.copy_from_slice(data);
if let Some(size) = packet.size_mut() {
size.copy_from_slice(&(data.len() as u16).to_le_bytes());
}
@ -281,6 +296,8 @@ pub fn new_data_packet(
.expect("packet malformed in creation")
.copy_from_slice(data);
crypto_instance.encrypt_outgoing(packet.payload_mut().expect("packet malformed in creation"));
if let Some(size) = packet.size_mut() {
size.copy_from_slice(&(data.len() as u16).to_le_bytes());
}

View file

@ -3,7 +3,7 @@ use std::{
hash::Hash,
net::{Ipv4Addr, SocketAddr, SocketAddrV4},
sync::{
Arc, LazyLock,
Arc, LazyLock, Weak,
atomic::{AtomicBool, AtomicU32},
},
thread::sleep,
@ -123,13 +123,14 @@ impl<C: Crypto> Server<C> {
let packet = Arc::new(packet);
let packet_ref = Arc::downgrade(&packet);
let conn = Arc::downgrade(&conn);
let this = Arc::downgrade(&self);
inner.unacknowledged_packets.insert(seq, packet);
drop(inner);
let conn = Arc::downgrade(&conn);
let this = Arc::downgrade(&self);
spawn(async move {
for n in 0..5 {
let Some(data) = packet_ref.upgrade() else {
@ -153,10 +154,11 @@ impl<C: Crypto> Server<C> {
}
async fn connection_thread(
self: Arc<Self>,
conn: Arc<Connection<C::Instance>>,
conn: Weak<Connection<C::Instance>>,
mut recv: SplittableBufferConnection,
) {
while let Some(data) = recv.recv().await {
let Some(conn) = conn.upgrade() else { break };
if &data[..] == &[0, 0, 0, 0, 0] {
info!("got keepalive");
continue;
@ -168,8 +170,8 @@ impl<C: Crypto> Server<C> {
async fn timeout_thread(self: Arc<Self>, conn: Arc<Connection<C::Instance>>) {
loop {
sleep(Duration::from_secs(3));
info!("running another loop");
let mut inner = conn.inner.lock().await;
if (Instant::now() - inner.last_action).as_secs() > 5 {
warn!("connection exceeded silence limit, sending ping");
let packet = new_ping_packet(
@ -187,11 +189,11 @@ impl<C: Crypto> Server<C> {
.await;
}
if (Instant::now() - conn.inner.lock().await.last_action).as_secs() > 15 {
if (Instant::now() - inner.last_action).as_secs() > 15 {
warn!("client timed out...");
let packet = new_disconnect_packet(
0,
NEED_ACK,
self.param.virtual_port,
conn.addr.virtual_port,
0,
@ -209,9 +211,12 @@ impl<C: Crypto> Server<C> {
self.socket
.send_to(&packet, conn.addr.regular_socket_addr)
.await;
drop(inner);
let mut conns = self.connections.write().await;
conns.remove(&conn.addr);
drop(conns);
break;
}
drop(inner);
@ -247,7 +252,10 @@ impl<C: Crypto> Server<C> {
remote_signat[3],
];
let ci = self.crypto.instantiate(data, self_signat, remote_signat);
let Some((ci, data)) = self.crypto.instantiate(&data, self_signat, remote_signat) else {
warn!("unable to instantiate crypto instance");
return;
};
let pid = ci.get_user_id();
let buf_conn = new_backend_connection(&self.param, addr, pid).await;
@ -281,7 +289,7 @@ impl<C: Crypto> Server<C> {
spawn({
let this = self.clone();
let conn = conn.clone();
let conn = Arc::downgrade(&conn);
this.connection_thread(conn, buf_conn)
});
spawn({
@ -297,7 +305,7 @@ impl<C: Crypto> Server<C> {
self_signat,
remote_signat,
packet.header().unwrap().session_id,
&[],
&data,
&self.crypto,
);
@ -314,10 +322,7 @@ impl<C: Crypto> Server<C> {
return;
};
let rd = self.connections.read().await;
let res = rd.get(&addr).cloned();
drop(rd);
let Some(res) = res else {
let Some(res) = self.get_connection(addr).await else {
warn!("data packet on inactive connection from: {:?}", addr);
return;
};
@ -335,7 +340,6 @@ impl<C: Crypto> Server<C> {
&self.crypto,
);
self.socket.send_to(&ack, addr.regular_socket_addr).await;
conn.last_action = Instant::now();
conn.packet_queue.insert(
packet.header().unwrap().sequence_id,
(Instant::now(), packet),
@ -356,6 +360,7 @@ impl<C: Crypto> Server<C> {
res.target.send(payload.to_owned()).await;
conn.client_packet_counter += 1;
}
info!("finished handeling packets, dropping inner connection");
drop(conn);
}
@ -378,7 +383,6 @@ impl<C: Crypto> Server<C> {
&self.crypto,
);
drop(inner);
drop(conn);
self.socket.send_to(&packet, addr.regular_socket_addr).await;
}
@ -405,7 +409,6 @@ impl<C: Crypto> Server<C> {
&self.crypto,
);
drop(inner);
drop(conn);
self.socket.send_to(&packet, addr.regular_socket_addr).await;
self.socket.send_to(&packet, addr.regular_socket_addr).await;
@ -429,17 +432,19 @@ impl<C: Crypto> Server<C> {
return;
};
info!("len: {}", packet.0.len());
let addr = PRUDPSockAddr::new(addr, header.source);
if header.type_flags.get_flags() & ACK != 0 {
info!("got ack(acks are ignored for now)");
return;
}
if let Some(conn) = self.get_connection(addr).await {
let mut inner = conn.inner.lock().await;
inner.last_action = Instant::now();
drop(inner);
};
if header.type_flags.get_flags() & ACK != 0 {
info!("got ack(acks are ignored for now)");
return;
}
println!("{:?}", header);
match header.type_flags.get_types() {
SYN => {
@ -464,20 +469,18 @@ impl<C: Crypto> Server<C> {
}
pub async fn run_task(self: Arc<Self>) {
loop {
let mut vec: Vec<u8> = vec![];
let addr = match self.socket.recv_buf_from(&mut vec).await {
let mut vec: Vec<u8> = vec![0u8; 65507];
let (len, addr) = match self.socket.recv_from(&mut vec).await {
Err(e) => {
error!("unable to recv: {}", e);
break;
}
Ok(v) => {
assert_eq!(vec.len(), v.0);
v.1
}
Ok(v) => v,
};
let this = self.clone();
tokio::spawn(async move {
let mut data = vec;
data.resize(len, 0);
let packet = PRUDPV0Packet::new(data);
let SocketAddr::V4(addr) = addr else {