From cd7558594fa36a3b5624d84b9e2f40b29234225b Mon Sep 17 00:00:00 2001 From: Jacek Galowicz Date: Thu, 14 Nov 2024 14:09:23 +0000 Subject: [PATCH] rp: Add `exchange-config` command This is similar to `rosenpass exchange`/`rosenpass exchange-config`. It's however slightly different to the configuration file models the `rp exchange` command line. --- Cargo.lock | 2 ++ rp/Cargo.toml | 2 ++ rp/src/cli.rs | 22 +++++++++++++++++++++- rp/src/exchange.rs | 5 +++-- rp/src/main.rs | 9 ++++++++- 5 files changed, 36 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1cf9e0c..ad7d21b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2003,9 +2003,11 @@ dependencies = [ "rosenpass-util", "rosenpass-wireguard-broker", "rtnetlink", + "serde", "stacker", "tempfile", "tokio", + "toml", "x25519-dalek", "zeroize", ] diff --git a/rp/Cargo.toml b/rp/Cargo.toml index 7e1073d..a095177 100644 --- a/rp/Cargo.toml +++ b/rp/Cargo.toml @@ -12,6 +12,8 @@ repository = "https://github.com/rosenpass/rosenpass" [dependencies] anyhow = { workspace = true } base64ct = { workspace = true } +serde = { workspace = true } +toml = { workspace = true } x25519-dalek = { version = "2", features = ["static_secrets"] } zeroize = { workspace = true } diff --git a/rp/src/cli.rs b/rp/src/cli.rs index c20400d..f7371a6 100644 --- a/rp/src/cli.rs +++ b/rp/src/cli.rs @@ -12,6 +12,9 @@ pub enum Command { public_keys_dir: PathBuf, }, Exchange(ExchangeOptions), + ExchangeConfig { + config_file: PathBuf, + }, Help, } @@ -19,6 +22,7 @@ enum CommandType { GenKey, PubKey, Exchange, + ExchangeConfig, } #[derive(Default)] @@ -33,8 +37,9 @@ fn fatal(note: &str, command: Option) -> Result { CommandType::GenKey => Err(format!("{}\nUsage: rp genkey PRIVATE_KEYS_DIR", note)), CommandType::PubKey => Err(format!("{}\nUsage: rp pubkey PRIVATE_KEYS_DIR PUBLIC_KEYS_DIR", note)), CommandType::Exchange => Err(format!("{}\nUsage: rp exchange PRIVATE_KEYS_DIR [dev ] [ip /] [listen :] [peer PUBLIC_KEYS_DIR [endpoint :] [persistent-keepalive ] [allowed-ips /[,/]...]]...", note)), + CommandType::ExchangeConfig => Err(format!("{}\nUsage: rp exchange-config ", note)), }, - None => Err(format!("{}\nUsage: rp [verbose] genkey|pubkey|exchange [ARGS]...", note)), + None => Err(format!("{}\nUsage: rp [verbose] genkey|pubkey|exchange|exchange-config [ARGS]...", note)), } } @@ -253,6 +258,21 @@ impl Cli { let options = ExchangeOptions::parse(&mut args)?; cli.command = Some(Command::Exchange(options)); } + "exchange-config" => { + if cli.command.is_some() { + return fatal("Too many commands supplied", None); + } + + if let Some(config_file) = args.next() { + let config_file = PathBuf::from(config_file); + cli.command = Some(Command::ExchangeConfig { config_file }); + } else { + return fatal( + "Required position argument: CONFIG_FILE", + Some(CommandType::ExchangeConfig), + ); + } + } "help" => { cli.command = Some(Command::Help); } diff --git a/rp/src/exchange.rs b/rp/src/exchange.rs index e337e72..3045a91 100644 --- a/rp/src/exchange.rs +++ b/rp/src/exchange.rs @@ -1,5 +1,6 @@ use anyhow::Error; use futures::lock::Mutex; +use serde::Deserialize; use std::future::Future; use std::ops::DerefMut; use std::pin::Pin; @@ -11,7 +12,7 @@ use anyhow::Result; #[cfg(any(target_os = "linux", target_os = "freebsd"))] use crate::key::WG_B64_LEN; -#[derive(Default)] +#[derive(Default, Deserialize)] pub struct ExchangePeer { pub public_keys_dir: PathBuf, pub endpoint: Option, @@ -19,7 +20,7 @@ pub struct ExchangePeer { pub allowed_ips: Option, } -#[derive(Default)] +#[derive(Default, Deserialize)] pub struct ExchangeOptions { pub verbose: bool, pub private_keys_dir: PathBuf, diff --git a/rp/src/main.rs b/rp/src/main.rs index 7a2ab99..1b9f696 100644 --- a/rp/src/main.rs +++ b/rp/src/main.rs @@ -1,4 +1,4 @@ -use std::process::exit; +use std::{fs, process::exit}; use cli::{Cli, Command}; use exchange::exchange; @@ -36,6 +36,13 @@ async fn main() { options.verbose = cli.verbose; exchange(options).await } + Command::ExchangeConfig { config_file } => { + let s: String = fs::read_to_string(config_file).expect("cannot read config"); + let mut options: exchange::ExchangeOptions = + toml::from_str::(&s).expect("cannot parse config"); + options.verbose = options.verbose || cli.verbose; + exchange(options).await + } Command::Help => { println!("Usage: rp [verbose] genkey|pubkey|exchange [ARGS]..."); Ok(())