<?php
/**
 * VMP Security WAF Bootstrap
 * 
 * This file is loaded BEFORE WordPress via auto_prepend_file directive
 * Provides maximum protection by running firewall before WordPress loads
 * 
 * DO NOT EDIT THIS FILE MANUALLY - Generated by WAF Optimizer
 * 
 * @package VMPFence
 * @since 2.2.4
 */

// Define constant to signal WAF is loaded
define('VMPFENCE_WAF_LOADED', true);

// Error handler to prevent fatal errors from breaking the site
set_error_handler(function($errno, $errstr, $errfile, $errline) {
    return true;
});

/**
 * Display styled 403 block page (pure PHP, no WordPress dependencies)
 */
function vmpwaf_block_page($title, $subtitle, $reason, $ip, $details = array()) {
    $current_time = date('Y-m-d H:i:s');
    $details_html = '';
    
    if (!empty($details)) {
        foreach ($details as $key => $value) {
            $details_html .= '<div class="info-row">
                <span class="info-label">' . htmlspecialchars($key) . '</span>
                <span class="info-value">' . htmlspecialchars($value) . '</span>
            </div>';
        }
    }
    
    http_response_code(403);
    header('Content-Type: text/html; charset=UTF-8');
    echo '<!DOCTYPE html>
<html>
<head>
    <title>403 Forbidden - ' . htmlspecialchars($title) . '</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        body { 
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
            margin: 0;
            padding: 0;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        .container { 
            max-width: 600px; 
            width: 90%;
            background: white; 
            padding: 50px 40px; 
            border-radius: 10px; 
            box-shadow: 0 20px 60px rgba(0,0,0,0.3);
        }
        .error-code {
            font-size: 72px;
            font-weight: bold;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            background-clip: text;
            text-align: center;
            margin: 0 0 20px 0;
            line-height: 1;
        }
        h1 { 
            color: #2d3748; 
            font-size: 28px;
            text-align: center;
            margin: 0 0 15px 0;
            font-weight: 600;
        }
        .subtitle {
            color: #718096;
            text-align: center;
            font-size: 16px;
            margin: 0 0 30px 0;
        }
        .shield-icon {
            text-align: center;
            font-size: 48px;
            margin-bottom: 20px;
        }
        .alert-box {
            background: #fff5f5;
            border-left: 4px solid #fc8181;
            padding: 20px;
            border-radius: 5px;
            margin: 25px 0;
        }
        .alert-title {
            color: #c53030;
            font-weight: 600;
            font-size: 16px;
            margin: 0 0 10px 0;
        }
        .alert-message {
            color: #742a2a;
            line-height: 1.6;
            margin: 0;
        }
        .info-box {
            background: #f7fafc;
            padding: 20px;
            border-radius: 8px;
            margin: 25px 0;
            border: 1px solid #e2e8f0;
        }
        .info-row {
            display: flex;
            justify-content: space-between;
            padding: 10px 0;
            border-bottom: 1px solid #e2e8f0;
        }
        .info-row:last-child {
            border-bottom: none;
        }
        .info-label {
            color: #4a5568;
            font-weight: 500;
        }
        .info-value {
            color: #2d3748;
            font-weight: 600;
        }
        .footer {
            font-size: 13px;
            color: #a0aec0;
            text-align: center;
            margin-top: 30px;
            padding-top: 20px;
            border-top: 1px solid #e2e8f0;
        }
        @media (max-width: 600px) {
            .container {
                padding: 30px 20px;
            }
            .error-code {
                font-size: 56px;
            }
            h1 {
                font-size: 24px;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="shield-icon">🛡️</div>
        <div class="error-code">403</div>
        <h1>' . htmlspecialchars($title) . '</h1>
        <p class="subtitle">' . htmlspecialchars($subtitle) . '</p>
        
        <div class="alert-box">
            <div class="alert-title">🚫 Request Blocked</div>
            <div class="alert-message">
                ' . htmlspecialchars($reason) . '
            </div>
        </div>

        <div class="info-box">
            <div class="info-row">
                <span class="info-label">Your IP</span>
                <span class="info-value">' . htmlspecialchars($ip) . '</span>
            </div>
            <div class="info-row">
                <span class="info-label">Status</span>
                <span class="info-value" style="color: #c53030;">Blocked</span>
            </div>
            <div class="info-row">
                <span class="info-label">Time</span>
                <span class="info-value">' . htmlspecialchars($current_time) . '</span>
            </div>
            ' . $details_html . '
        </div>

        <div class="footer">
            <p><strong>What happened?</strong></p>
            <p>Your request was blocked by our Web Application Firewall for security purposes.</p>
            <p style="margin-top: 15px;">If you believe this is an error, please contact the site administrator with the information above.</p>
            <p style="margin-top: 20px; font-size: 11px;">Protected by VMPFence Security • Incident logged for review</p>
        </div>
    </div>
</body>
</html>';
    exit;
}

try {    
    // Get WordPress root path
    $wp_root = '{ABSPATH}';
    
    // Parse WordPress configuration WITHOUT loading WordPress
    $wp_config_file = '';
    if (file_exists($wp_root . 'wp-config.php')) {
        $wp_config_file = $wp_root . 'wp-config.php';
    } elseif (file_exists(dirname($wp_root) . '/wp-config.php')) {
        $wp_config_file = dirname($wp_root) . '/wp-config.php';
    } else {
        restore_error_handler();
        return;
    }
    
    // Extract database credentials from wp-config.php without executing it
    $config_content = file_get_contents($wp_config_file);
    
    // Extract DB constants using regex
    preg_match("/define\s*\(\s*['\"]DB_NAME['\"]\s*,\s*['\"](.*?)['\"]\s*\)/", $config_content, $db_name);
    preg_match("/define\s*\(\s*['\"]DB_USER['\"]\s*,\s*['\"](.*?)['\"]\s*\)/", $config_content, $db_user);
    preg_match("/define\s*\(\s*['\"]DB_PASSWORD['\"]\s*,\s*['\"](.*?)['\"]\s*\)/", $config_content, $db_password);
    preg_match("/define\s*\(\s*['\"]DB_HOST['\"]\s*,\s*['\"](.*?)['\"]\s*\)/", $config_content, $db_host);
    
    $DB_NAME = isset($db_name[1]) ? $db_name[1] : '';
    $DB_USER = isset($db_user[1]) ? $db_user[1] : '';
    $DB_PASSWORD = isset($db_password[1]) ? $db_password[1] : '';
    $DB_HOST = isset($db_host[1]) ? $db_host[1] : '';
    
    // Establish database connection
    if (!empty($DB_HOST) && !empty($DB_USER) && !empty($DB_NAME)) {
        global $wpdb;
        
        // Create mysqli connection
        $mysqli = new mysqli($DB_HOST, $DB_USER, $DB_PASSWORD, $DB_NAME);
        
        if ($mysqli->connect_error) {
            restore_error_handler();
            return;
        }
        
        // Get table prefix
        $table_prefix = '{TABLE_PREFIX}';
        
        // Load essential configuration
        $config_table = $table_prefix . 'vmpfence_config';
        
        // Check if WAF is enabled
        $query = "SELECT val FROM `$config_table` WHERE name = 'waf_enabled' LIMIT 1";
        $result = $mysqli->query($query);
        
        if ($result && $row = $result->fetch_assoc()) {
            $waf_enabled = (int) $row['val'];
            
            if (!$waf_enabled) {
                $mysqli->close();
                restore_error_handler();
                return;
            }
        }
        
        // Get visitor IP
        $visitor_ip = '';
        $ip_source = 'unknown';
        if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) {
            $visitor_ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
            $ip_source = 'Cloudflare';
        } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
            $visitor_ip = trim($ips[0]);
            $ip_source = 'X-Forwarded-For';
        } elseif (isset($_SERVER['REMOTE_ADDR'])) {
            $visitor_ip = $_SERVER['REMOTE_ADDR'];
            $ip_source = 'REMOTE_ADDR';
        }

        // ==================== BASIC WAF RULES CHECK ====================
        
        // Get request data for pattern matching
        $request_uri = $_SERVER['REQUEST_URI'] ?? '';
        $query_string = $_SERVER['QUERY_STRING'] ?? '';
        $user_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
        $request_body = file_get_contents('php://input');
        
        // Combine all input sources for pattern matching
        $all_input = $request_uri . ' ' . $query_string . ' ' . http_build_query($_GET) . ' ' . http_build_query($_POST) . ' ' . $request_body;
        
        // URL-decode the input to catch encoded attacks (e.g., %3Cscript%3E becomes <script>)
        $all_input_decoded = urldecode($all_input);
        
        // Basic XSS patterns
        $xss_patterns = array(
            '/<script[\s\S]*?>/i',
            '/javascript:/i',
            '/on(load|error|click|mouse|focus|blur)[\s]*=/i',
            '/<iframe/i',
            '/eval\s*\(/i',
            '/expression\s*\(/i',
            '/<embed/i',
            '/<object/i'
        );
        
        foreach ($xss_patterns as $pattern) {
            if (preg_match($pattern, $all_input_decoded, $matches)) {
                $mysqli->close();
                restore_error_handler();
                
                vmpwaf_block_page(
                    'XSS Attack Detected',
                    'Cross-Site Scripting attempt blocked',
                    'Your request contains potentially malicious script code.',
                    $visitor_ip,
                    array(
                        'Attack Type' => 'XSS',
                        'Pattern Matched' => substr($matches[0], 0, 50),
                        'Request URI' => substr($request_uri, 0, 100)
                    )
                );
            }
        }
        
        // Basic SQLi patterns
        $sqli_patterns = array(
            '/union[\s]+select/i',
            '/select[\s]+.*[\s]+from/i',
            '/insert[\s]+into/i',
            '/delete[\s]+from/i',
            '/drop[\s]+table/i',
            '/update[\s]+.*[\s]+set/i',
            '/or[\s]+1[\s]*=[\s]*1/i',
            '/or[\s]+\'1\'[\s]*=[\s]*\'1\'/i',
            '/exec[\s]*\(/i',
            '/concat[\s]*\(/i',
            '/\/\*.*\*\//i',
            '/;\s*drop/i'
        );
        
        foreach ($sqli_patterns as $pattern) {
            if (preg_match($pattern, $all_input_decoded, $matches)) {
                $mysqli->close();
                restore_error_handler();
                
                vmpwaf_block_page(
                    'SQL Injection Detected',
                    'SQL Injection attempt blocked',
                    'Your request contains potentially malicious SQL code.',
                    $visitor_ip,
                    array(
                        'Attack Type' => 'SQL Injection',
                        'Pattern Matched' => substr($matches[0], 0, 50),
                        'Request URI' => substr($request_uri, 0, 100)
                    )
                );
            }
        }
        
        // Basic RCE patterns
        $rce_patterns = array(
            '/system\s*\(/i',
            '/exec\s*\(/i',
            '/passthru\s*\(/i',
            '/shell_exec\s*\(/i',
            '/popen\s*\(/i',
            '/proc_open\s*\(/i',
            '/base64_decode\s*\(/i',
            '/assert\s*\(/i',
            '/create_function\s*\(/i'
        );
        
        foreach ($rce_patterns as $pattern) {
            if (preg_match($pattern, $all_input_decoded, $matches)) {
                $mysqli->close();
                restore_error_handler();
                
                vmpwaf_block_page(
                    'Remote Code Execution Detected',
                    'RCE attempt blocked',
                    'Your request contains potentially malicious code execution patterns.',
                    $visitor_ip,
                    array(
                        'Attack Type' => 'Remote Code Execution',
                        'Pattern Matched' => substr($matches[0], 0, 50),
                        'Request URI' => substr($request_uri, 0, 100)
                    )
                );
            }
        }
        
        // Basic LFI/RFI patterns
        $lfi_patterns = array(
            '/\.\.[\/\\\\]/i',
            '/php:\/\//i',
            '/file:\/\//i',
            '/data:\/\//i',
            '/zip:\/\//i',
            '/expect:\/\//i',
            '/\/etc\/passwd/i',
            '/\/proc\/self/i',
            '/\/windows\/system32/i'
        );
        
        foreach ($lfi_patterns as $pattern) {
            if (preg_match($pattern, $all_input_decoded, $matches)) {
                $mysqli->close();
                restore_error_handler();
                
                vmpwaf_block_page(
                    'File Inclusion Attack Detected',
                    'LFI/RFI attempt blocked',
                    'Your request contains potentially malicious file path traversal patterns.',
                    $visitor_ip,
                    array(
                        'Attack Type' => 'Local/Remote File Inclusion',
                        'Pattern Matched' => substr($matches[0], 0, 50),
                        'Request URI' => substr($request_uri, 0, 100)
                    )
                );
            }
        }
        
        // ==================== END WAF RULES CHECK ====================
        
        // Check blocked IPs
        if (!empty($visitor_ip)) {
            $blocked_ips_table = $table_prefix . 'vmpfence_blocked_ips';
            $safe_ip = $mysqli->real_escape_string($visitor_ip);
            $query = "SELECT id FROM `$blocked_ips_table` WHERE ip_address = '$safe_ip' AND is_active = 1 LIMIT 1";
            $result = $mysqli->query($query);
            
            if ($result && $result->num_rows > 0) {
                // Close database connection
                $mysqli->close();
                restore_error_handler();
                
                vmpwaf_block_page(
                    'IP Address Blocked',
                    'Your IP has been blocked',
                    'Your IP address has been blocked by the site administrator.',
                    $visitor_ip,
                    array(
                        'Block Type' => 'IP Blocking',
                        'Request URI' => substr($_SERVER['REQUEST_URI'] ?? '/', 0, 100)
                    )
                );
            }
        }
        
        // Check blocked countries (if GeoIP enabled)
        $geoip_enabled_query = "SELECT val FROM `$config_table` WHERE name = 'country_blocking_enabled' LIMIT 1";
        $geoip_result = $mysqli->query($geoip_enabled_query);
        
        if ($geoip_result && $geoip_row = $geoip_result->fetch_assoc()) {
            $country_blocking_enabled = (int) $geoip_row['val'];
            
            if ($country_blocking_enabled && !empty($visitor_ip)) {
                // Load GeoIP lookup (simplified for WAF)
                $geoip_table = $table_prefix . 'vmpfence_geoip_ranges';
                $blocked_countries_table = $table_prefix . 'vmpfence_blocked_countries';
                
                // Convert IP to long for range matching
                $ip_long = ip2long($visitor_ip);
                
                if ($ip_long !== false) {
                    // Find country code
                    $query = "SELECT country_code FROM `$geoip_table` WHERE $ip_long BETWEEN ip_from AND ip_to LIMIT 1";
                    $result = $mysqli->query($query);
                    
                    if ($result && $row = $result->fetch_assoc()) {
                        $country_code = $row['country_code'];
                        
                        // Check if country is blocked
                        $safe_country = $mysqli->real_escape_string($country_code);
                        $query = "SELECT id FROM `$blocked_countries_table` WHERE country_code = '$safe_country' LIMIT 1";
                        $result = $mysqli->query($query);
                        
                        if ($result && $result->num_rows > 0) {                            
                            // Close database connection
                            $mysqli->close();
                            restore_error_handler();
                            
                            vmpwaf_block_page(
                                'Country Blocked',
                                'Access from your country is restricted',
                                'Site access from your geographic location has been blocked.',
                                $visitor_ip,
                                array(
                                    'Block Type' => 'Country Blocking',
                                    'Country Code' => $country_code,
                                    'Request URI' => substr($_SERVER['REQUEST_URI'] ?? '/', 0, 100)
                                )
                            );
                        }
                    }
                }
            }
        }
        
        // Close database connection
        $mysqli->close();        
    }
    
} catch (Exception $e) {
    error_log('VMP WAF Exception: ' . $e->getMessage());
} catch (Error $e) {
    error_log('VMP WAF Fatal Error: ' . $e->getMessage());
}

// Restore error handler
restore_error_handler();

// Continue to WordPress
