I'm sure it could be better but I'm just learning python. :)
#!/usr/bin/env python # # rbl-check: Check an email message from stdin for an RBL host # and return 1 if not found # Check all of the received lines # rbl-check [dnsbl-list-file] # Optional dnsbl-list-file shout have one RBL server per line # # Portions stolen from: # TMDA http://tmda.net # rbl-lookup http://hacks.u--3.com # # GPL License - http://www.gnu.org/copyleft/gpl.html # Use at your own risk!
import os
import sys
try:
import paths
except ImportError:
# Prepend /usr/lib/python2.x/site-packages/TMDA/pythonlib
sitedir = os.path.join(sys.prefix, 'lib', 'python'+sys.version[:3],
'site-packages', 'TMDA', 'pythonlib')
sys.path.insert(0, sitedir)
import string
import email
import fileinput
from cStringIO import StringIO
import re
import socket
rbls = []
if len(sys.argv)>1:
try:
for line in fileinput.input(sys.argv[1]):
line = string.strip(line)
if len(line)>0:
rbls.append(line)
except:
pass
if len(rbls)<1:
rbls = ['sbl.spamhaus.org','list.dsbl.org','bl.spamcop.net']
msg = email.message_from_file(StringIO(sys.stdin.read()))
def ip_ok(x):
octets = string.split(x, '.')
if len(octets) != 4:
return 0
for o in octets:
try:
o = int(o)
except ValueError:
return 0
if not (0 <= o < 256):
return 0
if octets[0] == '10':
return 0
if octets[0] == '192' and octets[1] == '168':
return 0
return 1
def parse_received(l):
l = string.join(string.split(l))
mo = re.match(
r'''
from\s+
(?:
(\S+)\s+ # hostname + trailing space
\( # opening bracket
(?:\S+\s+)?# maybe hostname and space
)?
(?:[\d\w:]+@)?\[(\d+.\d+.\d+.\d+)\]
''',
l, re.IGNORECASE | re.VERBOSE)
if mo and ip_ok(mo.group(2)):
return mo.groups()
else:
return (None, None)
def lookup(ip, domain):
foo = string.split(ip, '.')
foo.reverse()
rip = string.join(foo, '.')
pala = rip + '.' + domain
try:
r = socket.gethostbyname(pala)
if r:
ret = 1
else:
ret = 0
except socket.error, why:
ret = 0
return ret
def main():
blacklisted = 0
relays = map(parse_received,msg.get_all('received'))
for domain,host in relays:
if host:
for rbl in rbls:
if lookup(host,rbl):
blacklisted = 1
break
if blacklisted:
break
if blacklisted:
sys.exit(0)
else:
sys.exit(1)
if __name__ == '__main__':
main()
