use crate::eve::eve::EveJson;
use crate::logger::log;
use crate::rules::RuleMap;
use serde_json::json;
use std::sync::Arc;
pub enum EveFilter {
GeoIP(crate::geoip::GeoIP),
EveBoxMetadataFilter(EveBoxMetadataFilter),
CustomFieldFilter(CustomFieldFilter),
AddRuleFilter(AddRuleFilter),
Filters(Arc<Vec<EveFilter>>),
}
impl EveFilter {
pub fn run(&self, mut event: &mut EveJson) {
match self {
EveFilter::GeoIP(geoip) => {
geoip.add_geoip_to_eve(&mut event);
}
EveFilter::EveBoxMetadataFilter(filter) => {
filter.run(&mut event);
}
EveFilter::CustomFieldFilter(filter) => {
filter.run(&mut event);
}
EveFilter::AddRuleFilter(filter) => {
filter.run(&mut event);
}
EveFilter::Filters(filters) => {
for filter in filters.iter() {
filter.run(&mut event);
}
}
}
}
}
#[derive(Debug, Default)]
pub struct EveBoxMetadataFilter {
pub filename: Option<String>,
}
impl EveBoxMetadataFilter {
pub fn run(&self, event: &mut EveJson) {
if let EveJson::Null = event["evebox"] {
event["evebox"] = json!({});
}
if let EveJson::Object(_) = &event["evebox"] {
if let Some(filename) = &self.filename {
event["evebox"]["filename"] = filename.to_string().into();
}
}
event["tags"] = serde_json::Value::Array(vec![]);
}
}
impl From<EveBoxMetadataFilter> for EveFilter {
fn from(filter: EveBoxMetadataFilter) -> Self {
EveFilter::EveBoxMetadataFilter(filter)
}
}
pub struct CustomFieldFilter {
pub field: String,
pub value: String,
}
impl CustomFieldFilter {
pub fn new(field: &str, value: &str) -> Self {
Self {
field: field.to_string(),
value: value.to_string(),
}
}
pub fn run(&self, event: &mut EveJson) {
event[&self.field] = self.value.clone().into();
}
}
impl From<CustomFieldFilter> for EveFilter {
fn from(filter: CustomFieldFilter) -> Self {
EveFilter::CustomFieldFilter(filter)
}
}
pub struct AddRuleFilter {
pub map: Arc<RuleMap>,
}
impl AddRuleFilter {
pub fn run(&self, event: &mut EveJson) {
if let EveJson::String(_) = event["alert"]["rule"] {
return;
}
if let Some(sid) = &event["alert"]["signature_id"].as_u64() {
if let Some(rule) = self.map.find_by_sid(*sid) {
event["alert"]["rule"] = rule.into();
} else {
log::trace!("Failed to find rule for SID {}", sid);
}
}
}
}