可选数据指纹校验、支持ecb算法
This commit is contained in:
+14
-14
@@ -110,40 +110,40 @@ jobs:
|
||||
# some additional configuration for cross-compilation on linux
|
||||
cat >>~/.cargo/config <<EOF
|
||||
[target.x86_64-unknown-linux-musl]
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
rustflags = ["-C", "target-feature=+crt-static","-C", "target-feature=+aes","--cfg","aes_armv8"]
|
||||
[target.aarch64-unknown-linux-gnu]
|
||||
linker = "aarch64-linux-gnu-gcc"
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
rustflags = ["-C", "target-feature=+crt-static","-C", "target-feature=+aes","--cfg","aes_armv8"]
|
||||
[target.aarch64-unknown-linux-musl]
|
||||
linker = "aarch64-linux-gnu-gcc"
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
rustflags = ["-C", "target-feature=+crt-static","-C", "target-feature=+aes","--cfg","aes_armv8"]
|
||||
[target.armv7-unknown-linux-gnueabihf]
|
||||
linker = "arm-linux-gnueabihf-gcc"
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
rustflags = ["-C", "target-feature=+crt-static","-C", "target-feature=+aes","--cfg","aes_armv8"]
|
||||
[target.armv7-unknown-linux-musleabihf]
|
||||
linker = "arm-linux-gnueabihf-gcc"
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
rustflags = ["-C", "target-feature=+crt-static","-C", "target-feature=+aes","--cfg","aes_armv8"]
|
||||
[target.arm-unknown-linux-gnueabihf]
|
||||
linker = "arm-linux-gnueabihf-gcc"
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
rustflags = ["-C", "target-feature=+crt-static","-C", "target-feature=+aes","--cfg","aes_armv8"]
|
||||
[target.arm-unknown-linux-musleabihf]
|
||||
linker = "arm-linux-gnueabihf-gcc"
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
rustflags = ["-C", "target-feature=+crt-static","-C", "target-feature=+aes","--cfg","aes_armv8"]
|
||||
[target.mipsel-unknown-linux-musl]
|
||||
linker = "mipsel-linux-gnu-gcc"
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
rustflags = ["-C", "target-feature=+crt-static","-C", "target-feature=+aes","--cfg","aes_armv8"]
|
||||
[target.x86_64-pc-windows-msvc]
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
rustflags = ["-C", "target-feature=+crt-static","-C", "target-feature=+aes","--cfg","aes_armv8"]
|
||||
[target.i686-pc-windows-msvc]
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
rustflags = ["-C", "target-feature=+crt-static","-C", "target-feature=+aes","--cfg","aes_armv8"]
|
||||
[target.x86_64-apple-darwin]
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
rustflags = ["-C", "target-feature=+crt-static","-C", "target-feature=+aes","--cfg","aes_armv8"]
|
||||
[target.aarch64-apple-darwin]
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
rustflags = ["-C", "target-feature=+crt-static","-C", "target-feature=+aes","--cfg","aes_armv8"]
|
||||
[target.i686-unknown-linux-musl]
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
rustflags = ["-C", "target-feature=+crt-static","-C", "target-feature=+aes","--cfg","aes_armv8"]
|
||||
[target.x86_64-unknown-linux-gnu]
|
||||
rustflags = ["-C", "target-feature=+crt-static"]
|
||||
rustflags = ["-C", "target-feature=+crt-static","-C", "target-feature=+aes","--cfg","aes_armv8"]
|
||||
EOF
|
||||
- name: Install rust target
|
||||
run: rustup target add $TARGET
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "common"
|
||||
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
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "vnt-cli"
|
||||
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
|
||||
|
||||
+5
-2
@@ -52,6 +52,7 @@ fn main() {
|
||||
opts.optopt("", "par", "任务并行度(必须为正整数)", "<parallel>");
|
||||
opts.optopt("", "thread", "线程数(必须为正整数)", "<thread>");
|
||||
opts.optopt("", "model", "加密模式", "<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 <parallel> 任务并行度(必须为正整数),默认值为1");
|
||||
println!(" --thread <thread> 线程数(必须为正整数),默认为核心数乘2");
|
||||
println!(" --model <model> 加密模式,可选值 aes_gcm/aes_cbc,默认使用aes_gcm,通常情况使用aes_cbc性能更好");
|
||||
println!(" --model <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()));
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
@@ -59,7 +59,8 @@ fn new_sync(env: &mut JNIEnv, config: JObject) -> Result<VntUtilSync, Error> {
|
||||
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<VntUtilSync, Error> {
|
||||
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)
|
||||
|
||||
+2
-1
@@ -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 = [] }
|
||||
|
||||
@@ -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;
|
||||
|
||||
+32
-19
@@ -15,7 +15,7 @@ type Aes256CbcDec = cbc::Decryptor<aes::Aes256>;
|
||||
#[derive(Clone)]
|
||||
pub struct AesCbcCipher {
|
||||
pub(crate) cipher: AesCbcEnum,
|
||||
pub(crate) finger: Finger,
|
||||
pub(crate) finger: Option<Finger>,
|
||||
}
|
||||
|
||||
#[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<Finger>) -> 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<Finger>) -> 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::<Pkcs7>(secret_body.en_body_mut()) }
|
||||
@@ -90,6 +94,7 @@ impl AesCbcCipher {
|
||||
/// net_packet 必须预留足够长度
|
||||
/// data_len是有效载荷的长度
|
||||
pub fn encrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(&self, net_packet: &mut NetPacket<B>) -> 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(())
|
||||
}
|
||||
|
||||
@@ -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<aes::Aes128>;
|
||||
type Aes128EcbDec = ecb::Decryptor<aes::Aes128>;
|
||||
type Aes256EcbEnc = ecb::Encryptor<aes::Aes256>;
|
||||
type Aes256EcbDec = ecb::Decryptor<aes::Aes256>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AesEcbCipher {
|
||||
pub(crate) cipher: AesEcbEnum,
|
||||
pub(crate) finger: Option<Finger>,
|
||||
}
|
||||
|
||||
#[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<Finger>) -> Self {
|
||||
Self {
|
||||
cipher: AesEcbEnum::AES128ECB(key),
|
||||
finger,
|
||||
}
|
||||
}
|
||||
pub fn new_256(key: [u8; 32], finger: Option<Finger>) -> Self {
|
||||
Self {
|
||||
cipher: AesEcbEnum::AES256ECB(key),
|
||||
finger,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn decrypt_ipv4<B: AsRef<[u8]> + AsMut<[u8]>>(&self, net_packet: &mut NetPacket<B>) -> 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::<Pkcs7>(secret_body.en_body_mut()) }
|
||||
AesEcbEnum::AES256ECB(key) => { Aes256EcbDec::new(&(*key).into()).decrypt_padded_mut::<Pkcs7>(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<B: AsRef<[u8]> + AsMut<[u8]>>(&self, net_packet: &mut NetPacket<B>) -> 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::<Pkcs7>(net_packet.payload_mut(), p_len) }
|
||||
AesEcbEnum::AES256ECB(key) => { Aes256EcbEnc::new(&(*key).into()).encrypt_padded_mut::<Pkcs7>(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)))
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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<Finger>,
|
||||
}
|
||||
|
||||
#[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<Finger>) -> Self {
|
||||
let key: &Key<Aes128Gcm> = &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<Finger>) -> Self {
|
||||
let key: &Key<Aes256Gcm> = &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<u8, U12> = 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<u8, U16> = Tag::clone_from_slice(tag);
|
||||
let rs = match &self.cipher {
|
||||
@@ -90,7 +91,7 @@ impl AesGcmCipher {
|
||||
let nonce: &GenericArray<u8, U12> = 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(())
|
||||
}
|
||||
|
||||
+39
-11
@@ -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<u8>)),
|
||||
AesCbc(AesCbcCipher),
|
||||
AesEcb(AesEcbCipher),
|
||||
None,
|
||||
}
|
||||
|
||||
impl Cipher {
|
||||
pub fn new_password(model: CipherModel, password: Option<String>, token: String) -> Self {
|
||||
let finger = Finger::new(&token);
|
||||
pub fn new_password(model: CipherModel, password: Option<String>, token: Option<String>) -> 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<Self> {
|
||||
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<B: AsRef<[u8]>>(&self, net_packet: &NetPacket<B>) -> 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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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<Finger>,
|
||||
}
|
||||
|
||||
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<Finger>) -> 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<Finger>) -> 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(())
|
||||
}
|
||||
|
||||
+10
-3
@@ -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<String>, simulate_multicast: bool, mtu: Option<u16>, tcp: bool,
|
||||
ip: Option<Ipv4Addr>,
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,13 +71,12 @@ pub fn start_heartbeat(
|
||||
}
|
||||
|
||||
|
||||
fn heartbeat_packet(device_list: &Mutex<(u16, Vec<PeerDeviceInfo>)>, 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<PeerDeviceInfo>)>, 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);
|
||||
|
||||
@@ -61,7 +61,8 @@ async fn broadcast(server_cipher: &Cipher, multicast_members: Option<Arc<RwLock<
|
||||
server_packet.set_gateway_flag(true);
|
||||
server_packet.first_set_ttl(MAX_TTL);
|
||||
server_packet.set_source(net_packet.source());
|
||||
server_packet.set_destination(current_device.virtual_gateway);
|
||||
//使用对应的目的地址
|
||||
server_packet.set_destination(net_packet.destination());
|
||||
server_packet.set_protocol(protocol::Protocol::IpTurn);
|
||||
server_packet.set_transport_protocol(ip_turn_packet::Protocol::Ipv4Broadcast.into());
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
use crate::error::Error;
|
||||
pub const VNT_VERSION:&'static str = "1.2.1";
|
||||
pub const VNT_VERSION:&'static str = "1.2.2";
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
pub mod error;
|
||||
|
||||
+39
-20
@@ -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<u8>>,
|
||||
// @@protoc_insertion_point(field:PunchInfo.ipv6)
|
||||
pub ipv6: ::std::vec::Vec<u8>,
|
||||
// @@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>(
|
||||
"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
|
||||
|
||||
+101
-50
@@ -24,44 +24,62 @@ pub const ENCRYPTION_RESERVED: usize = 32;
|
||||
*/
|
||||
pub struct SecretBody<B> {
|
||||
buffer: B,
|
||||
exist_finger: bool,
|
||||
}
|
||||
|
||||
impl<B: AsRef<[u8]>> SecretBody<B> {
|
||||
pub fn new(buffer: B) -> io::Result<SecretBody<B>> {
|
||||
pub fn new(buffer: B, exist_finger: bool) -> io::Result<SecretBody<B>> {
|
||||
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<B: AsRef<[u8]>> SecretBody<B> {
|
||||
}
|
||||
|
||||
impl<B: AsRef<[u8]> + AsMut<[u8]>> SecretBody<B> {
|
||||
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<B: AsRef<[u8]> + AsMut<[u8]>> SecretBody<B> {
|
||||
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<B: AsRef<[u8]>> fmt::Debug for SecretBody<B> {
|
||||
.field("random", &self.random())
|
||||
.field("body", &self.body())
|
||||
.field("tag", &self.tag())
|
||||
.field("finger", &self.finger())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
@@ -149,43 +175,68 @@ impl<B: AsRef<[u8]>> fmt::Debug for SecretBody<B> {
|
||||
*/
|
||||
pub struct AesCbcSecretBody<B> {
|
||||
buffer: B,
|
||||
exist_finger: bool,
|
||||
}
|
||||
|
||||
impl<B: AsRef<[u8]>> AesCbcSecretBody<B> {
|
||||
pub fn new(buffer: B) -> io::Result<AesCbcSecretBody<B>> {
|
||||
pub fn new(buffer: B, exist_finger: bool) -> io::Result<AesCbcSecretBody<B>> {
|
||||
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<B: AsRef<[u8]> + AsMut<[u8]>> AesCbcSecretBody<B> {
|
||||
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]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,10 +40,7 @@ impl<B: AsRef<[u8]>> BroadcastPacket<B> {
|
||||
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<B: AsRef<[u8]>> BroadcastPacket<B> {
|
||||
|
||||
impl<B: AsRef<[u8]>> BroadcastPacket<B> {
|
||||
pub fn addr_num(&self) -> u8 {
|
||||
self.buffer.as_ref()[1]
|
||||
self.buffer.as_ref()[0]
|
||||
}
|
||||
/// 已经发送给了这些地址
|
||||
pub fn addresses(&self) -> Vec<Ipv4Addr> {
|
||||
@@ -61,7 +58,12 @@ impl<B: AsRef<[u8]>> BroadcastPacket<B> {
|
||||
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<B: AsRef<[u8]>> BroadcastPacket<B> {
|
||||
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<B: AsRef<[u8]> + AsMut<[u8]>> BroadcastPacket<B> {
|
||||
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<B: AsRef<[u8]> + AsMut<[u8]>> BroadcastPacket<B> {
|
||||
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(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user