diff options
author | Lia Lenckowski <lialenck@protonmail.com> | 2024-08-13 16:51:40 +0200 |
---|---|---|
committer | Lia Lenckowski <lialenck@protonmail.com> | 2024-08-13 16:51:40 +0200 |
commit | 8aa9f19e313b985aa13a52270a9dc77c19d8ce53 (patch) | |
tree | fe72c10161ce708833de1b07ab240812ad4ea21d /src/daemon_dbus.rs | |
parent | 5073dc6ee88a02eb60f46127cbdb598692a42f39 (diff) | |
download | maesch-8aa9f19e313b985aa13a52270a9dc77c19d8ce53.tar maesch-8aa9f19e313b985aa13a52270a9dc77c19d8ce53.tar.bz2 maesch-8aa9f19e313b985aa13a52270a9dc77c19d8ce53.tar.zst |
refactor: split dbus/network off of daemon.rs
Diffstat (limited to 'src/daemon_dbus.rs')
-rw-r--r-- | src/daemon_dbus.rs | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/daemon_dbus.rs b/src/daemon_dbus.rs new file mode 100644 index 0000000..7065eec --- /dev/null +++ b/src/daemon_dbus.rs @@ -0,0 +1,98 @@ +use base64::prelude::*; +use dbus::{channel::MatchingReceiver, message::MatchRule}; +use dbus_crossroads::{Context, Crossroads, MethodErr}; +use defguard_wireguard_rs::{ + host::Peer, key::Key, net::IpAddrMask, InterfaceConfiguration, WGApi, WireguardInterfaceApi, +}; +use log::{debug, error, info, warn}; +use rand::Rng; +use std::{ + collections::{BTreeSet, HashMap}, + marker::PhantomData, + ops::DerefMut, + str::FromStr, + sync::Arc, +}; +use tokio::{ + net::TcpListener, + sync::{broadcast, RwLock}, + task, +}; + +use crate::{daemon::*, daemon_network::*}; + +// TODO also take peers +pub async fn handle_add_network( + mut ctx: Context, + state: Arc<RwLock<State>>, + (name, may_key, may_ip, may_lp, may_mp): (String, String, String, u16, u16), +) -> PhantomData<(bool,)> { + // NOTE: this is kinda stupid: we convert to a string later anyways, as thats what + // defguard_wg takes... + let key = Key::new(match may_key.as_str() { + "" => rand::thread_rng().gen(), + _ => match BASE64_STANDARD.decode(may_key) { + Ok(v) if v.len() == 32 => v.try_into().unwrap(), + _ => { + warn!("AddNetwork with bad key"); + return ctx.reply(Err(MethodErr::invalid_arg("bad key"))); + } + }, + }); + + // we store the ip as the original string, but should validate it regardless + let (ip, ip_string) = match may_ip.as_str() { + "" => todo!(), + _ => match IpAddrMask::from_str(&may_ip) { + Ok(ip_mask) => (ip_mask.ip, may_ip), + Err(_) => { + warn!("AddNetwork with bad ip"); + return ctx.reply(Err(MethodErr::invalid_arg("invalid ip"))); + } + }, + }; + + let lp = if may_lp == 0 { 25565 } else { may_lp }; + let mp = if may_mp == 0 { 51820 } else { may_mp }; + + let mut state_rw_guard = state.write().await; + let state_rw = state_rw_guard.deref_mut(); + + let wg_api = match add_network( + &mut state_rw.hostfile, + name.clone(), + key.to_string(), + ip_string, + lp, + &HashMap::new(), + ) + .await + { + Ok(wg_api) => wg_api, + Err(e) => { + warn!("AddNetwork couldn't add network: {e}"); + return ctx.reply(Err(MethodErr::failed(&e))); + } + }; + + // TODO ins wg_api + let listener = match TcpListener::bind((ip, mp)).await { + Ok(l) => l, + Err(e) => { + let _ = wg_api.remove_interface(); + warn!("AddNetwork couldn't start listener: {e}"); + return ctx.reply(Err(MethodErr::failed(&e))); + } + }; + let h = task::spawn(print_error(run_network( + state.clone(), + listener, + name.clone(), + ))); + + state_rw.nw_handles.insert(name.clone(), (wg_api, h)); + + // TODO save new config + + ctx.reply(Ok((true,))) +} |