diff --git a/client/src/data_store.rs b/client/src/data_store.rs index 5ffa8a0..df582a2 100644 --- a/client/src/data_store.rs +++ b/client/src/data_store.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use shared::{ensure_dirs_exist, Cidr, IoErrorContext, Peer, WrappedIoError, CLIENT_DATA_DIR}; use std::{ fs::{File, OpenOptions}, - io::{Read, Seek, SeekFrom, Write}, + io::{self, Read, Seek, SeekFrom, Write}, path::{Path, PathBuf}, }; use wgctrl::InterfaceName; @@ -121,7 +121,7 @@ impl DataStore { } } - pub fn write(&mut self) -> Result<(), Error> { + pub fn write(&mut self) -> Result<(), io::Error> { self.file.seek(SeekFrom::Start(0))?; self.file.set_len(0)?; self.file diff --git a/client/src/main.rs b/client/src/main.rs index 410c6d4..909739f 100644 --- a/client/src/main.rs +++ b/client/src/main.rs @@ -245,7 +245,7 @@ fn update_hosts_file( interface: &InterfaceName, hosts_path: PathBuf, peers: &[Peer], -) -> Result<(), Error> { +) -> Result<(), WrappedIoError> { log::info!("updating {} with the latest peers.", "/etc/hosts".yellow()); let mut hosts_builder = HostsBuilder::new(format!("innernet {}", interface)); @@ -358,7 +358,11 @@ fn redeem_invite( network: NetworkOpt, ) -> Result<(), Error> { log::info!("bringing up the interface."); - let resolved_endpoint = config.server.external_endpoint.resolve()?; + let resolved_endpoint = config + .server + .external_endpoint + .resolve() + .with_str(config.server.external_endpoint.to_string())?; wg::up( &iface, &config.interface.private_key, @@ -370,7 +374,8 @@ fn redeem_invite( resolved_endpoint, )), network, - )?; + ) + .with_str(iface.to_string())?; log::info!("Generating new keypair."); let keypair = wgctrl::KeyPair::generate(); @@ -397,7 +402,8 @@ fn redeem_invite( log::info!("Changing keys and waiting for server's WireGuard interface to transition.",); DeviceUpdate::new() .set_private_key(keypair.private) - .apply(&iface, network.backend)?; + .apply(&iface, network.backend) + .with_str(iface.to_string())?; thread::sleep(*REDEEM_TRANSITION_WAIT); Ok(()) @@ -442,7 +448,11 @@ fn fetch( } log::info!("bringing up the interface."); - let resolved_endpoint = config.server.external_endpoint.resolve()?; + let resolved_endpoint = config + .server + .external_endpoint + .resolve() + .with_str(config.server.external_endpoint.to_string())?; wg::up( interface, &config.interface.private_key, @@ -454,7 +464,8 @@ fn fetch( resolved_endpoint, )), network, - )? + ) + .with_str(interface.to_string())?; } log::info!("fetching state from server."); @@ -521,7 +532,9 @@ fn fetch( } if device_config_changed { - device_config_builder.apply(&interface, network.backend)?; + device_config_builder + .apply(&interface, network.backend) + .with_str(interface.to_string())?; if let Some(path) = hosts_path { update_hosts_file(interface, path, &peers)?; @@ -534,7 +547,7 @@ fn fetch( } store.set_cidrs(cidrs); store.update_peers(peers)?; - store.write()?; + store.write().with_str(interface.to_string())?; Ok(()) } @@ -1020,6 +1033,9 @@ fn main() { if let Some(e) = e.downcast_ref::() { util::permissions_helptext(e); } + if let Some(e) = e.downcast_ref::() { + util::permissions_helptext(e); + } std::process::exit(1); } } diff --git a/client/src/util.rs b/client/src/util.rs index beb8b0a..3684c76 100644 --- a/client/src/util.rs +++ b/client/src/util.rs @@ -102,7 +102,7 @@ pub fn human_size(bytes: u64) -> String { } } -pub fn permissions_helptext(e: &WrappedIoError) { +pub fn permissions_helptext(e: &io::Error) { if e.raw_os_error() == Some(1) { let current_exe = std::env::current_exe() .ok() diff --git a/shared/src/interface_config.rs b/shared/src/interface_config.rs index 2e0ada0..657fc24 100644 --- a/shared/src/interface_config.rs +++ b/shared/src/interface_config.rs @@ -128,7 +128,7 @@ impl InterfaceConfig { .with_extension("conf") } - fn build_config_file_path(interface: &InterfaceName) -> Result { + fn build_config_file_path(interface: &InterfaceName) -> Result { ensure_dirs_exist(&[*CLIENT_CONFIG_DIR])?; Ok(Self::get_path(interface)) } diff --git a/shared/src/netlink.rs b/shared/src/netlink.rs index 6cb8f0b..bb96dd2 100644 --- a/shared/src/netlink.rs +++ b/shared/src/netlink.rs @@ -1,5 +1,3 @@ -use crate::Error; -use anyhow::anyhow; use ipnetwork::IpNetwork; use netlink_packet_core::{ NetlinkMessage, NetlinkPayload, NLM_F_ACK, NLM_F_CREATE, NLM_F_EXCL, NLM_F_REQUEST, @@ -12,9 +10,12 @@ use netlink_sys::{protocols::NETLINK_ROUTE, Socket, SocketAddr}; use std::io; use wgctrl::InterfaceName; -fn if_nametoindex(interface: &InterfaceName) -> Result { +fn if_nametoindex(interface: &InterfaceName) -> Result { match unsafe { libc::if_nametoindex(interface.as_ptr()) } { - 0 => Err(anyhow!("couldn't find interface '{}'.", interface)), + 0 => Err(io::Error::new( + io::ErrorKind::NotFound, + format!("couldn't find interface '{}'.", interface), + )), index => Ok(index), } } @@ -52,7 +53,7 @@ fn netlink_call( Ok(response) } -pub fn set_up(interface: &InterfaceName, mtu: u32) -> Result<(), Error> { +pub fn set_up(interface: &InterfaceName, mtu: u32) -> Result<(), io::Error> { let index = if_nametoindex(interface)?; let message = LinkMessage { header: LinkHeader { @@ -66,7 +67,7 @@ pub fn set_up(interface: &InterfaceName, mtu: u32) -> Result<(), Error> { Ok(()) } -pub fn set_addr(interface: &InterfaceName, addr: IpNetwork) -> Result<(), Error> { +pub fn set_addr(interface: &InterfaceName, addr: IpNetwork) -> Result<(), io::Error> { let index = if_nametoindex(interface)?; let (family, nlas) = match addr { IpNetwork::V4(network) => { @@ -101,7 +102,7 @@ pub fn set_addr(interface: &InterfaceName, addr: IpNetwork) -> Result<(), Error> Ok(()) } -pub fn add_route(interface: &InterfaceName, cidr: IpNetwork) -> Result { +pub fn add_route(interface: &InterfaceName, cidr: IpNetwork) -> Result { let if_index = if_nametoindex(interface)?; let (address_family, dst) = match cidr { IpNetwork::V4(network) => (AF_INET as u8, network.network().octets().to_vec()), diff --git a/shared/src/wg.rs b/shared/src/wg.rs index 40386a4..cf4520a 100644 --- a/shared/src/wg.rs +++ b/shared/src/wg.rs @@ -1,10 +1,13 @@ use crate::{Error, IoErrorContext, NetworkOpt}; use ipnetwork::IpNetwork; -use std::net::{IpAddr, SocketAddr}; +use std::{ + io, + net::{IpAddr, SocketAddr}, +}; use wgctrl::{Backend, Device, DeviceUpdate, InterfaceName, PeerConfigBuilder}; #[cfg(target_os = "macos")] -fn cmd(bin: &str, args: &[&str]) -> Result { +fn cmd(bin: &str, args: &[&str]) -> Result { let output = std::process::Command::new(bin).args(args).output()?; log::debug!("cmd: {} {}", bin, args.join(" ")); log::debug!("status: {:?}", output.status.code()); @@ -13,19 +16,21 @@ fn cmd(bin: &str, args: &[&str]) -> Result { if output.status.success() { Ok(output) } else { - Err(anyhow::anyhow!( - "failed to run {} {} command: {}", - bin, - args.join(" "), - String::from_utf8_lossy(&output.stderr) + Err(io::Error::new( + io::ErrorKind::Other, + format!( + "failed to run {} {} command: {}", + bin, + args.join(" "), + String::from_utf8_lossy(&output.stderr) + ), )) } } #[cfg(target_os = "macos")] -pub fn set_addr(interface: &InterfaceName, addr: IpNetwork) -> Result<(), Error> { - let real_interface = - wgctrl::backends::userspace::resolve_tun(interface).with_str(interface.to_string())?; +pub fn set_addr(interface: &InterfaceName, addr: IpNetwork) -> Result<(), io::Error> { + let real_interface = wgctrl::backends::userspace::resolve_tun(interface)?; if addr.is_ipv4() { cmd( @@ -49,9 +54,8 @@ pub fn set_addr(interface: &InterfaceName, addr: IpNetwork) -> Result<(), Error> } #[cfg(target_os = "macos")] -pub fn set_up(interface: &InterfaceName, mtu: u32) -> Result<(), Error> { - let real_interface = - wgctrl::backends::userspace::resolve_tun(interface).with_str(interface.to_string())?; +pub fn set_up(interface: &InterfaceName, mtu: u32) -> Result<(), io::Error> { + let real_interface = wgctrl::backends::userspace::resolve_tun(interface)?; cmd("ifconfig", &[&real_interface, "mtu", &mtu.to_string()])?; Ok(()) } @@ -69,11 +73,17 @@ pub fn up( listen_port: Option, peer: Option<(&str, IpAddr, SocketAddr)>, network: NetworkOpt, -) -> Result<(), Error> { +) -> Result<(), io::Error> { let mut device = DeviceUpdate::new(); if let Some((public_key, address, endpoint)) = peer { let prefix = if address.is_ipv4() { 32 } else { 128 }; - let peer_config = PeerConfigBuilder::new(&wgctrl::Key::from_base64(&public_key)?) + let peer_config = + PeerConfigBuilder::new(&wgctrl::Key::from_base64(&public_key).map_err(|_| { + io::Error::new( + io::ErrorKind::InvalidInput, + "failed to parse base64 public key", + ) + })?) .add_allowed_ip(address, prefix) .set_endpoint(endpoint); device = device.add_peer(peer_config); @@ -85,7 +95,12 @@ pub fn up( .set_private_key(wgctrl::Key::from_base64(&private_key).unwrap()) .apply(interface, network.backend)?; set_addr(interface, address)?; - set_up(interface, network.mtu.unwrap_or_else(|| if address.is_ipv4() { 1420 } else { 1400 }))?; + set_up( + interface, + network + .mtu + .unwrap_or_else(|| if address.is_ipv4() { 1420 } else { 1400 }), + )?; if !network.no_routing { add_route(interface, address)?; } @@ -119,9 +134,8 @@ pub fn down(interface: &InterfaceName, backend: Backend) -> Result<(), Error> { /// Returns an error if the process doesn't exit successfully, otherwise returns /// true if the route was changed, false if the route already exists. #[cfg(target_os = "macos")] -pub fn add_route(interface: &InterfaceName, cidr: IpNetwork) -> Result { - let real_interface = - wgctrl::backends::userspace::resolve_tun(interface).with_str(interface.to_string())?; +pub fn add_route(interface: &InterfaceName, cidr: IpNetwork) -> Result { + let real_interface = wgctrl::backends::userspace::resolve_tun(interface)?; let output = cmd( "route", &[ @@ -135,11 +149,12 @@ pub fn add_route(interface: &InterfaceName, cidr: IpNetwork) -> Result