crowdstrike_cloudproto/
services.rs

1//! High-level socket/client support for the main CloudProto services
2
3pub mod lfo;
4pub mod ts;
5
6use strum_macros::{Display, EnumCount, FromRepr};
7
8/// This CID is **NOT** structurally valid, it would not be accepted by the sensor.
9/// It is also possible to use a structurally valid CID that belongs to no one, but all zeros are accepted by LFO.
10pub const DEFAULT_CID_HEX: &str = "00000000000000000000000000000000";
11/// The AID is a value assigned to clients by TS on connection. It is zero for new agents.
12pub const DEFAULT_AID_HEX: &str = "00000000000000000000000000000000";
13/// Arbitrary machine-specific value generated on an isolated VM (from /proc/sys/kernel/random/boot_id)
14pub const DEFAULT_BOOTID_HEX: &str = "6c959680d4945d45924301a720debc88";
15/// Arbitrary machine-specific value generated on an isolated VM
16pub const DEFAULT_UNK0_HEX: &str = "54645dacc392cb43b4803094141e0087";
17
18#[repr(u8)]
19#[derive(Eq, PartialEq, Debug, Copy, Clone, Display, EnumCount, FromRepr)]
20pub enum CloudProtoMagic {
21    TS,
22    LFO,
23    Other(u8),
24}
25
26impl From<u8> for CloudProtoMagic {
27    fn from(value: u8) -> Self {
28        match value {
29            x if x == Self::TS => Self::TS,
30            x if x == Self::LFO => Self::LFO,
31            x => Self::Other(x),
32        }
33    }
34}
35
36impl From<CloudProtoMagic> for u8 {
37    fn from(kind: CloudProtoMagic) -> Self {
38        match kind {
39            CloudProtoMagic::TS => 0x8F,
40            CloudProtoMagic::LFO => 0x9F,
41            CloudProtoMagic::Other(x) => x,
42        }
43    }
44}
45
46impl From<&CloudProtoMagic> for u8 {
47    fn from(v: &CloudProtoMagic) -> Self {
48        u8::from(*v)
49    }
50}
51
52impl PartialEq<u8> for CloudProtoMagic {
53    fn eq(&self, other: &u8) -> bool {
54        u8::from(self) == *other
55    }
56}
57
58impl PartialEq<CloudProtoMagic> for u8 {
59    fn eq(&self, other: &CloudProtoMagic) -> bool {
60        u8::from(other) == *self
61    }
62}
63
64impl std::fmt::LowerHex for CloudProtoMagic {
65    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
66        let val: u8 = self.into();
67        std::fmt::LowerHex::fmt(&val, f)
68    }
69}
70
71impl std::fmt::UpperHex for CloudProtoMagic {
72    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73        let val: u8 = self.into();
74        std::fmt::UpperHex::fmt(&val, f)
75    }
76}
77
78#[cfg(test)]
79mod test {
80    use super::CloudProtoMagic;
81    use std::collections::HashSet;
82    use strum::EnumCount;
83
84    #[test]
85    fn cloud_proto_magic_roundtrip() {
86        let mut seen = HashSet::new();
87        for v in 0..=u8::MAX {
88            let m = CloudProtoMagic::from(v);
89            seen.insert(std::mem::discriminant(&m));
90            assert_eq!(u8::from(m), v);
91        }
92        // If this fails, you may have forgotten to update From<u8>
93        assert_eq!(seen.len(), CloudProtoMagic::COUNT)
94    }
95}