summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/infra.gentoo.org/milters/subscribed.py')
-rw-r--r--src/infra.gentoo.org/milters/subscribed.py52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/infra.gentoo.org/milters/subscribed.py b/src/infra.gentoo.org/milters/subscribed.py
new file mode 100644
index 0000000..dc5d842
--- /dev/null
+++ b/src/infra.gentoo.org/milters/subscribed.py
@@ -0,0 +1,52 @@
+"""Reject messages at RCPT_TO time if the envelop sender is not subscribed.
+
+Gentoo's mlmmj is configured to silently drop messages if the poster is not
+subscribed (including no bounces) to prevent backscatter. This milter is
+intended to work around this problem by rejecting messages at message-send
+time. We do this by:
+
+ - Looking at RCPT TO headers to see where the message is headed.
+ - If its an mlmmj list, checking the subscriber list.
+ - If the envelop sender is not subscribed, reject the message rather
+ than accepting it for delivery.
+
+This is accomplished with a sendmail compatible milter that receives
+callbacks for every message seen by postfix and computing some extra logic
+to enforce these rules.
+"""
+
+import os
+import Milter
+import mlmmj
+
+def SubscribedMilterFactory():
+ """Return a SubscribedMilter with a MlmmjSource configured."""
+ inst = mlmmj.GetSingletonConfig()
+ return SubscribedMilter(mlmmj_config=inst)
+
+
+class SubscribedMilter(Milter.Base):
+ """Rejects messages at accept time if address is not subscribed."""
+
+ def __init__(self, mlmmj_config):
+ self.mlmmj_config = mlmmj_config
+
+ def envfrom(self, mailfrom, *args):
+ # Store the envelope sender for later computation
+ self.mailfrom = mailfrom
+ return Milter.CONTINUE
+
+ def envrcpt(self, to, *args):
+ if mlmmj_config.IsMailingList(to):
+ if mlmmj_config.IsSubscribed(self.mailfrom, to):
+ return Milter.ACCEPT
+ else:
+ self.setreply('550', '5.7.1',
+ '%s is not a subscriber to %d; please subscribe to send messages to this list.' %(self.mailfrom, to))
+ return Milter.REJECT
+
+if __name__ == "__main__":
+ socketname = "/var/run/mlmmj-milter.sock"
+ timeout = 600
+ Milter.factory = SubscribedMilterFactory
+ Milter.runmilter("MlmmjMilter", socketname, timeout)