#! /usr/bin/python
# written by Kirk Hammond (kirkdhammond@gmail.com)
# Licensed under GPL, feel free to use, modify, distribute.  Please give credit when/where appropriate.
#
# This script will check logs of a postfix mail server for the string "Barracuda Reputation".  When the string is matches a WARNING alert is passed to Nagios, the alert includes the IP address that is on the Barracuda RBL to simplify removal requests.
# You can submit removal requests to Barracuda here http://www.barracudacentral.org/rbl/removal-request
# Removal requests rarely recieve any feedback and typically take 24-48 hours for any change to be seen

#import libraries
import re, sys, datetime
from datetime import date, timedelta

#Nagios exit  codes
UNKNOWN = -1
OK = 0
WARNING = 1
CRITICAL = 2

#create logfiles list for processing, the script will loop through each logfile added to this list.
logfiles = []
logfiles.append('/var/log/maillog')
#logfiles.append('path/to/logfile/two')
#logfiles.append('path/to/logfile/three')

# create a time string that will determine how far back the script will checki logs.  Default is 2 hours.
def get_timestring():
  cutofftime = datetime.datetime.now() -timedelta(hours=2) #change the value of -timedelta(hours=<int>) to control how far back the script looks at logs. timedelta will accept days, hours, and minutes here.
  cutofftime = cutofftime.strftime('%H:%M')
  return cutofftime

# trim logs to only include "Barracuda Reputation" string matches and status= lines since the cutofftime 
def trim_logs(logfiles, cutofftime):
  reputation_matches = []
  for log in logfiles:
    f = open(log, 'rU')
    lines = f.readlines()
    for line in lines:
      time = re.search('^\w+\s+\d+\s+(\d+:\d+)', line).group(1)
      if time > cutofftime and re.search('Barracuda Reputation', line) and re.search("status=", line):
        reputation_matches.append(line)
  return reputation_matches

# process reputation matches into an array collecting only usable data
def process_matches(reputation_matches):
  reputation_array = []
  for line in reputation_matches:
    data = re.search('(^\w+\s+\d+)\s(\d\d:\d\d:\d\d).*ip=(\d+\.\d+\.\d+\.\d+)', line)
    date = data.group(1)
    time = data.group(2)
    ip = data.group(3)
    line_entry = date, time, ip
    reputation_array.append(line_entry)
  return reputation_array

# return exit status to nagios
def nagios_alerts(reputation_array):
  alerts = []
  if not reputation_array:
    print 'Barracuda Reputation - OK'
    sys.exit(OK)
  else:
    for line in reputation_array:
      if line[2] in alerts:
        pass
      else:
       alerts.append(line[2])
    print 'Baracuda Reputaiton - WARNING ', alerts
    sys.exit(WARNING)

# main function - controls flow of script
def main():
  reputation_matches = None
  reputation_array = None
  cutofftime = get_timestring()
  reputation_matches = trim_logs(logfiles, cutofftime)
  if reputation_matches is not None:
    reputation_array = process_matches(reputation_matches)
    if reputation_array is not None:
      nagios_alerts(reputation_array)
    else:
      print 'No Barracuda Reputation Matches Found'
  else:
    print 'No Barracuda Reputation Matches Found'

# call main function
if __name__ == '__main__':
  main()