mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-30 16:36:29 +01:00
New option resource_conflict defines server action (thanks to Lee Boynton)(EJAB-650)
This commit is contained in:
parent
7355e810a8
commit
fef8c3a1f3
@ -1243,6 +1243,16 @@ defines in what format the users passwords are stored:
|
|||||||
This format allows clients to authenticate using: \term{SASL PLAIN} and \term{SASL SCRAM-SHA-1}.
|
This format allows clients to authenticate using: \term{SASL PLAIN} and \term{SASL SCRAM-SHA-1}.
|
||||||
\end{description}
|
\end{description}
|
||||||
|
|
||||||
|
The option \option{resource\_conflict} defines the action when a client attempts to
|
||||||
|
login to an account with a resource that is already connected.
|
||||||
|
The option syntax is:
|
||||||
|
\esyntax{\{resource\_conflict, setresource|closenew|closeold\}.}
|
||||||
|
The possible values match exactly the three possibilities described in
|
||||||
|
\footahref{http://tools.ietf.org/html/rfc6120\#section-7.7.2.2}{XMPP Core: section 7.7.2.2}.
|
||||||
|
The default value is \term{closeold}.
|
||||||
|
If the client uses old Jabber Non-SASL authentication (\xepref{0078}),
|
||||||
|
then this option is not respected, and the action performed is \term{closeold}.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item To use internal Mnesia storage with hashed passwords on all virtual hosts:
|
\item To use internal Mnesia storage with hashed passwords on all virtual hosts:
|
||||||
|
@ -907,6 +907,29 @@ wait_for_sasl_response(closed, StateData) ->
|
|||||||
{stop, normal, StateData}.
|
{stop, normal, StateData}.
|
||||||
|
|
||||||
|
|
||||||
|
resource_conflict_action(U, S, R) ->
|
||||||
|
OptionRaw = case ejabberd_sm:is_existing_resource(U, S, R) of
|
||||||
|
true ->
|
||||||
|
ejabberd_config:get_local_option({resource_conflict,binary_to_list(S)});
|
||||||
|
false ->
|
||||||
|
acceptnew
|
||||||
|
end,
|
||||||
|
Option = case OptionRaw of
|
||||||
|
setresource -> setresource;
|
||||||
|
closeold -> acceptnew; %% ejabberd_sm will close old session
|
||||||
|
closenew -> closenew;
|
||||||
|
acceptnew -> acceptnew;
|
||||||
|
_ -> acceptnew %% default ejabberd behavior
|
||||||
|
end,
|
||||||
|
case Option of
|
||||||
|
acceptnew ->
|
||||||
|
{accept_resource, R};
|
||||||
|
closenew ->
|
||||||
|
closenew;
|
||||||
|
setresource ->
|
||||||
|
Rnew = lists:concat([randoms:get_string() | tuple_to_list(now())]),
|
||||||
|
{accept_resource, Rnew}
|
||||||
|
end.
|
||||||
|
|
||||||
wait_for_bind({xmlstreamelement, El}, StateData) ->
|
wait_for_bind({xmlstreamelement, El}, StateData) ->
|
||||||
try
|
try
|
||||||
@ -923,11 +946,17 @@ wait_for_bind({xmlstreamelement, El}, StateData) ->
|
|||||||
%%send_element(StateData,
|
%%send_element(StateData,
|
||||||
%% exmpp_stream:features([exmpp_server_session:feature()
|
%% exmpp_stream:features([exmpp_server_session:feature()
|
||||||
%% | RosterVersioningFeature])),
|
%% | RosterVersioningFeature])),
|
||||||
JID = exmpp_jid:make(StateData#state.user, StateData#state.server, R),
|
case resource_conflict_action(StateData#state.user, StateData#state.server, list_to_binary(R)) of
|
||||||
|
closenew ->
|
||||||
|
send_element(StateData, ?SERRT_CONFLICT), %% (Lang, "Replaced by new connection")),
|
||||||
|
fsm_next_state(wait_for_bind, StateData);
|
||||||
|
{accept_resource, R2} ->
|
||||||
|
JID = exmpp_jid:make(StateData#state.user, StateData#state.server, R2),
|
||||||
Res = exmpp_server_binding:bind(El, JID),
|
Res = exmpp_server_binding:bind(El, JID),
|
||||||
send_element(StateData, Res),
|
send_element(StateData, Res),
|
||||||
fsm_next_state(wait_for_session,
|
fsm_next_state(wait_for_session,
|
||||||
StateData#state{resource = exmpp_jid:resource(JID), jid = JID})
|
StateData#state{resource = exmpp_jid:resource(JID), jid = JID})
|
||||||
|
end
|
||||||
catch
|
catch
|
||||||
throw:{stringprep, resourceprep, _, _} ->
|
throw:{stringprep, resourceprep, _, _} ->
|
||||||
Err = exmpp_server_binding:error(El, 'bad-request'),
|
Err = exmpp_server_binding:error(El, 'bad-request'),
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
get_session_pid/1,
|
get_session_pid/1,
|
||||||
get_user_info/3,
|
get_user_info/3,
|
||||||
get_user_ip/1,
|
get_user_ip/1,
|
||||||
|
is_existing_resource/3,
|
||||||
migrate/1
|
migrate/1
|
||||||
]).
|
]).
|
||||||
|
|
||||||
@ -727,16 +728,12 @@ check_for_sessions_to_replace(JID) ->
|
|||||||
check_max_sessions(JID).
|
check_max_sessions(JID).
|
||||||
|
|
||||||
check_existing_resources(JID) ->
|
check_existing_resources(JID) ->
|
||||||
USR = {exmpp_jid:prep_node(JID),
|
|
||||||
exmpp_jid:prep_domain(JID),
|
|
||||||
exmpp_jid:prep_resource(JID)},
|
|
||||||
%% A connection exist with the same resource. We replace it:
|
%% A connection exist with the same resource. We replace it:
|
||||||
SIDs = mnesia:dirty_select(
|
SIDs = get_resource_sessions(JID),
|
||||||
session,
|
|
||||||
[{#session{sid = '$1', usr = USR, _ = '_'}, [], ['$1']}]),
|
|
||||||
if
|
if
|
||||||
SIDs == [] -> ok;
|
SIDs == [] -> ok;
|
||||||
true ->
|
true ->
|
||||||
|
%% A connection exist with the same resource. We replace it:
|
||||||
MaxSID = lists:max(SIDs),
|
MaxSID = lists:max(SIDs),
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun({_, Pid} = S) when S /= MaxSID ->
|
fun({_, Pid} = S) when S /= MaxSID ->
|
||||||
@ -745,6 +742,17 @@ check_existing_resources(JID) ->
|
|||||||
end, SIDs)
|
end, SIDs)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
is_existing_resource(U, S, R) ->
|
||||||
|
[] /= get_resource_sessions(exmpp_jid:make(U, S, R)).
|
||||||
|
|
||||||
|
get_resource_sessions(JID) ->
|
||||||
|
USR = {exmpp_jid:prep_node(JID),
|
||||||
|
exmpp_jid:prep_domain(JID),
|
||||||
|
exmpp_jid:prep_resource(JID)},
|
||||||
|
mnesia:dirty_select(
|
||||||
|
session,
|
||||||
|
[{#session{sid = '$1', usr = USR, _ = '_'}, [], ['$1']}]).
|
||||||
|
|
||||||
check_max_sessions(JID) ->
|
check_max_sessions(JID) ->
|
||||||
%% If the max number of sessions for a given is reached, we replace the
|
%% If the max number of sessions for a given is reached, we replace the
|
||||||
%% first one
|
%% first one
|
||||||
|
Loading…
Reference in New Issue
Block a user