Skip to main content

wg_netmanager/
configuration.rs

1use std::collections::HashMap;
2use std::net::{IpAddr, Ipv4Addr};
3
4//use log::*;
5use serde::{Deserialize, Serialize};
6
7use crate::manager::*;
8
9#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq)]
10pub struct PublicKeyWithTime {
11    pub key: String, // base64 encoded
12    pub priv_key_creation_time: u64,
13}
14
15#[derive(Debug, Clone)]
16pub struct PublicPeer {
17    pub endpoint: String,
18    pub wg_port: u16,
19    pub admin_port: u16,
20    pub wg_ip: Ipv4Addr,
21}
22
23#[derive(Default)]
24pub struct StaticConfigurationBuilder {
25    name: Option<String>,
26    ip_list: Option<Vec<IpAddr>>,
27    wg_ip: Option<Ipv4Addr>,
28    wg_name: Option<String>,
29    wg_port: Option<u16>,
30    wg_hopping: Option<bool>,
31    admin_port: Option<u16>,
32    subnet: Option<ipnet::Ipv4Net>,
33    shared_key: Option<Vec<u8>>,
34    my_private_key: Option<String>,
35    my_public_key: Option<PublicKeyWithTime>,
36    peers: HashMap<Ipv4Addr, PublicPeer>,
37    use_tui: Option<bool>,
38    use_existing_interface: Option<bool>,
39    network_yaml_filename: Option<String>,
40    peer_yaml_filename: Option<String>,
41}
42impl StaticConfigurationBuilder {
43    pub fn new() -> Self {
44        StaticConfigurationBuilder::default()
45    }
46    pub fn name<T: Into<String>>(mut self, name: T) -> Self {
47        self.name = Some(name.into());
48        self
49    }
50    pub fn ip_list(mut self, ip_list: Vec<IpAddr>) -> Self {
51        self.ip_list = Some(ip_list);
52        self
53    }
54    pub fn wg_ip<T: Into<Ipv4Addr>>(mut self, wg_ip: T) -> Self {
55        self.wg_ip = Some(wg_ip.into());
56        self
57    }
58    pub fn wg_name<T: Into<String>>(mut self, wg_name: T) -> Self {
59        self.wg_name = Some(wg_name.into());
60        self
61    }
62    pub fn wg_port(mut self, port: u16) -> Self {
63        self.wg_port = Some(port);
64        self
65    }
66    pub fn wg_hopping(mut self, hopping: bool) -> Self {
67        self.wg_hopping = Some(hopping);
68        self
69    }
70    pub fn admin_port(mut self, port: u16) -> Self {
71        self.admin_port = Some(port);
72        self
73    }
74    pub fn subnet(mut self, subnet: ipnet::Ipv4Net) -> Self {
75        self.subnet = Some(subnet);
76        self
77    }
78    pub fn shared_key(mut self, shared_key: Vec<u8>) -> Self {
79        self.shared_key = Some(shared_key);
80        self
81    }
82    pub fn my_private_key<T: Into<String>>(mut self, private_key: T) -> Self {
83        self.my_private_key = Some(private_key.into());
84        self
85    }
86    pub fn my_public_key(mut self, public_key: PublicKeyWithTime) -> Self {
87        self.my_public_key = Some(public_key);
88        self
89    }
90    pub fn peers(mut self, peers: HashMap<Ipv4Addr, PublicPeer>) -> Self {
91        self.peers = peers;
92        self
93    }
94    pub fn use_tui(mut self, use_tui: bool) -> Self {
95        self.use_tui = Some(use_tui);
96        self
97    }
98    pub fn use_existing_interface(mut self, use_existing_interface: bool) -> Self {
99        self.use_existing_interface = Some(use_existing_interface);
100        self
101    }
102    pub fn network_yaml_filename<T: Into<String>>(mut self, fname: T) -> Self {
103        self.network_yaml_filename = Some(fname.into());
104        self
105    }
106    pub fn peer_yaml_filename<T: Into<String>>(mut self, fname: T) -> Self {
107        self.peer_yaml_filename = Some(fname.into());
108        self
109    }
110    pub fn build(self) -> StaticConfiguration {
111        let is_static = self.peers.contains_key(self.wg_ip.as_ref().unwrap());
112        StaticConfiguration {
113            name: self.name.unwrap(),
114            ip_list: self.ip_list.unwrap(),
115            wg_ip: self.wg_ip.unwrap(),
116            wg_name: self.wg_name.unwrap(),
117            wg_port: self.wg_port.unwrap(),
118            wg_hopping: self.wg_hopping.unwrap(),
119            admin_port: self.admin_port.unwrap(),
120            subnet: self.subnet.unwrap(),
121            shared_key: self.shared_key.unwrap(),
122            my_private_key: self.my_private_key.unwrap(),
123            my_public_key: self.my_public_key.unwrap(),
124            is_static,
125            peers: self.peers,
126            use_tui: self.use_tui.unwrap(),
127            use_existing_interface: self.use_existing_interface.unwrap(),
128            network_yaml_filename: self.network_yaml_filename.unwrap(),
129            peer_yaml_filename: self.peer_yaml_filename,
130        }
131    }
132}
133
134#[derive(Debug)]
135pub struct StaticConfiguration {
136    pub name: String,
137    pub ip_list: Vec<IpAddr>,
138    pub wg_ip: Ipv4Addr,
139    pub wg_name: String,
140    pub wg_port: u16,
141    pub wg_hopping: bool,
142    pub admin_port: u16,
143    pub subnet: ipnet::Ipv4Net,
144    pub shared_key: Vec<u8>,
145    pub my_private_key: String,
146    pub my_public_key: PublicKeyWithTime,
147    pub peers: HashMap<Ipv4Addr, PublicPeer>,
148    pub is_static: bool,
149    pub use_tui: bool,
150    pub use_existing_interface: bool,
151    pub network_yaml_filename: String,
152    pub peer_yaml_filename: Option<String>,
153}
154
155impl StaticConfiguration {
156    pub fn builder() -> StaticConfigurationBuilder {
157        StaticConfigurationBuilder::new()
158    }
159    pub fn to_wg_configuration(&self, manager: &NetworkManager) -> String {
160        let mut lines: Vec<String> = vec![];
161        lines.push("[Interface]".to_string());
162        lines.push(format!("PrivateKey = {}", self.my_private_key));
163        let port = if self.wg_hopping {
164            manager.my_local_wg_port
165        } else {
166            self.peers
167                .get(&self.wg_ip)
168                .map(|peer| peer.wg_port)
169                .unwrap_or(self.wg_port)
170        };
171        lines.push(format!("ListenPort = {}", port));
172
173        for node in manager.all_nodes.values() {
174            if let Some(mut peer_lines) = node.peer_wireguard_configuration() {
175                lines.push("".to_string());
176                lines.push("[Peer]".to_string());
177                lines.append(&mut peer_lines);
178            }
179        }
180
181        lines.join("\n")
182    }
183    pub fn my_admin_port(&self) -> u16 {
184        self.peers
185            .get(&self.wg_ip)
186            .map(|peer| peer.admin_port)
187            .unwrap_or(self.admin_port)
188    }
189}