From f7f5f09f5ce1bab6b421c86e6da308b925390cd4 Mon Sep 17 00:00:00 2001
From: Tomas Plesnik <plesnik@ics.muni.cz>
Date: Sat, 25 Feb 2012 03:39:06 +0100
Subject: [PATCH] pridano podpora pro alternativni domenova jmena z SSL
 certifikatu; zmena verze na 0.1

---
 src/warden-server/bin/warden-server.pl | 67 +++++++++++++++++++-------
 1 file changed, 50 insertions(+), 17 deletions(-)

diff --git a/src/warden-server/bin/warden-server.pl b/src/warden-server/bin/warden-server.pl
index d585a23..c40143a 100755
--- a/src/warden-server/bin/warden-server.pl
+++ b/src/warden-server/bin/warden-server.pl
@@ -48,7 +48,7 @@ use Data::Dumper;
 use Net::CIDR::Lite;
 use DateTime;
 
-our $VERSION = "1.0";
+our $VERSION = "0.1";
 
 ################################################################################
 #			CONFIG FILE VARIABLES
@@ -167,6 +167,29 @@ sub sslErrorHandler
 } # End of sslErrorHandler
 
 
+#-------------------------------------------------------------------------------
+# altNamesFilter - parse hostnames from subjectAltNames array for SQL
+#		   IN operator in database query
+#-------------------------------------------------------------------------------
+sub altNamesFilter
+{
+  my $alt_names_array_ref = shift;
+  my @alt_names_array = @$alt_names_array_ref;
+
+  our $CN;
+  my @an_array;
+
+  push @an_array, $DBH->quote($CN);
+  my $i = 1;
+  while ($i <= scalar @alt_names_array) {
+    push @an_array, $DBH->quote($alt_names_array[$i]);
+    $i+=2;
+  }
+  my $an_filter = join(',', @an_array);
+  return $an_filter;
+}
+
+
 
 ################################################################################
 # 				SOAP Functions
@@ -181,8 +204,10 @@ sub saveNewEvent
   my ($sth, $cidr_list);
 
   # variables defined by server
-  our $IP;	# IP address of sender
-  our $CN;	# common name of sender
+  our $IP;		# IP address of sender
+  our $CN;		# common name of sender
+  our $AN_FILTER;	# alternate names of sender
+
   my $cn_db = $DBH->quote($CN);
 
   # variables defined by server
@@ -220,15 +245,15 @@ sub saveNewEvent
   # Authorization of incomming client
   #-----------------------------------------------------------------------------
 
-  # obtain cidr based on rigth common name, service and client_type
-  $sth = $DBH->prepare("SELECT ip_net_client FROM clients WHERE hostname = $cn_db AND service = $service_db AND client_type = $client_type_db;");
+  # obtain cidr based on rigth common name and alternate names, service and client_type
+  $sth = $DBH->prepare("SELECT hostname, ip_net_client FROM clients WHERE hostname IN ($AN_FILTER) AND service = $service_db AND client_type = $client_type_db limit 1;");
   if ( !defined $sth ) {die("Cannot prepare authorization statement in saveNewEvent: $DBI::errstr\n")}
   $sth->execute;
