pmat 3.11.0

PMAT - Zero-config AI context generation and code quality toolkit (CLI, MCP, HTTP)
// Security auditing and vulnerability checks
// Included from analyzer.rs - shares parent module scope

/// Security auditor for comprehensive security analysis
#[derive(Debug, Clone)]
pub struct SecurityAuditor {
    checks: Vec<SecurityCheck>,
}

impl Default for SecurityAuditor {
    fn default() -> Self {
        Self::new()
    }
}

impl SecurityAuditor {
    #[must_use]
    pub fn new() -> Self {
        Self {
            checks: vec![
                SecurityCheck::NoFilesystemAccess,
                SecurityCheck::NoNetworkAccess,
                SecurityCheck::MemoryBoundsChecked,
                SecurityCheck::NoUnvalidatedIndirectCalls,
                SecurityCheck::NoIntegerOverflow,
            ],
        }
    }

    pub fn audit(&self, binary: &[u8]) -> Result<SecurityReport> {
        let mut report = SecurityReport::new();

        // Run each security check
        for check in &self.checks {
            let result = check.verify(binary);
            report.add_check_result(check.name(), result);
        }

        Ok(report)
    }
}

/// Security analysis report
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SecurityReport {
    pub passed_checks: Vec<String>,
    pub failed_checks: Vec<String>,
    pub warnings: Vec<String>,
    pub is_safe: bool,
}

impl Default for SecurityReport {
    fn default() -> Self {
        Self::new()
    }
}

impl SecurityReport {
    #[must_use]
    pub fn new() -> Self {
        Self {
            passed_checks: Vec::new(),
            failed_checks: Vec::new(),
            warnings: Vec::new(),
            is_safe: true,
        }
    }

    pub fn add_check_result(&mut self, check_name: &str, passed: bool) {
        if passed {
            self.passed_checks.push(check_name.to_string());
        } else {
            self.failed_checks.push(check_name.to_string());
            self.is_safe = false;
        }
    }
}

/// Individual security check
#[derive(Debug, Clone)]
enum SecurityCheck {
    NoFilesystemAccess,
    NoNetworkAccess,
    MemoryBoundsChecked,
    NoUnvalidatedIndirectCalls,
    NoIntegerOverflow,
}

impl SecurityCheck {
    fn name(&self) -> &str {
        match self {
            Self::NoFilesystemAccess => "no-filesystem-access",
            Self::NoNetworkAccess => "no-network-access",
            Self::MemoryBoundsChecked => "memory-bounds-checked",
            Self::NoUnvalidatedIndirectCalls => "no-unvalidated-indirect-calls",
            Self::NoIntegerOverflow => "no-integer-overflow",
        }
    }

    fn verify(&self, _binary: &[u8]) -> bool {
        // Simplified verification - real implementation would check imports/exports
        match self {
            Self::NoFilesystemAccess => true,         // Check for fs imports
            Self::NoNetworkAccess => true,            // Check for network imports
            Self::MemoryBoundsChecked => true,        // Verify all memory ops are bounds-checked
            Self::NoUnvalidatedIndirectCalls => true, // Check indirect call validation
            Self::NoIntegerOverflow => true,          // Check for overflow patterns
        }
    }
}