forensic_rs/traits/
forensic.rs

1use std::borrow::Cow;
2
3use crate::{activity::ForensicActivity, prelude::ForensicData, utils::time::Filetime};
4
5/// Quickly transform a structure into one or more events that are part of a timeline
6/// ```rust,ignore
7/// impl<'a> IntoTimeline<'a> for PrefetchFile {
8///     fn timeline(&'a self) -> Self::IntoIter {
9///         PrefetchTimelineIterator {
10///             prefetch : self,
11///             time_pos : 0
12///         }
13///     }
14/// 
15///     type IntoIter = PrefetchTimelineIterator<'a> where Self: 'a;
16/// }
17/// ```
18pub trait IntoTimeline<'a> {
19    type IntoIter: Iterator<Item = TimelineData> where Self: 'a;
20    
21    fn timeline(&'a self) -> Self::IntoIter;
22}
23
24/// Quickly transform a structure into one or more user activity events. In order to know what a user did at a high level at a specific moment.
25/// 
26/// Example: `ForensicActivity { timestamp: 06-11-2023 15:18:00.237, user: "", session_id: Unknown, activity: ProgramExecution(\VOLUME{01d98a6b9e4a0a35-1c9e547d}\WINDOWS\SYSWOW64\WINDOWSPOWERSHELL\V1.0\POWERSHELL.EXE) }`
27/// 
28/// ```rust,ignore
29/// impl<'a> IntoActivity<'a> for PrefetchFile {
30///     fn activity(&'a self) -> Self::IntoIter {
31///         PrefetchActivityIterator {
32///             prefetch : self,
33///             time_pos : 0
34///         }
35///     }
36/// 
37///     type IntoIter = PrefetchActivityIterator<'a> where Self: 'a;
38/// }
39/// ```
40pub trait IntoActivity<'a> {
41    type IntoIter: Iterator<Item = ForensicActivity> where Self: 'a;
42    
43    fn activity(&'a self) -> Self::IntoIter;
44}
45
46#[derive(Clone, Debug, Default)]
47pub enum TimeContext {
48    #[default]
49    Creation,
50    Modification,
51    Accessed,
52    Other(Cow<'static, str>)
53}
54
55#[derive(Clone, Debug, Default)]
56pub struct TimelineData {
57    pub time : Filetime,
58    pub data : ForensicData,
59    pub time_context : TimeContext
60}
61
62pub trait ArtifactParser : IntoIterator<Item = ForensicData>  {
63    fn name(&self) -> &'static str;
64    fn description(&self) -> &'static str;
65    fn version(&self) -> &'static str;
66}
67
68
69pub trait RegistryParser : ArtifactParser  {
70    fn valid_path(&self, pth : &str) -> bool;
71    fn first_path_pattern(&self) -> &str;
72}
73
74#[cfg(test)]
75mod artifacts {
76    use crate::{data::ForensicData, prelude::{RegistryArtifacts, Artifact}};
77
78    use super::ArtifactParser;
79
80    struct Parser123 {}
81
82    impl ArtifactParser for Parser123 {
83        fn name(&self) -> &'static str {
84            "parser123"
85        }
86
87        fn description(&self) -> &'static str {
88            "parser123"    
89        }
90
91        fn version(&self) -> &'static str {
92            "1.2.3"
93        }
94    }
95    struct IterParser123 {}
96    impl Iterator for IterParser123 {
97        type Item = ForensicData;
98
99        fn next(&mut self) -> Option<Self::Item> {
100           Some(ForensicData::new("123",  RegistryArtifacts::ShellBags.into()))
101        }
102    }
103
104    impl IntoIterator for Parser123 {
105        type Item = ForensicData;
106
107        type IntoIter = IterParser123;
108
109        fn into_iter(self) -> Self::IntoIter {
110            IterParser123{}
111        }
112    }
113
114    #[test]
115    fn should_iterate_parser() {
116        let parser = Parser123{};
117        let mut iter = parser.into_iter();
118        let artfct : Artifact = RegistryArtifacts::ShellBags.into();
119        assert_eq!(&artfct, iter.next().unwrap().artifact());
120
121    }
122}