diff options
author | Simon Garrelou <simon@sixfoisneuf.fr> | 2023-05-25 10:31:49 +0200 |
---|---|---|
committer | Simon Garrelou <simon@sixfoisneuf.fr> | 2023-05-25 10:31:49 +0200 |
commit | d5fa15e5d067e0c05ab0bd2b40af1dfaa80aedde (patch) | |
tree | 66213ae30dccf12a414538fa8ab5d4d4e9e26050 | |
parent | 282cab5568d83decc44675be6dc5f32c366b1636 (diff) | |
download | wgmgr-d5fa15e5d067e0c05ab0bd2b40af1dfaa80aedde.tar.gz wgmgr-d5fa15e5d067e0c05ab0bd2b40af1dfaa80aedde.zip |
Simplify Wireguard config file discovery
-rw-r--r-- | src/configuration.rs | 12 | ||||
-rw-r--r-- | src/main.rs | 99 |
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)] |
6 | pub struct Configuration { | 6 | pub 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 | ||
13 | pub fn find_configuration_file(argument: Option<&String>) -> Result<String> { | 13 | pub 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 @@ | |||
1 | use std::ffi::OsStr; | 1 | use std::fs::File; |
2 | use std::fs::{read_to_string, self, File}; | ||
3 | use std::net::Ipv4Addr; | 2 | use std::net::Ipv4Addr; |
4 | use std::str::FromStr; | 3 | use std::str::FromStr; |
5 | use std::{env, process::exit}; | 4 | use std::{env, process::exit}; |
@@ -7,9 +6,7 @@ use std::io::Write; | |||
7 | use std::process::Command as processCommand; | 6 | use std::process::Command as processCommand; |
8 | 7 | ||
9 | use anyhow::{Result, anyhow, Context}; | 8 | use anyhow::{Result, anyhow, Context}; |
10 | use clap::{command, ArgMatches}; | 9 | use clap::{arg, command, Command}; |
11 | use clap::Command; | ||
12 | use clap::arg; | ||
13 | use wg::config::WireguardConfig; | 10 | use wg::config::WireguardConfig; |
14 | 11 | ||
15 | mod wg; | 12 | mod 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 | ||
187 | fn 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 | |||
250 | fn do_list(wg_conf: &wg::config::WireguardConfig) { | 169 | fn 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() { |