summaryrefslogtreecommitdiff
path: root/src/daemon_dbus.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon_dbus.rs')
-rw-r--r--src/daemon_dbus.rs135
1 files changed, 113 insertions, 22 deletions
diff --git a/src/daemon_dbus.rs b/src/daemon_dbus.rs
index 5ed4d94..f0873f0 100644
--- a/src/daemon_dbus.rs
+++ b/src/daemon_dbus.rs
@@ -1,4 +1,3 @@
-use base64::prelude::*;
use dbus::{
channel::{MatchingReceiver, Token},
message::MatchRule,
@@ -22,7 +21,11 @@ pub async fn start_dbus(
) -> Result<(Arc<SyncConnection>, Token), DaemonError> {
let mut cr = Crossroads::new();
let if_token = cr.register("de.a.maesch", move |b| {
- b.signal::<(String, String), _>("Proposal", ("network", "peer_data"));
+ //b.signal::<(String, String), _>("Proposal", ("network", "peer_data"));
+
+ let state_rem_network = state.clone();
+ let config_path_rem_network = config_path.clone();
+
b.method_with_cr_async(
"AddNetwork",
("name", "key", "ip", "listen_port", "maesch_port"),
@@ -32,6 +35,20 @@ pub async fn start_dbus(
handle_add_network(ctx, state.clone(), config_path.clone(), args)
},
);
+ b.method_with_cr_async(
+ "RemoveNetwork",
+ ("name",),
+ ("success",),
+ move |ctx, _, args: (String,)| {
+ debug!("Received RemoveNetwork");
+ handle_remove_network(
+ ctx,
+ state_rem_network.clone(),
+ config_path_rem_network.clone(),
+ args,
+ )
+ },
+ );
});
cr.insert("/de/a/maesch", &[if_token], ());
@@ -59,29 +76,84 @@ pub async fn start_dbus(
Ok((c, receive_token))
}
-// TODO also take peers
+pub async fn handle_remove_network(
+ mut ctx: Context,
+ state: Arc<RwLock<State>>,
+ config_path: PathBuf,
+ (name,): (String,),
+) -> PhantomData<(bool,)> {
+ let mut state_rw_guard = state.write().await;
+
+ if let Some(_) = state_rw_guard.conf.networks.remove(&name) {
+ let (wg_api, h) = state_rw_guard
+ .nw_handles
+ .remove(&name)
+ .expect("state.conf.networks and state.nw_handles desynced");
+ h.abort();
+
+ let ri = wg_api.remove_interface();
+ let _ = h.await;
+
+ match write_config(&state_rw_guard.conf, &config_path) {
+ Ok(_) => info!("Synced config"),
+ Err(e) => {
+ error!("Couldn't sync config: {e}");
+ return ctx.reply(Err(MethodErr::failed(&e)));
+ }
+ };
+ drop(state_rw_guard);
+
+ match ri {
+ Ok(_) => info!("Removed network: {name}"),
+ Err(e) => {
+ error!("Removing network: {e}");
+ return ctx.reply(Err(MethodErr::failed(&e)));
+ }
+ };
+ } else {
+ warn!("Tried to remove non-existent network: {name}");
+ return ctx.reply(Err(MethodErr::invalid_arg("bad network")));
+ }
+
+ ctx.reply(Ok((true,)))
+}
+
+// TODO make this merge correctly...
pub async fn handle_add_network(
mut ctx: Context,
state: Arc<RwLock<State>>,
config_path: PathBuf,
(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")));
- }
- },
- });
+ let mut state_rw_guard = state.write().await;
+ let state_rw = state_rw_guard.deref_mut();
+
+ // TODO do more with the entry...
+ let prev_entry = state_rw.conf.networks.remove(&name);
+
+ let key = if may_key.as_str() == "" {
+ prev_entry
+ .as_ref()
+ .map(|nw| nw.privkey.clone())
+ .unwrap_or_else(|| Key::new(rand::thread_rng().gen()).to_string())
+ } else {
+ may_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 prev_entry.as_ref() {
+ Some(e) => (
+ IpAddrMask::from_str(&e.address)
+ .expect("Impossible: old config broken!")
+ .ip,
+ e.address.clone(),
+ ),
+ None => {
+ warn!("AddNetwork with no ip");
+ return ctx.reply(Err(MethodErr::invalid_arg("ip required")));
+ }
+ },
_ => match IpAddrMask::from_str(&may_ip) {
Ok(ip_mask) => (ip_mask.ip, may_ip),
Err(_) => {
@@ -91,13 +163,24 @@ pub async fn handle_add_network(
},
};
- let lp = if may_lp == 0 { 25565 } else { may_lp };
- let mp = if may_mp == 0 { 51820 } else { may_mp };
+ let lp = if may_lp == 0 {
+ prev_entry
+ .as_ref()
+ .map(|nw| nw.listen_port)
+ .unwrap_or(25565)
+ } else {
+ may_lp
+ };
+ let mp = if may_mp == 0 {
+ prev_entry.as_ref().map(|nw| nw.mäsch_port).unwrap_or(51820)
+ } else {
+ may_mp
+ };
let (wg_api, hostnames) = match add_network(
name.clone(),
- key.to_string(),
- ip_string,
+ key.clone(),
+ ip_string.clone(),
lp,
&HashMap::new(),
)
@@ -124,9 +207,17 @@ pub async fn handle_add_network(
name.clone(),
)));
- let mut state_rw_guard = state.write().await;
- let state_rw = state_rw_guard.deref_mut();
state_rw.nw_handles.insert(name.clone(), (wg_api, h));
+ state_rw.conf.networks.insert(
+ name,
+ Network {
+ privkey: key,
+ address: ip_string,
+ listen_port: lp,
+ peers: prev_entry.map_or_else(|| HashMap::new(), |nw| nw.peers),
+ mäsch_port: mp,
+ },
+ );
// NOTE this _is_ thread-safe, as we hold an exclusive write handle to the state.
match write_config(&state_rw.conf, &config_path) {