New MAJOR version
This commit is contained in:
parent
87f2b142c9
commit
df0b58018d
17
Cargo.lock
generated
17
Cargo.lock
generated
|
@ -437,6 +437,16 @@ dependencies = [
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "eyre"
|
||||||
|
version = "0.6.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb"
|
||||||
|
dependencies = [
|
||||||
|
"indenter",
|
||||||
|
"once_cell",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ff"
|
name = "ff"
|
||||||
version = "0.13.0"
|
version = "0.13.0"
|
||||||
|
@ -579,6 +589,12 @@ version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indenter"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "inout"
|
name = "inout"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
|
@ -593,6 +609,7 @@ name = "irc-e2e"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
|
"eyre",
|
||||||
"ircparser",
|
"ircparser",
|
||||||
"openssl",
|
"openssl",
|
||||||
"pgp",
|
"pgp",
|
||||||
|
|
|
@ -7,6 +7,7 @@ edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
base64 = "0.21.4"
|
base64 = "0.21.4"
|
||||||
|
eyre = "0.6.8"
|
||||||
ircparser = "0.2.1"
|
ircparser = "0.2.1"
|
||||||
openssl = "0.10"
|
openssl = "0.10"
|
||||||
pgp = "0.10.2"
|
pgp = "0.10.2"
|
||||||
|
|
49
src/client_handler.rs
Normal file
49
src/client_handler.rs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
use crate::helpers::bytes_to_privmsg_base64;
|
||||||
|
use crate::{encryption, helpers};
|
||||||
|
use pgp::{Deserializable, SignedPublicKey};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::sync::mpsc::{Receiver, Sender};
|
||||||
|
use eyre::Result;
|
||||||
|
|
||||||
|
pub fn handle_message_from_client(
|
||||||
|
recieved: &str,
|
||||||
|
public_key: &Vec<u8>,
|
||||||
|
server: &str,
|
||||||
|
keys: &mut HashMap<String, SignedPublicKey>,
|
||||||
|
writer_channel_tx: &Sender<String>,
|
||||||
|
writer_channel_rx: &Receiver<String>,
|
||||||
|
listener_channel_tx: &Sender<String>,
|
||||||
|
_listener_channel_rx: &Receiver<String>,
|
||||||
|
) -> Result<()> {
|
||||||
|
let command = &ircparser::parse(recieved).expect("Got an invalid IRC instruction")[0];
|
||||||
|
|
||||||
|
if command.command == "PRIVMSG" && !command.params[0].starts_with("#") {
|
||||||
|
let other = &command.params[0];
|
||||||
|
|
||||||
|
if !keys.contains_key(other) {
|
||||||
|
helpers::send_key(writer_channel_tx, other, public_key)?;
|
||||||
|
let key = helpers::recieve_message_base64(
|
||||||
|
writer_channel_rx,
|
||||||
|
listener_channel_tx,
|
||||||
|
"127.0.0.1",
|
||||||
|
server,
|
||||||
|
&other,
|
||||||
|
"END_KEY",
|
||||||
|
)?;
|
||||||
|
let key = SignedPublicKey::from_bytes(key.as_slice())?;
|
||||||
|
keys.insert(other.to_string(), key);
|
||||||
|
}
|
||||||
|
|
||||||
|
let foreign_key = keys.get(other).unwrap();
|
||||||
|
|
||||||
|
writer_channel_tx.send(format!("PRIVMSG {other} START_MESSAGE\r\n"))?;
|
||||||
|
writer_channel_tx.send(bytes_to_privmsg_base64(
|
||||||
|
&encryption::encrypt(&foreign_key, &command.params[1])?,
|
||||||
|
other,
|
||||||
|
))?;
|
||||||
|
writer_channel_tx.send(format!("PRIVMSG {other} END_MESSAGE\r\n"))?;
|
||||||
|
} else {
|
||||||
|
writer_channel_tx.send(recieved.replace("127.0.0.1", &server))?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
29
src/encryption.rs
Normal file
29
src/encryption.rs
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
use pgp::crypto::sym::SymmetricKeyAlgorithm;
|
||||||
|
use pgp::ser::Serialize;
|
||||||
|
use pgp::{Deserializable, Message, SignedPublicKey, SignedSecretKey};
|
||||||
|
use rand::prelude::*;
|
||||||
|
use eyre::Result;
|
||||||
|
|
||||||
|
pub fn encrypt(key: &SignedPublicKey, message: &str) -> Result<Vec<u8>, pgp::errors::Error> {
|
||||||
|
let message = Message::new_literal("none", message);
|
||||||
|
let mut rng = StdRng::from_entropy();
|
||||||
|
|
||||||
|
let message = message.encrypt_to_keys(&mut rng, SymmetricKeyAlgorithm::AES128, &[key])?;
|
||||||
|
|
||||||
|
Ok(message.to_bytes()?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn decrypt<'a>(
|
||||||
|
key: &'a SignedSecretKey,
|
||||||
|
message: Vec<u8>,
|
||||||
|
password: &'a str,
|
||||||
|
) -> Result<String, pgp::errors::Error> {
|
||||||
|
let message = Message::from_bytes(message.as_slice())?; // Convert message bytes to message object
|
||||||
|
let message = message.decrypt(|| password.to_string(), &[key])?.0; // Decrypt
|
||||||
|
let message = message.map(|x| x.unwrap()).collect::<Vec<Message>>(); // Get all messages
|
||||||
|
let message = &message[0]; // Get first message
|
||||||
|
let message = message.get_content()?.unwrap_or(Vec::new()); // Get message content as Vec<u8>
|
||||||
|
let message = String::from_utf8(message).unwrap(); // Convert to String
|
||||||
|
|
||||||
|
Ok(message)
|
||||||
|
}
|
92
src/helpers.rs
Normal file
92
src/helpers.rs
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
use base64::{engine::general_purpose, Engine as _};
|
||||||
|
use std::sync::mpsc::{self, Receiver, Sender};
|
||||||
|
use eyre::Result;
|
||||||
|
use ircparser;
|
||||||
|
|
||||||
|
static MAX_LENGTH: usize = 300;
|
||||||
|
|
||||||
|
fn forward(
|
||||||
|
message: &str,
|
||||||
|
stream: &Sender<String>,
|
||||||
|
server_local: &str,
|
||||||
|
server_forward: &str,
|
||||||
|
) -> Result<(), mpsc::SendError<String>> {
|
||||||
|
if ircparser::parse(message).unwrap()[0].command == "PRIVMSG" {
|
||||||
|
return Ok(())
|
||||||
|
}
|
||||||
|
stream.send(message.replace(&server_local, server_forward))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_to_privmsg_base64(message: &Vec<u8>, reciever: &str) -> String {
|
||||||
|
let message_length = MAX_LENGTH - format!("PRIVMSG {reciever} :\r\n").len();
|
||||||
|
let encoded = general_purpose::STANDARD.encode(message);
|
||||||
|
|
||||||
|
let mut command = String::new();
|
||||||
|
for line in encoded
|
||||||
|
.chars()
|
||||||
|
.collect::<Vec<char>>()
|
||||||
|
.chunks(message_length)
|
||||||
|
.map(|c| c.iter().collect::<String>())
|
||||||
|
{
|
||||||
|
dbg!(&line);
|
||||||
|
command.push_str(&format!("PRIVMSG {reciever} :{line}\r\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("{}", encoded);
|
||||||
|
println!("{}", command);
|
||||||
|
command
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn send_key(
|
||||||
|
sender: &Sender<String>,
|
||||||
|
reciever: &str,
|
||||||
|
key: &Vec<u8>,
|
||||||
|
) -> Result<()> {
|
||||||
|
sender.send(format!("PRIVMSG {reciever} :START_KEY\r\n"))?;
|
||||||
|
sender.send(bytes_to_privmsg_base64(key, reciever))?;
|
||||||
|
sender.send(format!("PRIVMSG {reciever} :END_KEY\r\n"))?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_nick(userstring: &str) -> String {
|
||||||
|
let userstring = userstring.chars().collect::<Vec<char>>();
|
||||||
|
let start_pos = userstring.iter().position(|&x| x == ':').unwrap() + 1;
|
||||||
|
let end_pos = userstring.iter().position(|&x| x == '!').unwrap();
|
||||||
|
userstring[start_pos..end_pos].iter().collect::<String>()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn recieve_message_base64(
|
||||||
|
writer_channel_rx: &Receiver<String>,
|
||||||
|
forward_stream: &Sender<String>,
|
||||||
|
server_local: &str,
|
||||||
|
server_forward: &str,
|
||||||
|
sender: &str,
|
||||||
|
end: &str,
|
||||||
|
) -> Result<Vec<u8>> {
|
||||||
|
let mut message: Vec<String> = Vec::new();
|
||||||
|
|
||||||
|
while !message.contains(&end.to_string()) {
|
||||||
|
let recieved_raw = writer_channel_rx.recv()?;
|
||||||
|
|
||||||
|
let recieved = &ircparser::parse(&recieved_raw).unwrap()[0];
|
||||||
|
let begin_source_reciever = format!(":{sender}!");
|
||||||
|
if recieved.command != "PRIVMSG"
|
||||||
|
|| !recieved
|
||||||
|
.source
|
||||||
|
.clone()
|
||||||
|
.unwrap_or("".to_string())
|
||||||
|
.starts_with(&begin_source_reciever) || recieved.params[0].starts_with("#")
|
||||||
|
{
|
||||||
|
forward(&recieved_raw, forward_stream, server_local, server_forward)?;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
message.push(recieved.params[1].clone());
|
||||||
|
}
|
||||||
|
message.pop();
|
||||||
|
|
||||||
|
let foreign_key = dbg!(message.concat());
|
||||||
|
let foreign_key = general_purpose::STANDARD.decode(foreign_key)?;
|
||||||
|
Ok(foreign_key)
|
||||||
|
}
|
|
@ -1,6 +1,8 @@
|
||||||
use std::io::{ErrorKind, Read, Write};
|
use std::io::{ErrorKind, Read, Write};
|
||||||
use std::net::TcpListener;
|
use std::net::TcpListener;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
|
use std::thread;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
pub fn listen_to_client(tx: mpsc::Sender<String>, rx: mpsc::Receiver<String>, port: &str) {
|
pub fn listen_to_client(tx: mpsc::Sender<String>, rx: mpsc::Receiver<String>, port: &str) {
|
||||||
let listener = TcpListener::bind("127.0.0.1:".to_string() + port).unwrap();
|
let listener = TcpListener::bind("127.0.0.1:".to_string() + port).unwrap();
|
||||||
|
@ -19,7 +21,7 @@ pub fn listen_to_client(tx: mpsc::Sender<String>, rx: mpsc::Receiver<String>, po
|
||||||
match stream.read(&mut buf) {
|
match stream.read(&mut buf) {
|
||||||
Ok(_length) => buffer.push(buf[0]),
|
Ok(_length) => buffer.push(buf[0]),
|
||||||
Err(_error) => match _error.kind() {
|
Err(_error) => match _error.kind() {
|
||||||
ErrorKind::WouldBlock => {},
|
ErrorKind::WouldBlock => {}
|
||||||
_ => {
|
_ => {
|
||||||
dbg!(_error);
|
dbg!(_error);
|
||||||
}
|
}
|
||||||
|
@ -37,5 +39,6 @@ pub fn listen_to_client(tx: mpsc::Sender<String>, rx: mpsc::Receiver<String>, po
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = tx.send(String::from_utf8_lossy(&buffer).to_string());
|
let _ = tx.send(String::from_utf8_lossy(&buffer).to_string());
|
||||||
|
thread::sleep(Duration::from_millis(100));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
262
src/main.rs
262
src/main.rs
|
@ -1,81 +1,20 @@
|
||||||
use base64::{engine::general_purpose, Engine as _};
|
use pgp::{Deserializable, SignedPublicKey, SignedSecretKey};
|
||||||
use ircparser;
|
|
||||||
use pgp::crypto::sym::SymmetricKeyAlgorithm;
|
|
||||||
use pgp::ser::Serialize;
|
|
||||||
use pgp::{Deserializable, Message, SignedPublicKey, SignedSecretKey};
|
|
||||||
use rand::prelude::*;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::net::{Shutdown, TcpStream};
|
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;
|
||||||
use std::{env, fs};
|
use std::{env, fs};
|
||||||
|
use eyre::Result;
|
||||||
|
|
||||||
|
mod client_handler;
|
||||||
|
mod encryption;
|
||||||
|
mod helpers;
|
||||||
mod listener_server;
|
mod listener_server;
|
||||||
|
mod server_handler;
|
||||||
mod writer_client;
|
mod writer_client;
|
||||||
|
|
||||||
macro_rules! try_recv {
|
fn main() -> Result<()> {
|
||||||
($rx:ident) => {
|
|
||||||
match $rx.try_recv() {
|
|
||||||
Ok(recieved) => recieved,
|
|
||||||
Err(_e) => match _e {
|
|
||||||
mpsc::TryRecvError::Empty => String::new(),
|
|
||||||
mpsc::TryRecvError::Disconnected => {
|
|
||||||
panic!("Error!")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bytes_to_privmsg_base64(message: Vec<u8>, reciever: &str) -> String {
|
|
||||||
let mut command = String::new();
|
|
||||||
for line in general_purpose::STANDARD
|
|
||||||
.encode(message)
|
|
||||||
.chars()
|
|
||||||
.collect::<Vec<char>>()
|
|
||||||
.chunks(500)
|
|
||||||
.map(|c| c.iter().collect::<String>())
|
|
||||||
{
|
|
||||||
command.push_str(&format!("PRIVMSG {reciever} :{line}\r\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("{}", command);
|
|
||||||
command
|
|
||||||
}
|
|
||||||
|
|
||||||
fn encrypt(key: &SignedPublicKey, message: &str) -> Result<Vec<u8>, pgp::errors::Error> {
|
|
||||||
let message = Message::new_literal("none", message);
|
|
||||||
let mut rng = StdRng::from_entropy();
|
|
||||||
|
|
||||||
let message = message.encrypt_to_keys(&mut rng, SymmetricKeyAlgorithm::AES128, &[key])?;
|
|
||||||
|
|
||||||
Ok(message.to_bytes()?)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn decrypt<'a>(
|
|
||||||
key: &'a SignedSecretKey,
|
|
||||||
message: Vec<u8>,
|
|
||||||
password: &'a str,
|
|
||||||
) -> Result<String, pgp::errors::Error> {
|
|
||||||
let message = Message::from_bytes(message.as_slice())?; // Convert message bytes to message object
|
|
||||||
let message = message.decrypt(|| password.to_string(), &[key])?.0; // Decrypt
|
|
||||||
let message = message.map(|x| x.unwrap()).collect::<Vec<Message>>(); // Get all messages
|
|
||||||
let message = &message[0]; // Get first message
|
|
||||||
let message = message.get_content()?.unwrap_or(Vec::new()); // Get message content as Vec<u8>
|
|
||||||
let message = String::from_utf8(message).unwrap(); // Convert to String
|
|
||||||
|
|
||||||
Ok(message)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_nick(userstring: &str) -> String {
|
|
||||||
let userstring = userstring.chars().collect::<Vec<char>>();
|
|
||||||
let start_pos = userstring.iter().position(|&x| x == ':').unwrap() + 1;
|
|
||||||
let end_pos = userstring.iter().position(|&x| x == '!').unwrap();
|
|
||||||
userstring[start_pos..end_pos].iter().collect::<String>()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
let mut args = env::args().collect::<Vec<String>>();
|
let mut args = env::args().collect::<Vec<String>>();
|
||||||
|
|
||||||
let server = args[1].clone();
|
let server = args[1].clone();
|
||||||
|
@ -126,161 +65,44 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut keys: HashMap<String, SignedPublicKey> = HashMap::new();
|
let mut keys: HashMap<String, SignedPublicKey> = HashMap::new();
|
||||||
let mut userstring = String::new();
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let recieved = try_recv!(listener_channel_rx);
|
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"),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
if !recieved.is_empty() {
|
match writer_channel_rx.try_recv() {
|
||||||
let command = &ircparser::parse(&recieved).expect("Got an invalid IRC instruction")[0];
|
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"),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
if command.command == "PRIVMSG" && !command.params[0].starts_with("#") {
|
thread::sleep(Duration::from_millis(100));
|
||||||
let reciever = &command.params[0];
|
|
||||||
if !keys.contains_key(reciever) {
|
|
||||||
writer_channel_tx.send(format!("PRIVMSG {reciever} :START_KEY\r\n"))?;
|
|
||||||
|
|
||||||
writer_channel_tx
|
|
||||||
.send(bytes_to_privmsg_base64(public_key.clone(), reciever))?;
|
|
||||||
writer_channel_tx.send(format!("PRIVMSG {reciever} :END_KEY\r\n"))?;
|
|
||||||
|
|
||||||
let mut foreign_key: Vec<String> = Vec::new();
|
|
||||||
while !foreign_key.contains(&"END_KEY".to_string()) {
|
|
||||||
let recieved_raw = writer_channel_rx.recv()?;
|
|
||||||
|
|
||||||
let recieved = &ircparser::parse(&recieved_raw).unwrap()[0];
|
|
||||||
let begin_source_reciever = format!(":{reciever}!");
|
|
||||||
if recieved.command != "PRIVMSG"
|
|
||||||
|| !recieved
|
|
||||||
.source
|
|
||||||
.clone()
|
|
||||||
.unwrap_or("".to_string())
|
|
||||||
.starts_with(&begin_source_reciever)
|
|
||||||
{
|
|
||||||
listener_channel_tx.send(recieved_raw)?;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreign_key.push(recieved.params[1].clone());
|
|
||||||
}
|
|
||||||
foreign_key.pop();
|
|
||||||
|
|
||||||
println!("Got a foreign key from {reciever}");
|
|
||||||
let foreign_key = foreign_key.concat();
|
|
||||||
dbg!(&foreign_key);
|
|
||||||
|
|
||||||
let foreign_key = general_purpose::STANDARD.decode(foreign_key)?;
|
|
||||||
|
|
||||||
dbg!("It's decoded");
|
|
||||||
|
|
||||||
let key = SignedPublicKey::from_bytes(foreign_key.as_slice())?;
|
|
||||||
|
|
||||||
dbg!("And I now got it's SignedPublicKey format");
|
|
||||||
|
|
||||||
keys.insert(reciever.to_string(), key);
|
|
||||||
}
|
|
||||||
|
|
||||||
let foreign_key = keys.get(reciever).unwrap();
|
|
||||||
|
|
||||||
writer_channel_tx.send(format!("PRIVMSG {reciever} START_MESSAGE\r\n"))?;
|
|
||||||
writer_channel_tx.send(bytes_to_privmsg_base64(
|
|
||||||
encrypt(&foreign_key, &command.params[1])?,
|
|
||||||
reciever,
|
|
||||||
))?;
|
|
||||||
writer_channel_tx.send(format!("PRIVMSG {reciever} END_MESSAGE\r\n"))?;
|
|
||||||
} else {
|
|
||||||
writer_channel_tx.send(recieved.replace("127.0.0.1", &server))?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let recieved = try_recv!(writer_channel_rx);
|
|
||||||
if !recieved.is_empty() {
|
|
||||||
let recieved_parsed = &ircparser::parse(&recieved).unwrap()[0];
|
|
||||||
|
|
||||||
if recieved_parsed.command != "PRIVMSG"
|
|
||||||
|| recieved_parsed
|
|
||||||
.params
|
|
||||||
.get(0)
|
|
||||||
.unwrap_or(&String::new())
|
|
||||||
.starts_with("#")
|
|
||||||
{
|
|
||||||
listener_channel_tx.send(recieved.replace(&server, "127.0.0.1"))?;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
dbg!(&recieved_parsed);
|
|
||||||
|
|
||||||
if recieved_parsed.params[1] == "START_MESSAGE" {
|
|
||||||
let reciever = get_nick(&recieved_parsed.source.clone().unwrap());
|
|
||||||
let sample_privmsg = recieved.clone();
|
|
||||||
|
|
||||||
let mut encrypted_message: Vec<String> = Vec::new();
|
|
||||||
while !encrypted_message.contains(&"END_MESSAGE".to_string()) {
|
|
||||||
let recieved_raw = writer_channel_rx.recv()?;
|
|
||||||
let recieved = &ircparser::parse(&recieved_raw).unwrap()[0];
|
|
||||||
|
|
||||||
let begin_source_reciever = format!(":{reciever}!");
|
|
||||||
if recieved.command != "PRIVMSG"
|
|
||||||
|| !recieved
|
|
||||||
.source
|
|
||||||
.clone()
|
|
||||||
.unwrap_or("".to_string())
|
|
||||||
.starts_with(&begin_source_reciever)
|
|
||||||
{
|
|
||||||
listener_channel_tx.send(recieved_raw.replace(&server, "127.0.0.1"))?;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
encrypted_message.push(recieved.params[1].clone());
|
|
||||||
}
|
|
||||||
encrypted_message.pop();
|
|
||||||
|
|
||||||
let encrypted_message = encrypted_message.join("");
|
|
||||||
let encrypted_message = general_purpose::STANDARD.decode(encrypted_message)?;
|
|
||||||
|
|
||||||
let decrypted_message = decrypt(&secret_key, encrypted_message, &passwd)?;
|
|
||||||
listener_channel_tx
|
|
||||||
.send(sample_privmsg.replace("START_MESSAGE", &decrypted_message))?;
|
|
||||||
} else if recieved_parsed.params[1] == "START_KEY" {
|
|
||||||
let reciever = get_nick(&recieved_parsed.source.clone().unwrap());
|
|
||||||
let to_send = bytes_to_privmsg_base64(public_key.clone(), &reciever);
|
|
||||||
writer_channel_tx.send(to_send)?;
|
|
||||||
writer_channel_tx.send(format!("PRIVMSG {reciever} END_KEY\r\n"))?;
|
|
||||||
|
|
||||||
dbg!("Started Getting a key");
|
|
||||||
let reciever = get_nick(&recieved_parsed.source.clone().unwrap());
|
|
||||||
let mut foreign_key: Vec<String> = Vec::new();
|
|
||||||
while !foreign_key.contains(&"END_KEY".to_string()) {
|
|
||||||
let recieved_raw = writer_channel_rx.recv()?;
|
|
||||||
|
|
||||||
let recieved = &ircparser::parse(&recieved_raw).unwrap()[0];
|
|
||||||
let begin_source_reciever = format!(":{reciever}!");
|
|
||||||
if recieved.command != "PRIVMSG"
|
|
||||||
|| !recieved
|
|
||||||
.source
|
|
||||||
.clone()
|
|
||||||
.unwrap_or("".to_string())
|
|
||||||
.starts_with(&begin_source_reciever)
|
|
||||||
{
|
|
||||||
listener_channel_tx.send(recieved_raw.replace(&server, "127.0.0.1"))?;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreign_key.push(recieved.params[1].clone());
|
|
||||||
}
|
|
||||||
foreign_key.pop();
|
|
||||||
dbg!("Got a foreign key from");
|
|
||||||
dbg!(&reciever);
|
|
||||||
|
|
||||||
let foreign_key = foreign_key.concat();
|
|
||||||
|
|
||||||
let foreign_key = general_purpose::STANDARD.decode(foreign_key)?;
|
|
||||||
dbg!("Decoded the key");
|
|
||||||
|
|
||||||
let key = SignedPublicKey::from_bytes(foreign_key.as_slice())?;
|
|
||||||
dbg!("Deserialized the key");
|
|
||||||
|
|
||||||
keys.insert(reciever.to_string(), key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
77
src/server_handler.rs
Normal file
77
src/server_handler.rs
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
use crate::{encryption, helpers};
|
||||||
|
use pgp::{Deserializable, SignedPublicKey, SignedSecretKey};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::sync::mpsc::{self, Receiver, Sender};
|
||||||
|
use eyre::Result as Result;
|
||||||
|
|
||||||
|
fn forward(
|
||||||
|
message: &str,
|
||||||
|
listener_channel_tx: &Sender<String>,
|
||||||
|
server: &str,
|
||||||
|
) -> Result<(), mpsc::SendError<String>> {
|
||||||
|
listener_channel_tx.send(message.replace(&server, "127.0.0.1"))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_message_from_server(
|
||||||
|
recieved: &str,
|
||||||
|
public_key: &Vec<u8>,
|
||||||
|
secret_key: &SignedSecretKey,
|
||||||
|
server: &str,
|
||||||
|
passwd: &str,
|
||||||
|
keys: &mut HashMap<String, SignedPublicKey>,
|
||||||
|
writer_channel_tx: &Sender<String>,
|
||||||
|
writer_channel_rx: &Receiver<String>,
|
||||||
|
listener_channel_tx: &Sender<String>,
|
||||||
|
_listener_channel_rx: &Receiver<String>,
|
||||||
|
) -> Result<()> {
|
||||||
|
let recieved_parsed = &ircparser::parse(&recieved).unwrap()[0];
|
||||||
|
|
||||||
|
if recieved_parsed.command != "PRIVMSG"
|
||||||
|
|| recieved_parsed
|
||||||
|
.params
|
||||||
|
.get(0)
|
||||||
|
.unwrap_or(&String::new())
|
||||||
|
.starts_with("#")
|
||||||
|
{
|
||||||
|
forward(recieved, listener_channel_tx, server)?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
dbg!(&recieved_parsed);
|
||||||
|
|
||||||
|
if recieved_parsed.params[1] == "START_MESSAGE" {
|
||||||
|
let sender = helpers::get_nick(&recieved_parsed.source.clone().unwrap());
|
||||||
|
|
||||||
|
let message = helpers::recieve_message_base64(
|
||||||
|
writer_channel_rx,
|
||||||
|
listener_channel_tx,
|
||||||
|
&server,
|
||||||
|
"127.0.0.1",
|
||||||
|
&sender,
|
||||||
|
"END_MESSAGE",
|
||||||
|
)?; // Get
|
||||||
|
let message = encryption::decrypt(&secret_key, message, &passwd)?; // Decrypt
|
||||||
|
|
||||||
|
listener_channel_tx.send(recieved.replace("START_MESSAGE", &message))?; // Send
|
||||||
|
} else if recieved_parsed.params[1] == "START_KEY" {
|
||||||
|
let sender = helpers::get_nick(&recieved_parsed.source.clone().unwrap());
|
||||||
|
let to_send = helpers::bytes_to_privmsg_base64(&public_key, &sender);
|
||||||
|
writer_channel_tx.send(to_send)?;
|
||||||
|
writer_channel_tx.send(format!("PRIVMSG {sender} END_KEY\r\n"))?;
|
||||||
|
|
||||||
|
let foreign_key = helpers::recieve_message_base64(
|
||||||
|
writer_channel_rx,
|
||||||
|
listener_channel_tx,
|
||||||
|
&server,
|
||||||
|
"127.0.0.1",
|
||||||
|
&sender,
|
||||||
|
"END_KEY",
|
||||||
|
)?;
|
||||||
|
dbg!(&foreign_key);
|
||||||
|
let key = SignedPublicKey::from_bytes(foreign_key.as_slice())?;
|
||||||
|
println!("Got a key from {sender}");
|
||||||
|
keys.insert(sender.to_string(), key);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
|
@ -2,6 +2,8 @@ use openssl::ssl::{SslConnector, SslMethod};
|
||||||
use std::io::{ErrorKind, Write};
|
use std::io::{ErrorKind, Write};
|
||||||
use std::net::TcpStream;
|
use std::net::TcpStream;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
|
use std::thread;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
pub fn write_to_server(
|
pub fn write_to_server(
|
||||||
tcp_stream: TcpStream,
|
tcp_stream: TcpStream,
|
||||||
|
@ -52,5 +54,6 @@ pub fn write_to_server(
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = tx.send(dbg!(String::from_utf8_lossy(&buffer).to_string()));
|
let _ = tx.send(dbg!(String::from_utf8_lossy(&buffer).to_string()));
|
||||||
|
thread::sleep(Duration::from_millis(100));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue