diff options
| author | bwarsaw | 1999-12-09 22:27:39 +0000 |
|---|---|---|
| committer | bwarsaw | 1999-12-09 22:27:39 +0000 |
| commit | 13196dc0a2f3d069fb3eab67ab67936f8b5637ee (patch) | |
| tree | 6f84fb6182172ac4f2129afa1eea1459012595d3 /Mailman/Bouncer.py | |
| parent | dacfd207e653607e8d1e9e0ec0d4811913445bfa (diff) | |
| download | mailman-13196dc0a2f3d069fb3eab67ab67936f8b5637ee.tar.gz mailman-13196dc0a2f3d069fb3eab67ab67936f8b5637ee.tar.zst mailman-13196dc0a2f3d069fb3eab67ab67936f8b5637ee.zip | |
Rip out all the actual bounce detection code (moved to
Bouncers/Catchall.py) in the port to the new bounce detection
architecture.
Diffstat (limited to 'Mailman/Bouncer.py')
| -rw-r--r-- | Mailman/Bouncer.py | 160 |
1 files changed, 5 insertions, 155 deletions
diff --git a/Mailman/Bouncer.py b/Mailman/Bouncer.py index 19d193fb3..13bb39fcf 100644 --- a/Mailman/Bouncer.py +++ b/Mailman/Bouncer.py @@ -24,11 +24,11 @@ import sys import time -import regsub, string, regex, re -import Utils -import mm_cfg -import Errors +import string +from Mailman import mm_cfg +from Mailman import Errors +from Mailman import Utils from Mailman import Message from Mailman.Handlers import HandlerAPI @@ -78,6 +78,7 @@ class Bouncer: "Remove and notify me"), 0, "Action when critical or excessive bounces are detected.") ] + def ClearBounceInfo(self, email): email = string.lower(email) if self.bounce_info.has_key(email): @@ -306,154 +307,3 @@ class Bouncer: self.ClearBounceInfo(addr) self.Save() return Errors.MMNoSuchUserError, 1 - - # Return 0 if we couldn't make any sense of it, 1 if we handled it. - def ScanMessage(self, msg): -## realname, who_from = msg.getaddr('from') -## who_info = string.lower(who_from) - candidates = [] - who_info = string.lower(msg.GetSender()) - at_index = string.find(who_info, '@') - if at_index != -1: - who_from = who_info[:at_index] - remote_host = who_info[at_index+1:] - else: - who_from = who_info - remote_host = self.host_name - if not who_from in ['mailer-daemon', 'postmaster', 'orphanage', - 'postoffice', 'ucx_smtp', 'a2']: - return 0 - mime_info = msg.getheader('content-type') - boundry = None - if mime_info: - mime_info_parts = regsub.splitx( - mime_info, '[Bb][Oo][Uu][Nn][Dd][Aa][Rr][Yy]="[^"]+"') - if len(mime_info_parts) > 1: - boundry = regsub.splitx(mime_info_parts[1], - '"[^"]+"')[1][1:-1] - - if boundry: - relevant_text = string.split(msg.body, '--%s' % boundry) - # Invalid MIME messages shouldn't cause exceptions - if len(relevant_text) >= 2: - relevant_text = relevant_text[1] - else: - relevant_text = relevant_text[0] - else: - # This looks strange, but at least 2 are going to be no-ops. - relevant_text = regsub.split(msg.body, - '^.*Message header follows.*$')[0] - relevant_text = regsub.split(relevant_text, - '^The text you sent follows:.*$')[0] - relevant_text = regsub.split( - relevant_text, '^Additional Message Information:.*$')[0] - relevant_text = regsub.split(relevant_text, - '^-+Your original message-+.*$')[0] - - BOUNCE = 1 - REMOVE = 2 - - # Bounce patterns where it's simple to figure out the email addr. - email_regexp = '<?\([^ \t@|<>]+@[^ \t@<>]+\.[^ \t<>.]+\)>?' - simple_bounce_pats = ( - (regex.compile('.*451 %s.*' % email_regexp), BOUNCE), - (regex.compile('.*554 %s.*' % email_regexp), BOUNCE), - (regex.compile('.*552 %s.*' % email_regexp), BOUNCE), - (regex.compile('.*501 %s.*' % email_regexp), BOUNCE), - (regex.compile('.*553 %s.*' % email_regexp), BOUNCE), - (regex.compile('.*550 %s.*' % email_regexp), BOUNCE), - (regex.compile('%s .bounced.*' % email_regexp), BOUNCE), - (regex.compile('.*%s\.\.\. Deferred.*' % email_regexp), BOUNCE), - (regex.compile('.*User %s not known.*' % email_regexp), REMOVE), - (regex.compile('.*%s: User unknown.*' % email_regexp), REMOVE), - (regex.compile('.*%s\.\.\. User unknown' % email_regexp), REMOVE)) - # patterns we can't directly extract the email (special case these) - messy_pattern_1 = regex.compile('^Recipient .*$') - messy_pattern_2 = regex.compile('^Addressee: .*$') - messy_pattern_3 = regex.compile('^User .* not listed.*$') - messy_pattern_4 = regex.compile('^550 [^ ]+\.\.\. User unknown.*$') - messy_pattern_5 = regex.compile('^User [^ ]+ is not defined.*$') - messy_pattern_6 = regex.compile('^[ \t]*[^ ]+: User unknown.*$') - messy_pattern_7 = regex.compile('^[^ ]+ - User currently disabled.*$') - - # Patterns for cases where email addr is separate from error cue. - separate_cue_1 = re.compile( - '^554 [^ ]+\.\.\. unknown mailer error.*$', re.I) - separate_addr_1 = regex.compile('expanded from: %s' % email_regexp) - - message_grokked = 0 - use_prospects = 0 - prospects = [] # If bad but no candidates found. - - for line in string.split(relevant_text, '\n'): - for pattern, action in simple_bounce_pats: - if pattern.match(line) <> -1: - email = self.ExtractBouncingAddr(line) - candidates.append((string.split(email,',')[0], action)) - message_grokked = 1 - - # Now for the special case messages that are harder to parse... - if (messy_pattern_1.match(line) <> -1 - or messy_pattern_2.match(line) <> -1): - username = string.split(line)[1] - candidates.append(('%s@%s' % (username, remote_host), - BOUNCE)) - message_grokked = 1 - continue - if (messy_pattern_3.match(line) <> -1 - or messy_pattern_4.match(line) <> -1 - or messy_pattern_5.match(line) <> -1): - username = string.split(line)[1] - candidates.append(('%s@%s' % (username, remote_host), - REMOVE)) - message_grokked = 1 - continue - if messy_pattern_6.match(line) <> -1: - username = string.split(string.strip(line))[0][:-1] - candidates.append(('%s@%s' % (username, remote_host), - REMOVE)) - message_grokked = 1 - continue - if messy_pattern_7.match(line) <> -1: - username = string.split(string.strip(line))[0] - candidates.append(('%s@%s' % (username, remote_host), - REMOVE)) - message_grokked = 1 - continue - - if separate_cue_1.match(line): - # Here's an error message that doesn't contain the addr. - # Set a flag to use prospects found on separate lines. - use_prospects = 1 - if separate_addr_1.search(line) != -1: - # Found an addr that *might* be part of an error message. - # Register it on prospects, where it will only be used if a - # separate check identifies this message as an error message. - prospects.append((separate_addr_1.group(1), BOUNCE)) - - if use_prospects and prospects: - candidates = candidates + prospects - - did = [] - for who, action in candidates: - # First clean up some cruft around the addrs. - el = string.find(who, "...") - if el != -1: - who = who[:el] - if len(who) > 1 and who[0] == '<': - # Use stuff after open angle and before (optional) close: - who = regsub.splitx(who[1:], ">")[0] - if who not in did: - if action == REMOVE: - self.HandleBouncingAddress(who, msg) - else: - self.RegisterBounce(who, msg) - did.append(who) - return message_grokked - - def ExtractBouncingAddr(self, line): - email = regsub.splitx(line, '[^ \t@<>]+@[^ \t@<>]+\.[^ \t<>.]+')[1] - if email[0] == '<': - return regsub.splitx(email[1:], ">")[0] - else: - return email |
