diff --git a/src/licence.hrl b/src/licence.hrl new file mode 100644 index 000000000..a82dab15e --- /dev/null +++ b/src/licence.hrl @@ -0,0 +1 @@ +-define(IS_VALID, true). diff --git a/src/mod_admin_p1.erl b/src/mod_admin_p1.erl index bcfc8232c..18e391027 100644 --- a/src/mod_admin_p1.erl +++ b/src/mod_admin_p1.erl @@ -5,7 +5,7 @@ %%% Created : 21 May 2008 by Badlop %%% %%% -%%% ejabberd, Copyright (C) 2002-2008 ProcessOne +%%% ejabberd, Copyright (C) 2002-2010 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_antiflood.erl b/src/mod_antiflood.erl index a80d93636..aca0737eb 100644 --- a/src/mod_antiflood.erl +++ b/src/mod_antiflood.erl @@ -4,7 +4,7 @@ %%% Description : %%% Created : 12 Sep 2008 by Christophe Romain %%% -%%% ejabberd, Copyright (C) 2002-2009 ProcessOne +%%% ejabberd, Copyright (C) 2002-2010 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_autofilter.erl b/src/mod_autofilter.erl new file mode 100644 index 000000000..97b374b6b --- /dev/null +++ b/src/mod_autofilter.erl @@ -0,0 +1,127 @@ +%%% ==================================================================== +%%% This software is copyright 2006-2010, ProcessOne. +%%% +%%% mod_autofilter +%%% +%%% @copyright 2006-2010 ProcessOne +%%% @author Christophe Romain +%%% [http://www.process-one.net/] +%%% @version {@vsn}, {@date} {@time} +%%% @end +%%% ==================================================================== + + +-module(mod_autofilter). +-author('christophe.romain@process-one.net'). + +-behaviour(gen_mod). + +% module functions +-export([start/2,stop/1,is_loaded/0]). +-export([offline_message/3,filter_packet/1,close_session/2,close_session/3]). +-export([deny/2,allow/2,denied/0,listed/0,purge/1]). + +-include("ejabberd.hrl"). +-include("jlib.hrl"). +-include("licence.hrl"). + +-record(autofilter, {key, timestamp=0, count=1, drop=false, reason}). + +start(Host, Opts) -> + case ?IS_VALID of + true -> + mnesia:create_table(autofilter, [ + {disc_copies, [node()]}, {type, set}, + {attributes, record_info(fields, autofilter)} ]), + ejabberd_hooks:add(offline_message_hook, Host, ?MODULE, offline_message, 10), + ejabberd_hooks:add(filter_packet, ?MODULE, filter_packet, 10), + ejabberd_hooks:add(sm_remove_connection_hook, Host, ?MODULE, close_session, 10), + case gen_mod:get_opt(purge_freq, Opts, 0) of %% purge_freq in minutes + 0 -> + no_purge; + Freq -> + Keep = gen_mod:get_opt(keep, Opts, 10), %% keep in minutes + timer:apply_interval(Freq*60000, ?MODULE, purge, [Keep*60]) + end, + start; + false -> + not_started + end. + +stop(Host) -> + ejabberd_hooks:delete(offline_message_hook, Host, ?MODULE, offline_message, 10), + ejabberd_hooks:delete(filter_packet, ?MODULE, filter_packet, 10), + ejabberd_hooks:delete(sm_remove_connection_hook, Host, ?MODULE, close_session, 10), + stop. + +is_loaded() -> + ok. + +purge(Keep) -> + ?INFO_MSG("autofilter purge",[]), + {T1, T2, _} = now(), + Older = T1*1000000+T2-Keep, + lists:foreach(fun(Key) -> + mnesia:dirty_delete({autofilter, Key}) + end, mnesia:dirty_select(autofilter, [{#autofilter{key = '$1', drop = false, timestamp = '$2', _ = '_'}, [{'<', '$2', Older}], ['$1']}])), + ok. + +deny(User, Server) -> + Key = {User, Server}, + Record = case mnesia:dirty_read({autofilter, Key}) of + [R] -> R; + _ -> #autofilter{key=Key} + end, + ?INFO_MSG("autofilter: messages from ~s@~s will be droped~n", [User, Server]), + mnesia:dirty_write(Record#autofilter{drop=true}). + +allow(User, Server) -> + Key = {User, Server}, + ?INFO_MSG("autofilter: messages from ~s@~s are accepted~n", [User, Server]), + mnesia:dirty_delete({autofilter, Key}). + +denied() -> + mnesia:dirty_select(autofilter, [{#autofilter{key = '$1', drop = true, reason = '$2', _ = '_'}, [], [['$1','$2']]}]). +listed() -> + mnesia:dirty_select(autofilter, [{#autofilter{key = '$1', drop = false, reason = '$2', _ = '_'}, [], [['$1','$2']]}]). + +offline_message({jid, [], _, [], [], _, []}, _To, _Packet) -> + ok; +offline_message(From, To, Packet) -> + {User, Server, _} = jlib:jid_tolower(From), + Key = {User, Server}, + {T1, T2, _} = now(), + T = T1*1000000+T2, + Record = case mnesia:dirty_read({autofilter, Key}) of + [#autofilter{timestamp=O, count=C}=R] -> + D = T-O, + if + D > 3600 -> % this is usefull only of purge_freq is not set + R#autofilter{timestamp=T, count=1}; + ((C/D) > 1/10) and (C > 90) -> + ?INFO_MSG("autofilter: messages from ~s@~s will be droped~n", [User, Server]), + R#autofilter{drop=true, reason=offline_flood}; + true -> + R#autofilter{count=C+1} + end; + _ -> + #autofilter{key=Key, timestamp=T, count=1, drop=false, reason=offline_flood} + end, + mnesia:dirty_write(Record), + ok. + +filter_packet({From, To, Packet}) -> + {User, Server, _} = jlib:jid_tolower(From), + case mnesia:dirty_read({autofilter, {User, Server}}) of + [#autofilter{drop=true}] -> drop; + _ -> {From, To, Packet} + end. + +close_session(SID, JID) -> + close_session(SID, JID, []). +close_session(_SID, {jid, _, _, _, User, Server, _}, _Info) -> + % this allows user, except for blocked ones + lists:foreach(fun(#autofilter{key=Key}) -> + mnesia:dirty_delete({autofilter, Key}) + end, mnesia:dirty_match_object(#autofilter{key={User, Server}, drop = false, _ = '_'})), + ok. diff --git a/src/mod_filter.erl b/src/mod_filter.erl index ad42564b3..1debb6323 100644 --- a/src/mod_filter.erl +++ b/src/mod_filter.erl @@ -1,5 +1,5 @@ %%% ==================================================================== -%%% This software is copyright 2006-2009, ProcessOne. +%%% This software is copyright 2006-2010, ProcessOne. %%% %%% mod_filter %%% allow message filtering using regexp on message body @@ -9,7 +9,7 @@ %%% BUT, if patch is not available, mod_filter uses re.beam module %%% instead, with speed degradation. %%% -%%% @copyright 2006-2009 ProcessOne +%%% @copyright 2006-2010 ProcessOne %%% @author Christophe Romain %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} @@ -18,7 +18,6 @@ -module(mod_filter). -author('christophe.romain@process-one.net'). --vsn('$Id: mod_filter.erl 767 2009-04-20 16:31:40Z cromain $'). -behaviour(gen_mod). diff --git a/src/mod_support.erl b/src/mod_support.erl index de1c7ba65..bd3b8a01b 100644 --- a/src/mod_support.erl +++ b/src/mod_support.erl @@ -1,10 +1,10 @@ %%% ==================================================================== -%%% This software is copyright 2006-2009, ProcessOne. +%%% This software is copyright 2006-2010, ProcessOne. %%% %%% mod_support %%% allow automatic build of support archive to be sent to Process-One %%% -%%% @copyright 2006-2009 ProcessOne +%%% @copyright 2006-2010 ProcessOne %%% @author Christophe Romain %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} @@ -14,7 +14,6 @@ -module(mod_support). -author('christophe.romain@process-one.net'). --vsn('$Id: mod_support.erl 856 2009-09-21 18:46:38Z jpcarlino $'). -behaviour(gen_mod). %-behaviour(gen_server).