# Redirect perls "die" messages to the logger before exiting.
$SIG{__DIE__} = sub { $logger->Log("err", "@_"); };
+# Initialize the parser module.
+my $parser = Guardian::Parser->Init(%mainsettings);
+
# Initialize the event handler.
my $events = Guardian::Events->Init(%mainsettings);
# Obtain the parser name which should be used to parse any
# messages of this file.
- my $parser = $monitored_files{$file};
+ my $use_parser = $monitored_files{$file};
# Signal handler to kill worker.
$SIG{'KILL'} = sub { threads->exit(); };
# Send filename and message to the parser,
# which will return if any actions have to be performed.
- my @actions = &Guardian::Parser::Parser("$parser", @message);
+ my @actions = $parser->Parser("$use_parser", @message);
# Send the action to the main process and put it into
# the queue.
# Update logger object in mainsettings hash.
$mainsettings{Logger} = $logger;
+ # Update Parser handler.
+ $parser->Update(\%mainsettings);
+
# Update Event handler.
$events->Update(\%mainsettings);
"ssh" => \&message_parser_ssh,
);
+#
+## The "Init" (Parser) function.
+#
+## This function is responsible to initialize the Parser as a class based object.
+## It has to be called once before any parsing of messages can be done.
+#
+sub Init (%) {
+ my ( $class, %args ) = @_;
+ my $self = \%args;
+
+ # Use bless to make "$self" to an object of class "$class".
+ bless($self, $class);
+
+ # Return the class object.
+ return $self;
+}
+
+#
+## The "Update" Parser settings function.
+#
+## This object based function is called to update various class settings.
+#
+sub Update (\%) {
+ my $self = shift;
+
+ # Dereference the given hash-ref and store
+ # the values into a new temporary hash.
+ my %settings = %{ $_[0] };
+
+ # Update snort priority level settings or disable it.
+ if ((defined($self->{SnortPriorityLevel})) && (exists($settings{SnortPriorityLevel}))) {
+ # Change settings.
+ $self->{SnortPriorityLevel} = $settings{SnortPriorityLevel};
+ } else {
+ # Remove setting.
+ delete $self->{SnortPriorityLevel};
+ }
+
+ # Return modified class object.
+ return $self;
+}
+
#
## The main parsing function.
#
## any action should be performed.
#
sub Parser ($$) {
- my ($parser, @message) = @_;
+ my $self = shift;
+ my ($parser, @message) = @_;
# If no responsible message parser could be found, just return nothing.
unless (exists($logfile_parsers{$parser})) {
}
# Call responsible message parser.
- my @actions = $logfile_parsers{$parser}->(@message);
+ my @actions = $logfile_parsers{$parser}->($self, @message);
# In case an action has been returned, return it too.
if (@actions) {
## later time.
#
sub message_parser_snort(@) {
+ my $self = shift;
my @message = @_;
my @actions;
if($line =~ /^\s*$/) {
# Variable to store the grabbed IP-address.
my $address;
+ my $classification;
# Loop through all lines of the current alert.
foreach my $line (@alert) {
- # Check Priority Level and skip the alert if it is to low.
- #if ($line =~ /.*\[Priority: (\d+)\].*/) {
- # return unless($1 < $priority);
- #}
+ # Determine if the alert has been classified.
+ if ($line =~ /.*\[Classification: .*\] \[Priority: (\d+)\].*/) {
+ my $priority = $1;
+
+ # Set classification to true.
+ $classification = "1";
+
+ # Obtain configured priority level.
+ my $priority_level = $self->{SnortPriorityLevel};
+
+ # Skip alerts if the priority is to low.
+ if ($priority < $priority_level) {
+ last;
+ }
+ }
# Search for a line like xxx.xxx.xxx.xxx -> xxx.xxx.xxx.xxx
if ($line =~ /(\d+\.\d+\.\d+\.\d+)+ -\> (\d+\.\d+\.\d+\.\d+)+/) {
$address = $1;
}
- # Obtain the reported reason from the headline of the alert.
- if ($line =~ /.*\] (.*) \[\*\*\]/) {
+ # Grab the reason from a msg field of the alert.
+ if ($line =~ /.*msg:\"(.*)\".*/) {
# Store the extracted message.
$message = $1;
}
- # If the reason could not be determined, try to obtain it from a msg field.
- elsif ($line =~ /.*msg:\"(.*)\".*/) {
+ # If the reason could not be determined, try to obtain it from the headline of the alert.
+ elsif ($line =~ /.*\] (.*) \[\*\*\]/) {
# Store the extracted message.
$message = $1;
}
}
# Check if at least the IP-address information has been extracted.
- if (defined ($address)) {
+ if ((defined ($classification)) && (defined ($address))) {
# Add the extracted values and event message for the computed
# event to the actions array.
push(@actions, "count $address $name $message");
## against the SSH service.
#
sub message_parser_ssh (@) {
+ my $self = shift;
my @message = @_;
my @actions;
## against a running HTTPD service.
#
sub message_parser_httpd (@) {
+ my $self = shift;
my @message = @_;
my @actions;