improve conditions handling
This commit is contained in:
@@ -199,6 +199,33 @@ class ModifyMilter(Milter.Base):
|
||||
self.logger.debug(
|
||||
f"accepted milter connection from {self.IP} "
|
||||
f"port {self.port}")
|
||||
|
||||
# pre-filter rules and actions by the host condition
|
||||
# also check if the mail body is needed by any upcoming action.
|
||||
self.rules = []
|
||||
self._headersonly = True
|
||||
for rule in ModifyMilter._rules:
|
||||
if rule.conditions is None or \
|
||||
rule.conditions.match_host(self.IP):
|
||||
actions = []
|
||||
for action in rule.actions:
|
||||
if action.conditions is None or \
|
||||
action.conditions.match_host(self.IP):
|
||||
actions.append(action)
|
||||
if not action.headersonly():
|
||||
self._headersonly = False
|
||||
|
||||
if actions:
|
||||
# copy needed rules to preserve configured actions
|
||||
rule = copy(rule)
|
||||
rule.actions = actions
|
||||
self.rules.append(rule)
|
||||
|
||||
if not self.rules:
|
||||
self.logger.debug(
|
||||
"host is ignored by all rules, skip further processing")
|
||||
return Milter.ACCEPT
|
||||
|
||||
except Exception as e:
|
||||
self.logger.exception(
|
||||
f"an exception occured in connect method: {e}")
|
||||
@@ -244,37 +271,6 @@ class ModifyMilter(Milter.Base):
|
||||
self.logger = CustomLogger(
|
||||
self.logger, {"qid": self.qid, "name": "milter"})
|
||||
self.logger.debug("received queue-id from MTA")
|
||||
|
||||
# pre-filter rules and actions by the host condition, other
|
||||
# conditions (headers, envelope-from, envelope-to) may get
|
||||
# changed by executed actions later on.
|
||||
# also check if the mail body is needed by any upcoming action.
|
||||
|
||||
self.rules = []
|
||||
self._headersonly = True
|
||||
for rule in ModifyMilter._rules:
|
||||
if rule.conditions is None or \
|
||||
rule.conditions.match(host=self.IP, qid=self.qid):
|
||||
actions = []
|
||||
for action in rule.actions:
|
||||
if action.conditions is None or \
|
||||
action.conditions.match(host=self.IP,
|
||||
qid=self.qid):
|
||||
actions.append(action)
|
||||
if not action.headersonly():
|
||||
self._headersonly = False
|
||||
|
||||
if actions:
|
||||
# copy needed rules to preserve configured actions
|
||||
rule = copy(rule)
|
||||
rule.actions = actions
|
||||
self.rules.append(rule)
|
||||
|
||||
if not self.rules:
|
||||
self.logger.debug(
|
||||
"message is ignored by all rules, skip further processing")
|
||||
return Milter.ACCEPT
|
||||
|
||||
self.fp = BytesIO()
|
||||
except Exception as e:
|
||||
self.logger.exception(
|
||||
@@ -341,7 +337,7 @@ class ModifyMilter(Milter.Base):
|
||||
refold_source='none'))
|
||||
self.msginfo = {
|
||||
"mailfrom": self.mailfrom,
|
||||
"rcpts": self.rcpts,
|
||||
"rcpts": [*self.rcpts],
|
||||
"vars": {}}
|
||||
|
||||
self._replacebody = False
|
||||
|
||||
@@ -194,9 +194,6 @@ class Action:
|
||||
logger = CustomLogger(
|
||||
self.logger, {"qid": milter.qid, "name": self._name})
|
||||
if self.conditions is None or \
|
||||
self.conditions.match(envfrom=milter.mailfrom,
|
||||
envto=[*milter.rcpts],
|
||||
headers=milter.msg.items(),
|
||||
qid=milter.qid):
|
||||
self.conditions.match(milter):
|
||||
return self._class.execute(
|
||||
milter=milter, pretend=self.pretend, logger=logger)
|
||||
|
||||
@@ -81,15 +81,10 @@ class Conditions:
|
||||
self._args = cfg["args"]
|
||||
self.logger = cfg.logger
|
||||
|
||||
def match(self, host=None, envfrom=None, envto=None, headers=None,
|
||||
qid=None):
|
||||
if qid is None:
|
||||
logger = self.logger
|
||||
else:
|
||||
def match_host(self, host):
|
||||
logger = CustomLogger(
|
||||
self.logger, {"qid": qid, "name": self._name})
|
||||
self.logger, {"name": self._name})
|
||||
|
||||
if host:
|
||||
ip = IPAddress(host)
|
||||
|
||||
if "local" in self._args:
|
||||
@@ -124,6 +119,13 @@ class Conditions:
|
||||
logger.debug(
|
||||
f"condition hosts matches for host {host}")
|
||||
|
||||
return True
|
||||
|
||||
def match(self, milter):
|
||||
logger = CustomLogger(
|
||||
self.logger, {"qid": milter.qid, "name": self._name})
|
||||
|
||||
envfrom = milter.msginfo["mailfrom"]
|
||||
if envfrom and "envfrom" in self._args:
|
||||
if not self._args["envfrom"].match(envfrom):
|
||||
logger.debug(
|
||||
@@ -135,6 +137,7 @@ class Conditions:
|
||||
f"condition envfrom matches for "
|
||||
f"envelope-from address {envfrom}")
|
||||
|
||||
envto = milter.msginfo["rcpts"]
|
||||
if envto and "envto" in self._args:
|
||||
if not isinstance(envto, list):
|
||||
envto = [envto]
|
||||
@@ -150,9 +153,9 @@ class Conditions:
|
||||
f"condition envto matches for "
|
||||
f"envelope-to address {envto}")
|
||||
|
||||
if headers and "header" in self._args:
|
||||
if "header" in self._args:
|
||||
match = None
|
||||
for field, value in headers:
|
||||
for field, value in milter.msg.items():
|
||||
header = f"{field}: {value}"
|
||||
match = self._args["header"].search(header)
|
||||
if match:
|
||||
|
||||
@@ -86,10 +86,7 @@ class Rule:
|
||||
def execute(self, milter):
|
||||
"""Execute all actions of this rule."""
|
||||
if self.conditions is None or \
|
||||
self.conditions.match(envfrom=milter.mailfrom,
|
||||
envto=[*milter.rcpts],
|
||||
headers=milter.msg.items(),
|
||||
qid=milter.qid):
|
||||
self.conditions.match(milter):
|
||||
for action in self.actions:
|
||||
milter_action = action.execute(milter)
|
||||
if milter_action is not None:
|
||||
|
||||
Reference in New Issue
Block a user