1use std::
20{
21 thread,
22 net::TcpStream,
23 sync::mpsc::Sender,
24};
25
26use zeroize::Zeroizing;
27
28use serde_json::Value;
29
30use crate::
31{
32 options,
33 misc,
34 crypto::kex,
35 config::{ self, TofuCode },
36 network::
37 {
38 self,
39 MessageCode,
40 MessagePacket,
41 voice::
42 {
43 client as voice_client,
44 options as voice_options,
45 }
46 },
47};
48
49const GRID_W: usize = options::GRID_DIMENSIONS.0;
51const GRID_H: usize = options::GRID_DIMENSIONS.1;
52
53pub struct VoiceUser
55{
56 pub id: usize, pub username: String, pub is_speaking: bool, pub latency: u128, pub is_local: bool, }
62
63pub enum ClientEvent
65{
66 Connected(String), Message(MessagePacket), Info(String, bool, usize), Prompt(String, String), TofuError(TofuCode), VoiceActivity(Vec<VoiceUser>), Clear(usize), ExtraSpace, Quit, }
76
77fn key_exchange(stream: &mut TcpStream, keys: &mut options::SharedKeys, tx: &Sender<ClientEvent>) -> bool {
81 let message = loop
83 {
84 let received = network::receive(stream, None).unwrap();
86
87 if received.code == Some(MessageCode::KeyExchange) { break received; }
88 };
89
90 let message_text = message.text.as_ref().unwrap();
91
92 let server_keys: Value = serde_json::from_str(message_text).expect("Failed to parse server keys JSON");
94 let server_ecc_pk = server_keys["ecc"].as_str().expect("Parsing server ECC key failed");
95 let server_pq_pk = server_keys["pq"].as_str().expect("Parsing server PQ key failed");
96
97 match config::server_keys_check(&stream.peer_addr().unwrap().ip().to_string(), message_text)
99 {
100 TofuCode::Valid => {},
101
102 status @ (TofuCode::Mismatch | TofuCode::Unknown(_, _)) =>
103 {
104 network::send(stream, MessagePacket
106 {
107 code: Some(MessageCode::Disconnect),
108 ..Default::default()
109 }, None);
110
111 tx.send(ClientEvent::TofuError(status)).unwrap();
113
114 return false;
116 },
117 }
118
119 let (sk, pk) = kex::generate_ephemeral_keys();
121
122 let (pq_ciphertext, pq_secret) = kex::encapsulate_pq(server_pq_pk);
124
125 let response_text = serde_json::json!
127 ({
128 "ecc": pk,
129 "pq": pq_ciphertext,
130 }).to_string();
131
132 network::send(stream, MessagePacket
134 {
135 text: Some(response_text),
136 code: Some(MessageCode::KeyExchange),
137 ..Default::default()
138 }, None);
139
140 *keys = kex::derive_shared_secret::<GRID_W, GRID_H>(sk, server_ecc_pk.to_string(), pq_secret).expect("Shared secret derivation failed");
142
143 options::set_keys(keys.clone());
145
146 true
147}
148
149pub fn listen_server(stream: &mut TcpStream, tx: Sender<ClientEvent>) {
152 let mut keys = (Zeroizing::new(vec![]), Zeroizing::new(vec![]));
154 if !key_exchange(stream, &mut keys, &tx) { return; }
155
156 let mut min_pass: Option<u64> = None;
158 let mut max_uname: Option<u64> = None;
159 let mut min_uname: Option<u64> = None;
160 let mut server_name: &str;
161
162 let mut invalid_username = false; let mut invalid_password = false;
164
165 let mut disabled_registration = false; let mut first_message = true;
169 let mut extra_space: bool;
170
171 let mut channel = String::new();
172
173 let mut id = 0usize; let mut username: Option<String> = None;
176
177 loop
179 {
180 let read = match network::receive(stream, Some(&keys))
181 {
182 Some(packet) => packet,
183 None => continue
184 };
185
186 extra_space = false; if options::get_extra_space() { tx.send(ClientEvent::ExtraSpace).unwrap(); }
190
191 if let Some(code) = read.code
193 {
194 match code
195 {
196 MessageCode::Version =>
198 {
199 let version = misc::get_version().to_string();
200 let server_version = read.text.unwrap();
201
202 if server_version != version
204 {
205 tx.send(ClientEvent::Info(String::from("Incompatible version! ({version}/{server_version})"), true, 1)).unwrap();
206 }
207
208 network::send(stream, MessagePacket
210 {
211 text: Some(version),
212 code: Some(MessageCode::Version),
213 ..Default::default()
214 }, Some(&keys));
215
216 continue;
217 }
218
219 MessageCode::Welcome =>
221 {
222 let welcome_json: Value = serde_json::from_str(&read.text.unwrap()).expect("Parsing welcome json failed"); min_pass = Some(welcome_json["min_pass"].as_u64().expect("Invalid welcome json"));
227 max_uname = Some(welcome_json["max_uname"].as_u64().expect("Invalid welcome json"));
228 min_uname = Some(welcome_json["min_uname"].as_u64().expect("Invalid welcome json"));
229 server_name = welcome_json["server_name"].as_str().expect("Invalid welcome json");
230
231 tx.send(ClientEvent::Connected(server_name.to_string())).unwrap();
232 },
233
234 MessageCode::Rekey =>
236 {
237 key_exchange(stream, &mut keys, &tx);
239 }
240
241 MessageCode::Username =>
243 {
244 tx.send(ClientEvent::Clear(2)).unwrap();
245
246 if invalid_username
248 {
249 tx.send(ClientEvent::Clear(2)).unwrap();
250 tx.send(ClientEvent::Info(String::from("Username rejected!"), false, 0)).unwrap();
251 } else {
253 invalid_username = true;
255 }
256
257 tx.send(ClientEvent::Info(format!
258 (
259 "\n\rEnter username ({}):",
260
261 if disabled_registration
262 {
263 String::from("Registration disabled!")
264 } else
265 {
266 format!("a-Z, 0-9; {}-{} characters", min_uname.unwrap(), max_uname.unwrap())
267 }
268 ), true, 0)).unwrap();
269 },
270
271 MessageCode::PasswordR =>
273 {
274 tx.send(ClientEvent::Clear(3)).unwrap();
275 options::set_asking_password(true);
276
277 if invalid_password
279 {
280 tx.send(ClientEvent::Info(format!("Password rejected! Enter at least {} characters.", min_pass.unwrap()), false, 3)).unwrap();
281 } else
282 {
283 invalid_password = true;
284 }
285
286 tx.send(ClientEvent::Info(String::from("\n\rEnter password: (REGISTER)"), true, 0)).unwrap();
287 },
288
289 MessageCode::PasswordL =>
291 {
292 options::set_asking_password(true);
293 tx.send(ClientEvent::Info(String::from("\nEnter password: (LOGIN)"), true, 3)).unwrap();
294 },
295
296 MessageCode::Accept =>
298 {
299 tx.send(ClientEvent::Info(String::from("Login successful. Press Ctrl+H for help.\n"), true, 3)).unwrap();
300
301 id = read.text.unwrap_or("0".to_string()).parse().unwrap();
303
304 options::set_sending_messages(true);
306 },
307
308 MessageCode::Join =>
310 {
311 tx.send(ClientEvent::Clear(2)).unwrap();
312
313 let user = read.text.unwrap();
314
315 if first_message
316 {
317 tx.send(ClientEvent::ExtraSpace).unwrap();
318 username = Some(user.clone());
319 first_message = false;
320 }
321
322 tx.send(ClientEvent::Info(format!("[{}]: {} connected.\n", read.username.unwrap(), user), true, 0)).unwrap();
323 }
324
325 MessageCode::Leave =>
327 {
328 tx.send(ClientEvent::Info(format!("[{}]: {} disconnected.\n", read.username.unwrap(), read.text.unwrap()), true, 2)).unwrap();
329 voice_client::remove_consumer(&read.id.unwrap());
330 },
331
332 MessageCode::Channel =>
334 {
335 voice_client::remove_all_consumers();
337
338 channel = if let Some(c) = read.text
339 {
340 format!("#{c} | ")
341 } else
342 {
343 String::new()
344 };
345
346 tx.send(ClientEvent::Clear(1)).unwrap();
347 },
348
349 MessageCode::Voice =>
351 {
352 if options::socks5_enabled()
353 {
354 tx.send(ClientEvent::Info(String::from("Voice chat cannot be enabled while using SOCKS5.\n"), true, 2)).unwrap();
355 continue;
356 }
357
358 let status = if voice_options::swap_use_voice()
360 {
361 let username = username.clone();
362 let voice_tx = tx.clone();
363 thread::spawn(move || voice_client::listen_server_voice(id, username.unwrap(), voice_tx));
364 "en"
365 } else
366 {
367 "dis"
368 };
369
370 tx.send(ClientEvent::Info(format!("Voice {}abled.\n", status), true, 2)).unwrap();
372 },
373
374 MessageCode::VoiceClients =>
376 {
377 let clients: Vec<(usize, String)> = serde_json::from_str(&read.text.unwrap()).expect("Parsing welcome json failed");
379
380 for (id, username) in clients
382 {
383 voice_client::add_consumer(id, username);
384 }
385 }
386
387 MessageCode::ChannelJoin =>
389 {
390 let joined_id = read.id.unwrap();
391 if voice_options::get_use_voice() && id != joined_id
392 {
393 voice_client::add_consumer(read.id.unwrap(), read.username.unwrap());
394 }
395 },
396
397 MessageCode::ChannelLeave =>
399 {
400 voice_client::remove_consumer(&read.id.unwrap());
401 },
402
403 MessageCode::List =>
405 {
406 if !options::get_extra_space() { tx.send(ClientEvent::ExtraSpace).unwrap(); }
407 tx.send(ClientEvent::Info(String::from("Online clients:"), true, 2)).unwrap();
408
409 let users_json: Value = serde_json::from_str(&read.text.unwrap()).unwrap();
411
412 for user in users_json.as_array().unwrap()
414 {
415 let c = if let Some(c) = user["channel"].as_str().map(String::from)
417 {
418 format!(" | #{c}")
419 } else
420 {
421 String::new()
422 };
423
424 tx.send(ClientEvent::Info(format!("\r{} ({}){}", user["username"].as_str().unwrap(), user["id"], c), true, 0)).unwrap();
425 }
426
427 tx.send(ClientEvent::ExtraSpace).unwrap();
428
429 extra_space = true;
430 options::set_extra_space(true);
431 },
432
433 MessageCode::PrivateMessage =>
435 {
436 tx.send(ClientEvent::Info(format!("[PM FROM] {} ({}): {}\n", read.username.unwrap(), read.id.unwrap(), read.text.unwrap()), true, 2)).unwrap();
437 },
438
439 MessageCode::PrivateMessageBack =>
441 {
442 tx.send(ClientEvent::Info(format!("[PM TO] {} ({}): {}\n", read.username.unwrap(), read.id.unwrap(), read.text.unwrap()), true, 2)).unwrap();
443 },
444
445 MessageCode::SpamWarning =>
447 {
448 tx.send(ClientEvent::Info(String::from("Slow down! You're sending messages too quickly.\n"), true, 2)).unwrap();
449 },
450
451 MessageCode::RegisterDisabled =>
453 {
454 disabled_registration = true;
455 },
456
457 MessageCode::InvalidUsage =>
459 {
460 tx.send(ClientEvent::Info(String::from("Invalid usage! Press Ctrl+H for help.\n"), true, 2)).unwrap();
461 },
462
463 MessageCode::InvalidFeature =>
465 {
466 tx.send(ClientEvent::Info(String::from("Server has disabled the feature you requested.\n"), true, 2)).unwrap();
467 },
468
469 MessageCode::Disconnect =>
471 {
472 tx.send(ClientEvent::Quit).unwrap();
473 return;
474 },
475
476 _ => continue }
478 } else {
480 tx.send(ClientEvent::Message(read)).unwrap();
481 }
482
483 tx.send(ClientEvent::Prompt(channel.clone(), options::INPUT_READ.lock().unwrap().iter().collect::<String>())).unwrap();
485 if !extra_space { options::set_extra_space(false); } }
487}