diff --git a/vnt/proto/message.proto b/vnt/proto/message.proto index cd251fd..b0073d6 100644 --- a/vnt/proto/message.proto +++ b/vnt/proto/message.proto @@ -3,6 +3,7 @@ syntax = "proto3"; message HandshakeRequest { string version = 1; bool secret = 2; + string key_finger = 3; } message HandshakeResponse { string version = 1; diff --git a/vnt/src/channel/context.rs b/vnt/src/channel/context.rs index 0cbc107..25052da 100644 --- a/vnt/src/channel/context.rs +++ b/vnt/src/channel/context.rs @@ -74,6 +74,7 @@ impl Deref for Context { /// 对称网络增加的udp socket数目,有助于增加打洞成功率 pub const SYMMETRIC_CHANNEL_NUM: usize = 100; const PACKET_LOSS_RATE_DENOMINATOR: u32 = 100_0000; + pub struct ContextInner { // 核心udp socket pub(crate) main_udp_socket: Vec, @@ -198,6 +199,9 @@ impl ContextInner { self.send_main_udp(self.main_index.load(Ordering::Relaxed), buf, addr) } } + pub fn is_default_route(&self, route_key: RouteKey) -> bool { + self.is_tcp == route_key.is_tcp && self.main_index.load(Ordering::Relaxed) == route_key.index + } pub fn change_main_index(&self) { let index = (self.main_index.load(Ordering::Relaxed) + 1) % self.main_udp_socket.len(); self.main_index.store(index, Ordering::Relaxed); @@ -295,7 +299,7 @@ impl ContextInner { pub struct RouteTable { pub(crate) route_table: - RwLock)>)>>, + RwLock)>)>>, first_latency: bool, channel_num: usize, use_channel_type: UseChannelType, diff --git a/vnt/src/cipher/rsa_cipher.rs b/vnt/src/cipher/rsa_cipher.rs index 38d4f51..ca53910 100644 --- a/vnt/src/cipher/rsa_cipher.rs +++ b/vnt/src/cipher/rsa_cipher.rs @@ -1,7 +1,7 @@ -use crate::protocol::NetPacket; use std::io; + use { - crate::protocol::body::{RsaSecretBody, RSA_ENCRYPTION_RESERVED}, + crate::protocol::body::{RSA_ENCRYPTION_RESERVED, RsaSecretBody}, rand::Rng, rsa::pkcs8::der::Decode, rsa::RsaPublicKey, @@ -9,6 +9,8 @@ use { spki::{DecodePublicKey, EncodePublicKey}, }; +use crate::protocol::NetPacket; + #[derive(Clone)] pub struct RsaCipher { inner: Inner, @@ -16,13 +18,15 @@ pub struct RsaCipher { #[derive(Clone)] struct Inner { public_key: RsaPublicKey, + finger:String, } impl RsaCipher { pub fn new(der: &[u8]) -> io::Result { match RsaPublicKey::from_public_key_der(der) { Ok(public_key) => { - let inner = Inner { public_key }; + let finger = finger(&public_key)?; + let inner = Inner { public_key,finger }; Ok(Self { inner }) } Err(e) => Err(io::Error::new( @@ -31,30 +35,32 @@ impl RsaCipher { )), } } - - pub fn finger(&self) -> io::Result { - match self.inner.public_key.to_public_key_der() { - Ok(der) => match rsa::pkcs8::SubjectPublicKeyInfoRef::from_der(der.as_bytes()) { - Ok(spki) => match spki.fingerprint_base64() { - Ok(finger) => Ok(finger), - Err(e) => Err(io::Error::new( - io::ErrorKind::Other, - format!("fingerprint_base64 error {}", e), - )), - }, + pub fn finger(&self) ->&String{ + &self.inner.finger + } + pub fn public_key(&self) -> io::Result<&RsaPublicKey> { + return Ok(&self.inner.public_key); + } +} +pub fn finger(public_key: &RsaPublicKey) -> io::Result { + match public_key.to_public_key_der() { + Ok(der) => match rsa::pkcs8::SubjectPublicKeyInfoRef::from_der(der.as_bytes()) { + Ok(spki) => match spki.fingerprint_base64() { + Ok(finger) => Ok(finger), Err(e) => Err(io::Error::new( io::ErrorKind::Other, - format!("from_der error {}", e), + format!("fingerprint_base64 error {}", e), )), }, Err(e) => Err(io::Error::new( io::ErrorKind::Other, - format!("to_public_key_der error {}", e), + format!("from_der error {}", e), )), - } - } - pub fn public_key(&self) -> io::Result<&RsaPublicKey> { - return Ok(&self.inner.public_key); + }, + Err(e) => Err(io::Error::new( + io::ErrorKind::Other, + format!("to_public_key_der error {}", e), + )), } } diff --git a/vnt/src/core/conn.rs b/vnt/src/core/conn.rs index 48b2ad4..8d639b1 100644 --- a/vnt/src/core/conn.rs +++ b/vnt/src/core/conn.rs @@ -79,6 +79,7 @@ impl Vnt { config.token.clone(), config.ip, config.password.is_some(), + config.server_encrypt, config.device_id.clone(), config.server_address_str.clone(), ); @@ -144,7 +145,7 @@ impl Vnt { let down_counter = U64Adder::with_capacity(config.ports.as_ref().map(|v| v.len()).unwrap_or_default() + 8); let down_count_watcher = down_counter.watch(); - let handshake = Handshake::new(); + let handshake = Handshake::new(rsa_cipher.clone()); let handler = RecvDataHandler::new( #[cfg(feature = "server_encrypt")] rsa_cipher, diff --git a/vnt/src/handle/handshaker.rs b/vnt/src/handle/handshaker.rs index 8d7f22d..92a5048 100644 --- a/vnt/src/handle/handshaker.rs +++ b/vnt/src/handle/handshaker.rs @@ -4,6 +4,7 @@ use std::sync::Arc; use std::time::{Duration, Instant}; use crossbeam_utils::atomic::AtomicCell; +use parking_lot::Mutex; use protobuf::Message; use crate::channel::context::Context; @@ -27,11 +28,13 @@ pub enum HandshakeEnum { #[derive(Clone)] pub struct Handshake { time: Arc>, + rsa_cipher: Arc>> } impl Handshake { - pub fn new() -> Self { + pub fn new( rsa_cipher: Arc>>) -> Self { Handshake { time: Arc::new(AtomicCell::new(Instant::now() - Duration::from_secs(60))), + rsa_cipher } } pub fn send(&self, context: &Context, secret: bool, addr: SocketAddr) -> io::Result<()> { @@ -40,37 +43,42 @@ impl Handshake { if last.elapsed() < Duration::from_secs(3) { return Ok(()); } - let request_packet = handshake_request_packet(secret)?; + let request_packet = self.handshake_request_packet(secret)?; log::info!("发送握手请求,secret={},{:?}", secret, addr); context.send_default(request_packet.buffer(), addr)?; self.time.store(Instant::now()); Ok(()) } + /// 第一次握手数据 + pub fn handshake_request_packet(&self,secret: bool) -> io::Result>> { + + let mut request = HandshakeRequest::new(); + request.secret = secret; + request.version = crate::VNT_VERSION.to_string(); + if let Some(finger) = self.rsa_cipher.lock().as_ref().map(|v| v.finger().clone()){ + request.key_finger = finger; + } + let bytes = request.write_to_bytes().map_err(|e| { + io::Error::new( + io::ErrorKind::Other, + format!("handshake_request_packet {:?}", e), + ) + })?; + let buf = vec![0u8; 12 + bytes.len()]; + let mut net_packet = NetPacket::new(buf)?; + net_packet.set_version(Version::V1); + net_packet.set_gateway_flag(true); + net_packet.set_destination(GATEWAY_IP); + net_packet.set_source(SELF_IP); + net_packet.set_protocol(Protocol::Service); + net_packet.set_transport_protocol(service_packet::Protocol::HandshakeRequest.into()); + net_packet.first_set_ttl(MAX_TTL); + net_packet.set_payload(&bytes)?; + Ok(net_packet) + } } -/// 第一次握手数据 -pub fn handshake_request_packet(secret: bool) -> io::Result>> { - let mut request = HandshakeRequest::new(); - request.secret = secret; - request.version = crate::VNT_VERSION.to_string(); - let bytes = request.write_to_bytes().map_err(|e| { - io::Error::new( - io::ErrorKind::Other, - format!("handshake_request_packet {:?}", e), - ) - })?; - let buf = vec![0u8; 12 + bytes.len()]; - let mut net_packet = NetPacket::new(buf)?; - net_packet.set_version(Version::V1); - net_packet.set_gateway_flag(true); - net_packet.set_destination(GATEWAY_IP); - net_packet.set_source(SELF_IP); - net_packet.set_protocol(Protocol::Service); - net_packet.set_transport_protocol(service_packet::Protocol::HandshakeRequest.into()); - net_packet.first_set_ttl(MAX_TTL); - net_packet.set_payload(&bytes)?; - Ok(net_packet) -} + /// 第二次加密握手 #[cfg(feature = "server_encrypt")] diff --git a/vnt/src/handle/maintain/idle.rs b/vnt/src/handle/maintain/idle.rs index 0b3e760..8811ced 100644 --- a/vnt/src/handle/maintain/idle.rs +++ b/vnt/src/handle/maintain/idle.rs @@ -6,14 +6,14 @@ use std::time::Duration; use crossbeam_utils::atomic::AtomicCell; use mio::net::TcpStream; +use crate::{ErrorInfo, VntCallback}; use crate::channel::context::Context; use crate::channel::idle::{Idle, IdleType}; use crate::channel::sender::AcceptSocketSender; +use crate::handle::{BaseConfigInfo, ConnectStatus, CurrentDeviceInfo}; use crate::handle::callback::{ConnectInfo, ErrorType}; use crate::handle::handshaker::Handshake; -use crate::handle::{handshaker, BaseConfigInfo, ConnectStatus, CurrentDeviceInfo}; use crate::util::Scheduler; -use crate::{ErrorInfo, VntCallback}; pub fn idle_route( scheduler: &Scheduler, @@ -133,11 +133,11 @@ fn check_gateway_channel( //需要重连 call.connect(ConnectInfo::new(*count, current_device.connect_server)); log::info!("发送握手请求,{:?}", config); - if let Err(e) = handshake.send(context, config.client_secret, current_device.connect_server) + if let Err(e) = handshake.send(context, config.server_secret, current_device.connect_server) { log::warn!("{:?}", e); if context.is_main_tcp() { - let request_packet = handshaker::handshake_request_packet(config.client_secret)?; + let request_packet = handshake.handshake_request_packet(config.server_secret)?; //tcp需要重连 let tcp_stream = std::net::TcpStream::connect_timeout( ¤t_device.connect_server, diff --git a/vnt/src/handle/mod.rs b/vnt/src/handle/mod.rs index 33d166d..e4e97e6 100644 --- a/vnt/src/handle/mod.rs +++ b/vnt/src/handle/mod.rs @@ -51,6 +51,7 @@ pub struct BaseConfigInfo { pub token: String, pub ip: Option, pub client_secret: bool, + pub server_secret: bool, pub device_id: String, pub server_addr: String, } @@ -61,6 +62,7 @@ impl BaseConfigInfo { token: String, ip: Option, client_secret: bool, + server_secret: bool, device_id: String, server_addr: String, ) -> Self { @@ -69,6 +71,7 @@ impl BaseConfigInfo { token, ip, client_secret, + server_secret, device_id, server_addr, } diff --git a/vnt/src/handle/recv_data/server.rs b/vnt/src/handle/recv_data/server.rs index a55da30..d384421 100644 --- a/vnt/src/handle/recv_data/server.rs +++ b/vnt/src/handle/recv_data/server.rs @@ -11,30 +11,30 @@ use protobuf::Message; use packet::icmp::{icmp, Kind}; use packet::ip::ipv4; use packet::ip::ipv4::packet::IpV4Packet; -use tun::device::IFace; use tun::Device; +use tun::device::IFace; -use crate::channel::context::Context; use crate::channel::{Route, RouteKey}; +use crate::channel::context::Context; use crate::cipher::Cipher; #[cfg(feature = "server_encrypt")] use crate::cipher::RsaCipher; use crate::external_route::ExternalRoute; +use crate::handle::{ + BaseConfigInfo, ConnectStatus, CurrentDeviceInfo, GATEWAY_IP, PeerDeviceInfo, registrar, +}; use crate::handle::callback::{ErrorInfo, ErrorType, HandshakeInfo, RegisterInfo, VntCallback}; #[cfg(feature = "server_encrypt")] use crate::handle::handshaker; use crate::handle::handshaker::Handshake; use crate::handle::recv_data::PacketHandler; -use crate::handle::{ - registrar, BaseConfigInfo, ConnectStatus, CurrentDeviceInfo, PeerDeviceInfo, GATEWAY_IP, -}; use crate::nat::NatTest; use crate::proto; use crate::proto::message::{DeviceList, HandshakeResponse, RegistrationResponse}; +use crate::protocol::{ip_turn_packet, MAX_TTL, NetPacket, Protocol, service_packet, Version}; use crate::protocol::body::ENCRYPTION_RESERVED; use crate::protocol::control_packet::ControlPacket; use crate::protocol::error_packet::InErrorPacket; -use crate::protocol::{ip_turn_packet, service_packet, NetPacket, Protocol, Version, MAX_TTL}; /// 处理来源于服务端的包 #[derive(Clone)] @@ -136,13 +136,35 @@ impl PacketHandler for ServerPacketHandler { HandshakeResponse::parse_from_bytes(net_packet.payload()).map_err(|e| { io::Error::new(io::ErrorKind::Other, format!("HandshakeResponse {:?}", e)) })?; + log::info!("握手响应:{:?},{}",route_key, response); //如果开启了加密,则发送加密握手请求 #[cfg(feature = "server_encrypt")] if let Some(key) = self.server_cipher.key() { + { + let guard = self.rsa_cipher.lock(); + if let Some(rsa_cipher) = guard.as_ref(){ + if rsa_cipher.finger()==&response.key_finger{ + let packet = handshaker::secret_handshake_request_packet( + rsa_cipher, + self.config_info.token.clone(), + key, + )?; + drop(guard); + context.send_by_key(packet.buffer(), route_key)?; + return Ok(()); + } + log::info!("服务端密钥对变化,原指纹:{:?},新指纹:{:?}", rsa_cipher.finger(),response.key_finger); + } + drop(guard); + } let rsa_cipher = RsaCipher::new(&response.public_key)?; + if rsa_cipher.finger() != &response.key_finger { + log::info!("服务端密钥和指纹不匹 配拒绝握手,指纹1:{:?},指纹2:{:?}", rsa_cipher.finger(),response.key_finger); + return Ok(()); + } let handshake_info = HandshakeInfo::new( rsa_cipher.public_key()?.clone(), - rsa_cipher.finger()?, + response.key_finger, response.version, ); log::info!("加密握手请求:{:?}", handshake_info); @@ -158,7 +180,9 @@ impl PacketHandler for ServerPacketHandler { } return Ok(()); } - + if let Ok(rsa_cipher) = RsaCipher::new(&response.public_key){ + self.rsa_cipher.lock().replace(rsa_cipher); + } let handshake_info = HandshakeInfo::new_no_secret(response.version); if self.callback.handshake(handshake_info) { //没有加密,则发送注册请求 @@ -334,9 +358,11 @@ impl ServerPacketHandler { self.set_device_info_list(response.device_info_list, response.epoch as _); } service_packet::Protocol::SecretHandshakeResponse => { - log::info!("SecretHandshakeResponse"); - //加密握手结束,发送注册数据 - self.register(current_device, context)?; + if context.is_default_route(route_key){ + log::info!("SecretHandshakeResponse"); + //加密握手结束,发送注册数据 + self.register(current_device, context)?; + } } _ => { log::warn!( @@ -415,7 +441,7 @@ impl ServerPacketHandler { drop(dev); } self.handshake - .send(context, self.config_info.client_secret, route_key.addr)?; + .send(context, self.config_info.server_secret, route_key.addr)?; // self.register(current_device, context, route_key)?; } InErrorPacket::AddressExhausted => {