e2e-irc/src/main.rs

159 lines
5 KiB
Rust
Raw Normal View History

2023-10-19 17:08:05 +02:00
use argparse::{ArgumentParser, Store};
use dirs::config_local_dir;
2023-10-12 21:26:52 +02:00
use eyre::Result;
2023-10-12 13:59:07 +02:00
use pgp::{Deserializable, SignedPublicKey, SignedSecretKey};
use std::collections::HashMap;
use std::fs;
use std::net::{Shutdown, TcpStream};
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
2023-10-19 17:08:05 +02:00
use toml::Table;
2023-10-12 13:59:07 +02:00
mod client_handler;
mod encryption;
mod helpers;
mod listener_server;
2023-10-12 13:59:07 +02:00
mod server_handler;
mod writer_client;
2023-10-12 13:59:07 +02:00
fn main() -> Result<()> {
2023-10-19 17:08:05 +02:00
let config_file = config_local_dir()
.expect("Couldn't get config directory")
.join("e2e-irc/config.toml");
2023-10-19 17:08:05 +02:00
if !config_file.exists() {
panic!("Create a config file at {}", config_file.display());
}
2023-10-19 17:08:05 +02:00
let parsed_config = String::from_utf8_lossy(&fs::read(config_file)?).parse::<Table>()?;
2023-10-19 17:08:05 +02:00
let public_key_location = parsed_config
.get("public_key")
.expect("Coudln't get public_key. Try creating it in the config")
.as_str()
.expect("Couldn't convert public_key to str");
let secret_key_location = parsed_config
.get("secret_key")
.expect("Coudln't get secret_key. Try creating it in the config")
.as_str()
.expect("Couldn't convert secret_key to str");
2023-10-19 17:08:05 +02:00
let default_password = toml::Value::String(String::new());
let passwd = parsed_config
.get("passwd")
.unwrap_or(&default_password)
.as_str()
.expect("Coudln't convert passwd to str");
let mut server = "irc.vanten-s.com".to_string();
let mut port = "6666".to_string();
let mut server_port = "6697".to_string();
{
let mut ap = ArgumentParser::new();
ap.set_description("Encrypted IRC Bouncer");
ap.refer(&mut server)
.add_argument("server", Store, "The Address Of The Server The Bouncer Connects To")
.required();
2023-10-19 17:08:05 +02:00
ap.refer(&mut port)
.add_option(&["-p", "--port"], Store, "The Port The Bouncer Binds To");
ap.refer(&mut server_port).add_option(
&["--sp", "--server-port"],
Store,
"The TLS Enabled Port Of The Server",
);
ap.parse_args_or_exit();
}
2023-10-05 22:57:26 +02:00
2023-10-19 17:08:05 +02:00
let server = &server;
2023-10-19 17:08:05 +02:00
let stream = TcpStream::connect(format!("{server}:{server_port}"))?;
2023-10-19 17:08:05 +02:00
let public_key = fs::read(public_key_location)?;
let secret_key = SignedSecretKey::from_bytes(fs::read(secret_key_location)?.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();
2023-10-05 22:57:26 +02:00
thread::spawn(move || {
listener_server::listen_to_client(listener_channel_send_tx, listener_channel_recv_rx, port)
});
2023-10-05 22:57:26 +02:00
let tmp_server = server.clone();
thread::spawn(|| {
writer_client::write_to_server(
writer_stream,
2023-10-05 22:57:26 +02:00
tmp_server,
writer_channel_send_rx,
writer_channel_recv_tx,
)
});
2023-10-05 21:16:34 +02:00
let mut keys: HashMap<String, SignedPublicKey> = HashMap::new();
loop {
2023-10-12 13:59:07 +02:00
match listener_channel_rx.try_recv() {
Ok(message) => {
let _ = client_handler::handle_message_from_client(
&message,
&public_key,
server,
&mut keys,
&writer_channel_tx,
&writer_channel_rx,
&listener_channel_tx,
&listener_channel_rx,
);
}
2023-10-12 13:59:07 +02:00
Err(error) => match error {
mpsc::TryRecvError::Empty => {}
mpsc::TryRecvError::Disconnected => panic!("listener_channel_rx disconnected"),
},
};
match writer_channel_rx.try_recv() {
Ok(message) => {
let _ = 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,
);
}
2023-10-12 13:59:07 +02:00
Err(error) => match error {
mpsc::TryRecvError::Empty => {}
mpsc::TryRecvError::Disconnected => panic!("writer_channel_rx disconnected"),
},
};
2023-10-05 22:57:26 +02:00
2023-10-12 22:01:17 +02:00
thread::sleep(Duration::from_millis(1));
}
}