From 90366e7e586a1ca69441e8adfee11553fbca2ef7 Mon Sep 17 00:00:00 2001 From: Ramon Novoa Date: Fri, 13 Oct 2017 15:49:12 +0200 Subject: [PATCH] Performance improvements. Rewrote safe_input and safe_output. Ref pandora_enterprise#1465. --- pandora_server/lib/PandoraFMS/DataServer.pm | 11 +- pandora_server/lib/PandoraFMS/Tools.pm | 271 ++++++++++---------- 2 files changed, 144 insertions(+), 138 deletions(-) diff --git a/pandora_server/lib/PandoraFMS/DataServer.pm b/pandora_server/lib/PandoraFMS/DataServer.pm index ebd8f860ee..603cbf8cf2 100644 --- a/pandora_server/lib/PandoraFMS/DataServer.pm +++ b/pandora_server/lib/PandoraFMS/DataServer.pm @@ -186,6 +186,7 @@ sub data_consumer ($$) { for (0..1) { eval { threads->yield; + $xml_data = XMLin ($file_name, forcearray => 'module'); }; @@ -527,7 +528,7 @@ sub process_xml_data ($$$$$) { # Single data if (! defined ($module_data->{'datalist'})) { my $data_timestamp = get_tag_value ($module_data, 'timestamp', $timestamp); - process_module_data ($pa_config, $module_data, $server_id, $agent_name, $module_name, $module_type, $interval, $data_timestamp, $dbh, $new_agent); + process_module_data ($pa_config, $module_data, $server_id, $agent, $module_name, $module_type, $interval, $data_timestamp, $dbh, $new_agent); next; } @@ -544,7 +545,7 @@ sub process_xml_data ($$$$$) { $module_data->{'data'} = $data->{'value'}; my $data_timestamp = get_tag_value ($data, 'timestamp', $timestamp); - process_module_data ($pa_config, $module_data, $server_id, $agent_name, $module_name, + process_module_data ($pa_config, $module_data, $server_id, $agent, $module_name, $module_type, $interval, $data_timestamp, $dbh, $new_agent); } } @@ -584,16 +585,16 @@ sub process_xml_data ($$$$$) { # Process module data, creating module if necessary. ########################################################################## sub process_module_data ($$$$$$$$$$) { - my ($pa_config, $data, $server_id, $agent_name, + my ($pa_config, $data, $server_id, $agent, $module_name, $module_type, $interval, $timestamp, $dbh, $force_processing) = @_; # Get agent data - my $agent = get_db_single_row ($dbh, 'SELECT * FROM tagente WHERE nombre = ?', safe_input($agent_name)); if (! defined ($agent)) { - logger($pa_config, "Invalid agent '$agent_name' for module '$module_name'.", 3); + logger($pa_config, "Invalid agent for module '$module_name'.", 3); return; } + my $agent_name = $agent->{'nombre'}; # Get module parameters, matching column names in tagente_modulo my $module_conf; diff --git a/pandora_server/lib/PandoraFMS/Tools.pm b/pandora_server/lib/PandoraFMS/Tools.pm index e0dda9af4f..a9481d4f13 100755 --- a/pandora_server/lib/PandoraFMS/Tools.pm +++ b/pandora_server/lib/PandoraFMS/Tools.pm @@ -151,6 +151,141 @@ if ($OS eq 'linux') { } chomp($OS_VERSION); +# Entity to character mapping. Contains a few tweaks to make it backward compatible with the previous safe_input implementation. +my %ENT2CHR = ( + '#x00' => chr(0), + '#x01' => chr(1), + '#x02' => chr(2), + '#x03' => chr(3), + '#x04' => chr(4), + '#x05' => chr(5), + '#x06' => chr(6), + '#x07' => chr(7), + '#x08' => chr(8), + '#x09' => chr(9), + '#x0a' => chr(10), + '#x0b' => chr(11), + '#x0c' => chr(12), + '#x0d' => chr(13), + '#x0e' => chr(14), + '#x0f' => chr(15), + '#x10' => chr(16), + '#x11' => chr(17), + '#x12' => chr(18), + '#x13' => chr(19), + '#x14' => chr(20), + '#x15' => chr(21), + '#x16' => chr(22), + '#x17' => chr(23), + '#x18' => chr(24), + '#x19' => chr(25), + '#x1a' => chr(26), + '#x1b' => chr(27), + '#x1c' => chr(28), + '#x1d' => chr(29), + '#x1e' => chr(30), + '#x1f' => chr(31), + '#x20' => chr(32), + 'quot' => chr(34), + 'amp' => chr(38), + '#039' => chr(39), + '#40' => chr(40), + '#41' => chr(41), + 'lt' => chr(60), + 'gt' => chr(62), + '#92' => chr(92), + '#x80' => chr(128), + '#x81' => chr(129), + '#x82' => chr(130), + '#x83' => chr(131), + '#x84' => chr(132), + '#x85' => chr(133), + '#x86' => chr(134), + '#x87' => chr(135), + '#x88' => chr(136), + '#x89' => chr(137), + '#x8a' => chr(138), + '#x8b' => chr(139), + '#x8c' => chr(140), + '#x8d' => chr(141), + '#x8e' => chr(142), + '#x8f' => chr(143), + '#x90' => chr(144), + '#x91' => chr(145), + '#x92' => chr(146), + '#x93' => chr(147), + '#x94' => chr(148), + '#x95' => chr(149), + '#x96' => chr(150), + '#x97' => chr(151), + '#x98' => chr(152), + '#x99' => chr(153), + '#x9a' => chr(154), + '#x9b' => chr(155), + '#x9c' => chr(156), + '#x9d' => chr(157), + '#x9e' => chr(158), + '#x9f' => chr(159), + '#xa0' => chr(160), + '#xa1' => chr(161), + '#xa2' => chr(162), + '#xa3' => chr(163), + '#xa4' => chr(164), + '#xa5' => chr(165), + '#xa6' => chr(166), + '#xa7' => chr(167), + '#xa8' => chr(168), + '#xa9' => chr(169), + '#xaa' => chr(170), + '#xab' => chr(171), + '#xac' => chr(172), + '#xad' => chr(173), + '#xae' => chr(174), + '#xaf' => chr(175), + '#xb0' => chr(176), + '#xb1' => chr(177), + '#xb2' => chr(178), + '#xb3' => chr(179), + '#xb4' => chr(180), + '#xb5' => chr(181), + '#xb6' => chr(182), + '#xb7' => chr(183), + '#xb8' => chr(184), + '#xb9' => chr(185), + '#xba' => chr(186), + '#xbb' => chr(187), + '#xbc' => chr(188), + '#xbd' => chr(189), + '#xbe' => chr(190), + 'Aacute' => chr(193), + 'Auml' => chr(196), + 'Eacute' => chr(201), + 'Euml' => chr(203), + 'Iacute' => chr(205), + 'Iuml' => chr(207), + 'Ntilde' => chr(209), + 'Oacute' => chr(211), + 'Ouml' => chr(214), + 'Uacute' => chr(218), + 'Uuml' => chr(220), + 'aacute' => chr(225), + 'auml' => chr(228), + 'eacute' => chr(233), + 'euml' => chr(235), + 'iacute' => chr(237), + 'iuml' => chr(239), + 'ntilde' => chr(241), + 'oacute' => chr(243), + 'ouml' => chr(246), + 'uacute' => chr(250), + 'uuml' => chr(252), +); + +# Construct the character to entity mapping. +my %CHR2ENT; +while (my ($ent, $chr) = each(%ENT2CHR)) { + $CHR2ENT{$chr} = "&" . $ent . ";"; +} ############################################################################### # Sets user:group owner for the given file @@ -201,49 +336,7 @@ sub pandora_trash_ascii { sub safe_input($) { my $value = shift; - $value = encode_entities ($value, "<>&"); - - #//Replace the character '\' for the equivalent html entitie - $value =~ s/\\/\/gi; - - #// First attempt to avoid SQL Injection based on SQL comments - #// Specific for MySQL. - $value =~ s/\/\*//*/gi; - $value =~ s/\*\//*//gi; - - #//Replace ' for the html entitie - $value =~ s/\"/"/gi; - - #//Replace ' for the html entitie - $value =~ s/\'/'/gi; - - #//Replace ( for the html entitie - $value =~ s/\(/(/gi; - - #//Replace ( for the html entitie - $value =~ s/\)/)/gi; - - #//Replace some characteres for html entities - for (my $i=0;$i<33;$i++) { - my $pattern = chr($i); - my $hex = ascii_to_html($i); - $value =~ s/$pattern/$hex/gi; - } - - for (my $i=128;$i<191;$i++) { - my $pattern = chr($i); - my $hex = ascii_to_html($i); - $value =~ s/$pattern/$hex/gi; - } - - #//Replace characteres for tildes and others - my $trans = get_html_entities(); - - foreach(keys(%$trans)) - { - my $pattern = chr($_); - $value =~ s/$pattern/$trans->{$_}/g; - } + $value =~ s/([\x00-\xFF])/$CHR2ENT{$1}||$1/ge; return $value; } @@ -254,99 +347,11 @@ sub safe_input($) { sub safe_output($) { my $value = shift; - $value = decode_entities ($value); - - #//Replace the character '\' for the equivalent html entitie - $value =~ s/\/\\/gi; - - #// First attempt to avoid SQL Injection based on SQL comments - #// Specific for MySQL. - $value =~ s//*/\/\*/gi; - $value =~ s/*//\*\//gi; - - #//Replace ( for the html entitie - $value =~ s/(/\(/gi; - - #//Replace ( for the html entitie - $value =~ s/)/\)/gi; - - #//Replace ' for the html entitie - $value =~ s/'/')/gi; - - #//Replace " for the html entitie - $value =~ s/"/")/gi; - - #//Replace some characteres for html entities - for (my $i=0;$i<33;$i++) { - my $pattern = chr($i); - my $hex = ascii_to_html($i); - $value =~ s/$hex/$pattern/gi; - } - - for (my $i=128;$i<191;$i++) { - my $pattern = chr($i); - my $hex = ascii_to_html($i); - $value =~ s/$hex/$pattern/gi; - } - - #//Replace characteres for tildes and others - my $trans = get_html_entities(); - - foreach(keys(%$trans)) - { - my $pattern = chr($_); - $value =~ s/$trans->{$_}/$pattern/g; - } - + _decode_entities ($value, \%ENT2CHR); + return $value; } -########################################################################## -# SUB get_html_entities -# Returns a hash table with the acute and special html entities -# Usefull for future chars addition: -# http://cpansearch.perl.org/src/GAAS/HTML-Parser-3.68/lib/HTML/Entities.pm -########################################################################## - -sub get_html_entities { - my %trans = ( - 225 => 'á', - 233 => 'é', - 237 => 'í', - 243 => 'ó', - 250 => 'ú', - 193 => 'Á', - 201 => 'É', - 205 => 'Í', - 211 => 'Ó', - 218 => 'Ú', - 228 => 'ä', - 235 => 'ë', - 239 => 'ï', - 246 => 'ö', - 252 => 'ü', - 196 => 'Ä', - 203 => 'Ë', - 207 => 'Ï', - 214 => 'Ö', - 220 => 'Ü', - 241 => 'ñ', - 209 => 'Ñ' - ); - - return \%trans; -} -######################################################################## -# SUB ascii_to_html (string) -# Convert an ascii string to hexadecimal -######################################################################## - -sub ascii_to_html($) { - my $ascii = shift; - - return "&#x".substr(unpack("H*", pack("N", $ascii)),6,3).";"; -} - ######################################################################## # Sub daemonize () # Put program in background (for daemon mode)