| @@ -96,6 +96,12 @@ version = "3.3.0" | |||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "5356f1d23ee24a1f785a56d1d1a5f0fd5b0f6a0c0fb2412ce11da71649ab78f6" | checksum = "5356f1d23ee24a1f785a56d1d1a5f0fd5b0f6a0c0fb2412ce11da71649ab78f6" | ||||
| [[package]] | |||||
| name = "cassowary" | |||||
| version = "0.3.0" | |||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
| checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" | |||||
| [[package]] | [[package]] | ||||
| name = "cc" | name = "cc" | ||||
| version = "1.0.52" | version = "1.0.52" | ||||
| @@ -190,6 +196,12 @@ dependencies = [ | |||||
| "lazy_static", | "lazy_static", | ||||
| ] | ] | ||||
| [[package]] | |||||
| name = "either" | |||||
| version = "1.5.3" | |||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
| checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" | |||||
| [[package]] | [[package]] | ||||
| name = "fuchsia-zircon" | name = "fuchsia-zircon" | ||||
| version = "0.3.3" | version = "0.3.3" | ||||
| @@ -362,6 +374,15 @@ dependencies = [ | |||||
| "libc", | "libc", | ||||
| ] | ] | ||||
| [[package]] | |||||
| name = "itertools" | |||||
| version = "0.9.0" | |||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
| checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" | |||||
| dependencies = [ | |||||
| "either", | |||||
| ] | |||||
| [[package]] | [[package]] | ||||
| name = "itoa" | name = "itoa" | ||||
| version = "0.4.5" | version = "0.4.5" | ||||
| @@ -495,8 +516,10 @@ dependencies = [ | |||||
| "serde", | "serde", | ||||
| "serde_json", | "serde_json", | ||||
| "structopt", | "structopt", | ||||
| "termion", | |||||
| "thiserror", | "thiserror", | ||||
| "toml", | "toml", | ||||
| "tui", | |||||
| "uuid", | "uuid", | ||||
| ] | ] | ||||
| @@ -540,6 +563,12 @@ dependencies = [ | |||||
| "libc", | "libc", | ||||
| ] | ] | ||||
| [[package]] | |||||
| name = "numtoa" | |||||
| version = "0.1.0" | |||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
| checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" | |||||
| [[package]] | [[package]] | ||||
| name = "once_cell" | name = "once_cell" | ||||
| version = "1.4.0" | version = "1.4.0" | ||||
| @@ -693,6 +722,21 @@ dependencies = [ | |||||
| "rand_core", | "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]] | [[package]] | ||||
| name = "ring" | name = "ring" | ||||
| version = "0.16.13" | version = "0.16.13" | ||||
| @@ -821,6 +865,18 @@ dependencies = [ | |||||
| "syn", | "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]] | [[package]] | ||||
| name = "textwrap" | name = "textwrap" | ||||
| version = "0.11.0" | version = "0.11.0" | ||||
| @@ -869,6 +925,21 @@ dependencies = [ | |||||
| "serde", | "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]] | [[package]] | ||||
| name = "unicode-segmentation" | name = "unicode-segmentation" | ||||
| version = "1.6.0" | version = "1.6.0" | ||||
| @@ -20,3 +20,5 @@ ilmp = { path = "../ilmp"} | |||||
| ring = "0.16.13" | ring = "0.16.13" | ||||
| thiserror = "1.0.18" | thiserror = "1.0.18" | ||||
| orion = "0.15.1" | orion = "0.15.1" | ||||
| termion = "1.5.5" | |||||
| tui = "0.9.4" | |||||
| @@ -1,28 +1,67 @@ | |||||
| // namespacing | // namespacing | ||||
| use crate::config::ClientConfig as Config; | use crate::config::ClientConfig as Config; | ||||
| use crate::Result; | 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 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 | /// wraps the client | ||||
| pub async fn client(port: u16) -> Result<()> { | pub async fn client(port: u16) -> Result<()> { | ||||
| let _config = Config::load()?; | |||||
| let stream = TcpStream::connect(format!("127.0.0.1:{}", &port)).await?; | 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 (mut read, mut write) = stream.split(); | ||||
| let key = crate::initialize_connection(&mut read, &mut write).await?; | 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"); | 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 | 1337 | ||||
| }; | }; | ||||
| match options.server { | 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 crate::Result; | ||||
| use async_std::{ | use async_std::{ | ||||
| net::{TcpListener, TcpStream}, | net::{TcpListener, TcpStream}, | ||||
| sync::Mutex, | |||||
| task, | task, | ||||
| }; | }; | ||||
| use futures::io::{ReadHalf, WriteHalf}; | use futures::io::{ReadHalf, WriteHalf}; | ||||
| @@ -11,7 +12,7 @@ use ilmp::encrypt::Encryption; | |||||
| use ilmp::Sendable; | use ilmp::Sendable; | ||||
| use lazy_static::lazy_static; | use lazy_static::lazy_static; | ||||
| use orion::aead; | use orion::aead; | ||||
| use std::{collections::HashMap, sync::Mutex}; | |||||
| use std::collections::HashMap; | |||||
| use uuid::Uuid; | use uuid::Uuid; | ||||
| lazy_static! { | lazy_static! { | ||||
| @@ -23,7 +24,11 @@ lazy_static! { | |||||
| pub async fn server(port: u16) -> Result<()> { | pub async fn server(port: u16) -> Result<()> { | ||||
| let listener = TcpListener::bind(format!("127.0.0.1:{}", &port)).await?; | 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(); | let mut incoming = listener.incoming(); | ||||
| @@ -40,7 +45,7 @@ pub async fn server(port: u16) -> Result<()> { | |||||
| let encryption = encrypt::SymmetricEncrypt::new(key); | let encryption = encrypt::SymmetricEncrypt::new(key); | ||||
| println!("successfully hardened connection"); | 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)); | task::spawn(handle_stream(read, stream_id, encryption)); | ||||
| } | } | ||||
| @@ -62,31 +67,34 @@ async fn handle_stream( | |||||
| let res = match packet.kind { | let res = match packet.kind { | ||||
| ilmp::PacketKind::Message => ilmp::Message::from_packet(packet), | ilmp::PacketKind::Message => ilmp::Message::from_packet(packet), | ||||
| _ => panic!("bad packet"), | _ => panic!("bad packet"), | ||||
| }; | |||||
| println!("{:?}", res); | |||||
| }?; | |||||
| println!("got packet from: {}", &stream_id.as_u128()); | |||||
| relay_packet(res, &encryption).await?; | |||||
| } else { | } else { | ||||
| // if no packet was received the stream is closed | // if no packet was received the stream is closed | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| println!("stream disconnected"); | println!("stream disconnected"); | ||||
| WRITE_STREAMS.lock().expect("failed to aqcuire lock").remove(&stream_id); | |||||
| WRITE_STREAMS.lock().await.remove(&stream_id); | |||||
| Ok(()) | 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 stream = futures::stream::iter(locked_write_streams.iter_mut()); | ||||
| let packet = &packet; | 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(()) | Ok(()) | ||||
| } | } | ||||
| */ | |||||