more progress on friends
This commit is contained in:
parent
1b802ff33f
commit
7918e54487
19 changed files with 320 additions and 205 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -580,10 +580,12 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
|
"cfg-if",
|
||||||
"hmac",
|
"hmac",
|
||||||
"log",
|
"log",
|
||||||
"md-5",
|
"md-5",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
"proxy-common",
|
||||||
"rc4",
|
"rc4",
|
||||||
"rnex-core",
|
"rnex-core",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,17 @@
|
||||||
splatoon:
|
splatoon:
|
||||||
features:
|
features:
|
||||||
- rmc_struct_header
|
- rmc_struct_header
|
||||||
|
- prudpv1
|
||||||
settings:
|
settings:
|
||||||
AUTH_REPORT_VERSION: "branch:origin/project/wup-agmj build:3_8_15_2004_0"
|
AUTH_REPORT_VERSION: "branch:origin/project/wup-agmj build:3_8_15_2004_0"
|
||||||
|
RNEX_VIRTUAL_PORT_INSECURE: "1:16"
|
||||||
|
RNEX_VIRTUAL_PORT_SECURE: "0:0"
|
||||||
|
RNEX_DEFAULT_PORT: 6000
|
||||||
friends:
|
friends:
|
||||||
features:
|
features:
|
||||||
- friends
|
- friends
|
||||||
settings:
|
settings:
|
||||||
RNEX_VIRTUAL_PORT: 1:10
|
AUTH_REPORT_VERSION: "branch:origin/project/wup-agmj build:3_8_15_2004_0"
|
||||||
|
RNEX_VIRTUAL_PORT_INSECURE: "1:16"
|
||||||
|
RNEX_VIRTUAL_PORT_SECURE: "0:0"
|
||||||
|
RNEX_DEFAULT_PORT: 6000
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ rnex-core = { path = "../rnex-core", version = "0.1.1" }
|
||||||
prudpv0 = ["dep:prudpv0"]
|
prudpv0 = ["dep:prudpv0"]
|
||||||
prudpv1 = ["dep:prudpv1"]
|
prudpv1 = ["dep:prudpv1"]
|
||||||
friends = ["prudpv0", "prudpv0/friends"]
|
friends = ["prudpv0", "prudpv0/friends"]
|
||||||
|
splatoon = ["prudpv1"]
|
||||||
|
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
||||||
|
|
@ -16,4 +16,5 @@ hmac = "0.12.1"
|
||||||
md-5 = "^0.10.6"
|
md-5 = "^0.10.6"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
friends = []
|
prudpv0 = []
|
||||||
|
friends = ["prudpv0"]
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ impl CryptoInstance for InsecureInstance {
|
||||||
fn generate_signature(&self, types_flags: TypesFlags, data: &[u8]) -> [u8; 4] {
|
fn generate_signature(&self, types_flags: TypesFlags, data: &[u8]) -> [u8; 4] {
|
||||||
if types_flags.get_types() == DATA {
|
if types_flags.get_types() == DATA {
|
||||||
if data.len() == 0 {
|
if data.len() == 0 {
|
||||||
[0x12, 0x34, 0x56, 0x78]
|
[0x78, 0x56, 0x34, 0x12]
|
||||||
} else {
|
} else {
|
||||||
let mut hmac = <HmacMd5 as Mac>::new_from_slice(ACCESS_KEY.as_bytes())
|
let mut hmac = <HmacMd5 as Mac>::new_from_slice(ACCESS_KEY.as_bytes())
|
||||||
.expect("unable to create hmac md5");
|
.expect("unable to create hmac md5");
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
use hmac::Mac;
|
use hmac::Mac;
|
||||||
use rc4::Rc4;
|
use rc4::{Rc4, StreamCipher};
|
||||||
use rnex_core::prudp::{encryption::EncryptionPair, types_flags::TypesFlags};
|
use rnex_core::prudp::{
|
||||||
|
encryption::EncryptionPair,
|
||||||
|
types_flags::{TypesFlags, types::DATA},
|
||||||
|
};
|
||||||
use typenum::U32;
|
use typenum::U32;
|
||||||
|
|
||||||
use crate::crypto::{
|
use crate::crypto::{
|
||||||
|
|
@ -11,23 +14,34 @@ use crate::crypto::{
|
||||||
|
|
||||||
pub struct SecureInstance {
|
pub struct SecureInstance {
|
||||||
pair: EncryptionPair<Rc4<U32>>,
|
pair: EncryptionPair<Rc4<U32>>,
|
||||||
|
uid: u32,
|
||||||
|
self_signat: [u8; 4],
|
||||||
|
remote_signat: [u8; 4],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CryptoInstance for SecureInstance {
|
impl CryptoInstance for SecureInstance {
|
||||||
fn decrypt_incoming(&mut self, data: &mut [u8]) {
|
fn decrypt_incoming(&mut self, data: &mut [u8]) {
|
||||||
todo!()
|
self.pair.recv.apply_keystream(data);
|
||||||
}
|
}
|
||||||
fn encrypt_outgoing(&mut self, data: &mut [u8]) {
|
fn encrypt_outgoing(&mut self, data: &mut [u8]) {
|
||||||
todo!()
|
self.pair.send.apply_keystream(data);
|
||||||
}
|
}
|
||||||
fn get_user_id(&self) -> u32 {
|
fn get_user_id(&self) -> u32 {
|
||||||
todo!()
|
self.uid
|
||||||
}
|
}
|
||||||
fn generate_signature(&self, types_flags: TypesFlags, data: &[u8]) -> [u8; 4] {
|
fn generate_signature(&self, types_flags: TypesFlags, data: &[u8]) -> [u8; 4] {
|
||||||
let mut hmac = <HmacMd5 as Mac>::new_from_slice(ACCESS_KEY.as_bytes())
|
if types_flags.get_types() == DATA {
|
||||||
.expect("unable to create hmac md5");
|
if data.len() == 0 {
|
||||||
hmac.update(data);
|
[0x78, 0x56, 0x34, 0x12]
|
||||||
hmac.finalize().into_bytes()[0..4].try_into().unwrap()
|
} else {
|
||||||
|
let mut hmac = <HmacMd5 as Mac>::new_from_slice(ACCESS_KEY.as_bytes())
|
||||||
|
.expect("unable to create hmac md5");
|
||||||
|
hmac.update(data);
|
||||||
|
hmac.finalize().into_bytes()[0..4].try_into().unwrap()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.self_signat
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,62 +1,67 @@
|
||||||
use bytemuck::{Pod, Zeroable};
|
cfg_if::cfg_if! {
|
||||||
use log::{error, info, warn};
|
if #[cfg(feature = "prudpv0")] {
|
||||||
use proxy_common::{ProxyStartupParam, setup_edge_node_connection};
|
use bytemuck::{Pod, Zeroable};
|
||||||
use rnex_core::executables::common::{OWN_IP_PRIVATE, OWN_IP_PUBLIC, SERVER_PORT};
|
use cfg_if::cfg_if;
|
||||||
use rnex_core::prudp::types_flags::TypesFlags;
|
use log::{error, info, warn};
|
||||||
use rnex_core::prudp::types_flags::types::SYN;
|
use proxy_common::{ProxyStartupParam, setup_edge_node_connection};
|
||||||
use rnex_core::prudp::virtual_port::VirtualPort;
|
use rnex_core::executables::common::{OWN_IP_PRIVATE, OWN_IP_PUBLIC, SERVER_PORT};
|
||||||
use rnex_core::reggie::EdgeNodeHolderConnectOption::Register;
|
use rnex_core::prudp::types_flags::TypesFlags;
|
||||||
use rnex_core::reggie::RemoteEdgeNodeHolder;
|
use rnex_core::prudp::types_flags::types::SYN;
|
||||||
use rnex_core::rmc::protocols::{OnlyRemote, new_rmc_gateway_connection};
|
use rnex_core::prudp::virtual_port::VirtualPort;
|
||||||
use rnex_core::rmc::structures::RmcSerialize;
|
use rnex_core::reggie::EdgeNodeHolderConnectOption::Register;
|
||||||
use rnex_core::util::SplittableBufferConnection;
|
use rnex_core::reggie::RemoteEdgeNodeHolder;
|
||||||
use std::env;
|
use rnex_core::rmc::protocols::{OnlyRemote, new_rmc_gateway_connection};
|
||||||
use std::net::SocketAddrV4;
|
use rnex_core::rmc::structures::RmcSerialize;
|
||||||
use std::process::abort;
|
use rnex_core::util::SplittableBufferConnection;
|
||||||
use std::sync::{Arc, LazyLock};
|
use std::env;
|
||||||
use tokio::net::UdpSocket;
|
use std::net::SocketAddrV4;
|
||||||
|
use std::process::abort;
|
||||||
|
use std::sync::{Arc, LazyLock};
|
||||||
|
use tokio::net::UdpSocket;
|
||||||
|
|
||||||
use crate::crypto::{Crypto, Insecure, Secure};
|
use crate::crypto::{Crypto, Insecure, Secure};
|
||||||
use crate::packet::PRUDPV0Packet;
|
use crate::packet::PRUDPV0Packet;
|
||||||
use crate::server::Server;
|
use crate::server::Server;
|
||||||
|
|
||||||
mod crypto;
|
mod crypto;
|
||||||
mod packet;
|
mod packet;
|
||||||
mod server;
|
mod server;
|
||||||
|
|
||||||
pub static EDGE_NODE_HOLDER: LazyLock<SocketAddrV4> = LazyLock::new(|| {
|
pub static EDGE_NODE_HOLDER: LazyLock<SocketAddrV4> = LazyLock::new(|| {
|
||||||
env::var("EDGE_NODE_HOLDER")
|
env::var("EDGE_NODE_HOLDER")
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|s| s.parse().ok())
|
.and_then(|s| s.parse().ok())
|
||||||
.expect("EDGE_NODE_HOLDER not set")
|
.expect("EDGE_NODE_HOLDER not set")
|
||||||
});
|
});
|
||||||
|
|
||||||
pub static FORWARD_DESTINATION: LazyLock<SocketAddrV4> = LazyLock::new(|| {
|
pub static FORWARD_DESTINATION: LazyLock<SocketAddrV4> = LazyLock::new(|| {
|
||||||
env::var("FORWARD_DESTINATION")
|
env::var("FORWARD_DESTINATION")
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|s| s.parse().ok())
|
.and_then(|s| s.parse().ok())
|
||||||
.expect("FORWARD_DESTINATION not set")
|
.expect("FORWARD_DESTINATION not set")
|
||||||
});
|
});
|
||||||
//same as with prudpv1 this is responsible for handeling the different cryptography
|
//same as with prudpv1 this is responsible for handeling the different cryptography
|
||||||
//implementations, e.g. secure and insecure(this also includes special cases like friends)
|
//implementations, e.g. secure and insecure(this also includes special cases like friends)
|
||||||
|
|
||||||
async fn start_proxy<T: Crypto>(param: ProxyStartupParam) {
|
async fn start_proxy<T: Crypto>(param: ProxyStartupParam) {
|
||||||
setup_edge_node_connection(¶m, || abort());
|
setup_edge_node_connection(¶m, || abort());
|
||||||
|
|
||||||
info!("creating cryptography instance");
|
info!("creating cryptography instance");
|
||||||
let mut crypto = Arc::new(T::new());
|
let mut crypto = Arc::new(T::new());
|
||||||
info!("binding to socket");
|
info!("binding to socket");
|
||||||
|
|
||||||
let server: Arc<Server<T>> = Arc::new(Server::new(param).await);
|
let server: Arc<Server<T>> = Arc::new(Server::new(param).await);
|
||||||
|
|
||||||
info!("waiting on packets");
|
info!("waiting on packets");
|
||||||
server.run_task().await;
|
server.run_task().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn start_secure(param: ProxyStartupParam) {
|
pub async fn start_secure(param: ProxyStartupParam) {
|
||||||
start_proxy::<Secure>(param).await;
|
start_proxy::<Secure>(param).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn start_insecure(param: ProxyStartupParam) {
|
pub async fn start_insecure(param: ProxyStartupParam) {
|
||||||
start_proxy::<Insecure>(param).await;
|
start_proxy::<Insecure>(param).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ impl<T: AsRef<[u8]>> PRUDPV0Packet<T> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn size_mut(&mut self) -> Option<&mut u16>
|
pub fn size_mut(&mut self) -> Option<&mut [u8]>
|
||||||
where
|
where
|
||||||
T: AsMut<[u8]>,
|
T: AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
|
|
@ -74,9 +74,7 @@ impl<T: AsRef<[u8]>> PRUDPV0Packet<T> {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let offset = size_of::<PRUDPV0Header>() + get_type_specific_size(self.header()?.type_flags);
|
let offset = size_of::<PRUDPV0Header>() + get_type_specific_size(self.header()?.type_flags);
|
||||||
Some(bytemuck::from_bytes_mut(
|
Some(self.0.as_mut().get_mut(offset..offset + 2)?)
|
||||||
self.0.as_mut().get_mut(offset..offset + 2)?,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|
@ -224,7 +222,10 @@ pub fn new_connect_packet(
|
||||||
flags: u16,
|
flags: u16,
|
||||||
source: VirtualPort,
|
source: VirtualPort,
|
||||||
destination: VirtualPort,
|
destination: VirtualPort,
|
||||||
signat: [u8; 4],
|
self_signat: [u8; 4],
|
||||||
|
remote_signat: [u8; 4],
|
||||||
|
session_id: u8,
|
||||||
|
data: &[u8],
|
||||||
crypto: &impl Crypto,
|
crypto: &impl Crypto,
|
||||||
) -> Vec<u8> {
|
) -> Vec<u8> {
|
||||||
let type_flags = TypesFlags::default().types(CONNECT).flags(flags);
|
let type_flags = TypesFlags::default().types(CONNECT).flags(flags);
|
||||||
|
|
@ -236,15 +237,17 @@ pub fn new_connect_packet(
|
||||||
*header = PRUDPV0Header {
|
*header = PRUDPV0Header {
|
||||||
destination,
|
destination,
|
||||||
source,
|
source,
|
||||||
packet_signature: DEFAULT_SIGNAT,
|
packet_signature: self_signat,
|
||||||
sequence_id: 0,
|
sequence_id: 1,
|
||||||
session_id: 0,
|
session_id,
|
||||||
type_flags,
|
type_flags,
|
||||||
};
|
};
|
||||||
*packet
|
*packet
|
||||||
.connection_signature_mut()
|
.connection_signature_mut()
|
||||||
.expect("packet malformed in creation") = signat;
|
.expect("packet malformed in creation") = remote_signat;
|
||||||
|
if let Some(size) = packet.size_mut() {
|
||||||
|
size.copy_from_slice(&(data.len() as u16).to_le_bytes());
|
||||||
|
}
|
||||||
*packet.checksum_mut().expect("packet malformed in creation") = crypto.calculate_checksum(
|
*packet.checksum_mut().expect("packet malformed in creation") = crypto.calculate_checksum(
|
||||||
packet
|
packet
|
||||||
.checksummed_data()
|
.checksummed_data()
|
||||||
|
|
@ -279,7 +282,7 @@ pub fn new_data_packet(
|
||||||
.copy_from_slice(data);
|
.copy_from_slice(data);
|
||||||
|
|
||||||
if let Some(size) = packet.size_mut() {
|
if let Some(size) = packet.size_mut() {
|
||||||
*size = data.len() as u16;
|
size.copy_from_slice(&(data.len() as u16).to_le_bytes());
|
||||||
}
|
}
|
||||||
*packet
|
*packet
|
||||||
.fragment_id_mut()
|
.fragment_id_mut()
|
||||||
|
|
|
||||||
|
|
@ -244,10 +244,13 @@ impl<C: Crypto> Server<C> {
|
||||||
});
|
});
|
||||||
|
|
||||||
let packet = new_connect_packet(
|
let packet = new_connect_packet(
|
||||||
ACK,
|
ACK | HAS_SIZE,
|
||||||
header.destination,
|
header.destination,
|
||||||
header.source,
|
header.source,
|
||||||
|
self_signat,
|
||||||
remote_signat,
|
remote_signat,
|
||||||
|
packet.header().unwrap().session_id,
|
||||||
|
&[],
|
||||||
&self.crypto,
|
&self.crypto,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -274,7 +277,7 @@ impl<C: Crypto> Server<C> {
|
||||||
info!("frag: {}", frag_id);
|
info!("frag: {}", frag_id);
|
||||||
let mut conn = res.inner.lock().await;
|
let mut conn = res.inner.lock().await;
|
||||||
let ack = new_data_packet(
|
let ack = new_data_packet(
|
||||||
ACK | HAS_SIZE,
|
ACK,
|
||||||
self.param.virtual_port,
|
self.param.virtual_port,
|
||||||
res.addr.virtual_port,
|
res.addr.virtual_port,
|
||||||
&[],
|
&[],
|
||||||
|
|
@ -324,6 +327,12 @@ impl<C: Crypto> Server<C> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let addr = PRUDPSockAddr::new(addr, header.source);
|
let addr = PRUDPSockAddr::new(addr, header.source);
|
||||||
|
|
||||||
|
if header.type_flags.get_flags() & ACK != 0 {
|
||||||
|
info!("got ack(acks are ignored for now)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
println!("{:?}", header);
|
println!("{:?}", header);
|
||||||
match header.type_flags.get_types() {
|
match header.type_flags.get_types() {
|
||||||
SYN => {
|
SYN => {
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,8 @@ async-trait = "0.1.88"
|
||||||
typenum = "1.18.0"
|
typenum = "1.18.0"
|
||||||
once_cell = "1.21.3"
|
once_cell = "1.21.3"
|
||||||
rnex-core = { path = "../rnex-core", version = "0.1.1" }
|
rnex-core = { path = "../rnex-core", version = "0.1.1" }
|
||||||
|
proxy-common = {path = "../proxy-common"}
|
||||||
|
cfg-if = "1.0.4"
|
||||||
|
|
||||||
[[bin]]
|
[features]
|
||||||
name = "proxy_insecure"
|
prudpv1 = []
|
||||||
path = "src/executables/proxy_insecure.rs"
|
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "proxy_secure"
|
|
||||||
path = "src/executables/proxy_secure.rs"
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1,3 @@
|
||||||
pub mod common;
|
pub mod common;
|
||||||
|
pub mod proxy_insecure;
|
||||||
|
pub mod proxy_secure;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
|
use crate::executables::common::{EDGE_NODE_HOLDER, FORWARD_DESTINATION};
|
||||||
|
use crate::prudp::router::Router;
|
||||||
|
use crate::prudp::unsecure::Unsecure;
|
||||||
use log::error;
|
use log::error;
|
||||||
use prudpv1::executables::common::{EDGE_NODE_HOLDER, FORWARD_DESTINATION};
|
|
||||||
use prudpv1::prudp::router::Router;
|
|
||||||
use prudpv1::prudp::unsecure::Unsecure;
|
|
||||||
use rnex_core::common::setup;
|
use rnex_core::common::setup;
|
||||||
use rnex_core::executables::common::{OWN_IP_PRIVATE, OWN_IP_PUBLIC, SERVER_PORT};
|
use rnex_core::executables::common::{OWN_IP_PRIVATE, OWN_IP_PUBLIC, SERVER_PORT};
|
||||||
use rnex_core::prudp::virtual_port::VirtualPort;
|
use rnex_core::prudp::virtual_port::VirtualPort;
|
||||||
|
|
@ -20,8 +20,7 @@ use tokio::net::TcpStream;
|
||||||
use tokio::task;
|
use tokio::task;
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
|
|
||||||
#[tokio::main]
|
pub async fn start() {
|
||||||
async fn main() {
|
|
||||||
setup();
|
setup();
|
||||||
|
|
||||||
let conn = tokio::net::TcpStream::connect(&*EDGE_NODE_HOLDER)
|
let conn = tokio::net::TcpStream::connect(&*EDGE_NODE_HOLDER)
|
||||||
|
|
|
||||||
|
|
@ -1,48 +1,56 @@
|
||||||
use rnex_core::reggie::UnitPacketRead;
|
use crate::executables::common::{EDGE_NODE_HOLDER, FORWARD_DESTINATION};
|
||||||
use rnex_core::reggie::UnitPacketWrite;
|
use crate::prudp::router::Router;
|
||||||
use rnex_core::rmc::structures::RmcSerialize;
|
use crate::prudp::secure::Secure;
|
||||||
use std::net::SocketAddrV4;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use std::time::Duration;
|
|
||||||
use log::error;
|
use log::error;
|
||||||
use tokio::net::TcpStream;
|
|
||||||
use tokio::task;
|
|
||||||
use tokio::time::sleep;
|
|
||||||
use prudpv1::executables::common::{FORWARD_DESTINATION, EDGE_NODE_HOLDER};
|
|
||||||
use prudpv1::prudp::router::Router;
|
|
||||||
use prudpv1::prudp::secure::Secure;
|
|
||||||
use rnex_core::common::setup;
|
use rnex_core::common::setup;
|
||||||
use rnex_core::executables::common::{OWN_IP_PRIVATE, OWN_IP_PUBLIC, SECURE_SERVER_ACCOUNT, SERVER_PORT};
|
use rnex_core::executables::common::{
|
||||||
|
OWN_IP_PRIVATE, OWN_IP_PUBLIC, SECURE_SERVER_ACCOUNT, SERVER_PORT,
|
||||||
|
};
|
||||||
use rnex_core::prudp::virtual_port::VirtualPort;
|
use rnex_core::prudp::virtual_port::VirtualPort;
|
||||||
use rnex_core::reggie::EdgeNodeHolderConnectOption::Register;
|
use rnex_core::reggie::EdgeNodeHolderConnectOption::Register;
|
||||||
use rnex_core::reggie::RemoteEdgeNodeHolder;
|
use rnex_core::reggie::RemoteEdgeNodeHolder;
|
||||||
use rnex_core::rmc::protocols::{new_rmc_gateway_connection, OnlyRemote};
|
use rnex_core::reggie::UnitPacketRead;
|
||||||
|
use rnex_core::reggie::UnitPacketWrite;
|
||||||
|
use rnex_core::rmc::protocols::{OnlyRemote, new_rmc_gateway_connection};
|
||||||
|
use rnex_core::rmc::structures::RmcSerialize;
|
||||||
use rnex_core::rnex_proxy_common::ConnectionInitData;
|
use rnex_core::rnex_proxy_common::ConnectionInitData;
|
||||||
use rnex_core::util::SplittableBufferConnection;
|
use rnex_core::util::SplittableBufferConnection;
|
||||||
|
use std::net::SocketAddrV4;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::time::Duration;
|
||||||
|
use tokio::net::TcpStream;
|
||||||
|
use tokio::task;
|
||||||
|
use tokio::time::sleep;
|
||||||
|
|
||||||
#[tokio::main]
|
pub async fn start() {
|
||||||
async fn main() {
|
|
||||||
setup();
|
setup();
|
||||||
|
|
||||||
let conn = tokio::net::TcpStream::connect(&*EDGE_NODE_HOLDER).await.unwrap();
|
let conn = tokio::net::TcpStream::connect(&*EDGE_NODE_HOLDER)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let conn: SplittableBufferConnection = conn.into();
|
let conn: SplittableBufferConnection = conn.into();
|
||||||
|
|
||||||
conn.send(Register(SocketAddrV4::new(*OWN_IP_PUBLIC, *SERVER_PORT)).to_data().unwrap()).await;
|
conn.send(
|
||||||
|
Register(SocketAddrV4::new(*OWN_IP_PUBLIC, *SERVER_PORT))
|
||||||
let conn = new_rmc_gateway_connection(conn, |r| Arc::new(OnlyRemote::<RemoteEdgeNodeHolder>::new(r)));
|
.to_data()
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let conn = new_rmc_gateway_connection(conn, |r| {
|
||||||
|
Arc::new(OnlyRemote::<RemoteEdgeNodeHolder>::new(r))
|
||||||
|
});
|
||||||
|
|
||||||
let (router_secure, _) = Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *SERVER_PORT))
|
let (router_secure, _) = Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *SERVER_PORT))
|
||||||
.await
|
.await
|
||||||
.expect("unable to start router");
|
.expect("unable to start router");
|
||||||
|
|
||||||
let mut socket_secure = router_secure
|
let mut socket_secure = router_secure
|
||||||
.add_socket(VirtualPort::new(1, 10), Secure(
|
.add_socket(
|
||||||
"6f599f81",
|
VirtualPort::new(1, 10),
|
||||||
SECURE_SERVER_ACCOUNT.clone()
|
Secure("6f599f81", SECURE_SERVER_ACCOUNT.clone()),
|
||||||
))
|
)
|
||||||
.await
|
.await
|
||||||
.expect("unable to add socket");
|
.expect("unable to add socket");
|
||||||
|
|
||||||
|
|
@ -55,8 +63,7 @@ async fn main() {
|
||||||
};
|
};
|
||||||
|
|
||||||
task::spawn(async move {
|
task::spawn(async move {
|
||||||
let mut stream
|
let mut stream = match TcpStream::connect(*FORWARD_DESTINATION).await {
|
||||||
= match TcpStream::connect(*FORWARD_DESTINATION).await {
|
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("unable to connect: {}", e);
|
error!("unable to connect: {}", e);
|
||||||
|
|
@ -64,16 +71,21 @@ async fn main() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(e) = stream.send_buffer(&ConnectionInitData{
|
if let Err(e) = stream
|
||||||
prudpsock_addr: conn.socket_addr,
|
.send_buffer(
|
||||||
pid: conn.user_id
|
&ConnectionInitData {
|
||||||
}.to_data().unwrap()).await{
|
prudpsock_addr: conn.socket_addr,
|
||||||
|
pid: conn.user_id,
|
||||||
|
}
|
||||||
|
.to_data()
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
error!("error connecting to backend: {}", e);
|
error!("error connecting to backend: {}", e);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
data = conn.recv() => {
|
data = conn.recv() => {
|
||||||
|
|
@ -94,7 +106,7 @@ async fn main() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if conn.send(data).await == None{
|
if conn.send(data).await == None{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -106,6 +118,6 @@ async fn main() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
drop(conn);
|
drop(conn);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,14 @@
|
||||||
pub mod prudp;
|
cfg_if::cfg_if! {
|
||||||
pub mod executables;
|
if #[cfg(feature = "prudpv1")]{
|
||||||
|
use proxy_common::{ProxyStartupParam, setup_edge_node_connection};
|
||||||
|
pub mod executables;
|
||||||
|
pub mod prudp;
|
||||||
|
pub async fn start_secure(param: ProxyStartupParam) {
|
||||||
|
executables::proxy_secure::start();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn start_insecure(param: ProxyStartupParam) {
|
||||||
|
executables::proxy_insecure::start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ pub fn read_secure_connection_data(data: &[u8], act: &Account) -> Option<([u8; 3
|
||||||
|
|
||||||
let ticket_data = &mut ticket_data[0..ticket_data_size - 0x10];
|
let ticket_data = &mut ticket_data[0..ticket_data_size - 0x10];
|
||||||
|
|
||||||
let server_key = derive_key(act.pid, act.kerbros_password);
|
let server_key = derive_key(act.pid, &act.kerbros_password[..]);
|
||||||
|
|
||||||
let mut rc4: StreamCipherCoreWrapper<Rc4Core<U16>> =
|
let mut rc4: StreamCipherCoreWrapper<Rc4Core<U16>> =
|
||||||
Rc4::new_from_slice(&server_key).expect("unable to init rc4 keystream");
|
Rc4::new_from_slice(&server_key).expect("unable to init rc4 keystream");
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,8 @@ ureq = "3.1.4"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
rmc_struct_header = []
|
rmc_struct_header = []
|
||||||
|
guest_login = []
|
||||||
|
friends = ["guest_login"]
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "rmc_serialization"
|
name = "rmc_serialization"
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,26 @@
|
||||||
use std::io::{Read, Write};
|
use crate::rmc::structures::RmcSerialize;
|
||||||
use bytemuck::{bytes_of, Pod, Zeroable};
|
use bytemuck::{Pod, Zeroable, bytes_of};
|
||||||
use chrono::{Datelike, NaiveDate, NaiveDateTime, NaiveTime, Timelike, Utc};
|
use chrono::{Datelike, NaiveDate, NaiveDateTime, NaiveTime, Timelike, Utc};
|
||||||
use hmac::Hmac;
|
use hmac::Hmac;
|
||||||
|
use hmac::Mac;
|
||||||
use md5::{Digest, Md5};
|
use md5::{Digest, Md5};
|
||||||
use rc4::{Rc4, Rc4Core, StreamCipher};
|
use rc4::KeyInit;
|
||||||
use rc4::cipher::StreamCipherCoreWrapper;
|
use rc4::cipher::StreamCipherCoreWrapper;
|
||||||
use rc4::consts::U16;
|
use rc4::consts::U16;
|
||||||
use hmac::Mac;
|
use rc4::{Rc4, Rc4Core, StreamCipher};
|
||||||
use rc4::KeyInit;
|
use std::io::{Read, Write};
|
||||||
use crate::rmc::structures::RmcSerialize;
|
|
||||||
|
|
||||||
type Md5Hmac = Hmac<md5::Md5>;
|
type Md5Hmac = Hmac<md5::Md5>;
|
||||||
|
|
||||||
pub fn derive_key(pid: u32, password: [u8; 16]) -> [u8; 16]{
|
pub fn derive_key(pid: u32, password: &[u8]) -> [u8; 16] {
|
||||||
let iteration_count = 65000 + pid%1024;
|
let iteration_count = 65000 + pid % 1024 - 1;
|
||||||
|
// we do one iteration out here to ensure the key is always 16 bytes
|
||||||
|
|
||||||
let mut key = password;
|
let mut key: [u8; 16] = {
|
||||||
|
let mut md5 = Md5::new();
|
||||||
|
md5.update(password);
|
||||||
|
md5.finalize().try_into().unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
for _ in 0..iteration_count {
|
for _ in 0..iteration_count {
|
||||||
let mut md5 = Md5::new();
|
let mut md5 = Md5::new();
|
||||||
|
|
@ -29,12 +34,12 @@ pub fn derive_key(pid: u32, password: [u8; 16]) -> [u8; 16]{
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct KerberosDateTime(pub u64);
|
pub struct KerberosDateTime(pub u64);
|
||||||
|
|
||||||
impl KerberosDateTime{
|
impl KerberosDateTime {
|
||||||
pub fn new(second: u64, minute: u64, hour: u64, day: u64, month: u64, year:u64 ) -> Self {
|
pub fn new(second: u64, minute: u64, hour: u64, day: u64, month: u64, year: u64) -> Self {
|
||||||
Self(second | (minute << 6) | (hour << 12) | (day << 17) | (month << 22) | (year << 26))
|
Self(second | (minute << 6) | (hour << 12) | (day << 17) | (month << 22) | (year << 26))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn now() -> Self{
|
pub fn now() -> Self {
|
||||||
let now = chrono::Utc::now();
|
let now = chrono::Utc::now();
|
||||||
Self::new(
|
Self::new(
|
||||||
now.second() as u64,
|
now.second() as u64,
|
||||||
|
|
@ -47,42 +52,53 @@ impl KerberosDateTime{
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_seconds(&self) -> u8{
|
pub fn get_seconds(&self) -> u8 {
|
||||||
(self.0 & 0b111111) as u8
|
(self.0 & 0b111111) as u8
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_minutes(&self) -> u8{
|
pub fn get_minutes(&self) -> u8 {
|
||||||
((self.0 >> 6) & 0b111111) as u8
|
((self.0 >> 6) & 0b111111) as u8
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_hours(&self) -> u8{
|
pub fn get_hours(&self) -> u8 {
|
||||||
((self.0 >> 12) & 0b111111) as u8
|
((self.0 >> 12) & 0b111111) as u8
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_days(&self) -> u8{
|
pub fn get_days(&self) -> u8 {
|
||||||
((self.0 >> 17) & 0b111111) as u8
|
((self.0 >> 17) & 0b111111) as u8
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_month(&self) -> u8{
|
pub fn get_month(&self) -> u8 {
|
||||||
((self.0 >> 22) & 0b1111) as u8
|
((self.0 >> 22) & 0b1111) as u8
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_year(&self) -> u64{
|
pub fn get_year(&self) -> u64 {
|
||||||
(self.0 >> 26) & 0xFFFFFFFF
|
(self.0 >> 26) & 0xFFFFFFFF
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_regular_time(&self) -> chrono::DateTime<Utc>{
|
pub fn to_regular_time(&self) -> chrono::DateTime<Utc> {
|
||||||
NaiveDateTime::new(
|
NaiveDateTime::new(
|
||||||
NaiveDate::from_ymd_opt(self.get_year() as i32, self.get_month() as u32, self.get_days() as u32).unwrap(),
|
NaiveDate::from_ymd_opt(
|
||||||
NaiveTime::from_hms_opt(self.get_hours() as u32, self.get_minutes() as u32, self.get_seconds() as u32).unwrap()
|
self.get_year() as i32,
|
||||||
).and_utc()
|
self.get_month() as u32,
|
||||||
|
self.get_days() as u32,
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
NaiveTime::from_hms_opt(
|
||||||
|
self.get_hours() as u32,
|
||||||
|
self.get_minutes() as u32,
|
||||||
|
self.get_seconds() as u32,
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
.and_utc()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RmcSerialize for KerberosDateTime{
|
impl RmcSerialize for KerberosDateTime {
|
||||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||||
Ok(self.0.serialize(writer)?)
|
Ok(self.0.serialize(writer)?)
|
||||||
}
|
}
|
||||||
|
|
@ -94,22 +110,22 @@ impl RmcSerialize for KerberosDateTime{
|
||||||
|
|
||||||
#[derive(Pod, Zeroable, Copy, Clone)]
|
#[derive(Pod, Zeroable, Copy, Clone)]
|
||||||
#[repr(C, packed)]
|
#[repr(C, packed)]
|
||||||
pub struct TicketInternalData{
|
pub struct TicketInternalData {
|
||||||
pub issued_time: KerberosDateTime,
|
pub issued_time: KerberosDateTime,
|
||||||
pub pid: u32,
|
pub pid: u32,
|
||||||
pub session_key: [u8; 32],
|
pub session_key: [u8; 32],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TicketInternalData{
|
impl TicketInternalData {
|
||||||
pub(crate) fn new(pid: u32) -> Self{
|
pub(crate) fn new(pid: u32) -> Self {
|
||||||
Self{
|
Self {
|
||||||
issued_time: KerberosDateTime::now(),
|
issued_time: KerberosDateTime::now(),
|
||||||
pid,
|
pid,
|
||||||
session_key: rand::random()
|
session_key: rand::random(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn encrypt(&self, key: [u8; 16]) -> Box<[u8]>{
|
pub(crate) fn encrypt(&self, key: [u8; 16]) -> Box<[u8]> {
|
||||||
let mut data = bytes_of(self).to_vec();
|
let mut data = bytes_of(self).to_vec();
|
||||||
|
|
||||||
let mut rc4: StreamCipherCoreWrapper<Rc4Core<U16>> = Rc4::new_from_slice(&key).unwrap();
|
let mut rc4: StreamCipherCoreWrapper<Rc4Core<U16>> = Rc4::new_from_slice(&key).unwrap();
|
||||||
|
|
@ -117,11 +133,13 @@ impl TicketInternalData{
|
||||||
|
|
||||||
let mut hmac = <Md5Hmac as KeyInit>::new_from_slice(&key).unwrap();
|
let mut hmac = <Md5Hmac as KeyInit>::new_from_slice(&key).unwrap();
|
||||||
|
|
||||||
hmac.write_all(&data[..]).expect("failed to write data to hmac");
|
hmac.write_all(&data[..])
|
||||||
|
.expect("failed to write data to hmac");
|
||||||
|
|
||||||
let hmac_result = &hmac.finalize().into_bytes()[..];
|
let hmac_result = &hmac.finalize().into_bytes()[..];
|
||||||
|
|
||||||
data.write_all(&hmac_result).expect("failed to write data to vec");
|
data.write_all(&hmac_result)
|
||||||
|
.expect("failed to write data to vec");
|
||||||
|
|
||||||
data.into_boxed_slice()
|
data.into_boxed_slice()
|
||||||
}
|
}
|
||||||
|
|
@ -129,41 +147,44 @@ impl TicketInternalData{
|
||||||
|
|
||||||
#[derive(Pod, Zeroable, Copy, Clone)]
|
#[derive(Pod, Zeroable, Copy, Clone)]
|
||||||
#[repr(C, packed)]
|
#[repr(C, packed)]
|
||||||
pub struct Ticket{
|
pub struct Ticket {
|
||||||
pub session_key: [u8; 32],
|
pub session_key: [u8; 32],
|
||||||
pub pid: u32,
|
pub pid: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ticket{
|
impl Ticket {
|
||||||
pub fn encrypt(&self, key: [u8; 16], internal_data: &[u8]) -> Box<[u8]>{
|
pub fn encrypt(&self, key: [u8; 16], internal_data: &[u8]) -> Box<[u8]> {
|
||||||
let mut data = bytes_of(self).to_vec();
|
let mut data = bytes_of(self).to_vec();
|
||||||
|
|
||||||
internal_data.serialize(&mut data).expect("unable to write to vec");
|
internal_data
|
||||||
|
.serialize(&mut data)
|
||||||
|
.expect("unable to write to vec");
|
||||||
|
|
||||||
let mut rc4: StreamCipherCoreWrapper<Rc4Core<U16>> = Rc4::new_from_slice(&key).unwrap();
|
let mut rc4: StreamCipherCoreWrapper<Rc4Core<U16>> = Rc4::new_from_slice(&key).unwrap();
|
||||||
rc4.apply_keystream(&mut data);
|
rc4.apply_keystream(&mut data);
|
||||||
|
|
||||||
let mut hmac = <Md5Hmac as KeyInit>::new_from_slice(&key).unwrap();
|
let mut hmac = <Md5Hmac as KeyInit>::new_from_slice(&key).unwrap();
|
||||||
|
|
||||||
hmac.write_all(&data[..]).expect("failed to write data to hmac");
|
hmac.write_all(&data[..])
|
||||||
|
.expect("failed to write data to hmac");
|
||||||
|
|
||||||
let hmac_result = &hmac.finalize().into_bytes()[..];
|
let hmac_result = &hmac.finalize().into_bytes()[..];
|
||||||
|
|
||||||
data.write_all(&hmac_result).expect("failed to write data to vec");
|
data.write_all(&hmac_result)
|
||||||
|
.expect("failed to write data to vec");
|
||||||
|
|
||||||
data.into_boxed_slice()
|
data.into_boxed_slice()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test{
|
mod test {
|
||||||
use crate::kerberos::KerberosDateTime;
|
use crate::kerberos::KerberosDateTime;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn kerberos_time_convert_test(){
|
fn kerberos_time_convert_test() {
|
||||||
let time = KerberosDateTime(135904948834);
|
let time = KerberosDateTime(135904948834);
|
||||||
|
|
||||||
println!("{}", time.to_regular_time().to_rfc2822());
|
println!("{}", time.to_regular_time().to_rfc2822());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,39 +1,38 @@
|
||||||
use macros::RmcSerialize;
|
use macros::RmcSerialize;
|
||||||
|
|
||||||
#[derive(RmcSerialize)]
|
#[derive(RmcSerialize, Clone)]
|
||||||
#[derive(Clone)]
|
pub struct Account {
|
||||||
pub struct Account{
|
|
||||||
pub pid: u32,
|
pub pid: u32,
|
||||||
pub username: String,
|
pub username: String,
|
||||||
pub kerbros_password: [u8; 16],
|
pub kerbros_password: [u8; 16],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Account{
|
impl Account {
|
||||||
pub fn new(pid: u32, username: &str, passwd: &str) -> Self{
|
pub fn new(pid: u32, username: &str, passwd: &str) -> Self {
|
||||||
let passwd_data = passwd.as_bytes();
|
let passwd_data = passwd.as_bytes();
|
||||||
|
|
||||||
let mut passwd = [0u8; 16];
|
let mut passwd = [0u8; 16];
|
||||||
|
|
||||||
for (idx, byte) in passwd_data.iter().enumerate(){
|
for (idx, byte) in passwd_data.iter().enumerate() {
|
||||||
passwd[idx] = *byte;
|
passwd[idx] = *byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
Self{
|
Self {
|
||||||
kerbros_password: passwd,
|
kerbros_password: passwd,
|
||||||
username: username.into(),
|
username: username.into(),
|
||||||
pid
|
pid,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_raw_password(pid: u32, username: &str, passwd: [u8; 16]) -> Self{
|
pub fn new_raw_password(pid: u32, username: &str, passwd: [u8; 16]) -> Self {
|
||||||
Self{
|
Self {
|
||||||
kerbros_password: passwd,
|
kerbros_password: passwd,
|
||||||
username: username.into(),
|
username: username.into(),
|
||||||
pid
|
pid,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_login_data(&self) -> (u32, [u8; 16]){
|
pub fn get_login_data(&self) -> (u32, &[u8]) {
|
||||||
(self.pid, self.kerbros_password)
|
(self.pid, &self.kerbros_password)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::grpc::account;
|
use crate::grpc::account;
|
||||||
use crate::reggie::{RemoteEdgeNodeHolder, RemoteEdgeNodeManagement};
|
use crate::reggie::{RemoteEdgeNodeHolder, RemoteEdgeNodeManagement};
|
||||||
use crate::{define_rmc_proto, kerberos};
|
use crate::{define_rmc_proto, kerberos};
|
||||||
|
use log::warn;
|
||||||
use macros::rmc_struct;
|
use macros::rmc_struct;
|
||||||
use rnex_core::kerberos::{KerberosDateTime, Ticket, derive_key};
|
use rnex_core::kerberos::{KerberosDateTime, Ticket, derive_key};
|
||||||
use rnex_core::nex::account::Account;
|
use rnex_core::nex::account::Account;
|
||||||
|
|
@ -13,7 +14,7 @@ use rnex_core::rmc::structures::connection_data::ConnectionData;
|
||||||
use rnex_core::rmc::structures::qresult::QResult;
|
use rnex_core::rmc::structures::qresult::QResult;
|
||||||
use std::hash::{DefaultHasher, Hasher};
|
use std::hash::{DefaultHasher, Hasher};
|
||||||
use std::net::SocketAddrV4;
|
use std::net::SocketAddrV4;
|
||||||
use std::sync::Arc;
|
use std::sync::{Arc, LazyLock, OnceLock};
|
||||||
|
|
||||||
define_rmc_proto!(
|
define_rmc_proto!(
|
||||||
proto AuthClientProtocol{
|
proto AuthClientProtocol{
|
||||||
|
|
@ -30,8 +31,8 @@ pub struct AuthHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_ticket(
|
pub fn generate_ticket(
|
||||||
source_act_login_data: (u32, [u8; 16]),
|
source_act_login_data: (u32, &[u8]),
|
||||||
dest_act_login_data: (u32, [u8; 16]),
|
dest_act_login_data: (u32, &[u8]),
|
||||||
) -> Box<[u8]> {
|
) -> Box<[u8]> {
|
||||||
let source_key = derive_key(source_act_login_data.0, source_act_login_data.1);
|
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 dest_key = derive_key(dest_act_login_data.0, dest_act_login_data.1);
|
||||||
|
|
@ -68,27 +69,57 @@ fn station_url_from_sock_addr(sock_addr: SocketAddrV4) -> String {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GUEST_ACCOUNT: LazyLock<Account> =
|
||||||
|
LazyLock::new(|| Account::new(100, "guest", "MMQea3n!fsik"));
|
||||||
|
|
||||||
|
impl AuthHandler {
|
||||||
|
pub async fn generate_ticket_from_name(
|
||||||
|
&self,
|
||||||
|
name: &str,
|
||||||
|
) -> Result<(u32, Box<[u8]>), ErrorCode> {
|
||||||
|
#[cfg(feature = "guest_login")]
|
||||||
|
{
|
||||||
|
if name == GUEST_ACCOUNT.username {
|
||||||
|
let source_login_data = GUEST_ACCOUNT.get_login_data();
|
||||||
|
let destination_login_data = self.destination_server_acct.get_login_data();
|
||||||
|
|
||||||
|
return Ok((
|
||||||
|
source_login_data.0,
|
||||||
|
generate_ticket(source_login_data, destination_login_data),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let Ok(pid) = name.parse() else {
|
||||||
|
warn!("unable to connect to parse pid: {}", name);
|
||||||
|
return Err(ErrorCode::Core_InvalidArgument);
|
||||||
|
};
|
||||||
|
|
||||||
|
let Ok(mut client) = account::Client::new().await else {
|
||||||
|
warn!("unable to connect to grpc");
|
||||||
|
return Err(ErrorCode::Core_Exception);
|
||||||
|
};
|
||||||
|
|
||||||
|
let Ok(passwd) = client.get_nex_password(pid).await else {
|
||||||
|
warn!("unable to get nex password");
|
||||||
|
return Err(ErrorCode::Core_Exception);
|
||||||
|
};
|
||||||
|
|
||||||
|
let source_login_data = (pid, &passwd[..]);
|
||||||
|
let destination_login_data = self.destination_server_acct.get_login_data();
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
pid,
|
||||||
|
generate_ticket(source_login_data, destination_login_data),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Auth for AuthHandler {
|
impl Auth for AuthHandler {
|
||||||
async fn login(
|
async fn login(
|
||||||
&self,
|
&self,
|
||||||
name: String,
|
name: String,
|
||||||
) -> Result<(QResult, u32, Vec<u8>, ConnectionData, String), ErrorCode> {
|
) -> Result<(QResult, u32, Vec<u8>, ConnectionData, String), ErrorCode> {
|
||||||
let Ok(pid) = name.parse() else {
|
let (pid, ticket) = self.generate_ticket_from_name(&name).await?;
|
||||||
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 result = QResult::success(Core_Unknown);
|
||||||
|
|
||||||
|
|
@ -97,6 +128,7 @@ impl Auth for AuthHandler {
|
||||||
hasher.write(name.as_bytes());
|
hasher.write(name.as_bytes());
|
||||||
|
|
||||||
let Ok(addr) = self.control_server.get_url(hasher.finish()).await else {
|
let Ok(addr) = self.control_server.get_url(hasher.finish()).await else {
|
||||||
|
warn!("no secure proxies");
|
||||||
return Err(ErrorCode::Core_Exception);
|
return Err(ErrorCode::Core_Exception);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -110,7 +142,7 @@ impl Auth for AuthHandler {
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
result,
|
result,
|
||||||
source_login_data.0,
|
pid,
|
||||||
ticket.into(),
|
ticket.into(),
|
||||||
connection_data,
|
connection_data,
|
||||||
self.build_name.to_string(), //format!("{}; Rust NEX Version {} by DJMrTV", self.build_name, env!("CARGO_PKG_VERSION")),
|
self.build_name.to_string(), //format!("{}; Rust NEX Version {} by DJMrTV", self.build_name, env!("CARGO_PKG_VERSION")),
|
||||||
|
|
@ -130,22 +162,19 @@ impl Auth for AuthHandler {
|
||||||
source_pid: u32,
|
source_pid: u32,
|
||||||
destination_pid: u32,
|
destination_pid: u32,
|
||||||
) -> Result<(QResult, Vec<u8>), ErrorCode> {
|
) -> Result<(QResult, Vec<u8>), ErrorCode> {
|
||||||
let Some(source_login_data) = get_login_data_by_pid(source_pid).await else {
|
let Some((pid, passwd)) = get_login_data_by_pid(source_pid).await else {
|
||||||
return Err(ErrorCode::Core_Exception);
|
return Err(ErrorCode::Core_Exception);
|
||||||
};
|
};
|
||||||
|
|
||||||
let desgination_login_data = if destination_pid == self.destination_server_acct.pid {
|
let desgination_login_data = if destination_pid == self.destination_server_acct.pid {
|
||||||
self.destination_server_acct.get_login_data()
|
self.destination_server_acct.get_login_data()
|
||||||
} else {
|
} else {
|
||||||
let Some(login) = get_login_data_by_pid(destination_pid).await else {
|
return Err(ErrorCode::RendezVous_InvalidOperation);
|
||||||
return Err(ErrorCode::Core_Exception);
|
|
||||||
};
|
|
||||||
login
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = QResult::success(Core_Unknown);
|
let result = QResult::success(Core_Unknown);
|
||||||
|
|
||||||
let ticket = generate_ticket(source_login_data, desgination_login_data);
|
let ticket = generate_ticket((pid, &passwd[..]), desgination_login_data);
|
||||||
|
|
||||||
Ok((result, ticket.into()))
|
Ok((result, ticket.into()))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue