Send quarantine DSN to SPF PASS only.

This commit is contained in:
Stuart Gathman
2008-08-05 18:04:06 +00:00
parent a420148b1e
commit be3f463450
2 changed files with 38 additions and 21 deletions
+34 -17
View File
@@ -1,6 +1,9 @@
#!/usr/bin/env python #!/usr/bin/env python
# A simple milter that has grown quite a bit. # A simple milter that has grown quite a bit.
# $Log$ # $Log$
# Revision 1.123 2008/07/29 21:59:29 customdesigned
# Parse ESMTP params
#
# Revision 1.122 2008/05/08 21:35:56 customdesigned # Revision 1.122 2008/05/08 21:35:56 customdesigned
# Allow explicitly whitelisted email from banned_users. # Allow explicitly whitelisted email from banned_users.
# #
@@ -1580,7 +1583,7 @@ class bmsMilter(Milter.Milter):
ds.check_spam(screener,txt,self.recipients, ds.check_spam(screener,txt,self.recipients,
force_result=dspam.DSR_ISINNOCENT) force_result=dspam.DSR_ISINNOCENT)
return False return False
if self.reject_spam: if self.reject_spam and self.spf.result != 'pass':
self.log("DSPAM:",screener, self.log("DSPAM:",screener,
'REJECT: X-DSpam-Score: %f' % ds.probability) 'REJECT: X-DSpam-Score: %f' % ds.probability)
self.setreply('550','5.7.1','Your Message looks spammy') self.setreply('550','5.7.1','Your Message looks spammy')
@@ -1590,12 +1593,18 @@ class bmsMilter(Milter.Milter):
if self.spf and self.mailfrom != '<>': if self.spf and self.mailfrom != '<>':
# check that sender accepts quarantine DSN # check that sender accepts quarantine DSN
self.fp.seek(0) self.fp.seek(0)
if self.spf.result == 'pass' or self.cbv_needed:
msg = mime.message_from_file(self.fp) msg = mime.message_from_file(self.fp)
if self.spf.result == 'pass':
rc = self.send_dsn(self.spf,msg,'quarantine') rc = self.send_dsn(self.spf,msg,'quarantine')
else:
rc = self.do_needed_cbv(msg)
del msg
else:
rc = self.send_dsn(self.spf)
if rc != Milter.CONTINUE: if rc != Milter.CONTINUE:
self.fp = None self.fp = None
return rc return rc
del msg
if not ds.check_spam(screener,txt,self.recipients,classify=True): if not ds.check_spam(screener,txt,self.recipients,classify=True):
self.fp = None self.fp = None
return Milter.DISCARD return Milter.DISCARD
@@ -1638,6 +1647,25 @@ class bmsMilter(Milter.Milter):
quarantine=False) quarantine=False)
self.log("TRAINSPAM:",screener,'X-Dspam-Score: %f' % ds.probability) self.log("TRAINSPAM:",screener,'X-Dspam-Score: %f' % ds.probability)
def do_needed_cbv(self,msg):
q,res = self.cbv_needed
if res == 'softfail':
template_name = 'softfail'
elif res in ('fail','deny'):
template_name = 'fail'
elif res in ('unknown','permerror'):
template_name = 'permerror'
elif res == 'neutral':
#template_name = 'neutral'
template_name = None
elif res in ('error','temperror'):
template_name = 'temperror'
else:
template_name = 'strike3'
rc = self.send_dsn(q,msg,template_name)
self.cbv_needed = None
return rc
def eom(self): def eom(self):
if not self.fp: if not self.fp:
return Milter.ACCEPT # no message collected - so no eom processing return Milter.ACCEPT # no message collected - so no eom processing
@@ -1763,21 +1791,7 @@ class bmsMilter(Milter.Milter):
# need CBV. However, whitelisted domains might (to discover # need CBV. However, whitelisted domains might (to discover
# bogus localparts). Need a way to tell the difference. # bogus localparts). Need a way to tell the difference.
if self.cbv_needed and not self.internal_domain: if self.cbv_needed and not self.internal_domain:
q,res = self.cbv_needed rc = self.do_needed_cbv(msg)
if res == 'softfail':
template_name = 'softfail'
elif res in ('fail','deny'):
template_name = 'fail'
elif res in ('unknown','permerror'):
template_name = 'permerror'
elif res == 'neutral':
template_name = 'neutral'
elif res in ('error','temperror'):
template_name = 'temperror'
else:
template_name = 'strike3'
rc = self.send_dsn(q,msg,template_name)
self.cbv_needed = None
if rc == Milter.REJECT: if rc == Milter.REJECT:
# Do not feedback here, because feedback should only occur # Do not feedback here, because feedback should only occur
# for messages that have gone to DATA. Reputation lets us # for messages that have gone to DATA. Reputation lets us
@@ -1886,7 +1900,10 @@ class bmsMilter(Milter.Milter):
return Milter.TEMPFAIL return Milter.TEMPFAIL
cbv_cache[sender] = res cbv_cache[sender] = res
self.log('REJECT:',desc) self.log('REJECT:',desc)
try:
self.setreply('550','5.7.1',*desc.splitlines()) self.setreply('550','5.7.1',*desc.splitlines())
except TypeError:
self.setreply('550','5.7.1',"Callback failure")
return Milter.REJECT return Milter.REJECT
cbv_cache[sender] = res cbv_cache[sender] = res
return Milter.CONTINUE return Milter.CONTINUE
+1 -1
View File
@@ -61,7 +61,7 @@ porn_words = penis, breast, pussy, horse cock, porn, xenical, diet pill, d1ck,
p-e-n-i-s, hydrocodone, vicodin, xanax, vicod1n, x@nax, diazepam, p-e-n-i-s, hydrocodone, vicodin, xanax, vicod1n, x@nax, diazepam,
v1@gra, xan@x, cialis, ci@lis, frëe, xãnax, valíum, vãlium, via-gra, v1@gra, xan@x, cialis, ci@lis, frëe, xãnax, valíum, vãlium, via-gra,
x@n3x, vicod3n, penís, c0d1n, phentermine, en1arge, dip1oma, v1codin, x@n3x, vicod3n, penís, c0d1n, phentermine, en1arge, dip1oma, v1codin,
valium, rolex, sexual, fuck, adv1t, vgaira, medz valium, rolex, sexual, fuck, adv1t, vgaira, medz, acai berry
# reject mail with these case sensitive strings in the subject # reject mail with these case sensitive strings in the subject
spam_words = $$$, !!!, XXX, FREE, HGH spam_words = $$$, !!!, XXX, FREE, HGH
# attachments with these extensions will be replaced with a warning # attachments with these extensions will be replaced with a warning