basic strcuture [CI SKIP]
This commit is contained in:
parent
fc494fe4c0
commit
7491902b34
@ -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::os::unix::net::UnixStream;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
pub struct Userspace(PathBuf);
|
pub struct Userspace(PathBuf);
|
||||||
|
|
||||||
@ -11,36 +14,50 @@ impl Userspace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl WireguardController for Userspace {
|
impl WireguardController for Userspace {
|
||||||
fn peers<'a>(&'a mut self) -> Box<Iterator<Item = Result<Peer>> + 'a> {
|
fn peers<'a>(&'a mut self) -> Result<Box<Iterator<Item = Result<Peer>> + 'a>> {
|
||||||
let mut stream = UnixStream::connect(&self.0)?;
|
let mut stream = UnixStream::connect(&self.0)?;
|
||||||
stream.write_all(b"get=1\n")?;
|
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<String>) -> Option<Result<Peer>> {
|
||||||
let line = line?;
|
let line = line?;
|
||||||
let mut iter = line.chars();
|
let mut iter = line.chars();
|
||||||
let key = iter.by_ref().take_while(|c| c != &'=').collect::<String>();
|
let key = iter.by_ref().take_while(|c| c != &'=').collect::<String>();
|
||||||
let value = iter.collect::<String>();
|
let value = iter.collect::<String>();
|
||||||
let mut allowed_ips: Vec<(IpAddr, u8)> = Vec::new();
|
let mut ips: Vec<(IpAddr, u8)> = Vec::with_capacity(0);
|
||||||
let mut last_handshake: Option<Duration> = None;
|
if builder.allowed_ips.len() > 1 {
|
||||||
|
ips.append(&builder.allowed_ips);
|
||||||
|
}
|
||||||
let update_handshake = |d: Duration| {
|
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::<usize>();
|
||||||
|
let mut peer: Option<Peer> = 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() {
|
match key.as_ref() {
|
||||||
"public_key" => builder.key(ECCKey::from_base64(value)?),
|
"public_key" => add_key(ECCKey::from_base64(value)?),
|
||||||
"private_key" => builder.key(ECCKey::from_base64(value)?),
|
"private_key" => add_key(ECCKey::from_base64(value)?),
|
||||||
"endpoint" => builder.endpoint(value::parse::<SocketAddr>()?),
|
"endpoint" => builder.endpoint(value.parse::<SocketAddr>()?),
|
||||||
"last_handshake_time_sec" => {
|
"last_handshake_time_sec" => {
|
||||||
update_handshake(Duration::from_secs(value::parse::<usize>().into()))
|
update_handshake(Duration::from_secs(value_as_num().into()));
|
||||||
}
|
}
|
||||||
"last_handshake_time_nsec" => {
|
"last_handshake_time_nsec" => {
|
||||||
update_handshake(Duration::from_nsecs(value::parse::<usize>().into()))
|
update_handshake(Duration::from_nanos(value_as_num().into()));
|
||||||
}
|
}
|
||||||
"persistent_keepalive" => {
|
"persistent_keepalive" => {
|
||||||
builder.keepalive(Duration::from_secs(value::parse::<usize>().into()))
|
builder.persistent_keepalive(Some(Duration::from_secs(value_as_num().into())));
|
||||||
}
|
}
|
||||||
"allowed_ip" => {
|
"allowed_ip" => {
|
||||||
let mut parts = value.split("/").into_iter();
|
let mut parts = value.split("/").into_iter();
|
||||||
let ip = match (
|
let net = match (
|
||||||
parts.next().and_then(|addr| addr.parse::<IpAddr>().ok()),
|
parts.next().and_then(|addr| addr.parse::<IpAddr>().ok()),
|
||||||
parts.next().and_then(|mask| mask.parse::<u8>().ok()),
|
parts.next().and_then(|mask| mask.parse::<u8>().ok()),
|
||||||
) {
|
) {
|
||||||
@ -49,17 +66,18 @@ impl WireguardController for Userspace {
|
|||||||
(Some(addr), None) => Some((addr, 32)),
|
(Some(addr), None) => Some((addr, 32)),
|
||||||
_ => None,
|
_ => 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)
|
let peers = BufReader::new(stream)
|
||||||
.lines()
|
.lines()
|
||||||
.scan(PeerBuilder::default(), build_peer);
|
.scan(PeerBuilder::default(), build_peer);
|
||||||
loop {}
|
Ok(Box::new(peers))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_peer(&mut self, peer: &Peer) -> Result<()> {
|
fn update_peer(&mut self, peer: &Peer) -> Result<()> {
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
|
#[macro_use]
|
||||||
|
extern crate structopt;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate derive_builder;
|
||||||
|
|
||||||
mod controller;
|
mod controller;
|
||||||
|
mod model;
|
||||||
|
|
||||||
use controller::Userspace;
|
use controller::Userspace;
|
||||||
|
|
||||||
|
@ -1,47 +1,56 @@
|
|||||||
#[macro_use]
|
use base64::decode;
|
||||||
extern crate structopt;
|
use std::error::Error;
|
||||||
|
use std::io;
|
||||||
|
use std::net::{IpAddr, SocketAddr};
|
||||||
|
use std::time::Duration;
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
||||||
#[macro_use]
|
pub enum ECCKey {
|
||||||
extern crate derive_builder;
|
|
||||||
|
|
||||||
|
|
||||||
use std::io::Result;
|
|
||||||
use base64::{decode};
|
|
||||||
|
|
||||||
pub enum ECCKey{
|
|
||||||
PublicKey([u8; 32]),
|
PublicKey([u8; 32]),
|
||||||
PrivateKey([u8; 32])
|
PrivateKey([u8; 32]),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ECCKey {
|
impl ECCKey {
|
||||||
fn from_base64<I: AsRef<str>>(key: I) -> Result<ECCKey> {
|
pub fn from_base64<I: AsRef<str>>(key: I) -> io::Result<ECCKey> {
|
||||||
let key = decode(key.as_ref::<str>())?;
|
let key = decode(key.as_ref()).map_err(|err| {
|
||||||
|
io::Error::new(io::ErrorKind::InvalidData, "Failed to decode base64".into())
|
||||||
|
})?;
|
||||||
let bytes = [0; 32];
|
let bytes = [0; 32];
|
||||||
bytes.copy_from_slice(key);
|
if key.len() != 32 {
|
||||||
ECCKey::PublicKey(bytes)
|
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]);
|
struct SharedKey([u8; 32]);
|
||||||
|
|
||||||
#[derive(Debug,Builder, PartialEq, Eq, Hash, Clone)]
|
#[derive(Debug, Builder, PartialEq, Eq, Hash, Clone)]
|
||||||
|
#[builder(public)]
|
||||||
pub struct Peer {
|
pub struct Peer {
|
||||||
key: ECCKey,
|
key: ECCKey,
|
||||||
|
#[builder(default = "None")]
|
||||||
shared_key: Option<SharedKey>,
|
shared_key: Option<SharedKey>,
|
||||||
|
#[builder(default = "None")]
|
||||||
endpoint: Option<SocketAddr>,
|
endpoint: Option<SocketAddr>,
|
||||||
allowed_ips: Vec<(IpAddr, u8)>,
|
allowed_ips: Vec<(IpAddr, u8)>,
|
||||||
last_handshake: Option<Duration>,
|
last_handshake: Option<Duration>,
|
||||||
|
#[builder(default = "None")]
|
||||||
persistent_keepalive: Option<Duration>,
|
persistent_keepalive: Option<Duration>,
|
||||||
|
#[builder(default = "(0u64,0u64)")]
|
||||||
traffic: (u64, u64),
|
traffic: (u64, u64),
|
||||||
parsed: time::Timespec,
|
#[builder(default = "Instant::now()")]
|
||||||
|
parsed: Instant,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait WireguardController {
|
||||||
|
fn peers<'a>(&'a mut self) -> io::Result<Box<Iterator<Item = io::Result<Peer>> + 'a>>;
|
||||||
|
|
||||||
trait WireguardController {
|
fn update_peer(&mut self, peer: &Peer) -> io::Result<()>;
|
||||||
|
|
||||||
fn peers<'a>(&'a mut self) -> Box<Iterator<Item=Result<Peer>> + 'a>;
|
|
||||||
|
|
||||||
fn update_peer(&mut self, peer: &Peer) -> Result<()>;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user