package Guardian::Parser;
use strict;
use warnings;

use Exporter qw(import);

our @EXPORT_OK = qw(IsSupportedParser Parser);

# This hash contains all supported parsers and which function
# has to be called to parse messages in the right way.
my %logfile_parsers = (
	"snort" => \&message_parser_snort,
	"ssh" => \&message_parser_ssh,
);

#
## The main parsing function.
#
## It is used to determine which sub-parser has to be used to
## parse the given message in the right way and to return if
## any action should be performed.
#
sub Parser ($$) {
        my ($parser, @message) = @_;

	# If no responsible message parser could be found, just return nothing.
	unless (exists($logfile_parsers{$parser})) {
		return;
	}

	# Call responsible message parser.
	my $action = $logfile_parsers{$parser}->(@message);

	# In case an action has been returned, return it too. 
	if (defined($action)) {
		# Return which action should be performed.
		return "count $action";
	}

	# Return undef, no action required.
	return undef;
}

#
## IsSupportedParser function.
#
## This very tiny function checks if a given parser name is available and
## therefore a supported parser.
#
## To perform these check, the function is going to lookup if a key in the
## hash of supported parsers is available
#
sub IsSupportedParser ($) {
	my $parser = $_[0];

	# Check if a key for the given parser exists in the hash of logfile_parsers.
	if(exists($logfile_parsers{$parser})) {
		# Found a valid parser, so return nothing.
		return 1;
	}

	# Return "False" if we got here, and therefore no parser
	# is available.
	return;
}

#
## The Snort message parser.
#
## This subfunction is responsible for parsing sort alerts and determine if
## an action should be performed.
#
sub message_parser_snort($) {
	my @message = @_;

	# XXX
	# Currently this parser just returns a simple message.
	return "$message[0] SNORT A simple Snort Message";
}

#
## The SSH message parser.
#
## This subfunction is used for parsing and detecting different attacks
## against the SSH service.
#
sub message_parser_ssh (@) {
	my @message = @_;

	# The name of the parser module.
	my $name = "SSH";

	# Variable to store the grabbed IP-address.
	my $address;

	# Variable to store the parsed event.
	my $message;

	# Loop through all lines, in case multiple one have
	# been passed.
	foreach my $line (@message) {
		# Check for failed password attempts.
		if ($line =~/.*sshd.*Failed password for (.*) from (.*) port.*/) {
			# Store the grabbed IP-address.
			$address = $2;

			# Set event message.
			$message = "Possible SSH-Bruteforce Attack for user: $1.";
		}

		# This should catch Bruteforce Attacks with enabled preauth
		elsif ($line =~ /.*sshd.*Received disconnect from (.*):.*\[preauth\]/) {
			# Store obtained IP-address.
			$address = $1;

			# Set event message.
			$message = "Possible SSH-Bruteforce Attack - failed preauth.";
		}
	}

	# Check if at least the IP-address information has been extracted.
	if (defined ($address)) {
		# Return the extracted values and event message.
		return "$address $name $message";
	}

	# If we got here, the provided message is not affected by any filter and
	# therefore can be skipped. Return nothing (False) in this case.
	return;
}

1;
