diff --git a/TODO b/TODO index 22b3b40ad1def0dc136470c03a31129e679744c3..5b1db9b172f92e55a59b4c53a47bc833c34b1054 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,11 @@ +When bms.py can't find templates, it passes None to dsn.create_msg(), +which uses local variable as backup, which no longer exist. + +Purge old GOSSiP records nightly. + +Find and use X-GOSSiP: header for SPAM: and FP: submissions. Would need to +keep tags longer. + Generate DSNs according to RFC 3464 Parse incoming 3464 DSNs for "Action: failed" to recognize delayed diff --git a/bms.py b/bms.py index eb862b74781b29b54a501037cecce00f49cf7ea1..6c704f2673a5fcb04536ed9ac820af05e6fa28b5 100644 --- a/bms.py +++ b/bms.py @@ -1,6 +1,10 @@ #!/usr/bin/env python # A simple milter that has grown quite a bit. # $Log$ +# Revision 1.73 2006/12/04 18:47:03 customdesigned +# Reject multiple recipients to DSN. +# Auto-disable gossip on DB error. +# # Revision 1.72 2006/11/22 16:31:22 customdesigned # SRS domains were missing srs_reject check when SES was active. # @@ -28,6 +32,7 @@ import time import socket import struct import re +import shutil import gc import anydbm import Milter.dsn as dsn @@ -85,6 +90,8 @@ reject_virus_from = () wiretap_users = {} discard_users = {} wiretap_dest = None +mail_archive = None +_archive_lock = None blind_wiretap = True check_user = {} block_forward = {} @@ -258,12 +265,13 @@ def read_config(list): reject_virus_from = cp.getlist('scrub','reject_virus_from') # wiretap section - global blind_wiretap, wiretap_users, wiretap_dest, discard_users + global blind_wiretap,wiretap_users,wiretap_dest,discard_users,mail_archive blind_wiretap = cp.getboolean('wiretap','blind') wiretap_users = cp.getaddrset('wiretap','users') discard_users = cp.getaddrset('wiretap','discard') wiretap_dest = cp.getdefault('wiretap','dest') if wiretap_dest: wiretap_dest = '<%s>' % wiretap_dest + mail_archive = cp.getdefault('wiretap','archive') global smart_alias for sa,v in [ @@ -811,7 +819,8 @@ class bmsMilter(Milter.Milter): self.blacklist = True self.log("BLACKLIST",self.canon_from) global gossip - if gossip and domain and rc == Milter.CONTINUE: + if gossip and domain and rc == Milter.CONTINUE \ + and not self.internal_connection: if self.spf and self.spf.result == 'pass': qual = 'SPF' else: @@ -1579,6 +1588,21 @@ class bmsMilter(Milter.Milter): if rc != Milter.CONTINUE: return rc + if mail_archive: + global _archive_lock + if not _archive_lock: + import thread + _archive_lock = thread.allocate_lock() + _archive_lock.acquire() + try: + fin = open(self.tempname,'r') + fout = open(mail_archive,'a') + shutil.copyfileobj(fin,fout,8192) + finally: + _archive_lock.release() + fin.close() + fout.close() + if not defanged and not spam_checked: os.remove(self.tempname) self.tempname = None # prevent re-removal diff --git a/milter.cfg b/milter.cfg index 9e75f7fe200710413907cc4f8a3520487e03c24f..306b7992b3347b4e2b3520f10dd4e7adfa193e27 100644 --- a/milter.cfg +++ b/milter.cfg @@ -38,13 +38,13 @@ case_sensitive_localpart = true [defang] # do virus scanning on attached messages also -scan_rfc822 = 1 +scan_rfc822 = 0 # do virus scanning on attached zipfiles also scan_zip = 0 # Comment out scripts in HTML attachments. Can be CPU intensive. scan_html = 0 # reject messages with asian fonts because we can't read them -block_chinese = 1 +block_chinese = 0 # list users who hate forwarded mail ;block_forward = egghead@mycorp.com, busybee@mycorp.com # reject mail with these case insensitive strings in the subject @@ -128,6 +128,8 @@ blind = 1 # discard outgoing mail without alerting sender # can be used in conjunction with wiretap to censor outgoing mail ;discard_users = canned@bigcorp.com +# archive copies all delivered mail to a file +;mail_archive = /var/log/mail_archive # # smart aliases trigger on both sender and recipient