@@ -96,6 +96,12 @@ version = "3.3.0" | |||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||
checksum = "5356f1d23ee24a1f785a56d1d1a5f0fd5b0f6a0c0fb2412ce11da71649ab78f6" | |||
[[package]] | |||
name = "cassowary" | |||
version = "0.3.0" | |||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||
checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" | |||
[[package]] | |||
name = "cc" | |||
version = "1.0.52" | |||
@@ -190,6 +196,12 @@ dependencies = [ | |||
"lazy_static", | |||
] | |||
[[package]] | |||
name = "either" | |||
version = "1.5.3" | |||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||
checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" | |||
[[package]] | |||
name = "fuchsia-zircon" | |||
version = "0.3.3" | |||
@@ -362,6 +374,15 @@ dependencies = [ | |||
"libc", | |||
] | |||
[[package]] | |||
name = "itertools" | |||
version = "0.9.0" | |||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||
checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" | |||
dependencies = [ | |||
"either", | |||
] | |||
[[package]] | |||
name = "itoa" | |||
version = "0.4.5" | |||
@@ -495,8 +516,10 @@ dependencies = [ | |||
"serde", | |||
"serde_json", | |||
"structopt", | |||
"termion", | |||
"thiserror", | |||
"toml", | |||
"tui", | |||
"uuid", | |||
] | |||
@@ -540,6 +563,12 @@ dependencies = [ | |||
"libc", | |||
] | |||
[[package]] | |||
name = "numtoa" | |||
version = "0.1.0" | |||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||
checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" | |||
[[package]] | |||
name = "once_cell" | |||
version = "1.4.0" | |||
@@ -693,6 +722,21 @@ dependencies = [ | |||
"rand_core", | |||
] | |||
[[package]] | |||
name = "redox_syscall" | |||
version = "0.1.56" | |||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||
checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" | |||
[[package]] | |||
name = "redox_termios" | |||
version = "0.1.1" | |||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||
checksum = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" | |||
dependencies = [ | |||
"redox_syscall", | |||
] | |||
[[package]] | |||
name = "ring" | |||
version = "0.16.13" | |||
@@ -821,6 +865,18 @@ dependencies = [ | |||
"syn", | |||
] | |||
[[package]] | |||
name = "termion" | |||
version = "1.5.5" | |||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||
checksum = "c22cec9d8978d906be5ac94bceb5a010d885c626c4c8855721a4dbd20e3ac905" | |||
dependencies = [ | |||
"libc", | |||
"numtoa", | |||
"redox_syscall", | |||
"redox_termios", | |||
] | |||
[[package]] | |||
name = "textwrap" | |||
version = "0.11.0" | |||
@@ -869,6 +925,21 @@ dependencies = [ | |||
"serde", | |||
] | |||
[[package]] | |||
name = "tui" | |||
version = "0.9.5" | |||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||
checksum = "9533d39bef0ae8f510e8a99d78702e68d1bbf0b98a78ec9740509d287010ae1e" | |||
dependencies = [ | |||
"bitflags", | |||
"cassowary", | |||
"either", | |||
"itertools", | |||
"termion", | |||
"unicode-segmentation", | |||
"unicode-width", | |||
] | |||
[[package]] | |||
name = "unicode-segmentation" | |||
version = "1.6.0" | |||
@@ -20,3 +20,5 @@ ilmp = { path = "../ilmp"} | |||
ring = "0.16.13" | |||
thiserror = "1.0.18" | |||
orion = "0.15.1" | |||
termion = "1.5.5" | |||
tui = "0.9.4" |
@@ -1,28 +1,67 @@ | |||
// namespacing | |||
use crate::config::ClientConfig as Config; | |||
use crate::Result; | |||
use async_std::net::TcpStream; | |||
use async_std::{io, net::TcpStream, task}; | |||
use futures::io::{ReadHalf, WriteHalf}; | |||
use futures_util::io::AsyncReadExt; | |||
use ilmp::encrypt; | |||
use ilmp::{ | |||
encrypt::{EncryptKind, Encryption, SymmetricEncrypt}, | |||
Sendable, | |||
}; | |||
use lazy_static::lazy_static; | |||
use orion::aead; | |||
use std::sync::Mutex; | |||
lazy_static! { | |||
static ref MESSAGE_BUFFER: Mutex<Vec<ilmp::Message>> = Mutex::new(Vec::new()); | |||
static ref CONFIG: Config = Config::load().expect("failed to load config"); | |||
} | |||
/// wraps the client | |||
pub async fn client(port: u16) -> Result<()> { | |||
let _config = Config::load()?; | |||
let stream = TcpStream::connect(format!("127.0.0.1:{}", &port)).await?; | |||
println!("connection established to: {}:{}", stream.peer_addr()?.ip(), port); | |||
println!( | |||
"connection established to: {}:{}", | |||
stream.peer_addr()?.ip(), | |||
port | |||
); | |||
let (mut read, mut write) = stream.split(); | |||
let key = crate::initialize_connection(&mut read, &mut write).await?; | |||
let encryption = encrypt::SymmetricEncrypt::new(key); | |||
let encryption = SymmetricEncrypt::new(key); | |||
println!("successfully hardened connection"); | |||
let message = ilmp::Message::new( | |||
"Isabelle".to_owned(), | |||
"oh god oh fuck this shit actually works".to_owned(), | |||
); | |||
task::spawn(outgoing(write, encryption.clone()?)); | |||
task::spawn(incoming(read, encryption)); | |||
Ok(()) | |||
} | |||
pub async fn outgoing(mut write: WriteHalf<TcpStream>, encryption: SymmetricEncrypt) -> Result<()> { | |||
loop { | |||
let mut line = String::new(); | |||
io::stdin().read_line(&mut line).await?; | |||
let message = ilmp::Message::new(CONFIG.user.clone(), line); | |||
ilmp::write(&mut write, message, &encryption).await?; | |||
} | |||
} | |||
pub async fn incoming(mut read: ReadHalf<TcpStream>, encryption: SymmetricEncrypt) -> Result<()> { | |||
loop { | |||
let packet = ilmp::read(&mut read).await?; | |||
if let Some(mut packet) = packet { | |||
if packet.encrypt_kind == EncryptKind::Symmetric { | |||
packet.contents = aead::open(encryption.key().unwrap(), &packet.contents)?; | |||
} | |||
ilmp::write(&mut write, message, &encryption).await?; | |||
let res = match packet.kind { | |||
ilmp::PacketKind::Message => ilmp::Message::from_packet(packet), | |||
_ => panic!("bad packet"), | |||
}; | |||
println!("{:?}", res); | |||
} else { | |||
break; | |||
} | |||
} | |||
loop {} | |||
Ok(()) | |||
} |
@@ -26,15 +26,10 @@ async fn main() { | |||
1337 | |||
}; | |||
match options.server { | |||
true => { | |||
if let Err(err) = msg::server(port).await { | |||
println!("an error occured: {:?}", err); | |||
} | |||
} | |||
false => { | |||
if let Err(err) = msg::client(port).await { | |||
println!("an error occured: {:?}", err); | |||
} | |||
} | |||
true => async_std::task::spawn(msg::server(port)), | |||
false => async_std::task::spawn(msg::client(port)), | |||
}; | |||
loop { | |||
async_std::task::yield_now().await; | |||
} | |||
} |
@@ -2,6 +2,7 @@ | |||
use crate::Result; | |||
use async_std::{ | |||
net::{TcpListener, TcpStream}, | |||
sync::Mutex, | |||
task, | |||
}; | |||
use futures::io::{ReadHalf, WriteHalf}; | |||
@@ -11,7 +12,7 @@ use ilmp::encrypt::Encryption; | |||
use ilmp::Sendable; | |||
use lazy_static::lazy_static; | |||
use orion::aead; | |||
use std::{collections::HashMap, sync::Mutex}; | |||
use std::collections::HashMap; | |||
use uuid::Uuid; | |||
lazy_static! { | |||
@@ -23,7 +24,11 @@ lazy_static! { | |||
pub async fn server(port: u16) -> Result<()> { | |||
let listener = TcpListener::bind(format!("127.0.0.1:{}", &port)).await?; | |||
println!("online as server at: {}:{}", listener.local_addr()?.ip(), port); | |||
println!( | |||
"online as server at: {}:{}", | |||
listener.local_addr()?.ip(), | |||
port | |||
); | |||
let mut incoming = listener.incoming(); | |||
@@ -40,7 +45,7 @@ pub async fn server(port: u16) -> Result<()> { | |||
let encryption = encrypt::SymmetricEncrypt::new(key); | |||
println!("successfully hardened connection"); | |||
WRITE_STREAMS.lock().expect("could not aqcuire lock").insert(stream_id.clone(), write); | |||
WRITE_STREAMS.lock().await.insert(stream_id.clone(), write); | |||
task::spawn(handle_stream(read, stream_id, encryption)); | |||
} | |||
@@ -62,31 +67,34 @@ async fn handle_stream( | |||
let res = match packet.kind { | |||
ilmp::PacketKind::Message => ilmp::Message::from_packet(packet), | |||
_ => panic!("bad packet"), | |||
}; | |||
println!("{:?}", res); | |||
}?; | |||
println!("got packet from: {}", &stream_id.as_u128()); | |||
relay_packet(res, &encryption).await?; | |||
} else { | |||
// if no packet was received the stream is closed | |||
break; | |||
} | |||
} | |||
println!("stream disconnected"); | |||
WRITE_STREAMS.lock().expect("failed to aqcuire lock").remove(&stream_id); | |||
WRITE_STREAMS.lock().await.remove(&stream_id); | |||
Ok(()) | |||
} | |||
/*async fn relay_packet<T: Clone + Sendable>(packet: T) -> Result<()> { | |||
let mut locked_write_streams = WRITE_STREAMS.lock().expect("failed to aqcuire lock"); | |||
async fn relay_packet<T>(packet: T, encryption: &encrypt::SymmetricEncrypt) -> Result<()> | |||
where | |||
T: Clone + Sendable, | |||
{ | |||
let mut locked_write_streams = WRITE_STREAMS.lock().await; | |||
let stream = futures::stream::iter(locked_write_streams.iter_mut()); | |||
let packet = &packet; | |||
stream.for_each_concurrent(None, |(_, mut stream)| async move { | |||
let packet = packet | |||
.clone() | |||
.to_packet() | |||
.expect("failed to convert to packet"); | |||
// in case any of the writes fail just ignore them | |||
let _ = packet.write(&mut stream); | |||
}); | |||
stream | |||
.for_each_concurrent(None, |(stream_id, mut stream)| async move { | |||
println!("relaying packet to: {}", stream_id.as_u128()); | |||
let packet = packet.clone(); | |||
// in case any of the writes fail just ignore them | |||
let _ = ilmp::write(&mut stream, packet, encryption).await; | |||
}) | |||
.await; | |||
Ok(()) | |||
} | |||
*/ |