diff options
| author | Will Dillon <william@housedillon.com> | 2025-12-04 17:07:12 +0000 |
|---|---|---|
| committer | Will Dillon <william@housedillon.com> | 2025-12-04 17:07:12 +0000 |
| commit | bf21ebaaae44b267cfefc87eee9608c09aab96b7 (patch) | |
| tree | 67234092d3c85a9c58d1fa9ca51337ac480ebfb7 /src/anon_req.rs | |
| parent | Better than 90% everywhere. (diff) | |
| download | meshcore-rs-bf21ebaaae44b267cfefc87eee9608c09aab96b7.tar.gz meshcore-rs-bf21ebaaae44b267cfefc87eee9608c09aab96b7.zip | |
Getting closer to no-std being done
Diffstat (limited to 'src/anon_req.rs')
| -rw-r--r-- | src/anon_req.rs | 53 |
1 files changed, 31 insertions, 22 deletions
diff --git a/src/anon_req.rs b/src/anon_req.rs index b468e9e..60d58e4 100644 --- a/src/anon_req.rs +++ b/src/anon_req.rs @@ -1,11 +1,8 @@ -use std::fmt::{Debug, Display}; use chrono::{DateTime, Utc}; use bytes::{Buf, Bytes}; -use structdiff::{Difference, StructDiff}; -use crate::crypto::PublicKey; +use crate::{MeshcoreStringError, crypto::PublicKey, string_helper::{PasswordString, password_string_from_slice}}; -#[derive(PartialEq, Debug, Clone, Difference)] -#[difference(expose)] +#[derive(PartialEq, Clone, core::fmt::Debug)] pub struct AnonReq { pub dest: u8, pub public_key: PublicKey, @@ -15,6 +12,17 @@ pub struct AnonReq { incomplete: bool } +impl AnonReq { + #[allow(dead_code)] + fn password(&self) -> Result<PasswordString, MeshcoreStringError> { + if let Some(clear_request) = &self.request { + Ok(clear_request.password.clone()) + } else { + Err(MeshcoreStringError::StringEncrypted) + } + } +} + impl From<Bytes> for AnonReq { fn from(value: Bytes) -> Self { let mut bytes = value; @@ -45,9 +53,9 @@ impl From<Bytes> for AnonReq { } } -impl Display for AnonReq { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_fmt(format_args!("({:2x?}) -> ({:2x?}) MAC: {:4x?} ", self.public_key.hash_prefix(), self.dest, self.mac))?; +impl core::fmt::Display for AnonReq { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_fmt(format_args!("({:2x?}) -> ({:2x?}) MAC: {:4x?} ", self.public_key.hash_prefix() >> 24, self.dest, self.mac))?; if let Some(cleartext) = &self.request { f.write_fmt(format_args!("at: {} password: \"{}\"", cleartext.timestamp, cleartext.password)) @@ -57,12 +65,11 @@ impl Display for AnonReq { } } -#[derive(PartialEq, Debug, Clone, Difference)] -#[difference(expose)] +#[derive(PartialEq, Debug, Clone)] pub struct ClearAnonRequest { timestamp: DateTime<Utc>, sync_timestamp: Option<DateTime<Utc>>, - password: String + password: PasswordString, } impl From<Bytes> for ClearAnonRequest { @@ -70,9 +77,11 @@ impl From<Bytes> for ClearAnonRequest { let mut bytes = value; let mut anon_req = ClearAnonRequest { + // Safety: this is ok to unwrap because it's value isn't user controlled + // and never changes, and it exercised extensively in tests. timestamp: DateTime::from_timestamp(0, 0).unwrap(), sync_timestamp: None, - password: "".to_string(), + password: PasswordString::new() }; // Just check for the whole fixed-size part at once @@ -81,23 +90,23 @@ impl From<Bytes> for ClearAnonRequest { anon_req.timestamp = timestamp; } - // Strip-off any null characters after the password - let raw_password = String::from_utf8_lossy(&bytes).to_string(); - let trimmed_password: Vec<&str> = raw_password.splitn(2, "\0").collect(); - if let Some(password) = trimmed_password.first() { - anon_req.password = password.to_string(); - + // Strip-off any null characters after the password + if let Some(pass) = bytes.split(|b| *b == 0).next() { + anon_req.password = password_string_from_slice(pass); } + anon_req } } +// Tests for std operations #[cfg(test)] mod tests { use std::collections::HashMap; use std::str::FromStr; use hex::decode; - use crate::identity::KeystoreInput; + use tinyvec::ArrayVec; + use crate::std_identity::KeystoreInput; use crate::packet::*; use crate::crypto::*; use crate::packet_content::PacketContent; @@ -110,7 +119,7 @@ mod tests { let lhs_packet = Packet { route_type: RouteType::Flood, version: PayloadVersion::VersionOne, - path: vec![], + path: ArrayVec::new(), transport: [0, 0], raw_content: Bytes::copy_from_slice(&decode("3412349BDC1F76A0C12149BB15F791DBE42FDE02C209B04A85C6F512990C8CEDEC4E7B8DBF1C3C928D64D87AA8293B9603EEE0").unwrap()), content: PacketContent::AnonReq(AnonReq { @@ -146,13 +155,13 @@ mod tests { assert_eq!(lhs_packet, rhs_packet); println!("\"{}\"", rhs_packet); - assert!(format!("{}", rhs_packet) == " Flood | v1 | | [] | | ANON REQ. | (12) -> (34) MAC: 4e7b ENCRYPTED"); + assert_eq!(format!("{}", rhs_packet), " Flood | v1 | | [] | | ANON REQ. | (12) -> (34) MAC: 4e7b ENCRYPTED"); rhs_packet.try_decrypt(&keystore); let lhs_string = format!("{}", rhs_packet); let rhs_string = " Flood | v1 | | [] | | ANON REQ. | (12) -> (34) MAC: 4e7b at: 2025-11-13 17:21:13 UTC password: \"12345\""; - assert!(lhs_string == rhs_string); + assert_eq!(lhs_string, rhs_string); } }
\ No newline at end of file |
