e2e-irc/src/main.rs

151 lines
4.7 KiB
Rust

use argparse::{ArgumentParser, Store};
use dirs::config_local_dir;
use eyre::Result;
use helpers::State;
use pgp::{Deserializable, SignedPublicKey, SignedSecretKey};
use std::collections::HashMap;
use std::fs;
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
use toml::Table;
mod client_handler;
mod encryption;
mod helpers;
mod listener_server;
mod server_handler;
mod writer_client;
fn main() -> Result<()> {
let config_file = config_local_dir()
.expect("Couldn't get config directory")
.join("e2e-irc/config.toml");
if !config_file.exists() {
panic!("Create a config file at {}", config_file.display());
}
let parsed_config = String::from_utf8_lossy(&fs::read(config_file)?).parse::<Table>()?;
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");
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();
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();
}
let public_key = fs::read(public_key_location)?;
let secret_key = SignedSecretKey::from_bytes(fs::read(secret_key_location)?.as_slice())?;
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();
let tmp_port = port.clone();
thread::spawn(move || {
listener_server::listen_to_client(
listener_channel_send_tx,
listener_channel_recv_rx,
tmp_port,
)
});
let tmp_port = server_port.clone();
let tmp_server = server.clone();
thread::spawn(move || {
writer_client::write_to_server(
&tmp_server,
&tmp_port,
writer_channel_send_rx,
writer_channel_recv_tx,
)
});
let mut keys: HashMap<String, SignedPublicKey> = HashMap::new();
let mut state = State::new();
loop {
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,
&mut state,
);
}
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,
&state,
);
}
Err(error) => match error {
mpsc::TryRecvError::Empty => {}
mpsc::TryRecvError::Disconnected => panic!("writer_channel_rx disconnected"),
},
};
thread::sleep(Duration::from_millis(1));
}
}