use eyre::Result; use pgp::{Deserializable, SignedPublicKey, SignedSecretKey}; use std::collections::HashMap; use std::net::{Shutdown, TcpStream}; use std::sync::mpsc; use std::thread; use std::time::Duration; use std::{env, fs}; mod client_handler; mod encryption; mod helpers; mod listener_server; mod server_handler; mod writer_client; fn main() -> Result<()> { let mut args = env::args().collect::>(); let server = args[1].clone(); let port = args[2].clone(); let default_password = String::new(); let passwd = args.pop().unwrap_or(default_password); let stream = TcpStream::connect(format!("{server}:6697"))?; let public_key = fs::read("public.gpg")?; let secret_key = SignedSecretKey::from_bytes(fs::read("secret.gpg")?.as_slice())?; let reader_stream = match stream.try_clone() { Ok(stream) => stream, Err(_error) => { let _ = stream.shutdown(Shutdown::Both); panic!("Failed to create the reader stream") } }; let writer_stream = match stream.try_clone() { Ok(stream) => stream, Err(_error) => { let _ = stream.shutdown(Shutdown::Both); let _ = reader_stream.shutdown(Shutdown::Both); panic!("Failed to create the writer stream") } }; let (listener_channel_send_tx, listener_channel_rx) = mpsc::channel(); let (listener_channel_tx, listener_channel_recv_rx) = mpsc::channel(); let (writer_channel_tx, writer_channel_send_rx) = mpsc::channel(); let (writer_channel_recv_tx, writer_channel_rx) = mpsc::channel(); thread::spawn(move || { listener_server::listen_to_client(listener_channel_send_tx, listener_channel_recv_rx, &port) }); let tmp_server = server.clone(); thread::spawn(|| { writer_client::write_to_server( writer_stream, tmp_server, writer_channel_send_rx, writer_channel_recv_tx, ) }); let mut keys: HashMap = HashMap::new(); loop { match listener_channel_rx.try_recv() { Ok(message) => client_handler::handle_message_from_client( &message, &public_key, &server, &mut keys, &writer_channel_tx, &writer_channel_rx, &listener_channel_tx, &listener_channel_rx, )?, Err(error) => match error { mpsc::TryRecvError::Empty => {} mpsc::TryRecvError::Disconnected => panic!("listener_channel_rx disconnected"), }, }; match writer_channel_rx.try_recv() { Ok(message) => server_handler::handle_message_from_server( &message, &public_key, &secret_key, &server, &passwd, &mut keys, &writer_channel_tx, &writer_channel_rx, &listener_channel_tx, &listener_channel_rx, )?, Err(error) => match error { mpsc::TryRecvError::Empty => {} mpsc::TryRecvError::Disconnected => panic!("writer_channel_rx disconnected"), }, }; thread::sleep(Duration::from_millis(100)); } }