1use std::{borrow::Cow, collections::BTreeMap};
2
3#[cfg(feature="serde")]
4use serde::{Deserialize, Serialize, de::Visitor, Deserializer, ser::SerializeMap};
5
6use crate::{prelude::{Artifact, *}, field::{internal::{InternalField, PreStoredField}, Text, Field, Ip}, context::context};
7
8#[derive(Debug, Clone)]
10pub struct ForensicData {
11 artifact : Artifact,
12 pub(crate) fields: BTreeMap<Text, InternalField>,
13}
14
15impl Default for ForensicData {
16 fn default() -> Self {
17 let context = context();
18 let mut fields = BTreeMap::new();
19 fields.insert(Text::Borrowed(ARTIFACT_HOST), Field::Text(Text::Owned(context.host)).into());
20 fields.insert(Text::Borrowed(ARTIFACT_TENANT), Field::Text(Text::Owned(context.tenant)).into());
21 fields.insert(Text::Borrowed(ARTIFACT_NAME), Field::Text(Text::Owned(context.artifact.to_string())).into());
22 Self {
23 fields,
24 artifact : context.artifact
25 }
26 }
27}
28
29
30impl<'a> ForensicData {
31 pub fn new(host : &str, artifact : Artifact) -> Self {
32 let mut fields = BTreeMap::new();
33 fields.insert(Text::Borrowed(ARTIFACT_HOST), Field::Text(Text::Owned(host.to_string())).into());
34 fields.insert(Text::Borrowed(ARTIFACT_NAME), Field::Text(Text::Owned(artifact.to_string())).into());
35 Self {
36 fields,
37 artifact
38 }
39 }
40
41 pub fn artifact(&self) -> &Artifact {
42 &self.artifact
43 }
44
45 pub fn host(&'a self) -> &'a str {
46 match self.field(ARTIFACT_HOST) {
47 Some(v) => {
48 match v {
49 Field::Text(v) => v,
50 _ => ""
51 }
52 },
53 None => ""
54 }
55 }
56
57 pub fn field(&self, field_name : &str) -> Option<&Field> {
58 Some(&self.fields.get(field_name)?.original)
59 }
60
61 pub fn has_field(&self, field_name : &str) -> bool {
62 self.fields.contains_key(field_name)
63 }
64
65 pub fn field_mut(&'a mut self, field_name: &str) -> Option<&mut Field> {
66 Some(&mut self.fields.get_mut(field_name)?.original)
67 }
68 pub fn add_field(&mut self, field_name: &'static str, field_value: Field) {
69 self.insert(Text::Borrowed(field_name), field_value);
70 }
71 pub fn insert(&mut self, field_name: Text, field_value: Field) {
72 self.fields.insert(field_name, field_value.into());
73 }
74 pub fn i64_field(&'a mut self, field_name: &str) -> Option<i64> {
76 let field = self.fields.get_mut(field_name)?;
77 match field.ni64.as_ref() {
78 PreStoredField::Invalid => return None,
79 PreStoredField::None => {},
80 PreStoredField::Some(v) => return Some(*v)
81 };
82 let i64field : Option<i64> = (&field.original).try_into().ok();
83 let pfield = match i64field {
84 Some(v) => PreStoredField::Some(v),
85 None => PreStoredField::Invalid
86 };
87 field.ni64 = Box::new(pfield);
88 match field.ni64.as_ref() {
89 PreStoredField::Some(v) => Some(*v),
90 _ => None
91 }
92 }
93 pub fn f64_field(&'a mut self, field_name: &str) -> Option<f64> {
95 let field = self.fields.get_mut(field_name)?;
96 match field.nf64.as_ref() {
97 PreStoredField::Invalid => return None,
98 PreStoredField::None => {},
99 PreStoredField::Some(v) => return Some(*v)
100 };
101 let i64field : Option<f64> = (&field.original).try_into().ok();
102 let pfield = match i64field {
103 Some(v) => PreStoredField::Some(v),
104 None => PreStoredField::Invalid
105 };
106 field.nf64 = Box::new(pfield);
107 match field.nf64.as_ref() {
108 PreStoredField::Some(v) => Some(*v),
109 _ => None
110 }
111 }
112 pub fn u64_field(&'a mut self, field_name: &str) -> Option<u64> {
114 let field = self.fields.get_mut(field_name)?;
115 match field.nu64.as_ref() {
116 PreStoredField::Invalid => return None,
117 PreStoredField::None => {},
118 PreStoredField::Some(v) => return Some(*v)
119 };
120 let i64field : Option<u64> = (&field.original).try_into().ok();
121 let pfield = match i64field {
122 Some(v) => PreStoredField::Some(v),
123 None => PreStoredField::Invalid
124 };
125 field.nu64 = Box::new(pfield);
126 match field.nu64.as_ref() {
127 PreStoredField::Some(v) => Some(*v),
128 _ => None
129 }
130 }
131 pub fn ip_field(&'a mut self, field_name: &str) -> Option<Ip> {
133 let field = self.fields.get_mut(field_name)?;
134 match field.ip.as_ref() {
135 PreStoredField::Invalid => return None,
136 PreStoredField::None => {},
137 PreStoredField::Some(v) => return Some(*v)
138 };
139 let i64field : Option<Ip> = (&field.original).try_into().ok();
140 let pfield = match i64field {
141 Some(v) => PreStoredField::Some(v),
142 None => PreStoredField::Invalid
143 };
144 field.ip = Box::new(pfield);
145 match field.ip.as_ref() {
146 PreStoredField::Some(v) => Some(*v),
147 _ => None
148 }
149 }
150 pub fn txt_field(&'a mut self, field_name: &str) -> Option<&Text> {
152
153 let mut has_value = false;
154
155 let field = self.fields.get_mut(field_name)?;
156 match field.text.as_ref() {
157 PreStoredField::Invalid => return None,
158 PreStoredField::None => {},
159 PreStoredField::Some(_) => {
160 has_value = true;
161 }
162 };
163 if has_value {
164 match field.text.as_ref() {
165 PreStoredField::Some(v) => return Some(v),
166 _ => return None
167 }
168 }
169 let txtfield : Option<Text> = (&field.original).try_into().ok();
170 let pfield = match txtfield {
171 Some(v) => PreStoredField::Some(v),
172 None => PreStoredField::Invalid
173 };
174 field.text = Box::new(pfield);
175 match field.text.as_ref() {
176 PreStoredField::Some(v) => Some(v),
177 _ => None
178 }
179 }
180 pub fn array_field(&'a mut self, field_name: &str) -> Option<&Vec<Text>> {
182
183 let mut has_value = false;
184
185 let field = self.fields.get_mut(field_name)?;
186 match field.array.as_ref() {
187 PreStoredField::Invalid => return None,
188 PreStoredField::None => {},
189 PreStoredField::Some(_) => {
190 has_value = true;
191 }
192 };
193 if has_value {
194 match field.array.as_ref() {
195 PreStoredField::Some(v) => return Some(v),
196 _ => return None
197 }
198 }
199 let txtfield : Option<Vec<Text>> = (&field.original).try_into().ok();
200 let pfield = match txtfield {
201 Some(v) => PreStoredField::Some(v),
202 None => PreStoredField::Invalid
203 };
204 field.array = Box::new(pfield);
205 match field.array.as_ref() {
206 PreStoredField::Some(v) => Some(v),
207 _ => None
208 }
209 }
210
211 pub fn fields(&self) -> EventIter<'_> {
212 EventIter {
213 children: self.fields.iter(),
214 }
215 }
216 pub fn iter(&self) -> EventIter<'_> {
217 EventIter {
218 children: self.fields.iter(),
219 }
220 }
221 pub fn iter_mut(&mut self) -> EventIterMut<'_> {
222 EventIterMut {
223 children: self.fields.iter_mut(),
224 }
225 }
226
227}
228
229
230pub struct ForensicDataInspector<'a> {
231 iter : std::collections::btree_map::Iter<'a, Cow<'static, str>, String>
232}
233pub struct ForensicDataInspectorMut<'a> {
234 iter : std::collections::btree_map::IterMut<'a, Cow<'static, str>, String>
235}
236
237impl<'a> Iterator for ForensicDataInspector<'a> {
238 type Item = (&'a Cow<'a,str>,&'a String);
239
240 fn next(&mut self) -> Option<Self::Item> {
241 self.iter.next().map(|wrapper| (wrapper.0, wrapper.1))
242 }
243}
244impl<'a> Iterator for ForensicDataInspectorMut<'a> {
245 type Item = (&'a Cow<'a,str>,&'a mut String);
246
247 fn next(&mut self) -> Option<Self::Item> {
248 self.iter.next().map(|wrapper| (wrapper.0, wrapper.1))
249 }
250}
251
252impl std::fmt::Display for ForensicData {
253 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
254 write!(f, "{{artifact:{:?}, fields:{:?}}}", self.artifact, self.fields)
255 }
256}
257
258pub struct EventIter<'a> {
259 children: std::collections::btree_map::Iter<'a, Text, InternalField>,
260}
261pub struct EventFieldIter<'a> {
262 names: std::collections::btree_set::Iter<'a, Text>,
263 fields: &'a BTreeMap<Text, InternalField>,
264}
265
266pub struct EventIterMut<'a> {
267 children: std::collections::btree_map::IterMut<'a, Text, InternalField>,
268}
269
270impl<'a> Iterator for EventIter<'a> {
271 type Item = (&'a Text, &'a Field);
272
273 fn next(&mut self) -> Option<Self::Item> {
274 let evt = self.children.next()?;
275 Some((evt.0, &evt.1.original))
276 }
277}
278impl<'a> Iterator for EventIterMut<'a> {
279 type Item = (&'a Text, &'a mut Field);
280
281 fn next(&mut self) -> Option<Self::Item> {
282 let evt = self.children.next()?;
283 Some((evt.0, &mut evt.1.original))
284 }
285}
286impl<'a> Iterator for EventFieldIter<'a> {
287 type Item = (&'a Text, &'a Field);
288
289 fn next(&mut self) -> Option<Self::Item> {
290 let field = self.names.next()?;
291 let value = self.fields.get(field)?;
292 Some((field, &value.original))
293 }
294}
295#[cfg(feature = "serde")]
296impl<'de> Deserialize<'de> for ForensicData {
297 fn deserialize<D>(deserializer: D) -> Result<ForensicData, D::Error>
298 where
299 D: Deserializer<'de>,
300 {
301 deserializer.deserialize_any(DataVisitor)
302 }
303}
304#[cfg(feature = "serde")]
305impl Serialize for ForensicData {
306 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
307 where
308 S: serde::Serializer {
309 let mut map = serializer.serialize_map(Some(self.fields.len()))?;
310 for (k,v) in &self.fields {
311 map.serialize_entry(k, &v.original)?;
312 }
313 map.end()
314 }
315}
316#[cfg(feature = "serde")]
317struct DataVisitor;
318#[cfg(feature = "serde")]
319impl<'de> Visitor<'de> for DataVisitor {
320 type Value = ForensicData;
321
322 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
323 formatter.write_str("a valid forensic data")
324 }
325
326 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
327 where
328 A: serde::de::MapAccess<'de>, {
329 let mut artifact = Artifact::default();
330 let mut fields = BTreeMap::new();
331 while let Some((key, value)) = map.next_entry()? {
332 fields.insert(Cow::Owned(key), InternalField::new(value));
333 }
334 if let Some(artf) = fields.get(ARTIFACT_NAME) {
335 if let Field::Text(artf) = &artf.original {
336 artifact = (&artf[..]).into();
337 }
338 }
339 Ok(ForensicData { artifact, fields })
340 }
341}
342
343#[cfg(test)]
344mod data_tests {
345 use crate::{prelude::RegistryArtifacts, artifact::{Artifact, WindowsArtifacts}};
346
347 use super::ForensicData;
348
349 #[test]
350 fn iterate_fields_test() {
351 let mut data = ForensicData::new("host007", RegistryArtifacts::ShellBags.into());
352 data.insert("field001".into(), "value001".into());
353 data.insert("field002".into(), "value002".into());
354 data.insert("field003".into(), "value003".into());
355
356 let mut count = 0;
357 for (_name, _value) in data.fields() {
358 count += 1;
359 }
360 assert_eq!(5, count);}
362
363 #[test]
364 fn should_serialize_data() {
365 let mut data = ForensicData::new("host007", RegistryArtifacts::ShellBags.into());
366 data.insert("field001".into(), "value001".into());
367 data.insert("field002".into(), "value002".into());
368 data.insert("field003".into(), "value003".into());
369 data.insert("field004".into(), crate::field::Field::Array(vec!["aaa".into(), "bbb".into()]));
370 let deserialized = serde_json::to_string(&data).unwrap();
371 assert_eq!(r#"{"artifact.host":"host007","artifact.name":"Windows::Registry::ShellBags","field001":"value001","field002":"value002","field003":"value003","field004":["aaa","bbb"]}"#, deserialized);
372 let serialized : ForensicData = serde_json::from_str(&deserialized).unwrap();
373 assert_eq!(Artifact::Windows(WindowsArtifacts::Registry(RegistryArtifacts::ShellBags)), serialized.artifact);
374 let deserialized2 = serde_json::to_string(&serialized).unwrap();
375 assert_eq!(deserialized, deserialized2);
376 }
377}