Files
GLPI-Plugin-CVE-Prototype/setup.php

403 lines
12 KiB
PHP

<?php
/**
* GLPI CVE Plugin - Main setup file
* Handles plugin initialization, installation, and hooks
*/
define('PLUGIN_CVE_VERSION', '0.0.1');
define('PLUGIN_CVE_MIN_GLPI', '10.0.0');
define('PLUGIN_CVE_MAX_GLPI', '10.99.99');
define('PLUGIN_CVE_DIR', __DIR__);
// Load plugin language definition
include_once(PLUGIN_CVE_DIR . '/inc/define.php');
/**
* Plugin initialization
*
* @return boolean
*/
function plugin_init_cve() {
global $PLUGIN_HOOKS;
$PLUGIN_HOOKS['csrf_compliant']['cve'] = true;
// Add CSS and JS files
$PLUGIN_HOOKS['add_css']['cve'] = ['css/cve.css'];
$PLUGIN_HOOKS['add_javascript']['cve'] = ['js/cve.js'];
// Register classes for itemtype
Plugin::registerClass('PluginCveCve');
Plugin::registerClass('PluginCveCveSource');
Plugin::registerClass('PluginCveCveRule');
Plugin::registerClass('PluginCveCveTicket');
Plugin::registerClass('PluginCveCveInventory');
Plugin::registerClass('PluginCveCveAlert');
// Initialize localization
$PLUGIN_HOOKS['init_session']['cve'] = 'plugin_cve_load_language';
$PLUGIN_HOOKS['change_profile']['cve'] = 'plugin_cve_load_language';
// Add in objects
$PLUGIN_HOOKS['item_get_events']['cve'] = ['NotificationTargetTicket' =>
['PluginCveCveTicket', 'addEvents']];
// Add in database synchronization
$PLUGIN_HOOKS['plugin_datainjection_populate']['cve'] = ['PluginCveCve' =>
'plugin_datainjection_populate_cve'];
// Menu entry - Add to "Tools" menu only
$PLUGIN_HOOKS['menu_toadd']['cve'] = [
'tools' => 'PluginCveCveMenu'
];
// Dashboard widgets
$PLUGIN_HOOKS['dashboard_cards']['cve'] = 'plugin_cve_dashboard_cards';
// Cron tasks registration
CronTask::register('PluginCveCveSource', 'SyncCVESources', 6 * HOUR_TIMESTAMP,
['mode' => CronTask::MODE_EXTERNAL]);
CronTask::register('PluginCveCve', 'CleanOldCVEs', 7 * DAY_TIMESTAMP,
['mode' => CronTask::MODE_EXTERNAL]);
CronTask::register('PluginCveCveInventory', 'AnalyzeInventory', 12 * HOUR_TIMESTAMP,
['mode' => CronTask::MODE_EXTERNAL]);
// Item events (hooks)
$PLUGIN_HOOKS['item_add']['cve'] = ['Ticket' => 'plugin_cve_item_add_ticket'];
$PLUGIN_HOOKS['item_update']['cve'] = ['Ticket' => 'plugin_cve_item_update_ticket'];
$PLUGIN_HOOKS['pre_item_purge']['cve'] = ['Ticket' => 'plugin_cve_pre_item_purge_ticket'];
// Software inventory hook
$PLUGIN_HOOKS['item_add']['cve']['Software'] = 'plugin_cve_item_add_software';
$PLUGIN_HOOKS['item_add']['cve']['SoftwareVersion'] = 'plugin_cve_item_add_softwareversion';
return true;
}
/**
* Handler for software addition
*
* @param Software $software Software that was added
*/
function plugin_cve_item_add_software(Software $software) {
// Schedule a vulnerability analysis when new software is added
$task = new CronTask();
if ($task->getFromDBbyName('PluginCveCveInventory', 'AnalyzeInventory')) {
$task->update([
'id' => $task->fields['id'],
'state' => CronTask::STATE_WAITING
]);
}
}
/**
* Handler for software version addition
*
* @param SoftwareVersion $version Software version that was added
*/
function plugin_cve_item_add_softwareversion(SoftwareVersion $version) {
// Schedule a vulnerability analysis when new software version is added
$task = new CronTask();
if ($task->getFromDBbyName('PluginCveCveInventory', 'AnalyzeInventory')) {
$task->update([
'id' => $task->fields['id'],
'state' => CronTask::STATE_WAITING
]);
}
}
/**
* Plugin version information
*
* @return array Plugin version info
*/
function plugin_version_cve() {
return [
'name' => __('Vulnérabilité', 'cve'),
'version' => PLUGIN_CVE_VERSION,
'author' => 'Tips-Of-Mine',
'license' => 'GPL v3+',
'homepage' => 'https://github.com/tips-of-mine/GLPI-Plugin-CVE-Prototype',
'requirements' => [
'glpi' => [
'min' => PLUGIN_CVE_MIN_GLPI,
'max' => PLUGIN_CVE_MAX_GLPI,
'dev' => false
],
'php' => [
'min' => '7.4',
'max' => '8.2',
'required' => true
]
]
];
}
/**
* Plugin initialization check
*
* @return boolean
*/
function plugin_cve_check_prerequisites() {
// Check GLPI version
if (version_compare(GLPI_VERSION, PLUGIN_CVE_MIN_GLPI, 'lt') ||
version_compare(GLPI_VERSION, PLUGIN_CVE_MAX_GLPI, 'gt')) {
echo "This plugin requires GLPI >= " . PLUGIN_CVE_MIN_GLPI . " and GLPI <= " . PLUGIN_CVE_MAX_GLPI;
return false;
}
// Check curl extension
if (!extension_loaded('curl')) {
echo "This plugin requires the PHP cURL extension";
return false;
}
return true;
}
/**
* Plugin check config
*
* @return boolean
*/
function plugin_cve_check_config() {
return true;
}
/**
* Plugin installation process
*
* @return boolean
*/
function plugin_cve_install() {
global $DB;
$migration = new Migration(PLUGIN_CVE_VERSION);
// Install core tables
PluginCveCve::install($migration);
PluginCveCveSource::install($migration);
PluginCveCveRule::install($migration);
PluginCveCveTicket::install($migration);
PluginCveCveInventory::install($migration);
PluginCveCveAlert::install($migration);
// Create default notification templates
// This would be implemented here...
$migration->executeMigration();
// Schedule the initial CVE data download as a background task
$task = new CronTask();
// Check if the synchronization task is already registered
$taskId = $task->find(['itemtype' => 'PluginCveCveSource', 'name' => 'SyncCVESources']);
if (count($taskId) == 0) {
// Register the task if it doesn't exist
$taskId = $task->add([
'itemtype' => 'PluginCveCveSource',
'name' => 'SyncCVESources',
'frequency' => 6 * HOUR_TIMESTAMP,
'param' => null,
'state' => CronTask::STATE_WAITING,
'mode' => CronTask::MODE_EXTERNAL,
'allowmode' => CronTask::MODE_EXTERNAL,
'hourmin' => 0,
'hourmax' => 24,
'logs_lifetime' => 30,
'date_creation' => $_SESSION['glpi_currenttime'],
'comment' => 'Synchronize CVE data from external sources'
]);
} else {
$taskData = array_shift($taskId);
$taskId = $taskData['id'];
}
// Register the inventory analysis task
$inventoryTaskId = $task->find(['itemtype' => 'PluginCveCveInventory', 'name' => 'AnalyzeInventory']);
if (count($inventoryTaskId) == 0) {
// Register the task if it doesn't exist
$inventoryTaskId = $task->add([
'itemtype' => 'PluginCveCveInventory',
'name' => 'AnalyzeInventory',
'frequency' => 12 * HOUR_TIMESTAMP,
'param' => null,
'state' => CronTask::STATE_WAITING,
'mode' => CronTask::MODE_EXTERNAL,
'allowmode' => CronTask::MODE_EXTERNAL,
'hourmin' => 0,
'hourmax' => 24,
'logs_lifetime' => 30,
'date_creation' => $_SESSION['glpi_currenttime'],
'comment' => 'Analyze software inventory for vulnerabilities'
]);
} else {
$taskData = array_shift($inventoryTaskId);
$inventoryTaskId = $taskData['id'];
}
// Force run the task immediately to download initial CVE data
if ($taskId > 0) {
// Log the action
Toolbox::logInFile('cve_plugin', 'Initial CVE data synchronization scheduled');
// Queue the task for immediate execution
$task->getFromDB($taskId);
$task->update([
'id' => $taskId,
'state' => CronTask::STATE_WAITING
]);
// Start background sync process via AJAX or CLI
$syncUrl = Plugin::getWebDir('cve') . '/ajax/sync_now.php';
// Use asynchronous curl request to start the sync process
plugin_cve_async_request($syncUrl);
}
// Schedule initial software inventory analysis
if ($inventoryTaskId > 0) {
// Log the action
Toolbox::logInFile('cve_plugin', 'Initial software vulnerability analysis scheduled');
// Queue the task for immediate execution after CVE data is synchronized
$task->getFromDB($inventoryTaskId);
$task->update([
'id' => $inventoryTaskId,
'state' => CronTask::STATE_WAITING
]);
}
return true;
}
/**
* Make an asynchronous HTTP request
*
* @param string $url URL to request
* @return boolean Success
*/
function plugin_cve_async_request($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
// Add security token to the request
$params = [
'_glpi_csrf_token' => Session::getNewCSRFToken()
];
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
curl_exec($ch);
curl_close($ch);
return true;
}
/**
* Plugin uninstallation process
*
* @return boolean
*/
function plugin_cve_uninstall() {
global $DB;
$migration = new Migration(PLUGIN_CVE_VERSION);
// Remove cron tasks
$crontask = new CronTask();
$crontask->deleteByCriteria(['itemtype' => 'PluginCveCveSource', 'name' => 'SyncCVESources']);
$crontask->deleteByCriteria(['itemtype' => 'PluginCveCve', 'name' => 'CleanOldCVEs']);
$crontask->deleteByCriteria(['itemtype' => 'PluginCveCveInventory', 'name' => 'AnalyzeInventory']);
// Uninstall core tables
PluginCveCve::uninstall($migration);
PluginCveCveSource::uninstall($migration);
PluginCveCveRule::uninstall($migration);
PluginCveCveTicket::uninstall($migration);
PluginCveCveInventory::uninstall($migration);
PluginCveCveAlert::uninstall($migration);
// Remove user preferences
$query = "DELETE FROM `glpi_configs` WHERE `context` = 'plugin:cve'";
$DB->query($query);
$migration->executeMigration();
return true;
}
/**
* Define dropdown relations
*
* @return array
*/
function plugin_cve_getDatabaseRelations() {
$plugin = new Plugin();
if ($plugin->isActivated('cve')) {
return [
"glpi_entities" => [
"glpi_plugin_cve_cves" => "entities_id",
"glpi_plugin_cve_alerts" => "entities_id"
],
"glpi_tickets" => [
"glpi_plugin_cve_tickets" => "tickets_id",
"glpi_plugin_cve_alerts" => "tickets_id"
],
"glpi_softwares" => [
"glpi_plugin_cve_alerts" => "softwares_id"
],
"glpi_softwareversions" => [
"glpi_plugin_cve_alerts" => "softwareversions_id"
]
];
}
return [];
}
/**
* Define database table relations
*
* @return array
*/
function plugin_cve_getTablesNames() {
$plugin = new Plugin();
$tables = [];
if ($plugin->isActivated('cve')) {
$tables = [
'glpi_plugin_cve_cves',
'glpi_plugin_cve_sources',
'glpi_plugin_cve_rules',
'glpi_plugin_cve_tickets',
'glpi_plugin_cve_alerts'
];
}
return $tables;
}
/**
* Display a nice message when activated
*/
function plugin_cve_postinit() {
global $PLUGIN_HOOKS;
// Add nice message when activated for the first time
if (isset($_GET['activate']) && $_GET['activate'] === 'cve') {
Html::displayTitle(__('Plugin activated successfully!', 'cve'),
__('CVE Management plugin has been activated.', 'cve') . '<br>' .
__('Initial CVE data is being synchronized in the background.', 'cve') . '<br>' .
__('Software inventory will be analyzed for vulnerabilities automatically.', 'cve') . '<br>' .
__('You can now configure the data sources and rules.', 'cve'));
}
}