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
49pub struct VoiceUser
51{
52 pub id: usize, pub username: String, pub is_speaking: bool, pub latency: u128, pub is_local: bool, }
58
59pub enum ClientEvent
61{
62 Connected(String), Message(MessagePacket), Info(String, bool, usize), Prompt(String, String), TofuError(TofuCode), VoiceActivity(Vec<VoiceUser>), Clear(usize), ExtraSpace, Quit, }
72
73fn key_exchange(stream: &mut TcpStream, keys: &mut options::SharedKeys, tx: &Sender<ClientEvent>) -> bool {
77 let message = loop
79 {
80 let received = network::receive(stream, None).unwrap();
82
83 if received.code == Some(MessageCode::KeyExchange) { break received; }
84 };
85
86 let message_text = message.text.as_ref().unwrap();
87
88 let server_keys: Value = serde_json::from_str(message_text).expect("Failed to parse server keys JSON");
90 let server_ecc_pk = server_keys["ecc"].as_str().expect("Parsing server ECC key failed");
91 let server_pq_pk = server_keys["pq"].as_str().expect("Parsing server PQ key failed");
92
93 match config::server_keys_check(&stream.peer_addr().unwrap().ip().to_string(), message_text)
95 {
96 TofuCode::Valid => {},
97
98 status @ (TofuCode::Mismatch | TofuCode::Unknown(_, _)) =>
99 {
100 network::send(stream, MessagePacket
102 {
103 code: Some(MessageCode::Disconnect),
104 ..Default::default()
105 }, None);
106
107 tx.send(ClientEvent::TofuError(status)).unwrap();
109
110 return false;
112 },
113 }
114
115 let (sk, pk) = kex::generate_ephemeral_keys();
117
118 let (pq_ciphertext, pq_secret) = kex::encapsulate_pq(server_pq_pk);
120
121 let response_text = serde_json::json!
123 ({
124 "ecc": pk,
125 "pq": pq_ciphertext,
126 }).to_string();
127
128 network::send(stream, MessagePacket
130 {
131 text: Some(response_text),
132 code: Some(MessageCode::KeyExchange),
133 ..Default::default()
134 }, None);
135
136 *keys = kex::derive_shared_secret(sk, server_ecc_pk.to_string(), pq_secret).expect("Shared secret derivation failed");
138
139 options::set_keys(keys.clone());
141
142 true
143}
144
145pub fn listen_server(stream: &mut TcpStream, tx: Sender<ClientEvent>) {
148 let mut keys = (Zeroizing::new(vec![]), Zeroizing::new(vec![]));
150 if !key_exchange(stream, &mut keys, &tx) { return; }
151
152 let mut min_pass: Option<u64> = None;
154 let mut max_uname: Option<u64> = None;
155 let mut min_uname: Option<u64> = None;
156 let mut server_name: &str;
157
158 let mut invalid_username = false; let mut invalid_password = false;
160
161 let mut disabled_registration = false; let mut first_message = true;
165 let mut extra_space: bool;
166
167 let mut channel = String::new();
168
169 let mut id = 0usize; let mut username: Option<String> = None;
172
173 loop
175 {
176 let read = match network::receive(stream, Some(&keys))
177 {
178 Some(packet) => packet,
179 None => continue
180 };
181
182 extra_space = false; if options::get_extra_space() { tx.send(ClientEvent::ExtraSpace).unwrap(); }
186
187 if let Some(code) = read.code
189 {
190 match code
191 {
192 MessageCode::Version =>
194 {
195 let version = misc::get_version().to_string();
196 let server_version = read.text.unwrap();
197
198 if server_version != version
200 {
201 tx.send(ClientEvent::Info(String::from("Incompatible version! ({version}/{server_version})"), true, 1)).unwrap();
202 }
203
204 network::send(stream, MessagePacket
206 {
207 text: Some(version),
208 code: Some(MessageCode::Version),
209 ..Default::default()
210 }, Some(&keys));
211
212 continue;
213 }
214
215 MessageCode::Welcome =>
217 {
218 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"));
223 max_uname = Some(welcome_json["max_uname"].as_u64().expect("Invalid welcome json"));
224 min_uname = Some(welcome_json["min_uname"].as_u64().expect("Invalid welcome json"));
225 server_name = welcome_json["server_name"].as_str().expect("Invalid welcome json");
226
227 tx.send(ClientEvent::Connected(server_name.to_string())).unwrap();
228 },
229
230 MessageCode::Rekey =>
232 {
233 key_exchange(stream, &mut keys, &tx);
235 }
236
237 MessageCode::Username =>
239 {
240 tx.send(ClientEvent::Clear(2)).unwrap();
241
242 if invalid_username
244 {
245 tx.send(ClientEvent::Clear(2)).unwrap();
246 tx.send(ClientEvent::Info(String::from("Username rejected!"), false, 0)).unwrap();
247 } else {
249 invalid_username = true;
251 }
252
253 tx.send(ClientEvent::Info(format!
254 (
255 "\n\rEnter username ({}):",
256
257 if disabled_registration
258 {
259 String::from("Registration disabled!")
260 } else
261 {
262 format!("a-Z, 0-9; {}-{} characters", min_uname.unwrap(), max_uname.unwrap())
263 }
264 ), true, 0)).unwrap();
265 },
266
267 MessageCode::PasswordR =>
269 {
270 tx.send(ClientEvent::Clear(3)).unwrap();
271 options::set_asking_password(true);
272
273 if invalid_password
275 {
276 tx.send(ClientEvent::Info(format!("Password rejected! Enter at least {} characters.", min_pass.unwrap()), false, 3)).unwrap();
277 } else
278 {
279 invalid_password = true;
280 }
281
282 tx.send(ClientEvent::Info(String::from("\n\rEnter password: (REGISTER)"), true, 0)).unwrap();
283 },
284
285 MessageCode::PasswordL =>
287 {
288 options::set_asking_password(true);
289 tx.send(ClientEvent::Info(String::from("\nEnter password: (LOGIN)"), true, 3)).unwrap();
290 },
291
292 MessageCode::Accept =>
294 {
295 tx.send(ClientEvent::Info(String::from("Login successful. Press Ctrl+H for help.\n"), true, 3)).unwrap();
296
297 id = read.text.unwrap_or("0".to_string()).parse().unwrap();
299
300 options::set_sending_messages(true);
302 },
303
304 MessageCode::Join =>
306 {
307 tx.send(ClientEvent::Clear(2)).unwrap();
308
309 let user = read.text.unwrap();
310
311 if first_message
312 {
313 tx.send(ClientEvent::ExtraSpace).unwrap();
314 username = Some(user.clone());
315 first_message = false;
316 }
317
318 tx.send(ClientEvent::Info(format!("[{}]: {} connected.\n", read.username.unwrap(), user), true, 0)).unwrap();
319 }
320
321 MessageCode::Leave =>
323 {
324 tx.send(ClientEvent::Info(format!("[{}]: {} disconnected.\n", read.username.unwrap(), read.text.unwrap()), true, 2)).unwrap();
325 voice_client::remove_consumer(&read.id.unwrap());
326 },
327
328 MessageCode::Channel =>
330 {
331 voice_client::remove_all_consumers();
333
334 channel = if let Some(c) = read.text
335 {
336 format!("#{c} | ")
337 } else
338 {
339 String::new()
340 };
341
342 tx.send(ClientEvent::Clear(1)).unwrap();
343 },
344
345 MessageCode::Voice =>
347 {
348 if options::socks5_enabled()
349 {
350 tx.send(ClientEvent::Info(String::from("Voice chat cannot be enabled while using SOCKS5.\n"), true, 2)).unwrap();
351 continue;
352 }
353
354 let status = if voice_options::swap_use_voice()
356 {
357 let username = username.clone();
358 let voice_tx = tx.clone();
359 thread::spawn(move || voice_client::listen_server_voice(id, username.unwrap(), voice_tx));
360 "en"
361 } else
362 {
363 "dis"
364 };
365
366 tx.send(ClientEvent::Info(format!("Voice {}abled.\n", status), true, 2)).unwrap();
368 },
369
370 MessageCode::VoiceClients =>
372 {
373 let clients: Vec<(usize, String)> = serde_json::from_str(&read.text.unwrap()).expect("Parsing welcome json failed");
375
376 for (id, username) in clients
378 {
379 voice_client::add_consumer(id, username);
380 }
381 }
382
383 MessageCode::ChannelJoin =>
385 {
386 let joined_id = read.id.unwrap();
387 if voice_options::get_use_voice() && id != joined_id
388 {
389 voice_client::add_consumer(read.id.unwrap(), read.username.unwrap());
390 }
391 },
392
393 MessageCode::ChannelLeave =>
395 {
396 voice_client::remove_consumer(&read.id.unwrap());
397 },
398
399 MessageCode::List =>
401 {
402 if !options::get_extra_space() { tx.send(ClientEvent::ExtraSpace).unwrap(); }
403 tx.send(ClientEvent::Info(String::from("Online clients:"), true, 2)).unwrap();
404
405 let users_json: Value = serde_json::from_str(&read.text.unwrap()).unwrap();
407
408 for user in users_json.as_array().unwrap()
410 {
411 let c = if let Some(c) = user["channel"].as_str().map(String::from)
413 {
414 format!(" | #{c}")
415 } else
416 {
417 String::new()
418 };
419
420 tx.send(ClientEvent::Info(format!("\r{} ({}){}", user["username"].as_str().unwrap(), user["id"], c), true, 0)).unwrap();
421 }
422
423 tx.send(ClientEvent::ExtraSpace).unwrap();
424
425 extra_space = true;
426 options::set_extra_space(true);
427 },
428
429 MessageCode::PrivateMessage =>
431 {
432 tx.send(ClientEvent::Info(format!("[PM FROM] {} ({}): {}\n", read.username.unwrap(), read.id.unwrap(), read.text.unwrap()), true, 2)).unwrap();
433 },
434
435 MessageCode::PrivateMessageBack =>
437 {
438 tx.send(ClientEvent::Info(format!("[PM TO] {} ({}): {}\n", read.username.unwrap(), read.id.unwrap(), read.text.unwrap()), true, 2)).unwrap();
439 },
440
441 MessageCode::SpamWarning =>
443 {
444 tx.send(ClientEvent::Info(String::from("Slow down! You're sending messages too quickly.\n"), true, 2)).unwrap();
445 },
446
447 MessageCode::RegisterDisabled =>
449 {
450 disabled_registration = true;
451 },
452
453 MessageCode::InvalidUsage =>
455 {
456 tx.send(ClientEvent::Info(String::from("Invalid usage! Press Ctrl+H for help.\n"), true, 2)).unwrap();
457 },
458
459 MessageCode::InvalidFeature =>
461 {
462 tx.send(ClientEvent::Info(String::from("Server has disabled the feature you requested.\n"), true, 2)).unwrap();
463 },
464
465 MessageCode::Disconnect =>
467 {
468 tx.send(ClientEvent::Quit).unwrap();
469 return;
470 },
471
472 _ => continue }
474 } else {
476 tx.send(ClientEvent::Message(read)).unwrap();
477 }
478
479 tx.send(ClientEvent::Prompt(channel.clone(), options::INPUT_READ.lock().unwrap().iter().collect::<String>())).unwrap();
481 if !extra_space { options::set_extra_space(false); } }
483}