Add ability to whitelist envelope from addresses
This commit is contained in:
@@ -31,7 +31,7 @@ from netaddr import IPAddress, IPNetwork, AddrFormatError
|
|||||||
class HeaderRule:
|
class HeaderRule:
|
||||||
"""HeaderRule to implement a rule to apply on e-mail headers."""
|
"""HeaderRule to implement a rule to apply on e-mail headers."""
|
||||||
|
|
||||||
def __init__(self, name, action, header, search="", value="", ignore_hosts=[], only_hosts=[], log=True):
|
def __init__(self, name, action, header, search="", value="", ignore_hosts=[], ignore_envfrom="", only_hosts=[], log=True):
|
||||||
self.logger = logging.getLogger(__name__)
|
self.logger = logging.getLogger(__name__)
|
||||||
self.name = name
|
self.name = name
|
||||||
self._action = action
|
self._action = action
|
||||||
@@ -39,6 +39,7 @@ class HeaderRule:
|
|||||||
self.search = search
|
self.search = search
|
||||||
self.value = value
|
self.value = value
|
||||||
self.ignore_hosts = ignore_hosts
|
self.ignore_hosts = ignore_hosts
|
||||||
|
self.ignore_envfrom = ignore_envfrom
|
||||||
self.only_hosts = only_hosts
|
self.only_hosts = only_hosts
|
||||||
self.log = log
|
self.log = log
|
||||||
|
|
||||||
@@ -66,6 +67,11 @@ class HeaderRule:
|
|||||||
except AddrFormatError as e:
|
except AddrFormatError as e:
|
||||||
raise RuntimeError("unable to parse option 'ignore_hosts' of rule '{}': {}".format(name, e))
|
raise RuntimeError("unable to parse option 'ignore_hosts' of rule '{}': {}".format(name, e))
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.ignore_envfrom = re.compile(ignore_envfrom, re.IGNORECASE)
|
||||||
|
except re.error as e:
|
||||||
|
raise RuntimeError("unable to parse option 'ignore_envfrom' of rule '{}': {}".format(name, e))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
for index, only in enumerate(only_hosts):
|
for index, only in enumerate(only_hosts):
|
||||||
self.only_hosts[index] = IPNetwork(only)
|
self.only_hosts[index] = IPNetwork(only)
|
||||||
@@ -100,6 +106,15 @@ class HeaderRule:
|
|||||||
self.logger.debug("host {} is ignored by rule {}".format(host, self.name))
|
self.logger.debug("host {} is ignored by rule {}".format(host, self.name))
|
||||||
return ignore
|
return ignore
|
||||||
|
|
||||||
|
def ignore_from(self, envfrom):
|
||||||
|
ignore = False
|
||||||
|
|
||||||
|
if self.ignore_envfrom:
|
||||||
|
if self.ignore_envfrom.search(envfrom):
|
||||||
|
ignore = True
|
||||||
|
self.logger.debug("envelope-from {} is ignored by rule {}".format(envfrom, self.name))
|
||||||
|
return ignore
|
||||||
|
|
||||||
def execute(self, headers):
|
def execute(self, headers):
|
||||||
"""Execute rule on given headers and return list with modified headers."""
|
"""Execute rule on given headers and return list with modified headers."""
|
||||||
if self._action == "add":
|
if self._action == "add":
|
||||||
@@ -157,6 +172,17 @@ class HeaderMilter(Milter.Base):
|
|||||||
return Milter.ACCEPT
|
return Milter.ACCEPT
|
||||||
return Milter.CONTINUE
|
return Milter.CONTINUE
|
||||||
|
|
||||||
|
def envfrom(self, mailfrom, *str):
|
||||||
|
mailfrom = "@".join(parse_addr(mailfrom)).lower()
|
||||||
|
for rule in self.rules.copy():
|
||||||
|
if rule.ignore_from(mailfrom):
|
||||||
|
self.rules.remove(rule)
|
||||||
|
|
||||||
|
if not self.rules:
|
||||||
|
self.logger.debug("mail from {} is ignored by all rules, skip further processing".format(mailfrom))
|
||||||
|
return Milter.ACCEPT
|
||||||
|
return Milter.CONTINUE
|
||||||
|
|
||||||
@Milter.noreply
|
@Milter.noreply
|
||||||
def data(self):
|
def data(self):
|
||||||
self.queueid = self.getsymval('i')
|
self.queueid = self.getsymval('i')
|
||||||
@@ -304,6 +330,7 @@ def main():
|
|||||||
# check if optional config options are present in config
|
# check if optional config options are present in config
|
||||||
defaults = {
|
defaults = {
|
||||||
"ignore_hosts": [],
|
"ignore_hosts": [],
|
||||||
|
"ignore_envfrom": "",
|
||||||
"only_hosts": [],
|
"only_hosts": [],
|
||||||
"log": "true"
|
"log": "true"
|
||||||
}
|
}
|
||||||
|
|||||||
2
setup.py
2
setup.py
@@ -5,7 +5,7 @@ def read_file(fname):
|
|||||||
return f.read()
|
return f.read()
|
||||||
|
|
||||||
setup(name = "pyheadermilter",
|
setup(name = "pyheadermilter",
|
||||||
version = "0.0.2",
|
version = "0.0.3",
|
||||||
author = "Thomas Oettli",
|
author = "Thomas Oettli",
|
||||||
author_email = "spacefreak@noop.ch",
|
author_email = "spacefreak@noop.ch",
|
||||||
description = "A pymilter based sendmail/postfix pre-queue filter.",
|
description = "A pymilter based sendmail/postfix pre-queue filter.",
|
||||||
|
|||||||
Reference in New Issue
Block a user