dfirtk_eventdata/
session_id.rs

1use std::sync::Mutex;
2use std::convert::TryFrom;
3
4use crate::ActivityId;
5use evtx::SerializedEvtxRecord;
6use serde::Serialize;
7use serde_json::Value;
8
9#[derive(PartialEq, Eq, PartialOrd, Hash, Ord, Clone, Debug, Serialize)]
10pub enum SessionId {
11    ActivityId(String),
12    SessionName(String),
13    LogonId(String),
14    SessionId(String),
15    None(u64),
16}
17
18pub trait SessionIdGenerator {
19    fn session_id_of(record: &SerializedEvtxRecord<Value>) -> SessionId;
20}
21
22static NO_SESSION_ID_MUTEX: Mutex<u64> = Mutex::new(0);
23pub struct NoSessionId {}
24impl SessionIdGenerator for NoSessionId {
25    fn session_id_of(_: &SerializedEvtxRecord<Value>) -> SessionId {
26        let mut id_mutex = NO_SESSION_ID_MUTEX.lock().unwrap();
27        let id = *id_mutex;
28        *id_mutex = id + 1;
29        SessionId::None(id)
30    }
31}
32
33pub struct SessionNameInEventData {}
34impl SessionIdGenerator for SessionNameInEventData {
35    fn session_id_of(record: &SerializedEvtxRecord<Value>) -> SessionId {
36        SessionId::SessionName(
37            record.data["Event"]["EventData"]["SessionName"]
38                .as_str()
39                .expect("missing SessionName in event")
40                .into(),
41        )
42    }
43}
44
45pub struct SessionNameInActivityId {}
46impl SessionIdGenerator for SessionNameInActivityId {
47    fn session_id_of(record: &SerializedEvtxRecord<Value>) -> SessionId {
48        let activity_id = ActivityId::try_from(record).expect("missing activity id in event");
49
50        match activity_id.value().as_str() {
51            None => {
52                SessionId::ActivityId("".into())
53            }
54            Some(activity_id) => {
55                SessionId::ActivityId(activity_id.into())
56            }
57        }
58    }
59}
60
61pub struct SessionNameInTargetLogonId {}
62impl SessionIdGenerator for SessionNameInTargetLogonId {
63    fn session_id_of(record: &SerializedEvtxRecord<Value>) -> SessionId {
64        SessionId::LogonId(
65            record.data["Event"]["EventData"]["SessionName"]
66                .as_str()
67                .expect("missing TargetLogonId in event")
68                .into(),
69        )
70    }
71}
72
73pub struct SessionNameInSubjectLogonId {}
74impl SessionIdGenerator for SessionNameInSubjectLogonId {
75    fn session_id_of(record: &SerializedEvtxRecord<Value>) -> SessionId {
76        SessionId::LogonId(
77            record.data["Event"]["EventData"]["SubjectLogonId"]
78                .as_str()
79                .expect("missing SubjectLogonId in event")
80                .into(),
81        )
82    }
83}
84
85pub struct SessionNameInLogonId {}
86impl SessionIdGenerator for SessionNameInLogonId {
87    fn session_id_of(record: &SerializedEvtxRecord<Value>) -> SessionId {
88        if let Some(children) = record.data["Event"]["EventData"].as_object() {
89            for child in children {
90                if child.0.to_lowercase() == "targetlogonid" {
91                    return SessionId::LogonId(child.1.as_str().unwrap().to_owned())
92                }
93                if child.0.to_lowercase() == "logonid" {
94                    return SessionId::LogonId(child.1.as_str().unwrap().to_owned())
95                }
96            }
97        }
98        panic!("missing LogonId in event: {event}", event = record.data);
99    }
100}
101
102pub struct SessionIdInUserData {}
103impl SessionIdGenerator for SessionIdInUserData {
104    fn session_id_of(record: &SerializedEvtxRecord<Value>) -> SessionId {
105        SessionId::LogonId(
106            record.data["Event"]["UserData"]["EventXML"]["SessionID"]
107                .as_str()
108                .expect("missing SessionID in event")
109                .into(),
110        )
111    }
112}