#!/usr/bin/perl -wT # # mrtg-spamscorer.pl # version 1.3 (1/1/2004) # # Outputs MailScanner / SpamAssassin scores from the # system mail log with an average. # # Copyright, (c) 2003-2004, Corey S. McFadden & Associates (contact@csma.biz) # www.csma.biz # By postal mail: # McFadden Associates # PO Box 20665 # Lehigh Valley, PA 18002 # U.S.A. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # Version History # - v1.3 fixed year-end negative intervals # - v1.2 updated output: I,lowscoring O,highscoring # - v1.1 fixed day size problems # - v1.0 Working Release # use Time::Local; # Global Vars $IntMins = "10"; # Set this to your MRTG interval $HighScore = "9"; # Set this to your MailScanner high score $MailLogFile = "/var/log/maillog"; # Change this if your maillog isn't here. $HighAverage = "0"; $HighCount = "0"; $LowAverage = "0"; $LowCount = "0"; # Exec &Get_Time; &Process_Log; &Print_Average; # Subroutines sub Get_Time { # Gets the start time and sets global variables. $timestart = time(); my $date = localtime(); my($day, $month, $num, $time, $year) = split(/\s+/,$date); $timeyear = $year; } sub Back_Time { # This is a debug mechanism for taking the seconds and converting them # back to human readable date format. (Not used in operation.) my $date = localtime($_[0]); my ($day, $month, $num, $time, $year) = split(/\s+/,$date); my $back = "[$month $num $time]"; return $back; } sub Rec_Time { # Takes a date string on input and returns the universal second count # which is better for comparing intervals. # input format is 'Sep 26 16:27:50' (syslog) my @DateString = split(/\ /,$_[0]); my @TimeString = split(/:/,$DateString[2]); my $month = $DateString[0]; if ($month eq "Jan") { $month = "1"; } if ($month eq "Feb") { $month = "2"; } if ($month eq "Mar") { $month = "3"; } if ($month eq "Apr") { $month = "4"; } if ($month eq "May") { $month = "5"; } if ($month eq "Jun") { $month = "6"; } if ($month eq "Jul") { $month = "7"; } if ($month eq "Aug") { $month = "8"; } if ($month eq "Sep") { $month = "9"; } if ($month eq "Oct") { $month = "10"; } if ($month eq "Nov") { $month = "11"; } if ($month eq "Dec") { $month = "12"; } $month = int($month - 1); my $iseconds = timelocal($TimeString[2],$TimeString[1],$TimeString[0] ,$DateString[1],$month,$timeyear); return $iseconds; } sub Process_Log { # Bulk of the processing occurs here. # 1. Mail Log is inputted and checked for 'score=2.0,' format entries. # 2. Only entries that fall within our program's interval are checked. # 3. A total is divided by a count producing an average. # 4. A global var is set with the average. my $int_secs = int($IntMins * 60); open (MAILLOG,$MailLogFile); while ($cline = ) { if ($cline =~ "score\=") { my @curline = split(/\ /,$cline); my $test = "$curline[1]"; if ($test ne "") { $recsecs = Rec_Time("$curline[0] $curline[1] $curline[2]"); } else { $recsecs = Rec_Time("$curline[0] $curline[2] $curline[3]"); } my $distsecs = int($timestart - $recsecs); if ($int_secs > $distsecs && $distsecs > 0) { my @scorelin1 = split(/score\=/,$cline); my @scorelin2 = split(/\,/,$scorelin1[1]); $currentavg = $scorelin2[0]; if ($currentavg >= $HighScore) { # High Scoring SPAM $HighAverage = ($HighAverage + $currentavg); $HighCount++; } else { # Low Scoring SPAM $LowAverage = ($LowAverage + $currentavg); $LowCount++; } } } } close MAILLOG; if ($LowCount < 1) { $LowAverage = "0"; } else { $LowAverage = int($LowAverage / $LowCount); } if ($HighCount < 1) { $HighAverage = "0"; } else { $HighAverage = int($HighAverage / $HighCount); } } sub Print_Average { # Output the average in MRTG format. # IN: Low Scoring Spam Avg. # OUT: High Scoring Spam Avg. print "$LowAverage\n"; print "$HighAverage\n"; } exit 0;