diff options
-rw-r--r-- | src/cyrsasl_plain.erl | 2 | ||||
-rw-r--r-- | src/ejabberd_auth.erl | 32 | ||||
-rw-r--r-- | src/ejabberd_c2s.erl | 20 |
3 files changed, 37 insertions, 17 deletions
diff --git a/src/cyrsasl_plain.erl b/src/cyrsasl_plain.erl index 5759f7202..76bf08eee 100644 --- a/src/cyrsasl_plain.erl +++ b/src/cyrsasl_plain.erl @@ -72,6 +72,8 @@ mech_step(State, ClientIn) -> {true, AuthModule} -> {ok, [{username, User}, {authzid, AuthzId}, {auth_module, AuthModule}]}; + {false, ReasonAuthFail} when is_list(ReasonAuthFail) -> + {error, ReasonAuthFail, User}; _ -> {error, 'not-authorized', User} end; diff --git a/src/ejabberd_auth.erl b/src/ejabberd_auth.erl index 659c7bbbc..1662b5400 100644 --- a/src/ejabberd_auth.erl +++ b/src/ejabberd_auth.erl @@ -117,7 +117,7 @@ check_password(User, Server, Password) when is_list(User), is_list(Server), is_list(Password) -> case check_password_with_authmodule(User, Server, Password) of {true, _AuthModule} -> true; - false -> false + {false, _Reason} -> false end. %% @spec (User, Server, Password, Digest, DigestGen) -> bool() @@ -134,22 +134,22 @@ check_password(User, Server, Password, Digest, DigestGen) case check_password_with_authmodule(User, Server, Password, Digest, DigestGen) of {true, _AuthModule} -> true; - false -> false + {false, _Reason} -> false end. -%% @spec (User, Server, Password) -> {true, AuthModule} | false -%% User = string() -%% Server = string() -%% Password = string() -%% AuthModule = authmodule() +%% @spec (User::string(), Server::string(), Password::string()) -> +%% {true, AuthModule} | {false, Reason::string()} +%% where +%% AuthModule = ejabberd_auth_anonymous | ejabberd_auth_external +%% | ejabberd_auth_internal | ejabberd_auth_ldap +%% | ejabberd_auth_odbc | ejabberd_auth_pam %% @doc Check if the user and password can login in server. %% The user can login if at least an authentication method accepts the user %% and the password. %% The first authentication method that accepts the credentials is returned. - check_password_with_authmodule(User, Server, Password) when is_list(User), is_list(Server), is_list(Password) -> - check_password_loop(auth_modules(Server), [User, Server, Password]). + check_password_loop(auth_modules(Server), [User, Server, Password], ""). %% @spec (User, Server, Password, Digest, DigestGen) -> {true, AuthModule} | false %% User = string() @@ -167,16 +167,20 @@ check_password_with_authmodule(User, Server, Password, Digest, DigestGen) when is_list(User), is_list(Server), (is_list(Password) orelse Password == 'undefined'), is_function(DigestGen), (is_list(Digest) orelse Digest == 'undefined')-> check_password_loop(auth_modules(Server), [User, Server, Password, - Digest, DigestGen]). + Digest, DigestGen], ""). -check_password_loop([], _Args) -> - false; -check_password_loop([AuthModule | AuthModules], Args) -> +check_password_loop([], _Args, LastReason) -> + {false, LastReason}; +check_password_loop([AuthModule | AuthModules], Args, PreviousReason) -> case apply(AuthModule, check_password, Args) of true -> {true, AuthModule}; + {false, Reason} when Reason /= "" -> + check_password_loop(AuthModules, Args, Reason); + {false, ""} -> + check_password_loop(AuthModules, Args, PreviousReason); false -> - check_password_loop(AuthModules, Args) + check_password_loop(AuthModules, Args, PreviousReason) end. %% @spec (User, Server, Password) -> ok | {error, ErrorType} diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 7ef3ab055..da728989c 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -589,6 +589,20 @@ wait_for_auth({xmlstreamelement, El}, StateData) -> send_element(StateData, Res), fsm_next_state(wait_for_auth, StateData) end; + {false, ReasonAuthFail} when is_list(ReasonAuthFail) -> + ?INFO_MSG( + "(~w) Forbidden legacy authentication for ~s due to ~s", + [StateData#state.socket, + exmpp_jid:to_binary(JID), ReasonAuthFail]), + ErrorType = case ReasonAuthFail of + "not-authorized" -> 'not-authorized'; + "temporary-auth-failure" -> 'internal-server-error'; + _ -> 'not-authorized' + end, + Res = exmpp_iq:error_without_original(El, + ErrorType), + send_element(StateData, Res), + fsm_next_state(wait_for_auth, StateData); _ -> ?INFO_MSG( "(~w) Forbidden legacy authentication for ~s", @@ -663,11 +677,11 @@ wait_for_feature_request({xmlstreamelement, #xmlel{ns = NS, name = Name} = El}, fsm_next_state(wait_for_sasl_response, StateData#state{ sasl_state = NewSASLState}); - {error, Error, Username} -> + {error, Error, Username} when is_list(Error) -> ?INFO_MSG( - "(~w) Failed authentication for ~s@~s", + "(~w) Failed authentication for ~s@~s due to ~s", [StateData#state.socket, - Username, StateData#state.server]), + Username, StateData#state.server, Error]), send_element(StateData, exmpp_server_sasl:failure(Error)), {next_state, wait_for_feature_request, StateData, |