-- Module for checking mail list headers local metric = 'default' local symbol = 'MAILLIST' -- EZMLM -- Mailing-List: .*run by ezmlm -- Precedence: bulk -- List-Post: -- List-Id: -- List-Unsubscribe: .* -- List-Archive: -- X-Mailman-Version: \d function check_ml_mailman(task) local message = task:get_message() -- Mailing-List local header = message:get_header('x-mailman-version') if not header or not string.find(header[1], '^%d') then return false end -- Precedence header = message:get_header('precedence') if not header or (not string.match(header[1], '^bulk$') and not string.match(header[1], '^list$')) then return false end -- For reminders we have other headers than for normal messages header = message:get_header('x-list-administrivia') local subject = message:get_header('subject') if (header and string.find(header[1], 'yes')) or (subject and string.find(subject[1], 'mailing list memberships reminder$')) then if not message:get_header('errors-to') or not message:get_header('x-beenthere') then return false end header = message:get_header('x-no-archive') if not header or not string.find(header[1], 'yes') then return false end return true end -- Other headers header = message:get_header('list-id') if not header then return false end header = message:get_header('list-post') if not header or not string.find(header[1], '^') then return false end header = message:get_header('list-unsubscribe') if not header or not string.find(header[1], '') then return false end return true end -- Subscribe.ru -- Precedence: normal -- List-Id: <.*.subscribe.ru> -- List-Help: -- List-Subscribe: -- List-Unsubscribe: -- List-Archive: -- List-Owner: -- List-Post: NO function check_ml_subscriberu(task) local message = task:get_message() -- List-Id local header = message:get_header('list-id') if not header or not string.find(header[1], '^<.*%.subscribe%.ru>$') then return false end -- Precedence header = message:get_header('precedence') if not header or not string.match(header[1], '^normal$') then return false end -- Other headers header = message:get_header('list-archive') if not header or not string.find(header[1], '^$') then return false end header = message:get_header('list-owner') if not header or not string.find(header[1], '^$') then return false end header = message:get_header('list-help') if not header or not string.find(header[1], '^$') then return false end -- Subscribe and unsubscribe header = message:get_header('list-subscribe') if not header or not string.find(header[1], '^$') then return false end header = message:get_header('list-unsubscribe') if not header or not string.find(header[1], '^$') then return false end return true end function check_maillist(task) if check_ml_ezmlm(task) then task:insert_result(metric, symbol, 1, 'ezmlm') elseif check_ml_mailman(task) then task:insert_result(metric, symbol, 1, 'mailman') elseif check_ml_subscriberu(task) then task:insert_result(metric, symbol, 1, 'subscribe.ru') end end -- Configuration local opts = rspamd_config:get_all_opt('maillist') if opts then if opts['symbol'] then if opts['metric'] then metric = opts['metric'] end symbol = opts['symbol'] local m = rspamd_config:get_metric(metric) m:register_symbol(symbol, 1.0, 'check_maillist') end end