aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Garrelou <simon@sixfoisneuf.fr>2023-05-25 10:31:49 +0200
committerSimon Garrelou <simon@sixfoisneuf.fr>2023-05-25 10:31:49 +0200
commitd5fa15e5d067e0c05ab0bd2b40af1dfaa80aedde (patch)
tree66213ae30dccf12a414538fa8ab5d4d4e9e26050
parent282cab5568d83decc44675be6dc5f32c366b1636 (diff)
downloadwgmgr-d5fa15e5d067e0c05ab0bd2b40af1dfaa80aedde.tar.gz
wgmgr-d5fa15e5d067e0c05ab0bd2b40af1dfaa80aedde.zip
Simplify Wireguard config file discovery
-rw-r--r--src/configuration.rs12
-rw-r--r--src/main.rs99
2 files changed, 15 insertions, 96 deletions
diff --git a/src/configuration.rs b/src/configuration.rs
index 173b8ff..839db24 100644
--- a/src/configuration.rs
+++ b/src/configuration.rs
@@ -5,24 +5,24 @@ use std::fs::read_to_string;
5#[derive(Deserialize)] 5#[derive(Deserialize)]
6pub struct Configuration { 6pub struct Configuration {
7 pub endpoint: String, 7 pub endpoint: String,
8 pub wgconf: String,
8 pub port: Option<u32>, 9 pub port: Option<u32>,
9 pub dns: Option<String>, 10 pub dns: Option<String>,
10 pub wgconf: Option<String>,
11} 11}
12 12
13pub fn find_configuration_file(argument: Option<&String>) -> Result<String> { 13pub fn find_configuration_file(argument: Option<&String>) -> Result<Configuration> {
14 match argument { 14 match argument {
15 Some(p) => { 15 Some(p) => {
16 if let Ok(t) = read_to_string(p) { 16 if let Ok(t) = read_to_string(p) {
17 let _: Configuration = toml::from_str(&t).context("parsing configuration file")?; 17 let c: Configuration = toml::from_str(&t).context("parsing configuration file")?;
18 return Ok(p.clone()) 18 return Ok(c)
19 } 19 }
20 }, 20 },
21 None => { 21 None => {
22 // Try /etc/wgmgr.toml 22 // Try /etc/wgmgr.toml
23 if let Ok(t) = read_to_string("/etc/wgmgr.toml") { 23 if let Ok(t) = read_to_string("/etc/wgmgr.toml") {
24 let _: Configuration = toml::from_str(&t).context("parsing /etc/wgmgr.toml")?; 24 let c: Configuration = toml::from_str(&t).context("parsing /etc/wgmgr.toml")?;
25 return Ok(String::from("/etc/wgmgr.toml")) 25 return Ok(c)
26 } 26 }
27 }, 27 },
28 }; 28 };
diff --git a/src/main.rs b/src/main.rs
index 58c87e8..3f82d43 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,5 +1,4 @@
1use std::ffi::OsStr; 1use std::fs::File;
2use std::fs::{read_to_string, self, File};
3use std::net::Ipv4Addr; 2use std::net::Ipv4Addr;
4use std::str::FromStr; 3use std::str::FromStr;
5use std::{env, process::exit}; 4use std::{env, process::exit};
@@ -7,9 +6,7 @@ use std::io::Write;
7use std::process::Command as processCommand; 6use std::process::Command as processCommand;
8 7
9use anyhow::{Result, anyhow, Context}; 8use anyhow::{Result, anyhow, Context};
10use clap::{command, ArgMatches}; 9use clap::{arg, command, Command};
11use clap::Command;
12use clap::arg;
13use wg::config::WireguardConfig; 10use wg::config::WireguardConfig;
14 11
15mod wg; 12mod wg;
@@ -19,12 +16,6 @@ fn main() {
19 let matches = command!() 16 let matches = command!()
20 .arg( 17 .arg(
21 arg!( 18 arg!(
22 -w --wgconfig <WGCONFIG> "Wireguard configuration file name"
23 )
24 .required(false)
25 )
26 .arg(
27 arg!(
28 -c --config <CONFIG> "wgmgr configuration file path" 19 -c --config <CONFIG> "wgmgr configuration file path"
29 ) 20 )
30 .required(false) 21 .required(false)
@@ -89,8 +80,8 @@ fn main() {
89 80
90 81
91 // Find the configuration file for wgmgr 82 // Find the configuration file for wgmgr
92 let wgmgr_conf_path = match configuration::find_configuration_file(matches.get_one::<String>("config")) { 83 let wgmgr_conf = match configuration::find_configuration_file(matches.get_one::<String>("config")) {
93 Ok(s) => s, 84 Ok(c) => c,
94 Err(e) => { 85 Err(e) => {
95 eprintln!("Could not find wgmgr configuration file. Place it at /etc/wgmgr.toml or use the --config flag."); 86 eprintln!("Could not find wgmgr configuration file. Place it at /etc/wgmgr.toml or use the --config flag.");
96 eprintln!("{:?}", e); 87 eprintln!("{:?}", e);
@@ -98,21 +89,12 @@ fn main() {
98 } 89 }
99 }; 90 };
100 91
101 let wgmgr_conf: configuration::Configuration = toml::from_str(&read_to_string(wgmgr_conf_path).unwrap()).unwrap();
102 92
103 // Find the Wireguard configuration file 93 // Load the Wireguard configuration file
104 let wg_conf_path = match find_wg_config_file(&matches, &wgmgr_conf.wgconf) { 94 let mut wg_conf = match wg::config::WireguardConfig::new(&wgmgr_conf.wgconf) {
105 Ok(s) => s,
106 Err(e) => {
107 eprintln!("Wireguard configuration file error: {:?}", e);
108 exit(1);
109 }
110 };
111
112 let mut wg_conf = match wg::config::WireguardConfig::new(&wg_conf_path) {
113 Ok(c) => c, 95 Ok(c) => c,
114 Err(e) => { 96 Err(e) => {
115 eprintln!("Error loading the Wireguard configuration file '{}'.", wg_conf_path); 97 eprintln!("Error loading the Wireguard configuration file '{}'.", wgmgr_conf.wgconf);
116 eprintln!("{:?}", e); 98 eprintln!("{:?}", e);
117 exit(1); 99 exit(1);
118 } 100 }
@@ -151,7 +133,7 @@ fn main() {
151 133
152 Some(("add", args)) => { 134 Some(("add", args)) => {
153 let new_name = args.get_one::<String>("NAME").unwrap().to_string(); 135 let new_name = args.get_one::<String>("NAME").unwrap().to_string();
154 if let Err(e) = do_add(&mut wg_conf, wg_conf_path, &new_name, args.get_one::<String>("ip")) { 136 if let Err(e) = do_add(&mut wg_conf, wgmgr_conf.wgconf, &new_name, args.get_one::<String>("ip")) {
155 eprintln!("Error adding peer: {:?}", e); 137 eprintln!("Error adding peer: {:?}", e);
156 exit(1); 138 exit(1);
157 } 139 }
@@ -162,7 +144,7 @@ fn main() {
162 144
163 Some(("rm", args)) => { 145 Some(("rm", args)) => {
164 let rm_name = args.get_one::<String>("NAME").unwrap().to_string(); 146 let rm_name = args.get_one::<String>("NAME").unwrap().to_string();
165 if let Err(e) = do_rm(&mut wg_conf, wg_conf_path, &rm_name) { 147 if let Err(e) = do_rm(&mut wg_conf, wgmgr_conf.wgconf, &rm_name) {
166 eprintln!("Error removing peer: {:?}", e); 148 eprintln!("Error removing peer: {:?}", e);
167 exit(1); 149 exit(1);
168 } 150 }
@@ -184,69 +166,6 @@ fn main() {
184 166
185} 167}
186 168
187fn find_wg_config_file(matches: &ArgMatches, wgconf: &Option<String>) -> Result<String> {
188 // Top priority goes to the command-line argument
189 match matches.get_one::<String>("wgconfig") {
190 Some(s) => {
191 if s.starts_with("/") {
192 return Ok(s.to_string())
193 }
194 else {
195 return Ok(format!("/etc/wireguard/{}", s))
196 }
197 },
198 None => {}
199 }
200
201 // Then, if the environment variable exists, we take it
202 match env::var("WG_CONF") {
203 Ok(s) => return Ok(s),
204 Err(_) => {}
205 };
206
207 // Then, is there is a "wgconf" in the wgmgr configuration file, we take that
208 match wgconf {
209 Some(s) => return Ok(s.clone()),
210 None => {}
211 };
212
213 // Otherwise, we will first try a simple "wg0.conf"
214 match read_to_string("/etc/wireguard/wg0.conf") {
215 Ok(_) => return Ok(String::from_str("/etc/wireguard/wg0.conf").unwrap()),
216 Err(_) => {}
217 }
218
219 // Finally, we can try to see if there is a single ".conf" file in /etc/wireguard
220 match fs::read_dir("/etc/wireguard/") {
221 Ok(d) => {
222 let conf_files: Vec<fs::DirEntry> = d.filter(|e| {
223 if let Ok(e) = e {
224 if e.file_type().unwrap().is_dir() {
225 return false;
226 }
227
228 match e.path().extension().and_then(OsStr::to_str) {
229 Some("conf") => { return true} ,
230 _ => {return false},
231 }
232 }
233
234 return false;
235 }).map(|e| {
236 return e.unwrap();
237 }).collect();
238
239 if conf_files.len() == 1 {
240 return Ok(String::from_str(conf_files[0].path().to_str().unwrap()).unwrap());
241 }
242 else {
243 return Err(anyhow!("Could not determine the path to your WireGuard configuration file. Set the WG_CONF environment variable, or pass the '--config' parameter."))
244 }
245 },
246 Err(e) => return Err(anyhow!("Error listing /etc/wireguard/: {}", e))
247 }
248}
249
250fn do_list(wg_conf: &wg::config::WireguardConfig) { 169fn do_list(wg_conf: &wg::config::WireguardConfig) {
251 let mut max_length = 0; 170 let mut max_length = 0;
252 for p in wg_conf.peers.iter() { 171 for p in wg_conf.peers.iter() {