-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
limingwei
committed
Apr 14, 2024
0 parents
commit a86fc4b
Showing
13 changed files
with
433 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
/target | ||
Cargo.lock | ||
|
||
/logs | ||
.idea |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
[package] | ||
name = "Nal" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
reqwest = { version = "0.11", features = ["json"] } | ||
tokio = { version = "1", features = ["full"] } | ||
serde = { version = "1.0.197", features = ["derive"] } | ||
serde_json = "1.0.114" | ||
serde_yaml = "0.9.32" | ||
#rc4 = "0.1.0" | ||
log = "0.4.20" | ||
async-trait = "0.1.77" | ||
cron = "0.12.1" | ||
chrono = "0.4.34" | ||
#env_logger = "0.11.3" | ||
fern = "0.6" | ||
#log4rs = "1.3.0" | ||
yaml-rust = "0.4.5" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
login: | ||
username: 2336 #用户名(工号) | ||
password: 2336 #密码 | ||
|
||
check: | ||
interval: 10 #单位秒 | ||
|
||
log: | ||
normal: false #是否显示操作正常的日志 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pub mod nal; | ||
pub mod sangfor; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
use std::collections::HashMap; | ||
use std::time::Duration; | ||
use async_trait::async_trait; | ||
use reqwest::{Client, Error}; | ||
use serde::{Deserialize, Serialize}; | ||
use serde::__private::de::Content::I16; | ||
use serde_json::Value; | ||
use tokio::time::timeout; | ||
|
||
/// 网络自动登录trait | ||
#[async_trait] | ||
pub trait Nal { | ||
/// 登录网络 | ||
async fn login_net(&self, config: &LoginConfig) -> Result<bool, Error>; | ||
} | ||
|
||
/// 网络类型 | ||
#[derive(Debug, Serialize, Deserialize)] | ||
pub enum NetType { | ||
Sangfor, | ||
Other, | ||
} | ||
|
||
/// 登录配置 | ||
#[derive(Debug, Serialize, Deserialize)] | ||
pub struct LoginConfig { | ||
pub username: String, | ||
pub password: String, | ||
} | ||
|
||
impl LoginConfig { | ||
pub fn new(username: &str, password: &str) -> Self { | ||
Self { | ||
username: String::from(username), | ||
password: String::from(password), | ||
} | ||
} | ||
} | ||
|
||
/// 网络状态检测相关参数 | ||
#[derive(Debug, Serialize, Deserialize)] | ||
pub struct NetStatusCheck { | ||
/// 检测间隔时间,单位秒 | ||
pub interval: u16, | ||
} | ||
|
||
|
||
/// 获取没有代理的客户端 | ||
pub fn get_no_proxy_client() -> Client { | ||
Client::builder() | ||
.no_proxy() // 禁用代理 | ||
.timeout(Duration::from_secs(30)) | ||
.build().unwrap() | ||
} | ||
|
||
/// 检测网络是否正常 | ||
pub async fn check_net() -> bool { | ||
get_no_proxy_client() | ||
.get("http://baidu.com") | ||
.send() | ||
.await | ||
.is_ok() | ||
} | ||
|
||
pub async fn login<T: Nal>(nal: &T, lc: &LoginConfig) -> Result<bool, Error> { | ||
nal.login_net(lc).await | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
use std::collections::HashMap; | ||
use std::future::Future; | ||
use std::time::{SystemTime, UNIX_EPOCH}; | ||
use async_trait::async_trait; | ||
use log::info; | ||
use reqwest::{Error, Response}; | ||
use crate::core::nal; | ||
use crate::core::nal::{get_no_proxy_client, LoginConfig, Nal}; | ||
use crate::util::rc4::RC4; | ||
|
||
/// 深信服 | ||
pub struct Sangfor { | ||
login_url: String, | ||
} | ||
|
||
/// 登录接口 | ||
const LOGIN_API: &str = "/ac_portal/login.php"; | ||
|
||
impl Sangfor { | ||
pub fn new(addr: &str) -> Sangfor { | ||
let mut string = addr.to_owned(); | ||
string.push_str(LOGIN_API); | ||
Self { | ||
login_url: String::from(string), | ||
} | ||
} | ||
|
||
/// rc4编码 | ||
fn rc4_encode(key: &str, pwd: &str) -> String { | ||
let mut data = pwd.as_bytes().to_vec(); | ||
|
||
// let mut rc4 = Rc4::new(key.as_bytes().into()); | ||
// rc4.apply_keystream(&mut data); | ||
|
||
let mut rc4 = RC4::new(key.as_bytes()); | ||
rc4.apply_keystream(&mut data); | ||
|
||
data.iter().map(|b| format!("{:02x}", b)).collect::<String>() | ||
} | ||
} | ||
|
||
#[async_trait] | ||
impl Nal for Sangfor { | ||
async fn login_net(&self, config: &LoginConfig) -> Result<bool, Error> { | ||
let client = get_no_proxy_client(); | ||
|
||
let mut params = HashMap::new(); | ||
params.insert("opr", "pwdLogin"); | ||
params.insert("userName", config.username.as_str()); | ||
let timestamp = (SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis() as u64).to_string(); | ||
let auth_tag = timestamp.as_str(); | ||
params.insert("auth_tag", auth_tag); | ||
let pwd = Self::rc4_encode(auth_tag, config.password.as_str()); | ||
params.insert("pwd", pwd.as_str()); | ||
params.insert("rememberPwd", "1"); | ||
let lu = &self.login_url; | ||
let rsp = client.post(lu) | ||
.form(¶ms) | ||
.send() | ||
.await? | ||
.json::<serde_json::Value>() | ||
.await?; | ||
info!("login result: {rsp:#?}"); | ||
// rsp.is_ok() | ||
Ok(rsp["success"] == true) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
use std::fs; | ||
use std::fs::{File, OpenOptions}; | ||
use std::str::FromStr; | ||
use tokio::time::{Duration, sleep}; | ||
use chrono::{Datelike, DateTime, Local, Timelike, Utc}; | ||
use cron::Schedule; | ||
use log::{info, warn}; | ||
use serde_json::Value::Bool; | ||
use crate::core::nal; | ||
use crate::core::nal::{login, LoginConfig, NetStatusCheck, NetType}; | ||
use crate::core::sangfor::Sangfor; | ||
use std::io::{Error, Write}; | ||
use std::time::SystemTime; | ||
use serde::{Deserialize, Serialize}; | ||
|
||
mod core; | ||
mod test; | ||
mod util; | ||
|
||
|
||
/// NAL配置参数 | ||
#[derive(Debug, Serialize, Deserialize)] | ||
pub struct NalConfig { | ||
pub net_type: Option<NetType>, | ||
pub login: LoginConfig, | ||
pub check: NetStatusCheck, | ||
} | ||
|
||
impl NalConfig { | ||
pub fn default() -> Self { | ||
NalConfig { | ||
net_type: Option::from(NetType::Sangfor), | ||
login: LoginConfig { username: "".to_string(), password: "".to_string() }, | ||
check: NetStatusCheck { interval: 0 }, | ||
} | ||
} | ||
} | ||
|
||
/// 初始化配置 | ||
pub fn init_config() -> NalConfig { | ||
let result = File::open("./config.yml"); | ||
if result.is_err() { | ||
//初始化配置 | ||
return NalConfig::default(); | ||
} | ||
|
||
//缺少字段会导致序列化出错 | ||
let result1 = serde_yaml::from_reader(result.unwrap()); | ||
if result1.is_err() { | ||
let string = result1.err().unwrap().to_string(); | ||
warn!("config serde_yaml error: {string}"); | ||
NalConfig::default() | ||
} else { | ||
let mut yaml: NalConfig = result1.unwrap_or(NalConfig::default()); | ||
if yaml.net_type.is_none() { | ||
yaml.net_type = Option::from(NetType::Sangfor) | ||
} | ||
yaml | ||
} | ||
} | ||
|
||
#[tokio::main] | ||
async fn main() { | ||
util::logs::init("nal.log").expect("初始化日志出错"); | ||
|
||
let config = init_config(); | ||
info!("config: {config:#?}"); | ||
|
||
/*let expression = "* 1 * * * * *"; | ||
let schedule = Schedule::from_str(expression).unwrap(); | ||
println!("All stars: Upcoming fire times for '{}':", expression); | ||
for datetime in schedule.upcoming(Utc).take(10) { | ||
let is_ok = nal::check_net().await; | ||
println!("net isOk: -> {is_ok:}"); | ||
}*/ | ||
|
||
loop { | ||
//检测网络是否正常 | ||
let is_ok = nal::check_net().await; | ||
if !is_ok { | ||
warn!("网络异常"); | ||
//登录 | ||
let sangfor = Sangfor::new("http://1.1.1.4"); | ||
let login_ok = nal::login(&sangfor, &config.login).await; | ||
if login_ok.unwrap_or_else(|e| { false }) { | ||
info!("登录成功"); | ||
} else { | ||
info!("登录失败"); | ||
} | ||
} else { | ||
info!("网络正常"); | ||
}; | ||
|
||
// 延迟指定秒后再次执行 | ||
sleep(Duration::from_secs(config.check.interval as u64)).await; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
mod rc4; | ||
mod nal; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
use log::log; | ||
use crate::core::nal; | ||
use crate::core::nal::{LoginConfig, Nal}; | ||
use crate::core::sangfor::Sangfor; | ||
|
||
// #[test] | ||
#[tokio::test] | ||
async fn sangfor() { | ||
let nal: &dyn Nal = &Sangfor::new("http://1.1.1.4/ac_portal/login.php"); | ||
let config = LoginConfig { | ||
username: 2336.to_string(), | ||
password: 13141.to_string(), | ||
}; | ||
let is_ok = nal.login_net(&config).await; | ||
println!(" is_ok: {:?}", is_ok); | ||
} | ||
|
||
#[tokio::test] | ||
async fn check_net() { | ||
let is_ok = nal::check_net().await; | ||
println!(" is_ok: {:?}", is_ok); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
use std::string::String; | ||
use std::str::{from_utf8, from_utf8_mut}; | ||
// use rc4::{consts::*, KeyInit, StreamCipher}; | ||
// use rc4::{Key, Rc4}; | ||
|
||
#[test] | ||
fn custom_encode(){ | ||
let key = b"secret_key"; | ||
let mut rc4 = crate::util::rc4::RC4::new(key); | ||
|
||
let mut data = b"hello world".to_vec(); | ||
println!("Original: {:?}", from_utf8(&*data)); | ||
println!("Original: {:?}", data.iter().map(|b| format!("{:02x}", b)).collect::<String>()); | ||
|
||
// let mut data = data.as_slice(); | ||
rc4.apply_keystream(&mut data); | ||
let hex_string = data.iter().map(|b| format!("{:02x}", b)).collect::<String>(); | ||
println!("Encrypted: {:?}", hex_string); | ||
|
||
// 每次使用需要重新创建,不然解密后的数据不对 | ||
let mut rc4 = crate::util::rc4::RC4::new(key); | ||
let mut encode_data = b"\x2b\x5a\xf7\xcd\xaf\x75\x9c\x49\x3b\x8c\xd0".to_vec(); // 加密后的数据 | ||
rc4.apply_keystream(&mut encode_data); | ||
println!("Decrypted: {:?}", encode_data.iter().map(|b| format!("{:02x}", b)).collect::<String>()); | ||
} | ||
|
||
// #rc4 = "0.1.0" | ||
// #[test] | ||
// fn rc4_encode(){ | ||
// let mut rc4 = Rc4::new(b"secret_key".into()); | ||
// let mut data = b"hello world".to_vec(); | ||
// println!(" Original: {:?}", data.iter().map(|b| format!("{:02x}", b)).collect::<String>()); | ||
// rc4.apply_keystream(&mut data); | ||
// println!("Encrypted: {:?}", data.iter().map(|b| format!("{:02x}", b)).collect::<String>()); | ||
// | ||
// let mut rc4 = Rc4::new(b"secret_key".into()); | ||
// rc4.apply_keystream(&mut data); | ||
// println!("Decrypted: {:?}", data.iter().map(|b| format!("{:02x}", b)).collect::<String>()); | ||
// } |
Oops, something went wrong.