aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ejabberd_c2s.erl29
-rw-r--r--src/mod_carboncopy.erl22
-rw-r--r--src/mod_pubsub.erl42
-rw-r--r--src/mod_pubsub_odbc.erl42
4 files changed, 119 insertions, 16 deletions
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/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_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,