Compare commits
	
		
			12 commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
							
							
								
								 | 
						e4fd3224cf | ||
| 
							
							
								
								 | 
						5c24ae5f96 | ||
| 
							
							
								
								 | 
						c895210cea | ||
| 
							
							
								
								 | 
						4aed403c97 | ||
| 
							
							
								
								 | 
						247f35994b | ||
| 
							
							
								
								 | 
						6eeeb4a2e8 | ||
| 
							
							
								
								 | 
						2783cc9ca8 | ||
| 
							
							
								
								 | 
						bdb14a5b6d | ||
| 
							
							
								
								 | 
						805caebe35 | ||
| 
							
							
								
								 | 
						b9af753fc7 | ||
| 
							
							
								
								 | 
						e26db6d68b | ||
| 
							
							
								
								 | 
						7c5bc94ade | 
| 
						 | 
					@ -1,7 +1,11 @@
 | 
				
			||||||
[package]
 | 
					[package]
 | 
				
			||||||
name = "e2e-irc"
 | 
					name = "e2e-irc"
 | 
				
			||||||
version = "1.0.2"
 | 
					version = "3.0.0"
 | 
				
			||||||
edition = "2021"
 | 
					edition = "2021"
 | 
				
			||||||
 | 
					license = "GPL-3.0"
 | 
				
			||||||
 | 
					keywords = ["irc", "encryption"]
 | 
				
			||||||
 | 
					description = "An IRC bouncer that can send encrypted messages"
 | 
				
			||||||
 | 
					repository = "https://forgejo.vanten-s.com/vanten-s/e2e-irc/"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 | 
					# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,7 +14,7 @@ argparse = "0.2.2"
 | 
				
			||||||
base64 = "0.21.4"
 | 
					base64 = "0.21.4"
 | 
				
			||||||
dirs = "5.0.1"
 | 
					dirs = "5.0.1"
 | 
				
			||||||
eyre = "0.6.8"
 | 
					eyre = "0.6.8"
 | 
				
			||||||
ircparser = "0.2.1"
 | 
					ircparser-vanten = "0.2.1"
 | 
				
			||||||
openssl = "0.10"
 | 
					openssl = "0.10"
 | 
				
			||||||
pgp = "0.10.2"
 | 
					pgp = "0.10.2"
 | 
				
			||||||
rand = "0.8.5"
 | 
					rand = "0.8.5"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,7 +26,7 @@ Optional arguments:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Install
 | 
					# Install
 | 
				
			||||||
```bash
 | 
					```bash
 | 
				
			||||||
cargo install --git https://forgejo.vanten-s.com/vanten-s/e2e-irc.git
 | 
					cargo install e2e-irc
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Run
 | 
					# Run
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,10 +1,41 @@
 | 
				
			||||||
use crate::helpers::bytes_to_privmsg_base64;
 | 
					use crate::helpers::bytes_to_privmsg_base64;
 | 
				
			||||||
use crate::{encryption, helpers};
 | 
					use crate::{encryption, helpers, State};
 | 
				
			||||||
use eyre::Result;
 | 
					use eyre::Result;
 | 
				
			||||||
use pgp::{Deserializable, SignedPublicKey};
 | 
					use pgp::{Deserializable, SignedPublicKey};
 | 
				
			||||||
use std::collections::HashMap;
 | 
					use std::collections::HashMap;
 | 
				
			||||||
