diff --git a/src/warden-server/lib/Warden.pm b/src/warden-server/lib/Warden.pm index e01884952be35737961d788502c37180e91fee14..16cb6d5ecfa714f2bed4f9506c818afb6211db66 100755 --- a/src/warden-server/lib/Warden.pm +++ b/src/warden-server/lib/Warden.pm @@ -121,64 +121,6 @@ sub getAltNames } -#------------------------------------------------------------------------------- -# authorizeClient - authorize client by CN,AN and source IP range -#------------------------------------------------------------------------------- - -sub authorizeClient -{ - my ($alt_names, $ip, $service_type, $client_type, $function_name) = @_; - - my $sth; - # obtain cidr based on rigth common name and alternate names, service and client_type - if($function_name eq 'saveNewEvent') { - $sth = $DBH->prepare_cached("SELECT hostname, ip_net_client, receive_own_events - FROM clients WHERE hostname IN ($alt_names) AND service = ? AND client_type = ? - ORDER BY SUBSTRING_INDEX(ip_net_client,'/', -1) DESC;"); - } - elsif($function_name eq 'getNewEvents') { - $sth = $DBH->prepare_cached("SELECT hostname, ip_net_client, receive_own_events - FROM clients WHERE hostname IN ($alt_names) AND type = ? AND client_type = ? - ORDER BY SUBSTRING_INDEX(ip_net_client,'/', -1) DESC;"); - } - - if (!defined $sth) { die("Cannot prepare authorization statement in $function_name: $DBI::errstr\n")} - $sth->execute($service_type, $client_type); - - my ($an, $cidr, $receive_own, $cidr_list); - my $correct_ip_source = 0; - my %ret; - - while(($an, $cidr, $receive_own) = $sth->fetchrow()) { - my $cidr_list = Net::CIDR::Lite-> new -> add($cidr); - - $ret{'dns'} = $an; - $ret{'cidr'} = $cidr; - $ret{'receive_own'} = $receive_own; - - if ($cidr_list->bin_find($ip)) { - $correct_ip_source = 1; - last; - } - }; - - # check if client is registered - if ($sth->rows == 0) { - write2log ("err", "Unauthorized access to $function_name from: $ip (CN(AN): $alt_names) - client is not registered"); - die("Access denied - client is not registered at warden server!"); - return undef; - } - - # check if client has IP from registered CIDR - if (!$correct_ip_source) { - write2log ("err", "Unauthorized access to $function_name from: $ip (CN(AN): $alt_names) - access from bad subnet: " . $ret{'cidr'}); - die("Access denied - access from unauthorized subnet!"); - return undef; - } - - return %ret; -} - ################################################################################ # SOAP Functions @@ -205,38 +147,42 @@ sub saveNewEvent # parse object (event) parameters my $service = $data->{'SERVICE'}; my $detected = $data->{'DETECTED'}; - my $type = $data->{'TYPE'}; + my $type = $data->{'TYPE'}; my $source_type = $data->{'SOURCE_TYPE'}; my $source = $data->{'SOURCE'}; my $target_proto = $data->{'TARGET_PROTO'}; my $target_port = $data->{'TARGET_PORT'}; my $attack_scale = $data->{'ATTACK_SCALE'}; - my $note = $data->{'NOTE'}; + my $note = $data->{'NOTE'}; my $priority = $data->{'PRIORITY'}; my $timeout = $data->{'TIMEOUT'}; - my %client = authorizeClient($alt_names, $ip, $service, $client_type, 'saveNewEvent'); - if(defined %client) { + # 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 ($alt_names) AND service = ? AND client_type = ? LIMIT 1;"); + if (!defined $sth) {die("Cannot prepare authorization statement in saveNewEvent: $DBI::errstr\n")} + $sth->execute($service, $client_type); + my ($an, $cidr) = $sth->fetchrow(); + + # check if client is registered + if (!defined $cidr) { + 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 + -> new + -> add($cidr); + } + + # check if client has IP from registered CIDR + if (!$cidr_list->bin_find($ip)) { + write2log ("err", "Unauthorized access to saveNewEvent from: $ip (CN: $cn; AN: $an) - access from bad subnet: $cidr"); + die("Access denied - access from unauthorized subnet!"); + } else { # insert new events into DB - $sth=$DBH->prepare_cached("INSERT INTO events VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);"); + $sth=$DBH->prepare("INSERT INTO events VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);"); if (!defined $sth) {die("Cannot do insert statement in saveNewEvent: $DBI::errstr\n")} - $sth->execute(undef, $client{'dns'}, $service, $detected, $received, $type, $source_type, $source, $target_proto, $target_port, $attack_scale, $note, $priority, $timeout, $valid); - - ## log last inserted ID - #$sth = $DBH->prepare("SELECT last_insert_id()"); - #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: $cn; AN: $an)"); - - #if (! defined $id) { - # write2log ("err", "Event from $ip ($cn) was not save: INSERT INTO events VALUES (NULL,$cn,$service,$detected,$received,$type,$source_type,$source,$target_proto,$target_port,$attack_scale,$note,$priority,$timeout,$valid);"); - # die("Event was not save at warden server - database return empty ID!"); - # return 0; - #} else { - return 1; - # } + $sth->execute(undef, $cn, $service, $detected, $received, $type, $source_type, $source, $target_proto, $target_port, $attack_scale, $note, $priority, $timeout, $valid); } } # END of saveNewEvent @@ -251,21 +197,40 @@ sub getNewEvents my ($id, $hostname, $service, $detected, $type, $source_type, $source, $target_proto, $target_port, $attack_scale, $note, $priority, $timeout); # client network information - my $cn = $ENV{'SSL_CLIENT_S_DN_CN'}; + my $cn = $ENV{'SSL_CLIENT_S_DN_CN'}; my $alt_names = getAltNames(undef); - my $ip = $ENV{'REMOTE_ADDR'}; + my $ip = $ENV{'REMOTE_ADDR'}; my $client_type = "r"; # incoming client MUST be sender # parse SOAP data object - my $requested_type = $data->{'REQUESTED_TYPE'}; - my $last_id = $data->{'LAST_ID'}; + my $requested_type = $data->{'REQUESTED_TYPE'}; + my $last_id = $data->{'LAST_ID'}; - my %client = authorizeClient($alt_names, $ip, $requested_type, $client_type, 'getNewEvents'); - if(defined %client) { + # obtain cidr based on rigth common name, service and client_type + $sth = $DBH->prepare("SELECT hostname, receive_own_events, ip_net_client FROM clients WHERE hostname IN ($alt_names) AND type = ? AND client_type = ? LIMIT 1;"); + if (!defined $sth) {die("Cannot prepare authorization statement in getNewEvents: $DBI::errstr\n")} + $sth->execute($requested_type, $client_type); + 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: $cn; AN: $an) - client is not registered"); + die("Access denied - client is not registered at warden server!"); + } else { + $cidr_list = Net::CIDR::Lite + -> new + -> add($cidr); + } + + # check if client has IP from registered CIDR + if (!$cidr_list->bin_find($ip)) { + write2log ("err", "Unauthorized access to getNewEvents from: $ip (CN: $cn; AN: $an) - access from bad subnet: $cidr"); + die("Access denied - access from unathorized subnet!"); + } else { # check if client want your own events or not - if ($client{'receive_own'} eq 't') { + if ($receive_own_events eq 't') { $sth = $DBH->prepare("SELECT * FROM events WHERE type != 'test' AND id > ? AND type = ? AND valid = 't' ORDER BY id ASC;"); if (!defined $sth) {die("Cannot prepare ROE statement in getNewEvents: $DBI::errstr\n")} $sth->execute($last_id, $requested_type); @@ -288,19 +253,19 @@ sub getNewEvents $source = $result[7]; $target_proto = $result[8]; $target_port = $result[9]; - $attack_scale = $result[10]; + $attack_scale = $result[10]; $note = $result[11]; $priority = $result[12]; $timeout = $result[13]; # create SOAP data object $event = SOAP::Data->name(event => \SOAP::Data->value( - SOAP::Data->name(ID => $id), + 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_TYPE => $source_type), SOAP::Data->name(SOURCE => $source), SOAP::Data->name(TARGET_PROTO => $target_proto), SOAP::Data->name(TARGET_PORT => $target_port), @@ -316,9 +281,9 @@ sub getNewEvents # log sent ID of events if (scalar @events != 0) { if (scalar @ids == 1) { - write2log("info", "Sent 1 events [#$ids[0]] to $ip (CN(AN): $alt_names)"); + write2log("info", "Sent 1 events [#$ids[0]] to $ip (CN: $cn; AN: $an)"); } else { - write2log("info", "Sent " . scalar @ids . " events [#$ids[0] - #$ids[-1]] to $ip (CN(AN): $alt_names)"); + write2log("info", "Sent " . scalar @ids . " events [#$ids[0] - #$ids[-1]] to $ip (CN: $cn; AN: $an)"); } } return @events; @@ -373,7 +338,7 @@ sub registerSender my $ip_net_client = $data->{'IP_NET_CLIENT'}; # check if sender has been already registered - $sth = $DBH->prepare_cached("SELECT registered FROM clients WHERE hostname = ? AND requestor = ? AND service = ? AND client_type = ? AND type = ? AND receive_own_events = ? AND description_tags = ? AND ip_net_client = ? LIMIT 1;"); + $sth = $DBH->prepare("SELECT registered FROM clients WHERE hostname = ? AND requestor = ? AND service = ? AND client_type = ? AND type = ? AND receive_own_events = ? AND description_tags = ? AND ip_net_client = ? LIMIT 1;"); if (!defined $sth) {die("Cannot prepare check statement in registerSender: $DBI::errstr\n")} $sth->execute($hostname, $requestor, $service, $client_type, $type, $receive_own_events, $description_tags, $ip_net_client); my $result = $sth->fetchrow(); @@ -383,7 +348,7 @@ sub registerSender write2log ("err", "Attempt to re-register the sender"); die("Error - sender has already been registered at $result"); } else { - $sth = $DBH->prepare_cached("INSERT INTO clients VALUES (?,?,?,?,?,?,?,?,?,?);"); + $sth = $DBH->prepare("INSERT INTO clients VALUES (?,?,?,?,?,?,?,?,?,?);"); if (!defined $sth) {die("Cannot do statement in registerSender: $DBI::errstr\n")} $sth->execute(undef, $hostname, $registered, $requestor, $service, $client_type, $type, $receive_own_events, $description_tags, $ip_net_client); write2log("info", "New sender $hostname (service: $service, cidr: $ip_net_client) was registered"); @@ -393,9 +358,9 @@ sub registerSender } # END of registerSender -##----------------------------------------------------------------------------- -## registerReceiver - register new receiver -##----------------------------------------------------------------------------- +#----------------------------------------------------------------------------- +# registerReceiver - register new receiver +#----------------------------------------------------------------------------- sub registerReceiver { my ($class, $data) = @_; @@ -424,7 +389,7 @@ sub registerReceiver my $ip_net_client = $data->{'IP_NET_CLIENT'}; # check if receiver has been already registered - $sth = $DBH->prepare_cached("SELECT registered FROM clients WHERE hostname = ? AND requestor = ? AND service = ? AND client_type = ? AND type = ? AND receive_own_events = ? AND description_tags = ? AND ip_net_client = ? LIMIT 1;"); + $sth = $DBH->prepare("SELECT registered FROM clients WHERE hostname = ? AND requestor = ? AND service = ? AND client_type = ? AND type = ? AND receive_own_events = ? AND description_tags = ? AND ip_net_client = ? LIMIT 1;"); if (!defined $sth) {die("Cannot prepare check statement in registerReceiver: $DBI::errstr\n")} $sth->execute($hostname, $requestor, $service, $client_type, $type, $receive_own_events, $description_tags, $ip_net_client); my $result = $sth->fetchrow(); @@ -434,7 +399,7 @@ sub registerReceiver write2log ("err", "Attempt to re-register the receiver"); die("Error - receiver has already been registered at $result"); } else { - $sth = $DBH->prepare_cached("INSERT INTO clients VALUES (?,?,?,?,?,?,?,?,?,?);"); + $sth = $DBH->prepare("INSERT INTO clients VALUES (?,?,?,?,?,?,?,?,?,?);"); if (!defined($sth)) {die("Cannot do statement in registerReceiver: $DBI::errstr\n")} $sth->execute(undef, $hostname, $registered, $requestor, $service, $client_type, $type, $receive_own_events, $description_tags, $ip_net_client); write2log("info", "New receiver $hostname (type: $type, cidr: $ip_net_client: receive_own_events: $receive_own_events) was registered"); @@ -465,7 +430,7 @@ sub unregisterClient my $client_id = $data->{'CLIENT_ID'}; # check if receiver has been already registered - $sth = $DBH->prepare_cached("SELECT client_id, hostname, service, client_type FROM clients WHERE client_id = ? LIMIT 1;"); + $sth = $DBH->prepare("SELECT client_id, hostname, service, client_type FROM clients WHERE client_id = ? LIMIT 1;"); if (!defined $sth) {die("Cannot prepare check statement in unregisterClient: $DBI::errstr\n")} $sth->execute($client_id); my ($id, $hostname, $service, $client_type) = $sth->fetchrow(); @@ -476,18 +441,18 @@ sub unregisterClient die("Error - client (#$client_id) is not registered"); } else { if ($client_type eq 's') { - $sth = $DBH->prepare_cached("DELETE FROM clients WHERE client_id = ?;"); + $sth = $DBH->prepare("DELETE FROM clients WHERE client_id = ?;"); if (!defined $sth) {die("Cannot do delete statement of sender in unregisterClient: $DBI::errstr\n")} $sth->execute($client_id); - $sth = $DBH->prepare_cached("UPDATE events SET valid = 'f' where hostname = ? AND service = ?;"); + $sth = $DBH->prepare("UPDATE events SET valid = 'f' where hostname = ? AND service = ?;"); if (!defined $sth) {die("Cannot do unvalidation statement in unregisterClient: $DBI::errstr\n")} $sth->execute($hostname, $service); write2log("info", "Sender $hostname (client_id: $client_id, service: $service) was deleted and its data were invalidated" ); return 1; } else { - $sth = $DBH->prepare_cached("DELETE FROM clients WHERE client_id = ?;"); + $sth = $DBH->prepare("DELETE FROM clients WHERE client_id = ?;"); if (!defined $sth) {die("Cannot do delete statement of receiver in unregisterClient: $DBI::errstr\n")} $sth->execute($client_id); @@ -582,7 +547,7 @@ sub getStatus my $port = $ENV{'SERVER_PORT'}; # size of database events - $sth = $DBH->prepare_cached("SELECT data_length + index_length FROM information_schema.TABLES WHERE table_schema = ? AND TABLE_NAME = ?"); + $sth = $DBH->prepare("SELECT data_length + index_length FROM information_schema.TABLES WHERE table_schema = ? AND TABLE_NAME = ?"); $sth->execute('warden', 'events'); my $size = $sth->fetchrow(); my $db_size = (defined $size ? Format::Human::Bytes::base10($size) : "none"); @@ -650,13 +615,13 @@ sub getStatus while(($client_id, $hostname, $service) = $sth->fetchrow()) { my $sth2; # sum of stored events - $sth2 = $DBH->prepare_cached("SELECT count(*) FROM events WHERE hostname = ? AND service = ?;"); + $sth2 = $DBH->prepare("SELECT count(*) FROM events WHERE hostname = ? AND service = ?;"); if (!defined $sth2) {die("Cannot prepare statement in getStatus: $DBI::errstr\n")} $sth2->execute($hostname, $service); my $count = $sth2->fetchrow(); if (!defined $count) {$count = "none"} # timestamp of last stored event - $sth2 = $DBH->prepare_cached("SELECT max(received) FROM events WHERE hostname = ? AND service = ?;"); + $sth2 = $DBH->prepare("SELECT max(received) FROM events WHERE hostname = ? AND service = ?;"); if (!defined $sth2) {die("Cannot prepare statement in getStatus: $DBI::errstr\n")} $sth2->execute($hostname, $service); my $timestamp = $sth2->fetchrow();