You need to sign in or sign up before continuing.
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);
our $VERSION = "2.0";
#-------------------------------------------------------------------------------
# errMsg - print error message and die
#-------------------------------------------------------------------------------
sub errMsg
{
my $msg = shift;
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
my $response;
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
{
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
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) = WardenClientConf::loadConf($conf_file);
# 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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# 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 {
print STDERR "Warden-client unexpected end in eval block: " . $@ . "\n";
soukal
committed