false, 'message' => __('Access denied', 'siem-wazuh')]); exit; } // Vérification CSRF pour les requêtes POST if ($_SERVER['REQUEST_METHOD'] === 'POST' && !Session::validateCSRF($_POST)) { echo json_encode(['success' => false, 'message' => __('Invalid CSRF token', 'siem-wazuh')]); exit; } $response = ['success' => false, 'message' => '', 'stats' => []]; try { $action = $_POST['action'] ?? $_GET['action'] ?? 'sync'; switch ($action) { case 'sync': $server_id = intval($_POST['server_id'] ?? $_GET['server_id'] ?? 0); if ($server_id > 0) { // Synchronisation d'un serveur spécifique $result = syncSingleServer($server_id); } else { // Synchronisation de tous les serveurs actifs $result = syncAllServers(); } $response = $result; break; case 'sync_for_item': // Synchronisation pour un élément spécifique $item_id = intval($_POST['item_id'] ?? 0); $item_type = $_POST['item_type'] ?? ''; if ($item_id > 0 && !empty($item_type)) { $result = syncForItem($item_id, $item_type); $response = $result; } else { throw new Exception(__('Invalid item parameters', 'siem-wazuh')); } break; case 'status': // Statut de la synchronisation $response = getSyncStatus(); break; default: throw new Exception(__('Unknown action', 'siem-wazuh')); } } catch (Exception $e) { $response = [ 'success' => false, 'message' => $e->getMessage(), 'error_type' => 'exception' ]; } echo json_encode($response, JSON_UNESCAPED_UNICODE); /** * Synchroniser un serveur spécifique */ function syncSingleServer($server_id) { $server = new PluginSiemWazuhServer(); if (!$server->getFromDB($server_id)) { throw new Exception(__('Server not found', 'siem-wazuh')); } $start_time = microtime(true); $result = $server->syncAlerts(); $sync_time = round((microtime(true) - $start_time) * 1000, 2); if ($result['success']) { // Extraire le nombre d'alertes du message $processed = 0; if (preg_match('/(\d+)/', $result['message'], $matches)) { $processed = intval($matches[1]); } Event::log( $server_id, "PluginSiemWazuhServer", 5, "sync", sprintf(__('Manual sync completed for server %s: %s'), $server->fields['name'], $result['message']) ); return [ 'success' => true, 'message' => $result['message'], 'stats' => [ 'processed' => $processed, 'sync_time' => $sync_time, 'server_name' => $server->fields['name'] ] ]; } else { Event::log( $server_id, "PluginSiemWazuhServer", 2, "sync", sprintf(__('Manual sync failed for server %s: %s'), $server->fields['name'], $result['message']) ); return [ 'success' => false, 'message' => $result['message'], 'server_name' => $server->fields['name'] ]; } } /** * Synchroniser tous les serveurs actifs */ function syncAllServers() { global $DB; $iterator = $DB->request([ 'FROM' => 'glpi_plugin_siem_wazuh_servers', 'WHERE' => ['is_active' => 1] ]); $total_processed = 0; $successful_servers = 0; $failed_servers = 0; $sync_results = []; $start_time = microtime(true); foreach ($iterator as $server_data) { try { $result = syncSingleServer($server_data['id']); if ($result['success']) { $successful_servers++; $total_processed += $result['stats']['processed'] ?? 0; $sync_results[] = [ 'server' => $server_data['name'], 'status' => 'success', 'processed' => $result['stats']['processed'] ?? 0 ]; } else { $failed_servers++; $sync_results[] = [ 'server' => $server_data['name'], 'status' => 'failed', 'error' => $result['message'] ]; } } catch (Exception $e) { $failed_servers++; $sync_results[] = [ 'server' => $server_data['name'], 'status' => 'error', 'error' => $e->getMessage() ]; } } $total_time = round((microtime(true) - $start_time) * 1000, 2); $message = sprintf( __('Sync completed: %d servers processed, %d successful, %d failed, %d total alerts processed'), count($sync_results), $successful_servers, $failed_servers, $total_processed ); return [ 'success' => $failed_servers == 0, 'message' => $message, 'stats' => [ 'total_servers' => count($sync_results), 'successful_servers' => $successful_servers, 'failed_servers' => $failed_servers, 'total_processed' => $total_processed, 'sync_time' => $total_time ], 'details' => $sync_results ]; } /** * Synchroniser pour un élément spécifique */ function syncForItem($item_id, $item_type) { // Cette fonction recherche et synchronise les alertes // pour un élément spécifique (ordinateur, équipement réseau, etc.) $valid_types = ['Computer', 'NetworkEquipment', 'Peripheral', 'Phone', 'Printer']; if (!in_array($item_type, $valid_types)) { throw new Exception(__('Invalid item type', 'siem-wazuh')); } $item = new $item_type(); if (!$item->getFromDB($item_id)) { throw new Exception(__('Item not found', 'siem-wazuh')); } // Récupérer les informations de l'élément pour le matching $search_criteria = []; // Recherche par nom if (!empty($item->fields['name'])) { $search_criteria['hostname'] = $item->fields['name']; } // Recherche par IP (si disponible) $ip_addresses = []; if (method_exists($item, 'getNetworkInterfaces')) { // Logique pour récupérer les adresses IP de l'élément // Cette partie nécessiterait une implémentation plus détaillée } // Synchroniser avec tous les serveurs actifs en filtrant par critères global $DB; $iterator = $DB->request([ 'FROM' => 'glpi_plugin_siem_wazuh_servers', 'WHERE' => ['is_active' => 1] ]); $total_found = 0; foreach ($iterator as $server_data) { $server = new PluginSiemWazuhServer(); $server->fields = $server_data; $api = new PluginSiemWazuhAPI($server); // Construire les paramètres de recherche pour l'API $search_params = []; if (!empty($search_criteria['hostname'])) { $search_params['agent.name'] = $search_criteria['hostname']; } try { $result = $api->getAlerts($search_params); if ($result['success'] && isset($result['data']['data'])) { $alert = new PluginSiemWazuhAlert(); $processed = $alert->processAlerts($server_data['id'], $result['data']['data']); $total_found += $processed; } } catch (Exception $e) { // Log l'erreur mais continue avec les autres serveurs error_log("SIEM-Wazuh: Error syncing for item $item_type:$item_id on server {$server_data['name']}: " . $e->getMessage()); } } return [ 'success' => true, 'message' => sprintf(__('%d alerts found and processed for %s'), $total_found, $item->getName()), 'stats' => [ 'processed' => $total_found, 'item_name' => $item->getName(), 'item_type' => $item_type ] ]; } /** * Obtenir le statut de synchronisation */ function getSyncStatus() { global $DB; // Statistiques générales $stats = []; // Nombre total de serveurs $stats['total_servers'] = countElementsInTable('glpi_plugin_siem_wazuh_servers'); $stats['active_servers'] = countElementsInTable('glpi_plugin_siem_wazuh_servers', ['is_active' => 1]); // Dernière synchronisation $last_sync = $DB->request([ 'SELECT' => ['MAX' => 'last_sync AS last_sync'], 'FROM' => 'glpi_plugin_siem_wazuh_servers', 'WHERE' => ['is_active' => 1] ])->current(); $stats['last_sync'] = $last_sync['last_sync']; // Alertes par statut $alert_stats = []; $statuses = ['new', 'processed', 'ignored', 'ticket_created']; foreach ($statuses as $status) { $alert_stats[$status] = countElementsInTable('glpi_plugin_siem_wazuh_alerts', ['status' => $status]); } $stats['alerts'] = $alert_stats; // Alertes par sévérité $severity_stats = []; $severities = ['low', 'medium', 'high', 'critical']; foreach ($severities as $severity) { $severity_stats[$severity] = countElementsInTable('glpi_plugin_siem_wazuh_alerts', ['severity' => $severity]); } $stats['severity'] = $severity_stats; // Alertes des dernières 24h $stats['alerts_24h'] = countElementsInTable( 'glpi_plugin_siem_wazuh_alerts', ['date_creation' => ['>=', date('Y-m-d H:i:s', strtotime('-24 hours'))]] ); // Tickets créés aujourd'hui $stats['tickets_today'] = countElementsInTable( 'glpi_plugin_siem_wazuh_alerts', [ 'status' => 'ticket_created', 'date_mod' => ['>=', date('Y-m-d 00:00:00')] ] ); // Vérifier s'il y a une synchronisation en cours $config = new PluginSiemWazuhConfig(); $sync_in_progress = $config->getConfiguration('sync_in_progress', 0); return [ 'success' => true, 'message' => __('Status retrieved successfully', 'siem-wazuh'), 'stats' => $stats, 'sync_in_progress' => (bool)$sync_in_progress, 'timestamp' => date('Y-m-d H:i:s') ]; }