diff --git a/Cargo.lock b/Cargo.lock index a48f766..0b5de4b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1441,6 +1441,21 @@ dependencies = [ "tokio", ] +[[package]] +name = "triba-packet" +version = "0.1.0" +dependencies = [ + "aes-gcm-siv", + "anyhow", + "interprocess", + "rmp-serde", + "serde", + "strum", + "tokio", + "uuid", + "x25519-dalek", +] + [[package]] name = "trinitrix" version = "0.1.0" @@ -1464,6 +1479,7 @@ dependencies = [ "strum", "tokio", "tokio-util", + "triba-packet", "trinitry", "trixy", "tui-textarea", diff --git a/Cargo.toml b/Cargo.toml index 1bc4095..c958b9b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -69,6 +69,7 @@ crossterm = { version = "0.25" } # Trinitrx Backend API specific interprocess = { version = "2.1.0", features = ["tokio"] } +triba-packet = { path = "../triba-packet" } [dev-dependencies] pretty_assertions = "1.4.0" diff --git a/src/cbs/connection.rs b/src/cbs/connection.rs index 489d1e9..77bfd14 100644 --- a/src/cbs/connection.rs +++ b/src/cbs/connection.rs @@ -1,5 +1,3 @@ -use super::packet::{self, IdPool, Packet}; - use aes_gcm_siv::{Aes256GcmSiv, Nonce}; use anyhow::{anyhow, Result}; use interprocess::local_socket::tokio::{RecvHalf, SendHalf}; @@ -8,6 +6,7 @@ use tokio::{ sync::mpsc, }; use tokio_util::sync::CancellationToken; +use triba_packet::{self as packet, IdPool, Packet}; use uuid::Uuid; pub struct Connection { diff --git a/src/cbs/dummy.rs b/src/cbs/dummy.rs index 9563d37..33d7b82 100644 --- a/src/cbs/dummy.rs +++ b/src/cbs/dummy.rs @@ -1,13 +1,11 @@ -use super::packet; -use crate::cbs::packet::Packet; use aes_gcm_siv::{Aes256GcmSiv, KeyInit, Nonce}; -use anyhow::anyhow; use interprocess::local_socket::{ self, tokio::{prelude::*, Stream}, }; use rand::thread_rng; use tokio::io::{AsyncReadExt, AsyncWriteExt, BufReader}; +use triba_packet::{self as packet, IdPool, Packet}; use uuid::Uuid; use x25519_dalek::{EphemeralSecret, PublicKey}; @@ -40,7 +38,7 @@ pub async fn cbs(sock_name: local_socket::Name<'_>, id: Uuid) { let cipher = Aes256GcmSiv::new(shared_secret.as_bytes().into()); - let mut id_pool = packet::IdPool::new(); + let mut id_pool = IdPool::new(); tx.write( Packet::new(&mut id_pool, packet::Body::HandshakeUpgradeConnection) diff --git a/src/cbs/manager.rs b/src/cbs/manager.rs index ac67cf3..1176034 100644 --- a/src/cbs/manager.rs +++ b/src/cbs/manager.rs @@ -1,4 +1,4 @@ -use super::{packet, Connection, UnstableConnection}; +use super::{Connection, UnstableConnection}; use aes_gcm_siv::{Aes256GcmSiv, KeyInit, Nonce}; use anyhow::{anyhow, Result}; @@ -17,6 +17,7 @@ use tokio::{ sync::{mpsc, oneshot}, }; use tokio_util::sync::CancellationToken; +use triba_packet as packet; use uuid::Uuid; use x25519_dalek::{EphemeralSecret, PublicKey}; diff --git a/src/cbs/mod.rs b/src/cbs/mod.rs index 44a3d35..7c576cf 100644 --- a/src/cbs/mod.rs +++ b/src/cbs/mod.rs @@ -1,7 +1,6 @@ pub mod connection; mod dummy; pub mod manager; -pub(self) mod packet; // TODO: This whole module uses hell a lot of unwraps, // which need to be replaced by proper error handling. - antifallobst 2024-05-14 diff --git a/src/cbs/packet.rs b/src/cbs/packet.rs deleted file mode 100644 index 4ba395f..0000000 --- a/src/cbs/packet.rs +++ /dev/null @@ -1,117 +0,0 @@ -use aes_gcm_siv::{AeadInPlace, Aes256GcmSiv, Nonce}; -use anyhow::{anyhow, Result}; -use serde::{Deserialize, Serialize}; -use strum::Display; -use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; - -pub struct IdPool { - last: u64, -} - -impl IdPool { - pub fn new() -> Self { - Self { last: 0 } - } - - pub fn acquire(&mut self) -> u64 { - self.last += 1; - self.last - } -} - -#[derive(Debug, Copy, Clone, Serialize, Deserialize)] -pub struct Version(u32); - -impl Version { - /// Splits the version into its three parts: (major, minor, patch) - pub fn extract(self) -> (u8, u16, u8) { - let major = ((self.0 & 0xFF000000) >> 24) as u8; - let minor = ((self.0 & 0x00FFFF00) >> 8) as u16; - let patch = (self.0 & 0x000000FF) as u8; - - (major, minor, patch) - } -} - -#[repr(u8)] -#[derive(Debug, Clone, Serialize, Deserialize)] -pub enum Error { - Fatal(String), -} - -#[repr(u32)] -#[derive(Debug, Clone, Serialize, Deserialize, Display)] -pub enum Body { - // Misc - Exit(Error) = 0x000_00000, - - // Handshake - HandshakeUpgradeConnection = 0x001_00000, - HandshakeApiVersion(Version) = 0x001_00001, - HandshakeConfig = 0x001_00002, - HandshakeSuccess = 0x001_00003, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct Packet { - id: u64, - body: Body, -} - -impl Packet { - pub fn new(id_pool: &mut IdPool, body: Body) -> Self { - Self { - id: id_pool.acquire(), - body, - } - } - - pub fn body(&self) -> &Body { - &self.body - } - - // Serializes the packet to MessagePack and encrypts it. - pub fn pack(&self, cipher: &Aes256GcmSiv, nonce: &Nonce) -> Result> { - let mut data = rmp_serde::to_vec(self)?; - cipher - .encrypt_in_place(&nonce, b"", &mut data) - .map_err(|e| anyhow!("while packing packet: {e}"))?; - - let mut vec = (data.len() as u32).to_le_bytes().to_vec(); - vec.append(&mut data); - - Ok(vec) - } - - // Deserializes a packet from encrypted MessagePack. - pub fn unpack(data: &mut Vec, cipher: &Aes256GcmSiv, nonce: &Nonce) -> Result { - cipher - .decrypt_in_place(&nonce, b"", data) - .map_err(|e| anyhow!("while unpacking packet: {e}"))?; - Ok(rmp_serde::from_slice::(data.as_slice())?) - } - - pub async fn recv( - rx: &mut T, - cipher: &Aes256GcmSiv, - nonce: &Nonce, - ) -> Result { - let size = rx.read_u32_le().await? as usize; - - let mut buffer = vec![0u8; size]; - rx.read(&mut buffer).await?; - - Packet::unpack(&mut buffer, &cipher, &nonce) - } - - pub async fn send( - &self, - tx: &mut T, - cipher: &Aes256GcmSiv, - nonce: &Nonce, - ) -> Result<()> { - let raw = self.pack(cipher, nonce)?; - tx.write(raw.as_slice()).await?; - Ok(()) - } -}