package My::parser::exim_parser; use strict; use warnings; sub new { my $class = shift; my $self = {}; bless ($self, $class); return $self; } sub parser { my $self = shift; my $string = shift; my ($reply,$hostile,$host) = ("No match for $string",0,''); my $re_host = qr/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/; my $re_msgid = qr/[0-9a-z]{6}-[0-9a-z]{11}-[0-9a-z]{4}/i; my $saslauth = qr/saslauthd_server authenticator failed/i; if($string =~ m/ ($re_msgid) /) { $reply = 'MSG ID, normal delivery'; } elsif($string =~ m/(Start|End) queue run/) { $reply = 'Queue run'; } elsif($string =~ m/1 accept\(\) failure/) { $reply = 'Connection aborted by software'; } elsif($string =~ m/SSL verify error: /) { if($string =~ m/self signed certificate in certificate chain/) { $reply = 'Self signed certificate in chain'; } elsif($string =~ m/error=self signed certificate cert=/) { $reply = 'Self signed certificate'; } else { $reply = 'Other SSL verify errors'; } } elsif($string =~ m/Temporary DNS error while checking SPF record/) { $reply = 'Temporary DNS error while checking SPF record'; } elsif($string =~ m/$saslauth /) { $_ = $string; $hostile = 1; $reply = 'saslauth error'; PARSER: m/(\ \[($re_host)\]:)/gcix && do { $host = $2; }; } elsif($string =~ m/> rejected (after DATA|RCPT)/) { $_ = $string; $reply = 'Rejected'; $hostile = 1; PARSER: m/(\ \[($re_host)\]\ )/gcix && do { $host = $2; }; } elsif($string =~ m/\ rejected (AUTH|MAIL)\ /) { $_ = $string; $reply = 'Rejected MAIL or AUTH'; $hostile = 1; PARSER: m/(\ \[($re_host)\]\ )/gcix && do { $host = $2; }; } elsif($string =~ m/ too many (nonmail|syntax or protocol errors|unrecognized commands) /) { $_ = $string; $reply = 'protocol violations'; $hostile = 1; PARSER: m/(\ \[($re_host)\])/gcix && do { $host = $2; }; } elsif($string =~ m/ SMTP protocol synchronization error /) { $_ = $string; $reply = 'protocol errors'; $hostile = 1; PARSE: m/(\[($re_host)\]\ ) /gcix && do { $host = $2; }; } elsif($string =~ m/ TLS error on connection /) { $_ = $string; $reply = 'TLS error'; $hostile = 1; PARSE: m/(\ \[($re_host)\]\ )/gcix && do { $host = $2; }; } elsif($string =~ m/ TLS error \(SSL_read\)\: on connection /) { $_ = $string; $reply = 'TLS error'; $hostile = 1; PARSE: m/(\ \[($re_host)\]\ )/gcix && do { $host = $2; }; } elsif($string =~ m/ no IP address found for host /) { $_ = $string; $reply = 'Problems resolving hostname'; $hostile = 1; PARSE: m/(\ \[($re_host)\])/gcix && do { $host = $2; }; } elsif($string =~ m/ no host name found for IP address /) { $_ = $string; $reply = 'No hostname'; $hostile = 1; PARSE: m/\ ($re_host)/gcix && do { $host = $1; }; } elsif($string =~ m/unexpected disconnection while reading SMTP command from/) { $_ = $string; $reply = 'SMTP error, disconnected'; $hostile = 1; PARSE: m/(\ \[($re_host)\]\ )/gcix && do { $host = $2; }; } elsif($string =~ m/ sender verify fail for /) { $_ = $string; $reply = 'Sender verify failure'; $hostile = 1; PARSE: m/(\ \[($re_host)\]\ )/gcix && do { $host = $2; }; } elsif($string =~ m/ rejected (EH|HE)LO from /) { $_ = $string; $reply = 'HELO/EHLO error'; $hostile = 1; PARSE: m/(\ \[($re_host)\](:|)\ )/gcix && do { $host = $2; }; } elsif($string =~ m/ You are not me /) { $_ = $string; $reply = 'Forged HELO'; $hostile = 1; PARSE: m/(\ \[($re_host)\]\ )/gcix && do { $host = $2; }; } elsif($string =~ m/ rejected after DATA /) { $_ = $string; $reply = 'Parser error'; $hostile = 1; PARSE: m/(\ \[($re_host)\]\ )/gcix && do { $host = $2; }; } elsif($string =~ m/ (login_saslauthd_server|LOGIN|PLAIN) authenticator failed for /) { $_ = $string; $reply = 'Auth error'; $hostile = 1; PARSE: m/(\ \[($re_host)\])/gcix && do { $host = $2; }; } elsif($string =~ m/ SMTP command timeout /) { $_ = $string; $reply = 'SMTP timeout'; $hostile = 1; PARSE: m/(\ \[($re_host)\])/gcix && do { $host = $2; }; } elsif($string =~ m/SSL_write: /) { $_ = $string; $reply = 'SSL write error'; #Most, if not all of these, are because we have blocked the ip } elsif($string =~ m/TLS ALPN/) { if($string =~ m/rejected$/) { $reply = 'TLS ALPN rejected' } } return { retval => 1, retmsg => $reply, hostile => $hostile, host => $host, string => $string }; } return 1;