]> source.dussan.org Git - rspamd.git/commitdiff
* Add maillist plugin for detecting mailmain/ezml and subscribe.ru lists
authorcebka@lenovo-laptop <cebka@lenovo-laptop>
Mon, 1 Feb 2010 17:01:20 +0000 (20:01 +0300)
committercebka@lenovo-laptop <cebka@lenovo-laptop>
Mon, 1 Feb 2010 17:01:20 +0000 (20:01 +0300)
src/main.c
src/plugins/lua/maillist.lua [new file with mode: 0644]

index ee0a1ae56134734c0017cf63659d3b0fb0c21169..49ac3da861d12318d158efacff9d4be756eac9ea 100644 (file)
@@ -610,6 +610,7 @@ main (int argc, char **argv, char **env)
 
        /* First set logger to console logger */
        rspamd_set_logger (RSPAMD_LOG_CONSOLE, rspamd->cfg);
+       (void)open_log ();
        g_log_set_default_handler (rspamd_glib_log_function, cfg);
 
 #ifndef HAVE_SETPROCTITLE
diff --git a/src/plugins/lua/maillist.lua b/src/plugins/lua/maillist.lua
new file mode 100644 (file)
index 0000000..18514aa
--- /dev/null
@@ -0,0 +1,179 @@
+-- Module for checking mail list headers
+
+
+local metric = 'default'
+local symbol = 'MAILLIST'
+
+-- EZMLM
+-- Mailing-List: .*run by ezmlm
+-- Precedence: bulk
+-- List-Post: <mailto:
+-- List-Help: <mailto:
+-- List-Unsubscribe: <mailto:[a-zA-Z\.-]+-unsubscribe@
+-- List-Subscribe: <mailto:[a-zA-Z\.-]+-subscribe@
+function check_ml_ezmlm(task)
+       local message = task:get_message()
+       -- Mailing-List
+       local header = message:get_header('mailing-list')
+       if not header or not string.find(header[1], 'ezmlm$') then
+               return false
+       end
+       -- Precedence
+       header = message:get_header('precedence')
+       if not header or not string.match(header[1], '^bulk$') then
+               return false
+       end
+       -- Other headers
+       header = message:get_header('list-post')
+       if not header or not string.find(header[1], '^<mailto:') then
+               return false
+       end
+       header = message:get_header('list-help')
+       if not header or not string.find(header[1], '^<mailto:') then
+               return false
+       end
+       -- Subscribe and unsubscribe
+       header = message:get_header('list-subscribe')
+       if not header or not string.find(header[1], '<mailto:[a-zA-Z.-]+-subscribe@') then
+               return false
+       end
+       header = message:get_header('list-unsubscribe')
+       if not header or not string.find(header[1], '<mailto:[a-zA-Z.-]+-unsubscribe@') then
+               return false
+       end
+
+       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-Id: 
+-- List-Unsubscribe: .*<mailto:.*=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], '^<mailto:') then
+               return false
+       end
+       header = message:get_header('list-help')
+       if not header or not string.find(header[1], '^<mailto:') then
+               return false
+       end
+       -- Subscribe and unsubscribe
+       header = message:get_header('list-subscribe')
+       if not header or not string.find(header[1], '<mailto:.*=subscribe>') then
+               return false
+       end
+       header = message:get_header('list-unsubscribe')
+       if not header or not string.find(header[1], '<mailto:.*=unsubscribe>') then
+               return false
+       end
+
+       return true
+
+end
+
+-- Subscribe.ru
+-- Precedence: normal
+-- List-Id: <.*.subscribe.ru>
+-- List-Help: <http://subscribe.ru/catalog/.*>
+-- List-Subscribe: <mailto:.*-sub@subscribe.ru>
+-- List-Unsubscribe: <mailto:.*-unsub@subscribe.ru>
+-- List-Archive:  <http://subscribe.ru/archive/.*>
+-- List-Owner: <mailto:.*-owner@subscribe.ru>
+-- 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], '^<http://subscribe.ru/archive/.*>$') then
+               return false
+       end
+       header = message:get_header('list-owner')
+       if not header or not string.find(header[1], '^<mailto:.*-owner@subscribe.ru>$') then
+               return false
+       end
+       header = message:get_header('list-help')
+       if not header or not string.find(header[1], '^<http://subscribe.ru/catalog/.*>$') then
+               return false
+       end
+       -- Subscribe and unsubscribe
+       header = message:get_header('list-subscribe')
+       if not header or not string.find(header[1], '^<mailto:.*-sub@subscribe.ru>$') then
+               return false
+       end
+       header = message:get_header('list-unsubscribe')
+       if not header or not string.find(header[1], '^<mailto:.*-unsub@subscribe.ru>$') 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