1use std::collections::HashMap;
2use std::net::{IpAddr, Ipv4Addr};
3
4use serde::{Deserialize, Serialize};
6
7use crate::manager::*;
8
9#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq)]
10pub struct PublicKeyWithTime {
11 pub key: String, 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}