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.
This commit is contained in:
Jacek Galowicz
2024-11-14 14:09:23 +00:00
committed by Paul Spooren
parent 022cdc4ffa
commit cd7558594f
5 changed files with 36 additions and 4 deletions

2
Cargo.lock generated
View File

@@ -2003,9 +2003,11 @@ dependencies = [
"rosenpass-util", "rosenpass-util",
"rosenpass-wireguard-broker", "rosenpass-wireguard-broker",
"rtnetlink", "rtnetlink",
"serde",
"stacker", "stacker",
"tempfile", "tempfile",
"tokio", "tokio",
"toml",
"x25519-dalek", "x25519-dalek",
"zeroize", "zeroize",
] ]

View File

@@ -12,6 +12,8 @@ repository = "https://github.com/rosenpass/rosenpass"
[dependencies] [dependencies]
anyhow = { workspace = true } anyhow = { workspace = true }
base64ct = { workspace = true } base64ct = { workspace = true }
serde = { workspace = true }
toml = { workspace = true }
x25519-dalek = { version = "2", features = ["static_secrets"] } x25519-dalek = { version = "2", features = ["static_secrets"] }
zeroize = { workspace = true } zeroize = { workspace = true }

View File

@@ -12,6 +12,9 @@ pub enum Command {
public_keys_dir: PathBuf, public_keys_dir: PathBuf,
}, },
Exchange(ExchangeOptions), Exchange(ExchangeOptions),
ExchangeConfig {
config_file: PathBuf,
},
Help, Help,
} }
@@ -19,6 +22,7 @@ enum CommandType {
GenKey, GenKey,
PubKey, PubKey,
Exchange, Exchange,
ExchangeConfig,
} }
#[derive(Default)] #[derive(Default)]
@@ -33,8 +37,9 @@ fn fatal<T>(note: &str, command: Option<CommandType>) -> Result<T, String> {
CommandType::GenKey => Err(format!("{}\nUsage: rp genkey PRIVATE_KEYS_DIR", note)), 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::PubKey => Err(format!("{}\nUsage: rp pubkey PRIVATE_KEYS_DIR PUBLIC_KEYS_DIR", note)),
CommandType::Exchange => Err(format!("{}\nUsage: rp exchange PRIVATE_KEYS_DIR [dev <device>] [ip <ip1>/<cidr1>] [listen <ip>:<port>] [peer PUBLIC_KEYS_DIR [endpoint <ip>:<port>] [persistent-keepalive <interval>] [allowed-ips <ip1>/<cidr1>[,<ip2>/<cidr2>]...]]...", note)), CommandType::Exchange => Err(format!("{}\nUsage: rp exchange PRIVATE_KEYS_DIR [dev <device>] [ip <ip1>/<cidr1>] [listen <ip>:<port>] [peer PUBLIC_KEYS_DIR [endpoint <ip>:<port>] [persistent-keepalive <interval>] [allowed-ips <ip1>/<cidr1>[,<ip2>/<cidr2>]...]]...", note)),
CommandType::ExchangeConfig => Err(format!("{}\nUsage: rp exchange-config <CONFIG_FILE>", 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)?; let options = ExchangeOptions::parse(&mut args)?;
cli.command = Some(Command::Exchange(options)); 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" => { "help" => {
cli.command = Some(Command::Help); cli.command = Some(Command::Help);
} }

View File

@@ -1,5 +1,6 @@
use anyhow::Error; use anyhow::Error;
use futures::lock::Mutex; use futures::lock::Mutex;
use serde::Deserialize;
use std::future::Future; use std::future::Future;
use std::ops::DerefMut; use std::ops::DerefMut;
use std::pin::Pin; use std::pin::Pin;
@@ -11,7 +12,7 @@ use anyhow::Result;
#[cfg(any(target_os = "linux", target_os = "freebsd"))] #[cfg(any(target_os = "linux", target_os = "freebsd"))]
use crate::key::WG_B64_LEN; use crate::key::WG_B64_LEN;
#[derive(Default)] #[derive(Default, Deserialize)]
pub struct ExchangePeer { pub struct ExchangePeer {
pub public_keys_dir: PathBuf, pub public_keys_dir: PathBuf,
pub endpoint: Option<SocketAddr>, pub endpoint: Option<SocketAddr>,
@@ -19,7 +20,7 @@ pub struct ExchangePeer {
pub allowed_ips: Option<String>, pub allowed_ips: Option<String>,
} }
#[derive(Default)] #[derive(Default, Deserialize)]
pub struct ExchangeOptions { pub struct ExchangeOptions {
pub verbose: bool, pub verbose: bool,
pub private_keys_dir: PathBuf, pub private_keys_dir: PathBuf,

View File

@@ -1,4 +1,4 @@
use std::process::exit; use std::{fs, process::exit};
use cli::{Cli, Command}; use cli::{Cli, Command};
use exchange::exchange; use exchange::exchange;
@@ -36,6 +36,13 @@ async fn main() {
options.verbose = cli.verbose; options.verbose = cli.verbose;
exchange(options).await 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::<exchange::ExchangeOptions>(&s).expect("cannot parse config");
options.verbose = options.verbose || cli.verbose;
exchange(options).await
}
Command::Help => { Command::Help => {
println!("Usage: rp [verbose] genkey|pubkey|exchange [ARGS]..."); println!("Usage: rp [verbose] genkey|pubkey|exchange [ARGS]...");
Ok(()) Ok(())