From 7491902b34278c0394be31c4f3f5fc81d6610e91 Mon Sep 17 00:00:00 2001 From: Drone CI Date: Tue, 19 Mar 2019 12:05:31 +0100 Subject: [PATCH] basic strcuture [CI SKIP] --- wg-event-gen/src/controller.rs | 52 +++++++++++++++++++--------- wg-event-gen/src/main.rs | 7 ++++ wg-event-gen/src/model.rs | 63 +++++++++++++++++++--------------- 3 files changed, 78 insertions(+), 44 deletions(-) diff --git a/wg-event-gen/src/controller.rs b/wg-event-gen/src/controller.rs index ecff9c1..2cff8fb 100644 --- a/wg-event-gen/src/controller.rs +++ b/wg-event-gen/src/controller.rs @@ -1,6 +1,9 @@ -use crate::model::WireguardController; +use crate::model::{ECCKey, Peer, PeerBuilder, WireguardController}; +use std::io::{BufRead, BufReader, Result, Write}; +use std::net::{IpAddr, SocketAddr}; use std::os::unix::net::UnixStream; use std::path::PathBuf; +use std::time::Duration; pub struct Userspace(PathBuf); @@ -11,36 +14,50 @@ impl Userspace { } impl WireguardController for Userspace { - fn peers<'a>(&'a mut self) -> Box> + 'a> { + fn peers<'a>(&'a mut self) -> Result> + 'a>> { let mut stream = UnixStream::connect(&self.0)?; stream.write_all(b"get=1\n")?; - fn build_peer(builder: &mut PeerBuilder, line: String) -> Result<()> { + fn build_peer(builder: &mut PeerBuilder, line: io::Result) -> Option> { let line = line?; let mut iter = line.chars(); let key = iter.by_ref().take_while(|c| c != &'=').collect::(); let value = iter.collect::(); - let mut allowed_ips: Vec<(IpAddr, u8)> = Vec::new(); - let mut last_handshake: Option = None; + let mut ips: Vec<(IpAddr, u8)> = Vec::with_capacity(0); + if builder.allowed_ips.len() > 1 { + ips.append(&builder.allowed_ips); + } let update_handshake = |d: Duration| { - last_handshake = last_handshake.map(|c| c + d); + builder.last_handshake(last_handshake.map(|c| c + d)); + }; + let value_as_num = || value.parse::(); + let mut peer: Option = None; + let add_key = |key| { + if builder.key.is_some() { + //If next entry begins + peer = Some(builder.build().map_err(|err: String| { + io::Error::new(ErrorKind::InvalidData, err.into()) + })?); + *builder = PeerBuilder::default(); + } + builder.key(key); }; match key.as_ref() { - "public_key" => builder.key(ECCKey::from_base64(value)?), - "private_key" => builder.key(ECCKey::from_base64(value)?), - "endpoint" => builder.endpoint(value::parse::()?), + "public_key" => add_key(ECCKey::from_base64(value)?), + "private_key" => add_key(ECCKey::from_base64(value)?), + "endpoint" => builder.endpoint(value.parse::()?), "last_handshake_time_sec" => { - update_handshake(Duration::from_secs(value::parse::().into())) + update_handshake(Duration::from_secs(value_as_num().into())); } "last_handshake_time_nsec" => { - update_handshake(Duration::from_nsecs(value::parse::().into())) + update_handshake(Duration::from_nanos(value_as_num().into())); } "persistent_keepalive" => { - builder.keepalive(Duration::from_secs(value::parse::().into())) + builder.persistent_keepalive(Some(Duration::from_secs(value_as_num().into()))); } "allowed_ip" => { let mut parts = value.split("/").into_iter(); - let ip = match ( + let net = match ( parts.next().and_then(|addr| addr.parse::().ok()), parts.next().and_then(|mask| mask.parse::().ok()), ) { @@ -49,17 +66,18 @@ impl WireguardController for Userspace { (Some(addr), None) => Some((addr, 32)), _ => None, }; - ips.push(ip); + if let Some(net) = net { + builder.allowed_ips.map(|ips| ips.push(net)); + } } } - builder.allowed_ips(ips); - builder.last_handshake(last_handshake); + peer.map(|peer| Ok(peer)) } let peers = BufReader::new(stream) .lines() .scan(PeerBuilder::default(), build_peer); - loop {} + Ok(Box::new(peers)) } fn update_peer(&mut self, peer: &Peer) -> Result<()> { diff --git a/wg-event-gen/src/main.rs b/wg-event-gen/src/main.rs index 9c4ad6f..c979a28 100644 --- a/wg-event-gen/src/main.rs +++ b/wg-event-gen/src/main.rs @@ -1,4 +1,11 @@ +#[macro_use] +extern crate structopt; + +#[macro_use] +extern crate derive_builder; + mod controller; +mod model; use controller::Userspace; diff --git a/wg-event-gen/src/model.rs b/wg-event-gen/src/model.rs index 2c2390a..e01d7db 100644 --- a/wg-event-gen/src/model.rs +++ b/wg-event-gen/src/model.rs @@ -1,47 +1,56 @@ -#[macro_use] -extern crate structopt; +use base64::decode; +use std::error::Error; +use std::io; +use std::net::{IpAddr, SocketAddr}; +use std::time::Duration; +use std::time::Instant; - - #[macro_use] - extern crate derive_builder; - - -use std::io::Result; -use base64::{decode}; - -pub enum ECCKey{ - PublicKey([u8; 32]), - PrivateKey([u8; 32]) +#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)] +pub enum ECCKey { + PublicKey([u8; 32]), + PrivateKey([u8; 32]), } impl ECCKey { - fn from_base64>(key: I) -> Result { - let key = decode(key.as_ref::())?; - let bytes = [0; 32]; - bytes.copy_from_slice(key); - ECCKey::PublicKey(bytes) - } + pub fn from_base64>(key: I) -> io::Result { + let key = decode(key.as_ref()).map_err(|err| { + io::Error::new(io::ErrorKind::InvalidData, "Failed to decode base64".into()) + })?; + let bytes = [0; 32]; + if key.len() != 32 { + return Err(io::Error::new( + io::ErrorKind::Other, + "Mismatched key size".into(), + )); + } + bytes.copy_from_slice(&key); + Ok(ECCKey::PublicKey(bytes)) + } } +#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)] struct SharedKey([u8; 32]); -#[derive(Debug,Builder, PartialEq, Eq, Hash, Clone)] +#[derive(Debug, Builder, PartialEq, Eq, Hash, Clone)] +#[builder(public)] pub struct Peer { key: ECCKey, + #[builder(default = "None")] shared_key: Option, + #[builder(default = "None")] endpoint: Option, allowed_ips: Vec<(IpAddr, u8)>, last_handshake: Option, + #[builder(default = "None")] persistent_keepalive: Option, + #[builder(default = "(0u64,0u64)")] traffic: (u64, u64), - parsed: time::Timespec, + #[builder(default = "Instant::now()")] + parsed: Instant, } +pub trait WireguardController { + fn peers<'a>(&'a mut self) -> io::Result> + 'a>>; -trait WireguardController { - - fn peers<'a>(&'a mut self) -> Box> + 'a>; - - fn update_peer(&mut self, peer: &Peer) -> Result<()>; - + fn update_peer(&mut self, peer: &Peer) -> io::Result<()>; }