Skip to content
Snippets Groups Projects
WardenClientCommon.pm 6.99 KiB
Newer Older
# WardenClientCommon.pm
#
# Copyright (C) 2011-2015 Cesnet z.s.p.o
#
# Use of this source is governed by a BSD-style license, see LICENSE file.
use SOAP::Lite;
use IO::Socket::SSL qw(debug1);
use SOAP::Transport::HTTP;
use Sys::Syslog qw(:DEFAULT setlogsock);
Sys::Syslog::setlogsock('unix');
use Carp;
our $VERSION = "2.2";

#-------------------------------------------------------------------------------
# errMsg - prints error msg and returns undef or prints warning and returns 1
#-------------------------------------------------------------------------------
sub errMsg
{
  my $type = shift; 
  defined $type or $type = "err"; # default type is err. Other: warn
  # check verbose logging
  if (($type eq "err") && ($WardenCommon::LOG_VERBOSE)) {
    $msg .= "\nStack info: " . Carp::longmess();
  }

  # check logging into STDERR
  if ($WardenCommon::LOG_STDERR) {
    print STDERR $msg . "\n";
  }

  # check logging into Syslog
  if ($WardenCommon::SYSLOG) {
    openlog("Warden-client:", "pid", "$WardenCommon::SYSLOG_FACILITY");
    syslog("$type|$WardenCommon::SYSLOG_FACILITY", $msg . "\n");
} # End of errMsg


#-------------------------------------------------------------------------------
# c2s - connect to server, send request and receive response
#-------------------------------------------------------------------------------
sub c2s
{
  my $uri               = shift;
  my $ssl_key           = shift;
  my $ssl_cert          = shift;
  my $ssl_ca_cert       = shift;
  my $method            = shift;
  my $data              = shift;

  my $client;
  my ($server, $port, $service) = $uri =~ /https:\/\/(.+)\:(\d+)\/(.+)/;
Tomáš Plesník's avatar
Tomáš Plesník committed
  # create SOAP::Transport::HTTP:Client object
  eval {
    $client = SOAP::Transport::HTTP::Client->new();
  } or return errMsg("Error in function 'c2s()' when creating SOAP::Transport::HTTP::Client object: " . $@);
  # setting of connection timeout
  eval {$client->timeout($WardenCommon::CONNECTION_TIMEOUT);}
  or return errMsg("Error in function 'c2s()' when setting connection timeout: " . $@);
  eval {
    $client->ssl_opts(verify_hostname   => 1,
                    SSL_key_file        => $ssl_key,
                    SSL_cert_file       => $ssl_cert,
                    SSL_ca_file         => $ssl_ca_cert);
    return 1; # fix of eval triggering 'or' statement
  } or return errMsg("Ërror in function 'c2s()' when setting SSL options: " . $@);
  my $soap;
  eval {
    $soap = SOAP::Lite->uri($service)->proxy($uri);
  } or return errMsg("Error in function 'c2s()' when setting service URI: " . $@);
  # serialize SOAP envelope or SOAP envelope and data object
    eval {
      $envelope = $soap->serializer->envelope(method => $method);
    } or return errMsg("Error in function 'c2s()' when serializing envelope: " . $@);
    eval {
      $envelope = $soap->serializer->envelope(method => $method, $data);
    } or return errMsg("Error in function 'c2s()' when serializing envelope and data: " . $@);
  # setting of complete HTTPs URI and send serialized SOAP envelope and data
  my $server_uri = "https://$server:$port/$service";
  my $result;
  eval {
    $result = $client->send_receive(envelope => $envelope, endpoint => $server_uri);
  } or return errMsg("Error in function 'c2s()' when sending SOAP envelope and data: " . $@);

  # check server response
  if (!defined $result) {
Tomáš Plesník's avatar
Tomáš Plesník committed
    errMsg("Server returned empty response. Problem with used SSL ceritificate/key or Warden server at $server:$port is down.");
    # deserialized response from server to SOAP data object
    my $response;
    eval {
      $response = $soap->deserializer->deserialize($result);
    } or return errMsg("Error in deserialization of server response: " . $@ . " (Received response: " . $result . ")");
    $response->fault ? return errMsg("Server sent error message:: " . $response->faultstring) : return $response;
#-------------------------------------------------------------------------------
# getClientsInfo - retrieve information about other clients from Warden server
#-------------------------------------------------------------------------------
sub getClientsInfo 
{
  my $warden_path = shift;

  my $etcdir = $warden_path . "/etc/";
  my $libdir = $warden_path . "/lib/";

  require $libdir . "WardenClientConf.pm";

  # read the config file
  my $conf_file = $etcdir . "warden-client.conf";
  WardenClientConf::loadConf($conf_file);

  # c2s() returns undef on fail
  my $response = c2s($WardenClientConf::URI, $WardenClientConf::SSL_KEY_FILE, $WardenClientConf::SSL_CERT_FILE, $WardenClientConf::SSL_CA_FILE, "getClientInfo");
  
  defined $response or return; # receive data or return undef     

  # parse returned SOAP data object with clients
  my @clients;
  my ($client_id, $hostname, $registered, $requestor, $service, $client_type, $type, $receive_own_events, $description_tags, $ip_net_client);
  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 received clients from warden server into @clients which is returned
#-------------------------------------------------------------------------------
# loadConf - load configuration file
#-------------------------------------------------------------------------------
sub loadConf
{
  my $conf_file = shift;

  our $BASEDIR              = undef;
  our $URI                  = undef;
  our $SSL_KEY              = undef;
  our $SSL_CERT             = undef;
  our $SSL_CA_CERT          = undef;
  our $MAX_RCV_EVENTS_LIMIT = undef;
  our $CONNECTION_TIMEOUT   = undef;
  our $LOG_STDERR           = undef;
  our $SYSLOG               = undef;
  our $SYSLOG_FACILITY      = undef;
  unless (do $conf_file) {
    die("Errors in config file '$conf_file': $@") if $@;
    die("Can't read config file '$conf_file': $!") unless defined $_;
    # if $_ defined, it's retvalue of last statement of conf, for which we don't care
  }
} # End of loadConf