diff --git a/Cargo.lock b/Cargo.lock index ddd3361..cc8d3b3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -121,17 +121,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "async-trait" -version = "0.1.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.39", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -253,7 +242,6 @@ dependencies = [ "aead", "anyhow", "async-channel", - "async-trait", "base64", "blake2", "caps", diff --git a/burrow/Cargo.toml b/burrow/Cargo.toml index 4d03a80..f263cc6 100644 --- a/burrow/Cargo.toml +++ b/burrow/Cargo.toml @@ -36,7 +36,6 @@ base64 = "0.21.4" fehler = "1.0.0" ip_network_table = "0.2.0" ip_network = "0.4.0" -async-trait = "0.1.74" async-channel = "2.1.1" schemars = "0.8" futures = "0.3.28" diff --git a/burrow/src/daemon/instance.rs b/burrow/src/daemon/instance.rs index 8c96b98..34e9878 100644 --- a/burrow/src/daemon/instance.rs +++ b/burrow/src/daemon/instance.rs @@ -41,10 +41,6 @@ impl DaemonInstance { } } - pub fn set_tun_interface(&mut self, tun_interface: Arc>) { - self.tun_interface = Some(tun_interface); - } - async fn proc_command(&mut self, command: DaemonCommand) -> Result { info!("Daemon got command: {:?}", command); match command { diff --git a/burrow/src/daemon/mod.rs b/burrow/src/daemon/mod.rs index 3768e62..9f60e2f 100644 --- a/burrow/src/daemon/mod.rs +++ b/burrow/src/daemon/mod.rs @@ -1,52 +1,24 @@ -use std::net::ToSocketAddrs; -use std::{ - net::{IpAddr, Ipv4Addr, SocketAddr}, - sync::Arc, -}; +use std::sync::Arc; mod command; mod instance; mod net; mod response; -use anyhow::{anyhow, Error, Result}; -use base64::{engine::general_purpose, Engine as _}; +use anyhow::Result; pub use command::{DaemonCommand, DaemonStartOptions}; -use fehler::throws; use instance::DaemonInstance; -use ip_network::{IpNetwork, Ipv4Network}; #[cfg(target_vendor = "apple")] pub use net::start_srv; pub use net::DaemonClient; pub use response::{DaemonResponse, DaemonResponseData, ServerInfo}; use tokio::sync::RwLock; -use crate::wireguard::Config; use crate::{ daemon::net::listen, - wireguard::{Interface, Peer, PublicKey, StaticSecret}, + wireguard::{Config, Interface}, }; -#[throws] -fn parse_key(string: &str) -> [u8; 32] { - let value = general_purpose::STANDARD.decode(string)?; - let mut key = [0u8; 32]; - key.copy_from_slice(&value[..]); - key -} - -#[throws] -fn parse_secret_key(string: &str) -> StaticSecret { - let key = parse_key(string)?; - StaticSecret::from(key) -} - -#[throws] -fn parse_public_key(string: &str) -> PublicKey { - let key = parse_key(string)?; - PublicKey::from(key) -} - pub async fn daemon_main() -> Result<()> { let (commands_tx, commands_rx) = async_channel::unbounded(); let (response_tx, response_rx) = async_channel::unbounded(); @@ -73,6 +45,7 @@ pub async fn daemon_main() -> Result<()> { } }); - tokio::try_join!(inst_job, listen_job).map(|_| ()); - Ok(()) + tokio::try_join!(inst_job, listen_job) + .map(|_| ()) + .map_err(|e| e.into()) } diff --git a/burrow/src/daemon/net/apple.rs b/burrow/src/daemon/net/apple.rs index f7b4e81..8a2aadc 100644 --- a/burrow/src/daemon/net/apple.rs +++ b/burrow/src/daemon/net/apple.rs @@ -23,8 +23,8 @@ pub extern "C" fn start_srv() { Ok(..) => { info!("Server successfully started"); break - }, - Err(e) => error!("Could not connect to server: {}", e) + } + Err(e) => error!("Could not connect to server: {}", e), } } }); diff --git a/burrow/src/daemon/net/systemd.rs b/burrow/src/daemon/net/systemd.rs index e619c04..80fe41c 100644 --- a/burrow/src/daemon/net/systemd.rs +++ b/burrow/src/daemon/net/systemd.rs @@ -1,7 +1,9 @@ +use std::os::fd::IntoRawFd; + +use anyhow::Result; + use super::*; use crate::daemon::DaemonResponse; -use anyhow::Result; -use std::os::fd::IntoRawFd; pub async fn listen( cmd_tx: async_channel::Sender, diff --git a/burrow/src/daemon/net/unix.rs b/burrow/src/daemon/net/unix.rs index cd8fb83..e2ae16f 100644 --- a/burrow/src/daemon/net/unix.rs +++ b/burrow/src/daemon/net/unix.rs @@ -6,16 +6,16 @@ use std::{ }, path::{Path, PathBuf}, }; -use tracing::info; -use crate::daemon::{DaemonCommand, DaemonResponse, DaemonResponseData}; use anyhow::{anyhow, Result}; use tokio::{ io::{AsyncBufReadExt, AsyncWriteExt, BufReader}, net::{UnixListener, UnixStream}, }; -use tracing::debug; +use tracing::{debug, info}; + use super::*; +use crate::daemon::{DaemonCommand, DaemonResponse, DaemonResponseData}; #[cfg(not(target_vendor = "apple"))] const UNIX_SOCKET_PATH: &str = "/run/burrow.sock"; @@ -36,7 +36,7 @@ fn fetch_socket_path() -> Option { for path in tries { let path = PathBuf::from(path); if path.exists() { - return Some(path); + return Some(path) } } None diff --git a/burrow/src/daemon/net/windows.rs b/burrow/src/daemon/net/windows.rs index 6dfd155..c4a1d71 100644 --- a/burrow/src/daemon/net/windows.rs +++ b/burrow/src/daemon/net/windows.rs @@ -1,5 +1,6 @@ -use super::*; use anyhow::Result; + +use super::*; use crate::daemon::DaemonResponse; pub async fn listen( diff --git a/burrow/src/daemon/response.rs b/burrow/src/daemon/response.rs index aa5507a..386da46 100644 --- a/burrow/src/daemon/response.rs +++ b/burrow/src/daemon/response.rs @@ -1,7 +1,6 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use tun::TunInterface; -use anyhow::anyhow; #[derive(Clone, Serialize, Deserialize, Debug, JsonSchema)] pub struct DaemonResponse { @@ -19,9 +18,9 @@ impl DaemonResponse { } } -impl Into for DaemonResponseData { - fn into(self) -> DaemonResponse { - DaemonResponse::new(Ok::(self)) +impl From for DaemonResponse { + fn from(val: DaemonResponseData) -> Self { + DaemonResponse::new(Ok::(val)) } } diff --git a/burrow/src/lib.rs b/burrow/src/lib.rs index 2fee67f..3dfc4ac 100644 --- a/burrow/src/lib.rs +++ b/burrow/src/lib.rs @@ -5,7 +5,12 @@ pub mod wireguard; mod daemon; #[cfg(any(target_os = "linux", target_vendor = "apple"))] pub use daemon::{ - DaemonClient, DaemonCommand, DaemonResponse, DaemonResponseData, DaemonStartOptions, ServerInfo, + DaemonClient, + DaemonCommand, + DaemonResponse, + DaemonResponseData, + DaemonStartOptions, + ServerInfo, }; #[cfg(target_vendor = "apple")] diff --git a/burrow/src/main.rs b/burrow/src/main.rs index 2cc3753..db4602f 100644 --- a/burrow/src/main.rs +++ b/burrow/src/main.rs @@ -232,6 +232,6 @@ fn system_log() -> Result> { } #[cfg(not(any(target_os = "linux", target_vendor = "apple")))] -pub fn main(){ +pub fn main() { eprintln!("This platform is not supported currently.") -} \ No newline at end of file +} diff --git a/burrow/src/wireguard/config.rs b/burrow/src/wireguard/config.rs index a2599d4..d86486e 100644 --- a/burrow/src/wireguard/config.rs +++ b/burrow/src/wireguard/config.rs @@ -1,13 +1,13 @@ -use crate::wireguard::{Interface as WgInterface, Peer as WgPeer}; +use std::{net::ToSocketAddrs, str::FromStr}; + use anyhow::{anyhow, Error, Result}; -use base64::engine::general_purpose; -use base64::Engine; +use base64::{engine::general_purpose, Engine}; use fehler::throws; use ip_network::IpNetwork; -use std::net::ToSocketAddrs; -use std::str::FromStr; use x25519_dalek::{PublicKey, StaticSecret}; +use crate::wireguard::{Interface as WgInterface, Peer as WgPeer}; + #[throws] fn parse_key(string: &str) -> [u8; 32] { let value = general_purpose::STANDARD.decode(string)?; @@ -68,12 +68,11 @@ impl TryFrom for WgInterface { endpoint: p .endpoint .to_socket_addrs()? - .filter(|sock| sock.is_ipv4()) - .next() + .find(|sock| sock.is_ipv4()) .ok_or(anyhow!("DNS Lookup Fails!"))?, preshared_key: match &p.preshared_key { None => Ok(None), - Some(k) => parse_key(k).map(|res| Some(res)), + Some(k) => parse_key(k).map(Some), }?, allowed_ips: p .allowed_ips @@ -86,29 +85,28 @@ impl TryFrom for WgInterface { }) }) .collect::>>()?; - Ok(WgInterface::new(wg_peers)?) + WgInterface::new(wg_peers) } } - impl Default for Config { fn default() -> Self { - Self{ - interface: Interface{ + Self { + interface: Interface { private_key: "GNqIAOCRxjl/cicZyvkvpTklgQuUmGUIEkH7IXF/sEE=".into(), address: "10.13.13.2/24".into(), listen_port: 51820, dns: Default::default(), - mtu: Default::default() + mtu: Default::default(), }, - peers: vec![Peer{ + peers: vec![Peer { endpoint: "wg.burrow.rs:51820".into(), allowed_ips: vec!["8.8.8.8/32".into()], public_key: "uy75leriJay0+oHLhRMpV+A5xAQ0hCJ+q7Ww81AOvT4=".into(), preshared_key: Some("s7lx/mg+reVEMnGnqeyYOQkzD86n2+gYnx1M9ygi08k=".into()), persistent_keepalive: Default::default(), - name: Default::default() - }] + name: Default::default(), + }], } } -} \ No newline at end of file +} diff --git a/burrow/src/wireguard/iface.rs b/burrow/src/wireguard/iface.rs index 897dac1..281cc4a 100755 --- a/burrow/src/wireguard/iface.rs +++ b/burrow/src/wireguard/iface.rs @@ -1,33 +1,15 @@ -use std::{net::IpAddr, sync::Arc, time::Duration}; +use std::{net::IpAddr, sync::Arc}; use anyhow::Error; -use async_trait::async_trait; use fehler::throws; -use futures::{future::join_all, FutureExt}; +use futures::future::join_all; use ip_network_table::IpNetworkTable; -use tokio::{sync::RwLock, task::JoinHandle, time::timeout}; +use tokio::sync::RwLock; use tracing::{debug, error}; use tun::tokio::TunInterface; use super::{noise::Tunnel, Peer, PeerPcb}; -#[async_trait] -pub trait PacketInterface { - async fn recv(&mut self, buf: &mut [u8]) -> Result; - async fn send(&mut self, buf: &[u8]) -> Result; -} - -#[async_trait] -impl PacketInterface for tun::tokio::TunInterface { - async fn recv(&mut self, buf: &mut [u8]) -> Result { - self.recv(buf).await - } - - async fn send(&mut self, buf: &[u8]) -> Result { - self.send(buf).await - } -} - struct IndexedPcbs { pcbs: Vec>, allowed_ips: IpNetworkTable, @@ -44,7 +26,7 @@ impl IndexedPcbs { pub fn insert(&mut self, pcb: PeerPcb) { let idx: usize = self.pcbs.len(); for allowed_ip in pcb.allowed_ips.iter() { - self.allowed_ips.insert(allowed_ip.clone(), idx); + self.allowed_ips.insert(*allowed_ip, idx); } self.pcbs.insert(idx, Arc::new(pcb)); } @@ -53,10 +35,6 @@ impl IndexedPcbs { let (_, &idx) = self.allowed_ips.longest_match(addr)?; Some(idx) } - - pub async fn connect(&self, idx: usize, handle: JoinHandle<()>) { - self.pcbs[idx].handle.write().await.replace(handle); - } } impl FromIterator for IndexedPcbs { @@ -78,7 +56,7 @@ impl Interface { pub fn new>(peers: I) -> Self { let pcbs: IndexedPcbs = peers .into_iter() - .map(|peer| PeerPcb::new(peer)) + .map(PeerPcb::new) .collect::>()?; let pcbs = Arc::new(pcbs); @@ -106,7 +84,7 @@ impl Interface { Ok(len) => &buf[..len], Err(e) => { error!("Failed to read from interface: {}", e); - continue; + continue } }; debug!("Read {} bytes from interface", src.len()); @@ -117,7 +95,7 @@ impl Interface { Some(addr) => addr, None => { debug!("No destination found"); - continue; + continue } }; @@ -136,7 +114,7 @@ impl Interface { } Err(e) => { log::error!("Failed to send packet {}", e); - continue; + continue } }; } @@ -160,12 +138,11 @@ impl Interface { let tsk = async move { if let Err(e) = pcb.open_if_closed().await { log::error!("failed to open pcb: {}", e); - return; + return } let r2 = pcb.run(tun).await; if let Err(e) = r2 { log::error!("failed to run pcb: {}", e); - return; } else { debug!("pcb ran successfully"); } diff --git a/burrow/src/wireguard/mod.rs b/burrow/src/wireguard/mod.rs index c181a83..b2e7b54 100755 --- a/burrow/src/wireguard/mod.rs +++ b/burrow/src/wireguard/mod.rs @@ -4,21 +4,8 @@ mod noise; mod pcb; mod peer; +pub use config::Config; pub use iface::Interface; pub use pcb::PeerPcb; pub use peer::Peer; pub use x25519_dalek::{PublicKey, StaticSecret}; -pub use config::Config; - -const WIREGUARD_CONFIG: &str = r#" -[Interface] -# Device: Gentle Tomcat -PrivateKey = sIxpokQPnWctJKNaQ3DRdcQbL2S5OMbUrvr4bbsvTHw= -Address = 10.68.136.199/32,fc00:bbbb:bbbb:bb01::5:88c6/128 -DNS = 10.64.0.1 - -[Peer] -public_key = EKZXvHlSDeqAjfC/m9aQR0oXfQ6Idgffa9L0DH5yaCo= -AllowedIPs = 0.0.0.0/0,::0/0 -Endpoint = 146.70.173.66:51820 -"#; diff --git a/burrow/src/wireguard/noise/errors.rs b/burrow/src/wireguard/noise/errors.rs index 10513ae..e196635 100755 --- a/burrow/src/wireguard/noise/errors.rs +++ b/burrow/src/wireguard/noise/errors.rs @@ -4,9 +4,7 @@ #[derive(Debug)] pub enum WireGuardError { DestinationBufferTooSmall, - IncorrectPacketLength, UnexpectedPacket, - WrongPacketType, WrongIndex, WrongKey, InvalidTai64nTimestamp, @@ -17,7 +15,6 @@ pub enum WireGuardError { DuplicateCounter, InvalidPacket, NoCurrentSession, - LockFailed, ConnectionExpired, UnderLoad, } diff --git a/burrow/src/wireguard/noise/handshake.rs b/burrow/src/wireguard/noise/handshake.rs index 08a4faa..2ec0c6a 100755 --- a/burrow/src/wireguard/noise/handshake.rs +++ b/burrow/src/wireguard/noise/handshake.rs @@ -9,14 +9,20 @@ use std::{ use aead::{Aead, Payload}; use blake2::{ digest::{FixedOutput, KeyInit}, - Blake2s256, Blake2sMac, Digest, + Blake2s256, + Blake2sMac, + Digest, }; use chacha20poly1305::XChaCha20Poly1305; use rand_core::OsRng; use ring::aead::{Aad, LessSafeKey, Nonce, UnboundKey, CHACHA20_POLY1305}; use super::{ - errors::WireGuardError, session::Session, x25519, HandshakeInit, HandshakeResponse, + errors::WireGuardError, + session::Session, + x25519, + HandshakeInit, + HandshakeResponse, PacketCookieReply, }; @@ -203,7 +209,7 @@ impl Tai64N { /// Parse a timestamp from a 12 byte u8 slice fn parse(buf: &[u8; 12]) -> Result { if buf.len() < 12 { - return Err(WireGuardError::InvalidTai64nTimestamp); + return Err(WireGuardError::InvalidTai64nTimestamp) } let (sec_bytes, nano_bytes) = buf.split_at(std::mem::size_of::()); @@ -550,22 +556,19 @@ impl Handshake { let timestamp = Tai64N::parse(×tamp)?; if !timestamp.after(&self.last_handshake_timestamp) { // Possibly a replay - return Err(WireGuardError::WrongTai64nTimestamp); + return Err(WireGuardError::WrongTai64nTimestamp) } self.last_handshake_timestamp = timestamp; // initiator.hash = HASH(initiator.hash || msg.encrypted_timestamp) hash = b2s_hash(&hash, packet.encrypted_timestamp); - self.previous = std::mem::replace( - &mut self.state, - HandshakeState::InitReceived { - chaining_key, - hash, - peer_ephemeral_public, - peer_index, - }, - ); + self.previous = std::mem::replace(&mut self.state, HandshakeState::InitReceived { + chaining_key, + hash, + peer_ephemeral_public, + peer_index, + }); self.format_handshake_response(dst) } @@ -666,7 +669,7 @@ impl Handshake { let local_index = self.cookies.index; if packet.receiver_idx != local_index { - return Err(WireGuardError::WrongIndex); + return Err(WireGuardError::WrongIndex) } // msg.encrypted_cookie = XAEAD(HASH(LABEL_COOKIE || responder.static_public), // msg.nonce, cookie, last_received_msg.mac1) @@ -722,7 +725,7 @@ impl Handshake { dst: &'a mut [u8], ) -> Result<&'a mut [u8], WireGuardError> { if dst.len() < super::HANDSHAKE_INIT_SZ { - return Err(WireGuardError::DestinationBufferTooSmall); + return Err(WireGuardError::DestinationBufferTooSmall) } let (message_type, rest) = dst.split_at_mut(4); @@ -805,7 +808,7 @@ impl Handshake { dst: &'a mut [u8], ) -> Result<(&'a mut [u8], Session), WireGuardError> { if dst.len() < super::HANDSHAKE_RESP_SZ { - return Err(WireGuardError::DestinationBufferTooSmall); + return Err(WireGuardError::DestinationBufferTooSmall) } let state = std::mem::replace(&mut self.state, HandshakeState::None); diff --git a/burrow/src/wireguard/noise/mod.rs b/burrow/src/wireguard/noise/mod.rs index b366775..6ece759 100755 --- a/burrow/src/wireguard/noise/mod.rs +++ b/burrow/src/wireguard/noise/mod.rs @@ -45,7 +45,11 @@ const N_SESSIONS: usize = 8; pub mod x25519 { pub use x25519_dalek::{ - EphemeralSecret, PublicKey, ReusableSecret, SharedSecret, StaticSecret, + EphemeralSecret, + PublicKey, + ReusableSecret, + SharedSecret, + StaticSecret, }; } @@ -129,15 +133,15 @@ pub struct PacketData<'a> { pub enum Packet<'a> { HandshakeInit(HandshakeInit<'a>), HandshakeResponse(HandshakeResponse<'a>), - PacketCookieReply(PacketCookieReply<'a>), - PacketData(PacketData<'a>), + CookieReply(PacketCookieReply<'a>), + Data(PacketData<'a>), } impl Tunnel { #[inline(always)] pub fn parse_incoming_packet(src: &[u8]) -> Result { if src.len() < 4 { - return Err(WireGuardError::InvalidPacket); + return Err(WireGuardError::InvalidPacket) } // Checks the type, as well as the reserved zero fields @@ -159,12 +163,12 @@ impl Tunnel { .expect("length already checked above"), encrypted_nothing: &src[44..60], }), - (COOKIE_REPLY, COOKIE_REPLY_SZ) => Packet::PacketCookieReply(PacketCookieReply { + (COOKIE_REPLY, COOKIE_REPLY_SZ) => Packet::CookieReply(PacketCookieReply { receiver_idx: u32::from_le_bytes(src[4..8].try_into().unwrap()), nonce: &src[8..32], encrypted_cookie: &src[32..64], }), - (DATA, DATA_OVERHEAD_SZ..=std::usize::MAX) => Packet::PacketData(PacketData { + (DATA, DATA_OVERHEAD_SZ..=std::usize::MAX) => Packet::Data(PacketData { receiver_idx: u32::from_le_bytes(src[4..8].try_into().unwrap()), counter: u64::from_le_bytes(src[8..16].try_into().unwrap()), encrypted_encapsulated_packet: &src[16..], @@ -179,7 +183,7 @@ impl Tunnel { pub fn dst_address(packet: &[u8]) -> Option { if packet.is_empty() { - return None; + return None } match packet[0] >> 4 { @@ -203,7 +207,7 @@ impl Tunnel { pub fn src_address(packet: &[u8]) -> Option { if packet.is_empty() { - return None; + return None } match packet[0] >> 4 { @@ -298,7 +302,7 @@ impl Tunnel { self.timer_tick(TimerName::TimeLastDataPacketSent); } self.tx_bytes += src.len(); - return TunnResult::WriteToNetwork(packet); + return TunnResult::WriteToNetwork(packet) } // If there is no session, queue the packet for future retry @@ -322,7 +326,7 @@ impl Tunnel { ) -> TunnResult<'a> { if datagram.is_empty() { // Indicates a repeated call - return self.send_queued_packet(dst); + return self.send_queued_packet(dst) } let mut cookie = [0u8; COOKIE_REPLY_SZ]; @@ -333,7 +337,7 @@ impl Tunnel { Ok(packet) => packet, Err(TunnResult::WriteToNetwork(cookie)) => { dst[..cookie.len()].copy_from_slice(cookie); - return TunnResult::WriteToNetwork(&mut dst[..cookie.len()]); + return TunnResult::WriteToNetwork(&mut dst[..cookie.len()]) } Err(TunnResult::Err(e)) => return TunnResult::Err(e), _ => unreachable!(), @@ -350,8 +354,8 @@ impl Tunnel { match packet { Packet::HandshakeInit(p) => self.handle_handshake_init(p, dst), Packet::HandshakeResponse(p) => self.handle_handshake_response(p, dst), - Packet::PacketCookieReply(p) => self.handle_cookie_reply(p), - Packet::PacketData(p) => self.handle_data(p, dst), + Packet::CookieReply(p) => self.handle_cookie_reply(p), + Packet::Data(p) => self.handle_data(p, dst), } .unwrap_or_else(TunnResult::from) } @@ -433,7 +437,7 @@ impl Tunnel { let cur_idx = self.current; if cur_idx == new_idx { // There is nothing to do, already using this session, this is the common case - return; + return } if self.sessions[cur_idx % N_SESSIONS].is_none() || self.timers.session_timers[new_idx % N_SESSIONS] @@ -479,7 +483,7 @@ impl Tunnel { force_resend: bool, ) -> TunnResult<'a> { if self.handshake.is_in_progress() && !force_resend { - return TunnResult::Done; + return TunnResult::Done } if self.handshake.is_expired() { @@ -538,7 +542,7 @@ impl Tunnel { }; if computed_len > packet.len() { - return TunnResult::Err(WireGuardError::InvalidPacket); + return TunnResult::Err(WireGuardError::InvalidPacket) } self.timer_tick(TimerName::TimeLastDataPacketReceived); diff --git a/burrow/src/wireguard/noise/rate_limiter.rs b/burrow/src/wireguard/noise/rate_limiter.rs index 826414b..ff19efd 100755 --- a/burrow/src/wireguard/noise/rate_limiter.rs +++ b/burrow/src/wireguard/noise/rate_limiter.rs @@ -12,9 +12,19 @@ use ring::constant_time::verify_slices_are_equal; use super::{ handshake::{ - b2s_hash, b2s_keyed_mac_16, b2s_keyed_mac_16_2, b2s_mac_24, LABEL_COOKIE, LABEL_MAC1, + b2s_hash, + b2s_keyed_mac_16, + b2s_keyed_mac_16_2, + b2s_mac_24, + LABEL_COOKIE, + LABEL_MAC1, }, - HandshakeInit, HandshakeResponse, Packet, TunnResult, Tunnel, WireGuardError, + HandshakeInit, + HandshakeResponse, + Packet, + TunnResult, + Tunnel, + WireGuardError, }; const COOKIE_REFRESH: u64 = 128; // Use 128 and not 120 so the compiler can optimize out the division @@ -126,7 +136,7 @@ impl RateLimiter { dst: &'a mut [u8], ) -> Result<&'a mut [u8], WireGuardError> { if dst.len() < super::COOKIE_REPLY_SZ { - return Err(WireGuardError::DestinationBufferTooSmall); + return Err(WireGuardError::DestinationBufferTooSmall) } let (message_type, rest) = dst.split_at_mut(4); @@ -192,7 +202,7 @@ impl RateLimiter { let cookie_packet = self .format_cookie_reply(sender_idx, cookie, mac1, dst) .map_err(TunnResult::Err)?; - return Err(TunnResult::WriteToNetwork(cookie_packet)); + return Err(TunnResult::WriteToNetwork(cookie_packet)) } } } diff --git a/burrow/src/wireguard/noise/session.rs b/burrow/src/wireguard/noise/session.rs index 14c191b..8988728 100755 --- a/burrow/src/wireguard/noise/session.rs +++ b/burrow/src/wireguard/noise/session.rs @@ -88,11 +88,11 @@ impl ReceivingKeyCounterValidator { fn will_accept(&self, counter: u64) -> Result<(), WireGuardError> { if counter >= self.next { // As long as the counter is growing no replay took place for sure - return Ok(()); + return Ok(()) } if counter + N_BITS < self.next { // Drop if too far back - return Err(WireGuardError::InvalidCounter); + return Err(WireGuardError::InvalidCounter) } if !self.check_bit(counter) { Ok(()) @@ -107,22 +107,22 @@ impl ReceivingKeyCounterValidator { fn mark_did_receive(&mut self, counter: u64) -> Result<(), WireGuardError> { if counter + N_BITS < self.next { // Drop if too far back - return Err(WireGuardError::InvalidCounter); + return Err(WireGuardError::InvalidCounter) } if counter == self.next { // Usually the packets arrive in order, in that case we simply mark the bit and // increment the counter self.set_bit(counter); self.next += 1; - return Ok(()); + return Ok(()) } if counter < self.next { // A packet arrived out of order, check if it is valid, and mark if self.check_bit(counter) { - return Err(WireGuardError::InvalidCounter); + return Err(WireGuardError::InvalidCounter) } self.set_bit(counter); - return Ok(()); + return Ok(()) } // Packets where dropped, or maybe reordered, skip them and mark unused if counter - self.next >= N_BITS { @@ -247,7 +247,7 @@ impl Session { panic!("The destination buffer is too small"); } if packet.receiver_idx != self.receiving_index { - return Err(WireGuardError::WrongIndex); + return Err(WireGuardError::WrongIndex) } // Don't reuse counters, in case this is a replay attack we want to quickly // check the counter without running expensive decryption diff --git a/burrow/src/wireguard/noise/timers.rs b/burrow/src/wireguard/noise/timers.rs index f713e6f..1d0cf1f 100755 --- a/burrow/src/wireguard/noise/timers.rs +++ b/burrow/src/wireguard/noise/timers.rs @@ -190,7 +190,7 @@ impl Tunnel { { if self.handshake.is_expired() { - return TunnResult::Err(WireGuardError::ConnectionExpired); + return TunnResult::Err(WireGuardError::ConnectionExpired) } // Clear cookie after COOKIE_EXPIRATION_TIME @@ -206,7 +206,7 @@ impl Tunnel { tracing::error!("CONNECTION_EXPIRED(REJECT_AFTER_TIME * 3)"); self.handshake.set_expired(); self.clear_all(); - return TunnResult::Err(WireGuardError::ConnectionExpired); + return TunnResult::Err(WireGuardError::ConnectionExpired) } if let Some(time_init_sent) = self.handshake.timer() { @@ -219,7 +219,7 @@ impl Tunnel { tracing::error!("CONNECTION_EXPIRED(REKEY_ATTEMPT_TIME)"); self.handshake.set_expired(); self.clear_all(); - return TunnResult::Err(WireGuardError::ConnectionExpired); + return TunnResult::Err(WireGuardError::ConnectionExpired) } if time_init_sent.elapsed() >= REKEY_TIMEOUT { @@ -299,11 +299,11 @@ impl Tunnel { } if handshake_initiation_required { - return self.format_handshake_initiation(dst, true); + return self.format_handshake_initiation(dst, true) } if keepalive_required { - return self.encapsulate(&[], dst); + return self.encapsulate(&[], dst) } TunnResult::Done diff --git a/burrow/src/wireguard/pcb.rs b/burrow/src/wireguard/pcb.rs index 27db935..a781870 100755 --- a/burrow/src/wireguard/pcb.rs +++ b/burrow/src/wireguard/pcb.rs @@ -1,10 +1,6 @@ -use std::{ - cell::{Cell, RefCell}, - net::SocketAddr, - sync::Arc, -}; +use std::{net::SocketAddr, sync::Arc}; -use anyhow::{anyhow, Error}; +use anyhow::Error; use fehler::throws; use ip_network::IpNetwork; use rand::random; @@ -74,7 +70,7 @@ impl PeerPcb { Ok(l) => l, Err(e) => { log::error!("{}: error reading from socket: {:?}", rid, e); - continue; + continue } }; let mut res_dat = &res_buf[..len]; @@ -90,7 +86,7 @@ impl PeerPcb { TunnResult::Done => break, TunnResult::Err(e) => { tracing::error!(message = "Decapsulate error", error = ?e); - break; + break } TunnResult::WriteToNetwork(packet) => { tracing::debug!("WriteToNetwork: {:?}", packet); @@ -98,17 +94,17 @@ impl PeerPcb { socket.send(packet).await?; tracing::debug!("WriteToNetwork done"); res_dat = &[]; - continue; + continue } TunnResult::WriteToTunnelV4(packet, addr) => { tracing::debug!("WriteToTunnelV4: {:?}, {:?}", packet, addr); tun_interface.read().await.send(packet).await?; - break; + break } TunnResult::WriteToTunnelV6(packet, addr) => { tracing::debug!("WriteToTunnelV6: {:?}, {:?}", packet, addr); tun_interface.read().await.send(packet).await?; - break; + break } } } diff --git a/tun/build.rs b/tun/build.rs index 03ee131..8da8a40 100644 --- a/tun/build.rs +++ b/tun/build.rs @@ -26,7 +26,7 @@ async fn generate(out_dir: &std::path::Path) -> anyhow::Result<()> { println!("cargo:rerun-if-changed={}", binary_path.to_str().unwrap()); if let (Ok(..), Ok(..)) = (File::open(&bindings_path), File::open(&binary_path)) { - return Ok(()); + return Ok(()) }; let archive = download(out_dir) diff --git a/tun/src/tokio/mod.rs b/tun/src/tokio/mod.rs index 3820ba9..947fb74 100644 --- a/tun/src/tokio/mod.rs +++ b/tun/src/tokio/mod.rs @@ -34,7 +34,7 @@ impl TunInterface { Ok(result) => return result, Err(_would_block) => { tracing::debug!("WouldBlock"); - continue; + continue } } } diff --git a/tun/src/unix/apple/mod.rs b/tun/src/unix/apple/mod.rs index 8efed1f..e72fb06 100644 --- a/tun/src/unix/apple/mod.rs +++ b/tun/src/unix/apple/mod.rs @@ -1,6 +1,6 @@ use std::{ io::{Error, IoSlice}, - mem::{self, ManuallyDrop}, + mem, net::{Ipv4Addr, SocketAddrV4}, os::fd::{AsRawFd, FromRawFd, RawFd}, }; diff --git a/tun/src/unix/apple/sys.rs b/tun/src/unix/apple/sys.rs index c0ea613..b4d4a6a 100644 --- a/tun/src/unix/apple/sys.rs +++ b/tun/src/unix/apple/sys.rs @@ -2,11 +2,20 @@ use std::mem; use libc::{c_char, c_int, c_short, c_uint, c_ulong, sockaddr}; pub use libc::{ - c_void, sockaddr_ctl, sockaddr_in, socklen_t, AF_SYSTEM, AF_SYS_CONTROL, IFNAMSIZ, + c_void, + sockaddr_ctl, + sockaddr_in, + socklen_t, + AF_SYSTEM, + AF_SYS_CONTROL, + IFNAMSIZ, SYSPROTO_CONTROL, }; use nix::{ - ioctl_read_bad, ioctl_readwrite, ioctl_write_ptr_bad, request_code_readwrite, + ioctl_read_bad, + ioctl_readwrite, + ioctl_write_ptr_bad, + request_code_readwrite, request_code_write, }; diff --git a/tun/src/unix/linux/mod.rs b/tun/src/unix/linux/mod.rs index e60429f..60d6341 100644 --- a/tun/src/unix/linux/mod.rs +++ b/tun/src/unix/linux/mod.rs @@ -13,6 +13,7 @@ use fehler::throws; use libc::in6_ifreq; use socket2::{Domain, SockAddr, Socket, Type}; use tracing::{info, instrument}; + use super::{ifname_to_string, string_to_ifname}; use crate::TunOptions; diff --git a/tun/src/unix/mod.rs b/tun/src/unix/mod.rs index 77a1158..ae0b77a 100644 --- a/tun/src/unix/mod.rs +++ b/tun/src/unix/mod.rs @@ -1,5 +1,5 @@ use std::{ - io::{Error, Read}, + io::Error, mem::MaybeUninit, os::fd::{AsRawFd, FromRawFd, IntoRawFd, RawFd}, }; @@ -51,7 +51,7 @@ impl TunInterface { let mut tmp_buf = [MaybeUninit::uninit(); 1500]; let len = self.socket.recv(&mut tmp_buf)?; let result_buf = unsafe { assume_init(&tmp_buf[4..len]) }; - buf[..len - 4].copy_from_slice(&result_buf); + buf[..len - 4].copy_from_slice(result_buf); len - 4 } diff --git a/tun/tests/packets.rs b/tun/tests/packets.rs index 91ebfba..28090a2 100644 --- a/tun/tests/packets.rs +++ b/tun/tests/packets.rs @@ -11,7 +11,7 @@ fn tst_read() { // This test is interactive, you need to send a packet to any server through // 192.168.1.10 EG. `sudo route add 8.8.8.8 192.168.1.10`, //`dig @8.8.8.8 hackclub.com` - let mut tun = TunInterface::new()?; + let tun = TunInterface::new()?; println!("tun name: {:?}", tun.name()?); tun.set_ipv4_addr(Ipv4Addr::from([192, 168, 1, 10]))?; println!("tun ip: {:?}", tun.ipv4_addr()?);