#!/usr/bin/python

# remove_email_virus.py
#       --copyright--                   Copyright 2007 (C) Tranzoa, Co. All rights reserved.    Warranty: You're free and on your own here. This code is not necessarily up-to-date or of public quality.
#       --url--                         http://www.tranzoa.net/tzpython/
#       --email--                       pycode is the name to send to. tranzoa.com is the place to send to.
#       --bodstamps--
#       August 19, 2003         bar
#       August 20, 2003         bar     get more lines of text
#       August 21, 2003         bar     ignore errors from TOP so that fetchmail won't mess us up
#       August 22, 2003         bar     change the script name
#                                       put the _help routine in
#       July 16, 2006           bar     use getpass
#       November 18, 2007       bar     turn on doxygen
#       November 27, 2007       bar     insert boilerplate copyright
#       May 17, 2008            bar     email adr
#       November 29, 2011       bar     pyflake cleanup
#       May 27, 2012            bar     doxygen namespace
#       --eodstamps--
##      \file
#       \namespace              tzpython.remove_email_virus
#
#
#       DATE IN _help()
#
#
#       Whack SoBig/F viruses from a POP3 account.
#
#       TODO:
#
#           ... And the list goes on and on. This script is a Q & D written under the gun.
#
#           Print out the spoofed email addresses in case their domains might give a clue to whose machine is generating the emails.
#           Properly parse the Received: headers (unfolded, etc. etc)
#           "except:" only what should be excepted, not everything.
#           Don't echo the password when operator enters it.
#           Hey, test the config, text file logic. It's never been used!
#
#

import  getpass
import  poplib
import  re
import  string
import  sys
import  time


__ALL__ = [
            'whack_pop3_viruses',
          ]



LINES_TO_GET        = 150

def whack_pop3_viruses(host = None, user = None, password = None, ip_address_file = None) :

    count = 0

    if  (host == None) or (len(host) == 0) :
        print "Host? ",
        host = sys.stdin.readline().strip()
        if  host == "" :
            return(-1)
        pass

    if  (user == None) or (len(user) == 0) :
        print "User? ",
        user = sys.stdin.readline().strip()
        if  user == "" :
            return(-1)
        pass

    if  (password == None) or (len(password) == 0) :
        print "Password? ",
        password = getpass.getpass().strip()
        if  password == "" :
            return(-1)
        pass

    host     = host.strip()
    user     = user.strip()
    password = password.strip()

    me = poplib.POP3(host)

    # me.set_debuglevel(2)

    r  = me.getwelcome()
    # print "Welcome is", r

    r = me.user(user)
    # print "User response is", r
    r = me.pass_(password)
    # print "Password response is", r

    (cnt, size) = me.stat()
    print cnt, "emails in the inbox"

    v = re.compile(r"\n"                                                                             +
                    "\nTVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
                    "\nAAAA4AAAAA4fug4AtAnNIbgBTM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1v" +
                    "\nZGUuDQ0KJAAAAAAAAADToEjPl8EmnJfBJpyXwSacFN0onI3BJpx/3iyc7cEmnMHeNZyawSacl8Em" +
                    "\nnJTBJpyXwSecBsEmnPXeNZyawSacf94tnI3BJpxSaWNol8EmnAAAAAAAAAAAAAAAAAAAAABQRQAA" +
                    "\nTAEEAF2zPz8AAAAAAAAAAOAADwELAQYAAAAAAABwAAAAAAAA1usBAAAQAAAAYAEAAABAAAAQAAAA" +
                    "\nAgAABAAAAAAAAAAEAAAAAAAAAAAAAgAAEAAAF/EBAAIAAAAAABAAABAAAAAAEAAAEAAAAAAAABAA" +
                    "\nAAAAAAAAAAAAAOLrAQCcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfuwBAAgAAAAAAAAAAAAA" +
                    "\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
                    "\nAAAAAAAAAAAAAAAAAAAgAC5zaHJpbmsAAFABAAAQAAAAxAAAABAAAAAAAAAAAAAAAAAAAEAAAMAu" +
                    "\nc2hyaW5rAAAwAAAAYAEAABIAAADUAAAAAAAAAAAAAAAAAABAAADALnNocmluawAAQAAAAJABAAAS" +
                    "\nAAAA5gAAAAAAAAAAAAAAAAAAQAAAwC5zaHJpbmsAADAAAADQAQAAIgAAAPgAAAAAAAAAAAAAAAAA" +
                    "\nAEAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +
                    "\n",
                    re.DOTALL
                  )

    from_ip = re.compile(r"Received: from[^\n]+?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s*[\]\)]", re.DOTALL)

    for midx in range(1, cnt + 1):
        r   = None
        try :
            r   = me.top(midx, LINES_TO_GET)
        except :
            break

        print midx, r[0], r[2] # , r[1]

        em  = string.join(r[1], "\n")

        if  v.search(em) :
            # print em

            real_ip_adr = ip_adr = ""

            g = from_ip.findall(em)
            if  len(g) :
                ip_adr = g[len(g) - 1]

            try :
                i  = r[1].index("")
                em = string.join(r[1][0:i], "\n")
            except :
                em = ""

            g = from_ip.findall(em)
            if  len(g) :
                real_ip_adr = g[len(g) - 1]
                pass

            s   = "Virus probably from [" + ip_adr + "] directly from [" + real_ip_adr + "] at " + time.asctime()

            if  ip_address_file != None :
                open(ip_address_file, "a+").write(s + "\n")

            print s

            try :
                me.dele(midx)                   # fetchmail can steal the email from us so we can't delete it, eh?
                count = count + 1
            except :
                break
            pass

        pass

    me.quit()

    return(count)


