From e37ecc64c320cad1c264c28127bdc07d2858fac1 Mon Sep 17 00:00:00 2001
From: Tomas Plesnik <plesnik@ics.muni.cz>
Date: Tue, 14 Oct 2014 16:09:34 +0200
Subject: [PATCH] bugfix: opraveno ziskavani udalosti z databaze ve funkci
 getNewEvents (dva SELECTy nahrazeny jednim SELECT JOINem); odstraneno
 nadbytecne preukladani hodnot z db do novych promennych; uprava a
 zjednoduseni logovacich hlasek; lepsi prehlednost kodu (nahrazeni negovanych
 ifu za unless); uprava odsazeni

---
 src/warden-server/lib/Warden.pm | 246 ++++++++++++--------------------
 1 file changed, 94 insertions(+), 152 deletions(-)

diff --git a/src/warden-server/lib/Warden.pm b/src/warden-server/lib/Warden.pm
index faeae35..75804ae 100755
--- a/src/warden-server/lib/Warden.pm
+++ b/src/warden-server/lib/Warden.pm
@@ -90,6 +90,7 @@ sub getAltNames
       push(@an_array, $DBH->quote($tmp));
     }
   }
+
   my $alt_names = join(',', @an_array);
   return $alt_names;
 }
@@ -116,7 +117,7 @@ sub authorizeClient
  }
 
   # check if db handler is defined
