diff options
author | Anton Yuzhaninov <citrin+git@citrin.ru> | 2020-08-08 13:12:15 +0100 |
---|---|---|
committer | Anton Yuzhaninov <citrin+git@citrin.ru> | 2020-08-08 13:26:24 +0100 |
commit | 8c34ee461c6cf0deaa8be67281bd88bbf2b2697c (patch) | |
tree | 2b8b98c33310e2ccc510cf8c06ce5be116baedb5 /src/plugins/lua/maillist.lua | |
parent | 2a7b9b37d54a6d52d12e459237513c66ce853019 (diff) | |
download | rspamd-8c34ee461c6cf0deaa8be67281bd88bbf2b2697c.tar.gz rspamd-8c34ee461c6cf0deaa8be67281bd88bbf2b2697c.zip |
[Minor] Improve mailman mailing list detection
Diffstat (limited to 'src/plugins/lua/maillist.lua')
-rw-r--r-- | src/plugins/lua/maillist.lua | 88 |
1 files changed, 45 insertions, 43 deletions
diff --git a/src/plugins/lua/maillist.lua b/src/plugins/lua/maillist.lua index 79c457662..d623abf16 100644 --- a/src/plugins/lua/maillist.lua +++ b/src/plugins/lua/maillist.lua @@ -63,62 +63,64 @@ local function check_ml_ezmlm(task) return true end --- MailMan (the gnu mailing list manager) --- Precedence: bulk [or list for v2] --- List-Help: <mailto: --- List-Post: <mailto: --- List-Subscribe: .*<mailto:.*=subscribe> --- List-Unsubscribe: .*<mailto:.*=unsubscribe> --- List-Archive: --- X-Mailman-Version: \d --- RFC 2919 headers exist +-- GNU Mailman +-- Two major versions currently in use and they use slightly different headers +-- Mailman2: https://code.launchpad.net/~mailman-coders/mailman/2.1 +-- Mailman3: https://gitlab.com/mailman/mailman local function check_ml_mailman(task) - -- Mailing-List - local header = task:get_header('x-mailman-version') - if not header or not string.find(header, '^%d') then + local header = task:get_header('X-Mailman-Version') + if not header then return false end - -- Precedence - header = task:get_header('precedence') - if not header or (header ~= 'bulk' and header ~= 'list') then + local mm_version = header:match('^([23])%.') + if not mm_version then + lua_util.debugm(N, task, 'unknown Mailman version: %s', header) return false end - -- For reminders we have other headers than for normal messages - header = task:get_header('x-list-administrivia') - local subject = task:get_header('subject') - if (header and string.find(header, 'yes')) or - (subject and string.find(subject, 'mailing list memberships reminder$')) then - if not task:get_header('errors-to') or not task:get_header('x-beenthere') then - return false - end - header = task:get_header('x-no-archive') - if not header or not string.find(header, 'yes') then - return false - end - return true - end + lua_util.debugm(N, task, 'checking Mailman %s headers', mm_version) - -- Other headers - header = task:get_header('list-post') - if not header or not string.find(header, '^<mailto:') then + -- XXX Some messages may not contain Precedence, but they are rare: + -- http://bazaar.launchpad.net/~mailman-coders/mailman/2.1/revision/1339 + header = task:get_header('Precedence') + if not header or (header ~= 'bulk' and header ~= 'list') then return false end - header = task:get_header('list-help') - if not header or not string.find(header, '^<mailto:') then + + -- Mailmain 3 allows to disable all List-* headers in settings, but by default it adds them. + -- In all other cases all Mailman message should have List-Id header + if not task:has_header('List-Id') then return false end - -- Subscribe and unsubscribe - header = task:get_header('list-subscribe') - if not header or not string.find(header, '<mailto:.*=subscribe>') then - return false + + if mm_version == '2' then + -- X-BeenThere present in all Mailman2 messages + if not task:has_header('X-BeenThere') then + return false + end + -- X-List-Administrivia: is only added to messages Mailman creates and + -- sends out of its own accord + header = task:get_header('X-List-Administrivia') + if header and header == 'yes' then + -- not much elase we can check, Subjects can be changed in settings + return true + end + else -- Mailman 3 + -- XXX not Mailman3 admin messages have this headers, but one + -- which don't usually have List-* headers examined below + if task:has_header('List-Administrivia') then + return true + end end - header = task:get_header('list-unsubscribe') - if not header or not string.find(header, '<mailto:.*=unsubscribe>') then - return false + + -- List-Archive and List-Post are optional, check other headers + for _, h in ipairs({'List-Help', 'List-Subscribe', 'List-Unsubscribe'}) do + header = task:get_header(h) + if not (header and header:find('<mailto:', 1, true)) then + return false + end end return true - end -- Subscribe.ru @@ -264,7 +266,7 @@ end -- RFC 2919 headers exist local function check_maillist(task) local score = check_generic_list_headers(task) - if score > 1 then + if score >= 1 then if check_ml_ezmlm(task) then task:insert_result(symbol, 1, 'ezmlm') elseif check_ml_mailman(task) then |