summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMathias Hall-Andersen <mathias@hall-andersen.dk>2019-11-11 23:13:46 +0100
committerMathias Hall-Andersen <mathias@hall-andersen.dk>2019-11-11 23:13:46 +0100
commit5b555a2e176bd5310d2efa614f67c96cb314eda4 (patch)
treeb79cb04b38e052fb8ed63d7212020a1c8a31b6f2 /src
parentImplemented UAPI "get" line-parser (diff)
downloadwireguard-rs-5b555a2e176bd5310d2efa614f67c96cb314eda4.tar.xz
wireguard-rs-5b555a2e176bd5310d2efa614f67c96cb314eda4.zip
Work on UAPI serialize device
Diffstat (limited to 'src')
-rw-r--r--src/configuration/config.rs18
-rw-r--r--src/configuration/uapi/get.rs41
-rw-r--r--src/configuration/uapi/mod.rs45
-rw-r--r--src/configuration/uapi/set.rs21
-rw-r--r--src/wireguard/handshake/device.rs2
-rw-r--r--src/wireguard/wireguard.rs3
6 files changed, 113 insertions, 17 deletions
diff --git a/src/configuration/config.rs b/src/configuration/config.rs
index ed78e43..b1c0121 100644
--- a/src/configuration/config.rs
+++ b/src/configuration/config.rs
@@ -19,6 +19,7 @@ pub struct PeerState {
pub last_handshake_time_nsec: u64,
pub public_key: PublicKey,
pub allowed_ips: Vec<(IpAddr, u32)>,
+ pub preshared_key: Option<[u8; 32]>,
}
pub struct WireguardConfig<T: tun::Tun, B: bind::Platform> {
@@ -157,15 +158,26 @@ pub trait Configuration {
/// 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 get_listen_port(&self) -> Option<u16>;
+
/// Returns the state of all peers
///
/// # Returns
///
/// A list of structures describing the state of each peer
fn get_peers(&self) -> Vec<PeerState>;
+
+ fn get_fwmark(&self) -> Option<u32>;
}
impl<T: tun::Tun, B: bind::Platform> Configuration for WireguardConfig<T, B> {
+ fn get_fwmark(&self) -> Option<u32> {
+ self.network
+ .lock()
+ .as_ref()
+ .and_then(|bind| bind.get_fwmark())
+ }
+
fn set_private_key(&self, sk: Option<StaticSecret>) {
self.wireguard.set_key(sk)
}
@@ -178,6 +190,10 @@ impl<T: tun::Tun, B: bind::Platform> Configuration for WireguardConfig<T, B> {
1
}
+ fn get_listen_port(&self) -> Option<u16> {
+ self.network.lock().as_ref().map(|bind| bind.get_port())
+ }
+
fn set_listen_port(&self, port: Option<u16>) -> Option<ConfigError> {
let mut bind = self.network.lock();
@@ -285,6 +301,7 @@ impl<T: tun::Tun, B: bind::Platform> Configuration for WireguardConfig<T, B> {
fn get_peers(&self) -> Vec<PeerState> {
let peers = self.wireguard.list_peers();
let mut state = Vec::with_capacity(peers.len());
+
for p in peers {
// convert the system time to (secs, nano) since epoch
let last_handshake = (*p.walltime_last_handshake.lock())
@@ -293,6 +310,7 @@ impl<T: tun::Tun, B: bind::Platform> Configuration for WireguardConfig<T, B> {
// extract state into PeerState
state.push(PeerState {
+ preshared_key: self.wireguard.get_psk(&p.pk),
rx_bytes: p.rx_bytes.load(Ordering::Relaxed),
tx_bytes: p.tx_bytes.load(Ordering::Relaxed),
allowed_ips: p.router.list_allowed_ips(),
diff --git a/src/configuration/uapi/get.rs b/src/configuration/uapi/get.rs
index c6f3c42..99ebbde 100644
--- a/src/configuration/uapi/get.rs
+++ b/src/configuration/uapi/get.rs
@@ -10,6 +10,45 @@ struct Serializer<C: Configuration> {
impl<C: Configuration> Serializer<C> {
fn get(&self) -> Vec<String> {
- vec![]
+ let mut peers = self.config.get_peers();
+ let mut lines = Vec::with_capacity(peers.len() * 6 + 5);
+ let mut write = |key, value: String| {
+ lines.push(String::new() + key + "=" + &value);
+ };
+
+ // serialize interface
+ self.config
+ .get_private_key()
+ .map(|sk| write("private_key", hex::encode(sk.to_bytes())));
+
+ self.config
+ .get_listen_port()
+ .map(|port| write("listen_port", port.to_string()));
+
+ self.config
+ .get_fwmark()
+ .map(|fwmark| write("fwmark", fwmark.to_string()));
+
+ // serialize all peers
+ while let Some(p) = peers.pop() {
+ write("rx_bytes", p.rx_bytes.to_string());
+ write("tx_bytes", p.tx_bytes.to_string());
+ write(
+ "last_handshake_time_sec",
+ p.last_handshake_time_nsec.to_string(),
+ );
+ write(
+ "last_handshake_time_nsec",
+ p.last_handshake_time_nsec.to_string(),
+ );
+ write("public_key", hex::encode(p.public_key.as_bytes()));
+ p.preshared_key
+ .map(|psk| write("preshared_key", hex::encode(psk)));
+ for (ip, cidr) in p.allowed_ips {
+ write("allowed_ip", ip.to_string() + "/" + &cidr.to_string())
+ }
+ }
+
+ lines
}
}
diff --git a/src/configuration/uapi/mod.rs b/src/configuration/uapi/mod.rs
index 5d89b94..cba156d 100644
--- a/src/configuration/uapi/mod.rs
+++ b/src/configuration/uapi/mod.rs
@@ -1,4 +1,49 @@
mod get;
mod set;
+use std::io::{Read, Write};
+
use super::{ConfigError, Configuration};
+
+const MAX_LINE_LENGTH: usize = 128;
+
+struct Parser<C: Configuration, R: Read, W: Write> {
+ config: C,
+ reader: R,
+ writer: W,
+}
+
+impl<C: Configuration, R: Read, W: Write> Parser<C, R, W> {
+ fn new(&self, reader: R, writer: W, config: C) -> Parser<C, R, W> {
+ Parser {
+ config,
+ reader,
+ writer,
+ }
+ }
+
+ fn parse(&mut self) -> Option<()> {
+ // read string up to maximum length (why is this not in std?)
+ let mut line = || {
+ let mut m: [u8; 1] = [0u8];
+ let mut l: String = String::with_capacity(MAX_LINE_LENGTH);
+ while let Ok(_) = self.reader.read_exact(&mut m) {
+ let c = m[0] as char;
+ if c == '\n' {
+ return Some(l);
+ };
+ l.push(c);
+ if l.len() > MAX_LINE_LENGTH {
+ break;
+ }
+ }
+ None
+ };
+
+ match line()?.as_str() {
+ "get=1" => Some(()),
+ "set=1" => Some(()),
+ _ => None,
+ }
+ }
+}
diff --git a/src/configuration/uapi/set.rs b/src/configuration/uapi/set.rs
index 575c7ad..c609d83 100644
--- a/src/configuration/uapi/set.rs
+++ b/src/configuration/uapi/set.rs
@@ -7,8 +7,8 @@ use super::{ConfigError, Configuration};
#[derive(Copy, Clone)]
enum ParserState {
Peer {
- public_key: PublicKey, // peer identity
- update_only: bool, // is the update_only flag set
+ public_key: PublicKey,
+ update_only: bool,
},
Interface,
}
@@ -18,10 +18,6 @@ struct LineParser<C: Configuration> {
state: ParserState,
}
-struct Serializer<C: Configuration> {
- config: C,
-}
-
impl<C: Configuration> LineParser<C> {
fn new_peer(value: &str) -> Result<ParserState, ConfigError> {
match <[u8; 32]>::from_hex(value) {
@@ -34,6 +30,7 @@ impl<C: Configuration> LineParser<C> {
}
fn parse_line(&mut self, key: &str, value: &str) -> Option<ConfigError> {
+ // add the peer if not update_only
let flush_peer = |st: ParserState| -> ParserState {
match st {
ParserState::Peer {
@@ -51,7 +48,7 @@ impl<C: Configuration> LineParser<C> {
};
// parse line and update parser state
- let new_state = match self.state {
+ match self.state {
// configure the interface
ParserState::Interface => match key {
// opt: set private key
@@ -202,14 +199,8 @@ impl<C: Configuration> LineParser<C> {
// unknown key
_ => Err(ConfigError::InvalidKey),
},
- };
-
- match new_state {
- Err(e) => Some(e),
- Ok(st) => {
- self.state = st;
- None
- }
}
+ .map(|st| self.state = st)
+ .err()
}
}
diff --git a/src/wireguard/handshake/device.rs b/src/wireguard/handshake/device.rs
index 85c2e45..f65692c 100644
--- a/src/wireguard/handshake/device.rs
+++ b/src/wireguard/handshake/device.rs
@@ -202,7 +202,7 @@ impl Device {
/// A 32 byte array holding the PSK
///
/// The call might fail if the public key is not found
- pub fn get_psk(&self, pk: PublicKey) -> Result<Psk, ConfigError> {
+ pub fn get_psk(&self, pk: &PublicKey) -> Result<Psk, ConfigError> {
match self.pk_map.get(pk.as_bytes()) {
Some(peer) => Ok(peer.psk),
_ => Err(ConfigError::new("No such public key")),
diff --git a/src/wireguard/wireguard.rs b/src/wireguard/wireguard.rs
index a890d5e..77be9f8 100644
--- a/src/wireguard/wireguard.rs
+++ b/src/wireguard/wireguard.rs
@@ -204,6 +204,9 @@ impl<T: Tun, B: Bind> Wireguard<T, B> {
pub fn set_psk(&self, pk: PublicKey, psk: Option<[u8; 32]>) -> bool {
self.state.handshake.write().set_psk(pk, psk).is_ok()
}
+ pub fn get_psk(&self, pk: &PublicKey) -> Option<[u8; 32]> {
+ self.state.handshake.read().get_psk(pk).ok()
+ }
pub fn add_peer(&self, pk: PublicKey) {
if self.state.peers.read().contains_key(pk.as_bytes()) {