use super::{Action, OperatorSpec, VariableSpec};
use crate::error::SourceLocation;
use std::path::PathBuf;
#[derive(Debug, Clone)]
pub enum Directive {
SecRule(SecRule),
SecAction(SecAction),
SecMarker(SecMarker),
SecRuleEngine(RuleEngineMode),
SecDefaultAction(Vec<Action>),
SecRuleRemoveById(Vec<u64>),
SecRuleUpdateActionById { id: u64, actions: Vec<Action> },
SecRequestBodyAccess(bool),
SecResponseBodyAccess(bool),
SecRequestBodyLimit(usize),
SecResponseBodyLimit(usize),
Include(PathBuf),
Unknown(String),
}
#[derive(Debug, Clone)]
pub struct SecRule {
pub variables: Vec<VariableSpec>,
pub operator: OperatorSpec,
pub actions: Vec<Action>,
pub location: SourceLocation,
}
#[derive(Debug, Clone)]
pub struct SecAction {
pub actions: Vec<Action>,
pub location: SourceLocation,
}
#[derive(Debug, Clone)]
pub struct SecMarker {
pub name: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RuleEngineMode {
On,
Off,
DetectionOnly,
}
impl Default for RuleEngineMode {
fn default() -> Self {
Self::Off
}
}
impl SecRule {
pub fn is_chained(&self) -> bool {
self.actions.iter().any(|a| matches!(a, Action::Flow(super::FlowAction::Chain)))
}
pub fn id(&self) -> Option<u64> {
for action in &self.actions {
if let Action::Metadata(super::MetadataAction::Id(id)) = action {
return Some(*id);
}
}
None
}
pub fn phase(&self) -> u8 {
for action in &self.actions {
if let Action::Metadata(super::MetadataAction::Phase(phase)) = action {
return *phase;
}
}
2 }
}