CVS: tmda/bin ChangeLog,1.282,1.283 tmda-rfilter,1.101,1.102
Timothy Legant <[email protected]>
| Newsgroups | gmane.mail.spam.tmda.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/tmda/tmda/bin In directory sc8-pr-cvs1:/tmp/cvs-serv22566/bin Modified Files: ChangeLog tmda-rfilter Log Message: Added '-p/--print' option to tmda-rfilter to print successfully confirmed or filtered messages to stdout rather than delivering them. Modified MTA.deliver, MTA.stop, Qmail.deliver, Deliver.deliver and Deliver.get_instructions for '_filter_' delivery. This allows tmda-filter to work as a filter in maildrop and procmail. Index: ChangeLog =================================================================== RCS file: /cvsroot/tmda/tmda/bin/ChangeLog,v retrieving revision 1.282 retrieving revision 1.283 diff -u -r1.282 -r1.283 --- ChangeLog 11 Jul 2003 23:02:59 -0000 1.282 +++ ChangeLog 19 Jul 2003 04:29:26 -0000 1.283 @@ -1,3 +1,10 @@ +2003-07-18 Tim Legant <[email protected]> + + * tmda-rfilter (opt processing): Added '-p/--print' option to + print successfully confirmed or filtered messages to stdout rather + than delivering them. This allows tmda-filter to work as a filter + in maildrop and procmail. + 2003-07-11 Tim Legant <[email protected]> * tmda-inject (make_field): Added code to insert recipient into Index: tmda-rfilter =================================================================== RCS file: /cvsroot/tmda/tmda/bin/tmda-rfilter,v retrieving revision 1.101 retrieving revision 1.102 diff -u -r1.101 -r1.102 --- tmda-rfilter 11 Jul 2003 23:02:59 -0000 1.101 +++ tmda-rfilter 19 Jul 2003 04:29:26 -0000 1.102 @@ -40,6 +40,18 @@ --discard Discard message if address is invalid instead of bouncing it. + -p + --print + Print the message to stdout. This option is useful when TMDA is run + as a filter in maildrop or procmail. It overrides all other + delivery options, even if a specific delivery is given in a matching + rule. + + If the message is delivered, TMDA's exit code is 0. If the message + is dropped, bounced or a confirmation request is sent, the exit code + will be 99. You can use the exit code in maildrop/procmail to + decide if you want to perform further processing. + -t <dir> --template-dir <dir> Full pathname to a directory containing custom TMDA templates. @@ -89,6 +101,7 @@ filter_match = None discard = None +act_as_filter = 0 program = sys.argv[0] def usage(code, msg=''): @@ -121,8 +134,9 @@ try: opts, args = getopt.getopt(sys.argv[1:], - 'c:dt:I:M:S:Vh', ['config-file=', + 'c:dpt:I:M:S:Vh', ['config-file=', 'discard', + 'print', 'template-dir=', 'filter-incoming-file=', 'filter-match=', @@ -149,6 +163,8 @@ os.environ['TMDA_TEMPLATE_DIR'] = arg elif opt in ('-d', '--discard'): discard = 1 + elif opt in ('-p', '--print'): + act_as_filter = 1 elif opt in ('-c', '--config-file'): os.environ['TMDARC'] = arg elif opt in ('-S', '--vhome-script'): @@ -179,7 +195,10 @@ recip = sys.argv[-2] Util.filter_match(Defaults.FILTER_INCOMING, recip, sender) sys.exit() - + +if act_as_filter: + Defaults.DELIVERY = '_filter_' + # We use this MTA instance to control the fate of the message. mta = MTA.init(Defaults.MAIL_TRANSFER_AGENT, Defaults.DELIVERY) @@ -312,8 +331,11 @@ # Functions ########### -def logit(action_msg): +def logit(action, msg): """Write delivery statistics to the logfile if it's enabled.""" + if action in ('DELIVER', 'OK') and Defaults.DELIVERY == '_filter_': + action += ' [filtered to stdout]' + action_msg = action + ' ' + msg if Defaults.LOGFILE_INCOMING and recipient_address: from TMDA import MessageLogger logger = MessageLogger.MessageLogger(Defaults.LOGFILE_INCOMING, @@ -334,12 +356,12 @@ if envelope_sender == '<>' or \ envelope_sender == '#@[]' or \ envelope_sender.lower().startswith('mailer-daemon'): - logit ('NOREPLY (envelope sender = %s)' % envelope_sender) + logit ('NOREPLY', '(envelope sender = %s)' % envelope_sender) return 0 # Majordomo messages don't give any indication that they are # auto-responses. tsk, tsk. if envelope_sender.lower().startswith('majordomo'): - logit ('NOREPLY (Majordomo)') + logit ('NOREPLY', '(Majordomo)') return 0 # Try and detect an auto-response. guilty_header = None @@ -370,7 +392,7 @@ if precedence and precedence.lower() in ('bulk', 'junk', 'list'): guilty_header = 'Precedence: %s' % precedence if guilty_header: - logit ('NOREPLY (%s)' % guilty_header) + logit ('NOREPLY', '(%s)' % guilty_header) return 0 # Auto-response rate limiting. Algorithm based on Bruce Guenter's # qmail-autoresponder (http://untroubled.org/qmail-autoresponder/). @@ -402,8 +424,9 @@ # respond if that number it exceeds our threshold. if sndrlist.count(Util.normalize_sender(sender)) >= \ Defaults.MAX_AUTORESPONSES_PER_DAY: - logit('NOREPLY (%s = %s)' % ('MAX_AUTORESPONSES_PER_DAY', - Defaults.MAX_AUTORESPONSES_PER_DAY)) + logit('NOREPLY', + '(%s = %s)' % ('MAX_AUTORESPONSES_PER_DAY', + Defaults.MAX_AUTORESPONSES_PER_DAY)) return 0 return 1 @@ -424,26 +447,26 @@ def send_cc(address): """Send a 'carbon copy' of the message to address.""" Util.sendmail(Util.msg_as_string(msgin), address, envelope_sender) - logit('CC ' + address) + logit('CC', address) def do_default_action(action, logname, bouncetext): """Handle ACTION_* actions""" disposal_time = time.time() if action in ('bounce', 'reject'): - logit('%s %s' % ('BOUNCE', logname)) + logit('BOUNCE', logname) bouncegen('bounce', bouncetext) elif action in ('drop', 'exit', 'stop'): - logit('%s %s' % ('DROP', logname)) + logit('DROP', logname) mta.stop() elif action in ('accept', 'deliver', 'ok'): - logit('%s %s' % ('OK', logname)) + logit('OK', logname) mta.deliver(msgin) elif action == 'hold': - logit('%s %s' % ('HOLD', logname)) + logit('HOLD', logname) bouncegen('hold') else: - logit('%s %s' % ('CONFIRM', logname)) + logit('CONFIRM', logname) bouncegen('request') @@ -478,7 +501,7 @@ confirm_timestamp, confirm_pid, confirm_hmac = \ confirm_cookie.split('.') except ValueError: - logit("BOUNCE invalid_confirmation_address") + logit("BOUNCE", "invalid_confirmation_address") bouncegen('bounce', Defaults.BOUNCE_TEXT_INVALID_CONFIRMATION) confirmed_filename = '%s.%s.msg' % (confirm_timestamp, confirm_pid) confirmed_filepath = os.path.join(pendingdir, confirmed_filename) @@ -495,14 +518,14 @@ confirm_pid, confirm_action) # Accept the message only if the HMAC can be verified. if not (confirm_hmac == new_confirm_hmac): - logit("BOUNCE invalid_confirmation_address") + logit("BOUNCE", "invalid_confirmation_address") bouncegen('bounce', Defaults.BOUNCE_TEXT_INVALID_CONFIRMATION) # If the message isn't recorded as delivered and doesn't exist, # alert sender that their original is missing. if not delivery_status and not (os.path.exists(confirmed_filepath)): - logit("BOUNCE nonexistent_pending_message") + logit("BOUNCE", "nonexistent_pending_message") bouncegen('bounce', Defaults.BOUNCE_TEXT_NONEXISTENT_PENDING) - logit("CONFIRM accept " + confirmed_filename) + logit("CONFIRM", "accept " + confirmed_filename) # Optionally carbon copy the confirmation to another address. if Defaults.CONFIRM_ACCEPT_CC: send_cc(Defaults.CONFIRM_ACCEPT_CC) @@ -519,7 +542,7 @@ if Defaults.CONFIRM_APPEND: if Util.append_to_file(confirm_append_addr, Defaults.CONFIRM_APPEND) != 0: - logit('CONFIRM_APPEND ' + Defaults.CONFIRM_APPEND) + logit('CONFIRM_APPEND', Defaults.CONFIRM_APPEND) if Defaults.DB_CONFIRM_APPEND and Defaults.DB_CONNECTION: _username = Defaults.USERNAME.lower() _hostname = Defaults.HOSTNAME.lower() @@ -530,7 +553,7 @@ Util.db_insert(Defaults.DB_CONNECTION, Defaults.DB_CONFIRM_APPEND, params) - logit('DB_CONFIRM_APPEND ') + logit('DB_CONFIRM_APPEND', '') # Optionally generate a confirmation acceptance notice. if Defaults.CONFIRM_ACCEPT_NOTIFY: if (delivery_status == 'c' and @@ -561,7 +584,7 @@ confirm_pid, 'done') # Accept the message only if the HMAC can be verified. if not (confirm_hmac == new_confirm_hmac): - logit("CONFIRM bad_confirm_done_cookie") + logit("CONFIRM", "bad_confirm_done_cookie") # Ask for confirmation instead of bouncing or dropping the # message in case the sender inadvertently had an # X-TMDA-Confirm-Done field in this message, such as when @@ -575,7 +598,7 @@ status_flag = ':3,R' if os.path.exists(confirmed_filepath): os.rename(confirmed_filepath, confirmed_filepath + status_flag) - logit("OK good_confirm_done_cookie") + logit("OK", "good_confirm_done_cookie") # Remove X-TMDA-Confirm-Done: since it's only used # internally. This won't work when delivering '_qok_', # since another program (qmail-local) is doing the actual @@ -601,7 +624,7 @@ Defaults.BOUNCE_TEXT_FAIL_DATED) else: if int(cookie_date) >= int('%d' % time.time()): - logit("OK good_dated_cookie (%s)" % \ + logit("OK", "good_dated_cookie (%s)" % \ Util.unixdate(int(cookie_date))) mta.deliver(msgin) else: @@ -616,7 +639,7 @@ sender_address_cookie = Cookie.make_sender_cookie(sender_address) # Accept the message only if the HMAC can be verified. if (sender_cookie == sender_address_cookie): - logit("OK good_sender_cookie") + logit("OK", "good_sender_cookie") mta.deliver(msgin) else: defact = Defaults.ACTION_FAIL_SENDER.lower() @@ -632,7 +655,7 @@ newmac = Cookie.make_keywordmac(keyword) # Accept the message only if the HMAC can be verified. if mac == newmac: - logit("OK good_keyword_cookie \"" + keyword + "\"") + logit("OK", "good_keyword_cookie \"" + keyword + "\"") mta.deliver(msgin) else: defact = Defaults.ACTION_FAIL_KEYWORD.lower() @@ -729,7 +752,7 @@ # Don't send anything for silently held messages if Defaults.CONFIRM_CC: send_cc(Defaults.CONFIRM_CC) - logit("HOLD pending " + pending_message) + logit("HOLD", "pending " + pending_message) mta.stop() # Create the confirm message and then send it. bounce_message = Util.maketext(templatefile, vars()) @@ -741,7 +764,7 @@ elif mode == 'request': if Defaults.CONFIRM_CC: send_cc(Defaults.CONFIRM_CC) - logit("CONFIRM pending " + pending_message) + logit("CONFIRM", "pending " + pending_message) send_bounce(bounce_message, mode) mta.stop() @@ -808,29 +831,29 @@ if Defaults.FILTER_BOUNCE_CC: send_cc(Defaults.FILTER_BOUNCE_CC) if option: - logit('%s (%s)' % ('BOUNCE', matching_line + '=' + option)) + logit('BOUNCE', '(%s)' % matching_line + '=' + option) bouncegen('bounce', Defaults.BOUNCE_TEXT_FILTER_INCOMING, template=option) else: - logit('%s (%s)' % ('BOUNCE', matching_line)) + logit('BOUNCE', '(%s)' % matching_line) bouncegen('bounce', Defaults.BOUNCE_TEXT_FILTER_INCOMING) elif action in ('drop','exit','stop'): if Defaults.FILTER_DROP_CC: send_cc(Defaults.FILTER_DROP_CC) - logit('%s (%s)' % ('DROP', matching_line)) + logit('DROP', '(%s)' % matching_line) mta.stop() elif action in ('accept','deliver','ok'): if option: - logit('%s (%s)' % ('DELIVER', matching_line + '=' + option)) + logit('DELIVER', '(%s)' % matching_line + '=' + option) mta.deliver(msgin, option) else: - logit('%s (%s)' % ('OK', matching_line)) + logit('OK', '(%s)' % matching_line) mta.deliver(msgin) elif action == 'confirm': - logit('%s (%s)' % ('CONFIRM', matching_line)) + logit('CONFIRM', '(%s)' % matching_line) bouncegen('request') elif action == 'hold': - logit('%s (%s)' % ('HOLD', matching_line)) + logit('HOLD', '(%s)' % matching_line) bouncegen('hold') # The message didn't match the filter file, so check if it was # sent to a 'tagged' address. _______________________________________ tmda-cvs mailing list http://tmda.net/lists/listinfo/tmda-cvs