diff --git a/bms.py b/bms.py
index f71d7ca227642ee1a1959e490ee658aabb4cfc00..3e043b2e74debe7879b7c1473fd70359f852ffac 100644
--- a/bms.py
+++ b/bms.py
@@ -1,6 +1,9 @@
#!/usr/bin/env python
# A simple milter that has grown quite a bit.
# $Log$
+# Revision 1.114 2007/10/10 18:07:50 customdesigned
+# Check porn keywords in From header field.
+#
# Revision 1.113 2007/09/25 16:37:26 customdesigned
# Tested on RH7
#
@@ -941,7 +944,7 @@ class bmsMilter(Milter.Milter):
if policy == 'CBV':
if self.mailfrom != '<>':
self.cbv_needed = (q,ores) # accept, but inform sender via DSN
- self.offenses = 3 # ban ip if any bad recipient
+ self.offenses = 3 # ban ip if any bad recipient
elif policy != 'OK':
self.log('REJECT: no PTR, HELO or SPF')
self.setreply('550','5.7.1',
@@ -1092,7 +1095,7 @@ class bmsMilter(Milter.Milter):
self.log('REJECT: RCPT TO:',to,str)
if gossip and self.umis:
gossip_node.feedback(self.umis,1)
- self.umis = None
+ self.umis = None
return self.offense()
# FIXME: should dspam_exempt be case insensitive?
if user in block_forward.get(domain,()):
@@ -1430,6 +1433,12 @@ class bmsMilter(Milter.Milter):
elif not self.internal_connection or dspam_internal:
if len(txt) > dspam_sizelimit:
self.log("Large message:",len(txt))
+ if self.blacklist:
+ self.log('REJECT: BLACKLISTED')
+ self.setreply('550','5.7.1',
+ '%s has been blacklisted.'%self.canon_from)
+ self.fp = None
+ return Milter.REJECT
return False
if user == 'honeypot' and Dspam.VERSION >= '1.1.9':
keep = False # keep honeypot mail
@@ -1441,9 +1450,12 @@ class bmsMilter(Milter.Milter):
return False
if self.spf and self.mailfrom != '<>':
# check that sender accepts quarantine DSN
- msg = mime.message_from_file(StringIO.StringIO(txt))
- rc = self.send_dsn(self.spf,msg,'quarantine')
- del msg
+ if self.spf.result == 'pass':
+ msg = mime.message_from_file(StringIO.StringIO(txt))
+ rc = self.send_dsn(self.spf,msg,'quarantine')
+ del msg
+ else:
+ rc = self.send_dsn(self.spf)
if rc != Milter.CONTINUE:
return rc
ds.check_spam(user,txt,self.recipients,quarantine=True,
@@ -1671,9 +1683,11 @@ class bmsMilter(Milter.Milter):
except Milter.error:
self.addheader(name,val) # older sendmail can't insheader
- # do not send CBV to internal domains (since we'll just get
- # the "Fraudulent MX" error).
- if self.cbv_needed and not self.internal_domain:
+ # Do not send CBV to internal domains (since we'll just get
+ # the "Fraudulent MX" error). Whitelisted senders clearly do not
+ # need CBV. However, whitelisted domains might (to discover
+ # bogus localparts). Need a way to tell the difference.
+ if self.cbv_needed and not self.internal_domain and not self.whitelist:
q,res = self.cbv_needed
if res == 'softfail':
template_name = 'softfail'
@@ -1754,22 +1768,24 @@ class bmsMilter(Milter.Milter):
out.close()
return Milter.TEMPFAIL
- def send_dsn(self,q,msg,template_name):
+ def send_dsn(self,q,msg=None,template_name=None):
sender = q.s
cached = cbv_cache.has_key(sender)
if cached:
self.log('CBV:',sender,'(cached)')
res = cbv_cache[sender]
else:
- fname = template_name+'.txt'
- try:
- template = file(template_name+'.txt').read()
- self.log('CBV:',sender,'Using:',fname)
- except IOError:
- template = None
+ m = None
+ if template_name:
+ fname = template_name+'.txt'
+ try:
+ template = file(template_name+'.txt').read()
+ m = dsn.create_msg(q,self.recipients,msg,template)
+ self.log('CBV:',sender,'Using:',fname)
+ except IOError: pass
+ if not m:
self.log('CBV:',sender,'PLAIN')
- m = dsn.create_msg(q,self.recipients,msg,template)
- if m:
+ else:
if srs:
# Add SRS coded sender to various headers. When (incorrectly)
# replying to our DSN, any of these which are preserved