pymilter  1.0.5
milter-nomix.py
1 
4 
5 from __future__ import print_function
6 import Milter
7 import time
8 import sys
9 from Milter.utils import parse_addr
10 
11 internal_tlds = ["corp", "personal"]
12 
13 
15 def is_internal(hostname):
16  components = hostname.split(".")
17  return components.pop() in internal_tlds
18 
19 # Determine if internal and external hosts are mixed based on a list
20 # of hostnames
21 def are_mixed(hostnames):
22  hostnames_mapped = map(is_internal, hostnames)
23 
24  # Num internals
25  num_internal_hosts = hostnames_mapped.count(True)
26 
27  # Num externals
28  num_external_hosts = hostnames_mapped.count(False)
29 
30  return num_external_hosts >= 1 and num_internal_hosts >= 1
31 
32 class NoMixMilter(Milter.Base):
33 
34  def __init__(self): # A new instance with each new connection.
35  self.id = Milter.uniqueID() # Integer incremented with each call.
36 
37 
38 
39  @Milter.noreply
40  def envfrom(self, mailfrom, *str):
41  self.mailfrom = mailfrom
42  self.domains = []
43  t = parse_addr(mailfrom)
44  if len(t) > 1:
45  self.domains.append(t[1])
46  else:
47  self.domains.append('local')
48  self.internal = False
49  return Milter.CONTINUE
50 
51 
52  def envrcpt(self, to, *str):
53  self.R.append(to)
54  t = parse_addr(to)
55  if len(t) > 1:
56  self.domains.append(t[1])
57  else:
58  self.domains.append('local')
59 
60  if are_mixed(self.domains):
61  # FIXME: log recipients collected in self.mailfrom and self.R
62  self.setreply('550','5.7.1','Mixing internal and external TLDs')
63  return Milter.REJECT
64 
65  return Milter.CONTINUE
66 
67 def main():
68  socketname = "/var/run/nomixsock"
69  timeout = 600
70  # Register to have the Milter factory create instances of your class:
71  Milter.factory = NoMixMilter
72  print("%s milter startup" % time.strftime('%Y%b%d %H:%M:%S'))
73  sys.stdout.flush()
74  Milter.runmilter("nomixfilter",socketname,timeout)
75  logq.put(None)
76  bt.join()
77  print("%s nomix milter shutdown" % time.strftime('%Y%b%d %H:%M:%S'))
78 
79 if __name__ == "__main__":
80  main()
A do "nothing" Milter base class representing an SMTP connection.
Definition: __init__.py:265
Miscellaneous functions.
Definition: utils.py:1
def runmilter(name, socketname, timeout=0, rmsock=True)
Run the milter.
Definition: __init__.py:835
def uniqueID()
Definition: __init__.py:30