diff options
author | Mathias Hall-Andersen <mathias@hall-andersen.dk> | 2019-11-17 19:52:40 +0100 |
---|---|---|
committer | Mathias Hall-Andersen <mathias@hall-andersen.dk> | 2019-11-17 19:52:40 +0100 |
commit | 64707b0471b5efe06ac2c93e350676d9d4049b72 (patch) | |
tree | 04276f7085fa90e4470986da1d66ce44faa4b24d /src/configuration | |
parent | Update UAPI semantics for remove (diff) | |
download | wireguard-rs-64707b0471b5efe06ac2c93e350676d9d4049b72.tar.xz wireguard-rs-64707b0471b5efe06ac2c93e350676d9d4049b72.zip |
Update configuration API
Diffstat (limited to 'src/configuration')
-rw-r--r-- | src/configuration/config.rs | 105 | ||||
-rw-r--r-- | src/configuration/uapi/get.rs | 5 | ||||
-rw-r--r-- | src/configuration/uapi/mod.rs | 7 | ||||
-rw-r--r-- | src/configuration/uapi/set.rs | 13 |
4 files changed, 61 insertions, 69 deletions
diff --git a/src/configuration/config.rs b/src/configuration/config.rs index 50fdfb8..e50aeb6 100644 --- a/src/configuration/config.rs +++ b/src/configuration/config.rs @@ -10,6 +10,9 @@ use bind::Owner; /// The goal of the configuration interface is, among others, /// to hide the IO implementations (over which the WG device is generic), /// from the configuration and UAPI code. +/// +/// Furthermore it forms the simpler interface for embedding WireGuard in other applications, +/// and hides the complex types of the implementation from the host application. /// Describes a snapshot of the state of a peer pub struct PeerState { @@ -24,6 +27,7 @@ pub struct PeerState { pub struct WireguardConfig<T: tun::Tun, B: bind::PlatformBind> { wireguard: Wireguard<T, B>, + fwmark: Mutex<Option<u32>>, network: Mutex<Option<B::Owner>>, } @@ -31,6 +35,7 @@ impl<T: tun::Tun, B: bind::PlatformBind> WireguardConfig<T, B> { pub fn new(wg: Wireguard<T, B>) -> WireguardConfig<T, B> { WireguardConfig { wireguard: wg, + fwmark: Mutex::new(None), network: Mutex::new(None), } } @@ -59,7 +64,7 @@ pub trait Configuration { /// An integer indicating the protocol version fn get_protocol_version(&self) -> usize; - fn set_listen_port(&self, port: Option<u16>) -> Option<ConfigError>; + fn set_listen_port(&self, port: Option<u16>) -> Result<(), ConfigError>; /// Set the firewall mark (or similar, depending on platform) /// @@ -71,7 +76,7 @@ pub trait Configuration { /// /// An error if this operation is not supported by the underlying /// "bind" implementation. - fn set_fwmark(&self, mark: Option<u32>) -> Option<ConfigError>; + fn set_fwmark(&self, mark: Option<u32>) -> Result<(), ConfigError>; /// Removes all peers from the device fn replace_peers(&self); @@ -110,7 +115,7 @@ pub trait Configuration { /// # Returns /// /// An error if no such peer exists - fn set_preshared_key(&self, peer: &PublicKey, psk: [u8; 32]) -> Option<ConfigError>; + fn set_preshared_key(&self, peer: &PublicKey, psk: [u8; 32]); /// Update the endpoint of the /// @@ -118,7 +123,7 @@ pub trait Configuration { /// /// - `peer': The public key of the peer /// - `psk` - fn set_endpoint(&self, peer: &PublicKey, addr: SocketAddr) -> Option<ConfigError>; + fn set_endpoint(&self, peer: &PublicKey, addr: SocketAddr); /// Update the endpoint of the /// @@ -126,8 +131,7 @@ pub trait Configuration { /// /// - `peer': The public key of the peer /// - `psk` - fn set_persistent_keepalive_interval(&self, peer: &PublicKey, secs: u64) - -> Option<ConfigError>; + fn set_persistent_keepalive_interval(&self, peer: &PublicKey, secs: u64); /// Remove all allowed IPs from the peer /// @@ -138,7 +142,7 @@ pub trait Configuration { /// # Returns /// /// An error if no such peer exists - fn replace_allowed_ips(&self, peer: &PublicKey) -> Option<ConfigError>; + fn replace_allowed_ips(&self, peer: &PublicKey); /// Add a new allowed subnet to the peer /// @@ -151,12 +155,7 @@ pub trait Configuration { /// # Returns /// /// An error if the peer does not exist - /// - /// # Note: - /// - /// The API must itself sanitize the (ip, masklen) set: - /// The ip should be masked to remove any set bits right of the first "masklen" bits. - fn add_allowed_ip(&self, peer: &PublicKey, ip: IpAddr, masklen: u32) -> Option<ConfigError>; + fn add_allowed_ip(&self, peer: &PublicKey, ip: IpAddr, masklen: u32); fn get_listen_port(&self) -> Option<u16>; @@ -191,10 +190,14 @@ impl<T: tun::Tun, B: bind::PlatformBind> Configuration for WireguardConfig<T, B> } fn get_listen_port(&self) -> Option<u16> { - self.network.lock().as_ref().map(|bind| bind.get_port()) + let bind = self.network.lock(); + log::trace!("Config, Get listen port, bound: {}", bind.is_some()); + bind.as_ref().map(|bind| bind.get_port()) } - fn set_listen_port(&self, port: Option<u16>) -> Option<ConfigError> { + fn set_listen_port(&self, port: Option<u16>) -> Result<(), ConfigError> { + log::trace!("Config, Set listen port: {:?}", port); + let mut bind = self.network.lock(); // close the current listener @@ -203,13 +206,16 @@ impl<T: tun::Tun, B: bind::PlatformBind> Configuration for WireguardConfig<T, B> // bind to new port if let Some(port) = port { // create new listener - let (mut readers, writer, owner) = match B::bind(port) { + let (mut readers, writer, mut owner) = match B::bind(port) { Ok(r) => r, Err(_) => { - return Some(ConfigError::FailedToBind); + return Err(ConfigError::FailedToBind); } }; + // set fwmark + let _ = owner.set_fwmark(*self.fwmark.lock()); // TODO: handle + // add readers/writer to wireguard self.wireguard.set_writer(writer); while let Some(reader) = readers.pop() { @@ -220,16 +226,18 @@ impl<T: tun::Tun, B: bind::PlatformBind> Configuration for WireguardConfig<T, B> *bind = Some(owner); } - None + Ok(()) } - fn set_fwmark(&self, mark: Option<u32>) -> Option<ConfigError> { + fn set_fwmark(&self, mark: Option<u32>) -> Result<(), ConfigError> { + log::trace!("Config, Set fwmark: {:?}", mark); + match self.network.lock().as_mut() { Some(bind) => { bind.set_fwmark(mark).unwrap(); // TODO: handle - None + Ok(()) } - None => Some(ConfigError::NotListening), + None => Err(ConfigError::NotListening), } } @@ -242,59 +250,34 @@ impl<T: tun::Tun, B: bind::PlatformBind> Configuration for WireguardConfig<T, B> } fn add_peer(&self, peer: &PublicKey) -> bool { - self.wireguard.add_peer(*peer); - false + self.wireguard.add_peer(*peer) } - fn set_preshared_key(&self, peer: &PublicKey, psk: [u8; 32]) -> Option<ConfigError> { - if self.wireguard.set_psk(*peer, psk) { - None - } else { - Some(ConfigError::NoSuchPeer) - } + fn set_preshared_key(&self, peer: &PublicKey, psk: [u8; 32]) { + self.wireguard.set_psk(*peer, psk); } - fn set_endpoint(&self, peer: &PublicKey, addr: SocketAddr) -> Option<ConfigError> { - match self.wireguard.lookup_peer(peer) { - Some(peer) => { - peer.router.set_endpoint(B::Endpoint::from_address(addr)); - None - } - None => Some(ConfigError::NoSuchPeer), + fn set_endpoint(&self, peer: &PublicKey, addr: SocketAddr) { + if let Some(peer) = self.wireguard.lookup_peer(peer) { + peer.router.set_endpoint(B::Endpoint::from_address(addr)); } } - fn set_persistent_keepalive_interval( - &self, - peer: &PublicKey, - secs: u64, - ) -> Option<ConfigError> { - match self.wireguard.lookup_peer(peer) { - Some(peer) => { - peer.set_persistent_keepalive_interval(secs); - None - } - None => Some(ConfigError::NoSuchPeer), + fn set_persistent_keepalive_interval(&self, peer: &PublicKey, secs: u64) { + if let Some(peer) = self.wireguard.lookup_peer(peer) { + peer.set_persistent_keepalive_interval(secs); } } - fn replace_allowed_ips(&self, peer: &PublicKey) -> Option<ConfigError> { - match self.wireguard.lookup_peer(peer) { - Some(peer) => { - peer.router.remove_allowed_ips(); - None - } - None => Some(ConfigError::NoSuchPeer), + fn replace_allowed_ips(&self, peer: &PublicKey) { + if let Some(peer) = self.wireguard.lookup_peer(peer) { + peer.router.remove_allowed_ips(); } } - fn add_allowed_ip(&self, peer: &PublicKey, ip: IpAddr, masklen: u32) -> Option<ConfigError> { - match self.wireguard.lookup_peer(peer) { - Some(peer) => { - peer.router.add_allowed_ip(ip, masklen); - None - } - None => Some(ConfigError::NoSuchPeer), + fn add_allowed_ip(&self, peer: &PublicKey, ip: IpAddr, masklen: u32) { + if let Some(peer) = self.wireguard.lookup_peer(peer) { + peer.router.add_allowed_ip(ip, masklen); } } diff --git a/src/configuration/uapi/get.rs b/src/configuration/uapi/get.rs index 0874cfc..43d4735 100644 --- a/src/configuration/uapi/get.rs +++ b/src/configuration/uapi/get.rs @@ -1,10 +1,7 @@ -use hex::FromHex; -use subtle::ConstantTimeEq; - use log; +use std::io; use super::Configuration; -use std::io; pub fn serialize<C: Configuration, W: io::Write>(writer: &mut W, config: &C) -> io::Result<()> { let mut write = |key: &'static str, value: String| { diff --git a/src/configuration/uapi/mod.rs b/src/configuration/uapi/mod.rs index 4261e7d..3cb88c0 100644 --- a/src/configuration/uapi/mod.rs +++ b/src/configuration/uapi/mod.rs @@ -55,10 +55,13 @@ pub fn handle<S: Read + Write, C: Configuration>(stream: &mut S, config: &C) { loop { let ln = readline(stream)?; if ln == "" { + // end of transcript + parser.parse_line("", "")?; // flush final peer break Ok(()); + } else { + let (k, v) = keypair(ln.as_str())?; + parser.parse_line(k, v)?; }; - let (k, v) = keypair(ln.as_str())?; - parser.parse_line(k, v)?; } } _ => Err(ConfigError::InvalidOperation), diff --git a/src/configuration/uapi/set.rs b/src/configuration/uapi/set.rs index e449edd..882e4a7 100644 --- a/src/configuration/uapi/set.rs +++ b/src/configuration/uapi/set.rs @@ -109,7 +109,7 @@ impl<'a, C: Configuration> LineParser<'a, C> { // opt: set listen port "listen_port" => match value.parse() { Ok(port) => { - self.config.set_listen_port(Some(port)); + self.config.set_listen_port(Some(port))?; Ok(()) } Err(_) => Err(ConfigError::InvalidPortNumber), @@ -119,7 +119,7 @@ impl<'a, C: Configuration> LineParser<'a, C> { "fwmark" => match value.parse() { Ok(fwmark) => { self.config - .set_fwmark(if fwmark == 0 { None } else { Some(fwmark) }); + .set_fwmark(if fwmark == 0 { None } else { Some(fwmark) })?; Ok(()) } Err(_) => Err(ConfigError::InvalidFwmark), @@ -142,6 +142,9 @@ impl<'a, C: Configuration> LineParser<'a, C> { Ok(()) } + // ignore (end of transcript) + "" => Ok(()), + // unknown key _ => Err(ConfigError::InvalidKey), }, @@ -227,6 +230,12 @@ impl<'a, C: Configuration> LineParser<'a, C> { } } + // flush (used at end of transcipt) + "" => { + flush_peer(self.config, &peer); + Ok(()) + } + // unknown key _ => Err(ConfigError::InvalidKey), }, |