增加密钥hash,方便客户端判断加密是否一致

This commit is contained in:
lbl8603
2024-04-20 21:27:35 +08:00
parent 0cbc3e0f63
commit 137efe20b8
9 changed files with 67 additions and 10 deletions
+2
View File
@@ -36,5 +36,7 @@ pub struct DeviceItem {
pub rt: String,
pub status: String,
pub client_secret: bool,
pub client_secret_hash: Vec<u8>,
pub current_client_secret: bool,
pub current_client_secret_hash: Vec<u8>,
}
+3
View File
@@ -85,6 +85,7 @@ pub fn command_list(vnt: &Vnt) -> Vec<DeviceItem> {
let device_list = vnt.device_list();
let mut list = Vec::new();
let current_client_secret = vnt.client_encrypt();
let client_encrypt_hash = vnt.client_encrypt_hash().unwrap_or(&[]);
for peer in device_list {
let name = peer.name;
let virtual_ip = peer.virtual_ip.to_string();
@@ -153,7 +154,9 @@ pub fn command_list(vnt: &Vnt) -> Vec<DeviceItem> {
rt,
status,
client_secret,
client_secret_hash: peer.client_secret_hash,
current_client_secret,
current_client_secret_hash: client_encrypt_hash.to_vec(),
};
list.push(item);
}
+7 -2
View File
@@ -21,6 +21,7 @@ pub fn console_info(status: Info) {
println!("Up: {}", style(convert(status.up)).green());
println!("Down: {}", style(convert(status.down)).green());
}
fn convert(num: u64) -> String {
let gigabytes = num / (1024 * 1024 * 1024);
let remaining_bytes = num % (1024 * 1024 * 1024);
@@ -90,13 +91,17 @@ pub fn console_device_list(mut list: Vec<DeviceItem>) {
]);
for item in list {
if &item.status == "Online" {
if item.client_secret != item.current_client_secret {
if item.client_secret != item.current_client_secret
|| (!item.current_client_secret_hash.is_empty()
&& !item.client_secret_hash.is_empty()
&& item.current_client_secret_hash != item.client_secret_hash)
{
//加密状态不一致,无法通信的
out_list.push(vec![
(item.name, Style::new().red()),
(item.virtual_ip, Style::new().red()),
(item.status, Style::new().red()),
("".to_string(), Style::new().red()),
("Mismatch".to_string(), Style::new().red()),
("".to_string(), Style::new().red()),
]);
} else {
+2
View File
@@ -24,6 +24,7 @@ message RegistrationRequest {
fixed32 virtual_ip = 6;
bool allow_ip_change = 7;
bool client_secret = 8;
bytes client_secret_hash = 9;
}
message RegistrationResponse {
@@ -41,6 +42,7 @@ message DeviceInfo {
fixed32 virtual_ip = 2;
uint32 device_status = 3;
bool client_secret = 4;
bytes client_secret_hash = 5;
}
message DeviceList {
+13
View File
@@ -1,6 +1,7 @@
#[cfg(feature = "aes_ecb")]
#[cfg(not(any(feature = "openssl-vendored", feature = "openssl")))]
use crate::cipher::aes_ecb::AesEcbCipher;
use std::fmt::Display;
#[cfg(feature = "aes_cbc")]
use crate::cipher::aes_cbc::AesCbcCipher;
@@ -48,6 +49,18 @@ pub enum CipherModel {
None,
}
impl Display for CipherModel {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let str = match self {
CipherModel::AesGcm => "aes_gcm".to_string(),
CipherModel::AesCbc => "aes_cbc".to_string(),
CipherModel::AesEcb => "aes_ecb".to_string(),
CipherModel::Sm4Cbc => "sm4_cbc".to_string(),
CipherModel::None => "none".to_string(),
};
write!(f, "{}", str)
}
}
impl FromStr for CipherModel {
type Err = String;
+15 -1
View File
@@ -7,6 +7,7 @@ use std::time::Duration;
use crossbeam_utils::atomic::AtomicCell;
use parking_lot::{Mutex, RwLock};
use rand::Rng;
use rsa::signature::digest::Digest;
#[cfg(not(target_os = "android"))]
use tun::device::IFace;
@@ -43,6 +44,7 @@ pub struct Vnt {
peer_nat_info_map: Arc<RwLock<HashMap<Ipv4Addr, NatInfo>>>,
down_count_watcher: WatchU64Adder,
up_count_watcher: WatchSingleU64Adder,
client_secret_hash: Option<[u8; 16]>,
}
impl Vnt {
@@ -79,7 +81,14 @@ impl Vnt {
config.name.clone(),
config.token.clone(),
config.ip,
config.password.is_some(),
config.password.as_ref().map(|v| {
let mut hasher = sha2::Sha256::new();
hasher.update(config.cipher_model.to_string().as_bytes());
hasher.update(v.as_bytes());
hasher.update(config.token.as_bytes());
let key: [u8; 32] = hasher.finalize().into();
key[16..].try_into().unwrap()
}),
config.server_encrypt,
config.device_id.clone(),
config.server_address_str.clone(),
@@ -222,6 +231,7 @@ impl Vnt {
let device_list = device_list.clone();
let down_count_watcher = down_count_watcher.clone();
let up_count_watcher = up_count_watcher.clone();
let config_info = config_info.clone();
let current_device = current_device.clone();
if !config.use_channel_type.is_only_relay() {
// 定时nat探测
@@ -262,6 +272,7 @@ impl Vnt {
peer_nat_info_map,
down_count_watcher,
up_count_watcher,
client_secret_hash: config_info.client_secret_hash,
})
}
}
@@ -350,6 +361,9 @@ impl Vnt {
pub fn client_encrypt(&self) -> bool {
self.config.password.is_some()
}
pub fn client_encrypt_hash(&self) -> Option<&[u8]> {
self.client_secret_hash.as_ref().map(|v| v.as_ref())
}
pub fn current_device(&self) -> CurrentDeviceInfo {
self.current_device.load()
}
+12 -4
View File
@@ -32,15 +32,23 @@ pub struct PeerDeviceInfo {
pub name: String,
pub status: PeerDeviceStatus,
pub client_secret: bool,
pub client_secret_hash: Vec<u8>,
}
impl PeerDeviceInfo {
pub fn new(virtual_ip: Ipv4Addr, name: String, status: u8, client_secret: bool) -> Self {
pub fn new(
virtual_ip: Ipv4Addr,
name: String,
status: u8,
client_secret: bool,
client_secret_hash: Vec<u8>,
) -> Self {
Self {
virtual_ip,
name,
status: PeerDeviceStatus::from(status),
client_secret,
client_secret_hash,
}
}
}
@@ -50,7 +58,7 @@ pub struct BaseConfigInfo {
pub name: String,
pub token: String,
pub ip: Option<Ipv4Addr>,
pub client_secret: bool,
pub client_secret_hash: Option<[u8; 16]>,
pub server_secret: bool,
pub device_id: String,
pub server_addr: String,
@@ -61,7 +69,7 @@ impl BaseConfigInfo {
name: String,
token: String,
ip: Option<Ipv4Addr>,
client_secret: bool,
client_secret_hash: Option<[u8; 16]>,
server_secret: bool,
device_id: String,
server_addr: String,
@@ -70,7 +78,7 @@ impl BaseConfigInfo {
name,
token,
ip,
client_secret,
client_secret_hash,
server_secret,
device_id,
server_addr,
+6 -1
View File
@@ -418,6 +418,7 @@ impl<Call: VntCallback> ServerPacketHandler<Call> {
info.name,
info.device_status as u8,
info.client_secret,
info.client_secret_hash,
)
})
.collect();
@@ -442,7 +443,11 @@ impl<Call: VntCallback> ServerPacketHandler<Call> {
let token = self.config_info.token.clone();
let device_id = self.config_info.device_id.clone();
let name = self.config_info.name.clone();
let client_secret = self.config_info.client_secret;
let client_secret = self
.config_info
.client_secret_hash
.as_ref()
.map(|v| v.as_ref());
let mut ip = self.config_info.ip;
if ip.is_none() {
ip = Some(current_device.virtual_ip)
+7 -2
View File
@@ -18,7 +18,7 @@ pub fn registration_request_packet(
ip: Option<Ipv4Addr>,
is_fast: bool,
allow_ip_change: bool,
client_secret: bool,
client_secret_hash: Option<&[u8]>,
) -> io::Result<NetPacket<Vec<u8>>> {
let mut request = RegistrationRequest::new();
request.token = token;
@@ -30,7 +30,12 @@ pub fn registration_request_packet(
request.allow_ip_change = allow_ip_change;
request.is_fast = is_fast;
request.version = crate::VNT_VERSION.to_string();
request.client_secret = client_secret;
if let Some(client_secret_hash) = client_secret_hash {
request.client_secret = true;
request
.client_secret_hash
.extend_from_slice(client_secret_hash);
}
let bytes = request.write_to_bytes().map_err(|e| {
io::Error::new(io::ErrorKind::Other, format!("RegistrationRequest {:?}", e))
})?;