aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xMailman/Defaults.py.in4
-rwxr-xr-xMailman/MailList.py6
-rw-r--r--Mailman/Utils.py22
3 files changed, 32 insertions, 0 deletions
diff --git a/Mailman/Defaults.py.in b/Mailman/Defaults.py.in
index 7a86f63c..63a8e99f 100755
--- a/Mailman/Defaults.py.in
+++ b/Mailman/Defaults.py.in
@@ -150,6 +150,10 @@ GLOBAL_BAN_LIST = []
# will be blocked.
BLOCK_SPAMHAUS_LISTED_IP_SUBSCRIBE = No
+# IF the following is set to Yes, and a subscriper uses a domain that is
+# listed in the Spamhaus DBL, the subscription will be blocked.
+BLOCK_SPAMHAUS_LISTED_DBL_SUBSCRIBE = No
+
# Command that is used to convert text/html parts into plain text. This
# should output results to standard output. %(filename)s will contain the
# name of the temporary file that the program should operate on.
diff --git a/Mailman/MailList.py b/Mailman/MailList.py
index fdc3802a..b2bb22a5 100755
--- a/Mailman/MailList.py
+++ b/Mailman/MailList.py
@@ -915,6 +915,12 @@ class MailList(HTMLFormatter, Deliverer, ListAdmin,
syslog('vette', '%s banned subscription: %s%s (Spamhaus IP)',
realname, email, whence)
raise Errors.MembershipIsBanned, 'Spamhaus IP'
+ # See if this is from a spamhaus listed domain.
+ if email and mm_cfg.BLOCK_SPAMHAUS_LISTED_DBL_SUBSCRIBE:
+ if Utils.banned_domain(email):
+ syslog('vette', '%s banned subscription: %s (Spamhaus DBL)',
+ realname, email)
+ raise Errors.MembershipIsBanned, 'Spamhaus DBL'
# Sanity check the digest flag
if digest and not self.digestable:
raise Errors.MMCantDigestError
diff --git a/Mailman/Utils.py b/Mailman/Utils.py
index 6038667b..a8c8fd82 100644
--- a/Mailman/Utils.py
+++ b/Mailman/Utils.py
@@ -1530,3 +1530,25 @@ def banned_ip(ip):
if re.search(r'127\.0\.0\.[2-7]$', text, re.MULTILINE):
return True
return False
+
+def banned_domain(email):
+ if not dns_resolver:
+ return False
+
+ email = email.lower()
+ user, domain = ParseEmail(email)
+
+ lookup = '%s.zen.spamhaus.org' % (domain)
+
+ resolver = dns.resolver.Resolver()
+ try:
+ ans = resolver.query(lookup, dns.rdatatype.A)
+ except DNSException:
+ return False
+ if not ans:
+ return False
+ text = ans.rrset.to_text()
+ if re.search(r'127\.0\.1\.\d{1,3}$', text, re.MULTILINE):
+ if not re.search(r'127\.0\.1\.255$', text, re.MULTILINE):
+ return True
+ return False