coraza 0.1.0

Safe Rust bindings to OWASP Coraza WAF
/*
 * Copyright 2022 OWASP Coraza contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

use coraza_sys::*;

/// Severity level of a matched rule.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Severity {
    Unknown,
    Debug,
    Info,
    Notice,
    Warning,
    Error,
    Critical,
    Alert,
    Emergency,
}

impl From<coraza_severity_t> for Severity {
    fn from(val: coraza_severity_t) -> Self {
        match val {
            coraza_severity_t_CORAZA_SEVERITY_DEBUG => Severity::Debug,
            coraza_severity_t_CORAZA_SEVERITY_INFO => Severity::Info,
            coraza_severity_t_CORAZA_SEVERITY_NOTICE => Severity::Notice,
            coraza_severity_t_CORAZA_SEVERITY_WARNING => Severity::Warning,
            coraza_severity_t_CORAZA_SEVERITY_ERROR => Severity::Error,
            coraza_severity_t_CORAZA_SEVERITY_CRITICAL => Severity::Critical,
            coraza_severity_t_CORAZA_SEVERITY_ALERT => Severity::Alert,
            coraza_severity_t_CORAZA_SEVERITY_EMERGENCY => Severity::Emergency,
            _ => Severity::Unknown,
        }
    }
}

impl std::fmt::Display for Severity {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Severity::Unknown => write!(f, "UNKNOWN"),
            Severity::Debug => write!(f, "DEBUG"),
            Severity::Info => write!(f, "INFO"),
            Severity::Notice => write!(f, "NOTICE"),
            Severity::Warning => write!(f, "WARNING"),
            Severity::Error => write!(f, "ERROR"),
            Severity::Critical => write!(f, "CRITICAL"),
            Severity::Alert => write!(f, "ALERT"),
            Severity::Emergency => write!(f, "EMERGENCY"),
        }
    }
}

/// A rule that matched during request processing.
#[derive(Debug, Clone)]
pub struct MatchedRule {
    /// The error log message for this match.
    pub message: String,
    /// The severity of the matched rule.
    pub severity: Severity,
    /// The numeric rule ID (from the seclang `id:` action).
    pub rule_id: i32,
    /// The URI being processed when the rule matched. Not exposed via C API.
    pub uri: String,
    /// The client IP address. Not exposed via C API.
    pub client_ip: String,
    /// The server IP address. Not exposed via C API.
    pub server_ip: String,
    /// Whether this rule is disruptive (deny/drop/redirect).
    pub disruptive: bool,
}

/// Debug log level for the WAF debug log callback.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum LogLevel {
    Unknown,
    Trace,
    Debug,
    Info,
    Warn,
    Error,
}

impl From<coraza_debug_log_level_t> for LogLevel {
    fn from(val: coraza_debug_log_level_t) -> Self {
        match val {
            coraza_debug_log_level_t_CORAZA_DEBUG_LOG_LEVEL_TRACE => LogLevel::Trace,
            coraza_debug_log_level_t_CORAZA_DEBUG_LOG_LEVEL_DEBUG => LogLevel::Debug,
            coraza_debug_log_level_t_CORAZA_DEBUG_LOG_LEVEL_INFO => LogLevel::Info,
            coraza_debug_log_level_t_CORAZA_DEBUG_LOG_LEVEL_WARN => LogLevel::Warn,
            coraza_debug_log_level_t_CORAZA_DEBUG_LOG_LEVEL_ERROR => LogLevel::Error,
            _ => LogLevel::Unknown,
        }
    }
}

impl std::fmt::Display for LogLevel {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            LogLevel::Unknown => write!(f, "UNKNOWN"),
            LogLevel::Trace => write!(f, "TRACE"),
            LogLevel::Debug => write!(f, "DEBUG"),
            LogLevel::Info => write!(f, "INFO"),
            LogLevel::Warn => write!(f, "WARN"),
            LogLevel::Error => write!(f, "ERROR"),
        }
    }
}