aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMickaël Rémond <mickael.remond@process-one.net>2008-12-08 09:21:36 +0000
committerMickaël Rémond <mickael.remond@process-one.net>2008-12-08 09:21:36 +0000
commit4618ec1fefb73a8ba85441de19bb17fd451961ec (patch)
treeef5ffe85a55c771b7ad10fb5c0bbc2eba878f3e3
parentFix 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--ChangeLog6
-rw-r--r--src/ejabberd_c2s.erl87
-rw-r--r--src/jlib.erl9
3 files changed, 80 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog
index 2aea56718..823b6bc7b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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),