1use crate::model::KnowledgeBase;
5
6const EMBEDDED_LINUX: &str = include_str!("../data/knowledge.json");
7const EMBEDDED_WINDOWS: &str = include_str!("../data/knowledge-windows.json");
8const EMBEDDED_MACOS: &str = include_str!("../data/knowledge-macos.json");
9
10#[derive(Clone, Copy, Debug, PartialEq, Eq)]
12#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
13pub enum Platform {
14 #[cfg_attr(feature = "clap", value(name = "linux-auditd", alias = "linux"))]
16 LinuxAuditd,
17 #[cfg_attr(feature = "clap", value(name = "windows-sysmon", alias = "windows"))]
19 WindowsSysmon,
20 #[cfg_attr(feature = "clap", value(name = "macos-es", alias = "macos"))]
22 MacosEs,
23}
24
25impl Platform {
26 pub fn sigma_product(self) -> &'static str {
28 match self {
29 Platform::LinuxAuditd => "linux",
30 Platform::WindowsSysmon => "windows",
31 Platform::MacosEs => "macos",
32 }
33 }
34}
35
36#[derive(Debug)]
46pub enum KbError {
47 Parse(serde_json::Error),
49 Invalid(String),
52}
53
54impl std::fmt::Display for KbError {
55 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56 match self {
57 KbError::Parse(e) => write!(f, "malformed knowledge base: {e}"),
58 KbError::Invalid(m) => write!(f, "invalid knowledge base: {m}"),
59 }
60 }
61}
62
63impl std::error::Error for KbError {
64 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
65 match self {
66 KbError::Parse(e) => Some(e),
67 KbError::Invalid(_) => None,
68 }
69 }
70}
71
72impl From<serde_json::Error> for KbError {
73 fn from(e: serde_json::Error) -> Self {
74 KbError::Parse(e)
75 }
76}
77
78pub fn load(platform: Platform) -> Result<KnowledgeBase, KbError> {
85 let raw = match platform {
86 Platform::LinuxAuditd => EMBEDDED_LINUX,
87 Platform::WindowsSysmon => EMBEDDED_WINDOWS,
88 Platform::MacosEs => EMBEDDED_MACOS,
89 };
90 let kb: KnowledgeBase = serde_json::from_str(raw)?;
91 kb.validate().map_err(KbError::Invalid)?;
92 Ok(kb)
93}