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