Newer
Older
soukal
committed
#
soukal
committed
# Use of this source is governed by a BSD-style license, see LICENSE file.
package WardenClientReceive;
use strict;
use SOAP::Lite;
use IO::Socket::SSL qw(debug1);
use Carp;
use Sys::Syslog;
our $VERSION = "2.0";
#----- global configuration variables -----------------------------------------
our $LOG_STDERR = 1;
our $LOG_SYSLOG = 0;
our $LOG_SYSLOG_FACILITY;
our $LOG_VERBOSE = 0;
#----- end of configuration variables ------------------------------------------
#-------------------------------------------------------------------------------
# errMsg - print error message and die
#-------------------------------------------------------------------------------
sub errMsg
{
my $msg = "Error message: " . shift;
if ($LOG_VERBOSE) { # user wants to log debug information
$msg .= "\nStack info: " . Carp::longmess();
}
die($msg . "\n");
} # End of errMsg
#-------------------------------------------------------------------------------
# c2s - connect to server, send request and receive response
#-------------------------------------------------------------------------------
sub c2s
{
my $ssl_ca_file = shift;
my $method = shift;
my $data = shift;
my $client;
my ($server, $port, $service) = $uri =~ /https:\/\/(.+)\:(\d+)\/(.+)/;
soukal
committed
if (!($client = SOAP::Transport::HTTP::Client->new())) {
errMsg("Sorry, unable to create socket: " . &SOAP::Transport::HTTP::Client::errstr)
}
soukal
committed
$client->ssl_opts(verify_hostname => 1,
SSL_use_cert => 1,
SSL_verify_mode => 0x02,
SSL_key_file => $ssl_key_file,
SSL_cert_file => $ssl_cert_file,
SSL_ca_file => $ssl_ca_file);
# setting of URI and serialize SOAP envelope and data object
my $soap = SOAP::Lite->uri($service)->proxy($uri);
my $envelope;
if (!defined $data) {
$envelope = $soap->serializer->envelope(method => $method);
} else {
$envelope = $soap->serializer->envelope(method => $method, $data);
}
# setting of TCP URI and send serialized SOAP envelope and data
soukal
committed
my $server_uri = "https://$server:$port/$service";
my $result = $client->send_receive(envelope => $envelope, endpoint => $server_uri);
errMsg("Error: server returned empty response." . "\n" . "Problem with used SSL ceritificates or Warden server at $server:$port is down.");
} else {
# deserialized response from server -> create SOAP envelope and data object
# test
errMsg("test error in c2s()");
eval {
$response = $soap->deserializer->deserialize($result);
} or errMsg($@ . "Received data: " . $result);
# check SOAP fault status
$response->fault ? errMsg("Server sent error message:: " . $response->faultstring) : return $response;
}
}
#-------------------------------------------------------------------------------
# getNewEvents - get new events from warden server greater than last received ID
#-------------------------------------------------------------------------------
sub getNewEvents
{
my @events;
eval {
my $warden_path = shift;
my $requested_type = shift;
my $vardir = $warden_path . "/var/";
my $etcdir = $warden_path . "/etc/";
my $libdir = $warden_path . "/lib/";
# read the config file
require $libdir . "WardenClientConf.pm";
my $conf_file = $etcdir . "warden-client.conf";
my ($uri, $ssl_key_file, $ssl_cert_file, $ssl_ca_file, $max_rcv_events_limit);
($uri, $ssl_key_file, $ssl_cert_file, $ssl_ca_file, $max_rcv_events_limit, $LOG_STDERR, $LOG_SYSLOG, $LOG_SYSLOG_FACILITY, $LOG_VERBOSE) = WardenClientConf::loadConf($conf_file);
# test
# errMsg("testovaci error\n");
# set name of ID file for each client aplication
my $caller_name = $FindBin::Script;
my $id_file = $vardir . $caller_name . ".id";
#-----------------------------------------------------------------------------
# get last ID from ID file (if exist) or
# get last ID from warden server DB and save it into ID file
my $last_id;
if (-e $id_file) {
open(ID, "< $id_file") || errMsg("Cannot open ID file $id_file: $!");
foreach(<ID>) {
$last_id = $_;
}
close ID;
} else {
my $response = c2s($uri, $ssl_key_file, $ssl_cert_file, $ssl_ca_file, "getLastId");
$last_id = $response->result;
open(ID, "> $id_file") || die ("Cannot open ID file $id_file: $!");
print ID $last_id;
close ID;
#-----------------------------------------------------------------------------
# get new events from warden server DB based on gathered last ID
# create SOAP data obejct
my $request_data = SOAP::Data->name(
request => \SOAP::Data->value(
SOAP::Data->name(REQUESTED_TYPE => $requested_type),
SOAP::Data->name(LAST_ID => $last_id),
SOAP::Data->name(MAX_RCV_EVENTS_LIMIT => $max_rcv_events_limit)
)
);
soukal
committed
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# call server method getNewEvents
my $response = c2s($uri, $ssl_key_file, $ssl_cert_file, $ssl_ca_file, "getNewEvents", $request_data);
# parse returned SOAP data object
my ($id, $hostname, $service, $detected, $type, $source_type, $source, $target_proto, $target_port, $attack_scale, $note, $priority, $timeout);
# my @events;
my @response_list = $response->valueof('/Envelope/Body/getNewEventsResponse/event/');
while (scalar @response_list) {
my $response_data = shift(@response_list);
my @event;
# parse items of one event
$id = $response_data->{'ID'};
$hostname = $response_data->{'HOSTNAME'};
$service = $response_data->{'SERVICE'};
$detected = $response_data->{'DETECTED'};
$type = $response_data->{'TYPE'};
$source_type = $response_data->{'SOURCE_TYPE'};
$source = $response_data->{'SOURCE'};
$target_proto = $response_data->{'TARGET_PROTO'};
$target_port = $response_data->{'TARGET_PORT'};
$attack_scale = $response_data->{'ATTACK_SCALE'};
$note = $response_data->{'NOTE'};
$priority = $response_data->{'PRIORITY'};
$timeout = $response_data->{'TIMEOUT'};
# push new event from warden server into @events which is returned
@event = ($id, $hostname, $service, $detected, $type, $source_type, $source, $target_proto, $target_port, $attack_scale, $note, $priority, $timeout);
push (@events, \@event);
# set maximum received ID from current batch
if ($id > $last_id) {
$last_id = $id;
}
} #end of while loop
# write last return ID
if (defined $last_id) { # must be defined for first check ID
open(ID, "> $id_file") || die ("Cannot open ID file $id_file: $!");
print ID $last_id;
close ID;
} # End of eval block
or do {
if ($LOG_STDERR) {
print STDERR "(STDERR)Warden-client unexpected end in eval block.\n" . $@ . "\n";
}
if ($LOG_SYSLOG) {
#TODO: zapis do syslogu, ne STDERR
print STDERR "(SYSLOG)Warden-client unexpected end in eval block.\n" . $@ . "\n";
# openlog("Warden:", "pid", "$LOG_SYSLOG_FACILITY");
# syslog("err|$LOG_SYSLOG_FACILITY", "Warden-client unexpected end in eval block.\n" . $@ . "\n");
# closelog();
soukal
committed