<?php
// security_monitor.php
class SecurityMonitor {
    private $logFile;
    private $emailTo;
    private $maxFailedAttempts;
    private $blockDuration;
    private $blockedIPs;
    
    public function __construct($config = []) {
        // Initialize settings
        $this->logFile = $config['logFile'] ?? dirname(__FILE__) . '/security.log';
        $this->emailTo = $config['emailTo'] ?? '';
        $this->maxFailedAttempts = $config['maxFailedAttempts'] ?? 5;
        $this->blockDuration = $config['blockDuration'] ?? 3600; // 1 hour
        $this->blockedIPs = $this->loadBlockedIPs();
    }
    
    public function checkSecurity() {
        $ip = $this->getClientIP();
        
        // Check if IP is blocked
        if ($this->isIPBlocked($ip)) {
            $this->logActivity("Blocked access attempt from: $ip");
            header("HTTP/1.0 403 Forbidden");
            die("Access Denied");
        }
        
        // Log visit
        $this->logActivity("Visit from: $ip");
        
        // Check for suspicious activity
        $this->checkSuspiciousActivity($ip);
    }
    
    private function checkSuspiciousActivity($ip) {
        // Check POST requests
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            $this->checkPostData();
        }
        
        // Check for common attack patterns
        $this->checkURLInjection();
        $this->checkSQLInjection();
        $this->checkXSS();
    }
    
    private function checkPostData() {
        foreach ($_POST as $key => $value) {
            // Check for suspicious patterns
            if ($this->containsSuspiciousPattern($value)) {
                $this->handleThreat("Suspicious POST data detected", [
                    'ip' => $this->getClientIP(),
                    'data' => substr($value, 0, 100) // Log only first 100 chars
                ]);
            }
        }
    }
    
    private function checkURLInjection() {
        $url = $_SERVER['REQUEST_URI'];
        $suspicious_patterns = [
            '../../',
            'cmd=',
            'exec=',
            'wget',
            'curl',
            '/etc/passwd'
        ];
        
        foreach ($suspicious_patterns as $pattern) {
            if (stripos($url, $pattern) !== false) {
                $this->handleThreat("URL Injection attempt detected", [
                    'ip' => $this->getClientIP(),
                    'url' => $url
                ]);
            }
        }
    }
    
    private function checkSQLInjection() {
        $input = array_merge($_GET, $_POST);
        $patterns = [
            "SELECT.*FROM",
            "INSERT.*INTO",
            "UPDATE.*SET",
            "DELETE.*FROM",
            "DROP.*TABLE",
            "UNION.*SELECT",
            "--",
            "1=1"
        ];
        
        foreach ($input as $value) {
            foreach ($patterns as $pattern) {
                if (preg_match("/$pattern/i", $value)) {
                    $this->handleThreat("SQL Injection attempt detected", [
                        'ip' => $this->getClientIP(),
                        'input' => substr($value, 0, 100)
                    ]);
                }
            }
        }
    }
    
    private function checkXSS() {
        $input = array_merge($_GET, $_POST);
        $patterns = [
            "<script",
            "javascript:",
            "onerror=",
            "onload=",
            "eval(",
            "alert("
        ];
        
        foreach ($input as $value) {
            foreach ($patterns as $pattern) {
                if (stripos($value, $pattern) !== false) {
                    $this->handleThreat("XSS attempt detected", [
                        'ip' => $this->getClientIP(),
                        'input' => substr($value, 0, 100)
                    ]);
                }
            }
        }
    }
    
    private function handleThreat($message, $data) {
        // Log threat
        $this->logActivity($message . ": " . json_encode($data));
        
        // Increment failed attempts
        $this->incrementFailedAttempts($data['ip']);
        
        // Send alert email
        $this->sendAlert($message, $data);
    }
    
    private function incrementFailedAttempts($ip) {
        $attempts = $this->loadFailedAttempts();
        
        if (!isset($attempts[$ip])) {
            $attempts[$ip] = ['count' => 0, 'timestamp' => time()];
        }
        
        $attempts[$ip]['count']++;
        $attempts[$ip]['timestamp'] = time();
        
        // Block IP if too many attempts
        if ($attempts[$ip]['count'] >= $this->maxFailedAttempts) {
            $this->blockIP($ip);
        }
        
        file_put_contents(dirname(__FILE__) . '/failed_attempts.json', json_encode($attempts));
    }
    
    private function blockIP($ip) {
        $this->blockedIPs[$ip] = time() + $this->blockDuration;
        file_put_contents(dirname(__FILE__) . '/blocked_ips.json', json_encode($this->blockedIPs));
        $this->logActivity("IP Blocked: $ip");
        $this->sendAlert("IP Address Blocked", ['ip' => $ip]);
    }
    
    private function isIPBlocked($ip) {
        if (isset($this->blockedIPs[$ip])) {
            if ($this->blockedIPs[$ip] > time()) {
                return true;
            } else {
                unset($this->blockedIPs[$ip]);
                file_put_contents(dirname(__FILE__) . '/blocked_ips.json', json_encode($this->blockedIPs));
            }
        }
        return false;
    }
    
    private function loadBlockedIPs() {
        $file = dirname(__FILE__) . '/blocked_ips.json';
        return file_exists($file) ? json_decode(file_get_contents($file), true) : [];
    }
    
    private function loadFailedAttempts() {
        $file = dirname(__FILE__) . '/failed_attempts.json';
        return file_exists($file) ? json_decode(file_get_contents($file), true) : [];
    }
    
    private function logActivity($message) {
        $date = date('Y-m-d H:i:s');
        file_put_contents($this->logFile, "[$date] $message\n", FILE_APPEND);
    }
    
    private function sendAlert($subject, $data) {
        if (empty($this->emailTo)) return;
        
        $message = "Security Alert: $subject\n\n";
        $message .= "Details:\n";
        $message .= json_encode($data, JSON_PRETTY_PRINT);
        
        mail($this->emailTo, "Security Alert: $subject", $message);
    }
    
    private function getClientIP() {
        return $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
    }
    
    private function containsSuspiciousPattern($value) {
        $patterns = [
            "eval\(",
            "system\(",
            "exec\(",
            "base64_decode\(",
            "<script",
            "<?php"
        ];
        
        foreach ($patterns as $pattern) {
            if (preg_match("/$pattern/i", $value)) {
                return true;
            }
        }
        return false;
    }
}
