From eec7d73ebe5748763399ca793d79ca7db042375c Mon Sep 17 00:00:00 2001 From: lubeilin <1791778603@qq.com> Date: Fri, 1 Sep 2023 23:36:04 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=AF=E9=80=89=E6=95=B0=E6=8D=AE=E6=8C=87?= =?UTF-8?q?=E7=BA=B9=E6=A0=A1=E9=AA=8C=E3=80=81=E6=94=AF=E6=8C=81ecb?= =?UTF-8?q?=E7=AE=97=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/rust.yml | 28 ++--- common/Cargo.toml | 2 +- vnt-cli/Cargo.toml | 2 +- vnt-cli/src/main.rs | 7 +- vnt-jni/Cargo.toml | 2 +- vnt-jni/src/vnt_util.rs | 7 +- vnt/Cargo.toml | 3 +- vnt/proto/message.proto | 3 +- vnt/src/cipher/aes_cbc.rs | 51 +++++---- vnt/src/cipher/aes_ecb.rs | 140 ++++++++++++++++++++++++ vnt/src/cipher/aes_gcm_cipher.rs | 25 +++-- vnt/src/cipher/cipher.rs | 50 +++++++-- vnt/src/cipher/mod.rs | 1 + vnt/src/cipher/ring_aes_gcm_cipher.rs | 25 +++-- vnt/src/core/mod.rs | 13 ++- vnt/src/handle/heartbeat_handler.rs | 11 +- vnt/src/handle/tun_tap/mod.rs | 3 +- vnt/src/lib.rs | 2 +- vnt/src/proto/message.rs | 59 ++++++---- vnt/src/protocol/body.rs | 151 +++++++++++++++++--------- vnt/src/protocol/ip_turn_packet.rs | 29 ++--- 21 files changed, 441 insertions(+), 173 deletions(-) create mode 100644 vnt/src/cipher/aes_ecb.rs diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 4a9dd61..f426c0b 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -110,40 +110,40 @@ jobs: # some additional configuration for cross-compilation on linux cat >>~/.cargo/config <"); opts.optopt("", "thread", "线程数(必须为正整数)", ""); opts.optopt("", "model", "加密模式", ""); + opts.optflag("", "finger", "指纹校验", ); //"后台运行时,查看其他设备列表" opts.optflag("", "list", "后台运行时,查看其他设备列表"); opts.optflag("", "all", "后台运行时,查看其他设备完整信息"); @@ -208,13 +209,14 @@ fn main() { println!("--thread invalid"); return; } + let finger = matches.opt_present("finger"); println!("version {}",vnt::VNT_VERSION); let config = Config::new(tap, token, device_id, name, server_address, server_address_str, stun_server, in_ip, out_ip, password, simulate_multicast, mtu, - tcp_channel, virtual_ip, relay, server_encrypt, parallel, cipher_model); + tcp_channel, virtual_ip, relay, server_encrypt, parallel, cipher_model,finger); let runtime = tokio::runtime::Builder::new_multi_thread().enable_all().worker_threads(thread_num).build().unwrap(); runtime.block_on(main0(config, !unused_cmd)); std::process::exit(0); @@ -473,7 +475,8 @@ fn print_usage(program: &str, _opts: Options) { println!(" --relay 仅使用服务器转发,不使用p2p,默认情况允许使用p2p"); println!(" --par 任务并行度(必须为正整数),默认值为1"); println!(" --thread 线程数(必须为正整数),默认为核心数乘2"); - println!(" --model 加密模式,可选值 aes_gcm/aes_cbc,默认使用aes_gcm,通常情况使用aes_cbc性能更好"); + println!(" --model 加密模式(默认aes_gcm),可选值aes_gcm/aes_cbc/aes_ecb,通常性能aes_ecb>aes_cbc>aes_gcm,安全性则相反"); + println!(" --finger 增加数据指纹校验,可增加安全性,如果服务端开启指纹校验,则客户端也必须开启"); println!(); println!(" --list {}", yellow("后台运行时,查看其他设备列表".to_string())); println!(" --all {}", yellow("后台运行时,查看其他设备完整信息".to_string())); diff --git a/vnt-jni/Cargo.toml b/vnt-jni/Cargo.toml index 20267d6..bb8bc60 100644 --- a/vnt-jni/Cargo.toml +++ b/vnt-jni/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "vnt-jni" -version = "1.2.1" +version = "1.2.2" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/vnt-jni/src/vnt_util.rs b/vnt-jni/src/vnt_util.rs index b3b4944..51ca654 100644 --- a/vnt-jni/src/vnt_util.rs +++ b/vnt-jni/src/vnt_util.rs @@ -59,7 +59,8 @@ fn new_sync(env: &mut JNIEnv, config: JObject) -> Result { let server_address_str = to_string_not_null(env, &config, "server")?; let stun_server_str = to_string_not_null(env, &config, "stunServer")?; let cipher_model = to_string_not_null(env, &config, "cipherModel")?; - let is_tcp = env.get_field(&config, "isTcp", "Z")?.z()?; + let tcp = env.get_field(&config, "tcp", "Z")?.z()?; + let finger = env.get_field(&config, "finger", "Z")?.z()?; let server_address = match server_address_str.to_socket_addrs() { Ok(mut rs) => { @@ -93,7 +94,9 @@ fn new_sync(env: &mut JNIEnv, config: JObject) -> Result { token, device_id, name, server_address, server_address_str, stun_server, vec![], - vec![], password, false, None, is_tcp, None, false, false, 1, cipher_model); + vec![], password, + false, None, tcp, None, + false, false, 1, cipher_model,finger); match VntUtilSync::new(config) { Ok(vnt_util) => { Ok(vnt_util) diff --git a/vnt/Cargo.toml b/vnt/Cargo.toml index 26ca485..8219e68 100644 --- a/vnt/Cargo.toml +++ b/vnt/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "vnt" -version = "1.2.1" +version = "1.2.2" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -24,6 +24,7 @@ tokio = { version = "1.28.1", features = ["full"] } aes-gcm = {version="0.10.2", optional = true} ring = {version="0.16.20", optional = true} cbc = "0.1.2" +ecb = "0.1.2" aes = "0.8.3" stun-format = {version="1.0.1",features=["fmt","rfc3489"]} rsa = {version="0.7.2", features = [] } diff --git a/vnt/proto/message.proto b/vnt/proto/message.proto index 99506ec..3a0e6b8 100644 --- a/vnt/proto/message.proto +++ b/vnt/proto/message.proto @@ -54,7 +54,8 @@ message PunchInfo{ bool reply = 6; fixed32 local_ip = 7; uint32 local_port = 8; - repeated bytes public_ipv6_list = 9; + bytes ipv6 = 9; + uint32 ipv6_port = 10; } enum PunchNatType{ Symmetric = 0; diff --git a/vnt/src/cipher/aes_cbc.rs b/vnt/src/cipher/aes_cbc.rs index b91fc4d..e879ac6 100644 --- a/vnt/src/cipher/aes_cbc.rs +++ b/vnt/src/cipher/aes_cbc.rs @@ -15,7 +15,7 @@ type Aes256CbcDec = cbc::Decryptor; #[derive(Clone)] pub struct AesCbcCipher { pub(crate) cipher: AesCbcEnum, - pub(crate) finger: Finger, + pub(crate) finger: Option, } #[derive(Clone)] @@ -34,13 +34,13 @@ impl AesCbcCipher { } impl AesCbcCipher { - pub fn new_128(key: [u8; 16], finger: Finger) -> Self { + pub fn new_128(key: [u8; 16], finger: Option) -> Self { Self { cipher: AesCbcEnum::AES128CBC(key), finger, } } - pub fn new_256(key: [u8; 32], finger: Finger) -> Self { + pub fn new_256(key: [u8; 32], finger: Option) -> Self { Self { cipher: AesCbcEnum::AES256CBC(key), finger, @@ -52,8 +52,8 @@ impl AesCbcCipher { //未加密的数据直接丢弃 return Err(io::Error::new(io::ErrorKind::Other, "not encrypt")); } - if net_packet.payload().len() < 12 + 16 { - log::error!("数据异常,长度{}小于{}",net_packet.payload().len(),12+16); + if net_packet.payload().len() < 16 { + log::error!("数据异常,长度{}小于{}",net_packet.payload().len(),16); return Err(io::Error::new(io::ErrorKind::Other, "data err")); } let mut iv = [0; 16]; @@ -63,12 +63,16 @@ impl AesCbcCipher { iv[9] = net_packet.transport_protocol(); iv[10] = net_packet.is_gateway() as u8; iv[11] = net_packet.source_ttl(); - iv[12..16].copy_from_slice(&self.finger.hash[0..4]); + if let Some(finger) = &self.finger { + iv[12..16].copy_from_slice(&finger.hash[0..4]); + } - let mut secret_body = AesCbcSecretBody::new(net_packet.payload_mut())?; - let finger = self.finger.calculate_finger(&iv[..12], secret_body.en_body()); - if &finger != secret_body.finger() { - return Err(io::Error::new(io::ErrorKind::Other, "finger err")); + let mut secret_body = AesCbcSecretBody::new(net_packet.payload_mut(), self.finger.is_some())?; + if let Some(finger) = &self.finger { + let finger = finger.calculate_finger(&iv[..12], secret_body.en_body()); + if &finger != secret_body.finger() { + return Err(io::Error::new(io::ErrorKind::Other, "finger err")); + } } let rs = match &self.cipher { AesCbcEnum::AES128CBC(key) => { Aes128CbcDec::new(&(*key).into(), &iv.into()).decrypt_padded_mut::(secret_body.en_body_mut()) } @@ -90,6 +94,7 @@ impl AesCbcCipher { /// net_packet 必须预留足够长度 /// data_len是有效载荷的长度 pub fn encrypt_ipv4 + AsMut<[u8]>>(&self, net_packet: &mut NetPacket) -> io::Result<()> { + let data_len = net_packet.data_len(); let mut iv = [0; 16]; iv[0..4].copy_from_slice(&net_packet.source().octets()); iv[4..8].copy_from_slice(&net_packet.destination().octets()); @@ -97,11 +102,14 @@ impl AesCbcCipher { iv[9] = net_packet.transport_protocol(); iv[10] = net_packet.is_gateway() as u8; iv[11] = net_packet.source_ttl(); - iv[12..16].copy_from_slice(&self.finger.hash[0..4]); + if let Some(finger) = &self.finger { + iv[12..16].copy_from_slice(&finger.hash[0..4]); + net_packet.set_data_len(data_len + 16)?; + }else{ + net_packet.set_data_len(data_len + 4)?; + } //先扩充随机数 - let data_len = net_packet.data_len(); - net_packet.set_data_len(data_len + 16)?; - let mut secret_body = AesCbcSecretBody::new(net_packet.payload_mut())?; + let mut secret_body = AesCbcSecretBody::new(net_packet.payload_mut(), self.finger.is_some())?; secret_body.set_random(rand::thread_rng().next_u32()); let p_len = secret_body.en_body().len(); net_packet.set_data_len_max(); @@ -112,11 +120,16 @@ impl AesCbcCipher { return match rs { Ok(buf) => { let len = buf.len(); - let finger = self.finger.calculate_finger(&iv[..12], buf); - //设置实际长度 - net_packet.set_data_len(HEAD_LEN + len + finger.len())?; - let mut secret_body = AesCbcSecretBody::new(net_packet.payload_mut())?; - secret_body.set_finger(&finger)?; + if let Some(finger) = &self.finger { + let finger = finger.calculate_finger(&iv[..12], buf); + //设置实际长度 + net_packet.set_data_len(HEAD_LEN + len + finger.len())?; + let mut secret_body = AesCbcSecretBody::new(net_packet.payload_mut(), true)?; + secret_body.set_finger(&finger)?; + } else { + net_packet.set_data_len(HEAD_LEN + len)?; + } + net_packet.set_encrypt_flag(true); Ok(()) } diff --git a/vnt/src/cipher/aes_ecb.rs b/vnt/src/cipher/aes_ecb.rs new file mode 100644 index 0000000..635f04d --- /dev/null +++ b/vnt/src/cipher/aes_ecb.rs @@ -0,0 +1,140 @@ +use std::io; +use crate::cipher::Finger; +use crate::protocol::body::AesCbcSecretBody; +use crate::protocol::{HEAD_LEN, NetPacket}; +use aes::cipher::{block_padding::Pkcs7, BlockDecryptMut, BlockEncryptMut, KeyInit}; +use rand::RngCore; + +type Aes128EcbEnc = ecb::Encryptor; +type Aes128EcbDec = ecb::Decryptor; +type Aes256EcbEnc = ecb::Encryptor; +type Aes256EcbDec = ecb::Decryptor; + +#[derive(Clone)] +pub struct AesEcbCipher { + pub(crate) cipher: AesEcbEnum, + pub(crate) finger: Option, +} + +#[derive(Clone)] +pub enum AesEcbEnum { + AES128ECB([u8; 16]), + AES256ECB([u8; 32]), +} + +impl AesEcbCipher { + pub fn key(&self) -> &[u8] { + match &self.cipher { + AesEcbEnum::AES128ECB(key) => { key } + AesEcbEnum::AES256ECB(key) => { key } + } + } +} + +impl AesEcbCipher { + pub fn new_128(key: [u8; 16], finger: Option) -> Self { + Self { + cipher: AesEcbEnum::AES128ECB(key), + finger, + } + } + pub fn new_256(key: [u8; 32], finger: Option) -> Self { + Self { + cipher: AesEcbEnum::AES256ECB(key), + finger, + } + } + + pub fn decrypt_ipv4 + AsMut<[u8]>>(&self, net_packet: &mut NetPacket) -> io::Result<()> { + if !net_packet.is_encrypt() { + //未加密的数据直接丢弃 + return Err(io::Error::new(io::ErrorKind::Other, "not encrypt")); + } + if net_packet.payload().len() < 16 { + log::error!("数据异常,长度{}小于{}",net_packet.payload().len(),16); + return Err(io::Error::new(io::ErrorKind::Other, "data err")); + } + let mut iv = [0; 16]; + iv[0..4].copy_from_slice(&net_packet.source().octets()); + iv[4..8].copy_from_slice(&net_packet.destination().octets()); + iv[8] = net_packet.protocol().into(); + iv[9] = net_packet.transport_protocol(); + iv[10] = net_packet.is_gateway() as u8; + iv[11] = net_packet.source_ttl(); + if let Some(finger) = &self.finger { + iv[12..16].copy_from_slice(&finger.hash[0..4]); + } + + let mut secret_body = AesCbcSecretBody::new(net_packet.payload_mut(), self.finger.is_some())?; + if let Some(finger) = &self.finger { + let finger = finger.calculate_finger(&iv[..12], secret_body.en_body()); + if &finger != secret_body.finger() { + return Err(io::Error::new(io::ErrorKind::Other, "finger err")); + } + } + let rs = match &self.cipher { + AesEcbEnum::AES128ECB(key) => { Aes128EcbDec::new(&(*key).into()).decrypt_padded_mut::(secret_body.en_body_mut()) } + AesEcbEnum::AES256ECB(key) => { Aes256EcbDec::new(&(*key).into()).decrypt_padded_mut::(secret_body.en_body_mut()) } + }; + match rs { + Ok(buf) => { + let len = buf.len(); + net_packet.set_encrypt_flag(false); + //减去末尾的随机数 + net_packet.set_data_len(HEAD_LEN + len - 4)?; + Ok(()) + } + Err(e) => { + Err(io::Error::new(io::ErrorKind::Other, format!("解密失败:{}", e))) + } + } + } + /// net_packet 必须预留足够长度 + /// data_len是有效载荷的长度 + pub fn encrypt_ipv4 + AsMut<[u8]>>(&self, net_packet: &mut NetPacket) -> io::Result<()> { + let data_len = net_packet.data_len(); + let mut iv = [0; 16]; + iv[0..4].copy_from_slice(&net_packet.source().octets()); + iv[4..8].copy_from_slice(&net_packet.destination().octets()); + iv[8] = net_packet.protocol().into(); + iv[9] = net_packet.transport_protocol(); + iv[10] = net_packet.is_gateway() as u8; + iv[11] = net_packet.source_ttl(); + if let Some(finger) = &self.finger { + iv[12..16].copy_from_slice(&finger.hash[0..4]); + net_packet.set_data_len(data_len + 16)?; + }else{ + net_packet.set_data_len(data_len + 4)?; + } + //先扩充随机数 + + let mut secret_body = AesCbcSecretBody::new(net_packet.payload_mut(), self.finger.is_some())?; + secret_body.set_random(rand::thread_rng().next_u32()); + let p_len = secret_body.en_body().len(); + net_packet.set_data_len_max(); + let rs = match &self.cipher { + AesEcbEnum::AES128ECB(key) => { Aes128EcbEnc::new(&(*key).into()).encrypt_padded_mut::(net_packet.payload_mut(), p_len) } + AesEcbEnum::AES256ECB(key) => { Aes256EcbEnc::new(&(*key).into()).encrypt_padded_mut::(net_packet.payload_mut(), p_len) } + }; + return match rs { + Ok(buf) => { + let len = buf.len(); + if let Some(finger) = &self.finger { + let finger = finger.calculate_finger(&iv[..12], buf); + //设置实际长度 + net_packet.set_data_len(HEAD_LEN + len + finger.len())?; + let mut secret_body = AesCbcSecretBody::new(net_packet.payload_mut(), true)?; + secret_body.set_finger(&finger)?; + } else { + net_packet.set_data_len(HEAD_LEN + len)?; + } + + net_packet.set_encrypt_flag(true); + Ok(()) + } + Err(e) => { + Err(io::Error::new(io::ErrorKind::Other, format!("加密失败:{}", e))) + } + }; + } +} \ No newline at end of file diff --git a/vnt/src/cipher/aes_gcm_cipher.rs b/vnt/src/cipher/aes_gcm_cipher.rs index 661de1d..817f53a 100644 --- a/vnt/src/cipher/aes_gcm_cipher.rs +++ b/vnt/src/cipher/aes_gcm_cipher.rs @@ -9,11 +9,10 @@ use crate::cipher::finger::Finger; use crate::protocol::{body::ENCRYPTION_RESERVED, body::SecretBody, NetPacket}; - #[derive(Clone)] pub struct AesGcmCipher { pub(crate) cipher: AesGcmEnum, - pub(crate) finger: Finger, + pub(crate) finger: Option, } #[derive(Clone)] @@ -23,14 +22,14 @@ pub enum AesGcmEnum { } impl AesGcmCipher { - pub fn new_128(key: [u8; 16], finger: Finger) -> Self { + pub fn new_128(key: [u8; 16], finger: Option) -> Self { let key: &Key = &key.into(); Self { cipher: AesGcmEnum::AES128GCM(Aes128Gcm::new(key)), finger, } } - pub fn new_256(key: [u8; 32], finger: Finger) -> Self { + pub fn new_256(key: [u8; 32], finger: Option) -> Self { let key: &Key = &key.into(); Self { cipher: AesGcmEnum::AES256GCM(Aes256Gcm::new(key)), @@ -56,11 +55,13 @@ impl AesGcmCipher { nonce_raw[11] = net_packet.source_ttl(); let nonce: &GenericArray = Nonce::from_slice(&nonce_raw); - let mut secret_body = SecretBody::new(net_packet.payload_mut())?; + let mut secret_body = SecretBody::new(net_packet.payload_mut(), self.finger.is_some())?; let tag = secret_body.tag(); - let finger = self.finger.calculate_finger(&nonce_raw, secret_body.en_body()); - if &finger != secret_body.finger() { - return Err(io::Error::new(io::ErrorKind::Other, "finger err")); + if let Some(finger) = &self.finger { + let finger = finger.calculate_finger(&nonce_raw, secret_body.en_body()); + if &finger != secret_body.finger() { + return Err(io::Error::new(io::ErrorKind::Other, "finger err")); + } } let tag: GenericArray = Tag::clone_from_slice(tag); let rs = match &self.cipher { @@ -90,7 +91,7 @@ impl AesGcmCipher { let nonce: &GenericArray = Nonce::from_slice(&nonce_raw); let data_len = net_packet.data_len() + ENCRYPTION_RESERVED; net_packet.set_data_len(data_len)?; - let mut secret_body = SecretBody::new(net_packet.payload_mut())?; + let mut secret_body = SecretBody::new(net_packet.payload_mut(), self.finger.is_some())?; secret_body.set_random(rand::thread_rng().next_u32()); let rs = match &self.cipher { AesGcmEnum::AES128GCM(aes_gcm) => { aes_gcm.encrypt_in_place_detached(nonce, &[], secret_body.body_mut()) } @@ -99,8 +100,10 @@ impl AesGcmCipher { return match rs { Ok(tag) => { secret_body.set_tag(tag.as_slice())?; - let finger = self.finger.calculate_finger(&nonce_raw, secret_body.en_body()); - secret_body.set_finger(&finger)?; + if let Some(finger) = &self.finger { + let finger = finger.calculate_finger(&nonce_raw, secret_body.en_body()); + secret_body.set_finger(&finger)?; + } net_packet.set_encrypt_flag(true); Ok(()) } diff --git a/vnt/src/cipher/cipher.rs b/vnt/src/cipher/cipher.rs index cd7cc1d..b7a143f 100644 --- a/vnt/src/cipher/cipher.rs +++ b/vnt/src/cipher/cipher.rs @@ -8,11 +8,13 @@ use crate::cipher::ring_aes_gcm_cipher::AesGcmCipher; #[cfg(not(feature = "ring-cipher"))] use crate::cipher::aes_gcm_cipher::AesGcmCipher; use aes_cbc::AesCbcCipher; +use crate::cipher::aes_ecb::AesEcbCipher; #[derive(Copy, Clone, Eq, PartialEq, Debug)] pub enum CipherModel { AesGcm, AesCbc, + AesEcb, } impl FromStr for CipherModel { @@ -24,6 +26,7 @@ impl FromStr for CipherModel { Ok(CipherModel::AesGcm) } "aes_cbc" => { Ok(CipherModel::AesCbc) } + "aes_ecb" => { Ok(CipherModel::AesEcb) } _ => { Err(format!("not match '{}'", s)) } @@ -35,12 +38,13 @@ impl FromStr for CipherModel { pub enum Cipher { AesGcm((AesGcmCipher, Vec)), AesCbc(AesCbcCipher), + AesEcb(AesEcbCipher), None, } impl Cipher { - pub fn new_password(model: CipherModel, password: Option, token: String) -> Self { - let finger = Finger::new(&token); + pub fn new_password(model: CipherModel, password: Option, token: Option) -> Self { + let finger = token.map(|token| Finger::new(&token)); if let Some(password) = password { let mut hasher = sha2::Sha256::new(); hasher.update(password.as_bytes()); @@ -64,13 +68,22 @@ impl Cipher { Cipher::AesCbc(aes) } } + CipherModel::AesEcb => { + if password.len() < 8 { + let aes = AesEcbCipher::new_128(key[..16].try_into().unwrap(), finger); + Cipher::AesEcb(aes) + } else { + let aes = AesEcbCipher::new_256(key, finger); + Cipher::AesEcb(aes) + } + } } } else { Cipher::None } } pub fn new_key(key: [u8; 32], token: String) -> io::Result { - let finger = Finger::new(&token); + let finger = Some(Finger::new(&token)); match key.len() { 16 => { let aes = AesGcmCipher::new_128(key[..16].try_into().unwrap(), finger); @@ -91,8 +104,10 @@ impl Cipher { aes_gcm.decrypt_ipv4(net_packet) } Cipher::AesCbc(aes_cbc) => { - aes_cbc.decrypt_ipv4(net_packet).unwrap(); - Ok(()) + aes_cbc.decrypt_ipv4(net_packet) + } + Cipher::AesEcb(aes_ecb) => { + aes_ecb.decrypt_ipv4(net_packet) } Cipher::None => { if net_packet.is_encrypt() { @@ -108,8 +123,10 @@ impl Cipher { aes_gcm.encrypt_ipv4(net_packet) } Cipher::AesCbc(aes_cbc) => { - aes_cbc.encrypt_ipv4(net_packet).unwrap(); - Ok(()) + aes_cbc.encrypt_ipv4(net_packet) + } + Cipher::AesEcb(aes_ecb) => { + aes_ecb.encrypt_ipv4(net_packet) } Cipher::None => { Ok(()) @@ -117,16 +134,24 @@ impl Cipher { } } pub fn check_finger>(&self, net_packet: &NetPacket) -> io::Result<()> { - match self { + let finger = match self { Cipher::AesGcm((aes_gcm, _)) => { - aes_gcm.finger.check_finger(net_packet) + aes_gcm.finger.as_ref() } Cipher::AesCbc(aes_cbc) => { - aes_cbc.finger.check_finger(net_packet) + aes_cbc.finger.as_ref() + } + Cipher::AesEcb(aes_ecb) => { + aes_ecb.finger.as_ref() } Cipher::None => { - Ok(()) + None } + }; + if let Some(finger) = finger { + finger.check_finger(net_packet) + } else { + Ok(()) } } pub fn key(&self) -> Option<&[u8]> { @@ -137,6 +162,9 @@ impl Cipher { Cipher::AesCbc(aes_cbc) => { Some(aes_cbc.key()) } + Cipher::AesEcb(aes_ecb) => { + Some(aes_ecb.key()) + } Cipher::None => { None } diff --git a/vnt/src/cipher/mod.rs b/vnt/src/cipher/mod.rs index 2b64eef..f83b8ad 100644 --- a/vnt/src/cipher/mod.rs +++ b/vnt/src/cipher/mod.rs @@ -4,6 +4,7 @@ mod ring_aes_gcm_cipher; mod aes_gcm_cipher; mod rsa_cipher; mod aes_cbc; +mod aes_ecb; mod finger; mod cipher; diff --git a/vnt/src/cipher/ring_aes_gcm_cipher.rs b/vnt/src/cipher/ring_aes_gcm_cipher.rs index 9a00fb1..769c303 100644 --- a/vnt/src/cipher/ring_aes_gcm_cipher.rs +++ b/vnt/src/cipher/ring_aes_gcm_cipher.rs @@ -10,7 +10,7 @@ use crate::protocol::body::{ENCRYPTION_RESERVED, SecretBody}; #[derive(Clone)] pub struct AesGcmCipher { pub(crate) cipher: AesGcmEnum, - pub(crate) finger: Finger, + pub(crate) finger: Option, } pub enum AesGcmEnum { @@ -34,14 +34,14 @@ impl Clone for AesGcmEnum { } impl AesGcmCipher { - pub fn new_128(key: [u8; 16], finger: Finger) -> Self { + pub fn new_128(key: [u8; 16], finger: Option) -> Self { let cipher = LessSafeKey::new(UnboundKey::new(&aead::AES_128_GCM, &key).unwrap()); Self { cipher: AesGcmEnum::AesGCM128(cipher, key), finger, } } - pub fn new_256(key: [u8; 32], finger: Finger) -> Self { + pub fn new_256(key: [u8; 32], finger: Option) -> Self { let cipher = LessSafeKey::new(UnboundKey::new(&aead::AES_256_GCM, &key).unwrap()); Self { cipher: AesGcmEnum::AesGCM256(cipher, key), @@ -65,11 +65,12 @@ impl AesGcmCipher { nonce_raw[10] = net_packet.is_gateway() as u8; nonce_raw[11] = net_packet.source_ttl(); let nonce = aead::Nonce::assume_unique_for_key(nonce_raw); - let mut secret_body = SecretBody::new(net_packet.payload_mut())?; - let tag = secret_body.tag(); - let finger = self.finger.calculate_finger(&nonce_raw, secret_body.en_body()); - if &finger != secret_body.finger() { - return Err(io::Error::new(io::ErrorKind::Other, "finger err")); + let mut secret_body = SecretBody::new(net_packet.payload_mut(), self.finger.is_some())?; + if let Some(finger) = &self.finger { + let finger = finger.calculate_finger(&nonce_raw, secret_body.en_body()); + if &finger != secret_body.finger() { + return Err(io::Error::new(io::ErrorKind::Other, "ring aes finger err")); + } } let rs = match &self.cipher { @@ -101,7 +102,7 @@ impl AesGcmCipher { let nonce = aead::Nonce::assume_unique_for_key(nonce_raw); let data_len = net_packet.data_len() + ENCRYPTION_RESERVED; net_packet.set_data_len(data_len)?; - let mut secret_body = SecretBody::new(net_packet.payload_mut())?; + let mut secret_body = SecretBody::new(net_packet.payload_mut(), self.finger.is_some())?; secret_body.set_random(rand::thread_rng().next_u32()); let rs = match &self.cipher { @@ -119,8 +120,10 @@ impl AesGcmCipher { return Err(io::Error::new(io::ErrorKind::Other, format!("加密tag长度错误:{}", tag.len()))); } secret_body.set_tag(tag)?; - let finger = self.finger.calculate_finger(&nonce_raw, secret_body.en_body()); - secret_body.set_finger(&finger)?; + if let Some(finger) = &self.finger { + let finger = finger.calculate_finger(&nonce_raw, secret_body.en_body()); + secret_body.set_finger(&finger)?; + } net_packet.set_encrypt_flag(true); Ok(()) } diff --git a/vnt/src/core/mod.rs b/vnt/src/core/mod.rs index 0845edf..b0ec993 100644 --- a/vnt/src/core/mod.rs +++ b/vnt/src/core/mod.rs @@ -185,7 +185,12 @@ impl VntUtil { }; let config = self.config.clone(); let vnt_status_manager = VntStatusManger::new(); - let client_cipher = Cipher::new_password(config.cipher_model, config.password.clone(), config.token.clone()); + let finger = if config.finger { + Some(config.token.clone()) + } else { + None + }; + let client_cipher = Cipher::new_password(config.cipher_model, config.password.clone(), finger); let virtual_ip = response.virtual_ip; let virtual_gateway = response.virtual_gateway; let virtual_netmask = response.virtual_netmask; @@ -246,7 +251,7 @@ impl VntUtil { } #[cfg(any(target_os = "android"))] tun_handler::start(vnt_status_manager.worker("android tun_handler"), channel_sender.clone(), device_reader, device_writer.clone(), - igmp_server.clone(), current_device.clone(), in_external_route, ip_proxy_map.clone(), client_cipher.clone(),self.server_cipher.clone(), config.parallel).await; + igmp_server.clone(), current_device.clone(), in_external_route, ip_proxy_map.clone(), client_cipher.clone(), self.server_cipher.clone(), config.parallel).await; //外部数据接收处理 let channel_recv_handler = ChannelDataHandler::new(current_device.clone(), device_list.clone(), @@ -391,6 +396,7 @@ pub struct Config { pub server_encrypt: bool, pub parallel: usize, pub cipher_model: CipherModel, + pub finger: bool, } @@ -404,7 +410,7 @@ impl Config { in_ips: Vec<(u32, u32, Ipv4Addr)>, out_ips: Vec<(u32, u32)>, password: Option, simulate_multicast: bool, mtu: Option, tcp: bool, ip: Option, - relay: bool, server_encrypt: bool, parallel: usize, cipher_model: CipherModel) -> Self { + relay: bool, server_encrypt: bool, parallel: usize, cipher_model: CipherModel, finger: bool, ) -> Self { for x in stun_server.iter_mut() { if !x.contains(":") { x.push_str(":3478"); @@ -429,6 +435,7 @@ impl Config { server_encrypt, parallel, cipher_model, + finger, } } } \ No newline at end of file diff --git a/vnt/src/handle/heartbeat_handler.rs b/vnt/src/handle/heartbeat_handler.rs index 2efbb7c..04c00e1 100644 --- a/vnt/src/handle/heartbeat_handler.rs +++ b/vnt/src/handle/heartbeat_handler.rs @@ -71,13 +71,12 @@ pub fn start_heartbeat( } -fn heartbeat_packet(device_list: &Mutex<(u16, Vec)>, client_cipher: &Cipher, server_cipher: &Cipher, gateway: bool, src: Ipv4Addr, dest: Ipv4Addr) -> NetPacket<[u8; 48]> { +fn heartbeat_packet(ttl: u8, device_list: &Mutex<(u16, Vec)>, client_cipher: &Cipher, server_cipher: &Cipher, gateway: bool, src: Ipv4Addr, dest: Ipv4Addr) -> NetPacket<[u8; 48]> { let mut net_packet = NetPacket::new_encrypt([0u8; 12 + 4 + ENCRYPTION_RESERVED]).unwrap(); net_packet.set_version(Version::V1); net_packet.set_protocol(Protocol::Control); net_packet.set_transport_protocol(control_packet::Protocol::Ping.into()); - //只寻找两跳以内能到的目标 - net_packet.first_set_ttl(2); + net_packet.first_set_ttl(ttl); net_packet.set_source(src); net_packet.set_destination(dest); { @@ -138,7 +137,7 @@ async fn start_heartbeat_( } } let src = current_dev.virtual_ip(); - let server_packet = heartbeat_packet(&device_list, &client_cipher, &server_cipher, true, src, current_dev.virtual_gateway); + let server_packet = heartbeat_packet(MAX_TTL, &device_list, &client_cipher, &server_cipher, true, src, current_dev.virtual_gateway); if let Err(e) = sender.send_main(server_packet.buffer(), current_dev.connect_server).await { log::warn!( @@ -154,7 +153,7 @@ async fn start_heartbeat_( if peer.virtual_ip == current_dev.virtual_ip { continue; } - let client_packet = heartbeat_packet(&device_list, &client_cipher, &server_cipher, false, src, peer.virtual_ip); + let client_packet = heartbeat_packet(MAX_TTL, &device_list, &client_cipher, &server_cipher, false, src, peer.virtual_ip); if let Some(route) = sender.route_one(&peer.virtual_ip) { let _ = sender.send_by_key(client_packet.buffer(), &route.route_key()).await; if route.is_p2p() { @@ -191,7 +190,7 @@ async fn start_heartbeat_( if peer_ip == ¤t_dev.virtual_gateway { continue; } - let client_packet = heartbeat_packet(&device_list, &client_cipher, &server_cipher, false, src, *peer_ip); + let client_packet = heartbeat_packet(MAX_TTL, &device_list, &client_cipher, &server_cipher, false, src, *peer_ip); for route in route_list { if let Err(e) = sender.send_by_key(client_packet.buffer(), &route.route_key()).await { log::warn!("peer_ip:{:?},route:{:?},e:{:?}", peer_ip, route, e); diff --git a/vnt/src/handle/tun_tap/mod.rs b/vnt/src/handle/tun_tap/mod.rs index 1f95e8c..6506ae5 100644 --- a/vnt/src/handle/tun_tap/mod.rs +++ b/vnt/src/handle/tun_tap/mod.rs @@ -61,7 +61,8 @@ async fn broadcast(server_cipher: &Cipher, multicast_members: Option = std::result::Result; pub mod error; diff --git a/vnt/src/proto/message.rs b/vnt/src/proto/message.rs index 99be211..686d930 100644 --- a/vnt/src/proto/message.rs +++ b/vnt/src/proto/message.rs @@ -1313,8 +1313,10 @@ pub struct PunchInfo { pub local_ip: u32, // @@protoc_insertion_point(field:PunchInfo.local_port) pub local_port: u32, - // @@protoc_insertion_point(field:PunchInfo.public_ipv6_list) - pub public_ipv6_list: ::std::vec::Vec<::std::vec::Vec>, + // @@protoc_insertion_point(field:PunchInfo.ipv6) + pub ipv6: ::std::vec::Vec, + // @@protoc_insertion_point(field:PunchInfo.ipv6_port) + pub ipv6_port: u32, // special fields // @@protoc_insertion_point(special_field:PunchInfo.special_fields) pub special_fields: ::protobuf::SpecialFields, @@ -1332,7 +1334,7 @@ impl PunchInfo { } fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { - let mut fields = ::std::vec::Vec::with_capacity(8); + let mut fields = ::std::vec::Vec::with_capacity(9); let mut oneofs = ::std::vec::Vec::with_capacity(0); fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>( "public_ip_list", @@ -1369,10 +1371,15 @@ impl PunchInfo { |m: &PunchInfo| { &m.local_port }, |m: &mut PunchInfo| { &mut m.local_port }, )); - fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>( - "public_ipv6_list", - |m: &PunchInfo| { &m.public_ipv6_list }, - |m: &mut PunchInfo| { &mut m.public_ipv6_list }, + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "ipv6", + |m: &PunchInfo| { &m.ipv6 }, + |m: &mut PunchInfo| { &mut m.ipv6 }, + )); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "ipv6_port", + |m: &PunchInfo| { &m.ipv6_port }, + |m: &mut PunchInfo| { &mut m.ipv6_port }, )); ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( "PunchInfo", @@ -1417,7 +1424,10 @@ impl ::protobuf::Message for PunchInfo { self.local_port = is.read_uint32()?; }, 74 => { - self.public_ipv6_list.push(is.read_bytes()?); + self.ipv6 = is.read_bytes()?; + }, + 80 => { + self.ipv6_port = is.read_uint32()?; }, tag => { ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; @@ -1450,9 +1460,12 @@ impl ::protobuf::Message for PunchInfo { if self.local_port != 0 { my_size += ::protobuf::rt::uint32_size(8, self.local_port); } - for value in &self.public_ipv6_list { - my_size += ::protobuf::rt::bytes_size(9, &value); - }; + if !self.ipv6.is_empty() { + my_size += ::protobuf::rt::bytes_size(9, &self.ipv6); + } + if self.ipv6_port != 0 { + my_size += ::protobuf::rt::uint32_size(10, self.ipv6_port); + } my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); self.special_fields.cached_size().set(my_size as u32); my_size @@ -1480,9 +1493,12 @@ impl ::protobuf::Message for PunchInfo { if self.local_port != 0 { os.write_uint32(8, self.local_port)?; } - for v in &self.public_ipv6_list { - os.write_bytes(9, &v)?; - }; + if !self.ipv6.is_empty() { + os.write_bytes(9, &self.ipv6)?; + } + if self.ipv6_port != 0 { + os.write_uint32(10, self.ipv6_port)?; + } os.write_unknown_fields(self.special_fields.unknown_fields())?; ::std::result::Result::Ok(()) } @@ -1507,7 +1523,8 @@ impl ::protobuf::Message for PunchInfo { self.reply = false; self.local_ip = 0; self.local_port = 0; - self.public_ipv6_list.clear(); + self.ipv6.clear(); + self.ipv6_port = 0; self.special_fields.clear(); } @@ -1520,7 +1537,8 @@ impl ::protobuf::Message for PunchInfo { reply: false, local_ip: 0, local_port: 0, - public_ipv6_list: ::std::vec::Vec::new(), + ipv6: ::std::vec::Vec::new(), + ipv6_port: 0, special_fields: ::protobuf::SpecialFields::new(), }; &instance @@ -1625,15 +1643,16 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \n\rdevice_status\x18\x03\x20\x01(\rR\x0cdeviceStatus\x12#\n\rclient_sec\ ret\x18\x04\x20\x01(\x08R\x0cclientSecret\"Y\n\nDeviceList\x12\x14\n\x05\ epoch\x18\x01\x20\x01(\rR\x05epoch\x125\n\x10device_info_list\x18\x02\ - \x20\x03(\x0b2\x0b.DeviceInfoR\x0edeviceInfoList\"\xa2\x02\n\tPunchInfo\ + \x20\x03(\x0b2\x0b.DeviceInfoR\x0edeviceInfoList\"\xa9\x02\n\tPunchInfo\ \x12$\n\x0epublic_ip_list\x18\x02\x20\x03(\x07R\x0cpublicIpList\x12\x1f\ \n\x0bpublic_port\x18\x03\x20\x01(\rR\npublicPort\x12*\n\x11public_port_\ range\x18\x04\x20\x01(\rR\x0fpublicPortRange\x12(\n\x08nat_type\x18\x05\ \x20\x01(\x0e2\r.PunchNatTypeR\x07natType\x12\x14\n\x05reply\x18\x06\x20\ \x01(\x08R\x05reply\x12\x19\n\x08local_ip\x18\x07\x20\x01(\x07R\x07local\ - Ip\x12\x1d\n\nlocal_port\x18\x08\x20\x01(\rR\tlocalPort\x12(\n\x10public\ - _ipv6_list\x18\t\x20\x03(\x0cR\x0epublicIpv6List*'\n\x0cPunchNatType\x12\ - \r\n\tSymmetric\x10\0\x12\x08\n\x04Cone\x10\x01b\x06proto3\ + Ip\x12\x1d\n\nlocal_port\x18\x08\x20\x01(\rR\tlocalPort\x12\x12\n\x04ipv\ + 6\x18\t\x20\x01(\x0cR\x04ipv6\x12\x1b\n\tipv6_port\x18\n\x20\x01(\rR\x08\ + ipv6Port*'\n\x0cPunchNatType\x12\r\n\tSymmetric\x10\0\x12\x08\n\x04Cone\ + \x10\x01b\x06proto3\ "; /// `FileDescriptorProto` object which was a source for this generated file diff --git a/vnt/src/protocol/body.rs b/vnt/src/protocol/body.rs index 4914bf7..b884c01 100644 --- a/vnt/src/protocol/body.rs +++ b/vnt/src/protocol/body.rs @@ -24,44 +24,62 @@ pub const ENCRYPTION_RESERVED: usize = 32; */ pub struct SecretBody { buffer: B, + exist_finger: bool, } impl> SecretBody { - pub fn new(buffer: B) -> io::Result> { + pub fn new(buffer: B, exist_finger: bool) -> io::Result> { let len = buffer.as_ref().len(); + let min_len = if exist_finger { + 32 + } else { + 32 - 12 + }; // 不能大于udp最大载荷长度 - if len < 32 || len > 65535 - 20 - 8 - 12 { + if len < min_len || len > 65535 - 20 - 8 - 12 { return Err(io::Error::new( io::ErrorKind::InvalidData, - "length overflow", + "SecretBody length overflow", )); } - Ok(SecretBody { buffer }) - } - pub fn data(&self) -> &[u8] { - let end = self.buffer.as_ref().len() - 32; - &self.buffer.as_ref()[..end] + Ok(SecretBody { buffer, exist_finger }) } pub fn random(&self) -> u32 { - let end = self.buffer.as_ref().len() - 16 - 12; + let mut end = self.buffer.as_ref().len() - 16; + if self.exist_finger { + end -= 12; + } u32::from_be_bytes(self.buffer.as_ref()[end - 4..end].try_into().unwrap()) } pub fn body(&self) -> &[u8] { - let end = self.buffer.as_ref().len() - 16 - 12; + let mut end = self.buffer.as_ref().len() - 16; + if self.exist_finger { + end -= 12; + } &self.buffer.as_ref()[..end] } pub fn tag(&self) -> &[u8] { - let end = self.buffer.as_ref().len() - 12; + let mut end = self.buffer.as_ref().len(); + if self.exist_finger { + end -= 12; + } &self.buffer.as_ref()[end - 16..end] } /// 数据部分+tag部分 pub fn en_body(&self) -> &[u8] { - let end = self.buffer.as_ref().len() - 12; + let mut end = self.buffer.as_ref().len(); + if self.exist_finger { + end -= 12; + } &self.buffer.as_ref()[..end] } pub fn finger(&self) -> &[u8] { - let end = self.buffer.as_ref().len(); - &self.buffer.as_ref()[end - 12..end] + if self.exist_finger { + let end = self.buffer.as_ref().len(); + &self.buffer.as_ref()[end - 12..end] + } else { + &[] + } } pub fn buffer(&self) -> &[u8] { self.buffer.as_ref() @@ -69,16 +87,11 @@ impl> SecretBody { } impl + AsMut<[u8]>> SecretBody { - pub fn set_data(&mut self, data: &[u8]) -> io::Result<()> { - let end = self.buffer.as_ref().len() - 32; - if end - 4 != data.len() { - return Err(io::Error::new(io::ErrorKind::InvalidData, "end-4 != data.len")); - } - self.buffer.as_mut()[..end].copy_from_slice(data); - Ok(()) - } pub fn set_random(&mut self, random: u32) { - let end = self.buffer.as_ref().len() - 16 - 12; + let mut end = self.buffer.as_ref().len() - 16; + if self.exist_finger { + end -= 12; + } self.buffer.as_mut()[end - 4..end].copy_from_slice(&random.to_be_bytes()); } @@ -86,35 +99,47 @@ impl + AsMut<[u8]>> SecretBody { if tag.len() != 16 { return Err(io::Error::new(io::ErrorKind::InvalidData, "tag.len != 16")); } - let end = self.buffer.as_ref().len() - 12; + let mut end = self.buffer.as_ref().len(); + if self.exist_finger { + end -= 12; + } self.buffer.as_mut()[end - 16..end].copy_from_slice(tag); Ok(()) } pub fn set_finger(&mut self, finger: &[u8]) -> io::Result<()> { - if finger.len() != 12 { - return Err(io::Error::new(io::ErrorKind::InvalidData, "finger.len != 12")); + if self.exist_finger { + if finger.len() != 12 { + return Err(io::Error::new(io::ErrorKind::InvalidData, "finger.len != 12")); + } + let end = self.buffer.as_ref().len(); + self.buffer.as_mut()[end - 12..end].copy_from_slice(finger); + Ok(()) + } else { + Err(io::Error::new(io::ErrorKind::InvalidData, "not exist finger")) } - let end = self.buffer.as_ref().len(); - self.buffer.as_mut()[end - 12..end].copy_from_slice(finger); - Ok(()) } - pub fn data_mut(&mut self) -> &mut [u8] { - let end = self.buffer.as_ref().len() - 32; - &mut self.buffer.as_mut()[..end] - } /// 数据部分 pub fn body_mut(&mut self) -> &mut [u8] { - let end = self.buffer.as_ref().len() - 12 - 16; + let mut end = self.buffer.as_ref().len() - 16; + if self.exist_finger { + end -= 12; + } &mut self.buffer.as_mut()[..end] } pub fn tag_mut(&mut self) -> &mut [u8] { - let end = self.buffer.as_ref().len() - 12; + let mut end = self.buffer.as_ref().len(); + if self.exist_finger { + end -= 12; + } &mut self.buffer.as_mut()[end - 16..end] } /// 数据部分+tag部分 pub fn en_body_mut(&mut self) -> &mut [u8] { - let end = self.buffer.as_ref().len() - 12; + let mut end = self.buffer.as_ref().len(); + if self.exist_finger { + end -= 12; + } &mut self.buffer.as_mut()[..end] } pub fn buffer_mut(&mut self) -> &mut [u8] { @@ -128,6 +153,7 @@ impl> fmt::Debug for SecretBody { .field("random", &self.random()) .field("body", &self.body()) .field("tag", &self.tag()) + .field("finger", &self.finger()) .finish() } } @@ -149,43 +175,68 @@ impl> fmt::Debug for SecretBody { */ pub struct AesCbcSecretBody { buffer: B, + exist_finger: bool, } + impl> AesCbcSecretBody { - pub fn new(buffer: B) -> io::Result> { + pub fn new(buffer: B, exist_finger: bool) -> io::Result> { let len = buffer.as_ref().len(); + let min_len = if exist_finger { + 16 + } else { + 16 - 12 + }; // 不能大于udp最大载荷长度 - if len < 16 || len > 65535 - 20 - 8 - 12 { + if len < min_len || len > 65535 - 20 - 8 - 12 { return Err(io::Error::new( io::ErrorKind::InvalidData, - "length overflow", + "AesCbcSecretBody length overflow", )); } - Ok(AesCbcSecretBody { buffer }) + Ok(AesCbcSecretBody { buffer, exist_finger }) } pub fn en_body(&self) -> &[u8] { - let end = self.buffer.as_ref().len() - 12; + let mut end = self.buffer.as_ref().len(); + if self.exist_finger { + end -= 12; + } &self.buffer.as_ref()[..end] } pub fn finger(&self) -> &[u8] { - let end = self.buffer.as_ref().len(); - &self.buffer.as_ref()[end - 12..end] + if self.exist_finger { + let end = self.buffer.as_ref().len(); + &self.buffer.as_ref()[end - 12..end] + } else { + &[] + } } } + impl + AsMut<[u8]>> AesCbcSecretBody { pub fn set_random(&mut self, random: u32) { - let end = self.buffer.as_ref().len() - 12; + let mut end = self.buffer.as_ref().len(); + if self.exist_finger { + end -= 12; + } self.buffer.as_mut()[end - 4..end].copy_from_slice(&random.to_be_bytes()); } pub fn set_finger(&mut self, finger: &[u8]) -> io::Result<()> { - if finger.len() != 12 { - return Err(io::Error::new(io::ErrorKind::InvalidData, "finger.len != 12")); + if self.exist_finger { + if finger.len() != 12 { + return Err(io::Error::new(io::ErrorKind::InvalidData, "finger.len != 12")); + } + let end = self.buffer.as_ref().len(); + self.buffer.as_mut()[end - 12..end].copy_from_slice(finger); + Ok(()) + } else { + Err(io::Error::new(io::ErrorKind::InvalidData, "cbc not exist finger")) } - let end = self.buffer.as_ref().len(); - self.buffer.as_mut()[end - 12..end].copy_from_slice(finger); - Ok(()) } pub fn en_body_mut(&mut self) -> &mut [u8] { - let end = self.buffer.as_ref().len() - 12; + let mut end = self.buffer.as_ref().len(); + if self.exist_finger { + end -= 12; + } &mut self.buffer.as_mut()[..end] } } diff --git a/vnt/src/protocol/ip_turn_packet.rs b/vnt/src/protocol/ip_turn_packet.rs index 667a44f..a3fb292 100644 --- a/vnt/src/protocol/ip_turn_packet.rs +++ b/vnt/src/protocol/ip_turn_packet.rs @@ -40,10 +40,7 @@ impl> BroadcastPacket { let len = buffer.as_ref().len(); let packet = Self::unchecked(buffer); if len < 2 + 4 || packet.addr_num() == 0 { - Err(io::Error::new( - io::ErrorKind::InvalidData, - "InvalidData", - )) + Err(io::Error::new(io::ErrorKind::InvalidData, "BroadcastPacket InvalidData")) } else { Ok(packet) } @@ -52,7 +49,7 @@ impl> BroadcastPacket { impl> BroadcastPacket { pub fn addr_num(&self) -> u8 { - self.buffer.as_ref()[1] + self.buffer.as_ref()[0] } /// 已经发送给了这些地址 pub fn addresses(&self) -> Vec { @@ -61,7 +58,12 @@ impl> BroadcastPacket { let buf = self.buffer.as_ref(); let mut offset = 1; for _ in 0..num { - list.push(Ipv4Addr::new(buf[offset], buf[offset + 1], buf[offset + 2], buf[offset + 3])); + list.push(Ipv4Addr::new( + buf[offset], + buf[offset + 1], + buf[offset + 2], + buf[offset + 3], + )); offset += 4; } list @@ -69,10 +71,7 @@ impl> BroadcastPacket { pub fn data(&self) -> io::Result<&[u8]> { let start = 1 + self.addr_num() as usize * 4; if start > self.buffer.as_ref().len() { - Err(io::Error::new( - io::ErrorKind::InvalidData, - "InvalidData", - )) + Err(io::Error::new(io::ErrorKind::InvalidData, "InvalidData")) } else { Ok(&self.buffer.as_ref()[start..]) } @@ -85,7 +84,7 @@ impl + AsMut<[u8]>> BroadcastPacket { if buf.len() < 1 + addr.len() * 4 || addr.len() > u8::MAX as usize { Err(io::Error::new( io::ErrorKind::InvalidData, - "InvalidData", + "addr invalid data", )) } else { buf[0] = addr.len() as u8; @@ -101,17 +100,13 @@ impl + AsMut<[u8]>> BroadcastPacket { let num = self.addr_num() as usize; let start = 1 + 4 * num; let buf = self.buffer.as_mut(); - if start > buf.len() || start + data.len() != buf.len() { + if start >= buf.len() || start + data.len() != buf.len() { return Err(io::Error::new( io::ErrorKind::InvalidData, - "InvalidData", + "data invalid data", )); } buf[start..].copy_from_slice(data); Ok(()) } } - - - -