false, 'error' => 'No command']); exit; } // Commandes bloquées $blocked = ['rm -rf /', 'rm -rf /*', 'mkfs', 'dd if=/dev', ':(){', '> /dev/sda']; foreach ($blocked as $b) { if (stripos($command, $b) !== false) { echo json_encode(['success' => false, 'error' => 'Commande bloquée']); exit; } } if (!is_dir($cwd)) $cwd = '/opt/wevads'; $descriptors = [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']]; $env = ['PATH' => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', 'HOME' => '/root', 'TERM' => 'xterm-256color']; $process = proc_open($command, $descriptors, $pipes, $cwd, $env); if (!is_resource($process)) { echo json_encode(['success' => false, 'error' => 'Cannot execute']); exit; } fclose($pipes[0]); stream_set_timeout($pipes[1], 30); stream_set_timeout($pipes[2], 30); $stdout = stream_get_contents($pipes[1]); $stderr = stream_get_contents($pipes[2]); fclose($pipes[1]); fclose($pipes[2]); $exitCode = proc_close($process); echo json_encode(['success' => true, 'stdout' => $stdout, 'stderr' => $stderr, 'exitCode' => $exitCode, 'cwd' => $cwd]); break; case 'scan': // Scan système complet $scan = [ 'hostname' => gethostname(), 'ip' => $_SERVER['SERVER_ADDR'] ?? '95.216.167.89', 'os' => php_uname(), 'php' => PHP_VERSION, 'uptime' => trim(shell_exec('uptime -p 2>/dev/null') ?: 'N/A'), 'load' => sys_getloadavg(), 'memory' => [], 'disk' => [], 'services' => [], 'processes' => [] ]; // Mémoire $free = shell_exec('free -b 2>/dev/null'); if (preg_match('/Mem:\s+(\d+)\s+(\d+)\s+(\d+)/', $free, $m)) { $scan['memory'] = ['total' => (int)$m[1], 'used' => (int)$m[2], 'free' => (int)$m[3], 'percent' => round($m[2]/$m[1]*100, 1)]; } // Disque $scan['disk'] = ['total' => disk_total_space('/'), 'free' => disk_free_space('/'), 'used' => disk_total_space('/') - disk_free_space('/'), 'percent' => round((1 - disk_free_space('/') / disk_total_space('/')) * 100, 1)]; // Services $services = ['apache2', 'nginx', 'postgresql', 'mysql', 'redis', 'docker', 'ollama']; foreach ($services as $svc) { $status = trim(shell_exec("systemctl is-active $svc 2>/dev/null") ?: 'unknown'); $scan['services'][$svc] = $status; } // Top processus $ps = shell_exec('ps aux --sort=-%mem 2>/dev/null | head -6'); $scan['top_processes'] = $ps; // Ports ouverts $scan['ports'] = trim(shell_exec('ss -tlnp 2>/dev/null | head -15') ?: ''); // Docker containers $scan['docker'] = trim(shell_exec('docker ps --format "{{.Names}}: {{.Status}}" 2>/dev/null') ?: ''); echo json_encode(['success' => true, 'scan' => $scan]); break; case 'read': $file = $_GET['file'] ?? $_POST['file'] ?? ''; if (empty($file) || !file_exists($file)) { echo json_encode(['success' => false, 'error' => 'File not found']); exit; } if (filesize($file) > 1024 * 1024) { echo json_encode(['success' => false, 'error' => 'File too large (max 1MB)']); exit; } $content = file_get_contents($file); echo json_encode(['success' => true, 'file' => $file, 'content' => $content, 'size' => filesize($file), 'modified' => filemtime($file)]); break; case 'write': $file = $_POST['file'] ?? ''; $content = $_POST['content'] ?? ''; $backup = $_POST['backup'] ?? true; if (empty($file)) { echo json_encode(['success' => false, 'error' => 'No file specified']); exit; } // Créer backup si le fichier existe if ($backup && file_exists($file)) { $backupFile = $file . '.backup_' . date('Ymd_His'); copy($file, $backupFile); } $result = file_put_contents($file, $content); echo json_encode(['success' => $result !== false, 'file' => $file, 'size' => $result, 'backup' => $backupFile ?? null]); break; case 'logs': $type = $_GET['type'] ?? 'apache'; $lines = min((int)($_GET['lines'] ?? 50), 200); $logFiles = [ 'apache' => '/var/log/apache2/error.log', 'apache_access' => '/var/log/apache2/access.log', 'syslog' => '/var/log/syslog', 'auth' => '/var/log/auth.log', 'wevads' => '/opt/wevads/logs/app.log', 'postgresql' => '/var/log/postgresql/postgresql-*-main.log' ]; $logFile = $logFiles[$type] ?? $logFiles['apache']; if (strpos($logFile, '*') !== false) { $files = glob($logFile); $logFile = end($files) ?: $logFile; } $content = ''; if (file_exists($logFile)) { $content = shell_exec("tail -n $lines " . escapeshellarg($logFile) . " 2>/dev/null"); } echo json_encode(['success' => true, 'type' => $type, 'file' => $logFile, 'content' => $content]); break; case 'search': $query = $_GET['query'] ?? ''; $path = $_GET['path'] ?? '/opt/wevads'; $type = $_GET['type'] ?? 'content'; // content, filename if (empty($query)) { echo json_encode(['success' => false, 'error' => 'No query']); exit; } $results = []; if ($type === 'filename') { $cmd = "find " . escapeshellarg($path) . " -name " . escapeshellarg("*$query*") . " -type f 2>/dev/null | head -50"; } else { $cmd = "grep -rl " . escapeshellarg($query) . " " . escapeshellarg($path) . " --include='*.php' --include='*.js' --include='*.html' 2>/dev/null | head -30"; } $output = shell_exec($cmd); $results = array_filter(explode("\n", trim($output))); echo json_encode(['success' => true, 'query' => $query, 'results' => $results, 'count' => count($results)]); break; case 'tree': $path = $_GET['path'] ?? '/opt/wevads'; $depth = min((int)($_GET['depth'] ?? 2), 4); $tree = shell_exec("find " . escapeshellarg($path) . " -maxdepth $depth -type f -o -type d 2>/dev/null | head -100"); echo json_encode(['success' => true, 'path' => $path, 'tree' => $tree]); break; case 'hamid': $message = $_POST['message'] ?? ''; $context = $_POST['context'] ?? ''; $provider = $_POST['provider'] ?? 'cerebras'; if (empty($message)) { echo json_encode(['success' => false, 'error' => 'No message']); exit; } // Appeler l'API WEVAL MIND $ch = curl_init('http://localhost/api/widget-api.php'); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => http_build_query(['message' => $message . ($context ? "\n\nContexte:\n$context" : ''), 'provider' => $provider]), CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 120 ]); $response = curl_exec($ch); curl_close($ch); $data = json_decode($response, true); echo json_encode($data ?: ['success' => false, 'error' => 'API error']); break; default: echo json_encode(['success' => false, 'error' => 'Unknown action: ' . $action]); }