Files
parserfilter/lib/parser.pm
2024-03-09 15:36:42 +01:00

143 lines
4.4 KiB
Perl

package My::parser::parser;
use strict;
use warnings;
use My::parser::logger;
use My::parser::config;
use My::parser::geoip;
use My::parser::localcheck;
use My::parser::block;
sub new {
my $class = shift;
my $config_file = shift;
my $self = {};
bless ($self, $class);
$self->{'config'} = My::parser::config->new($config_file) || die "Could not load config file $config_file";
$self->{'config'}->{'logger'} = My::parser::logger->new($self->{'config'});
$self->{'config'}->{'logger'}->reload_log;
$self->{'geoip'} = My::parser::geoip->new($self->{'config'});
$self->{'localcheck'} = My::parser::localcheck->new;
$self->{'block'} = My::parser::block->new($self->{'config'});
return $self;
}
sub parse_all {
my $self = shift;
my $parsers = $self->{'config'}->get_parsers;
foreach my $service (keys %{$parsers}) {
my $fromparser = $parsers->{$service}->parse;
if($fromparser->{'retval'} == 1) {
foreach my $line (@{$fromparser->{'lines'}}) {
my $msg = $line->{'retmsg'};
my $host = $line->{'host'};
my $hostile = $line->{'hostile'};
if ($msg && $hostile && $host) {
unless($self->{'localcheck'}->islocal($host)) {
my $tolog = $host."($service";
my $geoip = $self->{'geoip'}->parse($host);
if ($geoip->{'asn'} && $geoip->{'iso'}) {
$tolog .= ",$geoip->{'asn'},$geoip->{'iso'}): ";
} else {
$geoip->{'asn'} = 0;
$geoip->{'iso'} = '';
$tolog .= '): ';
}
if(my $fromblock = $self->{'block'}->blocklogic({host => $host, geoip => $geoip, service => $service})) {
my $blmsg = $fromblock->{'retmsg'};
$tolog .= $blmsg;
}
$tolog .= ", $msg";
$self->{'config'}->{'logger'}->log($tolog);
} else {
$self->{'config'}->{'logger'}->log("$host is local");
}
} elsif ($msg =~ m/^No match/) {
$self->{'config'}->{'logger'}->log("$service said: $msg");
} elsif ($hostile) {
$self->{'config'}->{'logger'}->log("Parser error, $service reported hostile activity, but no host given. Message from parser was: $msg. String passed to parser: ".$line->{'string'});
}
}
}
}
return 1;
}
sub load_parsers {
my $self = shift;
my $config = $self->{'config'};
die 'No modules defined in config' unless(scalar(@{$config->get_modules}));
foreach my $parser(@{$config->get_modules}) {
if(my $newparser = $self->load($parser)) {
$config->set('parsers',$parser,$newparser);
my $module_info = $config->get_parser_info($parser);
my $fetcher_needed = $module_info->{'type'};
my $isloaded = $config->{'loadedparsers'}->{$fetcher_needed};
unless(defined($isloaded)) {
if(my $fetcher_loaded = $self->load($fetcher_needed)) {
$self->dyninit($fetcher_loaded,$fetcher_needed,$parser);
#$self->{'config'}->{'logger'}->log("Loaded dependency from $parser; $fetcher_needed"); FIXME add debug in config?
} else {
die "Failed to load $fetcher_needed, needed by $parser";
}
} else {
my $toinit = $config->get_fetcher_module($fetcher_needed);
if(defined($toinit)) {
unless($self->dyninit($toinit,$fetcher_needed,$parser)) {
$self->{'config'}->{'logger'}->log("Dyninit failed for $fetcher_needed for $parser");
}
} else {
$self->{'config'}->{'logger'}->log('No dyninit needed for '.$fetcher_needed.' for '.$parser);
}
}
} else {
$self->{'config'}->{'logger'}->log("Failed to load parser for $parser");
}
}
return 1;
}
sub dyninit {
my $self = shift;
my $fetcher_loaded = shift;
my $fetcher_needed = shift;
my $parser = shift;
if(my $initr = $self->init($fetcher_loaded,$parser)) {
$self->{'config'}->set('fetchers',$fetcher_needed,$fetcher_loaded);
#$self->{'config'}->{'logger'}->log("Dependency $fetcher_needed initialized"); FIXME add debug in config?
return 1;
}
return 0;
}
sub load {
my $self = shift;
my $config = $self->{'config'};
my $parser = shift;
my $filename = 'My/parser/'.$parser.'.pm';
my $newclass;
eval {
require $filename;
my $classname = 'My::parser::'.$parser;
$newclass = $classname->new($config) || die "Failed to load parser for $parser";
$self->{'config'}->{'logger'}->log("Loaded $classname");
} or do {
my $e = $@;
$self->{'config'}->{'logger'}->log("Failed to load $filename: $e");
return 0;
};
$config->{'loadedparsers'}->{$parser} = 'loaded';
return $newclass;
}
sub init {
my $self = shift;
my $fetcher = shift;
my $parser = shift;
return 1 if($fetcher->init($parser));
return 0;
}
1;