-  my $cidr = $sth->fetchrow();
+  my ($an, $cidr) = $sth->fetchrow();
 
   # check if client is registered
   if (!defined $cidr) {
-    write2log ("err", "Unauthorized access to saveNewEvent from: $IP ($CN) - client is not registered");
+    write2log ("err", "Unauthorized access to saveNewEvent from: $IP (CN: $CN; AN: $an) - client is not registered");
     die("Access denied - client is not registered at warden server!");
   } else {
     $cidr_list = Net::CIDR::Lite
@@ -238,7 +263,7 @@ sub saveNewEvent
 
   # check if client has IP from registered CIDR
   if (!$cidr_list->bin_find($IP)) {
-    write2log ("err", "Unauthorized access to saveNewEvent from: $IP ($CN) - access from bad subnet: $cidr");
+    write2log ("err", "Unauthorized access to saveNewEvent from: $IP (CN: $CN; AN: $an) - access from bad subnet: $cidr");
     die("Access denied - access from bad subnet!");
   } else {
 
@@ -252,7 +277,7 @@ sub saveNewEvent
     if ( !defined $sth ) {die("Cannot prepare last ID statement in saveNewEvent: $DBI::errstr\n")}
     $sth->execute;
     my $id= $sth->fetchrow();
-    write2log ("info", "Stored new event (#$id) from $IP ($CN)");
+    write2log ("info", "Stored new event (#$id) from $IP (CN: $CN; AN: $an)");
 
     if (! defined $id) {
       write2log ("err", "Event from $IP ($CN) was not save: INSERT INTO events VALUES (null,$cn_db,$service_db,$detected_db,$received_db,$type_db,$source_type_db,$source_db,$target_proto_db,$target_port_db,$attack_scale_db,$note_db,$priority_db,$timeout_db,$valid_db);");
@@ -274,8 +299,10 @@ sub getNewEvents
   my ($id, $hostname, $service, $detected, $type, $source_type, $source, $target_proto, $target_port, $attack_scale, $note, $priority, $timeout);
 
   # variables defined by server
-  our $IP;	# IP address of sender
-  our $CN;	# common name of sender
+  our $IP;		# IP address of receiver
+  our $CN;		# common name of receiver
+  our $AN_FILTER;	# alternate name of receiver
+
   my $cn_db 		= $DBH->quote($CN);
   my $client_type	= "r";	# incoming client MUST be sender
   my $client_type_db	= $DBH->quote($client_type);
@@ -291,14 +318,14 @@ sub getNewEvents
   #-----------------------------------------------------------------------------
 
   # obtain cidr based on rigth common name, service and client_type
-  $sth = $DBH->prepare("SELECT receive_own_events, ip_net_client FROM clients WHERE hostname = $cn_db AND type = $requested_type_db AND client_type = $client_type_db;");
+  $sth = $DBH->prepare("SELECT hostname, receive_own_events, ip_net_client FROM clients WHERE hostname IN ($AN_FILTER) AND type = $requested_type_db AND client_type = $client_type_db limit 1;");
   if ( !defined $sth ) {die("Cannot prepare authorization statement in getNewEvents: $DBI::errstr\n")}
   $sth->execute;
-  my ($receive_own_events, $cidr) = $sth->fetchrow();
+  my ($an, $receive_own_events, $cidr) = $sth->fetchrow();
 
   # check if client is registered
   if (!defined $cidr) {
-    write2log ("err", "Unauthorized access to getNewEvents from: $IP ($CN) - client is not registered");
+    write2log ("err", "Unauthorized access to getNewEvents from: $IP (CN: $CN; AN: $an) - client is not registered");
     die("Access denied - client is not registered at warden server!");
   } else {
     $cidr_list = Net::CIDR::Lite
@@ -308,7 +335,7 @@ sub getNewEvents
 
   # check if client has IP from registered CIDR
   if (!$cidr_list->bin_find($IP)) {
-    write2log ("err", "Unauthorized access to getNewEvents from: $IP ($CN) - access from bad subnet: $cidr");
+    write2log ("err", "Unauthorized access to getNewEvents from: $IP (CN: $CN; AN: $an) - access from bad subnet: $cidr");
     die("Access denied - access from bad subnet!");
   } else {
 
@@ -361,7 +388,7 @@ sub getNewEvents
 
     # log sent ID of events
     if (scalar(@events)!=0) {
-      write2log("info", "Sent events with ID: [@ids] to $IP ($CN)");
+      write2log("info", "Sent events with ID: [@ids] to $IP (CN: $CN; AN: $an)");
     }
     return @events;
   }
@@ -632,7 +659,7 @@ sub getStatus
     my $db_size = Format::Human::Bytes::base10(-s $db);
 
     # sum of records in table events
-    $sth = $DBH->prepare("SELECT count(*) FROM events;");
+    $sth = $DBH->prepare("SELECT count(*) FROM events WHERE valid = 't';");
     if (!defined $sth) { die("Cannot prepare statement in getStatus: $DBI::errstr\n") }
     $sth->execute;
     my $events_sum = $sth->fetchrow();
@@ -815,7 +842,10 @@ while ($die_now != 1)
 {
   my $socket = $server->accept();
   next if (!$socket);
+
   our $CN = $socket->peer_certificate("cn");
+  my @alt_names_array = $socket->peer_certificate("subjectAltNames");
+  our $AN_FILTER = altNamesFilter(\@alt_names_array);
   our $IP = $socket->peerhost;
   our $LOCAL_IP = $socket->sockhost;
 
@@ -833,6 +863,9 @@ while ($die_now != 1)
   $socket->close;
   undef($socket);
   undef($CN);
+  undef($AN_FILTER);
+  undef($IP);
+  undef($LOCAL_IP);
 }
 
 
-- 
GitLab