cached login info, and connect info is accessed while connect

This commit is contained in:
alex 2026-03-02 16:12:19 +08:00
parent 00c5c67307
commit e8e8655100
2 changed files with 118 additions and 23 deletions

View File

@ -4,11 +4,14 @@ use std::process;
use std::env; use std::env;
use clap::Parser; use clap::Parser;
use punchnet::CachedLoginInfo;
use punchnet::CommandLineInput2; use punchnet::CommandLineInput2;
use punchnet::Commands; use punchnet::Commands;
use punchnet::create_or_load_mac; use punchnet::create_or_load_mac;
use punchnet::get_access_token;
use punchnet::get_base_dir; use punchnet::get_base_dir;
use punchnet::get_edge; use punchnet::get_edge;
use punchnet::ip_string_to_u32;
use punchnet::mod_hostname; use punchnet::mod_hostname;
use punchnet::restore_dns; use punchnet::restore_dns;
use punchnet::run_sdlan; use punchnet::run_sdlan;
@ -27,9 +30,12 @@ use tracing::error;
use std::net::ToSocketAddrs; use std::net::ToSocketAddrs;
use structopt::StructOpt; use structopt::StructOpt;
use crate::api::ConnectData;
use crate::api::ConnectResponse;
use crate::api::LoginData; use crate::api::LoginData;
use crate::api::LoginResponse; use crate::api::LoginResponse;
use crate::api::TEST_PREFIX; use crate::api::TEST_PREFIX;
use crate::api::connect;
use crate::api::login_with_token; use crate::api::login_with_token;
use crate::api::login_with_user_pass; use crate::api::login_with_user_pass;
@ -38,6 +44,26 @@ const APP_USER_ENV_NAME: &str = "PUNCH_USER";
const APP_PASS_ENV_NAME: &str = "PUNCH_PASS"; const APP_PASS_ENV_NAME: &str = "PUNCH_PASS";
const APP_TOKEN_ENV_NAME: &str = "PUNCH_TOKEN"; const APP_TOKEN_ENV_NAME: &str = "PUNCH_TOKEN";
fn parse_connect_result(res: Result<ConnectResponse>) -> ConnectData {
match res {
Err(e) => {
eprintln!("failed to connect");
process::exit(-3);
}
Ok(data) => {
if data.code != 0 {
eprintln!("failed to connect: {}", data.message);
process::exit(-3);
}
if data.data.is_none() {
eprintln!("connect empty response");
process::exit(-3);
}
data.data.unwrap()
}
}
}
fn parse_login_result(res: Result<LoginResponse>) -> LoginData { fn parse_login_result(res: Result<LoginResponse>) -> LoginData {
match res { match res {
Err(e) => { Err(e) => {
@ -54,7 +80,14 @@ fn parse_login_result(res: Result<LoginResponse>) -> LoginData {
process::exit(-1); process::exit(-1);
}; };
if let Err(_e) = set_access_token(&data.access_token) { if let Err(_e) = set_access_token(&CachedLoginInfo {
access_token: data.access_token.clone(),
username: data.username.clone(),
user_type: data.user_type.clone(),
audit: data.audit,
network_id: data.network_id,
network_name: data.network_name.clone(),
}) {
eprintln!("failed to save access_token"); eprintln!("failed to save access_token");
} }
data data
@ -80,30 +113,68 @@ async fn main() {
let cmd = CommandLineInput2::parse(); let cmd = CommandLineInput2::parse();
// println!("port is {}", cmd.port); // println!("port is {}", cmd.port);
let connect_info: ConnectData;
let remembered: CachedLoginInfo;
match cmd.cmd { match cmd.cmd {
Commands::Login(user) => { Commands::Login(user) => {
// TODO: do login with user // TODO: do login with user
let data = parse_login_result( let _ = parse_login_result(
login_with_user_pass(TEST_PREFIX, &client_id, &user.username, &user.password, mac, system, version).await login_with_user_pass(TEST_PREFIX, &client_id, &user.username, &user.password, mac, system, version).await
); );
process::exit(0);
} }
Commands::TokenLogin(tk) => { Commands::TokenLogin(tk) => {
let _ = parse_login_result(
login_with_token(TEST_PREFIX, &client_id, &tk.token, mac, system, version).await
);
process::exit(0);
} }
Commands::AutoRun(tk) => { Commands::AutoRun(tk) => {
let mut remembered_token = get_access_token();
if remembered_token.is_none() {
let data = parse_login_result(
login_with_token(TEST_PREFIX, &client_id, &tk.token, mac, system, version).await
);
remembered_token = Some(CachedLoginInfo{
access_token: data.access_token,
username: data.username,
user_type: data.user_type,
audit: data.audit,
network_id: data.network_id,
network_name: data.network_name,
});
}
remembered = remembered_token.unwrap();
connect_info = parse_connect_result(
connect(TEST_PREFIX, &client_id, &remembered.access_token).await
);
} }
Commands::Start => { Commands::Start => {
let remembered_token = get_access_token();
if remembered_token.is_none() {
eprintln!("not logged in, should login with user/pass or token first");
process::exit(-2);
}
remembered = remembered_token.unwrap();
connect_info = parse_connect_result(
connect(TEST_PREFIX, &client_id, &remembered.access_token).await
);
} }
Commands::Stop => { Commands::Stop => {
process::exit(-4);
} }
} }
let self_host_name = connect_info.hostname;
let (tx, rx) = std::sync::mpsc::channel(); let (tx, rx) = std::sync::mpsc::channel();
let hostname = "punchnet.aioe.tech".to_owned(); let hostname = "118.178.229.213".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() {
@ -141,10 +212,11 @@ async fn main() {
client_id, client_id,
mac, mac,
CommandLine { CommandLine {
sn: server.clone()+":1265", sn: server.clone()+":1365",
tcp: server.clone()+":18083", tcp: server.clone()+":443",
nat_server1: server.clone() +":1265", nat_server1: server.clone() +":1365",
nat_server2: "47.98.178.3:1265".to_owned(), // nat_server2: "47.98.178.3:1265".to_owned(),
nat_server2: server.clone() +":1366",
_allow_routing: true, _allow_routing: true,
_drop_multicast: true, _drop_multicast: true,
register_ttl: 1, register_ttl: 1,
@ -159,7 +231,7 @@ async fn main() {
tx, tx,
&punchnet::get_install_channel(), &punchnet::get_install_channel(),
server, server,
Some(hostname), Some(self_host_name),
None, None,
) )
.await; .await;
@ -191,14 +263,20 @@ async fn main() {
// exit(0); // exit(0);
} }
*/ */
let Ok(ip_net) = ip_string_to_u32(&connect_info.ip) else {
eprintln!("got ip from network is invlid: {}", connect_info.ip);
process::exit(-5);
};
if let Err(e) = edge.start_without_feedback( if let Err(e) = edge.start_without_feedback(
String::new(), remembered.access_token.clone(),
0, // String::new(),
remembered.network_id,
&"".to_owned(), &"".to_owned(),
0, ip_net,
24, connect_info.mask_len,
0, connect_info.identity_id,
Some("".to_owned()) // 0,
None,
).await { ).await {
error!("failed to start: {:?}", e); error!("failed to start: {:?}", e);
} }

View File

@ -1,18 +1,29 @@
mod command; mod command;
use std::{fs::OpenOptions, io::Write, path::Path}; use std::{fs::OpenOptions, io::Write, net::Ipv4Addr, path::Path};
pub use command::*; pub use command::*;
mod socks; mod socks;
use rand::Rng; use rand::Rng;
use sdlan_sn_rs::utils::{Mac, Result, SDLanError, save_to_file}; use sdlan_sn_rs::utils::{Mac, Result, SDLanError, save_to_file};
use serde::{Deserialize, Serialize};
pub use socks::*; pub use socks::*;
use crate::get_base_dir; use crate::get_base_dir;
mod pid_recorder; mod pid_recorder;
#[derive(Serialize, Deserialize, Debug)]
pub struct CachedLoginInfo {
pub access_token: String,
pub username: String,
pub user_type: String,
pub audit: u32,
pub network_id: u32,
pub network_name: String,
}
// pub const CRC_HASH: crc::Crc<u32> = crc::Crc::<u32>::new(&crc::CRC_32_XFER); // pub const CRC_HASH: crc::Crc<u32> = crc::Crc::<u32>::new(&crc::CRC_32_XFER);
#[allow(unused)] #[allow(unused)]
@ -21,18 +32,24 @@ pub fn caculate_crc(data: &[u8]) -> u32 {
res res
} }
pub fn get_access_token() -> Option<String> { pub fn ip_string_to_u32(ip: &str) -> Result<u32> {
let ip = ip.parse::<Ipv4Addr>()?;
Ok(u32::from(ip))
}
pub fn get_access_token() -> Option<CachedLoginInfo> {
let path = format!("{}/.access_token", get_base_dir()); let path = format!("{}/.access_token", get_base_dir());
if let Ok(content) = std::fs::read(&path) { if let Ok(content) = std::fs::read(&path) {
let result = String::from_utf8_lossy(&content); let data = serde_json::from_slice((&content)).unwrap();
return Some(result.to_string()); return Some(data);
} }
None None
} }
pub fn set_access_token(tk: &str) -> Result<()> { pub fn set_access_token(cache_info: &CachedLoginInfo) -> Result<()> {
let path = format!("{}/.access_token", get_base_dir()); let path = format!("{}/.access_token", get_base_dir());
std::fs::write(path, tk)?; let data = serde_json::to_string(cache_info).unwrap();
std::fs::write(path, &data)?;
Ok(()) Ok(())
} }