aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ejabberd_auth_ldap.erl2
-rw-r--r--src/ejabberd_c2s.erl29
-rw-r--r--src/ejabberd_xmlrpc.erl4
-rw-r--r--src/mod_carboncopy.erl22
-rw-r--r--src/mod_client_state.erl8
-rw-r--r--src/mod_muc_room.erl24
-rw-r--r--src/mod_pubsub.erl42
-rw-r--r--src/mod_pubsub_odbc.erl42
8 files changed, 141 insertions, 32 deletions
diff --git a/src/ejabberd_auth_ldap.erl b/src/ejabberd_auth_ldap.erl
index 77937d010..7eba6ef32 100644
--- a/src/ejabberd_auth_ldap.erl
+++ b/src/ejabberd_auth_ldap.erl
@@ -387,7 +387,7 @@ parse_options(Host) ->
[{<<"%u">>, <<"*">>}]),
{DNFilter, DNFilterAttrs} =
eldap_utils:get_opt({ldap_dn_filter, Host}, [],
- fun({DNF, DNFA}) ->
+ fun([{DNF, DNFA}]) ->
NewDNFA = case DNFA of
undefined ->
[];
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index c0b042ec6..601d07443 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -1694,12 +1694,23 @@ handle_info({route, From, To,
jlib:replace_from_to_attrs(jlib:jid_to_string(From),
jlib:jid_to_string(To), NewAttrs),
FixedPacket = #xmlel{name = Name, attrs = Attrs2, children = Els},
- SentStateData = send_packet(NewState, FixedPacket),
- ejabberd_hooks:run(user_receive_packet,
- SentStateData#state.server,
- [SentStateData#state.jid, From, To, FixedPacket]),
+ FinalState =
+ case ejabberd_hooks:run_fold(c2s_filter_packet_in,
+ NewState#state.server, FixedPacket,
+ [NewState#state.jid, From, To])
+ of
+ drop ->
+ NewState;
+ FinalPacket = #xmlel{} ->
+ SentState = send_packet(NewState, FinalPacket),
+ ejabberd_hooks:run(user_receive_packet,
+ SentState#state.server,
+ [SentState#state.jid, From, To,
+ FinalPacket]),
+ SentState
+ end,
ejabberd_hooks:run(c2s_loop_debug, [{route, From, To, Packet}]),
- fsm_next_state(StateName, SentStateData);
+ fsm_next_state(StateName, FinalState);
true ->
ejabberd_hooks:run(c2s_loop_debug, [{route, From, To, Packet}]),
fsm_next_state(StateName, NewState)
@@ -1755,7 +1766,13 @@ handle_info({send_filtered, Feature, From, To, Packet}, StateName, StateData) ->
FinalPacket = jlib:replace_from_to(From, To, Packet),
case StateData#state.jid of
To ->
- send_packet(StateData, FinalPacket);
+ case privacy_check_packet(StateData, From, To,
+ FinalPacket, in) of
+ deny ->
+ StateData;
+ allow ->
+ send_stanza(StateData, FinalPacket)
+ end;
_ ->
ejabberd_router:route(From, To, FinalPacket),
StateData
diff --git a/src/ejabberd_xmlrpc.erl b/src/ejabberd_xmlrpc.erl
index c3b2fdab7..b59001819 100644
--- a/src/ejabberd_xmlrpc.erl
+++ b/src/ejabberd_xmlrpc.erl
@@ -448,8 +448,8 @@ format_arg({array, Elements}, {list, ElementsDef})
format_arg(Arg, integer) when is_integer(Arg) -> Arg;
format_arg(Arg, binary) when is_list(Arg) -> list_to_binary(Arg);
format_arg(Arg, binary) when is_binary(Arg) -> Arg;
-format_arg(Arg, string) when is_list(Arg) -> list_to_binary(Arg);
-format_arg(Arg, string) when is_binary(Arg) -> Arg;
+format_arg(Arg, string) when is_list(Arg) -> Arg;
+format_arg(Arg, string) when is_binary(Arg) -> binary_to_list(Arg);
format_arg(Arg, Format) ->
?ERROR_MSG("don't know how to format Arg ~p for format ~p", [Arg, Format]),
throw({error_formatting_argument, Arg, Format}).
diff --git a/src/mod_carboncopy.erl b/src/mod_carboncopy.erl
index 1313e341a..267ed84bb 100644
--- a/src/mod_carboncopy.erl
+++ b/src/mod_carboncopy.erl
@@ -138,8 +138,8 @@ user_receive_packet(JID, _From, To, Packet) ->
% - registered to the user_send_packet hook, to be called only once even for multicast
% - do not support "private" message mode, and do not modify the original packet in any way
% - we also replicate "read" notifications
-check_and_forward(JID, To, #xmlel{name = <<"message">>, attrs = Attrs} = Packet, Direction)->
- case xml:get_attr_s(<<"type">>, Attrs) == <<"chat">> andalso
+check_and_forward(JID, To, Packet, Direction)->
+ case is_chat_or_normal_message(Packet) andalso
xml:get_subtag(Packet, <<"private">>) == false andalso
xml:get_subtag(Packet, <<"no-copy">>) == false of
true ->
@@ -215,7 +215,7 @@ send_copies(JID, To, Packet, Direction)->
build_forward_packet(JID, Packet, Sender, Dest, Direction, ?NS_CARBONS_2) ->
#xmlel{name = <<"message">>,
attrs = [{<<"xmlns">>, <<"jabber:client">>},
- {<<"type">>, <<"chat">>},
+ {<<"type">>, message_type(Packet)},
{<<"from">>, jlib:jid_to_string(Sender)},
{<<"to">>, jlib:jid_to_string(Dest)}],
children = [
@@ -231,7 +231,7 @@ build_forward_packet(JID, Packet, Sender, Dest, Direction, ?NS_CARBONS_2) ->
build_forward_packet(JID, Packet, Sender, Dest, Direction, ?NS_CARBONS_1) ->
#xmlel{name = <<"message">>,
attrs = [{<<"xmlns">>, <<"jabber:client">>},
- {<<"type">>, <<"chat">>},
+ {<<"type">>, message_type(Packet)},
{<<"from">>, jlib:jid_to_string(Sender)},
{<<"to">>, jlib:jid_to_string(Dest)}],
children = [
@@ -272,6 +272,20 @@ complete_packet(_From, #xmlel{name = <<"message">>, attrs=OrigAttrs} = Packet, r
Attrs = lists:keystore(<<"xmlns">>, 1, OrigAttrs, {<<"xmlns">>, <<"jabber:client">>}),
Packet#xmlel{attrs = Attrs}.
+message_type(#xmlel{attrs = Attrs}) ->
+ case xml:get_attr(<<"type">>, Attrs) of
+ {value, Type} -> Type;
+ false -> <<"normal">>
+ end.
+
+is_chat_or_normal_message(#xmlel{name = <<"message">>} = Packet) ->
+ case message_type(Packet) of
+ <<"chat">> -> true;
+ <<"normal">> -> true;
+ _ -> false
+ end;
+is_chat_or_normal_message(_Packet) -> false.
+
%% list {resource, cc_version} with carbons enabled for given user and host
list(User, Server)->
mnesia:dirty_select(?TABLE, [{#carboncopy{us = {User, Server}, resource = '$2', version = '$3'}, [], [{{'$2','$3'}}]}]).
diff --git a/src/mod_client_state.erl b/src/mod_client_state.erl
index b43683bb7..69e76c24e 100644
--- a/src/mod_client_state.erl
+++ b/src/mod_client_state.erl
@@ -37,9 +37,13 @@
start(Host, Opts) ->
QueuePresence = gen_mod:get_opt(queue_presence, Opts,
- fun(true) -> true end, false),
+ fun(true) -> true;
+ (false) -> false
+ end, false),
DropChatStates = gen_mod:get_opt(drop_chat_states, Opts,
- fun(true) -> true end, false),
+ fun(true) -> true;
+ (false) -> false
+ end, false),
if QueuePresence; DropChatStates ->
ejabberd_hooks:add(c2s_post_auth_features, Host, ?MODULE,
add_stream_feature, 50),
diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl
index 6a2a91d21..0974950b7 100644
--- a/src/mod_muc_room.erl
+++ b/src/mod_muc_room.erl
@@ -174,7 +174,7 @@ normal_state({route, From, <<"">>,
Now = now_to_usec(now()),
MinMessageInterval =
trunc(gen_mod:get_module_opt(StateData#state.server_host,
- mod_muc, min_message_interval, fun(MMI) when is_integer(MMI) -> MMI end, 0)
+ mod_muc, min_message_interval, fun(MMI) when is_number(MMI) -> MMI end, 0)
* 1000000),
Size = element_size(Packet),
{MessageShaper, MessageShaperInterval} =
@@ -1517,15 +1517,17 @@ get_user_activity(JID, StateData) ->
store_user_activity(JID, UserActivity, StateData) ->
MinMessageInterval =
- gen_mod:get_module_opt(StateData#state.server_host,
- mod_muc, min_message_interval,
- fun(I) when is_integer(I), I>=0 -> I end,
- 0),
+ trunc(gen_mod:get_module_opt(StateData#state.server_host,
+ mod_muc, min_message_interval,
+ fun(I) when is_number(I), I>=0 -> I end,
+ 0)
+ * 1000),
MinPresenceInterval =
- gen_mod:get_module_opt(StateData#state.server_host,
- mod_muc, min_presence_interval,
- fun(I) when is_integer(I), I>=0 -> I end,
- 0),
+ trunc(gen_mod:get_module_opt(StateData#state.server_host,
+ mod_muc, min_presence_interval,
+ fun(I) when is_number(I), I>=0 -> I end,
+ 0)
+ * 1000),
Key = jlib:jid_tolower(JID),
Now = now_to_usec(now()),
Activity1 = clean_treap(StateData#state.activity,
@@ -1556,8 +1558,8 @@ store_user_activity(JID, UserActivity, StateData) ->
100000),
Delay = lists:max([MessageShaperInterval,
PresenceShaperInterval,
- MinMessageInterval * 1000,
- MinPresenceInterval * 1000])
+ MinMessageInterval,
+ MinPresenceInterval])
* 1000,
Priority = {1, -(Now + Delay)},
StateData#state{activity =
diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl
index e6437199b..5f16fed7e 100644
--- a/src/mod_pubsub.erl
+++ b/src/mod_pubsub.erl
@@ -74,7 +74,8 @@
on_user_offline/3, remove_user/2,
disco_local_identity/5, disco_local_features/5,
disco_local_items/5, disco_sm_identity/5,
- disco_sm_features/5, disco_sm_items/5]).
+ disco_sm_features/5, disco_sm_items/5,
+ drop_pep_error/4]).
%% exported iq handlers
-export([iq_sm/3]).
@@ -344,6 +345,8 @@ init([ServerHost, Opts]) ->
?MODULE, disco_sm_features, 75),
ejabberd_hooks:add(disco_sm_items, ServerHost, ?MODULE,
disco_sm_items, 75),
+ ejabberd_hooks:add(c2s_filter_packet_in, ServerHost, ?MODULE,
+ drop_pep_error, 75),
gen_iq_handler:add_iq_handler(ejabberd_sm, ServerHost,
?NS_PUBSUB, ?MODULE, iq_sm, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_sm, ServerHost,
@@ -1179,8 +1182,12 @@ presence_probe(#jid{luser = U, lserver = S}, #jid{luser = U, lserver = S}, _Pid)
%% ignore presence_probe from my other ressources
%% to not get duplicated last items
ok;
-presence_probe(#jid{luser = U, lserver = S, lresource = R}, #jid{lserver = Host} = JID, _Pid) ->
- presence(Host, {presence, U, S, [R], JID}).
+presence_probe(#jid{luser = U, lserver = S, lresource = R}, #jid{lserver = S} = JID, _Pid) ->
+ presence(S, {presence, U, S, [R], JID});
+presence_probe(_Host, _JID, _Pid) ->
+ %% ignore presence_probe from remote contacts,
+ %% those are handled via caps_update
+ ok.
presence(ServerHost, Presence) ->
SendLoop = case
@@ -1279,6 +1286,33 @@ unsubscribe_user(Entity, Owner) ->
end).
%% -------
+%% packet receive hook handling function
+%%
+
+drop_pep_error(#xmlel{name = <<"message">>, attrs = Attrs} = Packet, _JID, From,
+ #jid{lresource = <<"">>} = To) ->
+ case xml:get_attr_s(<<"type">>, Attrs) of
+ <<"error">> ->
+ case xml:get_subtag(Packet, <<"event">>) of
+ #xmlel{attrs = EventAttrs} ->
+ case xml:get_attr_s(<<"xmlns">>, EventAttrs) of
+ ?NS_PUBSUB_EVENT ->
+ ?DEBUG("Dropping PEP error message from ~s to ~s",
+ [jlib:jid_to_string(From),
+ jlib:jid_to_string(To)]),
+ drop;
+ _ ->
+ Packet
+ end;
+ false ->
+ Packet
+ end;
+ _ ->
+ Packet
+ end;
+drop_pep_error(Acc, _JID, _From, _To) -> Acc.
+
+%% -------
%% user remove hook handling function
%%
@@ -1418,6 +1452,8 @@ terminate(_Reason,
?MODULE, disco_sm_features, 75),
ejabberd_hooks:delete(disco_sm_items, ServerHost,
?MODULE, disco_sm_items, 75),
+ ejabberd_hooks:delete(c2s_filter_packet_in, ServerHost,
+ ?MODULE, drop_pep_error, 75),
gen_iq_handler:remove_iq_handler(ejabberd_sm,
ServerHost, ?NS_PUBSUB),
gen_iq_handler:remove_iq_handler(ejabberd_sm,
diff --git a/src/mod_pubsub_odbc.erl b/src/mod_pubsub_odbc.erl
index e2b357f03..c953e26a9 100644
--- a/src/mod_pubsub_odbc.erl
+++ b/src/mod_pubsub_odbc.erl
@@ -74,7 +74,8 @@
on_user_offline/3, remove_user/2,
disco_local_identity/5, disco_local_features/5,
disco_local_items/5, disco_sm_identity/5,
- disco_sm_features/5, disco_sm_items/5]).
+ disco_sm_features/5, disco_sm_items/5,
+ drop_pep_error/4]).
%% exported iq handlers
-export([iq_sm/3]).
@@ -344,6 +345,8 @@ init([ServerHost, Opts]) ->
?MODULE, disco_sm_features, 75),
ejabberd_hooks:add(disco_sm_items, ServerHost, ?MODULE,
disco_sm_items, 75),
+ ejabberd_hooks:add(c2s_filter_packet_in, ServerHost, ?MODULE,
+ drop_pep_error, 75),
gen_iq_handler:add_iq_handler(ejabberd_sm, ServerHost,
?NS_PUBSUB, ?MODULE, iq_sm, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_sm, ServerHost,
@@ -830,8 +833,12 @@ presence_probe(#jid{luser = U, lserver = S}, #jid{luser = U, lserver = S}, _Pid)
%% ignore presence_probe from my other ressources
%% to not get duplicated last items
ok;
-presence_probe(#jid{luser = U, lserver = S, lresource = R}, #jid{lserver = Host} = JID, _Pid) ->
- presence(Host, {presence, U, S, [R], JID}).
+presence_probe(#jid{luser = U, lserver = S, lresource = R}, #jid{lserver = S} = JID, _Pid) ->
+ presence(S, {presence, U, S, [R], JID});
+presence_probe(_Host, _JID, _Pid) ->
+ %% ignore presence_probe from remote contacts,
+ %% those are handled via caps_update
+ ok.
presence(ServerHost, Presence) ->
SendLoop = case
@@ -930,6 +937,33 @@ unsubscribe_user(Entity, Owner) ->
end).
%% -------
+%% packet receive hook handling function
+%%
+
+drop_pep_error(#xmlel{name = <<"message">>, attrs = Attrs} = Packet, _JID, From,
+ #jid{lresource = <<"">>} = To) ->
+ case xml:get_attr_s(<<"type">>, Attrs) of
+ <<"error">> ->
+ case xml:get_subtag(Packet, <<"event">>) of
+ #xmlel{attrs = EventAttrs} ->
+ case xml:get_attr_s(<<"xmlns">>, EventAttrs) of
+ ?NS_PUBSUB_EVENT ->
+ ?DEBUG("Dropping PEP error message from ~s to ~s",
+ [jlib:jid_to_string(From),
+ jlib:jid_to_string(To)]),
+ drop;
+ _ ->
+ Packet
+ end;
+ false ->
+ Packet
+ end;
+ _ ->
+ Packet
+ end;
+drop_pep_error(Acc, _JID, _From, _To) -> Acc.
+
+%% -------
%% user remove hook handling function
%%
@@ -1069,6 +1103,8 @@ terminate(_Reason,
?MODULE, disco_sm_features, 75),
ejabberd_hooks:delete(disco_sm_items, ServerHost,
?MODULE, disco_sm_items, 75),
+ ejabberd_hooks:delete(c2s_filter_packet_in, ServerHost,
+ ?MODULE, drop_pep_error, 75),
gen_iq_handler:remove_iq_handler(ejabberd_sm,
ServerHost, ?NS_PUBSUB),
gen_iq_handler:remove_iq_handler(ejabberd_sm,