Compare commits
2 Commits
fbe2aa12fb
...
372afd470b
| Author | SHA1 | Date | |
|---|---|---|---|
| 372afd470b | |||
| c6df26ac85 |
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"rust-analyzer.cargo.target": "x86_64-pc-windows-gnu",
|
// "rust-analyzer.cargo.target": "x86_64-pc-windows-gnu",
|
||||||
// "rust-analyzer.cargo.features": ["tun"]
|
// "rust-analyzer.cargo.features": ["tun"]
|
||||||
}
|
}
|
||||||
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -2075,8 +2075,11 @@ dependencies = [
|
|||||||
"dns-lookup",
|
"dns-lookup",
|
||||||
"etherparse",
|
"etherparse",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
"hex",
|
||||||
|
"hmac",
|
||||||
"libc",
|
"libc",
|
||||||
"local-ip-address",
|
"local-ip-address",
|
||||||
|
"md-5",
|
||||||
"myactor",
|
"myactor",
|
||||||
"num_enum",
|
"num_enum",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
|||||||
@ -36,6 +36,9 @@ clap = { version = "4.5.60", features = ["derive", "env"] }
|
|||||||
rpassword = "7.4.0"
|
rpassword = "7.4.0"
|
||||||
serde_json = "1.0.149"
|
serde_json = "1.0.149"
|
||||||
chacha20poly1305 = "0.10.1"
|
chacha20poly1305 = "0.10.1"
|
||||||
|
hmac = "0.12.1"
|
||||||
|
md-5 = "0.10.6"
|
||||||
|
hex = "0.4.3"
|
||||||
# rolling-file = { path = "../rolling-file" }
|
# rolling-file = { path = "../rolling-file" }
|
||||||
|
|
||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
|
|||||||
@ -1,9 +1,22 @@
|
|||||||
|
use hmac::{Hmac, Mac as HamcMac};
|
||||||
|
use punchnet::TokenLogin;
|
||||||
use reqwest::Client;
|
use reqwest::Client;
|
||||||
use sdlan_sn_rs::utils::{Mac, Result, SDLanError};
|
use sdlan_sn_rs::utils::{Mac, Result, SDLanError};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use md5::Md5;
|
||||||
|
|
||||||
pub const TEST_PREFIX: &'static str = "https://punchnet.s5s8.com/api";
|
pub const TEST_PREFIX: &'static str = "https://punchnet.s5s8.com/api";
|
||||||
|
|
||||||
|
const DIGEST_KEY: &'static str = "H6p*2RfEu4ITcL";
|
||||||
|
type HmacMd5 = Hmac<Md5>;
|
||||||
|
|
||||||
|
trait HMacCalculator {
|
||||||
|
fn calculate_hmac(&self) -> Result<String>;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calculate_hmac<T: HMacCalculator>(cal: T) -> Result<String> {
|
||||||
|
cal.calculate_hmac()
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct TokenLoginData<'a> {
|
struct TokenLoginData<'a> {
|
||||||
@ -14,6 +27,29 @@ struct TokenLoginData<'a> {
|
|||||||
version: &'a str,
|
version: &'a str,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn do_calculate(data: &[u8]) -> Result<String>{
|
||||||
|
let Ok(mut mac) = HmacMd5::new_from_slice(DIGEST_KEY.as_bytes()) else {
|
||||||
|
return Err(SDLanError::IOError("failed to new hmac".to_owned()));
|
||||||
|
};
|
||||||
|
mac.update(data);
|
||||||
|
let result = mac.finalize().into_bytes();
|
||||||
|
Ok(hex::encode(result))
|
||||||
|
}
|
||||||
|
|
||||||
|
impl <'a> HMacCalculator for TokenLoginData<'a> {
|
||||||
|
fn calculate_hmac(&self) -> Result<String> {
|
||||||
|
let data = format!("client_id={}&mac={}&system={}&token={}&version={}",
|
||||||
|
self.client_id,
|
||||||
|
self.mac,
|
||||||
|
self.system,
|
||||||
|
self.token,
|
||||||
|
self.version,
|
||||||
|
);
|
||||||
|
do_calculate(data.as_bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct UserPassLoginData<'a> {
|
struct UserPassLoginData<'a> {
|
||||||
client_id: &'a str,
|
client_id: &'a str,
|
||||||
@ -24,6 +60,20 @@ struct UserPassLoginData<'a> {
|
|||||||
version: &'a str,
|
version: &'a str,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl HMacCalculator for UserPassLoginData<'_> {
|
||||||
|
fn calculate_hmac(&self) -> Result<String> {
|
||||||
|
let data = format!("client_id={}&mac={}&password={}&system={}&username={}&version={}",
|
||||||
|
self.client_id,
|
||||||
|
self.mac,
|
||||||
|
self.password,
|
||||||
|
self.system,
|
||||||
|
self.username,
|
||||||
|
self.version,
|
||||||
|
);
|
||||||
|
do_calculate(data.as_bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct LoginResponse {
|
pub struct LoginResponse {
|
||||||
pub code: i32,
|
pub code: i32,
|
||||||
@ -54,14 +104,18 @@ async fn post_with_data<T, R>(
|
|||||||
url: &str,
|
url: &str,
|
||||||
data: T,
|
data: T,
|
||||||
) -> Result<R>
|
) -> Result<R>
|
||||||
where T: Serialize,
|
where T: Serialize + HMacCalculator,
|
||||||
R: for<'de> Deserialize<'de>
|
R: for<'de> Deserialize<'de>
|
||||||
{
|
{
|
||||||
|
|
||||||
let client = Client::new();
|
let client = Client::new();
|
||||||
|
|
||||||
|
let Ok(hmac) = data.calculate_hmac() else {
|
||||||
|
return Err(SDLanError::IOError("failed to calculate hmac".to_owned()));
|
||||||
|
};
|
||||||
|
|
||||||
let Ok(response) = client
|
let Ok(response) = client
|
||||||
.post(url)
|
.post(url)
|
||||||
|
.header("X-sign", hmac)
|
||||||
.json(&data)
|
.json(&data)
|
||||||
.send()
|
.send()
|
||||||
.await else {
|
.await else {
|
||||||
@ -70,7 +124,6 @@ where T: Serialize,
|
|||||||
|
|
||||||
// println!("status: {}", response.status());
|
// println!("status: {}", response.status());
|
||||||
let text = response.text().await.unwrap();
|
let text = response.text().await.unwrap();
|
||||||
// println!("text = {}", text);
|
|
||||||
|
|
||||||
let data = serde_json::from_str(&text).unwrap();
|
let data = serde_json::from_str(&text).unwrap();
|
||||||
|
|
||||||
@ -137,6 +190,16 @@ struct ConnectDisconnectRequest<'a> {
|
|||||||
access_token: &'a str,
|
access_token: &'a str,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl HMacCalculator for ConnectDisconnectRequest<'_> {
|
||||||
|
fn calculate_hmac(&self) -> Result<String> {
|
||||||
|
let data = format!("access_token={}&client_id={}",
|
||||||
|
self.access_token,
|
||||||
|
self.client_id
|
||||||
|
);
|
||||||
|
do_calculate(data.as_bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
pub struct ConnectResponse {
|
pub struct ConnectResponse {
|
||||||
pub code: i32,
|
pub code: i32,
|
||||||
@ -210,6 +273,17 @@ struct GetResourceRequest<'a> {
|
|||||||
id: i32,
|
id: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl HMacCalculator for GetResourceRequest<'_> {
|
||||||
|
fn calculate_hmac(&self) -> Result<String> {
|
||||||
|
let data = format!("access_token={}&client_id={}&id={}",
|
||||||
|
self.access_token,
|
||||||
|
self.client_id,
|
||||||
|
self.id,
|
||||||
|
);
|
||||||
|
do_calculate(data.as_bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
pub struct GetResourceResponse {
|
pub struct GetResourceResponse {
|
||||||
pub code: i32,
|
pub code: i32,
|
||||||
|
|||||||
@ -354,7 +354,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let should_daemonize = true;
|
let should_daemonize = false;
|
||||||
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
if should_daemonize {
|
if should_daemonize {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use std::sync::atomic::{AtomicU64, Ordering};
|
use std::sync::atomic::{Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
@ -15,7 +15,6 @@ use sdlan_sn_rs::utils::{get_current_timestamp, is_multi_broadcast};
|
|||||||
use sdlan_sn_rs::utils::{Mac, Result};
|
use sdlan_sn_rs::utils::{Mac, Result};
|
||||||
use tokio::net::{UdpSocket};
|
use tokio::net::{UdpSocket};
|
||||||
use tokio::sync::mpsc::{channel, Receiver, Sender};
|
use tokio::sync::mpsc::{channel, Receiver, Sender};
|
||||||
use tokio::time::sleep;
|
|
||||||
use tokio_util::sync::CancellationToken;
|
use tokio_util::sync::CancellationToken;
|
||||||
|
|
||||||
use super::{Node, StartStopInfo};
|
use super::{Node, StartStopInfo};
|
||||||
@ -118,17 +117,6 @@ pub async fn async_main(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run_quic_loop(
|
|
||||||
edge: &Node,
|
|
||||||
quic_addr: &str,
|
|
||||||
pong_time: Arc<AtomicU64>,
|
|
||||||
start_stop_chan: Receiver<StartStopInfo>,
|
|
||||||
connecting_chan: Sender<ConnectionInfo>,
|
|
||||||
ipv6_ntework_restarter: Option<Sender<bool>>
|
|
||||||
) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn run_edge_loop(eee: &'static Node, cancel: CancellationToken) {
|
async fn run_edge_loop(eee: &'static Node, cancel: CancellationToken) {
|
||||||
ping_to_sn().await;
|
ping_to_sn().await;
|
||||||
{
|
{
|
||||||
@ -251,7 +239,7 @@ async fn loop_tap(eee: &'static Node, cancel: CancellationToken) {
|
|||||||
packet.push(0x00);
|
packet.push(0x00);
|
||||||
packet.extend_from_slice(&reply);
|
packet.extend_from_slice(&reply);
|
||||||
|
|
||||||
/// TODO: check the packet should
|
// TODO: check the packet should
|
||||||
if let Err(_e) = eee.device.handle_packet_from_net(&packet).await {
|
if let Err(_e) = eee.device.handle_packet_from_net(&packet).await {
|
||||||
error!("failed to write dns packet to device");
|
error!("failed to write dns packet to device");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
use std::sync::RwLock;
|
|
||||||
|
|
||||||
use crate::utils::mac_to_string;
|
use crate::utils::mac_to_string;
|
||||||
use sdlan_sn_rs::{peer::IpSubnet, utils::Mac};
|
use sdlan_sn_rs::{peer::IpSubnet, utils::Mac};
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|||||||
@ -13,12 +13,12 @@ use tokio::sync::oneshot;
|
|||||||
use tracing::{debug, error};
|
use tracing::{debug, error};
|
||||||
|
|
||||||
use crate::quic::quic_init;
|
use crate::quic::quic_init;
|
||||||
use crate::{ConnectionInfo, Encryptor, MyEncryptor, get_base_dir};
|
use crate::{ConnectionInfo, MyEncryptor, get_base_dir};
|
||||||
use crate::pb::{
|
use crate::pb::{
|
||||||
encode_to_tcp_message, encode_to_udp_message, SdlEmpty, SdlStunProbe, SdlStunProbeReply,
|
encode_to_tcp_message, encode_to_udp_message, SdlEmpty, SdlStunProbe, SdlStunProbeReply,
|
||||||
};
|
};
|
||||||
use crate::tcp::{NatType, PacketType, StunProbeAttr, get_quic_write_conn};
|
use crate::tcp::{NatType, PacketType, StunProbeAttr, get_quic_write_conn};
|
||||||
use crate::utils::{Socket, create_or_load_mac};
|
use crate::utils::{Socket};
|
||||||
|
|
||||||
use sdlan_sn_rs::peer::{IpSubnet, V6Info};
|
use sdlan_sn_rs::peer::{IpSubnet, V6Info};
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
use std::{net::SocketAddr, sync::atomic::Ordering, time::Duration};
|
use std::{net::SocketAddr, sync::atomic::Ordering, time::Duration};
|
||||||
|
|
||||||
use crate::network::IdentityID;
|
|
||||||
use crate::pb::SdlPolicyRequest;
|
use crate::pb::SdlPolicyRequest;
|
||||||
use crate::tcp::{NatType, get_quic_write_conn, is_identity_ok};
|
use crate::tcp::{NatType, get_quic_write_conn, is_identity_ok};
|
||||||
use crate::{network::TunTapPacketHandler, utils::mac_to_string};
|
use crate::{network::TunTapPacketHandler, utils::mac_to_string};
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use etherparse::{Ethernet2Header};
|
use etherparse::{Ethernet2Header};
|
||||||
use sdlan_sn_rs::config::SDLAN_DEFAULT_TTL;
|
use sdlan_sn_rs::config::SDLAN_DEFAULT_TTL;
|
||||||
use sdlan_sn_rs::utils::{
|
use sdlan_sn_rs::utils::{
|
||||||
aes_encrypt, ip_to_string, is_ipv6_multicast, net_bit_len_to_mask,
|
ip_to_string, is_ipv6_multicast, net_bit_len_to_mask,
|
||||||
SDLanError,
|
SDLanError,
|
||||||
};
|
};
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
|
|||||||
@ -5,7 +5,7 @@ use dashmap::DashMap;
|
|||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use sdlan_sn_rs::{
|
use sdlan_sn_rs::{
|
||||||
config::SDLAN_DEFAULT_TTL,
|
config::SDLAN_DEFAULT_TTL,
|
||||||
utils::{aes_encrypt, get_current_timestamp, ip_to_string, Mac},
|
utils::{get_current_timestamp, ip_to_string, Mac},
|
||||||
};
|
};
|
||||||
|
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use std::{collections::{HashMap, HashSet}, sync::{OnceLock, atomic::{AtomicU64, Ordering}}, time::{SystemTime, UNIX_EPOCH}};
|
use std::{collections::{HashMap, HashSet}, sync::{OnceLock}, time::{SystemTime, UNIX_EPOCH}};
|
||||||
|
|
||||||
use dashmap::{DashMap, DashSet};
|
use dashmap::{DashMap};
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
type IdentityID = u32;
|
type IdentityID = u32;
|
||||||
|
|||||||
@ -225,7 +225,7 @@ async fn handle_tcp_message(msg: SdlanTcp) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let data = hdr.marshal_to_bytes();
|
let data = hdr.marshal_to_bytes();
|
||||||
if let Err(e) = edge.device.send(&data) {
|
if let Err(_e) = edge.device.send(&data) {
|
||||||
error!("failed to write arp response to device");
|
error!("failed to write arp response to device");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -692,7 +692,7 @@ async fn on_disconnected_callback() {
|
|||||||
*edge.encryptor.write().unwrap() = MyEncryptor::Invalid;
|
*edge.encryptor.write().unwrap() = MyEncryptor::Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn on_connected_callback(local_ip: Option<IpAddr>, stream: &mut SendStream, pkt_id: Option<u32>) {
|
async fn on_connected_callback(local_ip: Option<IpAddr>, stream: &mut SendStream, _pkt_id: Option<u32>) {
|
||||||
let edge = get_edge();
|
let edge = get_edge();
|
||||||
// let installed_channel = install_channel.to_owned();
|
// let installed_channel = install_channel.to_owned();
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
use std::{sync::{Arc, OnceLock, RwLock, atomic::{AtomicBool, AtomicU32, Ordering}}, time::{SystemTime, UNIX_EPOCH}};
|
use std::{sync::atomic::{AtomicU32, Ordering}, time::{SystemTime, UNIX_EPOCH}};
|
||||||
|
|
||||||
use tracing::debug;
|
|
||||||
|
|
||||||
use chacha20poly1305::{KeyInit, aead::Aead};
|
use chacha20poly1305::{KeyInit, aead::Aead};
|
||||||
use dashmap::DashSet;
|
|
||||||
use sdlan_sn_rs::utils::{Result, SDLanError, aes_decrypt, aes_encrypt};
|
use sdlan_sn_rs::utils::{Result, SDLanError, aes_decrypt, aes_encrypt};
|
||||||
|
|
||||||
const CounterMask: u32 = (1<<24) - 1;
|
const COUNTER_MASK: u32 = (1<<24) - 1;
|
||||||
|
|
||||||
pub trait Encryptor {
|
pub trait Encryptor {
|
||||||
fn is_setted(&self) -> bool;
|
fn is_setted(&self) -> bool;
|
||||||
@ -107,7 +105,7 @@ impl Encryptor for Chacha20Encryptor {
|
|||||||
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis() as u64;
|
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis() as u64;
|
||||||
|
|
||||||
let next_counter = self.next_counter.fetch_update(Ordering::Release, Ordering::Acquire, |current| {
|
let next_counter = self.next_counter.fetch_update(Ordering::Release, Ordering::Acquire, |current| {
|
||||||
Some((current + 1) & CounterMask)
|
Some((current + 1) & COUNTER_MASK)
|
||||||
}).unwrap() as u64;
|
}).unwrap() as u64;
|
||||||
|
|
||||||
let mut nonce = Vec::new();
|
let mut nonce = Vec::new();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user