diff --git a/pandora_console/extras/mr/66.sql b/pandora_console/extras/mr/66.sql index 4c13c4f51d..606bcea909 100644 --- a/pandora_console/extras/mr/66.sql +++ b/pandora_console/extras/mr/66.sql @@ -14,6 +14,14 @@ CREATE TABLE IF NOT EXISTS `tgraph_analytics_filter` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; +CREATE TABLE IF NOT EXISTS `tconfig_os_version` ( + `id_os_version` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `product` TEXT, + `version` TEXT, + `end_of_support` VARCHAR(10) DEFAULT NULL, + PRIMARY KEY (`id_os_version`) +) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; + ALTER TABLE `tusuario` MODIFY COLUMN `integria_user_level_pass` TEXT; DROP TABLE `tincidencia`; @@ -88,6 +96,10 @@ ADD COLUMN `time_init` VARCHAR(45) NULL AFTER `date_init`, ADD COLUMN `date_end` VARCHAR(45) NULL AFTER `time_init`, ADD COLUMN `time_end` VARCHAR(45) NULL AFTER `date_end`; +INSERT INTO `tconfig_os_version` (`id_os_version`, `product`, `version`, `end_of_support`) VALUES (1,'Windows.*','7.*','2020/01/14'); +INSERT INTO `tconfig_os_version` (`id_os_version`, `product`, `version`, `end_of_support`) VALUES (2,'Cisco.*','IOS 3.4.3','2017/05/12'); +INSERT INTO `tconfig_os_version` (`id_os_version`, `product`, `version`, `end_of_support`) VALUES (3,'Linux.*','Centos 7.*','2022/01/01'); + UPDATE `tdiscovery_apps` SET `version` = '1.1' WHERE `short_name` = 'pandorafms.vmware'; -- Insert new Proxmox APP diff --git a/pandora_console/godmode/agentes/agent_manager.php b/pandora_console/godmode/agentes/agent_manager.php index 70c2b1cf60..54392630fc 100644 --- a/pandora_console/godmode/agentes/agent_manager.php +++ b/pandora_console/godmode/agentes/agent_manager.php @@ -548,6 +548,21 @@ $tableAgent->data['os'][0] .= html_print_div( true ); +$tableAgent->data['caption_os_version'][0] = __('OS version'); +$tableAgent->rowclass['os_version'] = 'w540px'; +$tableAgent->data['os_version'][0] = html_print_input_text( + 'os_version', + $os_version, + '', + 16, + 100, + true, + false, + false, + '', + 'w540px' +); + $tableAgent->data['caption_server'][0] = __('Server'); $tableAgent->rowclass['server'] = 'w540px'; $tableAgent->data['server'][0] = html_print_select( diff --git a/pandora_console/godmode/agentes/configurar_agente.php b/pandora_console/godmode/agentes/configurar_agente.php index 91d911ae24..b78b98f3c7 100644 --- a/pandora_console/godmode/agentes/configurar_agente.php +++ b/pandora_console/godmode/agentes/configurar_agente.php @@ -216,6 +216,7 @@ if ($create_agent) { $id_parent = (int) get_parameter_post('id_agent_parent'); $server_name = (string) get_parameter_post('server_name'); $id_os = (int) get_parameter_post('id_os'); + $os_version = (string) get_parameter_post('os_version'); $disabled = (int) get_parameter_post('disabled'); $custom_id_safe_output = strip_tags(io_safe_output(get_parameter('custom_id', ''))); $custom_id = io_safe_input(trim(preg_replace('/[\/\\\|%#&$]/', '', $custom_id_safe_output))); @@ -284,6 +285,7 @@ if ($create_agent) { 'comentarios' => $comentarios, 'modo' => $modo, 'id_os' => $id_os, + 'os_version' => $os_version, 'disabled' => $disabled, 'cascade_protection' => $cascade_protection, 'cascade_protection_module' => $cascade_protection_module, @@ -982,6 +984,7 @@ if ($update_agent) { $modo = (int) get_parameter_post('modo', 0); // Mode: Learning, Normal or Autodisabled. $id_os = (int) get_parameter_post('id_os'); + $os_version = (string) get_parameter_post('os_version'); $disabled = (bool) get_parameter_post('disabled'); $server_name = (string) get_parameter_post('server_name', ''); $id_parent = (int) get_parameter_post('id_agent_parent'); @@ -1107,6 +1110,7 @@ if ($update_agent) { 'disabled' => $disabled, 'id_parent' => $id_parent, 'id_os' => $id_os, + 'os_version' => $os_version, 'modo' => $modo, 'alias' => $alias, 'alias_as_name' => $alias_as_name, @@ -1268,6 +1272,7 @@ if ($id_agente) { $server_name = $agent['server_name']; $modo = $agent['modo']; $id_os = $agent['id_os']; + $os_version = $agent['os_version']; $disabled = $agent['disabled']; $id_parent = $agent['id_parent']; $custom_id = $agent['custom_id']; diff --git a/pandora_console/godmode/reporting/reporting_builder.item_editor.php b/pandora_console/godmode/reporting/reporting_builder.item_editor.php index 786ad13d0e..291e0a1f01 100755 --- a/pandora_console/godmode/reporting/reporting_builder.item_editor.php +++ b/pandora_console/godmode/reporting/reporting_builder.item_editor.php @@ -880,6 +880,16 @@ switch ($action) { $idAgentModule = $module; break; + case 'end_of_life': + $es = json_decode($item['external_source'], true); + + $text_os_version = $es['os_version']; + $end_of_life_date = $es['end_of_life_date']; + $os_selector = $es['os_selector']; + $group = $es['group']; + $recursion = $es['recursion']; + break; + case 'alert_report_actions': $description = $item['description']; $es = json_decode($item['external_source'], true); @@ -1238,6 +1248,88 @@ $class = 'databox filters'; + + + + + + + + + + + + + + + + + + + + 'end_of_life_date', + 'style' => '', + 'content' => html_print_div( + [ + 'class' => '', + 'content' => html_print_input_text( + 'end_of_life_date', + $end_of_life_date, + '', + 10, + 10, + true + ), + ], + true + ), + ], + true + ); + + echo implode('', $timeInputs); + ?> + + + 'form_action']); echo ''; echo ''; +ui_require_css_file('datepicker'); +ui_require_jquery_file('ui.datepicker-'.get_user_language(), 'include/javascript/i18n/'); ui_include_time_picker(); ui_require_javascript_file('pandora'); @@ -5216,6 +5310,8 @@ $(document).ready (function () { chooseType(); chooseSQLquery(); + $("#text-end_of_life_date").datepicker({dateFormat: "", showButtonPanel: true}); + $("#id_agents").change(agent_changed_by_multiple_agents); // Load selected modules by default @@ -6529,7 +6625,11 @@ function addGeneralRow() { function loadGeneralAgents(agent_group) { var params = []; - var group = ; + var group = ; + if (group < 0) { + return; + } + group = agent_group || group; params.push("get_agents=1"); @@ -6796,6 +6896,9 @@ function chooseType() { $("#row_group_by").hide(); $("#row_type_show").hide(); $("#row_use_prefix_notation").hide(); + $("#row_os_selector").hide(); + $("#row_os_version_regexp").hide(); + $("#row_os_end_of_life").hide(); $("#row_cat_security_hardening").hide(); $("#row_ignore_skipped").hide(); $("#row_status_check").hide(); @@ -7379,6 +7482,13 @@ function chooseType() { }); break; + case 'end_of_life': + $("#row_os_selector").show(); + $("#row_os_version_regexp").show(); + $("#row_group").show(); + $("#row_os_end_of_life").show(); + break; + case 'inventory_changes': $("#row_description").show(); $("#row_period").show(); diff --git a/pandora_console/godmode/reporting/reporting_builder.php b/pandora_console/godmode/reporting/reporting_builder.php index a294a7b939..095f79b14a 100755 --- a/pandora_console/godmode/reporting/reporting_builder.php +++ b/pandora_console/godmode/reporting/reporting_builder.php @@ -1759,6 +1759,17 @@ switch ($action) { $good_format = true; break; + case 'end_of_life': + $es['end_of_life_date'] = get_parameter('end_of_life_date'); + $es['os_selector'] = get_parameter('os_selector'); + $es['os_version'] = get_parameter('text_os_version', ''); + $es['group'] = get_parameter('combo_group', ''); + $es['recursion'] = get_parameter('recursion', 0); + + $values['external_source'] = json_encode($es); + $good_format = true; + break; + case 'alert_report_actions': $alert_templates_to_report = get_parameter('alert_templates'); $alert_actions_to_report = get_parameter('alert_actions'); @@ -2747,6 +2758,17 @@ switch ($action) { $good_format = true; break; + case 'end_of_life': + $es['end_of_life_date'] = get_parameter('end_of_life_date'); + $es['os_selector'] = get_parameter('os_selector'); + $es['os_version'] = get_parameter('text_os_version', ''); + $es['group'] = get_parameter('combo_group', ''); + $es['recursion'] = get_parameter('recursion', 0); + + $values['external_source'] = json_encode($es); + $good_format = true; + break; + case 'alert_report_actions': $alert_templates_to_report = get_parameter('alert_templates'); $alert_actions_to_report = get_parameter('alert_actions'); diff --git a/pandora_console/godmode/setup/os.builder.php b/pandora_console/godmode/setup/os.builder.php index afe3982d8c..d8a2f47d00 100644 --- a/pandora_console/godmode/setup/os.builder.php +++ b/pandora_console/godmode/setup/os.builder.php @@ -40,6 +40,191 @@ if (! check_acl($config['id_user'], 0, 'PM') && ! is_user_admin($config['id_user return; } +if ($idOS > 0) { + $os = db_get_row_filter('tconfig_os', ['id_os' => $idOS]); + $name = $os['name']; + $description = $os['description']; + $icon = $os['icon_name']; +} else { + $name = io_safe_input(strip_tags(io_safe_output((string) get_parameter('name')))); + $description = io_safe_input(strip_tags(io_safe_output((string) get_parameter('description')))); + $icon = get_parameter('icon', 0); +} + +$icon_upload = get_parameter('icon_upload', null); + +$message = ''; +if ($is_management_allowed === true) { + switch ($action) { + case 'edit': + if ($idOS > 0) { + $actionHidden = 'update'; + $textButton = __('Update'); + $classButton = ['icon' => 'wand']; + } else { + $actionHidden = 'save'; + $textButton = __('Create'); + $classButton = ['icon' => 'next']; + } + break; + + case 'save': + if ($icon_upload !== null && $icon_upload['name'] !== '') { + if (isset($_FILES['icon_upload']) === true) { + $file_name = $_FILES['icon_upload']['name']; + $file_tmp = $_FILES['icon_upload']['tmp_name']; + $file_type = $_FILES['icon_upload']['type']; + $file_ext = strtolower(end(explode('.', $_FILES['icon_upload']['name']))); + + $allowed_extensions = [ + 'jpeg', + 'jpg', + 'png', + 'svg', + ]; + + $tab = 'manage_os'; + + if (in_array($file_ext, $allowed_extensions) === false) { + $message = 9; + } else { + $message = 8; + move_uploaded_file($file_tmp, $config['homedir'].'/images/os_icons/'.$file_name); + } + } + } else { + $values = []; + $values['name'] = $name; + $values['description'] = $description; + + if (($icon !== 0) && ($icon != '')) { + $values['icon_name'] = $icon; + } + + $resultOrId = false; + if ($name != '') { + $resultOrId = db_process_sql_insert('tconfig_os', $values); + } + + if ($resultOrId === false) { + $message = 2; + $tab = 'builder'; + $actionHidden = 'save'; + $textButton = __('Create'); + $classButton = ['icon' => 'wand']; + } else { + $tab = 'manage_os'; + $message = 1; + } + } + + if (is_metaconsole() === true) { + header('Location:'.$config['homeurl'].'index.php?sec=advanced&sec2=advanced/component_management&tab=os_manage&tab2=list&message='.$message); + } else { + header('Location:'.$config['homeurl'].'index.php?sec=gsetup&sec2=godmode/setup/os&tab='.$tab.'&message='.$message); + } + break; + + case 'update': + if ($icon_upload !== null && $icon_upload['name'] !== '') { + if (isset($_FILES['icon_upload']) === true) { + $file_name = $_FILES['icon_upload']['name']; + $file_tmp = $_FILES['icon_upload']['tmp_name']; + $file_type = $_FILES['icon_upload']['type']; + $file_ext = strtolower(end(explode('.', $_FILES['icon_upload']['name']))); + + $allowed_extensions = [ + 'jpeg', + 'jpg', + 'png', + 'svg', + ]; + + $tab = 'manage_os'; + + if (in_array($file_ext, $allowed_extensions) === false) { + $message = 9; + } else { + $message = 8; + move_uploaded_file($file_tmp, $config['homedir'].'/images/os_icons/'.$file_name); + } + } + } else { + $name = io_safe_input(strip_tags(io_safe_output((string) get_parameter('name')))); + $description = io_safe_input(strip_tags(io_safe_output((string) get_parameter('description')))); + $icon = get_parameter('icon', 0); + + $values = []; + $values['name'] = $name; + $values['description'] = $description; + // Only for Metaconsole. Save the previous name for synchronizing. + if (is_metaconsole() === true) { + $values['previous_name'] = db_get_value('name', 'tconfig_os', 'id_os', $idOS); + } + + if (($icon !== 0) && ($icon != '')) { + $values['icon_name'] = $icon; + } + + $result = false; + if ($name != '') { + $result = db_process_sql_update('tconfig_os', $values, ['id_os' => $idOS]); + } + + if ($result !== false) { + $message = 3; + $tab = 'manage_os'; + } else { + $message = 4; + $tab = 'builder'; + $os = db_get_row_filter('tconfig_os', ['id_os' => $idOS]); + $name = $os['name']; + } + + $actionHidden = 'update'; + $textButton = __('Update'); + $classButton = ['icon' => 'wand']; + } + + if (is_metaconsole() === true) { + header('Location:'.$config['homeurl'].'index.php?sec=advanced&sec2=advanced/component_management&tab=os_manage&tab2='.$tab.'&message='.$message); + } else { + header('Location:'.$config['homeurl'].'index.php?sec=gsetup&sec2=godmode/setup/os&tab='.$tab.'&message='.$message); + } + break; + + case 'delete': + $sql = 'SELECT COUNT(id_os) AS count FROM tagente WHERE id_os = '.$idOS; + $count = db_get_all_rows_sql($sql); + $count = $count[0]['count']; + + if ($count > 0) { + $message = 5; + } else { + $result = (bool) db_process_sql_delete('tconfig_os', ['id_os' => $idOS]); + if ($result) { + $message = 6; + } else { + $message = 7; + } + } + + if (is_metaconsole() === true) { + header('Location:'.$config['homeurl'].'index.php?sec=advanced&sec2=advanced/component_management&tab=list&tab2='.$tab.'&message='.$message); + } else { + header('Location:'.$config['homeurl'].'index.php?sec=gsetup&sec2=godmode/setup/os&tab='.$tab.'&message='.$message); + } + break; + + default: + case 'new': + $actionHidden = 'save'; + $textButton = __('Create'); + $classButton = ['icon' => 'next']; + break; + } +} + $icons = get_list_os_icons_dir(); $iconData = []; @@ -62,12 +247,11 @@ $iconData[] = html_print_div( true ); -echo '
'; +echo ''; $table = new stdClass(); $table->width = '100%'; $table->class = 'databox filter-table-adv'; -// $table->style[0] = 'width: 15%'; $table->data[0][] = html_print_label_input_block( __('Name'), html_print_input_text('name', $name, __('Name'), 20, 30, true, false, false, '', 'w250px') @@ -89,6 +273,11 @@ $table->data[1][] = html_print_label_input_block( html_print_textarea('description', 5, 20, $description, '', true, 'w250px') ); +$table->data[1][] = html_print_label_input_block( + '', + html_print_input_file('icon_upload', true, ['caption' => __('Upload icon')], 'form_setup') +); + html_print_table($table); html_print_input_hidden('id_os', $idOS); @@ -101,7 +290,6 @@ html_print_action_buttons( echo '
'; - function get_list_os_icons_dir() { global $config; diff --git a/pandora_console/godmode/setup/os.list.php b/pandora_console/godmode/setup/os.list.php index 330071353f..1ce9756cc0 100644 --- a/pandora_console/godmode/setup/os.list.php +++ b/pandora_console/godmode/setup/os.list.php @@ -45,7 +45,7 @@ if (is_management_allowed() === false) { $is_management_allowed = false; if (is_metaconsole() === false) { $url = ''.__('metaconsole').''; } else { $url = __('any node'); @@ -59,115 +59,68 @@ if (is_management_allowed() === false) { ); } -$table = new stdClass(); -$table->class = 'info_table'; -$table->head[0] = __('ID'); -$table->head[1] = __('Icon'); -$table->head[2] = __('Name'); -$table->head[3] = __('Description'); -if ($is_management_allowed === true) { - $table->head[4] = __('Actions'); -} +// Datatables list. +try { + $columns = [ + 'id_os', + 'icon_img', + 'name', + 'description', + 'options', + ]; -if ($is_management_allowed === true) { - $table->align[4] = 'center'; -} + $column_names = [ + [ + 'text' => __('ID'), + 'class' => 'w50px table_action_buttons', + ], + [ + 'text' => __('Icon'), + 'class' => 'w10px table_action_buttons', + ], + __('Name'), + __('Description'), + [ + 'text' => __('Options'), + 'class' => 'w20px table_action_buttons', + ], + ]; -$table->size[0] = '5%'; -if ($is_management_allowed === true) { - $table->size[4] = '20px'; -} - -// Prepare pagination. -$offset = (int) get_parameter('offset'); -$limit = $config['block_size']; -$count_osList = db_get_value('count(*)', 'tconfig_os'); - -$osList = db_get_all_rows_filter( - 'tconfig_os', - [ - 'offset' => $offset, - 'limit' => $limit, - ] -); - -if ($osList === false) { - $osList = []; -} - -$table->data = []; -foreach ($osList as $os) { - $data = []; - $data[] = $os['id_os']; - $data[] = ui_print_os_icon($os['id_os'], false, true); - if ($is_management_allowed === true) { - if (is_metaconsole() === true) { - $osNameUrl = 'index.php?sec=advanced&sec2=advanced/component_management&tab=os_manage&action=edit&tab2=builder&id_os='.$os['id_os']; - } else { - $osNameUrl = 'index.php?sec=gsetup&sec2=godmode/setup/os&action=edit&tab=builder&id_os='.$os['id_os']; - } - - $data[] = html_print_anchor( - [ - 'href' => $osNameUrl, - 'content' => io_safe_output($os['name']), + $tableId = 'os_table'; + // Load datatables user interface. + ui_print_datatable( + [ + 'id' => $tableId, + 'class' => 'info_table', + 'style' => 'width: 100%', + 'columns' => $columns, + 'column_names' => $column_names, + 'ajax_url' => 'include/ajax/os', + 'ajax_data' => ['method' => 'drawOSTable'], + 'ajax_postprocess' => 'process_datatables_item(item)', + 'no_sortable_columns' => [-1, 1], + 'order' => [ + 'field' => 'id', + 'direction' => 'asc', ], - true - ); - } else { - $data[] = io_safe_output($os['name']); - } - - $data[] = ui_print_truncate_text(io_safe_output($os['description']), 'description', true, true); - - if ($is_management_allowed === true) { - $table->cellclass[][4] = 'table_action_buttons'; - if ($os['id_os'] > 16) { - if (is_metaconsole() === true) { - $hrefDelete = 'index.php?sec=advanced&sec2=advanced/component_management&tab=os_manage&action=delete&tab2=list&id_os='.$os['id_os']; - } else { - $hrefDelete = 'index.php?sec=gsetup&sec2=godmode/setup/os&action=delete&tab=list&id_os='.$os['id_os']; - } - - $data[] = html_print_anchor( - [ - 'href' => $hrefDelete, - 'content' => html_print_image( - 'images/delete.svg', - true, - [ - 'alt' => __('Delete'), - 'title' => __('Delete'), - 'class' => 'main_menu_icon invert_filter', - ] - ), + 'search_button_class' => 'sub filter float-right', + 'form' => [ + 'inputs' => [ + [ + 'label' => __('Free search'), + 'type' => 'text', + 'class' => 'w25p', + 'id' => 'free_search', + 'name' => 'free_search', + ], ], - true - ); - } else { - // The original icons of pandora don't delete. - $data[] = ''; - } - } - - $table->data[] = $data; -} - -$tablePagination = ''; -if (isset($data) === true) { - html_print_table($table); - $tablePagination = ui_pagination( - $count_osList, - ui_get_url_refresh(['message' => false]), - $offset, - 0, - true, - 'offset', - false, - '' + ], + 'filter_main_class' => 'box-flat white_table_graph fixed_filter_bar', + 'dom_elements' => 'lftpB', + ] ); -} else { - ui_print_info_message(['no_close' => true, 'message' => __('There are no defined operating systems') ]); +} catch (Exception $e) { + echo $e->getMessage(); } $buttons = ''; @@ -191,3 +144,76 @@ html_print_action_buttons( 'right_content' => $tablePagination, ] ); + +echo ''; + +echo '
'; + +html_print_action_buttons( + html_print_submit_button(__('Create OS'), 'update_button', false, ['icon' => 'next'], true), + ['type' => 'form_action'] +); + +echo '
'; + +?> + diff --git a/pandora_console/godmode/setup/os.php b/pandora_console/godmode/setup/os.php index 539189f88d..99402ff30a 100644 --- a/pandora_console/godmode/setup/os.php +++ b/pandora_console/godmode/setup/os.php @@ -40,24 +40,13 @@ if (! check_acl($config['id_user'], 0, 'PM') && ! is_user_admin($config['id_user return; } -$action = get_parameter('action', 'new'); +$action = get_parameter('action', ''); $idOS = get_parameter('id_os', 0); $id_message = get_parameter('message', 0); if (is_metaconsole() === true) { $tab = get_parameter('tab2', 'list'); } else { - $tab = get_parameter('tab', 'list'); -} - -if ($idOS) { - $os = db_get_row_filter('tconfig_os', ['id_os' => $idOS]); - $name = $os['name']; - $description = $os['description']; - $icon = $os['icon_name']; -} else { - $name = io_safe_input(strip_tags(io_safe_output((string) get_parameter('name')))); - $description = io_safe_input(strip_tags(io_safe_output((string) get_parameter('description')))); - $icon = get_parameter('icon', 0); + $tab = get_parameter('tab', 'manage_os'); } $is_management_allowed = true; @@ -65,150 +54,60 @@ if (is_management_allowed() === false) { $is_management_allowed = false; } -$message = ''; -if ($is_management_allowed === true) { - switch ($action) { - case 'edit': - $actionHidden = 'update'; - $textButton = __('Update'); - $classButton = ['icon' => 'wand']; - break; - - case 'save': - $values = []; - $values['name'] = $name; - $values['description'] = $description; - - if (($icon !== 0) && ($icon != '')) { - $values['icon_name'] = $icon; - } - - $resultOrId = false; - if ($name != '') { - $resultOrId = db_process_sql_insert('tconfig_os', $values); - } - - if ($resultOrId === false) { - $message = 2; - $tab = 'builder'; - $actionHidden = 'save'; - $textButton = __('Create'); - $classButton = ['icon' => 'wand']; - } else { - $tab = 'list'; - $message = 1; - } - - if (is_metaconsole() === true) { - header('Location:'.$config['homeurl'].'index.php?sec=advanced&sec2=advanced/component_management&tab=os_manage&tab2='.$tab.'&message='.$message); - } else { - header('Location:'.$config['homeurl'].'index.php?sec=gsetup&sec2=godmode/setup/os&tab='.$tab.'&message='.$message); - } - break; - - case 'update': - $name = io_safe_input(strip_tags(io_safe_output((string) get_parameter('name')))); - $description = io_safe_input(strip_tags(io_safe_output((string) get_parameter('description')))); - $icon = get_parameter('icon', 0); - - $values = []; - $values['name'] = $name; - $values['description'] = $description; - // Only for Metaconsole. Save the previous name for synchronizing. - if (is_metaconsole() === true) { - $values['previous_name'] = db_get_value('name', 'tconfig_os', 'id_os', $idOS); - } - - if (($icon !== 0) && ($icon != '')) { - $values['icon_name'] = $icon; - } - - $result = false; - if ($name != '') { - $result = db_process_sql_update('tconfig_os', $values, ['id_os' => $idOS]); - } - - if ($result !== false) { - $message = 3; - $tab = 'list'; - } else { - $message = 4; - $tab = 'builder'; - $os = db_get_row_filter('tconfig_os', ['id_os' => $idOS]); - $name = $os['name']; - } - - $actionHidden = 'update'; - $textButton = __('Update'); - $classButton = ['icon' => 'wand']; - if (is_metaconsole() === true) { - header('Location:'.$config['homeurl'].'index.php?sec=advanced&sec2=advanced/component_management&tab=os_manage&tab2='.$tab.'&message='.$message); - } else { - header('Location:'.$config['homeurl'].'index.php?sec=gsetup&sec2=godmode/setup/os&tab='.$tab.'&message='.$message); - } - break; - - case 'delete': - $sql = 'SELECT COUNT(id_os) AS count FROM tagente WHERE id_os = '.$idOS; - $count = db_get_all_rows_sql($sql); - $count = $count[0]['count']; - - if ($count > 0) { - $message = 5; - } else { - $result = (bool) db_process_sql_delete('tconfig_os', ['id_os' => $idOS]); - if ($result) { - $message = 6; - } else { - $message = 7; - } - } - - if (is_metaconsole() === true) { - header('Location:'.$config['homeurl'].'index.php?sec=advanced&sec2=advanced/component_management&tab=os_manage&tab2='.$tab.'&message='.$message); - } else { - header('Location:'.$config['homeurl'].'index.php?sec=gsetup&sec2=godmode/setup/os&tab='.$tab.'&message='.$message); - } - break; - - default: - case 'new': - $actionHidden = 'save'; - $textButton = __('Create'); - $classButton = ['icon' => 'next']; - break; - } -} - $buttons = []; -$buttons['list'] = [ + +$buttons['manage_os'] = [ 'active' => false, - 'text' => ''.html_print_image( - 'images/logs@svg.svg', + 'text' => ''.html_print_image( + 'images/os@svg.svg', true, [ - 'title' => __('List OS'), + 'title' => __('Manage OS types'), + 'class' => 'invert_filter main_menu_icon', + ] + ).'', +]; + +$buttons['manage_version'] = [ + 'active' => false, + 'text' => ''.html_print_image( + 'images/os_version@svg.svg', + true, + [ + 'title' => __('Manage version expiration dates'), 'class' => 'invert_filter main_menu_icon', ] ).'', ]; -if ($is_management_allowed === true) { - $buttons['builder'] = [ - 'active' => false, - 'text' => ''.html_print_image( - 'images/edit.svg', - true, - [ - 'title' => __('Builder OS'), - 'class' => 'invert_filter main_menu_icon', - ] - ).'', - ]; -} $buttons[$tab]['active'] = true; -$headerTitle = ($tab === 'builder') ? __('Edit OS') : __('List of Operating Systems'); +switch ($tab) { + case 'builder': + $headerTitle = __('Edit OS'); + break; + + case 'manage_os': + case 'list': + if ($action === 'edit') { + $headerTitle = __('Edit OS'); + } else { + $headerTitle = __('List of Operating Systems'); + } + break; + + case 'manage_version': + if ($action === 'edit') { + $headerTitle = __('Edit OS version expiration date'); + } else { + $headerTitle = __('List of version expiration dates'); + } + break; + + default: + // Default. + break; +} if (is_metaconsole() === false) { // Header. @@ -262,6 +161,14 @@ if (empty($id_message) === false) { echo ui_print_error_message(__('Error deleting'), '', true); break; + case 8: + echo ui_print_success_message(__('Icon successfuly uploaded'), '', true); + break; + + case 9: + echo ui_print_error_message(__('File must be of type JPG, JPEG, PNG or SVG'), '', true); + break; + default: // Default. break; @@ -269,12 +176,21 @@ if (empty($id_message) === false) { } switch ($tab) { + case 'manage_os': case 'list': - include_once $config['homedir'].'/godmode/setup/os.list.php'; + if (in_array($action, ['edit', 'save', 'update']) && is_management_allowed() === true) { + include_once $config['homedir'].'/godmode/setup/os.builder.php'; + } else { + include_once $config['homedir'].'/godmode/setup/os.list.php'; + } break; - case 'builder': - include_once $config['homedir'].'/godmode/setup/os.builder.php'; + case 'manage_version': + if (in_array($action, ['edit', 'save', 'update']) && is_management_allowed() === true) { + include_once $config['homedir'].'/godmode/setup/os_version.builder.php'; + } else { + include_once $config['homedir'].'/godmode/setup/os_version.list.php'; + } break; default: diff --git a/pandora_console/godmode/setup/os_version.builder.php b/pandora_console/godmode/setup/os_version.builder.php new file mode 100644 index 0000000000..caf968e5be --- /dev/null +++ b/pandora_console/godmode/setup/os_version.builder.php @@ -0,0 +1,211 @@ + 0) { + $os_version = db_get_row_filter('tconfig_os_version', ['id_os_version' => $idOS]); + $product = $os_version['product']; + $version = $os_version['version']; + $end_of_life_date = $os_version['end_of_support']; +} else { + $product = io_safe_input(strip_tags(io_safe_output((string) get_parameter('product')))); + $version = io_safe_input(strip_tags(io_safe_output((string) get_parameter('version')))); + $end_of_life_date = get_parameter('end_of_life_date', date("Y/m/d")); +} + +$message = ''; +if ($is_management_allowed === true) { + switch ($action) { + case 'edit': + if ($idOS > 0) { + $actionHidden = 'update'; + $textButton = __('Update'); + $classButton = ['icon' => 'wand']; + } else { + $actionHidden = 'save'; + $textButton = __('Create'); + $classButton = ['icon' => 'next']; + } + break; + + case 'save': + $values = []; + // Product and version must be stored with no entities to be able to use REGEXP in queries. + // CAREFUL! output of these fields must be encoded to avoid scripting vulnerabilities. + $values['product'] = io_safe_output($product); + $values['version'] = io_safe_output($version); + $values['end_of_support'] = $end_of_life_date; + + $result = db_process_sql_insert('tconfig_os_version', $values); + + if ($result === false) { + $message = 2; + } else { + $message = 1; + } + + $tab = 'manage_version'; + + header('Location:'.$config['homeurl'].'index.php?sec=gsetup&sec2=godmode/setup/os&tab='.$tab.'&message='.$message); + break; + + case 'update': + $product = io_safe_output(get_parameter('product')); + $version = io_safe_output(get_parameter('version')); + $end_of_life_date = get_parameter('end_of_life_date', 0); + $values = []; + $values['product'] = $product; + $values['version'] = $version; + $values['end_of_support'] = $end_of_life_date; + $result = db_process_sql_update('tconfig_os_version', $values, ['id_os_version' => $idOS]); + + if ($result === false) { + $message = 4; + } else { + $message = 3; + } + + $tab = 'manage_version'; + + header('Location:'.$config['homeurl'].'index.php?sec=gsetup&sec2=godmode/setup/os&tab='.$tab.'&message='.$message); + break; + + case 'delete': + $sql = 'SELECT COUNT(id_os) AS count FROM tagente WHERE id_os = '.$idOS; + $count = db_get_all_rows_sql($sql); + $count = $count[0]['count']; + + if ($count > 0) { + $message = 5; + } else { + $result = (bool) db_process_sql_delete('tconfig_os', ['id_os' => $idOS]); + if ($result) { + $message = 6; + } else { + $message = 7; + } + } + + if (is_metaconsole() === true) { + header('Location:'.$config['homeurl'].'index.php?sec=advanced&sec2=advanced/component_management&tab=list&tab2='.$tab.'&message='.$message); + } else { + header('Location:'.$config['homeurl'].'index.php?sec=gsetup&sec2=godmode/setup/os&tab='.$tab.'&message='.$message); + } + break; + + default: + case 'new': + $actionHidden = 'save'; + $textButton = __('Create'); + $classButton = ['icon' => 'next']; + break; + } +} + +echo '
'; +$table = new stdClass(); +$table->width = '100%'; +$table->class = 'databox filter-table-adv'; + +// $table->style[0] = 'width: 15%'; +$table->data[0][] = html_print_label_input_block( + __('Product'), + html_print_input_text('product', io_safe_input($product), __('Product'), 20, 300, true, false, false, '', 'w250px') +); + +$table->data[0][] = html_print_label_input_block( + __('Version'), + html_print_input_text('version', io_safe_input($version), __('Version'), 20, 300, true, false, false, '', 'w250px') +); + +$timeInputs = []; + +$timeInputs[] = html_print_div( + [ + 'id' => 'end_of_life_date', + 'style' => '', + 'content' => html_print_div( + [ + 'class' => '', + 'content' => html_print_input_text( + 'end_of_life_date', + $end_of_life_date, + '', + 10, + 10, + true + ), + ], + true + ), + ], + true +); + +$table->data[1][] = html_print_label_input_block( + __('End of life date'), + implode('', $timeInputs) +); + +html_print_table($table); + +html_print_input_hidden('id_os', $idOS); +html_print_input_hidden('action', $actionHidden); + +html_print_action_buttons( + html_print_submit_button($textButton, 'update_button', false, $classButton, true), + ['type' => 'form_action'] +); + +echo '
'; + +?> + \ No newline at end of file diff --git a/pandora_console/godmode/setup/os_version.list.php b/pandora_console/godmode/setup/os_version.list.php new file mode 100644 index 0000000000..3e15725793 --- /dev/null +++ b/pandora_console/godmode/setup/os_version.list.php @@ -0,0 +1,198 @@ + __('Options'), + 'class' => 'w100px table_action_buttons', + ], + ]; + + $tableId = 'os_version_table'; + // Load datatables user interface. + ui_print_datatable( + [ + 'id' => $tableId, + 'class' => 'info_table', + 'style' => 'width: 100%', + 'columns' => $columns, + 'column_names' => $column_names, + 'ajax_url' => 'include/ajax/os', + 'ajax_data' => ['method' => 'drawOSVersionTable'], + 'ajax_postprocess' => 'process_datatables_item(item)', + 'no_sortable_columns' => [-1], + 'order' => [ + 'field' => 'id', + 'direction' => 'asc', + ], + 'search_button_class' => 'sub filter float-right', + 'form' => [ + 'inputs' => [ + [ + 'label' => __('Free search'), + 'type' => 'text', + 'class' => 'w25p', + 'id' => 'free_search', + 'name' => 'free_search', + ], + ], + ], + 'filter_main_class' => 'box-flat white_table_graph fixed_filter_bar', + 'dom_elements' => 'lftpB', + ] + ); +} catch (Exception $e) { + echo $e->getMessage(); +} + +echo ''; + +echo '
'; + +html_print_action_buttons( + html_print_submit_button(__('Create OS version'), 'update_button', false, ['icon' => 'next'], true), + ['type' => 'form_action'] +); + +echo '
'; + +echo '
'; +html_print_input_hidden('os_type_regex', ''); +html_print_input_hidden('os_version_regex', ''); + +echo '
'; + +?> + + \ No newline at end of file diff --git a/pandora_console/godmode/setup/os_version.php b/pandora_console/godmode/setup/os_version.php new file mode 100644 index 0000000000..ec5d27beae --- /dev/null +++ b/pandora_console/godmode/setup/os_version.php @@ -0,0 +1,285 @@ + $id_os_version]); + $product = $os_version['product']; + $version = $os_version['version']; + $end_of_life_date = $os_version['end_of_life_date']; +} else { + $product = io_safe_input(strip_tags(io_safe_output((string) get_parameter('product')))); + $version = io_safe_input(strip_tags(io_safe_output((string) get_parameter('version')))); + $end_of_life_date = get_parameter('end_of_life_date', 0); +} + +$is_management_allowed = true; +if (is_management_allowed() === false) { + $is_management_allowed = false; +} + +$message = ''; +if ($is_management_allowed === true) { + switch ($action) { + case 'edit': + $action_hidden = 'update'; + $text_button = __('Update'); + $class_button = ['icon' => 'wand']; + break; + + case 'save': + $values = []; + $values['product'] = $product; + $values['version'] = $version; + $values['end_of_life_date'] = $end_of_life_date; + + $result_or_id = false; + if ($product !== '') { + $result_or_id = db_process_sql_insert('tconfig_os_version', $values); + } + + if ($result_or_id === false) { + $message = 2; + $tab = 'builder'; + $actionHidden = 'save'; + $textButton = __('Create'); + $classButton = ['icon' => 'wand']; + } else { + $tab = 'list'; + $message = 1; + } + + if (is_metaconsole() === true) { + header('Location:'.$config['homeurl'].'index.php?sec=advanced&sec2=advanced/component_management&tab=os_manage&tab2='.$tab.'&message='.$message); + } else { + header('Location:'.$config['homeurl'].'index.php?sec=gsetup&sec2=godmode/setup/os&tab='.$tab.'&message='.$message); + } + break; + + case 'update': + $product = io_safe_input(strip_tags(io_safe_output((string) get_parameter('product')))); + $version = io_safe_input(strip_tags(io_safe_output((string) get_parameter('version')))); + $end_of_life_date = get_parameter('end_of_life_date', 0); + + $values = []; + $values['product'] = $product; + $values['version'] = $version; + + $result = false; + $result = db_process_sql_update('tconfig_os_version', $values, ['id_os' => $id_os_version]); + + if ($result !== false) { + $message = 3; + $tab = 'list'; + } else { + $message = 4; + $tab = 'builder'; + $os = db_get_row_filter('tconfig_os', ['id_os' => $idOS]); + $name = $os['name']; + } + + $actionHidden = 'update'; + $textButton = __('Update'); + $classButton = ['icon' => 'wand']; + if (is_metaconsole() === true) { + header('Location:'.$config['homeurl'].'index.php?sec=advanced&sec2=advanced/component_management&tab=os_manage&tab2='.$tab.'&message='.$message); + } else { + header('Location:'.$config['homeurl'].'index.php?sec=gsetup&sec2=godmode/setup/os_version&tab='.$tab.'&message='.$message); + } + break; + + case 'delete': + $sql = 'SELECT COUNT(id_os) AS count FROM tagente WHERE id_os = '.$idOS; + $count = db_get_all_rows_sql($sql); + $count = $count[0]['count']; + + if ($count > 0) { + $message = 5; + } else { + $result = (bool) db_process_sql_delete('tconfig_os', ['id_os' => $idOS]); + if ($result) { + $message = 6; + } else { + $message = 7; + } + } + + if (is_metaconsole() === true) { + header('Location:'.$config['homeurl'].'index.php?sec=advanced&sec2=advanced/component_management&tab=os_manage&tab2='.$tab.'&message='.$message); + } else { + header('Location:'.$config['homeurl'].'index.php?sec=gsetup&sec2=godmode/setup/os&tab='.$tab.'&message='.$message); + } + break; + + default: + case 'new': + $actionHidden = 'save'; + $textButton = __('Create'); + $classButton = ['icon' => 'next']; + break; + } +} + +$buttons = []; +$buttons['list'] = [ + 'active' => false, + 'text' => ''.html_print_image( + 'images/logs@svg.svg', + true, + [ + 'title' => __('List OS'), + 'class' => 'invert_filter main_menu_icon', + ] + ).'', +]; +if ($is_management_allowed === true) { + $buttons['builder'] = [ + 'active' => false, + 'text' => ''.html_print_image( + 'images/edit.svg', + true, + [ + 'title' => __('Builder OS'), + 'class' => 'invert_filter main_menu_icon', + ] + ).'', + ]; + + $buttons['version_exp_date_editor'] = [ + 'active' => false, + 'text' => ''.html_print_image( + 'images/edit.svg', + true, + [ + 'title' => __('Version expiration date editor'), + 'class' => 'invert_filter main_menu_icon', + ] + ).'', + ]; +} + +$buttons[$tab]['active'] = true; + +switch ($tab) { + case 'builder': + $headerTitle = __('Edit OS'); + break; + + case 'manage_version': + $headerTitle = __('Version expiration date editor'); + break; + + case 'list': + $headerTitle = __('List of Operating Systems'); + break; + + default: + // Default. + break; +} + +if (is_metaconsole() === false) { + // Header. + ui_print_standard_header( + $headerTitle, + '', + false, + '', + true, + $buttons, + [ + [ + 'link' => '', + 'label' => __('Servers'), + ], + [ + 'link' => '', + 'label' => __('Edit OS'), + ], + ] + ); +} + +if (empty($id_message) === false) { + switch ($id_message) { + case 1: + echo ui_print_success_message(__('Success creating OS'), '', true); + break; + + case 2: + echo ui_print_error_message(__('Fail creating OS'), '', true); + break; + + case 3: + echo ui_print_success_message(__('Success updating OS'), '', true); + break; + + case 4: + echo ui_print_error_message(__('Error updating OS'), '', true); + break; + + case 5: + echo ui_print_error_message(__('There are agents with this OS.'), '', true); + break; + + case 6: + echo ui_print_success_message(__('Success deleting'), '', true); + break; + + case 7: + echo ui_print_error_message(__('Error deleting'), '', true); + break; + + default: + // Default. + break; + } +} + +include_once $config['homedir'].'/godmode/setup/os_version.list.php'; diff --git a/pandora_console/images/os@svg.svg b/pandora_console/images/os@svg.svg new file mode 100644 index 0000000000..80f8caf194 --- /dev/null +++ b/pandora_console/images/os@svg.svg @@ -0,0 +1,7 @@ + + + os@svg + + + + \ No newline at end of file diff --git a/pandora_console/images/os_version@svg.svg b/pandora_console/images/os_version@svg.svg new file mode 100644 index 0000000000..1274ccc3f8 --- /dev/null +++ b/pandora_console/images/os_version@svg.svg @@ -0,0 +1,15 @@ + + + os version@svg + + + + + + + + + + + + \ No newline at end of file diff --git a/pandora_console/include/ajax/os.php b/pandora_console/include/ajax/os.php new file mode 100644 index 0000000000..058fe75578 --- /dev/null +++ b/pandora_console/include/ajax/os.php @@ -0,0 +1,376 @@ + false]); + return; + } + + if (db_process_sql_delete( + 'tconfig_os', + ['id_os' => $id_os] + ) === false + ) { + echo json_encode(['deleted' => false]); + } else { + echo json_encode(['deleted' => true]); + } +} + +if ($method === 'deleteOSVersion') { + global $config; + + $id_os_version = get_parameter('id_os_version', null); + + if (empty($id_os_version) === true || $id_os_version < 1) { + echo json_encode(['deleted' => false]); + } + + if (db_process_sql_delete( + 'tconfig_os_version', + ['id_os_version' => $id_os_version] + ) === false + ) { + echo json_encode(['deleted' => false]); + } else { + echo json_encode(['deleted' => true]); + } +} + +if ($method === 'drawOSTable') { + // Datatables offset, limit and order. + $filter = get_parameter('filter', []); + $start = get_parameter('start', 0); + $length = get_parameter('length', $config['block_size']); + $orderBy = get_datatable_order(true); + + $sort_field = $orderBy['field']; + $order = $orderBy['direction']; + + $pagination = ''; + + $pagination = sprintf( + ' LIMIT %d OFFSET %d ', + $length, + $start + ); + + try { + ob_start(); + + $fields = ['*']; + $sql_filters = []; + + if (isset($filter['free_search']) === true + && empty($filter['free_search']) === false + ) { + $sql_filters[] = sprintf( + ' AND (`name` like "%%%s%%" OR `description` like "%%%s%%") ', + $filter['free_search'], + $filter['free_search'] + ); + } + + if (isset($order) === true) { + $dir = 'asc'; + if ($order == 'desc') { + $dir = 'desc'; + }; + + if (in_array( + $sort_field, + [ + 'id_os', + 'name', + 'description', + ] + ) === true + ) { + $order_by = sprintf( + 'ORDER BY `%s` %s', + $sort_field, + $dir + ); + } + } + + // Retrieve data. + $sql = sprintf( + 'SELECT %s + FROM tconfig_os + WHERE 1=1 + %s + %s + %s', + join(',', $fields), + join(' ', $sql_filters), + $order_by, + $pagination + ); + + $count_sql = sprintf( + 'SELECT id_os + FROM tconfig_os + WHERE 1=1 + %s', + join(' ', $sql_filters) + ); + + $return = db_get_all_rows_sql($sql); + if ($return === false) { + $data = []; + } else { + $data = $return; + } + + $data = array_map( + function ($item) { + $item['icon_img'] = ui_print_os_icon($item['id_os'], false, true); + + if (is_management_allowed() === true) { + if (is_metaconsole() === true) { + $osNameUrl = 'index.php?sec=advanced&sec2=advanced/component_management&tab=os_manage&action=edit&tab2=list&id_os='.$item['id_os']; + } else { + $osNameUrl = 'index.php?sec=gsetup&sec2=godmode/setup/os&action=edit&tab=manage_os&id_os='.$item['id_os']; + } + + $item['name'] = html_print_anchor( + [ + 'href' => $osNameUrl, + 'content' => $item['name'], + ], + true + ); + } else { + $item['name'] = $item['name']; + } + + $item['description'] = ui_print_truncate_text( + $item['description'], + 'description', + true, + true + ); + + if (is_management_allowed() === true) { + $item['enable_delete'] = false; + + if ($item['id_os'] > 16) { + $item['enable_delete'] = true; + } + } + + return $item; + }, + $data + ); + + // Retrieve counter. + $count = db_get_value('count(*)', '('.$count_sql.') t'); + + // Datatables format: RecordsTotal && recordsfiltered. + echo json_encode( + [ + 'data' => $data, + 'recordsTotal' => $count, + 'recordsFiltered' => $count, + ] + ); + // Capture output. + $response = ob_get_clean(); + } catch (Exception $e) { + echo json_encode(['error' => $e->getMessage()]); + exit; + } + + // If not valid, show error with issue. + json_decode($response); + if (json_last_error() == JSON_ERROR_NONE) { + // If valid dump. + echo $response; + } else { + echo json_encode( + ['error' => $response] + ); + } + + exit; +} + +if ($method === 'drawOSVersionTable') { + // Datatables offset, limit and order. + $filter = get_parameter('filter', []); + $start = get_parameter('start', 0); + $length = get_parameter('length', $config['block_size']); + $orderBy = get_datatable_order(true); + + $sort_field = $orderBy['field']; + $order = $orderBy['direction']; + + $pagination = ''; + + $pagination = sprintf( + ' LIMIT %d OFFSET %d ', + $length, + $start + ); + + try { + ob_start(); + + $fields = ['*']; + $sql_filters = []; + + if (isset($filter['free_search']) === true + && empty($filter['free_search']) === false + ) { + $sql_filters[] = sprintf( + ' AND (`product` like "%%%s%%" OR `version` like "%%%s%%") ', + $filter['free_search'], + $filter['free_search'] + ); + } + + if (isset($order) === true) { + $dir = 'asc'; + if ($order == 'desc') { + $dir = 'desc'; + }; + + if (in_array( + $sort_field, + [ + 'product', + 'version', + 'end_of_support', + ] + ) === true + ) { + $order_by = sprintf( + 'ORDER BY `%s` %s', + $sort_field, + $dir + ); + } + } + + // Retrieve data. + $sql = sprintf( + 'SELECT %s + FROM tconfig_os_version + WHERE 1=1 + %s + %s + %s', + join(',', $fields), + join(' ', $sql_filters), + $order_by, + $pagination + ); + + $count_sql = sprintf( + 'SELECT id_os_version + FROM tconfig_os_version + WHERE 1=1 + %s', + join(' ', $sql_filters) + ); + + $return = db_get_all_rows_sql($sql); + + if ($return === false) { + $data = []; + } else { + // Format end of life date. + $return = array_map( + function ($item) { + $date_string = date_w_fixed_tz($item['end_of_support']); + $timestamp = strtotime($date_string); + $date_without_time = date('F j, Y', $timestamp); + $item['end_of_support'] = $date_without_time; + return $item; + }, + $return + ); + + $data = $return; + } + + // Retrieve counter. + $count = db_get_value('count(*)', '('.$count_sql.') t'); + + // Datatables format: RecordsTotal && recordsfiltered. + echo json_encode( + [ + 'data' => $data, + 'recordsTotal' => $count, + 'recordsFiltered' => $count, + ] + ); + // Capture output. + $response = ob_get_clean(); + } catch (Exception $e) { + echo json_encode(['error' => $e->getMessage()]); + exit; + } + + // If not valid, show error with issue. + json_decode($response); + if (json_last_error() == JSON_ERROR_NONE) { + // If valid dump. + echo $response; + } else { + echo json_encode( + ['error' => $response] + ); + } + + exit; +} diff --git a/pandora_console/include/functions_agents.php b/pandora_console/include/functions_agents.php index f1cb4e1f0e..720b0e6e55 100644 --- a/pandora_console/include/functions_agents.php +++ b/pandora_console/include/functions_agents.php @@ -497,7 +497,8 @@ function agents_get_agents( ], $return=false, $disabled_agent=0, - $use_meta_table=false + $use_meta_table=false, + $join_os_table=false ) { global $config; @@ -710,6 +711,18 @@ function agents_get_agents( ON tpolicy_agents.id_agent=tagente.id_agente'; } + if ($join_os_table === true) { + $os_version_join = ' + INNER JOIN tconfig_os + ON tagente.id_os = tconfig_os.id_os + INNER JOIN tconfig_os_version + ON tconfig_os.name REGEXP tconfig_os_version.product + '; + unset($filter['os_version_end_of_life']); + } else { + $os_version_join = ''; + } + if ($extra) { $where = sprintf( '(%s OR (%s)) AND (%s) AND (%s) %s AND %s %s %s %s', @@ -744,11 +757,12 @@ function agents_get_agents( FROM `%s` tagente LEFT JOIN tagent_secondary_group ON tagent_secondary_group.id_agent=tagente.id_agente - %s + %s %s WHERE %s %s', implode(',', $fields), $table_name, $policy_join, + $os_version_join, $where, $order ); diff --git a/pandora_console/include/functions_api.php b/pandora_console/include/functions_api.php index 9dfe1c0801..f6d1674022 100644 --- a/pandora_console/include/functions_api.php +++ b/pandora_console/include/functions_api.php @@ -1528,6 +1528,7 @@ function api_set_update_agent($id_agent, $thrash2, $other, $thrash3) $learningMode = $other['data'][10]; $disabled = $other['data'][11]; $description = $other['data'][12]; + $osVersion = $other['data'][13]; // Check parameters. if ($idGroup == 0) { @@ -1623,6 +1624,7 @@ function api_set_update_agent($id_agent, $thrash2, $other, $thrash3) 'server_name' => $nameServer, 'id_parent' => $idParent, 'custom_id' => $customId, + 'os_version' => $osVersion, ], ['id_agente' => $id_agent] ); diff --git a/pandora_console/include/functions_html.php b/pandora_console/include/functions_html.php index 0dd7808092..2552fbcdc1 100644 --- a/pandora_console/include/functions_html.php +++ b/pandora_console/include/functions_html.php @@ -4867,7 +4867,7 @@ function html_print_header_logo_image(bool $menuCollapsed, bool $return=false) * Key disabled: Whether to disable the input or not. * Key class: HTML class */ -function html_print_input_file($name, $return=false, $options=false) +function html_print_input_file($name, $return=false, $options=false, $inline_upload_anchor_to_form='') { $output = ''; // Start to build the input. @@ -4914,11 +4914,45 @@ function html_print_input_file($name, $return=false, $options=false) $output .= ($options['caption'] ?? __('Select a file')); $output .= ''; + + if ($inline_upload_anchor_to_form !== '') { + // Add script to submit targeted form. + $output .= ''; + $output .= '
'; + } + $output .= ' '; + + if ($inline_upload_anchor_to_form !== '') { + $output .= '
'; + $output .= html_print_button( + __('Upload'), + 'upload-icon-btn', + false, + sprintf( + 'javascript:submitForm("%s")', + $inline_upload_anchor_to_form + ), + [ + 'mode' => 'link', + 'style' => 'min-width: initial;', + ], + true, + ); + $output .= '
'; + $output .= '
'; + } + // Add script. $output .= ''; @@ -7612,5 +7647,4 @@ function html_print_wizard_diagnosis( } else { echo $output; } - -} \ No newline at end of file +} diff --git a/pandora_console/include/functions_reporting.php b/pandora_console/include/functions_reporting.php index eab4e761d3..ce15b4b626 100755 --- a/pandora_console/include/functions_reporting.php +++ b/pandora_console/include/functions_reporting.php @@ -778,6 +778,13 @@ function reporting_make_reporting_data( ); break; + case 'end_of_life': + $report['contents'][] = reporting_end_of_life( + $report, + $content + ); + break; + case 'alert_report_actions': $report['contents'][] = reporting_alert_report_actions( $report, @@ -3618,6 +3625,112 @@ function reporting_agent_module_status($report, $content) } +/** + * OS Version End of Life + * + * @param array $report Info Report. + * @param array $content Info content. + * + * @return array + */ +function reporting_end_of_life($report, $content) +{ + global $config; + + $return['type'] = 'end_of_life'; + + if (empty($content['name'])) { + $content['name'] = __('End of life'); + } + + $return['title'] = io_safe_output($content['name']); + $return['landscape'] = $content['landscape']; + $return['pagebreak'] = $content['pagebreak']; + $return['subtitle'] = __('End of life report'); + $return['description'] = io_safe_output($content['description']); + $return['date'] = reporting_get_date_text($report, $content); + $return['label'] = (isset($content['style']['label'])) ? $content['style']['label'] : ''; + + $return['data'] = []; + + $external_source = json_decode( + $content['external_source'], + true + ); + + $servers_ids = [0]; + + if (is_metaconsole() === true) { + $servers_ids = array_column(metaconsole_get_servers(), 'id'); + } + + foreach ($servers_ids as $server_id) { + if (is_metaconsole() === true) { + $connection = metaconsole_get_connection_by_id($server_id); + if (metaconsole_connect($connection) != NOERR) { + continue; + } + } + + $agents = agents_get_agents( + [], + [ + 'alias', + 'direccion', + 'name', + 'os_version', + ], + 'AR', + [ + 'field' => 'nombre', + 'order' => 'ASC', + ], + false, + 0, + false, + true + ); + + $es_os_version = $external_source['os_version']; + + $es_limit_eol_datetime = DateTime::createFromFormat('Y/m/d', $external_source['end_of_life_date']); + + // Post-process returned agents to filter agents using correctly formatted fields. + foreach ($agents as $idx => $agent) { + // Must perform this query and subsequent operations in each iteration (note this is costly) since OS version field may contain HTML entities in BD and decoding can't be fully handled with mysql methods when doing a REGEXP. + $result_end_of_life = db_get_value_sql('SELECT end_of_support FROM tconfig_os_version WHERE "'.io_safe_output($agent['os_version']).'" REGEXP version AND "'.io_safe_output($agent['name']).'" REGEXP product'); + $agent_eol_datetime = DateTime::createFromFormat('Y/m/d', $result_end_of_life); + + if ((preg_match('/'.$es_os_version.'/i', $agent['os_version']) || $es_os_version === '') && $result_end_of_life !== false && ($es_limit_eol_datetime === false || $es_limit_eol_datetime >= $agent_eol_datetime)) { + // Agent matches an existing OS version. + $agents[$idx]['end_of_life'] = $result_end_of_life; + } else { + // Set agent to be filtered out. + $agents[$idx] = null; + } + } + + if ($agents !== false) { + $agents = array_filter($agents); + } + + if (is_metaconsole() === true) { + $res[$connection['server_name']] = $agents; + + metaconsole_restore_db(); + } + } + + if (is_metaconsole() === true) { + $return['data'] = $res; + } else { + $return['data'] = $agents; + } + + return reporting_check_structure_content($return); +} + + function reporting_exception( $report, $content, diff --git a/pandora_console/include/functions_reporting_html.php b/pandora_console/include/functions_reporting_html.php index 0715b2f3f2..99f3af63ad 100644 --- a/pandora_console/include/functions_reporting_html.php +++ b/pandora_console/include/functions_reporting_html.php @@ -403,6 +403,10 @@ function reporting_html_print_report($report, $mini=false, $report_info=1, $cust reporting_html_agent_module_status($table, $item); break; + case 'end_of_life': + reporting_html_end_of_life($table, $item); + break; + case 'alert_report_actions': reporting_html_alert_report_actions($table, $item); break; @@ -2754,6 +2758,123 @@ function reporting_html_agent_module_status($table, $item, $pdf=0) } +/** + * Html report end of life. + * + * @param object $table Head table or false if it comes from pdf. + * @param array $item Items data. + * @param integer $pdf Pdf output. + * + * @return mixed + */ +function reporting_html_end_of_life($table, $item, $pdf=0) +{ + global $config; + + $return_pdf = ''; + + if (empty($item['data']) === true) { + if ($pdf !== 0) { + $return_pdf .= __('No items'); + } else { + $table->colspan['group_report']['cell'] = 3; + $table->cellstyle['group_report']['cell'] = 'text-align: center;'; + $table->data['group_report']['cell'] = __('No items'); + } + } else { + $table_info = new stdClass(); + $table_info->width = '99%'; + + $table_info->align = []; + + if (is_metaconsole() === true) { + $table_info->align['server'] = 'left'; + } + + $table_info->align['agent_alias'] = 'left'; + $table_info->align['ip'] = 'left'; + $table_info->align['os_type'] = 'left'; + $table_info->align['os_version'] = 'left'; + $table_info->align['end_of_life'] = 'left'; + + $table_info->headstyle = []; + + if (is_metaconsole() === true) { + $table_info->headstyle['server'] = 'text-align: left'; + } + + $table_info->headstyle['agent_alias'] = 'text-align: left'; + $table_info->headstyle['ip'] = 'text-align: left'; + $table_info->headstyle['os_type'] = 'text-align: left'; + $table_info->headstyle['os_version'] = 'text-align: left'; + $table_info->headstyle['end_of_life'] = 'text-align: left'; + + $table_info->head = []; + if (is_metaconsole() === true) { + $table_info->head['server'] = __('Server'); + } + + $table_info->head['agent_alias'] = __('Agent alias'); + $table_info->head['ip'] = __('IP'); + $table_info->head['os_type'] = __('OS Type'); + $table_info->head['os_version'] = __('OS Version'); + $table_info->head['end_of_life'] = __('End of life'); + + $table_info->data = []; + + if (is_metaconsole() === true) { + foreach ($item['data'] as $server_name => $agents_per_server) { + foreach ($agents_per_server as $agent) { + $row = []; + + $row['server'] = $server_name; + $row['agent_alias'] = $agent['alias']; + $row['ip'] = $agent['direccion']; + $row['os_type'] = $agent['name']; + $row['os_version'] = $agent['os_version']; + $date_string = date_w_fixed_tz($agent['end_of_life']); + $timestamp = strtotime($date_string); + $date_without_time = date('F j, Y', $timestamp); + $row['end_of_life'] = $date_without_time; + + $table_info->data[] = $row; + } + } + } else { + foreach ($item['data'] as $data) { + $row = []; + + $row['agent_alias'] = $data['alias']; + $row['ip'] = $data['direccion']; + $row['os_type'] = $data['name']; + $row['os_version'] = $data['os_version']; + $date_string = date_w_fixed_tz($data['end_of_life']); + $timestamp = strtotime($date_string); + $date_without_time = date('F j, Y', $timestamp); + $row['end_of_life'] = $date_without_time; + + $table_info->data[] = $row; + } + } + + if ($pdf !== 0) { + $table_info->title = $item['title']; + $table_info->titleclass = 'title_table_pdf'; + $table_info->titlestyle = 'text-align:left;'; + $return_pdf .= html_print_table($table_info, true); + } else { + $table->colspan['data']['cell'] = 3; + $table->cellstyle['data']['cell'] = 'text-align: center;'; + $table->data['data']['cell'] = html_print_table($table_info, true); + } + } + + if ($pdf !== 0) { + return $return_pdf; + } +} + + /** * Function to print to HTML Exception report. * diff --git a/pandora_console/include/functions_reports.php b/pandora_console/include/functions_reports.php index 1fe85aa92b..3da9993933 100755 --- a/pandora_console/include/functions_reports.php +++ b/pandora_console/include/functions_reports.php @@ -814,6 +814,11 @@ function reports_get_report_types($template=false, $not_editor=false) 'name' => __('Agents/Modules status'), ]; + $types['end_of_life'] = [ + 'optgroup' => __('Grouped'), + 'name' => __('End of life'), + ]; + // Only pandora managers have access to the whole database. if (check_acl($config['id_user'], 0, 'PM')) { $types['sql'] = [ diff --git a/pandora_console/operation/agentes/estado_agente.php b/pandora_console/operation/agentes/estado_agente.php index 75b1c6222a..d126b19144 100644 --- a/pandora_console/operation/agentes/estado_agente.php +++ b/pandora_console/operation/agentes/estado_agente.php @@ -169,6 +169,8 @@ $refr = get_parameter('refr', 0); $recursion = get_parameter('recursion', 0); $status = (int) get_parameter('status', -1); $os = (int) get_parameter('os', 0); +$os_version_regex = trim(get_parameter('os_version_regex', '')); +$os_type_regex = trim(get_parameter('os_type_regex', '')); $policies = (array) get_parameter('policies', []); $ag_custom_fields = (array) get_parameter('ag_custom_fields', []); @@ -181,6 +183,10 @@ $onheader = []; $load_filter_id = (int) get_parameter('filter_id', 0); +if (empty($os_type_regex) !== true) { + $os = (int) db_get_value_sql('SELECT id_os FROM tconfig_os WHERE `name` REGEXP "'.$os_type_regex.'"'); +} + if ($load_filter_id > 0) { $user_groups_fl = users_get_groups( $config['id_user'], @@ -402,6 +408,18 @@ $table->data[1][0] = html_print_label_input_block( html_print_select($fields, 'os', $os, '', 'All', 0, true) ); +$table->data[1][1] = html_print_label_input_block( + __('Operating System version').ui_print_help_tip(__('Case insensitive regular expression, e.g. Rocky.* will match the following OS version: Rocky Linux 8.7'), true), + html_print_input_text( + 'os_version_regex', + $os_version_regex, + '', + 35, + 255, + true + ) +); + if (function_exists('policies_get_policies') === true) { $pre_fields = policies_get_policies(false, ['id', 'name']); $fields = []; @@ -410,7 +428,7 @@ if (function_exists('policies_get_policies') === true) { } } -$table->data[1][1] = html_print_label_input_block( +$table->data[2][0] = html_print_label_input_block( __('Policies'), html_print_select($fields, 'policies[]', $policies, '', 'All', 0, true, true) ); @@ -452,8 +470,8 @@ foreach ($custom_fields as $custom_field) { $div_custom_fields .= ''; } -$table->colspan[2][0] = 2; -$table->data[2][0] = ui_toggle( +$table->colspan[3][0] = 2; +$table->data[3][0] = ui_toggle( $div_custom_fields, __('Agent custom fields'), '', @@ -881,6 +899,10 @@ if ($os > 0) { $id_os_sql = ' AND id_os = '.$os; } +if ($os_version_regex !== '') { + $id_os_sql .= ' AND os_version REGEXP \''.$os_version_regex.'\''; +} + if ($all_policies === false && is_array($policies) && count($policies) > 0) { $policies_sql = ' AND tpolicy_agents.id_policy IN ('.implode(',', $policies).')'; } diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql index b44fb54e92..f3828b3204 100644 --- a/pandora_console/pandoradb.sql +++ b/pandora_console/pandoradb.sql @@ -647,6 +647,17 @@ CREATE TABLE IF NOT EXISTS `tconfig_os` ( PRIMARY KEY (`id_os`) ) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; +-- ----------------------------------------------------- +-- Table `tconfig_os_version` +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `tconfig_os_version` ( + `id_os_version` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `product` TEXT, + `version` TEXT, + `end_of_support` VARCHAR(10) DEFAULT NULL, + PRIMARY KEY (`id_os_version`) +) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4; + -- ----------------------------------------------------- -- Table `tcontainer` -- ----------------------------------------------------- diff --git a/pandora_console/pandoradb_data.sql b/pandora_console/pandoradb_data.sql index 82ad9ca638..22db03654e 100644 --- a/pandora_console/pandoradb_data.sql +++ b/pandora_console/pandoradb_data.sql @@ -2823,3 +2823,15 @@ INSERT INTO `tsca` VALUES (29673,'Ensure sudo log file exist INSERT INTO `tmodule_inventory` (`id_module_inventory`, `id_os`, `name`, `description`, `interpreter`, `data_format`, `code`, `block_mode`,`script_mode`) VALUES (41,1,'Security','Hardening plugin for security compliance analysis','','ID;STATUS','',0,2); INSERT INTO `tmodule_inventory` (`id_module_inventory`, `id_os`, `name`, `description`, `interpreter`, `data_format`, `code`, `block_mode`,`script_mode`) VALUES (42,9,'Security','Hardening plugin for security compliance analysis','','ID;STATUS','',0,2); + + +-- +-- Dumping data for table `tconfig_os_version` +-- + +LOCK TABLES `tconfig_os_version` WRITE; +INSERT INTO `tconfig_os_version` (`id_os_version`, `product`, `version`, `end_of_support`) VALUES +(1,'Windows.*','7.*','2020/01/14'), +(2,'Cisco.*','IOS 3.4.3','2017/05/12'), +(3,'Linux.*','Centos 7.*','2022/01/01'); +UNLOCK TABLES; diff --git a/pandora_server/lib/PandoraFMS/Core.pm b/pandora_server/lib/PandoraFMS/Core.pm index ed4e127ade..7050fce514 100644 --- a/pandora_server/lib/PandoraFMS/Core.pm +++ b/pandora_server/lib/PandoraFMS/Core.pm @@ -4073,17 +4073,21 @@ Create a new entry in B optionaly with position information =cut ########################################################################## -sub pandora_create_agent ($$$$$$$$$$;$$$$$$$$$$) { +sub pandora_create_agent ($$$$$$$$$$;$$$$$$$$$$$) { # If parameter event_id is not undef, then create an extended event # related to it instead launch new event. my ($pa_config, $server_name, $agent_name, $address, $group_id, $parent_id, $os_id, $description, $interval, $dbh, $timezone_offset, $longitude, $latitude, $altitude, $position_description, - $custom_id, $url_address, $agent_mode, $alias, $event_id) = @_; + $custom_id, $url_address, $agent_mode, $alias, $event_id, $os_version) = @_; logger ($pa_config, "Server '$server_name' creating agent '$agent_name' address '$address'.", 10); + if (!defined $os_version) { + $os_version = ''; + } + if (!defined($group_id)) { $group_id = pandora_get_agent_group($pa_config, $dbh, $agent_name); if ($group_id <= 0) { @@ -4109,9 +4113,10 @@ sub pandora_create_agent ($$$$$$$$$$;$$$$$$$$$$) { 'url_address' => $url_address, 'timezone_offset' => $timezone_offset, 'alias' => safe_input($alias), - 'update_module_count' => 1, # Force to replicate in metaconsole - }); - + 'os_version' => $os_version, + 'update_module_count' => 1, # Force to replicate in metaconsole + }); + my $agent_id = db_insert ($dbh, 'id_agente', "INSERT INTO tagente $columns", @{$values}); # Save GIS data diff --git a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm index 2703f65113..0239decd60 100644 --- a/pandora_server/lib/PandoraFMS/DiscoveryServer.pm +++ b/pandora_server/lib/PandoraFMS/DiscoveryServer.pm @@ -788,8 +788,8 @@ sub get_recon_credential_macro($$$) { ################################################################################ # Guess the OS using xprobe2 or nmap. ################################################################################ -sub PandoraFMS::Recon::Base::guess_os($$;$) { - my ($self, $device, $string_flag) = @_; +sub PandoraFMS::Recon::Base::guess_os($$;$$$) { + my ($self, $device, $string_flag, $return_version_only) = @_; return $self->{'os_id'}{$device} if defined($self->{'os_id'}{$device}); @@ -810,15 +810,32 @@ sub PandoraFMS::Recon::Base::guess_os($$;$) { if (-x $self->{'pa_config'}->{'nmap'}) { my $return = `"$self->{pa_config}->{nmap}" -sSU -T5 -F -O --osscan-limit $device 2>$DEVNULL`; return OS_OTHER if ($? != 0); - my $str_os; + my ($str_os, $os_version); if ($return =~ /Aggressive OS guesses:(.*?)(?>\(\d+%\),)|^OS details:(.*?)$/mi) { if(defined($1) && $1 ne "") { $str_os = $1; } else { $str_os = $2; } + + my $pandora_os = pandora_get_os($self->{'dbh'}, $str_os); + my $pandora_os_name = pandora_get_os_by_id($self->{'dbh'}, $pandora_os); + + if ($return_version_only == 1) { + if ($str_os =~ /$pandora_os_name/i) { + $os_version = $'; # Get string after matched found OS name. + $os_version =~ s/^\s+//; # Remove leading spaces. + $os_version =~ s/\s+$//; # Remove trailing spaces. + } else { + $os_version = ''; + } + + return $os_version; + + } + return $str_os if is_enabled($string_flag); - return pandora_get_os($self->{'dbh'}, $str_os); + return $pandora_os; } } @@ -1640,6 +1657,10 @@ sub PandoraFMS::Recon::Base::report_scanned_agents($;$) { $os_id = $self->guess_os($data->{'agent'}{'direccion'}); } + if (is_empty($data->{'agent'}{'os_version'})) { + $data->{'agent'}{'os_version'} = $self->guess_os($data->{'agent'}{'direccion'}, undef, 1); + } + $self->call('message', "Agent accepted: ".$data->{'agent'}{'nombre'}, 5); # Agent creation. @@ -1681,7 +1702,7 @@ sub PandoraFMS::Recon::Base::report_scanned_agents($;$) { $os_id, $data->{'agent'}->{'description'}, $data->{'agent'}{'interval'}, $self->{'dbh'}, $data->{'agent'}{'timezone_offset'}, undef, undef, undef, undef, - undef, undef, 1, $data->{'agent'}{'alias'} + undef, undef, 1, $data->{'agent'}{'alias'}, undef, $data->{'agent'}{'os_version'} ); # Add found IP addresses to the agent. diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index 3e8788d21a..f5d42b561c 100755 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -6671,6 +6671,19 @@ sub cli_set_event_storm_protection () { db_do ($dbh, 'UPDATE tconfig SET value=? WHERE token=?', $value, 'event_storm_protection'); } +############################################################################## +# Set existing OS and OS version for a specific agent +# Related option: --agent_set_os +############################################################################## +sub cli_agent_set_os() { + my ($id_agente,$id_os,$os_version) = @ARGV[2..4]; + + my $os_name = get_db_value($dbh, 'SELECT name FROM tconfig_os WHERE id_os = ?',$id_os); + exist_check($id_os,'tconfig_os',$os_name); + + db_process_update($dbh, 'tagente', {'id_os' => $id_os, 'os_version' => $os_version}, {'id_agente' => $id_agente}); +} + ############################################################################## # Return event name given a event id ############################################################################## @@ -8147,7 +8160,11 @@ sub pandora_manage_main ($$$) { elsif ($param eq '--set_event_storm_protection') { param_check($ltotal, 1); cli_set_event_storm_protection(); - } + } + elsif ($param eq '--agent_set_os') { + param_check($ltotal, 3, 1); + cli_agent_set_os(); + } elsif ($param eq '--create_custom_graph') { param_check($ltotal, 11); cli_create_custom_graph();