diff options
| author | Barry Warsaw | 2007-12-29 21:02:15 -0500 |
|---|---|---|
| committer | Barry Warsaw | 2007-12-29 21:02:15 -0500 |
| commit | 66ffab7c0d56b8144a80045fac3a7dab036a597f (patch) | |
| tree | 288a2d291a2c3ea97c3de4a8f6c49ec9d2ef77f0 /Mailman/rules/suspicious.py | |
| parent | df10700b94c1c785337274c1a259f722231f580a (diff) | |
| download | mailman-66ffab7c0d56b8144a80045fac3a7dab036a597f.tar.gz mailman-66ffab7c0d56b8144a80045fac3a7dab036a597f.tar.zst mailman-66ffab7c0d56b8144a80045fac3a7dab036a597f.zip | |
Diffstat (limited to 'Mailman/rules/suspicious.py')
| -rw-r--r-- | Mailman/rules/suspicious.py | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/Mailman/rules/suspicious.py b/Mailman/rules/suspicious.py new file mode 100644 index 000000000..6384f8b9e --- /dev/null +++ b/Mailman/rules/suspicious.py @@ -0,0 +1,96 @@ +# Copyright (C) 2007 by the Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. + +"""The historical 'suspicious header' rule.""" + +__all__ = ['suspicious_header'] +__metaclass__ = type + + +import re +from email.utils import getaddresses +from zope.interface import implements + +from Mailman.i18n import _ +from Mailman.interfaces import IRule + + + +class SuspiciousHeader: + """The historical 'suspicious header' rule.""" + implements(IRule) + + name = 'suspicious-header' + description = _('Catch messages with suspicious headers.') + + def check(self, mlist, msg, msgdata): + """See `IRule`.""" + return (mlist.bounce_matching_headers and + has_matching_bounce_header(mlist, msg)) + + + +def _parse_matching_header_opt(mlist): + """Return a list of triples [(field name, regex, line), ...].""" + # - Blank lines and lines with '#' as first char are skipped. + # - Leading whitespace in the matchexp is trimmed - you can defeat + # that by, eg, containing it in gratuitous square brackets. + all = [] + for line in mlist.bounce_matching_headers.splitlines(): + line = line.strip() + # Skip blank lines and lines *starting* with a '#'. + if not line or line.startswith('#'): + continue + i = line.find(':') + if i < 0: + # This didn't look like a header line. BAW: should do a + # better job of informing the list admin. + log.error('bad bounce_matching_header line: %s\n%s', + mlist.real_name, line) + else: + header = line[:i] + value = line[i+1:].lstrip() + try: + cre = re.compile(value, re.IGNORECASE) + except re.error, e: + # The regexp was malformed. BAW: should do a better + # job of informing the list admin. + log.error("""\ +bad regexp in bounce_matching_header line: %s +\n%s (cause: %s)""", mlist.real_name, value, e) + else: + all.append((header, cre, line)) + return all + + +def has_matching_bounce_header(mlist, msg): + """Does the message have a matching bounce header? + + :param mlist: The mailing list the message is destined for. + :param msg: The email message object. + :return: True if a header field matches a regexp in the + bounce_matching_header mailing list variable. + """ + for header, cre, line in _parse_matching_header_opt(mlist): + for value in msg.get_all(header, []): + if cre.search(value): + return True + return False + + + +suspicious_header = SuspiciousHeader() |
