#!/usr/bin/python

""" Whitelist authenticated users - filter for courier-pythonfilter
    Author: Robert Penz <robert.penz@outertech.com>
    License: GPL
"""


import sys
#import courier.control
#import courier.config
import re


# Run before any other filter, except whitelist.py
order = 1

# Record in the system log that this filter was initialized.
sys.stderr.write( 'Initialized the "auth user" python filter\n' )


auth_regex = re.compile(r'\(AUTH:\s+(LOGIN|PLAIN|CRAM-MD5)\s+(?P<user>\S+),?.*\)', re.I)

# check the Header entry
# None      if no Received header entry
# ''        Received but not Auth
# '200 Ok'  Received and Auth
def checkHeaderEntry(entry):
    if not entry or not entry.startswith("Received:"):
        return None
    
    found = auth_regex.search(entry)
    if found:
        sys.stderr.write('Successful AUTH for "%s": message accepted\n' % found.group("user"))
        return "200 Ok"
    else:
        return ""        

def dofilter(message_data_file, message_ctrl_files):
    headerEntry = None

    try:
        lines = open(message_data_file,'r').read()
    except:
        return '451 Internal failure locating message data file'

    
    for line in lines.splitlines():        
        if line.strip() == "":
            # we have reached the end of the headers
            # check if the last header entry is our
            # Received one.
            result = checkHeaderEntry(headerEntry)
            if result:
                # result is non-None --> we've an anwser
                return result

            # there was no header --> can't say anything
            return ""
            
        # check is save as the if before would
        # have matched otherwise 
        elif line[0] in " \t\n\r\f\v":
            # The line begins with white space, which
            # means that it needs to be appended to the
            # current header entry
            # headerEntry = None would be a protocol
            # violation and would therefore never be
            # accepted by courier
            headerEntry+=line
        else:
            # we've a new header entry --> check the old
            # one if exists
            result = checkHeaderEntry(headerEntry)
            if result:
                # result is non-None --> we've an anwser
                return result
                
            headerEntry = line
    
    # now header --> can't say anything
    return ""

# Main program: parse command line and start processing
def main():
    # we only work with 1 parameter
    if len(sys.argv) != 2:
        print "Usage: auth_user <message_body_file>"
        sys.exit(0)
    print dofilter(sys.argv[1], "")
    
if __name__ == '__main__':
    main()
