From 33947a0fd4e21738098531d78f00f979438e7866 Mon Sep 17 00:00:00 2001 From: Isabelle L Date: Tue, 26 May 2020 18:04:11 -0500 Subject: [PATCH] starting to work on client --- Cargo.lock | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 2 ++ src/client.rs | 63 ++++++++++++++++++++++++++++++++++++--------- src/main.rs | 15 ++++------- src/server.rs | 42 ++++++++++++++++++------------ 5 files changed, 154 insertions(+), 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4cfff0d..4d7da89 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/Cargo.toml b/Cargo.toml index 6f2c6d0..e80cc4d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/src/client.rs b/src/client.rs index c69050f..2f2b63e 100644 --- a/src/client.rs +++ b/src/client.rs @@ -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> = 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, 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, 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(()) } diff --git a/src/main.rs b/src/main.rs index 2c4f7fd..aa6b8dd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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; } } diff --git a/src/server.rs b/src/server.rs index c1f8456..533f804 100644 --- a/src/server.rs +++ b/src/server.rs @@ -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(packet: T) -> Result<()> { - let mut locked_write_streams = WRITE_STREAMS.lock().expect("failed to aqcuire lock"); +async fn relay_packet(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(()) } -*/