use std::sync::mpsc::{Receiver, Sender};
 | 
					use std::sync::mpsc::{Receiver, Sender};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug)]
 | 
				
			||||||
 | 
					struct InvalidCommand;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl std::fmt::Display for InvalidCommand {
 | 
				
			||||||
 | 
					    fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
				
			||||||
 | 
					        Ok(())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl std::error::Error for InvalidCommand {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn parse_bouncer_command(message: String, state: &mut State) -> Result<()> {
 | 
				
			||||||
 | 
					    macro_rules! unwrap_option {
 | 
				
			||||||
 | 
					        ($t:expr) => {
 | 
				
			||||||
 | 
					            match $t {
 | 
				
			||||||
 | 
					                Some(val) => val,
 | 
				
			||||||
 | 
					                None => return Err(InvalidCommand.into()),
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mut splitted = message.split(' ');
 | 
				
			||||||
 | 
					    match unwrap_option!(splitted.next()) {
 | 
				
			||||||
 | 
					        "ALLOW_UNENCRYPTED" => state
 | 
				
			||||||
 | 
					            .nicks_without_encryption
 | 
				
			||||||
 | 
					            .push(unwrap_option!(splitted.next()).to_string().to_lowercase()),
 | 
				
			||||||
 | 
					        _ => return Err(InvalidCommand.into()),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn handle_message_from_client(
 | 
					pub fn handle_message_from_client(
 | 
				
			||||||
    recieved: &str,
 | 
					    recieved: &str,
 | 
				
			||||||
    public_key: &Vec<u8>,
 | 
					    public_key: &Vec<u8>,
 | 
				
			||||||
| 
						 | 
					@ -14,10 +45,34 @@ pub fn handle_message_from_client(
 | 
				
			||||||
    writer_channel_rx: &Receiver<String>,
 | 
					    writer_channel_rx: &Receiver<String>,
 | 
				
			||||||
    listener_channel_tx: &Sender<String>,
 | 
					    listener_channel_tx: &Sender<String>,
 | 
				
			||||||
    _listener_channel_rx: &Receiver<String>,
 | 
					    _listener_channel_rx: &Receiver<String>,
 | 
				
			||||||
 | 
					    state: &mut State,
 | 
				
			||||||
) -> Result<()> {
 | 
					) -> Result<()> {
 | 
				
			||||||
    let command = &ircparser::parse(recieved).expect("Got an invalid IRC instruction")[0];
 | 
					    let mut recieved = recieved.to_string();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if recieved.split(' ').count() == 1 {
 | 
				
			||||||
 | 
					        recieved += " ";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let parsed = ircparser::parse(&recieved);
 | 
				
			||||||
 | 
					    let command = match parsed {
 | 
				
			||||||
 | 
					        Ok(val) => val[0].clone(),
 | 
				
			||||||
 | 
					        Err(_) => {
 | 
				
			||||||
 | 
					            writer_channel_tx.send(recieved)?;
 | 
				
			||||||
 | 
					            return Ok(());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if command.command == "PRIVMSG" && !command.params[0].starts_with('#') {
 | 
					    if command.command == "PRIVMSG" && !command.params[0].starts_with('#') {
 | 
				
			||||||
 | 
					        if command.params[0] == "BOUNCER" {
 | 
				
			||||||
 | 
					            return parse_bouncer_command(command.params[1].clone(), state);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if state
 | 
				
			||||||
 | 
					            .nicks_without_encryption
 | 
				
			||||||
 | 
					            .contains(&command.params[0].to_lowercase())
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            writer_channel_tx.send(recieved)?;
 | 
				
			||||||
 | 
					            return Ok(());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        let other = &command.params[0];
 | 
					        let other = &command.params[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if !keys.contains_key(other) {
 | 
					        if !keys.contains_key(other) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,7 @@ use eyre::Result;
 | 
				
			||||||
use std::sync::mpsc::{self, Receiver, Sender};
 | 
					use std::sync::mpsc::{self, Receiver, Sender};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug)]
 | 
					#[derive(Debug)]
 | 
				
			||||||
struct IrcParseError;
 | 
					pub struct IrcParseError;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl std::fmt::Display for IrcParseError {
 | 
					impl std::fmt::Display for IrcParseError {
 | 
				
			||||||
    fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
					    fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
				
			||||||
| 
						 | 
					@ -35,6 +35,22 @@ macro_rules! unwrap_or_return_option {
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub struct State {
 | 
				
			||||||
 | 
					    pub nicks_without_encryption: Vec<String>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl State {
 | 
				
			||||||
 | 
					    pub fn new() -> Self {
 | 
				
			||||||
 | 
					        State {
 | 
				
			||||||
 | 
					            nicks_without_encryption: vec![
 | 
				
			||||||
 | 
					                "nickserv".to_string(),
 | 
				
			||||||
 | 
					                "chanserv".to_string(),
 | 
				
			||||||
 | 
					                "hostserv".to_string(),
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn forward(
 | 
					fn forward(
 | 
				
			||||||
    message: String,
 | 
					    message: String,
 | 
				
			||||||
    stream: &Sender<String>,
 | 
					    stream: &Sender<String>,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,5 +54,6 @@ pub fn listen_to_client(tx: mpsc::Sender<String>, rx: mpsc::Receiver<String>, po
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        stream_handler(&tx, &rx, stream);
 | 
					        stream_handler(&tx, &rx, stream);
 | 
				
			||||||
        println!("Closed connection with {ip}");
 | 
					        println!("Closed connection with {ip}");
 | 
				
			||||||
 | 
					        let _ = tx.send("DUMMY CLOSE_CONNECTION".to_string());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										50
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								src/main.rs
									
									
									
									
									
								
							| 
						 | 
					@ -1,10 +1,10 @@
 | 
				
			||||||
use argparse::{ArgumentParser, Store};
 | 
					use argparse::{ArgumentParser, Store};
 | 
				
			||||||
use dirs::config_local_dir;
 | 
					use dirs::config_local_dir;
 | 
				
			||||||
use eyre::Result;
 | 
					use eyre::Result;
 | 
				
			||||||
 | 
					use helpers::State;
 | 
				
			||||||
use pgp::{Deserializable, SignedPublicKey, SignedSecretKey};
 | 
					use pgp::{Deserializable, SignedPublicKey, SignedSecretKey};
 | 
				
			||||||
use std::collections::HashMap;
 | 
					use std::collections::HashMap;
 | 
				
			||||||
use std::fs;
 | 
					use std::fs;
 | 
				
			||||||
use std::net::{Shutdown, TcpStream};
 | 
					 | 
				
			||||||
use std::sync::mpsc;
 | 
					use std::sync::mpsc;
 | 
				
			||||||
use std::thread;
 | 
					use std::thread;
 | 
				
			||||||
use std::time::Duration;
 | 
					use std::time::Duration;
 | 
				
			||||||
| 
						 | 
					@ -55,7 +55,11 @@ fn main() -> Result<()> {
 | 
				
			||||||
        let mut ap = ArgumentParser::new();
 | 
					        let mut ap = ArgumentParser::new();
 | 
				
			||||||
        ap.set_description("Encrypted IRC Bouncer");
 | 
					        ap.set_description("Encrypted IRC Bouncer");
 | 
				
			||||||
        ap.refer(&mut server)
 | 
					        ap.refer(&mut server)
 | 
				
			||||||
            .add_argument("server", Store, "The Address Of The Server The Bouncer Connects To")
 | 
					            .add_argument(
 | 
				
			||||||
 | 
					                "server",
 | 
				
			||||||
 | 
					                Store,
 | 
				
			||||||
 | 
					                "The Address Of The Server The Bouncer Connects To",
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
            .required();
 | 
					            .required();
 | 
				
			||||||
        ap.refer(&mut port)
 | 
					        ap.refer(&mut port)
 | 
				
			||||||
            .add_option(&["-p", "--port"], Store, "The Port The Bouncer Binds To");
 | 
					            .add_option(&["-p", "--port"], Store, "The Port The Bouncer Binds To");
 | 
				
			||||||
| 
						 | 
					@ -67,50 +71,36 @@ fn main() -> Result<()> {
 | 
				
			||||||
        ap.parse_args_or_exit();
 | 
					        ap.parse_args_or_exit();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let server = &server;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let stream = TcpStream::connect(format!("{server}:{server_port}"))?;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let public_key = fs::read(public_key_location)?;
 | 
					    let public_key = fs::read(public_key_location)?;
 | 
				
			||||||
    let secret_key = SignedSecretKey::from_bytes(fs::read(secret_key_location)?.as_slice())?;
 | 
					    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_send_tx, listener_channel_rx) = mpsc::channel();
 | 
				
			||||||
    let (listener_channel_tx, listener_channel_recv_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_tx, writer_channel_send_rx) = mpsc::channel();
 | 
				
			||||||
    let (writer_channel_recv_tx, writer_channel_rx) = mpsc::channel();
 | 
					    let (writer_channel_recv_tx, writer_channel_rx) = mpsc::channel();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let tmp_port = port.clone();
 | 
				
			||||||
    thread::spawn(move || {
 | 
					    thread::spawn(move || {
 | 
				
			||||||
        listener_server::listen_to_client(listener_channel_send_tx, listener_channel_recv_rx, port)
 | 
					        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();
 | 
					    let tmp_server = server.clone();
 | 
				
			||||||
    thread::spawn(|| {
 | 
					    thread::spawn(move || {
 | 
				
			||||||
        writer_client::write_to_server(
 | 
					        writer_client::write_to_server(
 | 
				
			||||||
            writer_stream,
 | 
					            &tmp_server,
 | 
				
			||||||
            tmp_server,
 | 
					            &tmp_port,
 | 
				
			||||||
            writer_channel_send_rx,
 | 
					            writer_channel_send_rx,
 | 
				
			||||||
            writer_channel_recv_tx,
 | 
					            writer_channel_recv_tx,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let mut keys: HashMap<String, SignedPublicKey> = HashMap::new();
 | 
					    let mut keys: HashMap<String, SignedPublicKey> = HashMap::new();
 | 
				
			||||||
 | 
					    let mut state = State::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    loop {
 | 
					    loop {
 | 
				
			||||||
        match listener_channel_rx.try_recv() {
 | 
					        match listener_channel_rx.try_recv() {
 | 
				
			||||||
| 
						 | 
					@ -118,12 +108,13 @@ fn main() -> Result<()> {
 | 
				
			||||||
                let _ = client_handler::handle_message_from_client(
 | 
					                let _ = client_handler::handle_message_from_client(
 | 
				
			||||||
                    &message,
 | 
					                    &message,
 | 
				
			||||||
                    &public_key,
 | 
					                    &public_key,
 | 
				
			||||||
                    server,
 | 
					                    &server,
 | 
				
			||||||
                    &mut keys,
 | 
					                    &mut keys,
 | 
				
			||||||
                    &writer_channel_tx,
 | 
					                    &writer_channel_tx,
 | 
				
			||||||
                    &writer_channel_rx,
 | 
					                    &writer_channel_rx,
 | 
				
			||||||
                    &listener_channel_tx,
 | 
					                    &listener_channel_tx,
 | 
				
			||||||
                    &listener_channel_rx,
 | 
					                    &listener_channel_rx,
 | 
				
			||||||
 | 
					                    &mut state,
 | 
				
			||||||
                );
 | 
					                );
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            Err(error) => match error {
 | 
					            Err(error) => match error {
 | 
				
			||||||
| 
						 | 
					@ -138,13 +129,14 @@ fn main() -> Result<()> {
 | 
				
			||||||
                    &message,
 | 
					                    &message,
 | 
				
			||||||
                    &public_key,
 | 
					                    &public_key,
 | 
				
			||||||
                    &secret_key,
 | 
					                    &secret_key,
 | 
				
			||||||
                    server,
 | 
					                    &server,
 | 
				
			||||||
                    passwd,
 | 
					                    passwd,
 | 
				
			||||||
                    &mut keys,
 | 
					                    &mut keys,
 | 
				
			||||||
                    &writer_channel_tx,
 | 
					                    &writer_channel_tx,
 | 
				
			||||||
                    &writer_channel_rx,
 | 
					                    &writer_channel_rx,
 | 
				
			||||||
                    &listener_channel_tx,
 | 
					                    &listener_channel_tx,
 | 
				
			||||||
                    &listener_channel_rx,
 | 
					                    &listener_channel_rx,
 | 
				
			||||||
 | 
					                    &state,
 | 
				
			||||||
                );
 | 
					                );
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            Err(error) => match error {
 | 
					            Err(error) => match error {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
use crate::unwrap_or_return_option;
 | 
					use crate::unwrap_or_return_option;
 | 
				
			||||||
use crate::unwrap_or_return_result;
 | 
					use crate::unwrap_or_return_result;
 | 
				
			||||||
 | 
					use crate::State;
 | 
				
			||||||
use crate::{encryption, helpers};
 | 
					use crate::{encryption, helpers};
 | 
				
			||||||
use eyre::Result;
 | 
					use eyre::Result;
 | 
				
			||||||
use pgp::{Deserializable, SignedPublicKey, SignedSecretKey};
 | 
					use pgp::{Deserializable, SignedPublicKey, SignedSecretKey};
 | 
				
			||||||
| 
						 | 
					@ -25,15 +26,20 @@ pub fn handle_message_from_server(
 | 
				
			||||||
    writer_channel_rx: &Receiver<String>,
 | 
					    writer_channel_rx: &Receiver<String>,
 | 
				
			||||||
    listener_channel_tx: &Sender<String>,
 | 
					    listener_channel_tx: &Sender<String>,
 | 
				
			||||||
    _listener_channel_rx: &Receiver<String>,
 | 
					    _listener_channel_rx: &Receiver<String>,
 | 
				
			||||||
 | 
					    state: &State,
 | 
				
			||||||
) -> Result<()> {
 | 
					) -> Result<()> {
 | 
				
			||||||
    let recieved_parsed = &unwrap_or_return_result!(ircparser::parse(recieved))[0];
 | 
					    let recieved_parsed = &unwrap_or_return_result!(ircparser::parse(recieved))[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let default_reciever = String::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let reciever = match recieved_parsed.params.get(0) {
 | 
				
			||||||
 | 
					        Some(val) => val,
 | 
				
			||||||
 | 
					        None => &default_reciever,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if recieved_parsed.command != "PRIVMSG"
 | 
					    if recieved_parsed.command != "PRIVMSG"
 | 
				
			||||||
        || recieved_parsed
 | 
					        || reciever.starts_with('#')
 | 
				
			||||||
            .params
 | 
					        || state.nicks_without_encryption.contains(reciever)
 | 
				
			||||||
            .get(0)
 | 
					 | 
				
			||||||
            .unwrap_or(&String::new())
 | 
					 | 
				
			||||||
            .starts_with('#')
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        forward(recieved, listener_channel_tx, server)?;
 | 
					        forward(recieved, listener_channel_tx, server)?;
 | 
				
			||||||
        return Ok(());
 | 
					        return Ok(());
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,54 +6,68 @@ use std::thread;
 | 
				
			||||||
use std::time::Duration;
 | 
					use std::time::Duration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn write_to_server(
 | 
					pub fn write_to_server(
 | 
				
			||||||
    tcp_stream: TcpStream,
 | 
					    server: &str,
 | 
				
			||||||
    server: String,
 | 
					    port: &str,
 | 
				
			||||||
    rx: mpsc::Receiver<String>,
 | 
					    rx: mpsc::Receiver<String>,
 | 
				
			||||||
    tx: mpsc::Sender<String>,
 | 
					    tx: mpsc::Sender<String>,
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    let connector = SslConnector::builder(SslMethod::tls()).unwrap().build();
 | 
					    'big: loop {
 | 
				
			||||||
    let mut stream = connector
 | 
					        println!("Connecting to {server}:{port}");
 | 
				
			||||||
        .connect(&server, tcp_stream)
 | 
					        let tcp_stream =
 | 
				
			||||||
        .expect("Couldn't start TLS");
 | 
					            TcpStream::connect(format!("{server}:{port}")).expect("Couldn't connect to server");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    stream
 | 
					        let connector = SslConnector::builder(SslMethod::tls()).unwrap().build();
 | 
				
			||||||
        .get_mut()
 | 
					        let mut stream = connector
 | 
				
			||||||
        .set_nonblocking(true)
 | 
					            .connect(server, &tcp_stream)
 | 
				
			||||||
        .expect("Failed to set nonblocking");
 | 
					            .expect("Couldn't start TLS");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    loop {
 | 
					        stream
 | 
				
			||||||
        let mut buffer: Vec<u8> = Vec::new();
 | 
					            .get_mut()
 | 
				
			||||||
        let mut buf: [u8; 1] = [0];
 | 
					            .set_nonblocking(true)
 | 
				
			||||||
        let newline: u8 = b'\n';
 | 
					            .expect("Failed to set nonblocking");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        while buf[0] != newline {
 | 
					        loop {
 | 
				
			||||||
            match stream.ssl_read(&mut buf) {
 | 
					            let mut buffer: Vec<u8> = Vec::new();
 | 
				
			||||||
                Ok(_length) => {
 | 
					            let mut buf: [u8; 1] = [0];
 | 
				
			||||||
                    if _length > 0 {
 | 
					            let newline: u8 = b'\n';
 | 
				
			||||||
                        buffer.push(buf[0]);
 | 
					
 | 
				
			||||||
                    }
 | 
					            while buf[0] != newline {
 | 
				
			||||||
                }
 | 
					                match stream.ssl_read(&mut buf) {
 | 
				
			||||||
                Err(_error) => match _error.io_error() {
 | 
					                    Ok(_length) => {
 | 
				
			||||||
                    None => {
 | 
					                        if _length > 0 {
 | 
				
			||||||
                        dbg!(_error.ssl_error());
 | 
					                            buffer.push(buf[0]);
 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    Some(error) => match error.kind() {
 | 
					 | 
				
			||||||
                        ErrorKind::WouldBlock => {}
 | 
					 | 
				
			||||||
                        _ => {
 | 
					 | 
				
			||||||
                            dbg!(error.kind());
 | 
					 | 
				
			||||||
                            println!("Couldn't read the stream");
 | 
					 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    Err(_error) => match _error.io_error() {
 | 
				
			||||||
 | 
					                        None => {
 | 
				
			||||||
 | 
					                            dbg!(_error.ssl_error());
 | 
				
			||||||
 | 
					                            continue 'big;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        Some(error) => match error.kind() {
 | 
				
			||||||
 | 
					                            ErrorKind::WouldBlock => {}
 | 
				
			||||||
 | 
					                            _ => {
 | 
				
			||||||
 | 
					                                dbg!(error.kind());
 | 
				
			||||||
 | 
					                                println!("Couldn't read the stream");
 | 
				
			||||||
 | 
					                                continue 'big;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                },
 | 
					                }
 | 
				
			||||||
 | 
					                let value = rx.try_recv().unwrap_or("".to_string());
 | 
				
			||||||
 | 
					                match value.as_str() {
 | 
				
			||||||
 | 
					                    "DUMMY CLOSE_CONNECTION" => {
 | 
				
			||||||
 | 
					                        continue 'big;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    _ => {}
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                match stream.write_all(value.as_bytes()) {
 | 
				
			||||||
 | 
					                    Ok(_) => {}
 | 
				
			||||||
 | 
					                    Err(_e) => println!("Couldn't send {value}"),
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					                thread::sleep(Duration::from_micros(100));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            let value = rx.try_recv().unwrap_or("".to_string());
 | 
					 | 
				
			||||||
            match stream.write_all(value.as_bytes()) {
 | 
					 | 
				
			||||||
                Ok(_) => {}
 | 
					 | 
				
			||||||
                Err(_e) => println!("Couldn't send {value}"),
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
            thread::sleep(Duration::from_micros(100));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let _ = tx.send(dbg!(String::from_utf8_lossy(&buffer).to_string()));
 | 
					            let _ = tx.send(dbg!(String::from_utf8_lossy(&buffer).to_string()));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue