WIP [CI SKIP]
This commit is contained in:
parent
22dd07cc14
commit
fc494fe4c0
82
wg-event-gen/Cargo.lock
generated
82
wg-event-gen/Cargo.lock
generated
@ -48,6 +48,65 @@ dependencies = [
|
|||||||
"vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling"
|
||||||
|
version = "0.8.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"darling_core 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"darling_macro 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling_core"
|
||||||
|
version = "0.8.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ident_case 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling_macro"
|
||||||
|
version = "0.8.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"darling_core 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "derive_builder"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"darling 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"derive_builder_core 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "derive_builder_core"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"darling 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fnv"
|
||||||
|
version = "1.0.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
@ -61,6 +120,11 @@ name = "hex"
|
|||||||
version = "0.3.2"
|
version = "0.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ident_case"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.47"
|
version = "0.2.47"
|
||||||
@ -68,7 +132,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "0.4.25"
|
version = "0.4.27"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -79,7 +143,7 @@ name = "quote"
|
|||||||
version = "0.6.10"
|
version = "0.6.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -115,7 +179,7 @@ version = "0.2.14"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"proc-macro2 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
"syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@ -125,7 +189,7 @@ name = "syn"
|
|||||||
version = "0.15.26"
|
version = "0.15.26"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@ -183,6 +247,7 @@ name = "wg-event-gen"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"base64 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"derive_builder 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"structopt 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"structopt 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"structopt-derive 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"structopt-derive 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -215,10 +280,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
|
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
|
||||||
"checksum byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d"
|
"checksum byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d"
|
||||||
"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
|
"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
|
||||||
|
"checksum darling 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9158d690bc62a3a57c3e45b85e4d50de2008b39345592c64efd79345c7e24be0"
|
||||||
|
"checksum darling_core 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d2a368589465391e127e10c9e3a08efc8df66fd49b87dc8524c764bbe7f2ef82"
|
||||||
|
"checksum darling_macro 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)" = "244e8987bd4e174385240cde20a3657f607fb0797563c28255c353b5819a07b1"
|
||||||
|
"checksum derive_builder 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a0ca533e6abb78f9108585535ce2ae0b14c8b4504e138a9a28eaf8ba2b270c1d"
|
||||||
|
"checksum derive_builder_core 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fb484fe06ba1dc5b82f88aff700191dfc127e02b06b35e302c169706168e2528"
|
||||||
|
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
|
||||||
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
|
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
|
||||||
"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
|
"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
|
||||||
|
"checksum ident_case 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||||
"checksum libc 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)" = "48450664a984b25d5b479554c29cc04e3150c97aa4c01da5604a2d4ed9151476"
|
"checksum libc 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)" = "48450664a984b25d5b479554c29cc04e3150c97aa4c01da5604a2d4ed9151476"
|
||||||
"checksum proc-macro2 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)" = "d3797b7142c9aa74954e351fc089bbee7958cebbff6bf2815e7ffff0b19f547d"
|
"checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915"
|
||||||
"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c"
|
"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c"
|
||||||
"checksum redox_syscall 0.1.50 (registry+https://github.com/rust-lang/crates.io-index)" = "52ee9a534dc1301776eff45b4fa92d2c39b1d8c3d3357e6eb593e0d795506fc2"
|
"checksum redox_syscall 0.1.50 (registry+https://github.com/rust-lang/crates.io-index)" = "52ee9a534dc1301776eff45b4fa92d2c39b1d8c3d3357e6eb593e0d795506fc2"
|
||||||
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
||||||
|
@ -10,6 +10,7 @@ base64 = "0.10.0"
|
|||||||
time = "0.1.42"
|
time = "0.1.42"
|
||||||
structopt = "0.2.14"
|
structopt = "0.2.14"
|
||||||
structopt-derive = "0.2.14"
|
structopt-derive = "0.2.14"
|
||||||
|
derive_builder = "0.7.1"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = true
|
lto = true
|
||||||
|
68
wg-event-gen/src/controller.rs
Normal file
68
wg-event-gen/src/controller.rs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
use crate::model::WireguardController;
|
||||||
|
use std::os::unix::net::UnixStream;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
pub struct Userspace(PathBuf);
|
||||||
|
|
||||||
|
impl Userspace {
|
||||||
|
pub fn new<P: Into<PathBuf>>(path: P) -> Userspace {
|
||||||
|
Userspace(path.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WireguardController for Userspace {
|
||||||
|
fn peers<'a>(&'a mut self) -> Box<Iterator<Item = Result<Peer>> + 'a> {
|
||||||
|
let mut stream = UnixStream::connect(&self.0)?;
|
||||||
|
stream.write_all(b"get=1\n")?;
|
||||||
|
|
||||||
|
fn build_peer(builder: &mut PeerBuilder, line: String) -> Result<()> {
|
||||||
|
let line = line?;
|
||||||
|
let mut iter = line.chars();
|
||||||
|
let key = iter.by_ref().take_while(|c| c != &'=').collect::<String>();
|
||||||
|
let value = iter.collect::<String>();
|
||||||
|
let mut allowed_ips: Vec<(IpAddr, u8)> = Vec::new();
|
||||||
|
let mut last_handshake: Option<Duration> = None;
|
||||||
|
let update_handshake = |d: Duration| {
|
||||||
|
last_handshake = last_handshake.map(|c| c + d);
|
||||||
|
};
|
||||||
|
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::<SocketAddr>()?),
|
||||||
|
"last_handshake_time_sec" => {
|
||||||
|
update_handshake(Duration::from_secs(value::parse::<usize>().into()))
|
||||||
|
}
|
||||||
|
"last_handshake_time_nsec" => {
|
||||||
|
update_handshake(Duration::from_nsecs(value::parse::<usize>().into()))
|
||||||
|
}
|
||||||
|
"persistent_keepalive" => {
|
||||||
|
builder.keepalive(Duration::from_secs(value::parse::<usize>().into()))
|
||||||
|
}
|
||||||
|
"allowed_ip" => {
|
||||||
|
let mut parts = value.split("/").into_iter();
|
||||||
|
let ip = match (
|
||||||
|
parts.next().and_then(|addr| addr.parse::<IpAddr>().ok()),
|
||||||
|
parts.next().and_then(|mask| mask.parse::<u8>().ok()),
|
||||||
|
) {
|
||||||
|
(Some(addr), Some(mask)) => Some((addr, mask)),
|
||||||
|
(Some(addr), None) if addr.is_ipv6() => Some((addr, 128)),
|
||||||
|
(Some(addr), None) => Some((addr, 32)),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
ips.push(ip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
builder.allowed_ips(ips);
|
||||||
|
builder.last_handshake(last_handshake);
|
||||||
|
}
|
||||||
|
|
||||||
|
let peers = BufReader::new(stream)
|
||||||
|
.lines()
|
||||||
|
.scan(PeerBuilder::default(), build_peer);
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_peer(&mut self, peer: &Peer) -> Result<()> {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
}
|
@ -1,258 +1,7 @@
|
|||||||
#[macro_use]
|
mod controller;
|
||||||
extern crate structopt;
|
|
||||||
|
|
||||||
mod gen;
|
use controller::Userspace;
|
||||||
mod listener;
|
|
||||||
mod opts;
|
|
||||||
|
|
||||||
use listener::*;
|
|
||||||
|
|
||||||
use base64;
|
|
||||||
use hex;
|
|
||||||
use opts::Opts;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::env;
|
|
||||||
use std::fmt;
|
|
||||||
use std::io::prelude::*;
|
|
||||||
use std::io::{BufRead, BufReader, Error, ErrorKind, Result};
|
|
||||||
use std::net::{IpAddr, SocketAddr};
|
|
||||||
use std::os::unix::net::UnixStream;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::process::exit;
|
|
||||||
use std::thread;
|
|
||||||
use std::time::Duration;
|
|
||||||
use structopt::StructOpt;
|
|
||||||
|
|
||||||
use time;
|
|
||||||
|
|
||||||
pub type KV = (String, String);
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
|
||||||
enum State {
|
|
||||||
Interface(Vec<KV>),
|
|
||||||
Peer(Vec<KV>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
|
|
||||||
pub struct Peer {
|
|
||||||
public_key: String,
|
|
||||||
endpoint: Option<SocketAddr>,
|
|
||||||
allowed_ips: Vec<(IpAddr, u8)>,
|
|
||||||
last_handshake: Option<Duration>,
|
|
||||||
persistent_keepalive: Option<Duration>,
|
|
||||||
traffic: (u64, u64),
|
|
||||||
parsed: time::Timespec,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Peer {
|
|
||||||
fn from_kv(entries: &Vec<KV>) -> Result<Peer> {
|
|
||||||
let key = match entries
|
|
||||||
.iter()
|
|
||||||
.filter(|(key, _)| key == &"public_key")
|
|
||||||
.map(|(_, value)| value)
|
|
||||||
.next()
|
|
||||||
{
|
|
||||||
Some(key) => key,
|
|
||||||
None => return Err(Error::new(ErrorKind::Other, "Peer is missing key")),
|
|
||||||
};
|
|
||||||
Ok(Peer {
|
|
||||||
public_key: base64::encode(&hex::decode(key).unwrap()),
|
|
||||||
endpoint: entries
|
|
||||||
.iter()
|
|
||||||
.filter(|(key, _)| key == &"endpoint")
|
|
||||||
.map(|(_, value)| value.parse::<SocketAddr>().unwrap())
|
|
||||||
.next(),
|
|
||||||
allowed_ips: entries
|
|
||||||
.iter()
|
|
||||||
.filter(|(key, _)| key == &"allowed_ip")
|
|
||||||
.map(|(_, value)| {
|
|
||||||
let mut parts = value.split("/").into_iter();
|
|
||||||
match (
|
|
||||||
parts.next().and_then(|addr| addr.parse::<IpAddr>().ok()),
|
|
||||||
parts.next().and_then(|mask| mask.parse::<u8>().ok()),
|
|
||||||
) {
|
|
||||||
(Some(addr), Some(mask)) => Some((addr, mask)),
|
|
||||||
(Some(addr), None) if addr.is_ipv6() => Some((addr, 128)),
|
|
||||||
(Some(addr), None) => Some((addr, 32)),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.filter_map(|net| net)
|
|
||||||
.collect::<Vec<(IpAddr, u8)>>(),
|
|
||||||
last_handshake: entries
|
|
||||||
.iter()
|
|
||||||
.filter_map(|(key, value)| {
|
|
||||||
let value = || value.parse::<u64>().unwrap();
|
|
||||||
match key.as_ref() {
|
|
||||||
"last_handshake_time_sec" if value() != 0 => {
|
|
||||||
Some(Duration::new(value(), 0))
|
|
||||||
}
|
|
||||||
"last_handshake_time_nsec" if value() != 0 => {
|
|
||||||
Some(Duration::from_nanos(value()))
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.fold(None, |acc, add| {
|
|
||||||
if let Some(dur) = acc {
|
|
||||||
Some(dur + add)
|
|
||||||
} else {
|
|
||||||
Some(add)
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
persistent_keepalive: entries
|
|
||||||
.iter()
|
|
||||||
.filter(|(key, _)| key == &"persistent_keepalive")
|
|
||||||
.map(|(_, value)| Duration::from_secs(value.parse::<u64>().unwrap()))
|
|
||||||
.next(),
|
|
||||||
traffic: (0, 0),
|
|
||||||
parsed: time::get_time(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn last_handshake_rel(&self) -> Option<Duration> {
|
|
||||||
let time = self.parsed;
|
|
||||||
Some(Duration::new(time.sec as u64, time.nsec as u32) - self.last_handshake?)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl State {
|
|
||||||
pub fn kv(&self) -> &Vec<KV> {
|
|
||||||
match self {
|
|
||||||
State::Interface(kv) => kv,
|
|
||||||
State::Peer(kv) => kv,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn kv_mut(&mut self) -> &mut Vec<KV> {
|
|
||||||
match self {
|
|
||||||
State::Interface(kv) => kv,
|
|
||||||
State::Peer(kv) => kv,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn id<'a>(&'a self) -> Option<String> {
|
|
||||||
self.kv()
|
|
||||||
.iter()
|
|
||||||
.filter(|(key, _)| key == &"private_key" || key == &"public_key")
|
|
||||||
.map(|(_, value)| base64::encode(&hex::decode(&value).unwrap()))
|
|
||||||
.next()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn push(&mut self, key: String, value: String) {
|
|
||||||
self.kv_mut().push((key, value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for State {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
for (k, v) in self.kv() {
|
|
||||||
write!(f, "({:10}= {})", k, v)?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for Peer {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(f, "{:?}", self)
|
|
||||||
// write!(f, "peer {}\nshake {} ago\naddr {}\nkeepalive {}\n", self.public_key, self.last_handshake.map(|d|d.to_string()).unwrap_or("-"), self.endpoint.map(|d|d.to_string()).unwrap_or("-"), self.persistent_keepalive.map(|d|d.to_string()).unwrap_or("-"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Socket {
|
|
||||||
pub path: PathBuf,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Socket {
|
|
||||||
pub fn get(&self) -> Result<Vec<State>> {
|
|
||||||
let mut stream = UnixStream::connect(&self.path)?;
|
|
||||||
stream.write_all(b"get=1\n")?;
|
|
||||||
let mut state: Vec<State> = vec![];
|
|
||||||
let mut cur = State::Interface(Vec::with_capacity(0));
|
|
||||||
for line in BufReader::new(stream).lines() {
|
|
||||||
let line = line?;
|
|
||||||
let mut iter = line.chars();
|
|
||||||
let key = iter.by_ref().take_while(|c| c != &'=').collect::<String>();
|
|
||||||
let value = iter.collect::<String>();
|
|
||||||
match key.as_ref() {
|
|
||||||
"errno" if value != "0" => {
|
|
||||||
Err(Error::new(
|
|
||||||
ErrorKind::Other,
|
|
||||||
format!("Socket said error: {}", value),
|
|
||||||
))?;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
"public_key" | "private_key" => {
|
|
||||||
state.push(cur);
|
|
||||||
cur = if key == "private_key" {
|
|
||||||
State::Interface(Vec::with_capacity(3))
|
|
||||||
} else {
|
|
||||||
State::Peer(Vec::with_capacity(5))
|
|
||||||
};
|
|
||||||
cur.push(key, value);
|
|
||||||
}
|
|
||||||
_ => cur.push(key, value),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(state)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_by_id(&self) -> Result<HashMap<String, State>> {
|
|
||||||
let state = self.get()?;
|
|
||||||
let mut ided = HashMap::new();
|
|
||||||
for s in state {
|
|
||||||
if let Some(id) = s.id() {
|
|
||||||
ided.insert(id.clone(), s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(ided)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_peers(&self) -> Result<HashMap<String, Peer>> {
|
|
||||||
let by_id = self.get_by_id()?;
|
|
||||||
Ok(by_id
|
|
||||||
.iter()
|
|
||||||
.filter_map(|(id, state)| {
|
|
||||||
Peer::from_kv(state.kv())
|
|
||||||
.ok()
|
|
||||||
.map(|peer| (id.to_owned(), peer))
|
|
||||||
})
|
|
||||||
.collect())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let opts = Opts::from_args();
|
let controller = Userspace::new("");
|
||||||
|
|
||||||
let timeout = Duration::from_secs(opts.timeout);
|
|
||||||
let interval = Duration::from_secs(opts.poll);
|
|
||||||
let events = opts.events;
|
|
||||||
let path = opts.socket;
|
|
||||||
|
|
||||||
let mut listeners: Vec<Box<EventListener>> = vec![Box::new(LogListener)];
|
|
||||||
|
|
||||||
if let Some(events) = events {
|
|
||||||
listeners.push(Box::new(ScriptListener::new(events)))
|
|
||||||
}
|
|
||||||
|
|
||||||
let sock = Socket { path };
|
|
||||||
let mut prev_state: Option<HashMap<String, Peer>> = None;
|
|
||||||
loop {
|
|
||||||
let state = match sock.get_peers() {
|
|
||||||
Ok(state) => state,
|
|
||||||
Err(err) => {
|
|
||||||
eprintln!("Failed to read from socket: {}", err);
|
|
||||||
if !opts.ignore_socket_errors {
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if let Some(prev_state) = prev_state {
|
|
||||||
gen::gen_events(&state, &prev_state, &listeners, timeout, interval);
|
|
||||||
}
|
|
||||||
prev_state = Some(state);
|
|
||||||
thread::sleep(interval);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
47
wg-event-gen/src/model.rs
Normal file
47
wg-event-gen/src/model.rs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#[macro_use]
|
||||||
|
extern crate structopt;
|
||||||
|
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate derive_builder;
|
||||||
|
|
||||||
|
|
||||||
|
use std::io::Result;
|
||||||
|
use base64::{decode};
|
||||||
|
|
||||||
|
pub enum ECCKey{
|
||||||
|
PublicKey([u8; 32]),
|
||||||
|
PrivateKey([u8; 32])
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ECCKey {
|
||||||
|
fn from_base64<I: AsRef<str>>(key: I) -> Result<ECCKey> {
|
||||||
|
let key = decode(key.as_ref::<str>())?;
|
||||||
|
let bytes = [0; 32];
|
||||||
|
bytes.copy_from_slice(key);
|
||||||
|
ECCKey::PublicKey(bytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SharedKey([u8; 32]);
|
||||||
|
|
||||||
|
#[derive(Debug,Builder, PartialEq, Eq, Hash, Clone)]
|
||||||
|
pub struct Peer {
|
||||||
|
key: ECCKey,
|
||||||
|
shared_key: Option<SharedKey>,
|
||||||
|
endpoint: Option<SocketAddr>,
|
||||||
|
allowed_ips: Vec<(IpAddr, u8)>,
|
||||||
|
last_handshake: Option<Duration>,
|
||||||
|
persistent_keepalive: Option<Duration>,
|
||||||
|
traffic: (u64, u64),
|
||||||
|
parsed: time::Timespec,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
trait WireguardController {
|
||||||
|
|
||||||
|
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