mirror of
https://github.com/pandorafms/pandorafms.git
synced 2025-07-30 01:05:39 +02:00
WIP: Backup upload
This commit is contained in:
parent
c2f297c26a
commit
9e54f9517b
@ -73,4 +73,9 @@ enterprise/extensions/ipam.php
|
||||
enterprise/extensions/ipam
|
||||
enterprise/extensions/disabled/visual_console_manager.php
|
||||
enterprise/extensions/visual_console_manager.php
|
||||
pandora_console/extensions/net_tools.php
|
||||
pandora_console/extensions/net_tools.php
|
||||
pandora_enterprise/pandora_server/PandoraFMS-Enterprise/lib/Goliat/GoliatCURL.pm
|
||||
pandora_enterprise/pandora_server/PandoraFMS-Enterprise/lib/Goliat/GoliatConfig.pm
|
||||
pandora_enterprise/pandora_server/PandoraFMS-Enterprise/lib/Goliat/GoliatLWP.pm
|
||||
pandora_enterprise/pandora_server/PandoraFMS-Enterprise/lib/Goliat/GoliatTools.pm
|
||||
pandora_enterprise/pandora_server/PandoraFMS-Enterprise/lib/PandoraFMS/WebServer.pm
|
@ -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
|
||||
|
||||
|
365
pandora_server/lib/PandoraFMS/Goliat/GoliatCURL.pm
Executable file
365
pandora_server/lib/PandoraFMS/Goliat/GoliatCURL.pm
Executable file
@ -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 Goliat::GoliatCURL;
|
||||
|
||||
use 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__
|
265
pandora_server/lib/PandoraFMS/Goliat/GoliatConfig.pm
Executable file
265
pandora_server/lib/PandoraFMS/Goliat/GoliatConfig.pm
Executable file
@ -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 Goliat::GoliatConfig;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Goliat::GoliatTools;
|
||||
use PandoraFMS::Tools;
|
||||
|
||||
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__
|
||||
|
||||
|
478
pandora_server/lib/PandoraFMS/Goliat/GoliatLWP.pm
Executable file
478
pandora_server/lib/PandoraFMS/Goliat/GoliatLWP.pm
Executable file
@ -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 Goliat::GoliatLWP;
|
||||
|
||||
use 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__
|
222
pandora_server/lib/PandoraFMS/Goliat/GoliatTools.pm
Executable file
222
pandora_server/lib/PandoraFMS/Goliat/GoliatTools.pm
Executable file
@ -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 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
|
294
pandora_server/lib/PandoraFMS/WebServer.pm
Normal file
294
pandora_server/lib/PandoraFMS/WebServer.pm
Normal file
@ -0,0 +1,294 @@
|
||||
package PandoraFMS::WebServer;
|
||||
|
||||
##########################################################################
|
||||
# Pandora FMS Web Server.
|
||||
##########################################################################
|
||||
# Copyright (c) 2007-2021 Artica Soluciones Tecnologicas S.L
|
||||
# This code is not free or OpenSource. Please don't redistribute.
|
||||
##########################################################################
|
||||
|
||||
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::Goliat::GoliatTools;
|
||||
use PandoraFMS::Goliat::GoliatConfig;
|
||||
|
||||
use PandoraFMS::Tools;
|
||||
use PandoraFMS::DB;
|
||||
use PandoraFMS::Core;
|
||||
use PandoraFMS::ProducerConsumerServer;
|
||||
|
||||
# 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 Goliat::GoliatCURL;
|
||||
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 Goliat::GoliatLWP;
|
||||
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…
x
Reference in New Issue
Block a user