diff --git a/milter-nomix.py b/milter-nomix.py new file mode 100644 index 0000000000000000000000000000000000000000..b7899a61eb73942b22cabf2d70481d5ef4812966 --- /dev/null +++ b/milter-nomix.py @@ -0,0 +1,88 @@ +## To roll your own milter, create a class that extends Milter. +# See the pymilter project at http://bmsi.com/python/milter.html +# based on Sendmail's milter API http://www.milter.org/milter_api/api.html +# This code is open-source on the same terms as Python. + +## Milter calls methods of your class at milter events. +## Return REJECT,TEMPFAIL,ACCEPT to short circuit processing for a message. +## You can also add/del recipients, replacebody, add/del headers, etc. + +import Milter +import time +import sys +from Milter.utils import parse_addr + +internal_tlds = ["corp", "personal"] + +# Determine if a hostname is internal or not. True if internal, +# False otherwise +def is_internal(hostname): + components = hostname.split(".") + + if components.pop() in internal_tlds: + return True + else: + return False + +# Determine if internal and external hosts are mixed based on a list +# of hostnames +def are_mixed(hostnames): + hostnames_mapped = map(is_internal, hostnames) + + # Num internals + num_internal_hosts = hostnames_mapped.count(True) + + # Num externals + num_external_hosts = hostnames_mapped.count(False) + + return num_external_hosts >= 1 and num_internal_hosts >= 1 + +class NoMixMilter(Milter.Base): + + def __init__(self): # A new instance with each new connection. + self.id = Milter.uniqueID() # Integer incremented with each call. + + + ## def envfrom(self,f,*str): + @Milter.noreply + def envfrom(self, mailfrom, *str): + self.mailfrom = mailfrom + self.domains = [] + t = parse_addr(mailfrom) + if len(t) > 1: + self.domains.append(t[1]) + else: + self.domains.append('local') + self.internal = False + return Milter.CONTINUE + + ## def envrcpt(self, to, *str): + def envrcpt(self, to, *str): + self.R.append(to) + t = parse_addr(to) + if len(t) > 1: + self.domains.append(t[1]) + else: + self.domains.append('local') + + if are_mixed(self.domains): + # FIXME: log recipients collected in self.mailfrom and self.R + self.setreply('550','5.7.1','Mixing internal and external TLDs') + return Milter.REJECT + + return Milter.CONTINUE + +def main(): + socketname = "/var/run/nomixsock" + timeout = 600 + # Register to have the Milter factory create instances of your class: + Milter.factory = NoMixMilter + print "%s milter startup" % time.strftime('%Y%b%d %H:%M:%S') + sys.stdout.flush() + Milter.runmilter("nomixfilter",socketname,timeout) + logq.put(None) + bt.join() + print "%s nomix milter shutdown" % time.strftime('%Y%b%d %H:%M:%S') + +if __name__ == "__main__": + main()