-  if (!defined $sth) {
+  unless (defined $sth) {
     sendMsg("err",
             "Cannot prepare authorization statement in function 'authorizeClient': $DBH->errstr",
 	    "Internal 'prepare' server error");
@@ -125,14 +126,14 @@ sub authorizeClient
   # execute query for two or none params functions
   if ($function_name eq 'saveNewEvent' || $function_name eq 'getNewEvents') {
     $rc = $sth->execute($service_type, $client_type);
-    if (!$rc) {
+    unless ($rc) {
       sendMsg("err",
               "Cannot execute authorization statement in function 'authorizeClient': $DBH->errstr",
 	      "Internal 'execute' server error");
     }
   } else {
     $rc = $sth->execute;
-    if (!$rc) {
+    unless ($rc) {
       sendMsg("err",
               "Cannot execute authorization statement in function 'authorizeClient': $DBH->errstr",
               "Internal 'execute' server error");
@@ -143,7 +144,7 @@ sub authorizeClient
   my ($client_id, $ip_net_client, $receive_own, $ip_net_client_list);
   my $correct_ip_source = 0;
   my %ret;
-  while(($client_id, $ip_net_client, $receive_own)  = $sth->fetchrow()) {
+  while(($client_id, $ip_net_client, $receive_own) = $sth->fetchrow()) {
     my $ip_net_client_list = Net::CIDR::Lite->new->add($ip_net_client);
 
     $ret{'client_id'}	= $client_id;
@@ -164,7 +165,7 @@ sub authorizeClient
   }
 
   # check if client has IP from registered CIDR
-  if (!$correct_ip_source) {
+  unless ($correct_ip_source) {
     sendMsg ("err",
              "Unauthorized access to function '$function_name' from [IP: '$ip'; CN(AN): $alt_names; Client_type: '$client_type'; Service/Type: '$service_type'] - access to Warden server '$ENV{'SERVER_NAME'}' from another subnet than '$ip_net_client'",
              "Access denied - access to Warden server '$ENV{'SERVER_NAME'}' from unauthorized subnet '$ip_net_client'");
@@ -215,16 +216,17 @@ sub saveNewEvent
   my %client = authorizeClient($alt_names, $ip, $service, $client_type, $function_name);
   if (defined %client) {
     sendMsg("debug",
-            "Incoming event: [service: '$service', detected: '$detected', type: '$type', source_type: '$source_type', source: '$source', target_proto: '$target_proto', target_port: '$target_port', attack_scale: '$attack_scale', note: '$note', priority: '$priority', timeout: '$timeout']",
+            "Incoming event: [client_id: '$client{'client_id'}', service: '$service', detected: '$detected', type: '$type', source_type: '$source_type', source: '$source', target_proto: '$target_proto', target_port: '$target_port', attack_scale: '$attack_scale', note: '$note', priority: '$priority', timeout: '$timeout']",
              undef);
+
     if (%WardenCommon::VALID_STRINGS) {	# check if hash is not empty - use VALIDATION HASH
       if (!(exists $WardenCommon::VALID_STRINGS{'type'} && grep $type eq $_, @{$WardenCommon::VALID_STRINGS{'type'}})) {
         sendMsg("err",
-                "Unknown event type from [IP: '$ip'; CN(AN): $alt_names; Service: '$service'; Type: '$type']",
+                "Unknown event_type from client '$client{'client_id'}': '$type'",
 	        "Unknown event type: '$type'");
       } elsif (!(exists $WardenCommon::VALID_STRINGS{'source_type'} && grep $source_type eq $_, @{$WardenCommon::VALID_STRINGS{'source_type'}})) {
         sendMsg("err",
-                "Unknown source type from [IP '$ip'; CN(AN): $alt_names; Service: '$service'; Source_type: '$source_type']",
+                "Unknown source_type from client '$client{'client_id'}': '$source_type'",
                 "Unknown source type: '$source_type'");
       }
     }
@@ -232,7 +234,7 @@ sub saveNewEvent
     # http://my.safaribooksonline.com/book/programming/regular-expressions/9780596802837/4dot-validation-and-formatting/id2983571
     if ($detected !~ /^((?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[0-1]|0[1-9]|[1-2][0-9])T(2[0-3]|[0-1][0-9]):([0-5][0-9]):([0-5][0-9])(\.[0-9]+)?(Z|[+-](?:2[0-3]|[0-1][0-9]):[0-5][0-9])?/) {
       sendMsg("err",
-              "Unknown detected time format from [IP: '$ip'; CN(AN): $alt_names; Service: '$service'; Detected: '$detected']",
+              "Unknown detected time format from client '$client{'client_id'}': '$detected'",
               "Unknown detected time format: '$detected'");
     }
 
@@ -241,33 +243,38 @@ sub saveNewEvent
       push(@change_list, "target_port: '$target_port'");
       $target_port = undef;
     }
+
     if (defined $attack_scale && $attack_scale !~ /^\d+\z/) {
       push(@change_list, "attack_scale: '$attack_scale'");
       $attack_scale = undef;
     }
+
     if (defined $priority && $priority !~ /^\d+\z/) {
       push(@change_list, "priority: '$priority'");
       $priority = undef;
     }
+
     if (defined $timeout && $timeout !~ /^\d+\z/) {
       push(@change_list, "timeout: '$timeout'");
       $timeout = undef;
     }
+
     my $change_string = join(", ", @change_list);
-    if ($change_string ne "") {
+    unless ($change_string eq "") {
       sendMsg("info",
-              "Unknown event items detected {originaly - $change_string} received in $received from [IP '$ip'; CN(AN): $alt_names; Service: '$service'; Type: '$type'; Detected: $detected]",
+              "Unknown other event entries from client '$client{'client_id'}': ($change_string)",
               undef);
     }
 
     $sth = $DBH->prepare("INSERT INTO events VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?);");
-    if (!defined $sth) {
+    unless (defined $sth) {
       sendMsg("err",
               "Cannot prepare statement in function '$function_name': $DBH->errstr",
 	      "Internal 'prepare' server error");
     }
+
     $rc = $sth->execute(undef, $detected, $received, $type, $source_type, $source, $target_proto, $target_port, $attack_scale, $note, $priority, $timeout, $valid, $client{'client_id'});
-    if (!$rc) {
+    unless ($rc) {
       sendMsg("err",
               "Cannot execute statement in function '$function_name': $DBH->errstr",
 	      "Internal 'execute' server error");
@@ -283,15 +290,14 @@ sub saveNewEvent
 sub getNewEvents
 {
   my ($class, $data) = @_;
-  my ($sth, $sth2, $rc, @events, $event, @ids);
-  my ($id, $hostname, $service, $detected, $type, $source_type, $source, $target_proto, $target_port, $attack_scale, $note, $priority, $timeout, $client_id);
+  my ($sth, $rc, @events, $event, @ids, $used_limit);
 
   # client network information
   my $cn	= $ENV{'SSL_CLIENT_S_DN_CN'};
   my $alt_names	= getAltNames(undef);
   my $ip	= $ENV{'REMOTE_ADDR'};
 
-  my $client_type	= 'r';	# incoming client MUST be sender
+  my $client_type	= 'r';	# incoming client MUST be receiver
   my $function_name	= 'getNewEvents';
 
   # parse SOAP data object
@@ -300,139 +306,82 @@ sub getNewEvents
   my $max_rcv_events_limit 	= $data->{'MAX_RCV_EVENTS_LIMIT'}; # client events limit
 
   # comparison of client and server limit - which can be used
-  my $used_limit;
   if (defined $max_rcv_events_limit && $max_rcv_events_limit < $WardenCommon::MAX_EVENTS_LIMIT) {
     $used_limit = $max_rcv_events_limit;
   } else {
     $used_limit = $WardenCommon::MAX_EVENTS_LIMIT;
   }
 
+  # authorize incoming client
   my %client = authorizeClient($alt_names, $ip, $requested_type, $client_type, $function_name);
-  if(defined %client) {
-    if ($client{'receive_own'} eq 't') {
-      if ($requested_type eq '_any_') {
-        $sth = $DBH->prepare("SELECT * FROM events WHERE type != 'test' AND id > ? AND valid = 't' ORDER BY id ASC LIMIT ?;");
-        if (!defined $sth) {
-	  sendMsg("err",
-                  "Cannot prepare ROE-ANY statement in function '$function_name': $DBH->errstr",
-                  "Internal 'prepare' server error");
-        }
-        $rc = $sth->execute($last_id, $used_limit);
-        if (!$rc) {
-          sendMsg("err",
-                  "Cannot execute ROE-ANY statement in function '$function_name': $DBH->errstr",
-	          "Internal 'execute' server error");
-        }
-      } else {
-        $sth = $DBH->prepare("SELECT * FROM events WHERE type != 'test' AND id > ? AND type = ? AND valid = 't' ORDER BY id ASC LIMIT ?;");
-        if (!defined $sth) {
-	  sendMsg("err",
-	          "Cannot prepare ROE statement in function '$function_name': $DBH->errstr",
-                  "Internal 'prepare' server error");
-	}
-	$rc = $sth->execute($last_id, $requested_type, $used_limit);
-        if (!$rc) {
-          sendMsg("err",
-                  "Cannot execute ROE statement in function '$function_name': $DBH->errstr",
-	          "Internal 'execute' server error");
-        }
-      }
-    } else {
-      if ($requested_type eq '_any_') {
-        $sth = $DBH->prepare("SELECT * FROM events e, clients c WHERE e.type != 'test' AND e.id > ? AND e.valid = 't' AND e.client_id = c.client_id AND c.hostname NOT LIKE ? ORDER BY id ASC LIMIT ?;");
-        if (!defined $sth) {
-	  sendMsg("err",
-	          "Cannot prepare ANY statement in function '$function_name': $DBH->errstr",
-		  "Internal 'prepare' server error");
-	}
-        my ($domain) = $cn =~ /([^\.]+\.[^\.]+)$/;
-        $domain = '%' . $domain;
-        $rc = $sth->execute($last_id, $domain, $used_limit);
-        if (!$rc) {
-          sendMsg("err",
-                  "Cannot execute ANY statement in function '$function_name': $DBH->errstr",
-	          "Internal 'execute' server error");
-        }
-      } else {
-        $sth = $DBH->prepare("SELECT * FROM events e, clients c WHERE e.type != 'test' AND e.id > ? AND e.type = ? AND e.valid = 't' AND e.client_id = c.client_id AND c.hostname NOT LIKE ? ORDER BY id ASC LIMIT ?;");
-        if (!defined $sth) {
-	  sendMsg("err",
-	          "Cannot prepare statement in function '$function_name': $DBH->errstr",
-		  "Internal 'prepare' server error");
-	}
-        my ($domain) = $cn =~ /([^\.]+\.[^\.]+)$/;
-	$domain = '%' . $domain;
-        $rc = $sth->execute($last_id, $requested_type, $domain, $used_limit);
-        if (!$rc) {
-          sendMsg("err",
-                  "Cannot execute statement in function '$function_name': $DBH->errstr",
-	          "Internal 'execute' server error");
-        }
-      }
+  if (defined %client) {
+    my $query = "SELECT id, hostname, service, detected, events.type, source_type, source, target_proto, target_port, attack_scale, note, priority, timeout FROM events INNER JOIN clients ON events.client_id = clients.client_id WHERE events.type != 'test' AND id > ? AND events.valid = 't'";
+    my @params = ($last_id);
+
+    unless ($requested_type eq '_any_') {
+      $query .= " AND events.type = ?";
+      push(@params, $requested_type);
+    }
+
+    unless ($client{'receive_own'} eq 't') {
+      my ($domain) = $cn =~ /([^\.]+\.[^\.]+)$/;
+      $query .= " AND hostname NOT LIKE ?";
+      push(@params, '%' . $domain);
+    }
+
+    $query .= " ORDER BY id ASC LIMIT ?;";
+    push(@params, $used_limit);
+
+    $sth = $DBH->prepare($query);
+    unless (defined $sth) {
+      sendMsg("err",
+              "Cannot prepare statement in function '$function_name': $DBH->errstr",
+              "Internal 'prepare' server error");
+    }
+
+    $rc = $sth->execute(@params);
+    unless (defined $rc) {
+      sendMsg("err",
+              "Cannot execute statement in function '$function_name': $DBH->errstr",
+              "Internal 'execute' server error");
     }
 
     # obtain items of events stored in events table
     while (my @result = $sth->fetchrow()) {
-      $id 		= $result[0];
-      $detected 	= $result[1];
-      $type 		= $result[3];
-      $source_type 	= $result[4];
-      $source	 	= $result[5];
-      $target_proto	= $result[6];
-      $target_port 	= $result[7];
-      $attack_scale	= $result[8];
-      $note 		= $result[9];
-      $priority 	= $result[10];
-      $timeout	 	= $result[11];
-      $client_id        = $result[13];
-
-      # obtain hostname and service of events based on client_id from clients table
-      $sth2 = $DBH->prepare("SELECT hostname, service FROM clients WHERE client_id = ?;");
-      if (!defined $sth2) {
-        sendMsg("err",
-                "Cannot prepare statement in function '$function_name': $DBH->errstr",
-                "Internal 'prepare' server error");
-      }
-      $rc = $sth2->execute($client_id);
-      if (!$rc) {
-        sendMsg("err",
-                "Cannot execute statement in function '$function_name': $DBH->errstr",
-                "Internal 'execute' server error");
-      }
-      ($hostname, $service) = $sth2->fetchrow();
-
-      # create SOAP data object
+      # create SOAP data object set values
       $event = SOAP::Data->name(event => \SOAP::Data->value(
-        SOAP::Data->name(ID		=> $id),
-        SOAP::Data->name(HOSTNAME	=> $hostname),
-        SOAP::Data->name(SERVICE	=> $service),
-        SOAP::Data->name(DETECTED	=> $detected),
-        SOAP::Data->name(TYPE		=> $type),
-        SOAP::Data->name(SOURCE_TYPE	=> $source_type),
-        SOAP::Data->name(SOURCE		=> $source),
-        SOAP::Data->name(TARGET_PROTO	=> $target_proto),
-        SOAP::Data->name(TARGET_PORT	=> $target_port),
-        SOAP::Data->name(ATTACK_SCALE	=> $attack_scale),
-        SOAP::Data->name(NOTE		=> $note),
-        SOAP::Data->name(PRIORITY	=> $priority),
-        SOAP::Data->name(TIMEOUT	=> $timeout)
-      ));
+        SOAP::Data->name(ID		=> $result[0]),
+        SOAP::Data->name(HOSTNAME	=> $result[1]),
+        SOAP::Data->name(SERVICE	=> $result[2]),
+        SOAP::Data->name(DETECTED	=> $result[3]),
+        SOAP::Data->name(TYPE		=> $result[4]),
+        SOAP::Data->name(SOURCE_TYPE	=> $result[5]),
+        SOAP::Data->name(SOURCE		=> $result[6]),
+        SOAP::Data->name(TARGET_PROTO	=> $result[7]),
+        SOAP::Data->name(TARGET_PORT	=> $result[8]),
+        SOAP::Data->name(ATTACK_SCALE	=> $result[9]),
+        SOAP::Data->name(NOTE		=> $result[10]),
+        SOAP::Data->name(PRIORITY	=> $result[11]),
+        SOAP::Data->name(TIMEOUT	=> $result[12]),
+        ),
+      );
       push(@events, $event);
-      push(@ids, $id);
+      push(@ids, $result[0]);
     }
 
     # log sent ID of events
     if (scalar @events != 0) {
       if (scalar @ids == 1) {
         sendMsg("info",
-	        "Sent 1 event [#$ids[0]] to [IP: '$ip'; CN(AN): $alt_names; Client_limit: '$max_rcv_events_limit'; Requested_type: '$requested_type'; ROE: '$client{'receive_own'}']",
+	        "Sent 1 event [#$ids[0]] of type '$requested_type' to client '$client{'client_id'}'",
 	        undef);
       } else {
         sendMsg("info",
-                "Sent " . scalar @ids . " events [#$ids[0] - #$ids[-1]] to [IP: '$ip'; CN(AN): $alt_names; Client_limit: '$max_rcv_events_limit'; Requested_type: '$requested_type'; ROE: '$client{'receive_own'}']",
+                "Sent " . scalar @ids . " events [#$ids[0] - #$ids[-1]] of type '$requested_type' to client '$client{'client_id'}'",
 	        undef);
       }
     }
+
     return @events;
   }
 } # END of getNewEvents
@@ -458,17 +407,19 @@ sub getLastId
   my %client = authorizeClient($alt_names, $ip, $service, $client_type, $function_name);
   if (defined %client) {
     my $sth = $DBH->prepare("SELECT max(id) FROM events;");
-    if (!defined $sth) {
+    unless (defined $sth) {
       sendMsg("err",
               "Cannot prepare statement in function '$function_name': $DBH->errstr",
               "Internal 'prepare' server error");
     }
+
     my $rc = $sth->execute;
-    if (!$rc) {
+    unless ($rc) {
       sendMsg("err",
               "Cannot execute statement in function '$function_name': $DBH->errstr",
               "Internal 'execute' server error");
     }
+
     my $result = $sth->fetchrow();
     return $result;
   }
@@ -483,7 +434,6 @@ sub getClientInfo
 {
   my ($class, $data) = @_;
   my (@clients, $client);
-  my ($client_id, $hostname, $registered, $requestor, $service, $client_type, $type, $receive_own_events, $description_tags, $ip_net_client);
 
   # client network information
   my $cn	= $ENV{'SSL_CLIENT_S_DN_CN'};
@@ -498,47 +448,39 @@ sub getClientInfo
   my %client = authorizeClient($alt_names, $ip, $service, $client_type, $function_name);
   if (defined %client) {
     my $sth = $DBH->prepare("SELECT * FROM clients WHERE valid = 't' ORDER BY client_id ASC;");
-    if (!defined $sth) {
+    unless (defined $sth) {
       sendMsg("err",
             "Cannot prepare statement in function '$function_name': $DBH->errstr",
             "Internal 'prepare' server error");
     }
+
     my $rc = $sth->execute;
-    if (!$rc) {
+    unless ($rc) {
       sendMsg("err",
               "Cannot execute statement in function '$function_name': $DBH->errstr",
               "Internal 'execute' server error");
     }
 
     while ( my @result = $sth->fetchrow() ) {
-      $client_id		= $result[0];
-      $hostname			= $result[1];
-      $registered		= $result[2];
-      $requestor		= $result[3];
-      $service			= $result[4];
-      $client_type		= $result[5];
-      $type 			= $result[6];
-      $receive_own_events	= $result[7];
-      $description_tags		= $result[8];
-      $ip_net_client		= $result[9];
-
       $client = SOAP::Data->name(client => \SOAP::Data->value(
-      SOAP::Data->name(CLIENT_ID		=> $client_id),
-      SOAP::Data->name(HOSTNAME			=> $hostname),
-      SOAP::Data->name(REGISTERED		=> $registered),
-      SOAP::Data->name(REQUESTOR		=> $requestor),
-      SOAP::Data->name(SERVICE			=> $service),
-      SOAP::Data->name(CLIENT_TYPE		=> $client_type),
-      SOAP::Data->name(TYPE			=> $type),
-      SOAP::Data->name(RECEIVE_OWN_EVENTS	=> $receive_own_events),
-      SOAP::Data->name(DESCRIPTION_TAGS		=> $description_tags),
-      SOAP::Data->name(IP_NET_CLIENT		=> $ip_net_client),
-      ));
+        SOAP::Data->name(CLIENT_ID		=> $result[0]),
+        SOAP::Data->name(HOSTNAME		=> $result[1]),
+        SOAP::Data->name(REGISTERED		=> $result[2]),
+        SOAP::Data->name(REQUESTOR		=> $result[3]),
+        SOAP::Data->name(SERVICE		=> $result[4]),
+        SOAP::Data->name(CLIENT_TYPE		=> $result[5]),
+        SOAP::Data->name(TYPE			=> $result[6]),
+        SOAP::Data->name(RECEIVE_OWN_EVENTS	=> $result[7]),
+        SOAP::Data->name(DESCRIPTION_TAGS	=> $result[8]),
+        SOAP::Data->name(IP_NET_CLIENT		=> $result[9]),
+        ),
+      );
       push(@clients, $client);
     }
+
     my $sum = scalar @clients;
     sendMsg("info",
-            "Sent information about $sum registered clients from Warden server '$ENV{'SERVER_NAME'}'",
+            "Sent information about $sum registered clients from Warden server '$ENV{'SERVER_NAME'}' to client '$client{'client_id'}'",
             undef);
     return @clients;
   }
-- 
GitLab