mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-30 16:36:29 +01:00
Fix crash when SASL PLAIN denies auth (EJAB-1425)
This commit is contained in:
parent
dedd2a7f59
commit
71bfa17354
@ -204,7 +204,7 @@ server_new(Service, ServerFQDN, UserRealm, _SecFlags,
|
|||||||
%% Continue = {continue, ServerOut, New_State}
|
%% Continue = {continue, ServerOut, New_State}
|
||||||
%% ServerOut = string()
|
%% ServerOut = string()
|
||||||
%% New_State = saslstate()
|
%% New_State = saslstate()
|
||||||
%% Error = {error, Reason} | {error, Username, Reason}
|
%% Error = {error, Reason} | {error, Reason, Username}
|
||||||
%% Reason = term()
|
%% Reason = term()
|
||||||
%% Username = string()
|
%% Username = string()
|
||||||
|
|
||||||
@ -236,8 +236,9 @@ server_start(State, Mech, ClientIn) ->
|
|||||||
%% Continue = {continue, ServerOut, New_State}
|
%% Continue = {continue, ServerOut, New_State}
|
||||||
%% ServerOut = string()
|
%% ServerOut = string()
|
||||||
%% New_State = saslstate()
|
%% New_State = saslstate()
|
||||||
%% Error = {error, Reason} | {error, Username, Reason}
|
%% Error = {error, Reason} | {error, Reason, Text, Username}
|
||||||
%% Reason = term()
|
%% Reason = term()
|
||||||
|
%% Text = string()
|
||||||
%% Username = string()
|
%% Username = string()
|
||||||
|
|
||||||
server_step(State, ClientIn) ->
|
server_step(State, ClientIn) ->
|
||||||
@ -254,8 +255,8 @@ server_step(State, ClientIn) ->
|
|||||||
{continue, ServerOut, NewMechState} ->
|
{continue, ServerOut, NewMechState} ->
|
||||||
{continue, ServerOut,
|
{continue, ServerOut,
|
||||||
State#sasl_state{mech_state = NewMechState}};
|
State#sasl_state{mech_state = NewMechState}};
|
||||||
{error, Error, Username} ->
|
{error, Error, Text, Username} ->
|
||||||
{error, Error, Username};
|
{error, Error, Text, Username};
|
||||||
{error, Error} ->
|
{error, Error} ->
|
||||||
{error, Error}
|
{error, Error}
|
||||||
end.
|
end.
|
||||||
|
@ -80,7 +80,7 @@ mech_new(#sasl_params{host=Host, get_password=GetPassword,
|
|||||||
%% Continue = {continue, ServerOut, New_State}
|
%% Continue = {continue, ServerOut, New_State}
|
||||||
%% ServerOut = string()
|
%% ServerOut = string()
|
||||||
%% New_State = mechstate()
|
%% New_State = mechstate()
|
||||||
%% Error = {error, Reason} | {error, Reason, Username}
|
%% Error = {error, Reason} | {error, Reason, Text, Username}
|
||||||
%% Reason = term()
|
%% Reason = term()
|
||||||
|
|
||||||
mech_step(#state{step = 1, nonce = Nonce} = State, _) ->
|
mech_step(#state{step = 1, nonce = Nonce} = State, _) ->
|
||||||
@ -99,12 +99,12 @@ mech_step(#state{step = 3, nonce = Nonce} = State, ClientIn) ->
|
|||||||
false ->
|
false ->
|
||||||
?DEBUG("User login not authorized because digest-uri "
|
?DEBUG("User login not authorized because digest-uri "
|
||||||
"seems invalid: ~p", [DigestURI]),
|
"seems invalid: ~p", [DigestURI]),
|
||||||
{error, 'not-authorized', UserName};
|
{error, 'not-authorized', "", UserName};
|
||||||
true ->
|
true ->
|
||||||
AuthzId = proplists:get_value("authzid", KeyVals, ""),
|
AuthzId = proplists:get_value("authzid", KeyVals, ""),
|
||||||
case (State#state.get_password)(UserName) of
|
case (State#state.get_password)(UserName) of
|
||||||
{false, _} ->
|
{false, _} ->
|
||||||
{error, 'not-authorized', UserName};
|
{error, 'not-authorized', "", UserName};
|
||||||
{Passwd, AuthModule} ->
|
{Passwd, AuthModule} ->
|
||||||
case (State#state.check_password)(UserName, "",
|
case (State#state.check_password)(UserName, "",
|
||||||
proplists:get_value("response", KeyVals, ""),
|
proplists:get_value("response", KeyVals, ""),
|
||||||
@ -121,9 +121,9 @@ mech_step(#state{step = 3, nonce = Nonce} = State, ClientIn) ->
|
|||||||
username = UserName,
|
username = UserName,
|
||||||
authzid = AuthzId}};
|
authzid = AuthzId}};
|
||||||
false ->
|
false ->
|
||||||
{error, 'not-authorized', UserName};
|
{error, 'not-authorized', "", UserName};
|
||||||
{false, _} ->
|
{false, _} ->
|
||||||
{error, 'not-authorized', UserName}
|
{error, 'not-authorized', "", UserName}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -128,13 +128,13 @@ do_step(#state{needsmore=true,sasl=Sasl,step=Step}=State, ClientIn) ->
|
|||||||
{needsmore, RspAuth} ->
|
{needsmore, RspAuth} ->
|
||||||
?DEBUG("needsmore~n", []),
|
?DEBUG("needsmore~n", []),
|
||||||
if (Step > 0) and (ClientIn =:= []) and (RspAuth =:= <<>>) ->
|
if (Step > 0) and (ClientIn =:= []) and (RspAuth =:= <<>>) ->
|
||||||
{error, "not-authorized"};
|
{error, 'not-authorized'};
|
||||||
true ->
|
true ->
|
||||||
{continue, binary_to_list(RspAuth),
|
{continue, binary_to_list(RspAuth),
|
||||||
State#state{step=Step+1}}
|
State#state{step=Step+1}}
|
||||||
end;
|
end;
|
||||||
{error, _} ->
|
{error, _} ->
|
||||||
{error, "not-authorized"}
|
{error, 'not-authorized'}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
handle_step_ok(State, []) ->
|
handle_step_ok(State, []) ->
|
||||||
@ -147,7 +147,7 @@ check_user(#state{authid=Authid,authzid=Authzid,
|
|||||||
authrealm=Auth_realm,host=Host,realm=Realm}) ->
|
authrealm=Auth_realm,host=Host,realm=Realm}) ->
|
||||||
if Realm =/= Auth_realm ->
|
if Realm =/= Auth_realm ->
|
||||||
?DEBUG("bad realm ~p (expected ~p)~n",[Auth_realm, Realm]),
|
?DEBUG("bad realm ~p (expected ~p)~n",[Auth_realm, Realm]),
|
||||||
throw({error, "not-authorized"});
|
throw({error, 'not-authorized'});
|
||||||
true ->
|
true ->
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
@ -155,7 +155,7 @@ check_user(#state{authid=Authid,authzid=Authzid,
|
|||||||
case ejabberd_auth:is_user_exists(Authid, Host) of
|
case ejabberd_auth:is_user_exists(Authid, Host) of
|
||||||
false ->
|
false ->
|
||||||
?DEBUG("bad user ~p~n",[Authid]),
|
?DEBUG("bad user ~p~n",[Authid]),
|
||||||
throw({error, "not-authorized"});
|
throw({error, 'not-authorized'});
|
||||||
true ->
|
true ->
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
|
@ -62,8 +62,7 @@ mech_new(#sasl_params{check_password = CheckPassword}) ->
|
|||||||
%% Username = string()
|
%% Username = string()
|
||||||
%% AuthzId = string()
|
%% AuthzId = string()
|
||||||
%% AuthModule = atom()
|
%% AuthModule = atom()
|
||||||
%% Error = {error, Reason} | {error, Reason, Username}
|
%% Error = {error, Reason} | {error, Reason, Text, Username}
|
||||||
%% Reason = term()
|
|
||||||
|
|
||||||
mech_step(State, ClientIn) ->
|
mech_step(State, ClientIn) ->
|
||||||
case prepare(ClientIn) of
|
case prepare(ClientIn) of
|
||||||
@ -73,9 +72,9 @@ mech_step(State, ClientIn) ->
|
|||||||
{ok, [{username, User}, {authzid, AuthzId},
|
{ok, [{username, User}, {authzid, AuthzId},
|
||||||
{auth_module, AuthModule}]};
|
{auth_module, AuthModule}]};
|
||||||
{false, ReasonAuthFail} when is_list(ReasonAuthFail) ->
|
{false, ReasonAuthFail} when is_list(ReasonAuthFail) ->
|
||||||
{error, ReasonAuthFail, User};
|
{error, 'not-authorized', ReasonAuthFail, User};
|
||||||
_ ->
|
_ ->
|
||||||
{error, 'not-authorized', User}
|
{error, 'not-authorized', "", User}
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
{error, 'bad-protocol'}
|
{error, 'bad-protocol'}
|
||||||
|
@ -141,7 +141,8 @@ check_password(User, Server, Password, Digest, DigestGen)
|
|||||||
%% {true, AuthModule} | {false, Reason::string()}
|
%% {true, AuthModule} | {false, Reason::string()}
|
||||||
%% where
|
%% where
|
||||||
%% AuthModule = ejabberd_auth_anonymous | ejabberd_auth_external
|
%% AuthModule = ejabberd_auth_anonymous | ejabberd_auth_external
|
||||||
%% | ejabberd_auth_ldap | ejabberd_auth_pam | ejabberd_auth_storage
|
%% | ejabberd_auth_internal | ejabberd_auth_ldap
|
||||||
|
%% | ejabberd_auth_odbc | ejabberd_auth_pam
|
||||||
%% @doc Check if the user and password can login in server.
|
%% @doc Check if the user and password can login in server.
|
||||||
%% The user can login if at least an authentication method accepts the user
|
%% The user can login if at least an authentication method accepts the user
|
||||||
%% and the password.
|
%% and the password.
|
||||||
|
@ -716,13 +716,13 @@ wait_for_feature_request({xmlstreamelement, #xmlel{ns = NS, name = Name} = El},
|
|||||||
fsm_next_state(wait_for_sasl_response,
|
fsm_next_state(wait_for_sasl_response,
|
||||||
StateData#state{
|
StateData#state{
|
||||||
sasl_state = NewSASLState});
|
sasl_state = NewSASLState});
|
||||||
{error, Error, Username} when is_list(Error) ->
|
{error, Error, Text, Username} ->
|
||||||
?INFO_MSG(
|
?INFO_MSG(
|
||||||
"(~w) Failed authentication for ~s@~s due to ~s",
|
"(~w) Failed authentication for ~s@~s due to ~p ~s",
|
||||||
[StateData#state.socket,
|
[StateData#state.socket,
|
||||||
Username, StateData#state.server, Error]),
|
Username, StateData#state.server, Error, Text]),
|
||||||
send_element(StateData,
|
send_element(StateData,
|
||||||
exmpp_server_sasl:failure(Error)),
|
exmpp_server_sasl:failure(Error, Text)),
|
||||||
{next_state, wait_for_feature_request, StateData,
|
{next_state, wait_for_feature_request, StateData,
|
||||||
?C2S_OPEN_TIMEOUT};
|
?C2S_OPEN_TIMEOUT};
|
||||||
{error, Error} ->
|
{error, Error} ->
|
||||||
@ -834,13 +834,13 @@ wait_for_sasl_response({xmlstreamelement, #xmlel{ns = NS, name = Name} = El},
|
|||||||
exmpp_server_sasl:challenge(ServerOut)),
|
exmpp_server_sasl:challenge(ServerOut)),
|
||||||
fsm_next_state(wait_for_sasl_response,
|
fsm_next_state(wait_for_sasl_response,
|
||||||
StateData#state{sasl_state = NewSASLState});
|
StateData#state{sasl_state = NewSASLState});
|
||||||
{error, Error, Username} ->
|
{error, Error, Text, Username} ->
|
||||||
?INFO_MSG(
|
?INFO_MSG(
|
||||||
"(~w) Failed authentication for ~s@~s",
|
"(~w) Failed authentication for ~s@~s due to ~p ~s",
|
||||||
[StateData#state.socket,
|
[StateData#state.socket,
|
||||||
Username, StateData#state.server]),
|
Username, StateData#state.server, Error, Text]),
|
||||||
send_element(StateData,
|
send_element(StateData,
|
||||||
exmpp_server_sasl:failure(Error)),
|
exmpp_server_sasl:failure(Error, Text)),
|
||||||
fsm_next_state(wait_for_feature_request, StateData);
|
fsm_next_state(wait_for_feature_request, StateData);
|
||||||
{error, Error} ->
|
{error, Error} ->
|
||||||
send_element(StateData,
|
send_element(StateData,
|
||||||
|
Loading…
Reference in New Issue
Block a user