diff --git a/ChangeLog b/ChangeLog index 8948d28a6..6131a6b25 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2009-03-03 Badlop + * src/mod_privacy.erl: Privacy List: deny presence-out all + send + presence to: presence is sent (EJAB-255) + * src/ejabberd_c2s.erl: Likewise + * src/mod_privacy.erl: Only run roster_get_jid_info if privacy list has subscription or group (thanks to George Hazan)(EJAB-851). Sort items in privacy list by order before storing (EJAB-848) diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 614a4e4e4..6fd3254a4 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -877,8 +877,8 @@ session_established2(El, StateData) -> user_send_packet, Server, [FromJID, ToJID, NewEl]), - ejabberd_router:route( - FromJID, ToJID, NewEl), + check_privacy_route(FromJID, StateData, FromJID, + ToJID, NewEl), StateData end; #xmlel{ns = ?NS_JABBER_CLIENT, name = 'message'} -> @@ -1500,16 +1500,16 @@ presence_update(From, Packet, StateData) -> %% User sends a directed presence packet presence_track(From, To, Packet, StateData) -> LTo = jlib:short_prepd_jid(To), - BFrom = exmpp_jid:jid_to_bare_jid(From), case exmpp_presence:get_type(Packet) of 'unavailable' -> - ejabberd_router:route(From, To, Packet), + check_privacy_route(From, StateData, From, To, Packet), I = remove_element(LTo, StateData#state.pres_i), A = remove_element(LTo, StateData#state.pres_a), StateData#state{pres_i = I, pres_a = A}; 'invisible' -> ejabberd_router:route(From, To, Packet), + check_privacy_route(From, StateData, From, To, Packet), I = ?SETS:add_element(LTo, StateData#state.pres_i), A = remove_element(LTo, StateData#state.pres_a), StateData#state{pres_i = I, @@ -1518,52 +1518,59 @@ presence_track(From, To, Packet, StateData) -> ejabberd_hooks:run(roster_out_subscription, StateData#state.server, [StateData#state.user, StateData#state.server, To, subscribe]), - ejabberd_router:route(BFrom, To, Packet), + check_privacy_route(From, StateData, exmpp_jid:jid_to_bare_jid(From), + To, Packet), StateData; 'subscribed' -> ejabberd_hooks:run(roster_out_subscription, StateData#state.server, [StateData#state.user, StateData#state.server, To, subscribed]), - ejabberd_router:route(BFrom, To, Packet), + check_privacy_route(From, StateData, exmpp_jid:jid_to_bare_jid(From), + To, Packet), StateData; 'unsubscribe' -> ejabberd_hooks:run(roster_out_subscription, StateData#state.server, [StateData#state.user, StateData#state.server, To, unsubscribe]), - ejabberd_router:route(BFrom, To, Packet), + check_privacy_route(From, StateData, exmpp_jid:jid_to_bare_jid(From), + To, Packet), StateData; 'unsubscribed' -> ejabberd_hooks:run(roster_out_subscription, StateData#state.server, [StateData#state.user, StateData#state.server, To, unsubscribed]), - ejabberd_router:route(BFrom, To, Packet), + check_privacy_route(From, StateData, exmpp_jid:jid_to_bare_jid(From), + To, Packet), StateData; 'error' -> - ejabberd_router:route(From, To, Packet), + check_privacy_route(From, StateData, From, To, Packet), StateData; 'probe' -> - ejabberd_router:route(From, To, Packet), + check_privacy_route(From, StateData, From, To, Packet), StateData; _ -> - case ejabberd_hooks:run_fold( - privacy_check_packet, StateData#state.server, - allow, - [StateData#state.user, - StateData#state.server, - StateData#state.privacy_list, - {From, To, Packet}, - out]) of - deny -> - ok; - allow -> - ejabberd_router:route(From, To, Packet) - end, + check_privacy_route(From, StateData, From, To, Packet), I = remove_element(LTo, StateData#state.pres_i), A = ?SETS:add_element(LTo, StateData#state.pres_a), StateData#state{pres_i = I, pres_a = A} end. +check_privacy_route(From, StateData, FromRoute, To, Packet) -> + case ejabberd_hooks:run_fold( + privacy_check_packet, StateData#state.server, + allow, + [StateData#state.user, + StateData#state.server, + StateData#state.privacy_list, + {From, To, Packet}, + out]) of + deny -> + ok; + allow -> + ejabberd_router:route(FromRoute, To, Packet) + end. + presence_broadcast(StateData, From, JIDSet, Packet) -> lists:foreach(fun({U, S, R}) -> FJID = exmpp_jid:make_jid(U, S, R), diff --git a/src/mod_privacy.erl b/src/mod_privacy.erl index acd2fb380..2ef8e7a49 100644 --- a/src/mod_privacy.erl +++ b/src/mod_privacy.erl @@ -561,9 +561,12 @@ get_user_list(_, User, Server) end. +%% From is the sender, To is the destination. +%% If Dir = out, User@Server is the sender account (From). +%% If Dir = in, User@Server is the destination account (To). check_packet(_, User, Server, #userlist{list = List, needdb = NeedDb}, - {From, To, #xmlel{name = PName}}, + {From, To, #xmlel{name = PName, attrs = Attrs}}, Dir) when PName =:= message ; PName =:= iq ; @@ -572,48 +575,42 @@ check_packet(_, User, Server, [] -> allow; _ -> - case {PName, Dir} of - {message, in} -> - LJID = jlib:short_prepd_jid(From), - {Subscription, Groups} = - case NeedDb of - true -> ejabberd_hooks:run_fold(roster_get_jid_info, Server, {none, []}, [User, Server, From]); - false -> {[], []} - end, - check_packet_aux(List, message, - LJID, Subscription, Groups); - {iq, in} -> - LJID = jlib:short_prepd_jid(From), - {Subscription, Groups} = - case NeedDb of - true -> ejabberd_hooks:run_fold(roster_get_jid_info, Server, {none, []}, [User, Server, From]); - false -> {[], []} - end, - check_packet_aux(List, iq, - LJID, Subscription, Groups); - {presence, in} -> - LJID = jlib:short_prepd_jid(From), - {Subscription, Groups} = - case NeedDb of - true -> ejabberd_hooks:run_fold(roster_get_jid_info, Server, {none, []}, [User, Server, From]); - false -> {[], []} - end, - check_packet_aux(List, presence_in, - LJID, Subscription, Groups); - {presence, out} -> - LJID = jlib:short_prepd_jid(To), - {Subscription, Groups} = - case NeedDb of - true -> ejabberd_hooks:run_fold(roster_get_jid_info, Server, {none, []}, [User, Server, From]); - false -> {[], []} - end, - check_packet_aux(List, presence_out, - LJID, Subscription, Groups); - _ -> - allow - end + PType = case PName of + 'message' -> message; + 'iq' -> iq; + 'presence' -> + case xml:get_attr_s("type", Attrs) of + %% notification + '' -> presence; + 'unavailable' -> presence; + %% subscribe, subscribed, unsubscribe, + %% unsubscribed, error, probe, or other + _ -> other + end + end, + PType2 = case {PType, Dir} of + {message, in} -> message; + {iq, in} -> iq; + {presence, in} -> presence_in; + {presence, out} -> presence_out; + {_, _} -> other + end, + LJID = case Dir of + in -> From; + out -> To + end, + {Subscription, Groups} = + case NeedDb of + true -> ejabberd_hooks:run_fold(roster_get_jid_info, + exmpp_stringprep:nameprep(Server), + {none, []}, + [User, Server, LJID]); + false -> {[], []} + end, + check_packet_aux(List, PType2, LJID, Subscription, Groups) end. +%% Ptype = mesage | iq | presence_in | presence_out | other check_packet_aux([], _PType, _JID, _Subscription, _Groups) -> allow; check_packet_aux([Item | List], PType, JID, Subscription, Groups) -> @@ -651,7 +648,9 @@ is_ptype_match(Item, PType) -> presence_in -> Item#listitem.match_presence_in; presence_out -> - Item#listitem.match_presence_out + Item#listitem.match_presence_out; + other -> + false end end.