89 lines
2.5 KiB
Python
89 lines
2.5 KiB
Python
## 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()
|