acl is enabled

This commit is contained in:
alex 2026-07-06 11:54:41 +08:00
parent 2e823188ba
commit 465648c5df
6 changed files with 117 additions and 98 deletions

2
Cargo.lock generated
View File

@ -2343,7 +2343,7 @@ dependencies = [
[[package]] [[package]]
name = "punchnet" name = "punchnet"
version = "1.2.6" version = "1.2.7"
dependencies = [ dependencies = [
"ahash", "ahash",
"arc-swap", "arc-swap",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "punchnet" name = "punchnet"
version = "1.2.6" version = "1.2.7"
edition = "2021" edition = "2021"
license = "MIT" license = "MIT"
description = "punchnet client" description = "punchnet client"

View File

@ -35,7 +35,7 @@ libtun-musl:
deb-musl: deb-musl:
cargo deb --target x86_64-unknown-linux-musl --deb-revision="2-static" cargo deb --target x86_64-unknown-linux-musl --deb-revision="2-acl-static"
deb: libtun-so deb: libtun-so
RUSTFLAGS="-L ." cargo deb --deb-revision="1-dynamic" RUSTFLAGS="-L ." cargo deb --deb-revision="1-dynamic"
@ -44,4 +44,4 @@ deb-aarch64-musl: libtun-aarch64-musl
RUSTFLAGS="-L ." cargo deb --target aarch64-unknown-linux-musl --deb-revision="1-static" RUSTFLAGS="-L ." cargo deb --target aarch64-unknown-linux-musl --deb-revision="1-static"
deb-aarch64: deb-aarch64:
cargo deb --target aarch64-unknown-linux-musl --deb-revision="2-static" cargo deb --target aarch64-unknown-linux-musl --deb-revision="2-acl-static"

View File

@ -1,12 +1,14 @@
use hmac::{Hmac, Mac as HamcMac}; use hmac::{Hmac, Mac as HamcMac};
use punchnet::{CachedLoginInfo, ExitNodeConfiguration, TokenLogin, get_hostname, set_access_token}; use md5::Md5;
use punchnet::{
get_hostname, set_access_token, CachedLoginInfo, ExitNodeConfiguration, 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;
use tracing::warn; use tracing::warn;
pub const TEST_PREFIX: &'static str = "https://root.punchsky.com/api"; pub const TEST_PREFIX: &'static str = "https://test.punchsky.com/api";
const DIGEST_KEY: &'static str = "H6p*2RfEu4ITcL"; const DIGEST_KEY: &'static str = "H6p*2RfEu4ITcL";
type HmacMd5 = Hmac<Md5>; type HmacMd5 = Hmac<Md5>;
@ -29,7 +31,7 @@ struct TokenLoginData<'a> {
hostname: &'a str, hostname: &'a str,
} }
fn do_calculate(data: &[u8]) -> Result<String>{ fn do_calculate(data: &[u8]) -> Result<String> {
let Ok(mut mac) = HmacMd5::new_from_slice(DIGEST_KEY.as_bytes()) else { let Ok(mut mac) = HmacMd5::new_from_slice(DIGEST_KEY.as_bytes()) else {
return Err(SDLanError::IOError("failed to new hmac".to_owned())); return Err(SDLanError::IOError("failed to new hmac".to_owned()));
}; };
@ -38,21 +40,16 @@ fn do_calculate(data: &[u8]) -> Result<String>{
Ok(hex::encode(result)) Ok(hex::encode(result))
} }
impl <'a> HMacCalculator for TokenLoginData<'a> { impl<'a> HMacCalculator for TokenLoginData<'a> {
fn calculate_hmac(&self) -> Result<String> { fn calculate_hmac(&self) -> Result<String> {
let data = format!("client_id={}&hostname={}&mac={}&system={}&token={}&version={}", let data = format!(
self.client_id, "client_id={}&hostname={}&mac={}&system={}&token={}&version={}",
self.hostname, self.client_id, self.hostname, self.mac, self.system, self.token, self.version,
self.mac,
self.system,
self.token,
self.version,
); );
do_calculate(data.as_bytes()) do_calculate(data.as_bytes())
} }
} }
#[derive(Serialize)] #[derive(Serialize)]
struct UserPassLoginData<'a> { struct UserPassLoginData<'a> {
client_id: &'a str, client_id: &'a str,
@ -66,7 +63,8 @@ struct UserPassLoginData<'a> {
impl HMacCalculator for UserPassLoginData<'_> { impl HMacCalculator for UserPassLoginData<'_> {
fn calculate_hmac(&self) -> Result<String> { fn calculate_hmac(&self) -> Result<String> {
let data = format!("client_id={}&hostname={}&mac={}&password={}&system={}&username={}&version={}", let data = format!(
"client_id={}&hostname={}&mac={}&password={}&system={}&username={}&version={}",
self.client_id, self.client_id,
self.hostname, self.hostname,
self.mac, self.mac,
@ -99,14 +97,15 @@ impl TryInto<LoginData> for LoginResponse {
eprintln!("failed to save access_token"); eprintln!("failed to save access_token");
} }
Ok(data) Ok(data)
},
None => Err(SDLanError::IOError(format!("data is none: {}", self.message))),
} }
None => Err(SDLanError::IOError(format!(
"data is none: {}",
self.message
))),
}
} }
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct LoginResponse { pub struct LoginResponse {
pub code: i32, pub code: i32,
@ -134,19 +133,17 @@ pub struct LoginData {
} }
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
pub struct ExitNode{ pub struct ExitNode {
pub node_id: u32, pub node_id: u32,
pub node_name: String, pub node_name: String,
pub gateway: String, pub gateway: String,
pub target_network: String, pub target_network: String,
} }
async fn post_with_data<T, R>( async fn post_with_data<T, R>(url: &str, data: T) -> Result<R>
url: &str, where
data: T, T: Serialize + HMacCalculator,
) -> Result<R> R: for<'de> Deserialize<'de>,
where T: Serialize + HMacCalculator,
R: for<'de> Deserialize<'de>
{ {
let client = Client::new(); let client = Client::new();
@ -162,7 +159,8 @@ where T: Serialize + HMacCalculator,
.header("X-sign", hmac.clone()) .header("X-sign", hmac.clone())
.json(&data) .json(&data)
.send() .send()
.await { .await
{
Ok(response) => { Ok(response) => {
response_ok = true; response_ok = true;
response response
@ -183,18 +181,24 @@ where T: Serialize + HMacCalculator,
let text = match response.text().await { let text = match response.text().await {
Ok(text) => text, Ok(text) => text,
Err(e) => { Err(e) => {
return Err(SDLanError::IOError(format!("failed to get response text: {}", e))) return Err(SDLanError::IOError(format!(
"failed to get response text: {}",
e
)))
} }
}; };
let data = match serde_json::from_str(&text) { let data = match serde_json::from_str(&text) {
Ok(data) => data, Ok(data) => data,
Err(e) => { Err(e) => {
return Err(SDLanError::IOError(format!("failed to deserialize text: {}", e))) return Err(SDLanError::IOError(format!(
"failed to deserialize text: {}",
e
)))
} }
}; };
return Ok(data); return Ok(data);
}; }
// println!("got test: {}", text); // println!("got test: {}", text);
// let data = serde_json::from_str(&text).unwrap(); // let data = serde_json::from_str(&text).unwrap();
@ -217,7 +221,8 @@ pub async fn login_with_user_pass(
system: &str, system: &str,
version: &str, version: &str,
) -> Result<LoginResponse> { ) -> Result<LoginResponse> {
let mac = format!("{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}", let mac = format!(
"{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]
); );
@ -244,7 +249,8 @@ pub async fn login_with_token(
system: &str, system: &str,
version: &str, version: &str,
) -> Result<LoginResponse> { ) -> Result<LoginResponse> {
let mac = format!("{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}", let mac = format!(
"{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]
); );
@ -270,9 +276,9 @@ struct ConnectDisconnectRequest<'a> {
impl HMacCalculator for ConnectDisconnectRequest<'_> { impl HMacCalculator for ConnectDisconnectRequest<'_> {
fn calculate_hmac(&self) -> Result<String> { fn calculate_hmac(&self) -> Result<String> {
let data = format!("access_token={}&client_id={}", let data = format!(
self.access_token, "access_token={}&client_id={}",
self.client_id self.access_token, self.client_id
); );
do_calculate(data.as_bytes()) do_calculate(data.as_bytes())
} }
@ -354,10 +360,9 @@ struct GetResourceRequest<'a> {
impl HMacCalculator for GetResourceRequest<'_> { impl HMacCalculator for GetResourceRequest<'_> {
fn calculate_hmac(&self) -> Result<String> { fn calculate_hmac(&self) -> Result<String> {
let data = format!("access_token={}&client_id={}&id={}", let data = format!(
self.access_token, "access_token={}&client_id={}&id={}",
self.client_id, self.access_token, self.client_id, self.id,
self.id,
); );
do_calculate(data.as_bytes()) do_calculate(data.as_bytes())
} }

View File

@ -8,8 +8,8 @@ use std::process;
use std::time::Duration; use std::time::Duration;
use clap::Parser; use clap::Parser;
use punchnet::ExitNodeConfiguration;
use punchnet::store_configuration; use punchnet::store_configuration;
use punchnet::ExitNodeConfiguration;
use sdlan_sn_rs::utils::SDLanError; use sdlan_sn_rs::utils::SDLanError;
use std::env; use std::env;
@ -135,7 +135,7 @@ async fn daemonize_me(
let (tx, rx) = std::sync::mpsc::channel(); let (tx, rx) = std::sync::mpsc::channel();
let hostname = "root.punchsky.com".to_owned(); let hostname = "test.punchsky.com".to_owned();
let host = format!("{}:80", hostname); let host = format!("{}:80", hostname);
let mut server = String::new(); let mut server = String::new();
if let Ok(addrs) = host.to_socket_addrs() { if let Ok(addrs) = host.to_socket_addrs() {
@ -198,7 +198,8 @@ async fn daemonize_me(
None, None,
None, None,
) )
.await { .await
{
panic!("failed to run_sdlan: {}", e.as_str()); panic!("failed to run_sdlan: {}", e.as_str());
}; };
@ -312,26 +313,22 @@ async fn login_with_token_or_user_pass(
version: &str, version: &str,
token: &Option<String>, token: &Option<String>,
user: &Option<String>, user: &Option<String>,
pass: &Option<String> pass: &Option<String>,
) -> Result<LoginData>{ ) -> Result<LoginData> {
if let Some(ref tk) = token { if let Some(ref tk) = token {
login_with_token(TEST_PREFIX, client_id, tk, mac, system, version) login_with_token(TEST_PREFIX, client_id, tk, mac, system, version)
.await?.try_into() .await?
.try_into()
} else { } else {
if let (Some(ref user), Some(ref pass)) = (&user, &pass) { if let (Some(ref user), Some(ref pass)) = (&user, &pass) {
login_with_user_pass( login_with_user_pass(TEST_PREFIX, &client_id, &user, &pass, mac, system, version)
TEST_PREFIX, .await?
&client_id, .try_into()
&user,
&pass,
mac,
system,
version,
)
.await?.try_into()
} else { } else {
// eprintln!("invalid argument, use --help for help"); // eprintln!("invalid argument, use --help for help");
Err(SDLanError::IOError("Invalid argument, use --help for help".to_string())) Err(SDLanError::IOError(
"Invalid argument, use --help for help".to_string(),
))
// process::exit(-1); // process::exit(-1);
} }
} }
@ -374,7 +371,17 @@ fn main() {
std::process::exit(-1); std::process::exit(-1);
} }
if let Err(e) = login_with_token_or_user_pass(&client_id, mac, system, version, &user.token, &user.username, &user.password).await { if let Err(e) = login_with_token_or_user_pass(
&client_id,
mac,
system,
version,
&user.token,
&user.username,
&user.password,
)
.await
{
eprintln!("failed to login: {}", e.as_str()); eprintln!("failed to login: {}", e.as_str());
std::process::exit(-1); std::process::exit(-1);
} }
@ -395,7 +402,6 @@ fn main() {
process::exit(0); process::exit(0);
} }
*/ */
Commands::ExitNode(cmd) => { Commands::ExitNode(cmd) => {
let rt = Runtime::new().unwrap(); let rt = Runtime::new().unwrap();
rt.block_on(async move { rt.block_on(async move {
@ -519,13 +525,16 @@ fn record_exit_node(connect_info: &ConnectData) {
let mut local_configuration = load_configuration(); let mut local_configuration = load_configuration();
let mut temp = HashMap::new(); let mut temp = HashMap::new();
for node in &connect_info.exit_node { for node in &connect_info.exit_node {
temp.insert(node.node_id, ExitNodeConfiguration { temp.insert(
node.node_id,
ExitNodeConfiguration {
in_use: false, in_use: false,
node_id: node.node_id, node_id: node.node_id,
node_name: node.node_name.clone(), node_name: node.node_name.clone(),
gateway: node.gateway.clone(), gateway: node.gateway.clone(),
target_network: node.target_network.clone(), target_network: node.target_network.clone(),
}); },
);
} }
local_configuration.exit_node = temp; local_configuration.exit_node = temp;
if let Err(e) = store_configuration(&local_configuration) { if let Err(e) = store_configuration(&local_configuration) {
@ -544,7 +553,6 @@ fn run_it(
let rt = Runtime::new().unwrap(); let rt = Runtime::new().unwrap();
match &cmd.cmd { match &cmd.cmd {
Commands::Start(rtinfo) => rt.block_on(async move { Commands::Start(rtinfo) => rt.block_on(async move {
let remembered_token = get_access_token(); let remembered_token = get_access_token();
if remembered_token.is_none() { if remembered_token.is_none() {
eprintln!("not logged in, should login with user/pass or token first"); eprintln!("not logged in, should login with user/pass or token first");
@ -570,10 +578,18 @@ fn run_it(
}), }),
Commands::AutoRun(tk) => rt.block_on(async move { Commands::AutoRun(tk) => rt.block_on(async move {
loop { loop {
let data = match login_with_token_or_user_pass(&client_id, mac, system, version, &tk.token, &tk.username, &tk.password).await { let data = match login_with_token_or_user_pass(
Ok(data) => { &client_id,
data mac,
} system,
version,
&tk.token,
&tk.username,
&tk.password,
)
.await
{
Ok(data) => data,
Err(e) => { Err(e) => {
eprintln!("failed to login: {}, will try in 10 seconds", e.as_str()); eprintln!("failed to login: {}, will try in 10 seconds", e.as_str());
tokio::time::sleep(Duration::from_secs(10)).await; tokio::time::sleep(Duration::from_secs(10)).await;
@ -610,7 +626,6 @@ fn run_it(
.await; .await;
break; break;
} }
}), }),
_other => { _other => {
@ -639,7 +654,7 @@ fn is_pid_running(pid: u32) -> bool {
sys.process(sysinfo::Pid::from_u32(pid)).is_some() sys.process(sysinfo::Pid::from_u32(pid)).is_some()
} }
pub fn is_process_running() -> bool{ pub fn is_process_running() -> bool {
if Path::new(PID_FILE).exists() { if Path::new(PID_FILE).exists() {
if let Some(pid) = read_pid_file() { if let Some(pid) = read_pid_file() {
if !is_pid_running(pid) { if !is_pid_running(pid) {

View File

@ -162,7 +162,6 @@ impl RuleCache {
if allow_routing { if allow_routing {
return (true, false); return (true, false);
} }
return (true, false);
error!("is identity ok? {:?}", info); error!("is identity ok? {:?}", info);
if self.session_table.process_packet(&info) { if self.session_table.process_packet(&info) {