aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlexey Shchepin <alexey@process-one.net>2003-11-07 20:51:23 +0000
committerAlexey Shchepin <alexey@process-one.net>2003-11-07 20:51:23 +0000
commite7183996ed4b121d67e91c231cb5812fbf8fc350 (patch)
treec88682b5998aa09adbead8984b0da54ffb8cc34a /src
parent* src/mod_configure2.erl: Added reporting of outgoing S2S (diff)
* 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
Diffstat (limited to 'src')
-rw-r--r--src/cyrsasl.erl13
-rw-r--r--src/ejabberd_c2s.erl95
-rw-r--r--src/ejabberd_sm.erl13
-rw-r--r--src/jlib.hrl1
4 files changed, 92 insertions, 30 deletions
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),