first sync
This commit is contained in:
411
inc/wazuhserver.class.php
Normal file
411
inc/wazuhserver.class.php
Normal file
@@ -0,0 +1,411 @@
|
||||
<?php
|
||||
/*
|
||||
* Plugin SIEM-Wazuh pour GLPI
|
||||
* Classe de gestion des serveurs Wazuh
|
||||
*/
|
||||
|
||||
if (!defined('GLPI_ROOT')) {
|
||||
die("Sorry. You can't access this file directly");
|
||||
}
|
||||
|
||||
class PluginSiemWazuhServer extends CommonDBTM {
|
||||
|
||||
public $dohistory = true;
|
||||
|
||||
static protected $forward_entity_to = ['PluginSiemWazuhAlert'];
|
||||
|
||||
static $rightname = 'plugin_siem_wazuh_server';
|
||||
|
||||
const MATRIX_FIELD = '';
|
||||
const SEARCHOPTIONS_INHERITANCE = true;
|
||||
|
||||
/**
|
||||
* Return the localized name of the current Type
|
||||
*/
|
||||
static function getTypeName($nb = 0) {
|
||||
return _n('Wazuh Server', 'Wazuh Servers', $nb, 'siem-wazuh');
|
||||
}
|
||||
|
||||
/**
|
||||
* Define tab name
|
||||
*/
|
||||
function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) {
|
||||
if (!$withtemplate) {
|
||||
$nb = 0;
|
||||
switch ($item->getType()) {
|
||||
case 'PluginSiemWazuhServer':
|
||||
if ($_SESSION['glpishow_count_on_tabs']) {
|
||||
$nb = countElementsInTable('glpi_plugin_siem_wazuh_alerts',
|
||||
"`wazuh_server_id` = '".$item->getID()."'");
|
||||
}
|
||||
return self::createTabEntry(__('Alerts', 'siem-wazuh'), $nb);
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Display tab content
|
||||
*/
|
||||
static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) {
|
||||
if ($item->getType() == 'PluginSiemWazuhServer') {
|
||||
PluginSiemWazuhAlert::showForServer($item->getID());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define search options
|
||||
*/
|
||||
function rawSearchOptions() {
|
||||
$tab = [];
|
||||
|
||||
$tab[] = [
|
||||
'id' => 'common',
|
||||
'name' => __('Characteristics')
|
||||
];
|
||||
|
||||
$tab[] = [
|
||||
'id' => '1',
|
||||
'table' => $this->getTable(),
|
||||
'field' => 'name',
|
||||
'name' => __('Name'),
|
||||
'datatype' => 'itemlink',
|
||||
'massiveaction' => false
|
||||
];
|
||||
|
||||
$tab[] = [
|
||||
'id' => '2',
|
||||
'table' => $this->getTable(),
|
||||
'field' => 'wazuh_url',
|
||||
'name' => __('Wazuh URL', 'siem-wazuh'),
|
||||
'datatype' => 'string',
|
||||
'massiveaction' => false
|
||||
];
|
||||
|
||||
$tab[] = [
|
||||
'id' => '3',
|
||||
'table' => $this->getTable(),
|
||||
'field' => 'wazuh_port',
|
||||
'name' => __('Wazuh Port', 'siem-wazuh'),
|
||||
'datatype' => 'integer',
|
||||
'massiveaction' => false
|
||||
];
|
||||
|
||||
$tab[] = [
|
||||
'id' => '4',
|
||||
'table' => $this->getTable(),
|
||||
'field' => 'is_active',
|
||||
'name' => __('Active'),
|
||||
'datatype' => 'bool',
|
||||
'massiveaction' => true
|
||||
];
|
||||
|
||||
$tab[] = [
|
||||
'id' => '5',
|
||||
'table' => $this->getTable(),
|
||||
'field' => 'sync_interval',
|
||||
'name' => __('Sync Interval (seconds)', 'siem-wazuh'),
|
||||
'datatype' => 'integer',
|
||||
'massiveaction' => false
|
||||
];
|
||||
|
||||
$tab[] = [
|
||||
'id' => '6',
|
||||
'table' => $this->getTable(),
|
||||
'field' => 'last_sync',
|
||||
'name' => __('Last Sync', 'siem-wazuh'),
|
||||
'datatype' => 'datetime',
|
||||
'massiveaction' => false
|
||||
];
|
||||
|
||||
$tab[] = [
|
||||
'id' => '7',
|
||||
'table' => 'glpi_itilcategories',
|
||||
'field' => 'name',
|
||||
'name' => __('Default Ticket Category', 'siem-wazuh'),
|
||||
'datatype' => 'dropdown',
|
||||
'massiveaction' => false,
|
||||
'linkfield' => 'ticket_category'
|
||||
];
|
||||
|
||||
$tab[] = [
|
||||
'id' => '30',
|
||||
'table' => $this->getTable(),
|
||||
'field' => 'date_creation',
|
||||
'name' => __('Creation date'),
|
||||
'datatype' => 'datetime',
|
||||
'massiveaction' => false
|
||||
];
|
||||
|
||||
$tab[] = [
|
||||
'id' => '31',
|
||||
'table' => $this->getTable(),
|
||||
'field' => 'date_mod',
|
||||
'name' => __('Last update'),
|
||||
'datatype' => 'datetime',
|
||||
'massiveaction' => false
|
||||
];
|
||||
|
||||
return $tab;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display form
|
||||
*/
|
||||
function showForm($ID, $options = []) {
|
||||
$this->initForm($ID, $options);
|
||||
$this->showFormHeader($options);
|
||||
|
||||
echo "<tr class='tab_bg_1'>";
|
||||
echo "<td>".__('Name')."</td>";
|
||||
echo "<td>";
|
||||
Html::autocompletionTextField($this, "name", ['size' => 50]);
|
||||
echo "</td>";
|
||||
echo "<td>".__('Active')."</td>";
|
||||
echo "<td>";
|
||||
Dropdown::showYesNo("is_active", $this->fields["is_active"]);
|
||||
echo "</td>";
|
||||
echo "</tr>";
|
||||
|
||||
echo "<tr class='tab_bg_1'>";
|
||||
echo "<td>".__('Wazuh Server URL', 'siem-wazuh')."</td>";
|
||||
echo "<td>";
|
||||
Html::autocompletionTextField($this, "wazuh_url", ['size' => 50, 'placeholder' => 'https://wazuh-server.domain.com']);
|
||||
echo "</td>";
|
||||
echo "<td>".__('Wazuh API Port', 'siem-wazuh')."</td>";
|
||||
echo "<td>";
|
||||
Html::autocompletionTextField($this, "wazuh_port", ['size' => 10, 'value' => ($this->fields["wazuh_port"] ?: 55000)]);
|
||||
echo "</td>";
|
||||
echo "</tr>";
|
||||
|
||||
echo "<tr class='tab_bg_1'>";
|
||||
echo "<td>".__('Wazuh API Login', 'siem-wazuh')."</td>";
|
||||
echo "<td>";
|
||||
Html::autocompletionTextField($this, "wazuh_login", ['size' => 30]);
|
||||
echo "</td>";
|
||||
echo "<td>".__('Wazuh API Password', 'siem-wazuh')."</td>";
|
||||
echo "<td>";
|
||||
echo "<input type='password' name='wazuh_password' value='' size='30' autocomplete='new-password'>";
|
||||
if (!empty($this->fields["wazuh_password"])) {
|
||||
echo "<br><small>".__('Leave empty to keep current password', 'siem-wazuh')."</small>";
|
||||
}
|
||||
echo "</td>";
|
||||
echo "</tr>";
|
||||
|
||||
echo "<tr class='tab_bg_1'>";
|
||||
echo "<td>".__('Indexer Server URL', 'siem-wazuh')."</td>";
|
||||
echo "<td>";
|
||||
Html::autocompletionTextField($this, "indexer_url", ['size' => 50, 'placeholder' => 'https://wazuh-indexer.domain.com']);
|
||||
echo "</td>";
|
||||
echo "<td>".__('Indexer API Port', 'siem-wazuh')."</td>";
|
||||
echo "<td>";
|
||||
Html::autocompletionTextField($this, "indexer_port", ['size' => 10, 'value' => ($this->fields["indexer_port"] ?: 9200)]);
|
||||
echo "</td>";
|
||||
echo "</tr>";
|
||||
|
||||
echo "<tr class='tab_bg_1'>";
|
||||
echo "<td>".__('Indexer API Login', 'siem-wazuh')."</td>";
|
||||
echo "<td>";
|
||||
Html::autocompletionTextField($this, "indexer_login", ['size' => 30]);
|
||||
echo "</td>";
|
||||
echo "<td>".__('Indexer API Password', 'siem-wazuh')."</td>";
|
||||
echo "<td>";
|
||||
echo "<input type='password' name='indexer_password' value='' size='30' autocomplete='new-password'>";
|
||||
if (!empty($this->fields["indexer_password"])) {
|
||||
echo "<br><small>".__('Leave empty to keep current password', 'siem-wazuh')."</small>";
|
||||
}
|
||||
echo "</td>";
|
||||
echo "</tr>";
|
||||
|
||||
echo "<tr class='tab_bg_1'>";
|
||||
echo "<td>".__('Sync Interval (seconds)', 'siem-wazuh')."</td>";
|
||||
echo "<td>";
|
||||
Html::autocompletionTextField($this, "sync_interval", ['size' => 10, 'value' => ($this->fields["sync_interval"] ?: 300)]);
|
||||
echo "</td>";
|
||||
echo "<td>".__('Default Ticket Type', 'siem-wazuh')."</td>";
|
||||
echo "<td>";
|
||||
Ticket::dropdownType('ticket_type', $this->fields["ticket_type"]);
|
||||
echo "</td>";
|
||||
echo "</tr>";
|
||||
|
||||
echo "<tr class='tab_bg_1'>";
|
||||
echo "<td>".__('Default Ticket Category', 'siem-wazuh')."</td>";
|
||||
echo "<td>";
|
||||
ITILCategory::dropdown(['name' => 'ticket_category', 'value' => $this->fields["ticket_category"]]);
|
||||
echo "</td>";
|
||||
echo "<td>".__('Last Sync', 'siem-wazuh')."</td>";
|
||||
echo "<td>";
|
||||
echo ($this->fields["last_sync"] ? Html::convDateTime($this->fields["last_sync"]) : __('Never'));
|
||||
echo "</td>";
|
||||
echo "</tr>";
|
||||
|
||||
// Bouton de test de connexion
|
||||
if ($ID > 0) {
|
||||
echo "<tr class='tab_bg_1'>";
|
||||
echo "<td colspan='4' class='center'>";
|
||||
echo "<button type='button' class='btn btn-primary' onclick='testWazuhConnection($ID)'>";
|
||||
echo __('Test Connection', 'siem-wazuh');
|
||||
echo "</button>";
|
||||
echo "<div id='test-result-$ID' class='mt-2'></div>";
|
||||
echo "</td>";
|
||||
echo "</tr>";
|
||||
}
|
||||
|
||||
$this->showFormButtons($options);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare input for add
|
||||
*/
|
||||
function prepareInputForAdd($input) {
|
||||
if (!empty($input['wazuh_password'])) {
|
||||
$input['wazuh_password'] = Toolbox::encrypt($input['wazuh_password'], GLPIKEY);
|
||||
}
|
||||
if (!empty($input['indexer_password'])) {
|
||||
$input['indexer_password'] = Toolbox::encrypt($input['indexer_password'], GLPIKEY);
|
||||
}
|
||||
return $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare input for update
|
||||
*/
|
||||
function prepareInputForUpdate($input) {
|
||||
if (!empty($input['wazuh_password'])) {
|
||||
$input['wazuh_password'] = Toolbox::encrypt($input['wazuh_password'], GLPIKEY);
|
||||
} else {
|
||||
unset($input['wazuh_password']);
|
||||
}
|
||||
|
||||
if (!empty($input['indexer_password'])) {
|
||||
$input['indexer_password'] = Toolbox::encrypt($input['indexer_password'], GLPIKEY);
|
||||
} else {
|
||||
unset($input['indexer_password']);
|
||||
}
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get decrypted password
|
||||
*/
|
||||
function getPassword($field = 'wazuh_password') {
|
||||
if (!empty($this->fields[$field])) {
|
||||
return Toolbox::decrypt($this->fields[$field], GLPIKEY);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Test connection to Wazuh server
|
||||
*/
|
||||
function testConnection() {
|
||||
if (empty($this->fields['wazuh_url']) || empty($this->fields['wazuh_login'])) {
|
||||
return ['success' => false, 'message' => __('Missing connection parameters', 'siem-wazuh')];
|
||||
}
|
||||
|
||||
$api = new PluginSiemWazuhAPI($this);
|
||||
return $api->testConnection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronize alerts from this server
|
||||
*/
|
||||
function syncAlerts() {
|
||||
if (!$this->fields['is_active']) {
|
||||
return ['success' => false, 'message' => __('Server is not active', 'siem-wazuh')];
|
||||
}
|
||||
|
||||
$api = new PluginSiemWazuhAPI($this);
|
||||
$result = $api->getAlerts();
|
||||
|
||||
if ($result['success']) {
|
||||
$alert = new PluginSiemWazuhAlert();
|
||||
$processed = $alert->processAlerts($this->getID(), $result['data']);
|
||||
|
||||
// Mise à jour de la dernière synchronisation
|
||||
$this->update([
|
||||
'id' => $this->getID(),
|
||||
'last_sync' => $_SESSION['glpi_currenttime']
|
||||
]);
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
'message' => sprintf(__('%d alerts processed', 'siem-wazuh'), $processed)
|
||||
];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get servers for dropdown
|
||||
*/
|
||||
static function getDropdownValues($post) {
|
||||
global $DB;
|
||||
|
||||
$where = ['is_active' => 1];
|
||||
if (isset($post['searchText']) && !empty($post['searchText'])) {
|
||||
$where[] = ['name' => ['LIKE', '%' . $post['searchText'] . '%']];
|
||||
}
|
||||
|
||||
$iterator = $DB->request([
|
||||
'FROM' => 'glpi_plugin_siem_wazuh_servers',
|
||||
'WHERE' => $where,
|
||||
'ORDER' => 'name'
|
||||
]);
|
||||
|
||||
$values = [];
|
||||
foreach ($iterator as $row) {
|
||||
$values[] = [
|
||||
'id' => $row['id'],
|
||||
'text' => $row['name']
|
||||
];
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get menu content
|
||||
*/
|
||||
static function getMenuContent() {
|
||||
$menu = [];
|
||||
if (Session::haveRight(static::$rightname, READ)) {
|
||||
$menu['title'] = self::getMenuName();
|
||||
$menu['page'] = "/plugins/siem-wazuh/front/wazuhserver.php";
|
||||
$menu['links']['search'] = "/plugins/siem-wazuh/front/wazuhserver.php";
|
||||
if (Session::haveRight(static::$rightname, CREATE)) {
|
||||
$menu['links']['add'] = "/plugins/siem-wazuh/front/wazuhserver.form.php";
|
||||
}
|
||||
}
|
||||
return $menu;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get menu name
|
||||
*/
|
||||
static function getMenuName() {
|
||||
return self::getTypeName(Session::getPluralNumber());
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean database relations
|
||||
*/
|
||||
function cleanDBonPurge() {
|
||||
$this->deleteChildrenAndRelationsFromDb(
|
||||
[
|
||||
PluginSiemWazuhAlert::class
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get used configuration
|
||||
*/
|
||||
static function getUsedConfig() {
|
||||
return ['plugin_siem_wazuh_server'];
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user