|
Lines 1-4
Link Here
|
| 1 |
# Copyright (C) 1998-2005 by the Free Software Foundation, Inc. |
1 |
# Copyright (C) 1998-2006 by the Free Software Foundation, Inc. |
| 2 |
# |
2 |
# |
| 3 |
# This program is free software; you can redistribute it and/or |
3 |
# This program is free software; you can redistribute it and/or |
| 4 |
# modify it under the terms of the GNU General Public License |
4 |
# modify it under the terms of the GNU General Public License |
|
Lines 92-99
Link Here
|
| 92 |
|
92 |
|
| 93 |
|
93 |
|
| 94 |
def process(mlist, msg, msgdata): |
94 |
def process(mlist, msg, msgdata): |
| 95 |
if msgdata.get('approved') or msgdata.get('reduced_list_headers'): |
95 |
if msgdata.get('approved'): |
| 96 |
# TK: 'reduced_list_headers' is intenally crafted message (virgin). |
|
|
| 97 |
return |
96 |
return |
| 98 |
# First do site hard coded header spam checks |
97 |
# First do site hard coded header spam checks |
| 99 |
for header, regex in mm_cfg.KNOWN_SPAMMERS: |
98 |
for header, regex in mm_cfg.KNOWN_SPAMMERS: |
|
Lines 103-122
Link Here
|
| 103 |
if mo: |
102 |
if mo: |
| 104 |
# we've detected spam, so throw the message away |
103 |
# we've detected spam, so throw the message away |
| 105 |
raise SpamDetected |
104 |
raise SpamDetected |
|
|
105 |
# Before we go to header_filter_rules, we exclude internally generated |
| 106 |
# owner notification from checking, because 1) we collect headers from |
| 107 |
# all the attachments but this will cause matching the filter rule again, |
| 108 |
# and 2) list owners may want to check header name / value pair like |
| 109 |
# 'Precedence: bulk' which is also generated by mailman. Both will |
| 110 |
# cause loop of holding owner notification messages if the action is |
| 111 |
# set to 'hold'. |
| 112 |
if msgdata.get('toowner') and msg.get('x-list-administrivia') == 'yes': |
| 113 |
return |
| 106 |
# Now do header_filter_rules |
114 |
# Now do header_filter_rules |
| 107 |
# TK: Collect headers in sub-parts because attachment filename |
115 |
# TK: Collect headers in sub-parts because attachment filename |
| 108 |
# extension may be a clue to possible virus/spam. |
116 |
# extension may be a clue to possible virus/spam. |
| 109 |
if msg.is_multipart(): |
117 |
headers = '' |
| 110 |
headers = '' |
118 |
for p in msg.walk(): |
| 111 |
for p in msg.walk(): |
|
|
| 112 |
g = HeaderGenerator(StringIO()) |
| 113 |
g.flatten(p) |
| 114 |
headers += g.header_text() |
| 115 |
else: |
| 116 |
# Only the top level header should be checked. |
| 117 |
g = HeaderGenerator(StringIO()) |
119 |
g = HeaderGenerator(StringIO()) |
| 118 |
g.flatten(msg) |
120 |
g.flatten(p) |
| 119 |
headers = g.header_text() |
121 |
headers += g.header_text() |
| 120 |
# Now reshape headers (remove extra CR and connect multiline). |
122 |
# Now reshape headers (remove extra CR and connect multiline). |
| 121 |
headers = re.sub('\n+', '\n', headers) |
123 |
headers = re.sub('\n+', '\n', headers) |
| 122 |
headers = re.sub('\n\s', ' ', headers) |
124 |
headers = re.sub('\n\s', ' ', headers) |