From e7183996ed4b121d67e91c231cb5812fbf8fc350 Mon Sep 17 00:00:00 2001 From: Alexey Shchepin Date: Fri, 7 Nov 2003 20:51:23 +0000 Subject: [PATCH] * src/cyrsasl.erl: Updated SASL authentification * src/ejabberd_c2s.erl: Likewise * src/ejabberd_sm.erl: Better resource handling * src/jlib.hrl: Added NS_BIND macros SVN Revision: 170 --- ChangeLog | 9 +++++ src/cyrsasl.erl | 13 +++++- src/ejabberd_c2s.erl | 95 +++++++++++++++++++++++++++++++++----------- src/ejabberd_sm.erl | 13 +++--- src/jlib.hrl | 1 + 5 files changed, 101 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index f1184a9bf..3e0aba5e6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2003-11-07 Alexey Shchepin + + * src/cyrsasl.erl: Updated SASL authentification + * src/ejabberd_c2s.erl: Likewise + + * src/ejabberd_sm.erl: Better resource handling + + * src/jlib.hrl: Added NS_BIND macros + 2003-11-06 Alexey Shchepin * src/mod_configure2.erl: Added reporting of outgoing S2S diff --git a/src/cyrsasl.erl b/src/cyrsasl.erl index feb190afc..9376b25d2 100644 --- a/src/cyrsasl.erl +++ b/src/cyrsasl.erl @@ -64,6 +64,17 @@ check_authzid(State, Props) -> end end. +check_credentials(State, Props) -> + User = xml:get_attr_s(username, Props), + case jlib:nodeprep(User) of + error -> + {error, "not-authorized"}; + "" -> + {error, "not-authorized"}; + LUser -> + ok + end. + listmech() -> ets:select(sasl_mechanism, [{#sasl_mechanism{mechanism = '$1', _ = '_'}, [], ['$1']}]). @@ -90,7 +101,7 @@ server_step(State, ClientIn) -> MechState = State#sasl_state.mech_state, case Module:mech_step(MechState, ClientIn) of {ok, Props} -> - case check_authzid(State, Props) of + case check_credentials(State, Props) of ok -> {ok, Props}; {error, Error} -> diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 4ebec720f..97c82852b 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -24,6 +24,7 @@ wait_for_stream/2, wait_for_auth/2, wait_for_sasl_auth/2, + wait_for_bind/2, wait_for_session/2, wait_for_sasl_response/2, session_established/2, @@ -152,10 +153,20 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) -> {next_state, wait_for_sasl_auth, StateData#state{sasl_state = SASLState}}; _ -> - send_element( - StateData, - {xmlelement, "stream:features", [], []}), - {next_state, wait_for_session, StateData} + case StateData#state.resource of + "" -> + send_element( + StateData, + {xmlelement, "stream:features", [], + [{xmlelement, "bind", + [{"xmlns", ?NS_SASL}], []}]}), + {next_state, wait_for_bind, StateData}; + _ -> + send_element( + StateData, + {xmlelement, "stream:features", [], []}), + {next_state, wait_for_session, StateData} + end end; _ -> Header = io_lib:format( @@ -296,17 +307,12 @@ wait_for_sasl_auth({xmlstreamelement, El}, StateData) -> send_element(StateData, {xmlelement, "success", [{"xmlns", ?NS_SASL}], []}), - JID = #jid{user = U, resource = R} = - jlib:string_to_jid( - xml:get_attr_s(authzid, Props)), + U = xml:get_attr_s(username, Props), ?INFO_MSG("(~w) Accepted authentification for ~s", - [StateData#state.socket, - jlib:jid_to_string(JID)]), + [StateData#state.socket, U]), {next_state, wait_for_stream, StateData#state{authentificated = true, - user = U, - resource = R, - jid = JID + user = U }}; {continue, ServerOut, NewSASLState} -> send_element(StateData, @@ -364,16 +370,12 @@ wait_for_sasl_response({xmlstreamelement, El}, StateData) -> send_element(StateData, {xmlelement, "success", [{"xmlns", ?NS_SASL}], []}), - JID = #jid{user = U, resource = R} = - jlib:string_to_jid(xml:get_attr_s(authzid, Props)), + U = xml:get_attr_s(username, Props), ?INFO_MSG("(~w) Accepted authentification for ~s", - [StateData#state.socket, - jlib:jid_to_string(JID)]), + [StateData#state.socket, U]), {next_state, wait_for_stream, StateData#state{authentificated = true, - user = U, - resource = R, - jid = JID + user = U }}; {continue, ServerOut, NewSASLState} -> send_element(StateData, @@ -420,6 +422,51 @@ wait_for_sasl_response(closed, StateData) -> +wait_for_bind({xmlstreamelement, El}, StateData) -> + case jlib:iq_query_info(El) of + {iq, ID, set, ?NS_BIND, SubEl} -> + U = StateData#state.user, + R1 = xml:get_path_s(SubEl, [{elem, "resource"}, cdata]), + R = case jlib:resourceprep(R1) of + error -> error; + "" -> + lists:concat( + [randoms:get_string() | tuple_to_list(now())]); + Resource -> Resource + end, + case R of + error -> + Err = jlib:make_error_reply(El, ?ERR_BAD_REQUEST), + send_element(StateData, Err), + {next_state, wait_for_bind, StateData}; + _ -> + JID = jlib:make_jid(U, StateData#state.server, R), + Res = {iq, ID, result, ?NS_BIND, + [{xmlelement, "bind", + [{"xmlns", ?NS_BIND}], + [{xmlelement, "jid", [], + [{xmlcdata, jlib:jid_to_string(JID)}]}]}]}, + send_element(StateData, jlib:iq_to_xml(Res)), + {next_state, wait_for_session, + StateData#state{resource = R, jid = JID}} + end; + _ -> + {next_state, wait_for_bind, StateData} + end; + +wait_for_bind({xmlstreamend, Name}, StateData) -> + send_text(StateData, ?STREAM_TRAILER), + {stop, normal, StateData}; + +wait_for_bind({xmlstreamerror, _}, StateData) -> + send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER), + {stop, normal, StateData}; + +wait_for_bind(closed, StateData) -> + {stop, normal, StateData}. + + + wait_for_session({xmlstreamelement, El}, StateData) -> case jlib:iq_query_info(El) of {iq, ID, set, ?NS_SESSION, SubEl} -> @@ -742,10 +789,8 @@ handle_info({route, From, To, Packet}, StateName, StateData) -> %% Returns: any %%---------------------------------------------------------------------- terminate(Reason, StateName, StateData) -> - case StateData#state.user of - "" -> - ok; - _ -> + case StateName of + session_established -> ?INFO_MSG("(~w) Close session for ~s", [StateData#state.socket, jlib:jid_to_string(StateData#state.jid)]), @@ -756,7 +801,9 @@ terminate(Reason, StateName, StateData) -> ejabberd_sm:unset_presence(StateData#state.user, StateData#state.resource), presence_broadcast(StateData, From, StateData#state.pres_a, Packet), - presence_broadcast(StateData, From, StateData#state.pres_i, Packet) + presence_broadcast(StateData, From, StateData#state.pres_i, Packet); + _ -> + ok end, (StateData#state.sockmod):close(StateData#state.socket), ok. diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index af446d829..92173b4bc 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -104,7 +104,8 @@ close_session(User, Resource) -> register_connection(User, Resource, Pid) -> LUser = jlib:nodeprep(User), - UR = {LUser, Resource}, + LResource = jlib:nodeprep(Resource), + UR = {LUser, LResource}, F = fun() -> Ss = mnesia:wread({session, UR}), Ls = mnesia:wread({local_session, UR}), @@ -134,8 +135,9 @@ register_connection(User, Resource, Pid) -> replace_my_connection(User, Resource) -> LUser = jlib:nodeprep(User), + LResource = jlib:nodeprep(Resource), + UR = {LUser, LResource}, F = fun() -> - UR = {LUser, Resource}, Es = mnesia:read({local_session, UR}), mnesia:delete({local_session, UR}), Es @@ -153,8 +155,9 @@ replace_my_connection(User, Resource) -> remove_connection(User, Resource) -> LUser = jlib:nodeprep(User), + LResource = jlib:nodeprep(Resource), F = fun() -> - UR = {LUser, Resource}, + UR = {LUser, LResource}, mnesia:delete({local_session, UR}), mnesia:delete({session, UR}) end, @@ -178,10 +181,10 @@ clean_table_from_bad_node(Node) -> do_route(From, To, Packet) -> ?DEBUG("session manager~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n", [From, To, Packet, 8]), - #jid{user = User, resource = Resource, + #jid{user = User, luser = LUser, lserver = LServer, lresource = LResource} = To, {xmlelement, Name, Attrs, _Els} = Packet, - case Resource of + case LResource of "" -> case Name of "presence" -> diff --git a/src/jlib.hrl b/src/jlib.hrl index fdbf35dae..4497ec941 100644 --- a/src/jlib.hrl +++ b/src/jlib.hrl @@ -40,6 +40,7 @@ -define(NS_SASL, "urn:ietf:params:xml:ns:xmpp-sasl"). -define(NS_SESSION, "urn:ietf:params:xml:ns:xmpp-session"). +-define(NS_BIND, "urn:ietf:params:xml:ns:xmpp-bind"). % TODO: remove "code" attribute (currently it used for backward-compatibility) -define(STANZA_ERROR(Code, Type, Condition),