aboutsummaryrefslogtreecommitdiffstats
path: root/src/anon_req.rs
diff options
context:
space:
mode:
authorWill Dillon <william@housedillon.com>2025-12-04 17:07:12 +0000
committerWill Dillon <william@housedillon.com>2025-12-04 17:07:12 +0000
commitbf21ebaaae44b267cfefc87eee9608c09aab96b7 (patch)
tree67234092d3c85a9c58d1fa9ca51337ac480ebfb7 /src/anon_req.rs
parentBetter than 90% everywhere. (diff)
downloadmeshcore-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.rs53
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