#
#
#
if __name__ == '__main__' :


    def _help() :
        print """
remove_email_virus.py               August 22, 2003

I delete SoBig/F virus emails from a POP3 mailbox.

Command line parameters:

  --host            name            Post office host system.
  --user            name            POP3 user name.
  --password        pw              Password (I can ask for it interactively)
  --loop            value           How many seconds to wait before looping
                                        (dflt: run 1 time)
  --ip_address_file log_file_name   Print records to this file.

  @config_file_name                 File contains, e.g., host=tranzoa.com
"""
        pass


    host            = None
    user            = None
    password        = None
    loop            = None
    ip_address_file = None

    while (len(sys.argv) >= 2) :
        a = sys.argv[1]

        if  a[0] == '@' :
            a = a[1:]
            r = "\n" + open(a, "r").read() + "\n"

            def _get(what, r, dflt) :
                g = re.match(r"^\s*" + what + "\s*=\s*(\S)\s*$", r, re.MULTILINE)
                if  g != None :
                    return(g.group(1))
                return(dflt)

            host            = _get("host",                 r, host)
            user            = _get("user",                 r, user)
            password        = _get("password",             r, password)
            loop            = _get("loop",                 r, loop)
            ip_address_file = _get("ip_address_file",      r, ip_address_file)

        elif (a == "/?") or (a == "-?") or (a.lower() == "/h") or (a.lower() == "-h") or (a.lower() == "--help") :
            _help()
            sys.exit(0)

        elif len(sys.argv) < 3 :
            print
            print a, "requires a parameter"
            print
            sys.exit(101)


        elif a == "--host" :
            del(sys.argv[1])
            host = sys.argv.pop(1)

        elif a == "--user" :
            del(sys.argv[1])
            user = sys.argv.pop(1)

        elif a == "--password" :
            del(sys.argv[1])
            password = sys.argv.pop(1)

        elif a == "--loop" :
            del(sys.argv[1])
            loop = sys.argv.pop(1)

        elif a == "--ip_address_file" :
            del(sys.argv[1])
            ip_address_file = sys.argv.pop(1)

        else :
            print
            print "Unkonwn parameter", a
            print
            sys.exit(102)

        pass

    if  loop != None :  loop = int(loop)

    if  (host == None) or (len(host) == 0) :
        print "Host? ",
        host = sys.stdin.readline().strip()

    if  (user == None) or (len(user) == 0) :
        print "User? ",
        user = sys.stdin.readline().strip()

    if  (password == None) or (len(password) == 0) :
        print "Password? ",
        password = getpass.getpass().strip()

    total = 0
    while True :
        r     = whack_pop3_viruses(host = host, user = user, password = password, ip_address_file = ip_address_file)

        total = total + r
        print r, "viruses deleted this time", total, "total"

        if  loop == None :  break

        time.sleep(loop)

    pass


#
#
#
# eof
