Merge branch 'ent-6858-Goliat-opensource' into 'develop'
Backup upload See merge request artica/pandorafms!3936
This commit is contained in:
commit
13fa1159ce
|
@ -74,6 +74,10 @@ enterprise/extensions/ipam
|
|||
enterprise/extensions/disabled/visual_console_manager.php
|
||||
enterprise/extensions/visual_console_manager.php
|
||||
pandora_console/extensions/net_tools.php
|
||||
enterprise/godmode/agentes/module_manager_editor_web.php
|
||||
enterprise/include/ajax/web_server_module_debug.php
|
||||
enterprise/include/class/WebServerModuleDebug.class.php
|
||||
enterprise/include/styles/WebServerModuleDebug.css
|
||||
include/lib/WSManager.php
|
||||
include/lib/WebSocketServer.php
|
||||
include/lib/WebSocketUser.php
|
||||
|
|
|
@ -1,22 +1,38 @@
|
|||
<?php
|
||||
/**
|
||||
* Module Manager main script.
|
||||
*
|
||||
* @category Module
|
||||
* @package Pandora FMS
|
||||
* @subpackage Agent Configuration
|
||||
* @version 1.0.0
|
||||
* @license See below
|
||||
*
|
||||
* ______ ___ _______ _______ ________
|
||||
* | __ \.-----.--.--.--| |.-----.----.-----. | ___| | | __|
|
||||
* | __/| _ | | _ || _ | _| _ | | ___| |__ |
|
||||
* |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______|
|
||||
*
|
||||
* ============================================================================
|
||||
* Copyright (c) 2005-2021 Artica Soluciones Tecnologicas
|
||||
* Please see http://pandorafms.org for full contribution list
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation for version 2.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
// Pandora FMS - http://pandorafms.com
|
||||
// ==================================================
|
||||
// Copyright (c) 2005-2021 Artica Soluciones Tecnologicas
|
||||
// Please see http://pandorafms.org for full contribution list
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation for version 2.
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
// You can redefine $url and unset $id_agente to reuse the form. Dirty (hope temporal) hack
|
||||
if (isset($id_agente)) {
|
||||
$url = 'index.php?sec=gagente&sec2=godmode/agentes/configurar_agente&tab=module&id_agente='.$id_agente;
|
||||
} else {
|
||||
$url = 'index.php?sec=gagente&sec2=godmode/agentes/configurar_agente&tab=module';
|
||||
}
|
||||
// You can redefine $url and unset $id_agente to reuse the form. Dirty (hope temporal) hack.
|
||||
$url_id_agente = (isset($id_agente) === true) ? '&id_agente='.$id_agente : '';
|
||||
|
||||
$url = sprintf(
|
||||
'index.php?sec=gagente&sec2=godmode/agentes/configurar_agente&tab=module%s',
|
||||
$url_id_agente
|
||||
);
|
||||
|
||||
enterprise_include('godmode/agentes/module_manager.php');
|
||||
$isFunctionPolicies = enterprise_include_once('include/functions_policies.php');
|
||||
|
@ -56,7 +72,7 @@ echo __('Search').' '.html_print_input_text(
|
|||
);
|
||||
html_print_input_hidden('search', 1);
|
||||
// Search string filter form.
|
||||
if (($policy_page) || (isset($agent))) {
|
||||
if (($policy_page !== false) || (isset($agent) === true)) {
|
||||
echo '<form id="" method="post" action="">';
|
||||
} else {
|
||||
echo '<form id="create_module_type" method="post" action="'.$url.'">';
|
||||
|
@ -73,25 +89,31 @@ echo '</form>';
|
|||
$network_available = db_get_sql(
|
||||
'SELECT count(*)
|
||||
FROM tserver
|
||||
WHERE server_type = 1'
|
||||
WHERE server_type = '.SERVER_TYPE_NETWORK
|
||||
);
|
||||
// POSTGRESQL AND ORACLE COMPATIBLE.
|
||||
$wmi_available = db_get_sql(
|
||||
'SELECT count(*)
|
||||
FROM tserver
|
||||
WHERE server_type = 6'
|
||||
WHERE server_type = '.SERVER_TYPE_WMI
|
||||
);
|
||||
// POSTGRESQL AND ORACLE COMPATIBLE.
|
||||
$plugin_available = db_get_sql(
|
||||
'SELECT count(*)
|
||||
FROM tserver
|
||||
WHERE server_type = 4'
|
||||
WHERE server_type = '.SERVER_TYPE_PLUGIN
|
||||
);
|
||||
// POSTGRESQL AND ORACLE COMPATIBLE.
|
||||
$prediction_available = db_get_sql(
|
||||
'SELECT count(*)
|
||||
FROM tserver
|
||||
WHERE server_type = 5'
|
||||
WHERE server_type = '.SERVER_TYPE_PREDICTION
|
||||
);
|
||||
// POSTGRESQL AND ORACLE COMPATIBLE.
|
||||
$web_available = db_get_sql(
|
||||
'SELECT count(*)
|
||||
FROM tserver
|
||||
WHERE server_type = '.SERVER_TYPE_WEB
|
||||
);
|
||||
// POSTGRESQL AND ORACLE COMPATIBLE.
|
||||
// Development mode to use all servers.
|
||||
|
@ -122,6 +144,10 @@ if ($prediction_available) {
|
|||
$modules['predictionserver'] = __('Create a new prediction server module');
|
||||
}
|
||||
|
||||
if ($web_available) {
|
||||
$modules['webserver'] = __('Create a new web Server module');
|
||||
}
|
||||
|
||||
if (enterprise_installed()) {
|
||||
set_enterprise_module_types($modules);
|
||||
}
|
||||
|
@ -298,6 +324,7 @@ if ($module_action === 'delete') {
|
|||
switch ($config['dbtype']) {
|
||||
case 'mysql':
|
||||
case 'postgresql':
|
||||
default:
|
||||
$result = db_process_sql_delete(
|
||||
'tagente_estado',
|
||||
['id_agente_modulo' => $id_agent_module_del]
|
||||
|
@ -388,10 +415,8 @@ if ($module_action === 'delete') {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Check for errors.
|
||||
if ($error != 0) {
|
||||
} else {
|
||||
if ((int) $error == 0) {
|
||||
$count_correct_delete_modules++;
|
||||
}
|
||||
}
|
||||
|
@ -489,6 +514,7 @@ switch ($sortField) {
|
|||
switch ($config['dbtype']) {
|
||||
case 'mysql':
|
||||
case 'postgresql':
|
||||
default:
|
||||
$order[] = [
|
||||
'field' => 'tagente_modulo.nombre',
|
||||
'order' => 'ASC',
|
||||
|
@ -509,6 +535,7 @@ switch ($sortField) {
|
|||
switch ($config['dbtype']) {
|
||||
case 'mysql':
|
||||
case 'postgresql':
|
||||
default:
|
||||
$order[] = [
|
||||
'field' => 'tagente_modulo.nombre',
|
||||
'order' => 'DESC',
|
||||
|
@ -523,6 +550,10 @@ switch ($sortField) {
|
|||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Do none.
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -543,6 +574,10 @@ switch ($sortField) {
|
|||
'order' => 'DESC',
|
||||
];
|
||||
break;
|
||||
|
||||
default:
|
||||
// Do none.
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -563,6 +598,10 @@ switch ($sortField) {
|
|||
'order' => 'DESC',
|
||||
];
|
||||
break;
|
||||
|
||||
default:
|
||||
// Do none.
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -583,6 +622,10 @@ switch ($sortField) {
|
|||
'order' => 'DESC',
|
||||
];
|
||||
break;
|
||||
|
||||
default:
|
||||
// Do none.
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -598,6 +641,7 @@ switch ($sortField) {
|
|||
switch ($config['dbtype']) {
|
||||
case 'mysql':
|
||||
case 'postgresql':
|
||||
default:
|
||||
$order[] = [
|
||||
'field' => 'nombre',
|
||||
'order' => 'ASC',
|
||||
|
@ -622,7 +666,7 @@ if (!empty($order)) {
|
|||
|
||||
$first = true;
|
||||
foreach ($order as $ord) {
|
||||
if ($first) {
|
||||
if ($first === true) {
|
||||
$first = false;
|
||||
} else {
|
||||
$order_sql .= ',';
|
||||
|
@ -635,31 +679,35 @@ foreach ($order as $ord) {
|
|||
$limit = (int) $config['block_size'];
|
||||
$offset = (int) get_parameter('offset');
|
||||
|
||||
$params = ($checked) ? 'tagente_modulo.*, tmodule_group.*' : implode(
|
||||
',',
|
||||
[
|
||||
'tagente_modulo.id_agente_modulo',
|
||||
'id_tipo_modulo',
|
||||
'descripcion',
|
||||
'nombre',
|
||||
'max',
|
||||
'min',
|
||||
'module_interval',
|
||||
'id_modulo',
|
||||
'id_module_group',
|
||||
'disabled',
|
||||
'max_warning',
|
||||
'min_warning',
|
||||
'str_warning',
|
||||
'max_critical',
|
||||
'min_critical',
|
||||
'str_critical',
|
||||
'quiet',
|
||||
'critical_inverse',
|
||||
'warning_inverse',
|
||||
'id_policy_module',
|
||||
]
|
||||
);
|
||||
if ((bool) $checked === true) {
|
||||
$params = 'tagente_modulo.*, tmodule_group.*';
|
||||
} else {
|
||||
$params = implode(
|
||||
',',
|
||||
[
|
||||
'tagente_modulo.id_agente_modulo',
|
||||
'id_tipo_modulo',
|
||||
'descripcion',
|
||||
'nombre',
|
||||
'max',
|
||||
'min',
|
||||
'module_interval',
|
||||
'id_modulo',
|
||||
'id_module_group',
|
||||
'disabled',
|
||||
'max_warning',
|
||||
'min_warning',
|
||||
'str_warning',
|
||||
'max_critical',
|
||||
'min_critical',
|
||||
'str_critical',
|
||||
'quiet',
|
||||
'critical_inverse',
|
||||
'warning_inverse',
|
||||
'id_policy_module',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
$where = sprintf('delete_pending = 0 AND id_agente = %s', $id_agente);
|
||||
|
||||
|
@ -686,7 +734,11 @@ if (isset($config['paginate_module'])) {
|
|||
|
||||
if ($paginate_module) {
|
||||
if (!isset($limit_sql)) {
|
||||
$limit_sql = " LIMIT $offset, $limit ";
|
||||
$limit_sql = sprintf(
|
||||
'LIMIT %s, %s',
|
||||
$offset,
|
||||
$limit
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$limit_sql = '';
|
||||
|
@ -732,7 +784,13 @@ if ($modules === false) {
|
|||
}
|
||||
|
||||
// Prepare pagination.
|
||||
$url = '?'.'sec=gagente&'.'tab=module&'.'sec2=godmode/agentes/configurar_agente&'.'id_agente='.$id_agente.'&'.'sort_field='.$sortField.'&'.'&sort='.$sort.'&'.'search_string='.urlencode($search_string);
|
||||
$url = sprintf(
|
||||
'?sec=gagente&tab=module&sec2=godmode/agentes/configurar_agente&id_agente=%s&sort_field=%s&sort=%s&search_string=%s',
|
||||
$id_agente,
|
||||
$sortField,
|
||||
$sort,
|
||||
urlencode($search_string)
|
||||
);
|
||||
|
||||
if ($paginate_module) {
|
||||
ui_pagination($total_modules, $url);
|
||||
|
|
|
@ -682,6 +682,22 @@ switch ($moduletype) {
|
|||
include 'module_manager_editor_wmi.php';
|
||||
break;
|
||||
|
||||
case 'webserver':
|
||||
case MODULE_WEB:
|
||||
$moduletype = MODULE_WEB;
|
||||
// Remove content of $ip_target when it is ip_agent because
|
||||
// it is used as HTTP auth (server) ....ONLY IN NEW MODULE!!!
|
||||
if (empty($id_agent_module)
|
||||
&& ($ip_target === agents_get_address($id_agente))
|
||||
) {
|
||||
$ip_target = '';
|
||||
}
|
||||
|
||||
$categories = [9];
|
||||
include 'module_manager_editor_common.php';
|
||||
include 'module_manager_editor_web.php';
|
||||
break;
|
||||
|
||||
// WARNING: type 7 is reserved on enterprise.
|
||||
default:
|
||||
if (enterprise_include(
|
||||
|
|
|
@ -0,0 +1,468 @@
|
|||
<?php
|
||||
/**
|
||||
* Web Module Editor for Module Manager.
|
||||
*
|
||||
* @category Module manager
|
||||
* @package Pandora FMS
|
||||
* @subpackage Module manager
|
||||
* @version 1.0.0
|
||||
* @license See below
|
||||
*
|
||||
* ______ ___ _______ _______ ________
|
||||
* | __ \.-----.--.--.--| |.-----.----.-----. | ___| | | __|
|
||||
* | __/| _ | | _ || _ | _| _ | | ___| |__ |
|
||||
* |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______|
|
||||
*
|
||||
* ============================================================================
|
||||
* Copyright (c) 2005-2021 Artica Soluciones Tecnologicas
|
||||
* Please see http://pandorafms.org for full contribution list
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation for version 2.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
// Begin.
|
||||
enterprise_include_once('include/functions_policies.php');
|
||||
|
||||
$disabledBecauseInPolicy = false;
|
||||
$disabledTextBecauseInPolicy = '';
|
||||
$classdisabledBecauseInPolicy = '';
|
||||
$page = get_parameter('page', '');
|
||||
if (strstr($page, 'policy_modules') === false) {
|
||||
if ($config['enterprise_installed']) {
|
||||
if (policies_is_module_linked($id_agent_module) == 1) {
|
||||
$disabledBecauseInPolicy = 1;
|
||||
} else {
|
||||
$disabledBecauseInPolicy = 0;
|
||||
}
|
||||
} else {
|
||||
$disabledBecauseInPolicy = false;
|
||||
}
|
||||
|
||||
if ($disabledBecauseInPolicy) {
|
||||
$disabledTextBecauseInPolicy = 'disabled = "disabled"';
|
||||
$classdisabledBecauseInPolicy = 'readonly';
|
||||
}
|
||||
}
|
||||
|
||||
global $id_agente;
|
||||
|
||||
$extra_title = __('Web server module');
|
||||
|
||||
// Div for modal.
|
||||
html_print_div(
|
||||
[
|
||||
'id' => 'modal',
|
||||
'style' => 'display: none;',
|
||||
]
|
||||
);
|
||||
|
||||
require_once $config['homedir'].'/include/ajax/web_server_module_debug.php';
|
||||
|
||||
define('ID_NETWORK_COMPONENT_TYPE', 7);
|
||||
|
||||
if (!$tcp_port && !$id_agent_module) {
|
||||
$tcp_port = 80;
|
||||
}
|
||||
|
||||
// plugin_server is the browser id
|
||||
if ($plugin_user == '' && !$id_agent_module) {
|
||||
$plugin_user = get_product_name().' / Webcheck';
|
||||
}
|
||||
|
||||
// plugin_server is the referer
|
||||
if ($plugin_pass == '' && !$id_agent_module) {
|
||||
$plugin_pass = 1;
|
||||
}
|
||||
|
||||
if (empty($update_module_id)) {
|
||||
// Function in module_manager_editor_common.php
|
||||
add_component_selection(ID_NETWORK_COMPONENT_TYPE);
|
||||
} else {
|
||||
// TODO: Print network component if available
|
||||
}
|
||||
|
||||
$data = [];
|
||||
$data[0] = __('Web checks');
|
||||
|
||||
$adopt = false;
|
||||
if (isset($id_agent_module)) {
|
||||
$adopt = enterprise_hook('policies_is_module_adopt', [$id_agent_module]);
|
||||
}
|
||||
|
||||
$id_policy_module = (int) get_parameter('id_policy_module', '');
|
||||
if ($id_policy_module) {
|
||||
$module = enterprise_hook('policies_get_module', [$id_policy_module]);
|
||||
$plugin_parameter = $module['plugin_parameter'];
|
||||
}
|
||||
|
||||
if ((bool) $adopt === false) {
|
||||
$data[1] = html_print_textarea(
|
||||
'plugin_parameter',
|
||||
15,
|
||||
65,
|
||||
$plugin_parameter,
|
||||
$disabledTextBecauseInPolicy,
|
||||
true
|
||||
);
|
||||
} else {
|
||||
$data[1] = html_print_textarea(
|
||||
'plugin_parameter',
|
||||
15,
|
||||
65,
|
||||
$plugin_parameter,
|
||||
false,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
$table_simple->colspan['web_checks'][1] = 2;
|
||||
|
||||
// Disable debug button if module has not started.
|
||||
if ($id_agent_module > 0
|
||||
&& db_get_value_filter(
|
||||
'debug_content',
|
||||
'tagente_modulo',
|
||||
['id_agente_modulo' => $id_agent_module]
|
||||
) !== null
|
||||
) {
|
||||
$disableDebug = false;
|
||||
$hintDebug = __('Debug remotely this module');
|
||||
} else {
|
||||
$disableDebug = true;
|
||||
$hintDebug = __('Debug this module once it has been initialized');
|
||||
}
|
||||
|
||||
$suc_err_check = ' <span id="check_conf_suc" class="checks invisible">'.html_print_image('/images/ok.png', true).'</span>';
|
||||
$suc_err_check .= ' <span id="check_conf_err" class="checks invisible">'.html_print_image('/images/error_red.png', true).'</span>';
|
||||
$data[2] = html_print_button(
|
||||
__('Load basic'),
|
||||
'btn_loadbasic',
|
||||
false,
|
||||
'',
|
||||
'class="sub config"',
|
||||
true
|
||||
).ui_print_help_tip(__('Load a basic structure on Web Checks'), true);
|
||||
$data[2] .= '<br><br>'.html_print_button(
|
||||
__('Check'),
|
||||
'btn_checkconf',
|
||||
false,
|
||||
'',
|
||||
'class="sub upd"',
|
||||
true
|
||||
).ui_print_help_tip(__('Check the correct structure of the WebCheck'), true).$suc_err_check;
|
||||
$data[2] .= '<br><br>'.html_print_button(
|
||||
__('Debug'),
|
||||
'btn_debugModule',
|
||||
$disableDebug,
|
||||
'',
|
||||
'class="sub config" onClick="loadDebugWindow()"',
|
||||
true
|
||||
).ui_print_help_tip($hintDebug, true);
|
||||
|
||||
|
||||
push_table_simple($data, 'web_checks');
|
||||
|
||||
$http_checks_type = [
|
||||
0 => 'Anyauth',
|
||||
1 => 'NTLM',
|
||||
2 => 'DIGEST',
|
||||
3 => 'BASIC',
|
||||
];
|
||||
|
||||
$data = [];
|
||||
$data[0] = __('Check type');
|
||||
$data[1] = html_print_select($http_checks_type, 'tcp_port', $tcp_port, false, '', '', true, false, false);
|
||||
|
||||
push_table_advanced($data, 'web_0');
|
||||
|
||||
$data = [];
|
||||
$data[0] = __('Requests');
|
||||
$data[1] = html_print_input_text('plugin_pass', $plugin_pass, '', 10, 0, true, $disabledBecauseInPolicy, false, '', $classdisabledBecauseInPolicy);
|
||||
$data[2] = '';
|
||||
$data[3] = __('Agent browser id');
|
||||
$data[4] = html_print_input_text('plugin_user', $plugin_user, '', 30, 0, true, $disabledBecauseInPolicy, false, '', $classdisabledBecauseInPolicy);
|
||||
|
||||
push_table_advanced($data, 'web_1');
|
||||
|
||||
$data = [];
|
||||
$data[0] = __('HTTP auth (login)');
|
||||
$data[1] = html_print_input_text('http_user', $plugin_parameter_http_user, '', 10, 0, true, $disabledBecauseInPolicy, false, '', $classdisabledBecauseInPolicy);
|
||||
$data[2] = '';
|
||||
$data[3] = __('HTTP auth (password)');
|
||||
$data[4] = html_print_input_password('http_pass', $plugin_parameter_http_pass, '', 30, 0, true, $disabledBecauseInPolicy, false, '', $classdisabledBecauseInPolicy);
|
||||
|
||||
push_table_advanced($data, 'web_2');
|
||||
|
||||
$data = [];
|
||||
|
||||
$data[0] = __('Proxy URL');
|
||||
$data[1] = html_print_input_text('snmp_oid', $snmp_oid, '', 30, 0, true, $disabledBecauseInPolicy, false, '', $classdisabledBecauseInPolicy);
|
||||
$data[2] = $data[3] = $data[4] = '';
|
||||
push_table_advanced($data, 'web_3');
|
||||
|
||||
$data = [];
|
||||
|
||||
$data[0] = __('Proxy auth (login)');
|
||||
$data[1] = html_print_input_text('tcp_send', $tcp_send, '', 30, 0, true, $disabledBecauseInPolicy, false, '', $classdisabledBecauseInPolicy);
|
||||
|
||||
$data[2] = '';
|
||||
$data[3] = __('Proxy auth (pass)');
|
||||
$data[4] = html_print_input_password('tcp_rcv', $tcp_rcv, '', 30, 0, true, $disabledBecauseInPolicy, false, '', $classdisabledBecauseInPolicy);
|
||||
|
||||
push_table_advanced($data, 'web_4');
|
||||
|
||||
$data = [];
|
||||
|
||||
$data[0] = __('Proxy auth (server)');
|
||||
$data[1] = html_print_input_text('ip_target', $ip_target, '', 30, 100, true, $disabledBecauseInPolicy, false, '', $classdisabledBecauseInPolicy);
|
||||
|
||||
$data[2] = '';
|
||||
$data[3] = __('Proxy auth (realm)');
|
||||
$data[4] = html_print_input_text('snmp_community', $snmp_community, '', 30, 100, true, $disabledBecauseInPolicy, false, '', $classdisabledBecauseInPolicy);
|
||||
|
||||
push_table_advanced($data, 'web_5');
|
||||
|
||||
// Add some strings to be used from javascript
|
||||
$texts = [
|
||||
'lines_before_begin' => __('First line must be "task_begin"'),
|
||||
'missed_begin' => __('Webchecks configuration is empty'),
|
||||
'missed_end' => __('Last line must be "task_end"'),
|
||||
'lines_after_end' => __('Last line must be "task_end"'),
|
||||
'unknown_token' => __("There is a line with a unknown token 'token_fail'."),
|
||||
'missed_get_post' => __("There isn't get or post"),
|
||||
'correct' => __('Web checks are built correctly'),
|
||||
];
|
||||
|
||||
foreach ($texts as $code => $text) {
|
||||
echo '<span class="invisible" id="'.$code.'">'.$text.'</span>';
|
||||
}
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
var supported_tokens = [
|
||||
"task_begin",
|
||||
"post",
|
||||
"variable_name",
|
||||
"variable_value",
|
||||
"cookie",
|
||||
"resource",
|
||||
"get",
|
||||
"check_string",
|
||||
"check_not_string",
|
||||
"get_content_advanced",
|
||||
"get_content",
|
||||
"debug",
|
||||
"task_end",
|
||||
"head",
|
||||
"http_auth_user",
|
||||
"http_auth_pass"
|
||||
];
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
var plugin_parameter = $("#textarea_plugin_parameter");
|
||||
var http_auth_user = $('#text-http_user');
|
||||
var http_auth_pass = $('#password-http_pass');
|
||||
|
||||
$(plugin_parameter).keyup(function() {
|
||||
|
||||
// Check and fill textbox.
|
||||
if ($(plugin_parameter).val() == '') {
|
||||
$('#button-btn_loadbasic').removeAttr('disabled');
|
||||
} else {
|
||||
$('#button-btn_loadbasic').attr('disabled', 'disabled');
|
||||
}
|
||||
|
||||
// Update http_auth_user from conf data
|
||||
var http_auth_user_value = get_module_token_from_config('http_auth_user', plugin_parameter, "\n");
|
||||
if (http_auth_user_value != "") {
|
||||
http_auth_user.val(http_auth_user_value);
|
||||
}
|
||||
|
||||
// Update http_auth_pass from conf data
|
||||
var http_auth_pass_value = get_module_token_from_config('http_auth_pass', plugin_parameter, "\n");
|
||||
if (http_auth_pass_value != "") {
|
||||
http_auth_pass.val(http_auth_pass_value);
|
||||
}
|
||||
});
|
||||
|
||||
$('#button-btn_loadbasic').click(function() {
|
||||
if ($(plugin_parameter).val() != '') {
|
||||
return;
|
||||
}
|
||||
|
||||
$(plugin_parameter).val(
|
||||
'task_begin\ncookie 0\nresource 0\ntask_end');
|
||||
|
||||
$('#button-btn_loadbasic').attr('disabled', 'disabled');
|
||||
|
||||
// Hide success and error indicators
|
||||
$('.checks').hide();
|
||||
});
|
||||
|
||||
$('#button-btn_checkconf').click(function() {
|
||||
var msg_error = '';
|
||||
|
||||
if (plugin_parameter.val() == '') {
|
||||
msg_error = 'missed_begin';
|
||||
} else {
|
||||
var lines = plugin_parameter.val().split("\n");
|
||||
|
||||
var started = false;
|
||||
var ended = false;
|
||||
var lines_after_end = false;
|
||||
var lines_before_begin = false;
|
||||
var token_fail = false;
|
||||
var token_get_post = false;
|
||||
var token_check = true;
|
||||
var str_token_fail = '';
|
||||
|
||||
for (i = 0; i < lines.length; i++) {
|
||||
if (lines[i].match(/^\s*$/)) {
|
||||
// Empty line
|
||||
continue;
|
||||
} else if (!started) {
|
||||
if (lines[i].match(/^task_begin\s*$/)) {
|
||||
started = true;
|
||||
} else {
|
||||
// Found a not empty line before task_begin
|
||||
lines_before_begin = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lines[i].match(/^task_end\s*$/)) {
|
||||
ended = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
//Check token is correct
|
||||
if (!lines[i].match(/^([\s])*[#]/)) {
|
||||
|
||||
var token = lines[i].match(/^([^\s]+)\s*/);
|
||||
|
||||
if (typeof(token) == 'object') {
|
||||
token = token[1];
|
||||
|
||||
if ((!token_get_post) && (token == 'get' || token == 'post' || token == 'header')) {
|
||||
token_get_post = true;
|
||||
continue;
|
||||
}
|
||||
if (token == 'check_string') {
|
||||
if (token_get_post) {
|
||||
token_check = true;
|
||||
continue;
|
||||
} else {
|
||||
token_check = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ($.inArray(token, supported_tokens) == -1) {
|
||||
token_fail = true;
|
||||
str_token_fail = token;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var msg_error = '';
|
||||
|
||||
if (token_fail) {
|
||||
var temp_msg = $("#unknown_token").html();
|
||||
temp_msg = temp_msg.replace(/['](.*)[']/, "'" + str_token_fail + "'");
|
||||
|
||||
$("#unknown_token").html(temp_msg);
|
||||
|
||||
msg_error = 'unknown_token';
|
||||
} else if (lines_before_begin) {
|
||||
msg_error = 'lines_before_begin';
|
||||
} else if (!started) {
|
||||
msg_error = 'missed_begin';
|
||||
} else if (!ended) {
|
||||
msg_error = 'missed_end';
|
||||
} else if (lines_after_end) {
|
||||
msg_error = 'lines_after_end';
|
||||
} else if (!token_check) {
|
||||
msg_error = 'missed_get_post';
|
||||
} else {
|
||||
msg_error = 'correct';
|
||||
}
|
||||
|
||||
|
||||
if (msg_error == 'correct') {
|
||||
$('#check_conf_suc').find('img').eq(0)
|
||||
.attr('title', $('#' + msg_error).html());
|
||||
|
||||
$('#check_conf_err').hide();
|
||||
$('#check_conf_suc').show();
|
||||
} else {
|
||||
$('#check_conf_err').find('img').eq(0)
|
||||
.attr('title', $('#' + msg_error).html());
|
||||
|
||||
$('#check_conf_suc').hide();
|
||||
$('#check_conf_err').show();
|
||||
}
|
||||
});
|
||||
|
||||
$(plugin_parameter).trigger('keyup');
|
||||
|
||||
http_auth_user.keyup(function() {
|
||||
config = plugin_parameter.val();
|
||||
if (config.search("http_auth_user") == -1) {
|
||||
var http_auth_user_end =
|
||||
"http_auth_user " + this.value + "\n" + "task_end" + "\n";
|
||||
plugin_parameter.val(config.replace(/^task_end.*$/m, http_auth_user_end));
|
||||
} else {
|
||||
plugin_parameter.val(
|
||||
config.replace(/^http_auth_user.*$/m, "http_auth_user " + this.value)
|
||||
);
|
||||
// Hide success and error indicators
|
||||
$(".checks").hide();
|
||||
}
|
||||
});
|
||||
|
||||
http_auth_pass.keyup(function() {
|
||||
config = plugin_parameter.val();
|
||||
if (config.search("http_auth_pass") == -1) {
|
||||
var http_auth_pass_end =
|
||||
"http_auth_pass " + this.value + "\n" + "task_end" + "\n";
|
||||
plugin_parameter.val(config.replace(/^task_end.*$/m, http_auth_pass_end));
|
||||
} else {
|
||||
plugin_parameter.val(
|
||||
config.replace(/^http_auth_pass.*$/m, "http_auth_pass " + this.value)
|
||||
);
|
||||
// Hide success and error indicators
|
||||
$(".checks").hide();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function get_module_token_from_config(token_name, plugin_parameter, separator) {
|
||||
var return_var = "";
|
||||
if(token_name == null || token_name == '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
data = plugin_parameter.val().split(separator);
|
||||
len = data.length;
|
||||
for (i = 0; i < len; i++) {
|
||||
if (data[i][0] == "#") continue;
|
||||
tokens = data[i].split(" ");
|
||||
if (tokens.length == 0) continue;
|
||||
token = tokens.shift();
|
||||
if (token == token_name ) return_var = tokens.join(" ");
|
||||
}
|
||||
|
||||
return_var = $.trim(return_var);
|
||||
|
||||
return return_var;
|
||||
}
|
||||
|
||||
</script>
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
/**
|
||||
* Web Server Module Debug ajax controller.
|
||||
*
|
||||
* @category Web Server Module Debug
|
||||
* @package Pandora FMS
|
||||
* @subpackage Module Debug
|
||||
* @version 1.0.0
|
||||
* @license See below
|
||||
*
|
||||
* ______ ___ _______ _______ ________
|
||||
* | __ \.-----.--.--.--| |.-----.----.-----. | ___| | | __|
|
||||
* | __/| _ | | _ || _ | _| _ | | ___| |__ |
|
||||
* |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______|
|
||||
*
|
||||
* ============================================================================
|
||||
* Copyright (c) 2005-2021 Artica Soluciones Tecnologicas
|
||||
* Please see http://pandorafms.org for full contribution list
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation for version 2.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
// Begin.
|
||||
global $config;
|
||||
global $id_agent_module;
|
||||
// Module Debug Class.
|
||||
require_once $config['homedir'].'/include/class/WebServerModuleDebug.class.php';
|
||||
|
||||
// This page.
|
||||
$ajaxPage = $config['homedir'].'/include/ajax/web_server_module_debug';
|
||||
|
||||
// Control call flow for debug window.
|
||||
try {
|
||||
// Return of id of the agent module in AJAX.
|
||||
if (is_ajax()) {
|
||||
$id_agent_module = get_parameter('idAgentModule');
|
||||
}
|
||||
|
||||
// User access and validation is being processed on class constructor.
|
||||
$obj = new WebServerModuleDebug($ajaxPage, $id_agent_module);
|
||||
} catch (Exception $e) {
|
||||
if (is_ajax()) {
|
||||
echo json_encode(['error' => '[WebServerModuleDebug]'.$e->getMessage() ]);
|
||||
exit;
|
||||
} else {
|
||||
echo '[WebServerModuleDebug]'.$e->getMessage();
|
||||
}
|
||||
|
||||
// Stop this execution, but continue 'globally'.
|
||||
return;
|
||||
}
|
||||
|
||||
// AJAX controller.
|
||||
if (is_ajax()) {
|
||||
$method = get_parameter('method');
|
||||
|
||||
if (method_exists($obj, $method) === true) {
|
||||
$obj->{$method}();
|
||||
} else {
|
||||
$obj->error('Method not found. ['.$method.']');
|
||||
}
|
||||
|
||||
// Stop any execution.
|
||||
exit;
|
||||
} else {
|
||||
// Run.
|
||||
$obj->run();
|
||||
}
|
|
@ -0,0 +1,407 @@
|
|||
<?php
|
||||
/**
|
||||
* WebServer Module debug feature.
|
||||
*
|
||||
* @category Class
|
||||
* @package Pandora FMS
|
||||
* @subpackage Web Server Module
|
||||
* @version 1.0.0
|
||||
* @license See below
|
||||
*
|
||||
* ______ ___ _______ _______ ________
|
||||
* | __ \.-----.--.--.--| |.-----.----.-----. | ___| | | __|
|
||||
* | __/| _ | | _ || _ | _| _ | | ___| |__ |
|
||||
* |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______|
|
||||
*
|
||||
* ============================================================================
|
||||
* Copyright (c) 2005-2020 Artica Soluciones Tecnologicas
|
||||
* Please see http://pandorafms.org for full contribution list
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation for version 2.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
// Begin.
|
||||
global $config;
|
||||
|
||||
require_once $config['homedir'].'/godmode/wizards/Wizard.main.php';
|
||||
|
||||
/**
|
||||
* Class WebServerModuleDebug.
|
||||
*/
|
||||
class WebServerModuleDebug extends Wizard
|
||||
{
|
||||
|
||||
/**
|
||||
* Controller Url.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $ajaxController;
|
||||
|
||||
/**
|
||||
* Timeout for HTTP requests.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
private $requestTimeout;
|
||||
|
||||
/**
|
||||
* CURL Query.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $query;
|
||||
|
||||
/**
|
||||
* Id of the current module.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
private $idAgentModule;
|
||||
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param string $ajaxController Ajax Page Controller.
|
||||
* @param integer $idAgentModule Id of the module.
|
||||
*/
|
||||
public function __construct(string $ajaxController, int $idAgentModule)
|
||||
{
|
||||
global $config;
|
||||
|
||||
// Check access.
|
||||
check_login();
|
||||
|
||||
if (! check_acl($config['id_user'], 0, 'AR')) {
|
||||
db_pandora_audit(
|
||||
'ACL Violation',
|
||||
'Trying to access event viewer'
|
||||
);
|
||||
|
||||
if (is_ajax()) {
|
||||
echo json_encode(['error' => 'noaccess']);
|
||||
}
|
||||
|
||||
include 'general/noaccess.php';
|
||||
exit;
|
||||
}
|
||||
|
||||
// Parameter assigments.
|
||||
$this->ajaxController = $ajaxController;
|
||||
$this->query = '';
|
||||
$this->idAgentModule = $idAgentModule;
|
||||
// Hardcoded request timeout.
|
||||
$this->requestTimeout = 15;
|
||||
|
||||
return $this;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Run Module Debug window.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
// Added all necessary basic files for QueryResult.
|
||||
ui_require_css_file('ace');
|
||||
ui_require_javascript_file('ace', 'include/javascript/ace/');
|
||||
// Load Javascript.
|
||||
$this->loadJS();
|
||||
// CSS.
|
||||
ui_require_css_file('wizard');
|
||||
ui_require_css_file('discovery');
|
||||
// Specific CSS for this feature.
|
||||
ui_require_css_file('WebServerModuleDebug', '/include/styles/', true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Show the modal with the QueryResult.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function showWebServerDebug()
|
||||
{
|
||||
// Show QueryResult editor.
|
||||
ui_query_result_editor('webserverdebug');
|
||||
// Spinner for wait loads.
|
||||
html_print_div(
|
||||
[
|
||||
'id' => 'WebServerDebugSpinner',
|
||||
'style' => 'visibility: hidden;',
|
||||
'content' => __('Performing query. Please wait.').' '.html_print_image('images/spinner.gif', true),
|
||||
]
|
||||
);
|
||||
?>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
// Query section
|
||||
var query = ace.edit("webserverdebug_editor");
|
||||
let queryDefined = "<?php echo $this->defineQuery(); ?>";
|
||||
let queryRegex = /([-]+[a-zA-Z]\s)|(([-]{2})+[a-z]+[-]*[a-z]*)/g;
|
||||
query.setValue(queryDefined.replace(queryRegex, "\n$&"));
|
||||
query.clearSelection();
|
||||
// Result section
|
||||
var results = ace.edit("webserverdebug_view");
|
||||
var text = '';
|
||||
results.setTheme("ace/theme/textmate");
|
||||
results.session.setMode("ace/mode/json");
|
||||
results.renderer.setShowGutter(false);
|
||||
results.setReadOnly(true);
|
||||
results.setShowPrintMargin(false);
|
||||
|
||||
$("#submit-execute_query").click(function() {
|
||||
// Show the spinner.
|
||||
showSpinner(true);
|
||||
// Empty the results container.
|
||||
results.setValue("");
|
||||
// Get the entire text.
|
||||
text = query.getValue();
|
||||
// There are not values in the query section.
|
||||
if (text === null || text === undefined) {
|
||||
results.setValue('<?php echo __('No results'); ?>');
|
||||
results.clearSelection();
|
||||
// Hide spinner.
|
||||
showSpinner(false);
|
||||
return;
|
||||
}
|
||||
// Clean the carriage jumps.
|
||||
text = text.split("\n").join("");
|
||||
// Call to the method for execute the command.
|
||||
$.ajax({
|
||||
method: "post",
|
||||
url: "<?php echo ui_get_full_url('ajax.php', false, false, false); ?>",
|
||||
data: {
|
||||
page: "<?php echo $this->ajaxController; ?>",
|
||||
method: "executeCommand",
|
||||
text: text,
|
||||
idAgentModule: "<?php echo $this->idAgentModule; ?>",
|
||||
},
|
||||
datatype: "json",
|
||||
success: function(result) {
|
||||
results.setValue(result);
|
||||
},
|
||||
error: function(e) {
|
||||
results.setValue('<?php echo __('Error performing execution'); ?>');
|
||||
},
|
||||
complete: function() {
|
||||
results.clearSelection();
|
||||
showSpinner(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Definition of the query
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function defineQuery()
|
||||
{
|
||||
// Get the value of the debug_content.
|
||||
$outputDebugQuery = db_get_value_filter(
|
||||
'debug_content',
|
||||
'tagente_modulo',
|
||||
[
|
||||
'id_agente_modulo' => $this->idAgentModule,
|
||||
]
|
||||
);
|
||||
|
||||
$this->query = ($outputDebugQuery !== false) ? $outputDebugQuery : __('Please, wait for a first execution of module');
|
||||
|
||||
return $this->query;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Perform the cURL execution.
|
||||
*
|
||||
* @return void
|
||||
* @throws Exception $e Error message.
|
||||
*/
|
||||
public function executeCommand()
|
||||
{
|
||||
try {
|
||||
$executionForPerform = io_safe_output(get_parameter('text'));
|
||||
// If the execution comes empty.
|
||||
if (empty($executionForPerform) === true) {
|
||||
throw new Exception('Execution failed');
|
||||
}
|
||||
|
||||
// For security reasons, only allow the 'curl' command.
|
||||
$executionForPerform = strstr($executionForPerform, 'curl');
|
||||
// Avoid pipes or concatenation of commands.
|
||||
$unallowedChars = [
|
||||
'|',
|
||||
'&',
|
||||
'||',
|
||||
'&&',
|
||||
';',
|
||||
'\n',
|
||||
];
|
||||
$executionForPerform = str_replace(
|
||||
$unallowedChars,
|
||||
' ',
|
||||
$executionForPerform
|
||||
);
|
||||
// Set execution timeout.
|
||||
$executionForPerform .= sprintf(
|
||||
$executionForPerform.' -m %d',
|
||||
$this->requestTimeout
|
||||
);
|
||||
|
||||
// Perform the execution.
|
||||
system($executionForPerform, $returnCode);
|
||||
// If execution does not got well.
|
||||
if ($returnCode != 0) {
|
||||
switch ($returnCode) {
|
||||
case '2':
|
||||
throw new Exception('Failed to initialize. Review the syntax.');
|
||||
|
||||
case '3':
|
||||
throw new Exception('URL malformed. The syntax was not correct.');
|
||||
|
||||
case '5':
|
||||
throw new Exception('Couldn\'t resolve proxy. The given proxy host could not be resolved.');
|
||||
|
||||
case '6':
|
||||
throw new Exception('Couldn\'t resolve host. The given remote host could not be resolved.');
|
||||
|
||||
case '7':
|
||||
throw new Exception('Failed to connect to host.');
|
||||
|
||||
default:
|
||||
throw new Exception('Failed getting data.');
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// Show execution error message.
|
||||
echo __($e->getMessage());
|
||||
}
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Loads JS and return code.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function loadJS()
|
||||
{
|
||||
$str = '';
|
||||
ob_start();
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
|
||||
$(document).ready(function(){
|
||||
$('#button-btn_debugModule').click(function() {
|
||||
load_modal({
|
||||
target: $("#modal"),
|
||||
form: "add_module_form",
|
||||
url: "<?php echo ui_get_full_url('ajax.php', false, false, false); ?>",
|
||||
ajax_callback: showMsg,
|
||||
modal: {
|
||||
title: "<?php echo __('Debug'); ?>",
|
||||
},
|
||||
extradata: [
|
||||
{
|
||||
name: "idAgentModule",
|
||||
value: "<?php echo $this->idAgentModule; ?>"
|
||||
}],
|
||||
onshow: {
|
||||
page: "<?php echo $this->ajaxController; ?>",
|
||||
width: 800,
|
||||
method: "showWebServerDebug"
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Toggle the visibility of spinner.
|
||||
*/
|
||||
function showSpinner(setVisibility) {
|
||||
var spinner = $('#WebServerDebugSpinner');
|
||||
if (setVisibility) {
|
||||
spinner.css('visibility', 'visible');
|
||||
} else {
|
||||
spinner.css('visibility', 'hidden');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process ajax responses and shows a dialog with results.
|
||||
*/
|
||||
function showMsg(data) {
|
||||
var title = "<?php echo __('Success'); ?>";
|
||||
var text = "";
|
||||
var failed = 0;
|
||||
try {
|
||||
data = JSON.parse(data);
|
||||
text = data["result"];
|
||||
} catch (err) {
|
||||
title = "<?php echo __('Failed'); ?>";
|
||||
text = err.message;
|
||||
failed = 1;
|
||||
}
|
||||
if (!failed && data["error"] != undefined) {
|
||||
title = "<?php echo __('Failed'); ?>";
|
||||
text = data["error"];
|
||||
failed = 1;
|
||||
}
|
||||
if (data["report"] != undefined) {
|
||||
data["report"].forEach(function(item) {
|
||||
text += "<br>" + item;
|
||||
});
|
||||
}
|
||||
|
||||
$("#msg").empty();
|
||||
$("#msg").html(text);
|
||||
$("#msg").dialog({
|
||||
width: 450,
|
||||
position: {
|
||||
my: "center",
|
||||
at: "center",
|
||||
of: window,
|
||||
collision: "fit"
|
||||
},
|
||||
title: title
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<?php
|
||||
// Get the JS script.
|
||||
$str = ob_get_clean();
|
||||
// Return the loaded JS.
|
||||
echo $str;
|
||||
return $str;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
/* Web Server Module Debug Specific CSS file */
|
||||
.query_result_editor,
|
||||
.query_result_view {
|
||||
min-height: 45em;
|
||||
height: 45em;
|
||||
}
|
||||
|
||||
#query_result_container {
|
||||
margin-top: 30px;
|
||||
}
|
|
@ -38,6 +38,7 @@ use PandoraFMS::DiscoveryServer;
|
|||
use PandoraFMS::WMIServer;
|
||||
use PandoraFMS::PluginServer;
|
||||
use PandoraFMS::PredictionServer;
|
||||
use PandoraFMS::WebServer;
|
||||
|
||||
# Constants for Win32 services.
|
||||
use constant WIN32_SERVICE_STOPPED => 0x01;
|
||||
|
@ -123,6 +124,7 @@ sub pandora_startup () {
|
|||
push (@Servers, new PandoraFMS::WMIServer (\%Config, $DBH));
|
||||
push (@Servers, new PandoraFMS::PluginServer (\%Config, $DBH));
|
||||
push (@Servers, new PandoraFMS::PredictionServer (\%Config, $DBH));
|
||||
push (@Servers, new PandoraFMS::WebServer (\%Config, $DBH));
|
||||
} else {
|
||||
# Metaconsole service modules are run by the prediction server
|
||||
push (@Servers, new PandoraFMS::PredictionServer (\%Config, $DBH));
|
||||
|
|
|
@ -424,11 +424,11 @@ update_parent 1
|
|||
|
||||
# openstreetmaps_description 1
|
||||
|
||||
# Enable (1) or disable (0) Pandora FMS Web Server/Goliat (PANDORA FMS ENTERPRISE ONLY).
|
||||
# Enable (1) or disable (0) Pandora FMS Web Server/Goliat.
|
||||
|
||||
webserver 1
|
||||
|
||||
# Number of threads for the Web Server/Goliat (PANDORA FMS ENTERPRISE ONLY).
|
||||
# Number of threads for the Web Server/Goliat.
|
||||
|
||||
web_threads 1
|
||||
|
||||
|
|
|
@ -0,0 +1,365 @@
|
|||
##################################################################################
|
||||
# Goliath Tools CURL Module
|
||||
##################################################################################
|
||||
# Copyright (c) 2013-2021 Artica Soluciones Tecnologicas S.L
|
||||
# This code is not free or OpenSource. Please don't redistribute.
|
||||
##################################################################################
|
||||
|
||||
package PandoraFMS::Goliat::GoliatCURL;
|
||||
|
||||
use PandoraFMS::Goliat::GoliatTools;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Data::Dumper;
|
||||
use PandoraFMS::DB;
|
||||
|
||||
use IO::Socket::INET6;
|
||||
use URI::Escape;
|
||||
use Time::Local;
|
||||
use Time::HiRes qw ( gettimeofday );
|
||||
|
||||
# Japanese encoding support
|
||||
use Encode::Guess qw/euc-jp shiftjis iso-2022-jp/;
|
||||
|
||||
require Exporter;
|
||||
|
||||
our @ISA = ("Exporter");
|
||||
our %EXPORT_TAGS = ( 'all' => [ qw() ] );
|
||||
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
|
||||
our @EXPORT = qw(
|
||||
g_http_task
|
||||
@task_requests
|
||||
@task_reqsec
|
||||
@task_fails
|
||||
@task_time
|
||||
@task_end
|
||||
@task_sessions
|
||||
@task_ssec
|
||||
@task_get_string
|
||||
@task_get_content
|
||||
@task_session_fails
|
||||
);
|
||||
|
||||
our @task_requests;
|
||||
our @task_reqsec;
|
||||
our @task_fails ;
|
||||
our @task_time;
|
||||
our @task_end;
|
||||
our @task_sessions;
|
||||
our @task_ssec;
|
||||
our @task_get_string;
|
||||
our @task_get_content;
|
||||
our @task_session_fails;
|
||||
our $goliat_abort;
|
||||
|
||||
# Returns a string than can be safely used as a command line parameter for CURL
|
||||
sub safe_param ($) {
|
||||
my $string = shift;
|
||||
|
||||
$string =~ s/'/"/g;
|
||||
return "'" . $string . "'";
|
||||
}
|
||||
|
||||
sub g_http_task {
|
||||
my ( $config, $thread_id, @work_list ) = @_;
|
||||
my ( $ax, $bx, $cx ); # used in FOR loop
|
||||
my ( $ttime1, $ttime2, $ttime_tot );
|
||||
|
||||
my $resp; # HTTP Response
|
||||
my $total_requests = 0;
|
||||
my $total_valid_requests = 0;
|
||||
my $total_invalid_request = 0;
|
||||
my $cookie_file = "/tmp/gtc_".$thread_id."_".g_trash_ascii (3);
|
||||
my $check_string = 1;
|
||||
my $get_string = "";
|
||||
my $get_content = "";
|
||||
my $get_content_advanced = "";
|
||||
my $timeout = 10;
|
||||
|
||||
#my $ua = new LWP::UserAgent;
|
||||
$task_requests [$thread_id] = 0 ;
|
||||
$task_sessions [$thread_id] = 0 ;
|
||||
$task_reqsec[$thread_id] = 0;
|
||||
$task_fails[$thread_id] = 0;
|
||||
$task_session_fails[$thread_id] = 0;
|
||||
$task_ssec[$thread_id] = 0;
|
||||
$task_end[$thread_id] = 0;
|
||||
$task_time[$thread_id] = 0;
|
||||
$task_get_string[$thread_id] = "";
|
||||
$task_get_content[$thread_id] = "";
|
||||
|
||||
# Set command line options for CURL
|
||||
my $curl_opts;
|
||||
|
||||
# Follow redirects
|
||||
$curl_opts .= " --location-trusted";
|
||||
|
||||
# User agent
|
||||
if ($config->{"agent"} ne '') {
|
||||
$curl_opts .= " -A " . safe_param($config->{"agent"})
|
||||
}
|
||||
|
||||
# Prevent pages from being cached
|
||||
$curl_opts .= " -H 'Pragma: no-cache'";
|
||||
|
||||
# Timeout
|
||||
if (defined ($config->{"timeout"}) && $config->{"timeout"} > 0) {
|
||||
$timeout = $config->{"timeout"};
|
||||
}
|
||||
|
||||
# Maximum file size
|
||||
if (defined($config->{"maxsize"}) && $config->{"maxsize"} > 0) {
|
||||
$curl_opts .= " --max-filesize " . $config->{"maxsize"};
|
||||
}
|
||||
|
||||
# Disable SSL certificate host verification
|
||||
$curl_opts .= " -k";
|
||||
|
||||
# Proxy
|
||||
if ($config->{'proxy'} ne ""){
|
||||
$curl_opts .= " -x " . safe_param($config->{'proxy'});
|
||||
}
|
||||
|
||||
# Proxy HTTP authentication
|
||||
if ($config->{'auth_user'} ne "") {
|
||||
$curl_opts .= " --proxy-anyauth -U " . safe_param($config->{'auth_user'} . ':' . $config->{'auth_pass'});
|
||||
}
|
||||
|
||||
# Delete existing cookies
|
||||
my $cookie_carry_on = 0;
|
||||
if ( -e $cookie_file){
|
||||
unlink ($cookie_file);
|
||||
}
|
||||
|
||||
$ttime1 = Time::HiRes::gettimeofday();
|
||||
for ($ax = 0; $ax != $config->{'retries'}; $ax++){
|
||||
for ($bx = 0; $bx < $config->{"work_items"}; $bx++){
|
||||
if ($config->{'con_delay'} > 0){
|
||||
sleep ($config->{'con_delay'});
|
||||
}
|
||||
$total_requests++;
|
||||
# Start to count!
|
||||
$check_string = 1;
|
||||
# Prepare parameters
|
||||
my $task_curl_opts = $curl_opts;
|
||||
my $params = "";
|
||||
$cx = 0;
|
||||
while (defined($work_list[$bx]->{'variable_name'}[$cx])){
|
||||
if ($cx > 0){
|
||||
$params = $params."&";
|
||||
}
|
||||
$params = $params . $work_list[$bx]->{'variable_name'}[$cx] . "=" . uri_escape($work_list[$bx]->{'variable_value'}[$cx]);
|
||||
$cx++;
|
||||
}
|
||||
|
||||
# Cookie carry on
|
||||
if (defined ($work_list[$bx]->{'cookie'}) && $work_list[$bx]->{'cookie'} == 1){
|
||||
$cookie_carry_on = 1;
|
||||
}
|
||||
|
||||
if ($cookie_carry_on == 1) {
|
||||
$task_curl_opts .= " -c " . safe_param ($cookie_file);
|
||||
$task_curl_opts .= " -b " . safe_param ($cookie_file);
|
||||
}
|
||||
|
||||
# HTTP authentication
|
||||
if ($work_list[$bx]->{'http_auth_user'} ne "" && $work_list[$bx]->{'http_auth_pass'} ne "") {
|
||||
|
||||
if($config->{'http_check_type'} == 0){
|
||||
$task_curl_opts .= " --anyauth -u " . safe_param($work_list[$bx]->{'http_auth_user'} . ':' . $work_list[$bx]->{'http_auth_pass'});
|
||||
}
|
||||
|
||||
if ($config->{'http_check_type'} == 1) {
|
||||
$task_curl_opts .= " --ntlm -u " . safe_param($work_list[$bx]->{'http_auth_user'} . ':' . $work_list[$bx]->{'http_auth_pass'});
|
||||
}
|
||||
|
||||
if ($config->{'http_check_type'} == 2) {
|
||||
$task_curl_opts .= " --digest -u " . safe_param($work_list[$bx]->{'http_auth_user'} . ':' . $work_list[$bx]->{'http_auth_pass'});
|
||||
}
|
||||
|
||||
if ($config->{'http_check_type'} == 3) {
|
||||
$task_curl_opts .= " --basic -u " . safe_param($work_list[$bx]->{'http_auth_user'} . ':' . $work_list[$bx]->{'http_auth_pass'});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
# GET
|
||||
if ($work_list[$bx]->{'type'} eq "GET"){
|
||||
$task_curl_opts .= " -H 'Accept: text/html'";
|
||||
if ($cx > 0){
|
||||
$params = $work_list[$bx]->{'url'} . "?" . $params;
|
||||
} else {
|
||||
$params = $work_list[$bx]->{'url'};
|
||||
}
|
||||
|
||||
$resp = curl ($config->{"plugin_exec"}, $timeout, $task_curl_opts, $params, $work_list[$bx]->{'headers'}, $work_list[$bx]->{'debug'}, $config->{"moduleId"}, $config->{"dbh"});
|
||||
|
||||
# POST
|
||||
} elsif ($work_list[$bx]->{'type'} eq "POST") {
|
||||
$task_curl_opts .= " -d " . safe_param($params);
|
||||
$task_curl_opts .= " -H 'Content-type: application/x-www-form-urlencoded'";
|
||||
$resp = curl ($config->{"plugin_exec"}, $timeout, $task_curl_opts, $work_list[$bx]->{'url'}, $work_list[$bx]->{'headers'}, $work_list[$bx]->{'debug'}, $config->{"moduleId"}, $config->{"dbh"});
|
||||
|
||||
# HEAD
|
||||
} else {
|
||||
$task_curl_opts .= " -I";
|
||||
if ($cx > 0){
|
||||
$params = $work_list[$bx]->{'url'} . "?" . uri_escape($params);
|
||||
} else {
|
||||
$params = $work_list[$bx]->{'url'};
|
||||
}
|
||||
$resp = curl ($config->{"plugin_exec"}, $timeout, $task_curl_opts, $params, $work_list[$bx]->{'headers'}, $work_list[$bx]->{'debug'}, $config->{"moduleId"}, $config->{"dbh"});
|
||||
}
|
||||
|
||||
# Get string ?
|
||||
if (defined($work_list[$bx]->{'get_string'})) {
|
||||
my $temp = $work_list[$bx]->{'get_string'};
|
||||
if ($resp =~ m/($temp)/) {
|
||||
$task_get_string[$thread_id] = $1;
|
||||
}
|
||||
}
|
||||
|
||||
# Get response ?
|
||||
if ($work_list[$bx]->{'get_content_advanced'} ne "") {
|
||||
my $temp = $work_list[$bx]->{'get_content_advanced'};
|
||||
if ($resp =~ m/$temp/) {
|
||||
$task_get_content[$thread_id] = $1 if defined ($1);
|
||||
}
|
||||
} elsif ($work_list[$bx]->{'get_content'} ne "") {
|
||||
my $temp = $work_list[$bx]->{'get_content'};
|
||||
if ($resp =~ m/($temp)/) {
|
||||
$task_get_content[$thread_id] = $1;
|
||||
}
|
||||
} else {
|
||||
$task_get_content[$thread_id] = $resp;
|
||||
}
|
||||
|
||||
# Resource bashing
|
||||
#if ((defined($work_list[$bx]->{'get_resources'})) && ($work_list[$bx]->{'get_resources'} == 1)){
|
||||
# $total_requests = g_get_all_links ($config, $ua, $resp, $total_requests, $work_list[$bx]->{'url'}, $work_list[$bx]->{'headers'}, $work_list[$bx]->{'debug'});
|
||||
#}
|
||||
|
||||
# CHECKSTRING check
|
||||
$cx = 0;
|
||||
while (defined($work_list[$bx]->{'checkstring'}[$cx])) {
|
||||
my $match_string = $work_list[$bx]->{'checkstring'}[$cx];
|
||||
my $as_string = $resp;
|
||||
my $guess = Encode::Guess::guess_encoding($as_string);
|
||||
if (ref $guess) {
|
||||
$as_string = $guess->decode($as_string);
|
||||
}
|
||||
unless (utf8::is_utf8($match_string)) {
|
||||
utf8::decode($match_string);
|
||||
}
|
||||
|
||||
if ( $as_string =~ m/$match_string/i ){
|
||||
$total_valid_requests++;
|
||||
} else {
|
||||
$total_invalid_request++;
|
||||
$bx = $config->{"work_items"}; # Abort session remaining request
|
||||
$check_string=0;
|
||||
}
|
||||
$cx++;
|
||||
}
|
||||
|
||||
# CHECKNOTSTRING check
|
||||
$cx = 0;
|
||||
while (defined($work_list[$bx]->{'checknotstring'}[$cx])) {
|
||||
my $match_string = $work_list[$bx]->{'checknotstring'}[$cx];
|
||||
my $as_string = $resp;
|
||||
|
||||
my $guess = Encode::Guess::guess_encoding($as_string);
|
||||
if (ref $guess) {
|
||||
$as_string = $guess->decode($as_string);
|
||||
}
|
||||
unless (utf8::is_utf8($match_string)) {
|
||||
utf8::decode($match_string);
|
||||
}
|
||||
|
||||
if ( $as_string !~ m/$match_string/i ){
|
||||
$total_valid_requests++;
|
||||
} else {
|
||||
$total_invalid_request++;
|
||||
$bx = $config->{"work_items"}; # Abort session remaining request
|
||||
$check_string=0;
|
||||
}
|
||||
$cx++;
|
||||
}
|
||||
|
||||
# End just now by pressing CTRL-C or Kill Signal !
|
||||
#if ($goliat_abort == 1){
|
||||
#$ax = $config->{'retries'};
|
||||
#$bx = $config->{'items'};
|
||||
#goto END_LOOP;
|
||||
#}
|
||||
} #main work_detail loop
|
||||
$ttime2 = Time::HiRes::gettimeofday();
|
||||
|
||||
$ttime_tot = $ttime2 - $ttime1; # Total time for this task
|
||||
$task_time[$thread_id] = $ttime_tot;
|
||||
$task_requests [$thread_id] = $total_requests;
|
||||
if ($ttime_tot > 0 ){
|
||||
$task_reqsec[$thread_id] = $total_requests / $ttime_tot;
|
||||
} else {
|
||||
$task_reqsec[$thread_id] = $total_requests;
|
||||
}
|
||||
$task_fails[$thread_id] = $total_invalid_request;
|
||||
if ($check_string == 0){
|
||||
$task_session_fails[$thread_id]++
|
||||
}
|
||||
$task_sessions [$thread_id]++;
|
||||
if ($task_sessions [$thread_id] > 0 ){
|
||||
$task_ssec[$thread_id] = $ttime_tot / $task_sessions [$thread_id];
|
||||
} else {
|
||||
$task_ssec[$thread_id] = $task_sessions[$thread_id];
|
||||
}
|
||||
sleep $config->{'ses_delay'};
|
||||
}
|
||||
END_LOOP:
|
||||
|
||||
if ( -f $cookie_file){
|
||||
unlink ($cookie_file);
|
||||
}
|
||||
|
||||
$task_end[$thread_id] = 1;
|
||||
}
|
||||
|
||||
# Call CURL and return its output.
|
||||
sub curl {
|
||||
my ($exec, $timeout, $curl_opts, $url, $headers, $debug, $moduleId, $dbh) = @_;
|
||||
|
||||
while (my ($header, $value) = each %{$headers}) {
|
||||
$curl_opts .= " -H " . safe_param($header . ':' . $value);
|
||||
}
|
||||
|
||||
my $cmd = "curl $curl_opts " . safe_param($url);
|
||||
my $response = `"$exec" $timeout $cmd 2>/dev/null`;
|
||||
|
||||
# Curl command stored for live debugging feature.
|
||||
set_update_agentmodule ($dbh, $moduleId, { 'debug_content' => $cmd }) if defined($dbh);
|
||||
|
||||
return $response if ($debug eq '');
|
||||
|
||||
# Debug
|
||||
if (open (DEBUG, '>>', $debug . '.req')) {
|
||||
print DEBUG "[Goliat debug " . time () . "]\n";
|
||||
print DEBUG $cmd;
|
||||
print "\n";
|
||||
close (DEBUG);
|
||||
}
|
||||
if (open (DEBUG, '>>', $debug . '.res')) {
|
||||
print DEBUG "[Goliat debug " . time () . "]\n";
|
||||
print DEBUG $response;
|
||||
print "\n";
|
||||
close (DEBUG);
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
# End of function declaration
|
||||
# End of defined Code
|
||||
|
||||
1;
|
||||
__END__
|
|
@ -0,0 +1,265 @@
|
|||
##########################################################################
|
||||
# Goliat Config package
|
||||
##########################################################################
|
||||
# Copyright (c) 2007-2021 Artica Soluciones Tecnologicas S.L
|
||||
# This code is not free or OpenSource. Please don't redistribute.
|
||||
##########################################################################
|
||||
|
||||
package PandoraFMS::Goliat::GoliatConfig;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use PandoraFMS::Tools;
|
||||
use PandoraFMS::Goliat::GoliatTools;
|
||||
|
||||
require Exporter;
|
||||
our @ISA = ("Exporter");
|
||||
our %EXPORT_TAGS = ( 'all' => [ qw( ) ] );
|
||||
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
|
||||
our @EXPORT = qw( g_help_screen
|
||||
g_init
|
||||
g_load_config );
|
||||
|
||||
my $g_version = "1.0";
|
||||
my $g_build = "110929";
|
||||
our $VERSION = $g_version." ".$g_build;
|
||||
|
||||
|
||||
sub g_load_config {
|
||||
my ( $config , $work_list )= @_ ;
|
||||
my $archivo_cfg = $config->{'config_file'};
|
||||
my $buffer_line;
|
||||
my $task_block = 0;
|
||||
my $commit_block = 0;
|
||||
my $task_url = "";
|
||||
my $task_cookie = 0;
|
||||
my $task_resources = 1;
|
||||
my $task_type = "";
|
||||
my $task_headers = {};
|
||||
my $task_debug = "";
|
||||
my $http_auth_user = "";
|
||||
my $http_auth_pass = "";
|
||||
my $http_auth_realm = "";
|
||||
my $http_auth_serverport = "";
|
||||
my $get_string = "";
|
||||
my $get_content = "";
|
||||
my $get_content_advanced = "";
|
||||
my @task_variable_name;
|
||||
my @task_variable_value;
|
||||
my @task_check_string;
|
||||
my @task_check_not_string;
|
||||
my $parametro;
|
||||
my $temp1;
|
||||
|
||||
# Default options
|
||||
$config->{'con_delay'} =0;
|
||||
$config->{'ses_delay'} =0;
|
||||
if (!defined($config->{'agent'})){
|
||||
$config->{'agent'}="PandoraFMS/Goliat 4.0; Linux)";
|
||||
}
|
||||
if (!defined($config->{'proxy'})){
|
||||
$config->{'proxy'}="";
|
||||
}
|
||||
|
||||
if (!defined($config->{'retries'})){
|
||||
$config->{'retries'} = 1;
|
||||
}
|
||||
|
||||
if ((!is_numeric($config->{'retries'})) || ($config->{'retries'} == 0)){
|
||||
$config->{'retries'} = 1;
|
||||
}
|
||||
|
||||
$config->{'refresh'} = "5";
|
||||
$config->{"max_depth"} = 25;
|
||||
$config->{'log_file'}="/var/log/pandora/pandora_goliat.log";
|
||||
$config->{'log_output'} = 0;
|
||||
|
||||
# Collect items from config file and put in an array
|
||||
open (CFG, "< $archivo_cfg");
|
||||
while (<CFG>){
|
||||
$buffer_line = $_;
|
||||
if ($buffer_line =~ /^[a-zA-Z]/){ # begins with letters
|
||||
$parametro = $buffer_line;
|
||||
} else {
|
||||
$parametro = "";
|
||||
}
|
||||
# Need to commit block ??
|
||||
if (($commit_block == 1) && ($task_block == 1)) {
|
||||
my %work_item;
|
||||
$work_item{'url'} = $task_url;
|
||||
$work_item{'cookie'} = $task_cookie;
|
||||
$work_item{'type'} = $task_type;
|
||||
$work_item{'get_resources'} = $task_resources;
|
||||
$work_item{'get_string'} = $get_string;
|
||||
$work_item{'get_content'} = $get_content;
|
||||
$work_item{'get_content_advanced'} = $get_content_advanced;
|
||||
$work_item{'http_auth_user'} = $http_auth_user;
|
||||
$work_item{'http_auth_pass'} = $http_auth_pass;
|
||||
$work_item{'http_auth_realm'} = $http_auth_realm;
|
||||
$work_item{'http_auth_serverport'} = $http_auth_serverport;
|
||||
$work_item{'headers'} = $task_headers;
|
||||
$work_item{'debug'} = $task_debug;
|
||||
|
||||
my $ax=0;
|
||||
while ($#task_check_string >= 0){
|
||||
$temp1 = pop (@task_check_string);
|
||||
$work_item{'checkstring'}[$ax] = $temp1;
|
||||
$ax++;
|
||||
}
|
||||
$ax=0;
|
||||
while ($#task_check_not_string >= 0){
|
||||
$temp1 = pop (@task_check_not_string);
|
||||
$work_item{'checknotstring'}[$ax] = $temp1;
|
||||
$ax++;
|
||||
}
|
||||
$ax=0;
|
||||
while ($#task_variable_name >= 0){
|
||||
$temp1 = pop (@task_variable_name);
|
||||
$work_item{'variable_name'}[$ax] = $temp1;
|
||||
$ax++;
|
||||
}
|
||||
$ax=0;
|
||||
while ($#task_variable_value >= 0){
|
||||
$temp1 = pop (@task_variable_value);
|
||||
$work_item{'variable_value'}[$ax] = $temp1;
|
||||
$ax++;
|
||||
|
||||
}
|
||||
push @{$work_list}, \%work_item;
|
||||
$commit_block = 0;
|
||||
$task_block = 0;
|
||||
$task_url = "";
|
||||
$task_cookie = 0;
|
||||
$task_resources = 0;
|
||||
$task_type = "";
|
||||
$task_headers = {};
|
||||
$task_debug = "";
|
||||
$config->{"work_items"}++;
|
||||
$commit_block = 0;
|
||||
$task_block = 0;
|
||||
$http_auth_user = "";
|
||||
$http_auth_pass = "";
|
||||
$http_auth_realm = "";
|
||||
$get_string = "";
|
||||
$get_content = "";
|
||||
$get_content_advanced = "";
|
||||
}
|
||||
# ~~~~~~~~~~~~~~
|
||||
# Main setup items
|
||||
# ~~~~~~~~~~~~~~
|
||||
|
||||
if ($parametro =~ m/^task_begin/i) {
|
||||
$task_block = 1;
|
||||
}
|
||||
elsif ($parametro =~ m/^task_end/i) {
|
||||
$commit_block = 1;
|
||||
}
|
||||
elsif ($parametro =~ m/^ses_delay\s(.*)/i) {
|
||||
$config->{'ses_delay'} = $1;
|
||||
}
|
||||
elsif ($parametro =~ m/^con_delay\s(.*)/i) {
|
||||
$config->{'con_delay'} = $1;
|
||||
}
|
||||
elsif ($parametro =~ m/^agent\s(.*)/i) {
|
||||
$config->{'agent'} = $1;
|
||||
}
|
||||
elsif ($parametro =~ m/^proxy\s(.*)/i) {
|
||||
$config->{'proxy'} = $1;
|
||||
}
|
||||
elsif ($parametro =~ m/^max_depth\s(.*)/i) {
|
||||
$config->{'max_depth'} = $1;
|
||||
}
|
||||
elsif ($parametro =~ m/^log_file\s(.*)/i) {
|
||||
$config->{"log_file"} = $1;
|
||||
}
|
||||
elsif ($parametro =~ m/^log_output\s(.*)/i) {
|
||||
$config->{"log_output"} = $1;
|
||||
}
|
||||
elsif ($parametro =~ m/^log_http\s(.*)/i) {
|
||||
$config->{"log_http"} = $1;
|
||||
}
|
||||
elsif ($parametro =~ m/^retries\s(.*)/i) {
|
||||
$config->{"retries"} = $1;
|
||||
}
|
||||
# ~~~~~~~~~~~~~~
|
||||
# Task items
|
||||
# ~~~~~~~~~~~~~~
|
||||
elsif ($parametro =~ m/^variable_name\s(.*)/i) {
|
||||
push (@task_variable_name, $1);
|
||||
}
|
||||
elsif ($parametro =~ m/^variable_value\s(.*)/i) {
|
||||
push (@task_variable_value, $1);
|
||||
}
|
||||
elsif ($parametro =~ m/^check_string\s(.*)/i) {
|
||||
push (@task_check_string, $1);
|
||||
}
|
||||
elsif ($parametro =~ m/^check_not_string\s(.*)/i) {
|
||||
push (@task_check_not_string, $1);
|
||||
}
|
||||
elsif ($parametro =~ m/^get\s(.*)/i) {
|
||||
$task_type = "GET";
|
||||
$task_url = $1;
|
||||
}
|
||||
elsif ($parametro =~ m/^post\s(.*)/i) {
|
||||
$task_type = "POST";
|
||||
$task_url = $1;
|
||||
}
|
||||
elsif ($parametro =~ m/^head\s(.*)/i) {
|
||||
$task_type = "HEAD";
|
||||
$task_url = $1;
|
||||
}
|
||||
# New in 4.0 version
|
||||
elsif ($parametro =~ m/^get_string\s(.*)/i) {
|
||||
$get_string = $1;
|
||||
}
|
||||
elsif ($parametro =~ m/^get_content\s(.*)/i) {
|
||||
$get_content = $1;
|
||||
}
|
||||
elsif ($parametro =~ m/^get_content_advanced\s(.*)/i) {
|
||||
$get_content_advanced = $1;
|
||||
}
|
||||
elsif ($parametro =~ m/^http_auth_user\s(.*)/i) {
|
||||
$http_auth_user = $1;
|
||||
}
|
||||
elsif ($parametro =~ m/^http_auth_pass\s(.*)/i) {
|
||||
$http_auth_pass = $1;
|
||||
}
|
||||
elsif ($parametro =~ m/^http_auth_realm\s(.*)/i) {
|
||||
$http_auth_realm = $1;
|
||||
}
|
||||
elsif ($parametro =~ m/^http_auth_serverport\s(.*)/i) {
|
||||
$http_auth_serverport = $1;
|
||||
}
|
||||
elsif ($parametro =~ m/^cookie\s(.*)/i) {
|
||||
if ($1 =~ m/1/i){
|
||||
$task_cookie = 1;
|
||||
} else {
|
||||
$task_cookie = 0;
|
||||
}
|
||||
}
|
||||
elsif ($parametro =~ m/^resource\s(.*)/i) {
|
||||
if ($1 =~ m/1/i){
|
||||
$task_resources = 1;
|
||||
} else {
|
||||
$task_resources = 0;
|
||||
}
|
||||
}
|
||||
# New in 5.0 version
|
||||
elsif ($parametro =~ m/^header\s+(\S+)\s(.*)/i) {
|
||||
$task_headers->{$1} = $2;
|
||||
}
|
||||
elsif ($parametro =~ m/^debug\s+(.*)/i) {
|
||||
$task_debug = $1;
|
||||
}
|
||||
|
||||
}
|
||||
close (CFG);
|
||||
}
|
||||
|
||||
# End of function declaration
|
||||
# End of defined Code
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
|
|
@ -0,0 +1,478 @@
|
|||
##################################################################################
|
||||
# Goliath Tools LWP Module
|
||||
##################################################################################
|
||||
# Copyright (c) 2007-2021 Artica Soluciones Tecnologicas S.L
|
||||
# This code is not free or OpenSource. Please don't redistribute.
|
||||
##################################################################################
|
||||
|
||||
package PandoraFMS::Goliat::GoliatLWP;
|
||||
|
||||
use PandoraFMS::Goliat::GoliatTools;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Data::Dumper;
|
||||
|
||||
use IO::Socket::INET6;
|
||||
use LWP::UserAgent;
|
||||
use LWP::ConnCache;
|
||||
use HTTP::Request::Common;
|
||||
use HTTP::Response;
|
||||
use HTML::TreeBuilder;
|
||||
use HTML::Element;
|
||||
use HTTP::Cookies;
|
||||
use URI::URL;
|
||||
use Time::Local;
|
||||
use Time::HiRes qw ( gettimeofday );
|
||||
|
||||
# For IPv6 support in Net::HTTP.
|
||||
BEGIN {
|
||||
$Net::HTTP::SOCKET_CLASS = 'IO::Socket::INET6';
|
||||
require Net::HTTP;
|
||||
}
|
||||
|
||||
# Japanese encoding support
|
||||
use Encode::Guess qw/euc-jp shiftjis iso-2022-jp/;
|
||||
|
||||
require Exporter;
|
||||
|
||||
our @ISA = ("Exporter");
|
||||
our %EXPORT_TAGS = ( 'all' => [ qw() ] );
|
||||
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
|
||||
our @EXPORT = qw(
|
||||
g_http_task
|
||||
@task_requests
|
||||
@task_reqsec
|
||||
@task_fails
|
||||
@task_time
|
||||
@task_end
|
||||
@task_sessions
|
||||
@task_ssec
|
||||
@task_get_string
|
||||
@task_get_content
|
||||
@task_session_fails
|
||||
);
|
||||
|
||||
our @task_requests;
|
||||
our @task_reqsec;
|
||||
our @task_fails;
|
||||
our @task_time;
|
||||
our @task_end;
|
||||
our @task_sessions;
|
||||
our @task_ssec;
|
||||
our @task_get_string;
|
||||
our @task_get_content;
|
||||
our @task_session_fails;
|
||||
our $goliat_abort;
|
||||
|
||||
sub parse_html ($;$)
|
||||
{
|
||||
my $p = $_[1];
|
||||
$p = _new_tree_maker() unless $p;
|
||||
$p->parse($_[0]);
|
||||
}
|
||||
|
||||
|
||||
sub parse_htmlfile ($;$)
|
||||
{
|
||||
my($file, $p) = @_;
|
||||
local(*HTML);
|
||||
open(HTML, $file) or return undef;
|
||||
$p = _new_tree_maker() unless $p;
|
||||
$p->parse_file(\*HTML);
|
||||
}
|
||||
|
||||
sub _new_tree_maker
|
||||
{
|
||||
my $p = HTML::TreeBuilder->new(implicit_tags => 1,
|
||||
ignore_unknown => 1,
|
||||
ignore_text => 0,
|
||||
'warn' => 0,
|
||||
);
|
||||
$p->strict_comment(1);
|
||||
$p;
|
||||
}
|
||||
|
||||
|
||||
sub g_http_task {
|
||||
my ( $config, $thread_id, @work_list ) = @_;
|
||||
my ( $ax, $bx, $cx ); # used in FOR loop
|
||||
my ( $ttime1, $ttime2, $ttime_tot );
|
||||
|
||||
my $resp; # HTTP Response
|
||||
my $total_requests = 0;
|
||||
my $total_valid_requests = 0;
|
||||
my $total_invalid_request = 0;
|
||||
my $cookie_file = "/tmp/gtc_".$thread_id."_".g_trash_ascii (3);
|
||||
my $check_string = 1;
|
||||
my $get_string = "";
|
||||
my $get_content = "";
|
||||
my $get_content_advanced = "";
|
||||
|
||||
my $ua = new LWP::UserAgent;
|
||||
$task_requests [$thread_id] = 0 ;
|
||||
$task_sessions [$thread_id] = 0 ;
|
||||
$task_reqsec[$thread_id] = 0;
|
||||
$task_fails[$thread_id] = 0;
|
||||
$task_session_fails[$thread_id] = 0;
|
||||
$task_ssec[$thread_id] = 0;
|
||||
$task_end[$thread_id] = 0;
|
||||
$task_time[$thread_id] = 0;
|
||||
$task_get_string[$thread_id] = "";
|
||||
$task_get_content[$thread_id] = "";
|
||||
|
||||
$ua->agent($config->{"agent"});
|
||||
$ua->protocols_allowed( ['http', 'https'] );
|
||||
$ua->default_headers->push_header('pragma' => "no-cache");
|
||||
$ua->timeout ($config->{"timeout"});
|
||||
$ua->max_size($config->{"maxsize"});
|
||||
$ua->use_alarm($config->{"alarm"});
|
||||
|
||||
# Disable SSL certificate host verification
|
||||
if ($ua->can ('ssl_opts')) {
|
||||
$ua->ssl_opts("verify_hostname" => 0);
|
||||
}
|
||||
|
||||
# Set proxy
|
||||
|
||||
if ($config->{'proxy'} ne ""){
|
||||
$ua->proxy(['http','https'], $config->{'proxy'});
|
||||
}
|
||||
|
||||
# Set HTTP Proxy auth
|
||||
if ($config->{'auth_user'} ne "") {
|
||||
$ua->credentials(
|
||||
$config->{'auth_server'},
|
||||
$config->{'auth_realm'},
|
||||
$config->{'auth_user'} => $config->{'auth_pass'} );
|
||||
}
|
||||
|
||||
if ( -e $cookie_file){
|
||||
unlink ($cookie_file);
|
||||
}
|
||||
my $cookies = HTTP::Cookies->new ('file' => $cookie_file, 'autosave' => '0');
|
||||
|
||||
$ttime1 = Time::HiRes::gettimeofday();
|
||||
for ($ax = 0; $ax != $config->{'retries'}; $ax++){
|
||||
for ($bx = 0; $bx < $config->{"work_items"}; $bx++){
|
||||
if ($config->{'con_delay'} > 0){
|
||||
sleep ($config->{'con_delay'});
|
||||
}
|
||||
$total_requests++;
|
||||
# Start to count!
|
||||
$check_string = 1;
|
||||
# Prepare parameters
|
||||
my $params = "";
|
||||
$cx = 0;
|
||||
while (defined($work_list[$bx]->{'variable_name'}[$cx])){
|
||||
if ($cx > 0){
|
||||
$params = $params."&";
|
||||
}
|
||||
$params = $params . $work_list[$bx]->{'variable_name'}[$cx] . "=" . $work_list[$bx]->{'variable_value'}[$cx];
|
||||
$cx++;
|
||||
}
|
||||
|
||||
if ( (defined($work_list[$bx]->{'http_auth_realm'})) && (defined($work_list[$bx]->{'http_auth_serverport'}))&& (defined($work_list[$bx]->{'http_auth_user'})) && (defined($work_list[$bx]->{'http_auth_pass'}))) {
|
||||
if ($work_list[$bx]->{'http_auth_realm'} ne "") {
|
||||
$ua->credentials(
|
||||
$work_list[$bx]->{'http_auth_serverport'},
|
||||
$work_list[$bx]->{'http_auth_realm'},
|
||||
$work_list[$bx]->{'http_auth_user'} => $work_list[$bx]->{'http_auth_pass'}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
# GET
|
||||
if ($work_list[$bx]->{'type'} eq "GET"){
|
||||
if ($cx > 0){
|
||||
$params = $work_list[$bx]->{'url'} . "?" . $params;
|
||||
} else {
|
||||
$params = $work_list[$bx]->{'url'};
|
||||
}
|
||||
$resp = g_get_page ( $ua, $params, $work_list[$bx]->{'headers'}, $work_list[$bx]->{'debug'});
|
||||
|
||||
# POST
|
||||
} elsif ($work_list[$bx]->{'type'} eq "POST") {
|
||||
$resp = g_post_page ( $ua, $work_list[$bx]->{'url'}, $params, $work_list[$bx]->{'headers'}, $work_list[$bx]->{'debug'});
|
||||
|
||||
# HEAD
|
||||
} else {
|
||||
if ($cx > 0){
|
||||
$params = $work_list[$bx]->{'url'} . "?" . $params;
|
||||
} else {
|
||||
$params = $work_list[$bx]->{'url'};
|
||||
}
|
||||
$resp = g_head_page ( $ua, $params, $work_list[$bx]->{'headers'}, $work_list[$bx]->{'debug'});
|
||||
}
|
||||
|
||||
# Check for errors.
|
||||
if ($resp->code() == 500) {
|
||||
$total_invalid_request++;
|
||||
$bx = $config->{"work_items"};
|
||||
$check_string=0;
|
||||
last;
|
||||
}
|
||||
|
||||
# Get string ?
|
||||
if (defined($work_list[$bx]->{'get_string'})) {
|
||||
my $as_string = $resp->as_string;
|
||||
my $temp = $work_list[$bx]->{'get_string'};
|
||||
if ($as_string =~ m/($temp)/) {
|
||||
$task_get_string[$thread_id] = $1;
|
||||
}
|
||||
}
|
||||
|
||||
# Get response ?
|
||||
if ($work_list[$bx]->{'get_content_advanced'} ne "") {
|
||||
my $content = $resp->decoded_content;
|
||||
my $temp = $work_list[$bx]->{'get_content_advanced'};
|
||||
if ($content =~ m/$temp/) {
|
||||
$task_get_content[$thread_id] = $1 if defined ($1);
|
||||
}
|
||||
} elsif ($work_list[$bx]->{'get_content'} ne "") {
|
||||
my $content = $resp->decoded_content;
|
||||
my $temp = $work_list[$bx]->{'get_content'};
|
||||
if ($content =~ m/($temp)/) {
|
||||
$task_get_content[$thread_id] = $1;
|
||||
}
|
||||
}
|
||||
|
||||
# Resource bashing
|
||||
if ((defined($work_list[$bx]->{'get_resources'})) && ($work_list[$bx]->{'get_resources'} == 1)){
|
||||
$total_requests = g_get_all_links ($config, $ua, $resp, $total_requests, $work_list[$bx]->{'url'}, $work_list[$bx]->{'headers'}, $work_list[$bx]->{'debug'});
|
||||
}
|
||||
|
||||
# CHECKSTRING check
|
||||
$cx = 0;
|
||||
while (defined($work_list[$bx]->{'checkstring'}[$cx])) {
|
||||
my $match_string = $work_list[$bx]->{'checkstring'}[$cx];
|
||||
my $as_string = $resp->as_string;
|
||||
|
||||
my $guess = Encode::Guess::guess_encoding($as_string);
|
||||
if (ref $guess) {
|
||||
$as_string = $guess->decode($as_string);
|
||||
}
|
||||
unless (utf8::is_utf8($match_string)) {
|
||||
utf8::decode($match_string);
|
||||
}
|
||||
|
||||
if ( $as_string =~ m/$match_string/i ){
|
||||
$total_valid_requests++;
|
||||
} else {
|
||||
$total_invalid_request++;
|
||||
$bx = $config->{"work_items"}; # Abort session remaining request
|
||||
$check_string=0;
|
||||
}
|
||||
$cx++;
|
||||
}
|
||||
|
||||
# CHECKNOTSTRING check
|
||||
$cx = 0;
|
||||
while (defined($work_list[$bx]->{'checknotstring'}[$cx])) {
|
||||
my $match_string = $work_list[$bx]->{'checknotstring'}[$cx];
|
||||
my $as_string = $resp->as_string;
|
||||
|
||||
my $guess = Encode::Guess::guess_encoding($as_string);
|
||||
if (ref $guess) {
|
||||
$as_string = $guess->decode($as_string);
|
||||
}
|
||||
unless (utf8::is_utf8($match_string)) {
|
||||
utf8::decode($match_string);
|
||||
}
|
||||
|
||||
if ( $as_string !~ m/$match_string/i ){
|
||||
$total_valid_requests++;
|
||||
} else {
|
||||
$total_invalid_request++;
|
||||
$bx = $config->{"work_items"}; # Abort session remaining request
|
||||
$check_string=0;
|
||||
}
|
||||
$cx++;
|
||||
}
|
||||
|
||||
# Cookie carry on
|
||||
if (defined ($work_list[$bx]->{'cookie'}) && $work_list[$bx]->{'cookie'} == 1){
|
||||
$cookies->extract_cookies($resp);
|
||||
$ua->cookie_jar($cookies);
|
||||
}
|
||||
|
||||
# End just now by pressing CTRL-C or Kill Signal !
|
||||
#if ($goliat_abort == 1){
|
||||
#$ax = $config->{'retries'};
|
||||
#$bx = $config->{'items'};
|
||||
#goto END_LOOP;
|
||||
#}
|
||||
} #main work_detail loop
|
||||
$ttime2 = Time::HiRes::gettimeofday();
|
||||
|
||||
$ttime_tot = $ttime2 - $ttime1; # Total time for this task
|
||||
$task_time[$thread_id] = $ttime_tot;
|
||||
$task_requests [$thread_id] = $total_requests;
|
||||
if ($ttime_tot > 0 ){
|
||||
$task_reqsec[$thread_id] = $total_requests / $ttime_tot;
|
||||
} else {
|
||||
$task_reqsec[$thread_id] = $total_requests;
|
||||
}
|
||||
$task_fails[$thread_id] = $total_invalid_request;
|
||||
if ($check_string == 0){
|
||||
$task_session_fails[$thread_id]++
|
||||
}
|
||||
$task_sessions [$thread_id]++;
|
||||
if ($task_sessions [$thread_id] > 0 ){
|
||||
$task_ssec[$thread_id] = $ttime_tot / $task_sessions [$thread_id];
|
||||
} else {
|
||||
$task_ssec[$thread_id] = $task_sessions[$thread_id];
|
||||
}
|
||||
sleep $config->{'ses_delay'};
|
||||
}
|
||||
END_LOOP:
|
||||
|
||||
$cookies->clear;
|
||||
|
||||
if ( -f $cookie_file){
|
||||
unlink ($cookie_file);
|
||||
}
|
||||
|
||||
$task_end[$thread_id] = 1;
|
||||
}
|
||||
|
||||
|
||||
sub g_get_all_links {
|
||||
my ($config, $ua, $response, $counter, $myurl, $headers, $debug) = @_;
|
||||
my $html;
|
||||
|
||||
if ($response->is_success) {
|
||||
$html = $response->content;
|
||||
} else {
|
||||
return $counter;
|
||||
}
|
||||
# Beware this funcion, needs to be destroyed after use it !!!
|
||||
my $parsed_html = parse_html($html);
|
||||
#$ua->conn_cache(LWP::ConnCache->new());
|
||||
|
||||
my @url_list;
|
||||
my $url = "";
|
||||
my $link;
|
||||
my $full_url;
|
||||
|
||||
for (@{ $parsed_html->extract_links( ) }) {
|
||||
$link=$_->[0];
|
||||
if (($link =~ m/.png/i) || ($link =~ m/.gif/i) || ($link =~ m/.htm/i) ||
|
||||
($link =~ m/.html/i) || ($link =~ m/.pdf/i) || ($link =~ m/.jpg/i)
|
||||
|| ($link =~ m/.ico/i)){
|
||||
$url = new URI::URL $link;
|
||||
$full_url = $url->abs($myurl);
|
||||
@url_list = $full_url;
|
||||
}
|
||||
|
||||
}
|
||||
$parsed_html->delete;
|
||||
my $ax = 0;
|
||||
while ($full_url = pop(@url_list)) {
|
||||
g_get_page ($ua, $full_url, $headers, $debug);
|
||||
$counter++;
|
||||
$ax++;
|
||||
if ($ax > $config->{"max_depth"}){
|
||||
return $counter;
|
||||
}
|
||||
}
|
||||
return $counter;
|
||||
}
|
||||
|
||||
sub g_get_page {
|
||||
my $ua = $_[0];
|
||||
my $url = $_[1];
|
||||
my $headers = $_[2];
|
||||
my $debug = $_[3];
|
||||
|
||||
my $req = HTTP::Request->new(GET => $url);
|
||||
$req->header('Accept' => 'text/html');
|
||||
while (my ($header, $value) = each %{$headers}) {
|
||||
$req->header($header => $value);
|
||||
}
|
||||
my $response = $ua->request($req);
|
||||
return $response if ($debug eq '');
|
||||
|
||||
# Debug
|
||||
if (open (DEBUG, '>>', $debug . '.req')) {
|
||||
print DEBUG "[Goliat debug " . time () . "]\n";
|
||||
print DEBUG $req->as_string ();
|
||||
print "\n";
|
||||
close (DEBUG);
|
||||
}
|
||||
if (open (DEBUG, '>>', $debug . '.res')) {
|
||||
print DEBUG "[Goliat debug " . time () . "]\n";
|
||||
print DEBUG $response->as_string ();
|
||||
print "\n";
|
||||
close (DEBUG);
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
sub g_head_page {
|
||||
my $ua = $_[0];
|
||||
my $url = $_[1];
|
||||
my $headers = $_[2];
|
||||
my $debug = $_[3];
|
||||
|
||||
my $req = HTTP::Request->new(HEAD => $url);
|
||||
$req->header('Accept' => 'text/html');
|
||||
while (my ($header, $value) = each %{$headers}) {
|
||||
$req->header($header => $value);
|
||||
}
|
||||
my $response = $ua->request($req);
|
||||
return $response if ($debug eq '');
|
||||
|
||||
# Debug
|
||||
if (open (DEBUG, '>>', $debug . '.req')) {
|
||||
print DEBUG "[Goliat debug " . time () . "]\n";
|
||||
print DEBUG $req->as_string ();
|
||||
print "\n";
|
||||
close (DEBUG);
|
||||
}
|
||||
if (open (DEBUG, '>>', $debug . '.res')) {
|
||||
print DEBUG "[Goliat debug " . time () . "]\n";
|
||||
print DEBUG $response->as_string ();
|
||||
print "\n";
|
||||
close (DEBUG);
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
sub g_post_page {
|
||||
my $ua = $_[0];
|
||||
my $url = $_[1];
|
||||
my $content = $_[2];
|
||||
my $headers = $_[3];
|
||||
my $debug = $_[4];
|
||||
|
||||
my $req = HTTP::Request->new(POST => $url);
|
||||
$req->content_type('application/x-www-form-urlencoded');
|
||||
$req->content ($content);
|
||||
while (my ($header, $value) = each %{$headers}) {
|
||||
$req->header($header => $value);
|
||||
}
|
||||
my $response = $ua->request($req);
|
||||
return $response if ($debug eq '');
|
||||
|
||||
# Debug
|
||||
if (open (DEBUG, '>>', $debug . '.req')) {
|
||||
print DEBUG "[Goliat debug " . time () . "]\n";
|
||||
print DEBUG $req->as_string ();
|
||||
print "\n";
|
||||
close (DEBUG);
|
||||
}
|
||||
if (open (DEBUG, '>>', $debug . '.res')) {
|
||||
print DEBUG "[Goliat debug " . time () . "]\n";
|
||||
print DEBUG $response->as_string ();
|
||||
print "\n";
|
||||
close (DEBUG);
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
# End of function declaration
|
||||
# End of defined Code
|
||||
|
||||
1;
|
||||
__END__
|
|
@ -0,0 +1,222 @@
|
|||
###############################################################################
|
||||
# Goliath Tools Module
|
||||
###############################################################################
|
||||
# Copyright (c) 2007-2021 Artica Soluciones Tecnologicas S.L
|
||||
# This code is not free or OpenSource. Please don't redistribute.
|
||||
###############################################################################
|
||||
|
||||
package PandoraFMS::Goliat::GoliatTools;
|
||||
|
||||
use 5.008004;
|
||||
use strict;
|
||||
use warnings;
|
||||
use integer;
|
||||
|
||||
require Exporter;
|
||||
|
||||
our @ISA = ("Exporter");
|
||||
our %EXPORT_TAGS = ( 'all' => [ qw() ] );
|
||||
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
|
||||
our @EXPORT = qw(
|
||||
g_clean_string
|
||||
g_clean_string_unicode
|
||||
g_random_string
|
||||
g_trash_ascii
|
||||
g_trash_unicode
|
||||
g_unicode );
|
||||
|
||||
# Delaracion de funciones publicas
|
||||
|
||||
##############################################################################
|
||||
# clean_string (string) - Purge a string for any forbidden characters (esc, etc)
|
||||
##############################################################################
|
||||
sub g_clean_string {
|
||||
my $micadena;
|
||||
$micadena = $_[0];
|
||||
$micadena =~ s/[^\-\:\;\.\,\_\s\a\*\=\(\)a-zA-Z0-9]/ /g;
|
||||
$micadena =~ s/[\n\l\f]/ /g;
|
||||
return $micadena;
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
# limpia_cadena_unicode (string) - Purge a string for any unicode character
|
||||
##############################################################################
|
||||
sub g_clean_string_unicode {
|
||||
my $micadena;
|
||||
$micadena = $_[0];
|
||||
$micadena =~ s/[%]/%%/g;
|
||||
return $micadena;
|
||||
}
|
||||
|
||||
#############################################################################
|
||||
# Hex converter - Convert dec value in hex representation (00 - FF)
|
||||
#############################################################################
|
||||
sub g_decToHex { #return a 16bit (o uno de 8bit) hex value
|
||||
my @hex = (0,1,2,3,4,5,6,7,8,9,"A","B","C","D","E","F");
|
||||
my @dec = @_;
|
||||
my $s3 = $hex[($dec[0]/4096)%16];
|
||||
my $s2 = $hex[($dec[0]/256)%16];
|
||||
my $s1 = $hex[($dec[0]/16)%16];
|
||||
my $s0 = $hex[$dec[0]%16];
|
||||
return "$s1$s0";
|
||||
}
|
||||
|
||||
#############################################################################
|
||||
# unicode - Generate unicode string (recursive)
|
||||
#############################################################################
|
||||
|
||||
sub g_unicode {
|
||||
my $config_word = $_[0];
|
||||
my $config_depth = $_[1];
|
||||
my $config_char="%";
|
||||
if ($config_depth == 0) {
|
||||
return $config_word;
|
||||
}
|
||||
|
||||
my $a;
|
||||
my $pos=0;
|
||||
my $output="";
|
||||
my $len;
|
||||
|
||||
for ($a=0;$a<$config_depth;$a++){
|
||||
$len = length($config_word);
|
||||
while ($pos < $len ) {
|
||||
my $item;
|
||||
$item = substr($config_word,$pos,1);
|
||||
$output = $output.$config_char.decToHex(ord($item));
|
||||
$pos++;
|
||||
}
|
||||
$config_word = $output;
|
||||
}
|
||||
return $output
|
||||
}
|
||||
|
||||
#############################################################################
|
||||
# trash - Generate "unicode" style trash string
|
||||
#############################################################################
|
||||
|
||||
sub g_trash_unicode {
|
||||
my $config_depth = $_[0];
|
||||
my $config_char="%";
|
||||
my $a;
|
||||
my $output;
|
||||
|
||||
for ($a=0;$a<$config_depth;$a++){
|
||||
$output = $output.$config_char.decToHex(int(rand(25)+97));
|
||||
}
|
||||
return $output
|
||||
}
|
||||
|
||||
#############################################################################
|
||||
# trash_ascii - Generate ASCII random strings
|
||||
#############################################################################
|
||||
|
||||
sub g_trash_ascii {
|
||||
my $config_depth = $_[0];
|
||||
my $config_char="%";
|
||||
my $a;
|
||||
my $output;
|
||||
|
||||
for ($a=0;$a<$config_depth;$a++){
|
||||
$output = $output.chr(int(rand(25)+97));
|
||||
}
|
||||
return $output
|
||||
}
|
||||
|
||||
#############################################################################
|
||||
# random_string (min, max, type) - Generate ASCII alphanumeric string,
|
||||
# from min and max
|
||||
#############################################################################
|
||||
|
||||
sub g_random_string {
|
||||
my $config_min = $_[0];
|
||||
my $config_max = $_[1];
|
||||
my $config_type = $_[2]; # alphanumeric, alpha, numeric, lowalpha, highalpha
|
||||
my $a;
|
||||
my $output = "";
|
||||
my @valid_chars;
|
||||
my $rango;
|
||||
|
||||
# First fill list of valid chars (A-Z, a-z, 0-9)
|
||||
if (($config_type eq "alphanumeric") || ($config_type eq "numeric")){
|
||||
for ($a=48;$a<58;$a++){ # numeric
|
||||
push @valid_chars, chr($a);
|
||||
}
|
||||
}
|
||||
|
||||
if (($config_type eq "alphanumeric") || ($config_type eq "alpha") ||
|
||||
($config_type eq "highalpha") || ($config_type eq "lowalpha") ){
|
||||
if (($config_type eq "alphanumeric") || ($config_type eq "highalpha") || ($config_type eq "alpha")){
|
||||
for ($a=65;$a<91;$a++){ # alpha (CAPS)
|
||||
push @valid_chars, chr($a);
|
||||
}
|
||||
}
|
||||
if (($config_type eq "alphanumeric") || ($config_type eq "lowalpha") || ($config_type eq "alpha")){
|
||||
for ($a=97;$a<123;$a++){ # alpha (low)
|
||||
push @valid_chars, chr($a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$rango = @valid_chars;
|
||||
|
||||
# Fill min. value
|
||||
for ($a=0;$a<$config_min;$a++){
|
||||
$output = $output.$valid_chars[(int(rand($rango)))];
|
||||
}
|
||||
|
||||
# Fill to max;
|
||||
if (($config_max - $config_min) != 0){
|
||||
for ($a=0;$a<rand($config_max - $config_min +1)-1;$a++){
|
||||
$output = $output.$valid_chars[(int(rand($rango)))];
|
||||
}
|
||||
}
|
||||
return $output
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Goliath-Tools Library tools for Goliath application.
|
||||
This is an internal module, does not use for independent apps.
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use GoliatTools;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
=head2 EXPORT
|
||||
|
||||
Pues no se que poner aqui :)
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
Mention other useful documentation such as the documentation of
|
||||
related modules or operating system documentation (such as man pages
|
||||
in UNIX), or any relevant external documentation such as RFCs or
|
||||
standards.
|
||||
|
||||
If you have a mailing list set up for your module, mention it here.
|
||||
|
||||
If you have a web site set up for your module, mention it here.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
slerena, E<lt>slerena@Egmail.com<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
Copyright (C) 2005 by Sancho Lerena
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the same terms as Perl itself, either Perl version 5.8.4 or,
|
||||
at your option, any later version of Perl 5 you may have available.
|
||||
|
||||
Licenced under GPL
|
||||
|
||||
=cut
|
|
@ -0,0 +1,304 @@
|
|||
package PandoraFMS::WebServer;
|
||||
##########################################################################
|
||||
# Pandora FMS Web Server.
|
||||
# Pandora FMS. the Flexible Monitoring System. http://www.pandorafms.org
|
||||
##########################################################################
|
||||
# Copyright (c) 2007-2021 Artica Soluciones Tecnologicas S.L
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License
|
||||
# as published by the Free Software Foundation; version 2
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
##########################################################################
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use threads;
|
||||
use threads::shared;
|
||||
use Thread::Semaphore;
|
||||
|
||||
use File::Temp qw(tempfile);
|
||||
use HTML::Entities;
|
||||
use POSIX qw(strftime);
|
||||
|
||||
# Default lib dir for RPM and DEB packages
|
||||
use lib '/usr/lib/perl5';
|
||||
|
||||
use PandoraFMS::Tools;
|
||||
use PandoraFMS::DB;
|
||||
use PandoraFMS::Core;
|
||||
use PandoraFMS::ProducerConsumerServer;
|
||||
|
||||
use PandoraFMS::Goliat::GoliatTools;
|
||||
use PandoraFMS::Goliat::GoliatConfig;
|
||||
|
||||
# Inherits from PandoraFMS::ProducerConsumerServer
|
||||
our @ISA = qw(PandoraFMS::ProducerConsumerServer);
|
||||
|
||||
# Global variables
|
||||
my @TaskQueue :shared;
|
||||
my %PendingTasks :shared;
|
||||
my $Sem :shared;
|
||||
my $TaskSem :shared;
|
||||
|
||||
########################################################################################
|
||||
# Web Server class constructor.
|
||||
########################################################################################
|
||||
sub new ($$;$) {
|
||||
my ($class, $config, $dbh) = @_;
|
||||
|
||||
return undef unless defined ($config->{'webserver'}) and ($config->{'webserver'} == 1);
|
||||
|
||||
# Initialize semaphores and queues
|
||||
@TaskQueue = ();
|
||||
%PendingTasks = ();
|
||||
$Sem = Thread::Semaphore->new;
|
||||
$TaskSem = Thread::Semaphore->new (0);
|
||||
|
||||
# Call the constructor of the parent class
|
||||
my $self = $class->SUPER::new($config, WEBSERVER, \&PandoraFMS::WebServer::data_producer, \&PandoraFMS::WebServer::data_consumer, $dbh);
|
||||
|
||||
bless $self, $class;
|
||||
return $self;
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Run.
|
||||
###############################################################################
|
||||
sub run ($) {
|
||||
my $self = shift;
|
||||
my $pa_config = $self->getConfig ();
|
||||
|
||||
print_message ($pa_config, " [*] Starting " . $pa_config->{'rb_product_name'} . " Web Server.", 1);
|
||||
|
||||
# Use Goliat with CURL
|
||||
if ($pa_config->{'web_engine'} eq 'curl') {
|
||||
require PandoraFMS::Goliat::GoliatCURL;
|
||||
PandoraFMS::Goliat::GoliatCURL->import;
|
||||
|
||||
# Check for CURL binary
|
||||
if (system ("curl -V >$DEVNULL 2>&1") >> 8 != 0) {
|
||||
logger ($pa_config, ' [E] CURL binary not found. Install CURL or uncomment the web_engine configuration token to use LWP.', 1);
|
||||
print_message ($pa_config, ' [E] CURL binary not found. Install CURL or uncomment the web_engine configuration token to use LWP.', 1);
|
||||
return undef;
|
||||
}
|
||||
# Check for pandora_exec binary
|
||||
if (system ("\"" . $pa_config->{'plugin_exec'} . "\" 10 echo >$DEVNULL 2>&1") >> 8 != 0) {
|
||||
logger ($pa_config, ' [E] ' . $pa_config->{'plugin_exec'} . ' not found. Please install it or add it to the PATH.', 1);
|
||||
print_message ($pa_config, ' [E] ' . $pa_config->{'plugin_exec'} . ' not found. Please install it or add it to the PATH.', 1);
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
# Use LWP by default
|
||||
else {
|
||||
require PandoraFMS::Goliat::GoliatLWP;
|
||||
PandoraFMS::Goliat::GoliatLWP->import;
|
||||
|
||||
if (! LWP::UserAgent->can('ssl_opts')) {
|
||||
logger($pa_config, "LWP version $LWP::VERSION does not support SSL. Make sure version 6.0 or higher is installed.", 1);
|
||||
print_message ($pa_config, " [W] LWP version $LWP::VERSION does not support SSL. Make sure version 6.0 or higher is installed.", 1);
|
||||
}
|
||||
}
|
||||
|
||||
$self->setNumThreads ($pa_config->{'web_threads'});
|
||||
$self->SUPER::run (\@TaskQueue, \%PendingTasks, $Sem, $TaskSem);
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Data producer.
|
||||
###############################################################################
|
||||
sub data_producer ($) {
|
||||
my $self = shift;
|
||||
my ($pa_config, $dbh) = ($self->getConfig (), $self->getDBH ());
|
||||
|
||||
my @tasks;
|
||||
my @rows;
|
||||
|
||||
if (pandora_is_master($pa_config) == 0) {
|
||||
@rows = get_db_rows ($dbh, 'SELECT tagente_modulo.id_agente_modulo, tagente_modulo.flag, tagente_estado.current_interval + tagente_estado.last_execution_try AS time_left, last_execution_try
|
||||
FROM tagente, tagente_modulo, tagente_estado
|
||||
WHERE server_name = ?
|
||||
AND tagente_modulo.id_agente = tagente.id_agente
|
||||
AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo
|
||||
AND tagente.disabled = 0
|
||||
AND tagente_modulo.id_modulo = 7
|
||||
AND tagente_modulo.disabled = 0
|
||||
AND (tagente_modulo.flag = 1 OR ((tagente_estado.last_execution_try + tagente_estado.current_interval) < UNIX_TIMESTAMP()))
|
||||
ORDER BY tagente_modulo.flag DESC, time_left ASC, last_execution_try ASC ', $pa_config->{'servername'});
|
||||
} else {
|
||||
@rows = get_db_rows ($dbh, 'SELECT DISTINCT(tagente_modulo.id_agente_modulo), tagente_modulo.flag, tagente_estado.current_interval + tagente_estado.last_execution_try AS time_left, last_execution_try
|
||||
FROM tagente, tagente_modulo, tagente_estado, tserver
|
||||
WHERE ((server_name = ?) OR (server_name = ANY(SELECT server_name FROM tserver WHERE status = 0 AND server_type = ?)))
|
||||
AND tagente_modulo.id_agente = tagente.id_agente
|
||||
AND tagente.disabled = 0
|
||||
AND tagente_modulo.disabled = 0
|
||||
AND tagente_modulo.id_modulo = 7
|
||||
AND tagente_estado.id_agente_modulo = tagente_modulo.id_agente_modulo
|
||||
AND ((tagente_estado.last_execution_try + tagente_estado.current_interval) < UNIX_TIMESTAMP() OR tagente_modulo.flag = 1 )
|
||||
ORDER BY tagente_modulo.flag DESC, time_left ASC, last_execution_try ASC', $pa_config->{'servername'}, WEBSERVER);
|
||||
}
|
||||
|
||||
foreach my $row (@rows) {
|
||||
|
||||
# Reset forced execution flag
|
||||
if ($row->{'flag'} == 1) {
|
||||
db_do ($dbh, 'UPDATE tagente_modulo SET flag = 0 WHERE id_agente_modulo = ?', $row->{'id_agente_modulo'});
|
||||
}
|
||||
|
||||
push (@tasks, $row->{'id_agente_modulo'});
|
||||
}
|
||||
|
||||
return @tasks;
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Data consumer.
|
||||
###############################################################################
|
||||
sub data_consumer ($$) {
|
||||
my ($self, $module_id) = @_;
|
||||
my ($pa_config, $dbh) = ($self->getConfig (), $self->getDBH ());
|
||||
our (@task_fails, @task_time, @task_ssec, @task_get_content); # Defined in GoliatLWP.pm and GoliatCURL.
|
||||
|
||||
# Retrieve module data
|
||||
my $module = get_db_single_row ($dbh, 'SELECT * FROM tagente_modulo WHERE id_agente_modulo = ?', $module_id);
|
||||
return unless defined ($module);
|
||||
|
||||
# Retrieve agent data
|
||||
my $agent = get_db_single_row ($dbh, 'SELECT * FROM tagente WHERE id_agente = ?', $module->{'id_agente'});
|
||||
return unless defined $agent;
|
||||
|
||||
# Save Goliat config to a temporary file
|
||||
my ($fh, $temp_file) = tempfile();
|
||||
return unless defined ($fh);
|
||||
|
||||
# Read the Goliat task
|
||||
my $task = safe_output($module->{'plugin_parameter'});
|
||||
|
||||
# Delete any carriage returns
|
||||
$task =~ s/\r//g;
|
||||
|
||||
# Agent and module macros
|
||||
my %macros = (_agent_ => (defined ($agent)) ? $agent->{'alias'} : '',
|
||||
_agentdescription_ => (defined ($agent)) ? $agent->{'comentarios'} : '',
|
||||
_agentstatus_ => (defined ($agent)) ? get_agent_status ($pa_config, $dbh, $agent->{'id_agente'}) : '',
|
||||
_address_ => (defined ($agent)) ? $agent->{'direccion'} : '',
|
||||
_module_ => (defined ($module)) ? $module->{'nombre'} : '',
|
||||
_modulegroup_ => (defined ($module)) ? (get_module_group_name ($dbh, $module->{'id_module_group'}) || '') : '',
|
||||
_moduledescription_ => (defined ($module)) ? $module->{'descripcion'} : '',
|
||||
_modulestatus_ => (defined ($module)) ? get_agentmodule_status($pa_config, $dbh, $module->{'id_agente_modulo'}) : '',
|
||||
_moduletags_ => (defined ($module)) ? pandora_get_module_url_tags ($pa_config, $dbh, $module->{'id_agente_modulo'}) : '',
|
||||
_id_agent_ => (defined ($module)) ? $module->{'id_agente'} : '',
|
||||
_interval_ => (defined ($module) && $module->{'module_interval'} != 0) ? $module->{'module_interval'} : (defined ($agent)) ? $agent->{'intervalo'} : '',
|
||||
_target_ip_ => (defined ($agent)) ? $agent->{'direccion'} : '',
|
||||
_target_port_ => (defined ($module)) ? $module->{'tcp_port'} : '',
|
||||
_policy_ => (defined ($module)) ? enterprise_hook('get_policy_name', [$dbh, $module->{'id_policy_module'}]) : '',
|
||||
_plugin_parameters_ => (defined ($module)) ? $module->{'plugin_parameter'} : '',
|
||||
_email_tag_ => (defined ($module)) ? pandora_get_module_email_tags ($pa_config, $dbh, $module->{'id_agente_modulo'}) : '',
|
||||
_phone_tag_ => (defined ($module)) ? pandora_get_module_phone_tags ($pa_config, $dbh, $module->{'id_agente_modulo'}) : '',
|
||||
_name_tag_ => (defined ($module)) ? pandora_get_module_tags ($pa_config, $dbh, $module->{'id_agente_modulo'}) : '',
|
||||
);
|
||||
$task = subst_alert_macros ($task, \%macros);
|
||||
|
||||
# Goliat has some trouble parsing conf files without the newlines
|
||||
$fh->print ("\n\n" . $task . "\n\n");
|
||||
close ($fh);
|
||||
|
||||
# Global vars needed by Goliat
|
||||
my (%config, @work_list, $check_string);
|
||||
|
||||
# Goliat config defaults
|
||||
$config{'verbosity'} = 1;
|
||||
$config{'slave'} = 0;
|
||||
$config{'port'} = 80;
|
||||
$config{'log_file'} = "$DEVNULL";
|
||||
$config{'log_output'} = 0;
|
||||
$config{'log_http'} = 0;
|
||||
$config{'work_items'} = 0;
|
||||
$config{'config_file'} = $temp_file;
|
||||
$config{'agent'} = safe_output($module->{'plugin_user'});
|
||||
if ($module->{'max_retries'} != 0) {
|
||||
$config{'retries'} = $module->{'max_retries'};
|
||||
}
|
||||
if ($module->{'max_timeout'} != 0) {
|
||||
$config{'timeout'} = $module->{'max_timeout'};
|
||||
} else {
|
||||
$config{'timeout'} = $pa_config->{'web_timeout'};
|
||||
}
|
||||
|
||||
$config{'proxy'} = $module->{'snmp_oid'};
|
||||
$config{'auth_user'} = safe_output($module->{'tcp_send'});
|
||||
$config{'auth_pass'} = safe_output($module->{'tcp_rcv'});
|
||||
$config{'auth_server'} = $module->{'ip_target'};
|
||||
$config{'auth_realm'} = $module->{'snmp_community'};
|
||||
$config{'http_check_type'} = $module->{'tcp_port'};
|
||||
$config{'moduleId'} = $module_id;
|
||||
$config{'dbh'} = $dbh;
|
||||
|
||||
# Pandora FMS variables passed to Goliat.
|
||||
$config{'plugin_exec'} = $pa_config->{'plugin_exec'};
|
||||
|
||||
eval {
|
||||
# Load Goliat config
|
||||
g_load_config(\%config, \@work_list);
|
||||
|
||||
# Run Goliat task
|
||||
g_http_task (\%config, 0, @work_list);
|
||||
};
|
||||
|
||||
if ($@) {
|
||||
pandora_update_module_on_error ($pa_config, $module, $dbh);
|
||||
unlink ($temp_file);
|
||||
return;
|
||||
}
|
||||
|
||||
unlink ($temp_file);
|
||||
|
||||
my $utimestamp = time ();
|
||||
my $timestamp = strftime ("%Y-%m-%d %H:%M:%S", localtime($utimestamp));
|
||||
|
||||
# Get module type
|
||||
my $module_type = get_db_value ($dbh, 'SELECT nombre FROM ttipo_modulo WHERE id_tipo = ?', $module->{'id_tipo_modulo'});
|
||||
|
||||
# Get data from Goliat
|
||||
my $module_data;
|
||||
{
|
||||
no strict 'vars';
|
||||
if ($module_type eq 'web_proc') {
|
||||
$module_data = ($task_fails[0] == 0 && $task_get_content[0] ne "") ? 1 : 0;
|
||||
}
|
||||
elsif ($module_type eq 'web_data') {
|
||||
$module_data = $task_ssec[0];
|
||||
} elsif ($module_type eq 'web_server_status_code_string') {
|
||||
my @resp_lines = split "\r\n", $task_get_content[0];
|
||||
$module_data = $resp_lines[0];
|
||||
} else {
|
||||
$module_data = $task_get_content[0];
|
||||
}
|
||||
}
|
||||
|
||||
my %data = ("data" => $module_data);
|
||||
pandora_process_module ($pa_config, \%data, undef, $module, $module_type, $timestamp, $utimestamp, $self->getServerID (), $dbh);
|
||||
|
||||
my $agent_os_version = get_db_value ($dbh, 'SELECT os_version FROM tagente WHERE id_agente = ?', $module->{'id_agente'});
|
||||
|
||||
if (! defined ($agent_os_version) || $agent_os_version eq '') {
|
||||
$agent_os_version = $pa_config->{'servername'}.'_Web';
|
||||
}
|
||||
|
||||
# Todo: Implement here
|
||||
# 1. Detect if exists a module with the same name, but with type generic_string.
|
||||
# 2. If not, create the module, get the id's
|
||||
# 3. Insert data coming from $task_get_string in that module
|
||||
|
||||
pandora_update_agent ($pa_config, $timestamp, $module->{'id_agente'}, undef, undef, -1, $dbh);
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
Loading…
Reference in New Issue