Skip to content
Snippets Groups Projects
WardenClient.pm 7.89 KiB
Newer Older
# WardenClient.pm
#
# Copyright (C) 2011-2015 Cesnet z.s.p.o
#
# Use of this source is governed by a BSD-style license, see LICENSE file.  

package WardenClient;

use strict;
use warnings;

use SOAP::Lite;
use File::Basename;
my $lib = File::Basename::dirname(__FILE__);
use lib $lib;
use WardenClientCommon;


################################################################################
#				VARIABLES
################################################################################
our $VAR = "$lib/../var";

################################################################################
#			READING OF CONFIGURATION FILE
################################################################################
# load server configuration
my $etc = "$lib/../etc";
my $conf_file = "$etc/warden-client.conf";
WardenClientCommon::loadConf($conf_file);


################################################################################
#				FUNCTIONS
################################################################################


#-------------------------------------------------------------------------------
# saveNewEvent - send new event from detection scripts to warden server
#-------------------------------------------------------------------------------
sub saveNewEvent
{
  my $event_ref = shift;

  # prepare variables of event 
  my @event        = @{$event_ref};
  my $service      = $event[0];
  my $detected     = $event[1];
  my $type         = $event[2];
  my $source_type  = $event[3];
  my $source       = $event[4];
  my $target_proto = $event[5];
  my $target_port  = $event[6];
  my $attack_scale = $event[7];
  my $note         = $event[8];
  my $priority     = $event[9];
  my $timeout      = $event[10];

  # Issue #596 - Should be removed in Warden client 3.0.
  # check if obsolete event attribute 'Priority' is used
  if ((defined $priority) && ($priority >= 0)) {
    WardenClientCommon::errMsg("Event attribute 'Priority' is now obsolete and will be removed in Warden client v.3.0", "warn");
  }
  # check if obsolete event attribute 'Timeout' is used
  if ((defined $timeout) && ($timeout >= 0)) {
    WardenClientCommon::errMsg("Event attribute 'Timeout' is now obsolete and will be removed in Warden client v.3.0", "warn");
  } 
  # end of Issue #596 
    
  # create SOAP data object
  my $event;
  eval {
    $event = SOAP::Data->name(
      event => \SOAP::Data->value(
        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)
      )
    );
  } or WardenClientCommon::errMsg("Error when creating SOAP data object: " . $@);

  my $result = WardenClientCommon::c2s("saveNewEvent", $event);

  defined $result ? return 1 : return 0;  
 
} # End of saveNewEvent


#-------------------------------------------------------------------------------
# getNewEvents - get new events from warden server greater than last received ID
#-------------------------------------------------------------------------------
sub getNewEvents
{
  my $requested_type = shift;

  # set name of ID file based on caller name (each client application)
  my ($caller_name) = ($FindBin::Script =~ /^(.*)$/);	# untaint
  my $id_file = $VAR . $caller_name . "-". ($requested_type || "any") . ".id";

  # get last event ID
  my $last_id;
  if (-e $id_file) { # get ID from ID file
    open(FILE, "< $id_file") or return WardenClientCommon::errMsg("Cannot open ID file $id_file: $!");
    foreach(<FILE>) {
      $last_id = $_;
    close FILE;
  } else { # get ID from Warden server database and print it into the ID file
    my $response = WardenClientCommon::c2s("getLastId");
    defined $response or return;
    $last_id = $response->result;
    open(FILE, "> $id_file") or return WardenClientCommon::errMsg("Cannot open ID file $id_file: $!");
    print FILE $last_id;
    close FILE;
  }
  # prepare SOAP data object for Warden server
  my $request_data;
  eval {
    $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  => $WardenClientCommon::MAX_RCV_EVENTS_LIMIT)
    )
  } or return WardenClientCommon::errMsg('Unknown error when creating SOAP data object, ' . $@);
  # call server method getNewEvents
  my $response = WardenClientCommon::c2s("getNewEvents", $request_data);
  defined $response or return;
  # parse server response (SOAP data object)
  my @events;
  my ($id, $hostname, $service, $detected, $type, $source_type, $source, $target_proto, $target_port, $attack_scale, $note, $priority, $timeout);
  my @response_list = $response->valueof('/Envelope/Body/getNewEventsResponse/event/');
  while (scalar @response_list) {
    my $response_data = shift(@response_list);
    my @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'};

    @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;
  # print last returned event ID into ID file
  if (defined $last_id) {
    open(FILE, "> $id_file") or return WardenClientCommon::errMsg("Cannot open ID file $id_file: $!");
    print FILE $last_id;
    close FILE;
  }
} # End of getNewEvents


#-------------------------------------------------------------------------------
# getClientInfo - retrieve information about other clients from Warden server
#-------------------------------------------------------------------------------
sub getClientInfo
{
  # obtain information about clients on Warden server
  my $response = c2s("getClientInfo");
  defined $response or return; # receive data or return undef

  # parse server response (SOAP data object)
  my @clients;
  my @response_list = $response->valueof('/Envelope/Body/getClientInfoResponse/client/');
  while (scalar @response_list) {
    my $response_data = shift(@response_list);
    my %client;
    $client{'client_id'}                = $response_data->{'CLIENT_ID'} ;
    $client{'hostname'}                 = $response_data->{'HOSTNAME'};
    $client{'registered'}               = $response_data->{'REGISTERED'};
    $client{'requestor'}                = $response_data->{'REQUESTOR'};
    $client{'service'}                  = $response_data->{'SERVICE'};
    $client{'client_type'}              = $response_data->{'CLIENT_TYPE'};
    $client{'type'}                     = $response_data->{'TYPE'};
    $client{'receive_own_events'}       = $response_data->{'RECEIVE_OWN_EVENTS'};
    $client{'description_tags'}         = $response_data->{'DESCRIPTION_TAGS'};
    $client{'ip_net_client'}            = $response_data->{'IP_NET_CLIENT'};
    push (@clients,\%client);
  }

  return @clients;
}  # End of getClientInfo

1;