#!/usr/bin/python

# wireless sentry
# ianw@ieee.org

import re
import time
import sys
import os
import errno
import smtplib

LAST_CHECK_FILE='/etc/wireless_sentry/last_checked'
VALID_MACS='/etc/wireless_sentry/valid_macs'
SYSLOG_MESSAGES='/var/log/messages'

AP_HOSTNAME='wireless'
MAIL_TO='root@host.com'
MAIL_FROM='wireless-security@host.com'
MAIL_SERVER='mail.host.com'

MESSAGE = """Subject: Wireless Security Breach [%s]

Seems %s was connecting up to our wireless network
at %s

Thanks
"""

class MacChecker:
    def __init__(self):
        self.allowed_macs = []
        try:
            for line in open(VALID_MACS):
                stripped_line = line[0:line.find('#')].strip()
                if (len(stripped_line) == 0):
                    continue # comment line
                if (len(stripped_line) != 17):
                    print "Syntax error : %s" % line
                    sys.exit(1)
                self.allowed_macs.append(stripped_line.upper())
        except IOError, (error, message):
            print "Error reading mac input : %s" % message
            sys.exit(1)

        try:
            self.last_file = open(LAST_CHECK_FILE, 'r+')
        except IOError, (error, message):
            print "Can't open status file : %s" % message
            sys.exit(1)

        try:
            in_time = self.last_file.readline().strip()
            self.last_time = time.strptime(in_time,
                                           '%Y %b %d %H:%M:%S')
        except ValueError:
            self.last_time = time.localtime()

    def check_mac(self, in_entry):
        if self.last_time > in_entry.timestamp:
            return True
        for mac in self.allowed_macs:
            if mac == in_entry.mac:
                return True
        return False

    def update_last_time(self):
        self.last_file.seek(0)
        self.last_file.truncate()
        self.last_file.write(time.strftime("%Y %b %d %H:%M:%S"))
        self.last_file.close()

class Entry:
    def __init__(self, line):
        self.valid = False
        # group 1 : time
        # group 2 : host
        # group 3 : the rest
        line_regex = re.compile('(.{15,15}) (.*?) (.*)');
        line_match = line_regex.match(line)
        if (line_match.group(2) == AP_HOSTNAME):
            # filter for things likely to be a mac
            if line_match.group(3).find(":") == -1:
                self.valid = False
                return
            #hack, no year in time
            line_time = time.strftime("%Y") + " " + line_match.group(1)
            self.string_time = line_time
            self.timestamp = time.strptime(line_time,
                                           '%Y %b %d %H:%M:%S' )
            self.mac = line_match.group(3)[-17:]
            self.valid = True

    def is_valid(self):
        return self.valid

#
# begin mac checker
#
mc = MacChecker()

for line in open(SYSLOG_MESSAGES, 'r').readlines():
    e = Entry(line)
    if e.is_valid():
        if mc.check_mac(e) == False:
            msg = MESSAGE % (e.mac, e.mac, e.string_time)
            server = smtplib.SMTP(MAIL_SERVER)
            server.sendmail(MAIL_FROM, MAIL_TO, msg)
            server.quit()
    
mc.update_last_time()

