diff options
author | Mickaël Rémond <mickael.remond@process-one.net> | 2008-12-08 09:21:36 +0000 |
---|---|---|
committer | Mickaël Rémond <mickael.remond@process-one.net> | 2008-12-08 09:21:36 +0000 |
commit | 4618ec1fefb73a8ba85441de19bb17fd451961ec (patch) | |
tree | ef5ffe85a55c771b7ad10fb5c0bbc2eba878f3e3 | |
parent | Fix default value of default_room_options (thanks to Aleksey Shchepin) (diff) |
* src/ejabberd_c2s.erl: Enforce client stanza from attribute (EJAB-812).
* src/jlib.erl: Likewise.
SVN Revision: 1706
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | src/ejabberd_c2s.erl | 87 | ||||
-rw-r--r-- | src/jlib.erl | 9 |
3 files changed, 80 insertions, 22 deletions
@@ -1,3 +1,9 @@ +2008-12-08 Mickael Remond <mremond@process-one.net> + + * src/ejabberd_c2s.erl: Enforce client stanza from attribute + (EJAB-812). + * src/jlib.erl: Likewise. + 2008-12-02 Badlop <badlop@process-one.net> * src/mod_muc/mod_muc_room.erl: Move definitions to header file diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 5b08d1e35..fb93d8dde 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -133,6 +133,9 @@ xml:element_to_string(?SERR_HOST_UNKNOWN)). -define(POLICY_VIOLATION_ERR(Lang, Text), xml:element_to_string(?SERRT_POLICY_VIOLATION(Lang, Text))). +-define(INVALID_FROM, + xml:element_to_string(?SERR_INVALID_FROM)). + %%%---------------------------------------------------------------------- %%% API @@ -868,10 +871,41 @@ wait_for_session(closed, StateData) -> session_established({xmlstreamelement, El}, StateData) -> + FromJID = StateData#state.jid, + % Check 'from' attribute in stanza RFC 3920 Section 9.1.2 + case check_from(El, FromJID) of + 'invalid-from' -> + send_text(StateData, ?INVALID_FROM ++ ?STREAM_TRAILER), + {stop, normal, StateData}; + _NewEl -> + session_established2(El, StateData) + end; + +%% We hibernate the process to reduce memory consumption after a +%% configurable activity timeout +session_established(timeout, StateData) -> + %% TODO: Options must be stored in state: + Options = [], + proc_lib:hibernate(gen_fsm, enter_loop, + [?MODULE, Options, session_established, StateData]), + fsm_next_state(session_established, StateData); + +session_established({xmlstreamend, _Name}, StateData) -> + send_text(StateData, ?STREAM_TRAILER), + {stop, normal, StateData}; + +session_established({xmlstreamerror, _}, StateData) -> + send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER), + {stop, normal, StateData}; + +session_established(closed, StateData) -> + {stop, normal, StateData}. + + +session_established2(El, StateData) -> {xmlelement, Name, Attrs, _Els} = El, User = StateData#state.user, Server = StateData#state.server, - % TODO: check 'from' attribute in stanza FromJID = StateData#state.jid, To = xml:get_attr_s("to", Attrs), ToJID = case To of @@ -951,27 +985,7 @@ session_established({xmlstreamelement, El}, StateData) -> end end, ejabberd_hooks:run(c2s_loop_debug, [{xmlstreamelement, El}]), - fsm_next_state(session_established, NewState); - -%% We hibernate the process to reduce memory consumption after a -%% configurable activity timeout -session_established(timeout, StateData) -> - %% TODO: Options must be stored in state: - Options = [], - proc_lib:hibernate(gen_fsm, enter_loop, - [?MODULE, Options, session_established, StateData]), - fsm_next_state(session_established, StateData); - -session_established({xmlstreamend, _Name}, StateData) -> - send_text(StateData, ?STREAM_TRAILER), - {stop, normal, StateData}; - -session_established({xmlstreamerror, _}, StateData) -> - send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER), - {stop, normal, StateData}; - -session_established(closed, StateData) -> - {stop, normal, StateData}. + fsm_next_state(session_established, NewState). @@ -1994,3 +2008,32 @@ fsm_reply(Reply, StateName, StateData) -> %% Used by c2s blacklist plugins is_ip_blacklisted({IP,_Port}) -> ejabberd_hooks:run_fold(check_bl_c2s, false, [IP]). + +%% Check from attributes +%% returns invalid-from|NewElement +check_from(El, FromJID) -> + case xml:get_tag_attr("from", El) of + false -> + jlib:replace_from(FromJID, El); + {value, JIDElString} -> + JIDEl = jlib:string_to_jid(JIDElString), + case JIDEl#jid.lresource of + "" -> + %% Matching JID: The stanza is ok + if JIDEl#jid.luser == FromJID#jid.luser andalso + JIDEl#jid.lserver == FromJID#jid.lserver -> + El; + true -> + 'invalid-from' + end; + _ -> + %% Matching JID: The stanza is ok + if JIDEl#jid.luser == FromJID#jid.luser andalso + JIDEl#jid.lserver == FromJID#jid.lserver andalso + JIDEl#jid.lresource == FromJID#jid.lresource -> + El; + true -> + 'invalid-from' + end + end + end. diff --git a/src/jlib.erl b/src/jlib.erl index 70f190a93..765457a5b 100644 --- a/src/jlib.erl +++ b/src/jlib.erl @@ -34,6 +34,8 @@ make_correct_from_to_attrs/3, replace_from_to_attrs/3, replace_from_to/3, + replace_from_attrs/2, + replace_from/2, remove_attr/2, make_jid/3, make_jid/1, @@ -153,6 +155,13 @@ replace_from_to(From, To, {xmlelement, Name, Attrs, Els}) -> Attrs), {xmlelement, Name, NewAttrs, Els}. +replace_from_attrs(From, Attrs) -> + Attrs1 = lists:keydelete("from", 1, Attrs), + [{"from", From} | Attrs1]. + +replace_from(From, {xmlelement, Name, Attrs, Els}) -> + NewAttrs = replace_from_attrs(jlib:jid_to_string(From), Attrs), + {xmlelement, Name, NewAttrs, Els}. remove_attr(Attr, {xmlelement, Name, Attrs, Els}) -> NewAttrs = lists:keydelete(Attr, 1, Attrs), |