+ elsif ($flag eq "SA") {
+ $ip = (/From.*?(\\[[^]]+\\])/ || /\\((local)\\)/) ? $1 : "";
+ #SpamAssassin message
+ if (/Action: ((permanently|temporarily) rejected message|flagged as Spam but accepted): score=(\d+\.\d)/) {
+ #add_volume(\\$spam_score,\\$spam_score_gigs,$3);
+ ++$spam_count_by_ip{$ip};
+ } elsif (/Action: scanned but message isn\'t spam: score=(-?\d+\.\d)/) {
+ #add_volume(\\$ham_score,\\$ham_score_gigs,$1);
+ ++$ham_count_by_ip{$ip};
+ } elsif (/(Not running SA because SAEximRunCond expanded to false|check skipped due to message size)/) {
+ ++$ham_count_by_ip{$ip};
+ }
+ }
+
+ # Look for Reject messages or blackholed messages (deliveries
+ # without a transport)
+ if ($flag eq "Re" || ($flag eq "=>" && ! /\\sT=\\S+/)) {
+ # Correct the IP address for rejects:
+ # rejected EHLO from my.test.net [10.0.0.5]: syntactically invalid argument(s):
+ # rejected EHLO from [10.0.0.6]: syntactically invalid argument(s):
+ $ip = $1 if ($ip eq "local" && /^rejected [HE][HE]LO from .*?(\[.+?\]):/);
+ if (/SpamAssassin/) {
+ ++$rejected_count_by_reason{"Rejected by SpamAssassin"};
+ ++$rejected_count_by_ip{$ip};
+ }
+ elsif (
+ /(temporarily rejected [A-Z]*) .*?(: .*?)(:|\s*$)/
+ ) {
+ ++$temporarily_rejected_count_by_reason{"\u$1$2"};
+ ++$temporarily_rejected_count_by_ip{$ip};
+ }
+ elsif (
+ /(temporarily refused connection)/
+ ) {
+ ++$temporarily_rejected_count_by_reason{"\u$1"};
+ ++$temporarily_rejected_count_by_ip{$ip};
+ }
+ elsif (
+ /(listed at [^ ]+)/ ||
+ /(Forged IP detected in HELO)/ ||
+ /(Invalid domain or IP given in HELO\/EHLO)/ ||
+ /(unqualified recipient rejected)/ ||
+ /(closed connection (after|in response) .*?)\s*$/ ||
+ /(sender rejected)/ ||
+ # 2005-09-23 15:07:49 1EInHJ-0007Ex-Au H=(a.b.c) [10.0.0.1] F=<> rejected after DATA: This message contains a virus: (Eicar-Test-Signature) please scan your system.
+ # 2005-10-06 10:50:07 1ENRS3-0000Nr-Kt => blackhole (DATA ACL discarded recipients): This message contains a virus: (Worm.SomeFool.P) please scan your system.
+ / rejected after DATA: (.*)/ ||
+ / (rejected DATA: .*)/ ||
+ /.DATA ACL discarded recipients.: (.*)/ ||
+ /rejected after DATA: (unqualified address not permitted)/ ||
+ /(VRFY rejected)/ ||
+# /(sender verify (defer|fail))/i ||
+ /(too many recipients)/ ||
+ /(refused relay.*?) to/ ||
+ /(rejected by non-SMTP ACL: .*)/ ||
+ /(rejected by local_scan.*)/ ||
+ # SMTP call from %s dropped: too many syntax or protocol errors (last command was "%s"
+ # SMTP call from %s dropped: too many nonmail commands
+ /(dropped: too many ((nonmail|unrecognized) commands|syntax or protocol errors))/ ||
+
+ # local_scan() function crashed with signal %d - message temporarily rejected
+ # local_scan() function timed out - message temporarily rejected
+ /(local_scan.. function .* - message temporarily rejected)/ ||
+ # SMTP protocol synchronization error (input sent without waiting for greeting): rejected connection from %s
+ /(SMTP protocol .*?(error|violation))/ ||
+ /(message too big)/
+ ) {
+ ++$rejected_count_by_reason{"\u$1"};
+ ++$rejected_count_by_ip{$ip};
+ }
+ elsif (/rejected [HE][HE]LO from [^:]*: syntactically invalid argument/) {
+ ++$rejected_count_by_reason{"Rejected HELO/EHLO: syntactically invalid argument"};
+ ++$rejected_count_by_ip{$ip};
+ }
+ elsif (/response to "RCPT TO.*? was: (.*)/) {
+ ++$rejected_count_by_reason{"Response to RCPT TO was: $1"};
+ ++$rejected_count_by_ip{$ip};
+ }
+ elsif (
+ /(lookup of host )\S+ (failed)/ ||
+
+ # rejected from <%s>%s%s%s%s: message too big:
+ /(rejected [A-Z]*) .*?(: .*?)(:|\s*$)/ ||
+ # refused connection from %s (host_reject_connection)
+ # refused connection from %s (tcp wrappers)
+ /(refused connection )from.*? (\(.*)/ ||
+
+ # error from remote mailer after RCPT TO:<a@b.c>: host a.b.c [10.0.0.1]: 450 <a@b.c>: Recipient address rejected: Greylisted for 60 seconds
+ # error from remote mailer after MAIL FROM:<> SIZE=3468: host a.b.c [10.0.0.1]: 421 a.b.c has refused your connection because your server did not have a PTR record.
+ /(error from remote mailer after .*?:).*(: .*?)(:|\s*$)/ ||
+
+ # a.b.c F=<a@b.c> rejected after DATA: "@" or "." expected after "Undisclosed-Recipient": failing address in "To" header is: <Undisclosed-Recipient:;>
+ /rejected after DATA: ("." or "." expected).*?(: failing address in .*? header)/ ||
+
+ # connection from %s refused load average = %.2f
+ /(Connection )from.*? (refused: load average)/ ||
+ # connection from %s refused (IP options)
+ # Connection from %s refused: too many connections
+ # connection from %s refused
+ /([Cc]onnection )from.*? (refused.*)/ ||
+ # [10.0.0.1]: connection refused
+ /: (Connection refused)()/
+ ) {
+ ++$rejected_count_by_reason{"\u$1$2"};
+ ++$rejected_count_by_ip{$ip};
+ }
+ elsif (
+ # 2008-03-31 06:25:22 H=mail.densitron.com [216.70.140.224]:45386 temporarily rejected connection in "connect" ACL: too fast reconnects // .hs
+ # 2008-03-31 06:25:22 H=mail.densitron.com [216.70.140.224]:45386 temporarily rejected connection in "connect" ACL // .hs
+ /(temporarily rejected connection in .*?ACL:?.*)/
+ ) {
+ ++$temporarily_rejected_count_by_ip{$ip};
+ ++$temporarily_rejected_count_by_reason{"\u$1"};
+ }
+ else {
+ ++$rejected_count_by_reason{Unknown};
+ ++$rejected_count_by_ip{$ip};
+ print STDERR "Unknown rejection: $_" if $debug;
+ }
+ }