diff options
-rw-r--r-- | src/cyrsasl.erl | 2 | ||||
-rw-r--r-- | src/cyrsasl_digest.erl | 10 | ||||
-rw-r--r-- | src/cyrsasl_plain.erl | 15 | ||||
-rw-r--r-- | src/ejabberd_auth.erl | 42 | ||||
-rw-r--r-- | src/ejabberd_auth_anonymous.erl | 10 | ||||
-rw-r--r-- | src/ejabberd_auth_external.erl | 54 | ||||
-rw-r--r-- | src/ejabberd_auth_internal.erl | 84 | ||||
-rw-r--r-- | src/ejabberd_auth_ldap.erl | 26 | ||||
-rw-r--r-- | src/ejabberd_auth_odbc.erl | 174 | ||||
-rw-r--r-- | src/ejabberd_auth_pam.erl | 36 | ||||
-rw-r--r-- | src/ejabberd_auth_riak.erl | 78 | ||||
-rw-r--r-- | src/ejabberd_c2s.erl | 28 | ||||
-rw-r--r-- | src/ejabberd_commands.erl | 2 | ||||
-rw-r--r-- | src/ejabberd_web_admin.erl | 2 | ||||
-rw-r--r-- | src/mod_proxy65_stream.erl | 2 | ||||
-rw-r--r-- | src/mod_register_web.erl | 2 |
16 files changed, 306 insertions, 261 deletions
diff --git a/src/cyrsasl.erl b/src/cyrsasl.erl index 764473ba..09b1a1a6 100644 --- a/src/cyrsasl.erl +++ b/src/cyrsasl.erl @@ -128,7 +128,7 @@ register_mechanism(Mechanism, Module, PasswordType) -> %% end. check_credentials(_State, Props) -> - User = proplists:get_value(username, Props, <<>>), + User = proplists:get_value(authzid, Props, <<>>), case jlib:nodeprep(User) of error -> {error, <<"not-authorized">>}; <<"">> -> {error, <<"not-authorized">>}; diff --git a/src/cyrsasl_digest.erl b/src/cyrsasl_digest.erl index be9867ba..12e5555a 100644 --- a/src/cyrsasl_digest.erl +++ b/src/cyrsasl_digest.erl @@ -47,7 +47,7 @@ username = <<"">> :: binary(), authzid = <<"">> :: binary(), get_password = fun(_) -> {false, <<>>} end :: get_password_fun(), - check_password = fun(_, _, _, _) -> false end :: check_password_fun(), + check_password = fun(_, _, _, _, _) -> false end :: check_password_fun(), auth_module :: atom(), host = <<"">> :: binary(), hostfqdn = <<"">> :: binary()}). @@ -95,7 +95,7 @@ mech_step(#state{step = 3, nonce = Nonce} = State, case (State#state.get_password)(UserName) of {false, _} -> {error, <<"not-authorized">>, UserName}; {Passwd, AuthModule} -> - case (State#state.check_password)(UserName, <<"">>, + case (State#state.check_password)(UserName, UserName, <<"">>, proplists:get_value(<<"response">>, KeyVals, <<>>), fun (PW) -> response(KeyVals, @@ -123,7 +123,11 @@ mech_step(#state{step = 5, auth_module = AuthModule, username = UserName, authzid = AuthzId}, <<"">>) -> {ok, - [{username, UserName}, {authzid, AuthzId}, + [{username, UserName}, {authzid, case AuthzId of + <<"">> -> UserName; + _ -> AuthzId + end + }, {auth_module, AuthModule}]}; mech_step(A, B) -> ?DEBUG("SASL DIGEST: A ~p B ~p", [A, B]), diff --git a/src/cyrsasl_plain.erl b/src/cyrsasl_plain.erl index d2fb373e..ceceacca 100644 --- a/src/cyrsasl_plain.erl +++ b/src/cyrsasl_plain.erl @@ -45,7 +45,7 @@ mech_new(_Host, _GetPassword, CheckPassword, _CheckPasswordDigest) -> mech_step(State, ClientIn) -> case prepare(ClientIn) of [AuthzId, User, Password] -> - case (State#state.check_password)(User, Password) of + case (State#state.check_password)(User, AuthzId, Password) of {true, AuthModule} -> {ok, [{username, User}, {authzid, AuthzId}, @@ -60,12 +60,17 @@ prepare(ClientIn) -> [<<"">>, UserMaybeDomain, Password] -> case parse_domain(UserMaybeDomain) of %% <NUL>login@domain<NUL>pwd - [User, _Domain] -> [UserMaybeDomain, User, Password]; + [User, _Domain] -> [User, User, Password]; %% <NUL>login<NUL>pwd - [User] -> [<<"">>, User, Password] + [User] -> [User, User, Password] end; - %% login@domain<NUL>login<NUL>pwd - [AuthzId, User, Password] -> [AuthzId, User, Password]; + [AuthzId, User, Password] -> + case parse_domain(AuthzId) of + %% login@domain<NUL>login<NUL>pwd + [AuthzUser, _Domain] -> [AuthzUser, User, Password]; + %% login<NUL>login<NUL>pwd + [AuthzUser] -> [AuthzUser, User, Password] + end; _ -> error end. diff --git a/src/ejabberd_auth.erl b/src/ejabberd_auth.erl index 991cb664..bf47af85 100644 --- a/src/ejabberd_auth.erl +++ b/src/ejabberd_auth.erl @@ -30,9 +30,9 @@ -author('alexey@process-one.net'). %% External exports --export([start/0, set_password/3, check_password/3, - check_password/5, check_password_with_authmodule/3, - check_password_with_authmodule/5, try_register/3, +-export([start/0, set_password/3, check_password/4, + check_password/6, check_password_with_authmodule/4, + check_password_with_authmodule/6, try_register/3, dirty_get_registered_users/0, get_vh_registered_users/1, get_vh_registered_users/2, export/1, import/1, get_vh_registered_users_number/1, import/3, @@ -61,8 +61,8 @@ -callback remove_user(binary(), binary()) -> any(). -callback remove_user(binary(), binary(), binary()) -> any(). -callback is_user_exists(binary(), binary()) -> boolean() | {error, atom()}. --callback check_password(binary(), binary(), binary()) -> boolean(). --callback check_password(binary(), binary(), binary(), binary(), +-callback check_password(binary(), binary(), binary(), binary()) -> boolean(). +-callback check_password(binary(), binary(), binary(), binary(), binary(), fun((binary()) -> binary())) -> boolean(). -callback try_register(binary(), binary(), binary()) -> {atomic, atom()} | {error, atom()}. @@ -100,10 +100,10 @@ store_type(Server) -> end, plain, auth_modules(Server)). --spec check_password(binary(), binary(), binary()) -> boolean(). +-spec check_password(binary(), binary(), binary(), binary()) -> boolean(). -check_password(User, Server, Password) -> - case check_password_with_authmodule(User, Server, +check_password(User, AuthzId, Server, Password) -> + case check_password_with_authmodule(User, AuthzId, Server, Password) of {true, _AuthModule} -> true; @@ -111,15 +111,15 @@ check_password(User, Server, Password) -> end. %% @doc Check if the user and password can login in server. -%% @spec (User::string(), Server::string(), Password::string(), +%% @spec (User::string(), AuthzId::string(), Server::string(), Password::string(), %% Digest::string(), DigestGen::function()) -> %% true | false --spec check_password(binary(), binary(), binary(), binary(), +-spec check_password(binary(), binary(), binary(), binary(), binary(), fun((binary()) -> binary())) -> boolean(). - -check_password(User, Server, Password, Digest, + +check_password(User, AuthzId, Server, Password, Digest, DigestGen) -> - case check_password_with_authmodule(User, Server, + case check_password_with_authmodule(User, AuthzId, Server, Password, Digest, DigestGen) of {true, _AuthModule} -> true; @@ -130,28 +130,28 @@ check_password(User, Server, Password, Digest, %% 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. -%% @spec (User::string(), Server::string(), Password::string()) -> +%% @spec (User::string(), AuthzId::string(), Server::string(), Password::string()) -> %% {true, AuthModule} | false %% where %% AuthModule = ejabberd_auth_anonymous | ejabberd_auth_external %% | ejabberd_auth_internal | ejabberd_auth_ldap -%% | ejabberd_auth_odbc | ejabberd_auth_pam --spec check_password_with_authmodule(binary(), binary(), binary()) -> false | +%% | ejabberd_auth_odbc | ejabberd_auth_pam | ejabberd_auth_riak +-spec check_password_with_authmodule(binary(), binary(), binary(), binary()) -> false | {true, atom()}. -check_password_with_authmodule(User, Server, +check_password_with_authmodule(User, AuthzId, Server, Password) -> check_password_loop(auth_modules(Server), - [User, Server, Password]). + [User, AuthzId, Server, Password]). --spec check_password_with_authmodule(binary(), binary(), binary(), binary(), +-spec check_password_with_authmodule(binary(), binary(), binary(), binary(), binary(), fun((binary()) -> binary())) -> false | {true, atom()}. -check_password_with_authmodule(User, Server, Password, +check_password_with_authmodule(User, AuthzId, Server, Password, Digest, DigestGen) -> check_password_loop(auth_modules(Server), - [User, Server, Password, Digest, DigestGen]). + [User, AuthzId, Server, Password, Digest, DigestGen]). check_password_loop([], _Args) -> false; check_password_loop([AuthModule | AuthModules], Args) -> diff --git a/src/ejabberd_auth_anonymous.erl b/src/ejabberd_auth_anonymous.erl index cb320dea..05f790db 100644 --- a/src/ejabberd_auth_anonymous.erl +++ b/src/ejabberd_auth_anonymous.erl @@ -38,8 +38,8 @@ %% Function used by ejabberd_auth: --export([login/2, set_password/3, check_password/3, - check_password/5, try_register/3, +-export([login/2, set_password/3, check_password/4, + check_password/6, try_register/3, dirty_get_registered_users/0, get_vh_registered_users/1, get_vh_registered_users/2, get_vh_registered_users_number/1, get_vh_registered_users_number/2, get_password_s/2, @@ -174,11 +174,11 @@ purge_hook(true, LUser, LServer) -> %% When anonymous login is enabled, check the password for permenant users %% before allowing access -check_password(User, Server, Password) -> - check_password(User, Server, Password, undefined, +check_password(User, AuthzId, Server, Password) -> + check_password(User, AuthzId, Server, Password, undefined, undefined). -check_password(User, Server, _Password, _Digest, +check_password(User, _AuthzId, Server, _Password, _Digest, _DigestGen) -> case ejabberd_auth:is_user_exists_in_other_modules(?MODULE, diff --git a/src/ejabberd_auth_external.erl b/src/ejabberd_auth_external.erl index 0aa825f7..44c931cb 100644 --- a/src/ejabberd_auth_external.erl +++ b/src/ejabberd_auth_external.erl @@ -30,8 +30,8 @@ -behaviour(ejabberd_auth). %% External exports --export([start/1, set_password/3, check_password/3, - check_password/5, try_register/3, +-export([start/1, set_password/3, check_password/4, + check_password/6, try_register/3, dirty_get_registered_users/0, get_vh_registered_users/1, get_vh_registered_users/2, get_vh_registered_users_number/1, @@ -75,16 +75,20 @@ plain_password_required() -> true. store_type() -> external. -check_password(User, Server, Password) -> - case get_cache_option(Server) of - false -> check_password_extauth(User, Server, Password); - {true, CacheTime} -> - check_password_cache(User, Server, Password, CacheTime) +check_password(User, AuthzId, Server, Password) -> + if AuthzId /= <<>> andalso AuthzId /= User -> + false; + true -> + case get_cache_option(Server) of + false -> check_password_extauth(User, AuthzId, Server, Password); + {true, CacheTime} -> + check_password_cache(User, AuthzId, Server, Password, CacheTime) + end end. -check_password(User, Server, Password, _Digest, +check_password(User, AuthzId, Server, Password, _Digest, _DigestGen) -> - check_password(User, Server, Password). + check_password(User, AuthzId, Server, Password). set_password(User, Server, Password) -> case extauth:set_password(User, Server, Password) of @@ -177,8 +181,8 @@ get_cache_option(Host) -> CacheTime -> {true, CacheTime} end. -%% @spec (User, Server, Password) -> true | false -check_password_extauth(User, Server, Password) -> +%% @spec (User, AuthzId, Server, Password) -> true | false +check_password_extauth(User, _AuthzId, Server, Password) -> extauth:check_password(User, Server, Password) andalso Password /= <<"">>. @@ -186,35 +190,35 @@ check_password_extauth(User, Server, Password) -> try_register_extauth(User, Server, Password) -> extauth:try_register(User, Server, Password). -check_password_cache(User, Server, Password, 0) -> - check_password_external_cache(User, Server, Password); -check_password_cache(User, Server, Password, +check_password_cache(User, AuthzId, Server, Password, 0) -> + check_password_external_cache(User, AuthzId, Server, Password); +check_password_cache(User, AuthzId, Server, Password, CacheTime) -> case get_last_access(User, Server) of online -> - check_password_internal(User, Server, Password); + check_password_internal(User, AuthzId, Server, Password); never -> - check_password_external_cache(User, Server, Password); + check_password_external_cache(User, AuthzId, Server, Password); mod_last_required -> ?ERROR_MSG("extauth is used, extauth_cache is enabled " "but mod_last is not enabled in that " "host", []), - check_password_external_cache(User, Server, Password); + check_password_external_cache(User, AuthzId, Server, Password); TimeStamp -> case is_fresh_enough(TimeStamp, CacheTime) of %% If no need to refresh, check password against Mnesia true -> - case check_password_internal(User, Server, Password) of + case check_password_internal(User, AuthzId, Server, Password) of %% If password valid in Mnesia, accept it true -> true; %% Else (password nonvalid in Mnesia), check in extauth and cache result false -> - check_password_external_cache(User, Server, Password) + check_password_external_cache(User, AuthzId, Server, Password) end; %% Else (need to refresh), check in extauth and cache result false -> - check_password_external_cache(User, Server, Password) + check_password_external_cache(User, AuthzId, Server, Password) end end. @@ -240,8 +244,8 @@ get_password_cache(User, Server, CacheTime) -> end. %% Check the password using extauth; if success then cache it -check_password_external_cache(User, Server, Password) -> - case check_password_extauth(User, Server, Password) of +check_password_external_cache(User, AuthzId, Server, Password) -> + case check_password_extauth(User, AuthzId, Server, Password) of true -> set_password_internal(User, Server, Password), true; false -> false @@ -255,9 +259,9 @@ try_register_external_cache(User, Server, Password) -> _ -> {error, not_allowed} end. -%% @spec (User, Server, Password) -> true | false -check_password_internal(User, Server, Password) -> - ejabberd_auth_internal:check_password(User, Server, +%% @spec (User, AuthzId, Server, Password) -> true | false +check_password_internal(User, AuthzId, Server, Password) -> + ejabberd_auth_internal:check_password(User, AuthzId, Server, Password). %% @spec (User, Server, Password) -> ok | {error, invalid_jid} diff --git a/src/ejabberd_auth_internal.erl b/src/ejabberd_auth_internal.erl index fc128ac5..bb4ceab5 100644 --- a/src/ejabberd_auth_internal.erl +++ b/src/ejabberd_auth_internal.erl @@ -30,8 +30,8 @@ -behaviour(ejabberd_auth). %% External exports --export([start/1, set_password/3, check_password/3, - check_password/5, try_register/3, +-export([start/1, set_password/3, check_password/4, + check_password/6, try_register/3, dirty_get_registered_users/0, get_vh_registered_users/1, get_vh_registered_users/2, get_vh_registered_users_number/1, @@ -85,45 +85,53 @@ store_type() -> true -> scram %% allows: PLAIN SCRAM end. -check_password(User, Server, Password) -> - LUser = jlib:nodeprep(User), - LServer = jlib:nameprep(Server), - US = {LUser, LServer}, - case catch mnesia:dirty_read({passwd, US}) of - [#passwd{password = Password}] - when is_binary(Password) -> - Password /= <<"">>; - [#passwd{password = Scram}] - when is_record(Scram, scram) -> - is_password_scram_valid(Password, Scram); - _ -> false +check_password(User, AuthzId, Server, Password) -> + if AuthzId /= <<>> andalso AuthzId /= User -> + false; + true -> + LUser = jlib:nodeprep(User), + LServer = jlib:nameprep(Server), + US = {LUser, LServer}, + case catch mnesia:dirty_read({passwd, US}) of + [#passwd{password = Password}] + when is_binary(Password) -> + Password /= <<"">>; + [#passwd{password = Scram}] + when is_record(Scram, scram) -> + is_password_scram_valid(Password, Scram); + _ -> false + end end. -check_password(User, Server, Password, Digest, +check_password(User, AuthzId, Server, Password, Digest, DigestGen) -> - LUser = jlib:nodeprep(User), - LServer = jlib:nameprep(Server), - US = {LUser, LServer}, - case catch mnesia:dirty_read({passwd, US}) of - [#passwd{password = Passwd}] when is_binary(Passwd) -> - DigRes = if Digest /= <<"">> -> - Digest == DigestGen(Passwd); - true -> false - end, - if DigRes -> true; - true -> (Passwd == Password) and (Password /= <<"">>) - end; - [#passwd{password = Scram}] - when is_record(Scram, scram) -> - Passwd = jlib:decode_base64(Scram#scram.storedkey), - DigRes = if Digest /= <<"">> -> - Digest == DigestGen(Passwd); - true -> false - end, - if DigRes -> true; - true -> (Passwd == Password) and (Password /= <<"">>) - end; - _ -> false + if AuthzId /= <<>> andalso AuthzId /= User -> + false; + true -> + LUser = jlib:nodeprep(User), + LServer = jlib:nameprep(Server), + US = {LUser, LServer}, + case catch mnesia:dirty_read({passwd, US}) of + [#passwd{password = Passwd}] when is_binary(Passwd) -> + DigRes = if Digest /= <<"">> -> + Digest == DigestGen(Passwd); + true -> false + end, + if DigRes -> true; + true -> (Passwd == Password) and (Password /= <<"">>) + end; + [#passwd{password = Scram}] + when is_record(Scram, scram) -> + Passwd = jlib:decode_base64(Scram#scram.storedkey), + DigRes = if Digest /= <<"">> -> + Digest == DigestGen(Passwd); + true -> false + end, + if DigRes -> true; + true -> (Passwd == Password) and (Password /= <<"">>) + end; + _ -> false + end end. %% @spec (User::string(), Server::string(), Password::string()) -> diff --git a/src/ejabberd_auth_ldap.erl b/src/ejabberd_auth_ldap.erl index 3055d104..45964d66 100644 --- a/src/ejabberd_auth_ldap.erl +++ b/src/ejabberd_auth_ldap.erl @@ -36,7 +36,7 @@ %% External exports -export([start/1, stop/1, start_link/1, set_password/3, - check_password/3, check_password/5, try_register/3, + check_password/4, check_password/6, try_register/3, dirty_get_registered_users/0, get_vh_registered_users/1, get_vh_registered_users/2, get_vh_registered_users_number/1, @@ -115,19 +115,23 @@ plain_password_required() -> true. store_type() -> external. -check_password(User, Server, Password) -> - if Password == <<"">> -> false; - true -> - case catch check_password_ldap(User, Server, Password) - of - {'EXIT', _} -> false; - Result -> Result - end +check_password(User, AuthzId, Server, Password) -> + if AuthzId /= <<>> andalso AuthzId /= User -> + false; + true -> + if Password == <<"">> -> false; + true -> + case catch check_password_ldap(User, Server, Password) + of + {'EXIT', _} -> false; + Result -> Result + end + end end. -check_password(User, Server, Password, _Digest, +check_password(User, AuthzId, Server, Password, _Digest, _DigestGen) -> - check_password(User, Server, Password). + check_password(User, AuthzId, Server, Password). set_password(User, Server, Password) -> {ok, State} = eldap_utils:get_state(Server, ?MODULE), diff --git a/src/ejabberd_auth_odbc.erl b/src/ejabberd_auth_odbc.erl index 881b86cc..b3bcd369 100644 --- a/src/ejabberd_auth_odbc.erl +++ b/src/ejabberd_auth_odbc.erl @@ -30,8 +30,8 @@ -behaviour(ejabberd_auth). %% External exports --export([start/1, set_password/3, check_password/3, - check_password/5, try_register/3, +-export([start/1, set_password/3, check_password/4, + check_password/6, try_register/3, dirty_get_registered_users/0, get_vh_registered_users/1, get_vh_registered_users/2, get_vh_registered_users_number/1, @@ -63,89 +63,97 @@ store_type() -> true -> scram %% allows: PLAIN SCRAM end. -%% @spec (User, Server, Password) -> true | false | {error, Error} -check_password(User, Server, Password) -> - LServer = jlib:nameprep(Server), - LUser = jlib:nodeprep(User), - if (LUser == error) or (LServer == error) -> - false; - (LUser == <<>>) or (LServer == <<>>) -> - false; - true -> - Username = ejabberd_odbc:escape(LUser), - case is_scrammed() of - true -> - try odbc_queries:get_password_scram(LServer, Username) of - {selected, [<<"password">>, <<"serverkey">>, - <<"salt">>, <<"iterationcount">>], - [[StoredKey, ServerKey, Salt, IterationCount]]} -> - Scram = - #scram{storedkey = StoredKey, - serverkey = ServerKey, - salt = Salt, - iterationcount = jlib:binary_to_integer( - IterationCount)}, - is_password_scram_valid(Password, Scram); - {selected, [<<"password">>, <<"serverkey">>, - <<"salt">>, <<"iterationcount">>], []} -> - false; %% Account does not exist - {error, _Error} -> - false %% Typical error is that table doesn't exist - catch - _:_ -> - false %% Typical error is database not accessible - end; - false -> - try odbc_queries:get_password(LServer, Username) of - {selected, [<<"password">>], [[Password]]} -> - Password /= <<"">>; - {selected, [<<"password">>], [[_Password2]]} -> - false; %% Password is not correct - {selected, [<<"password">>], []} -> - false; %% Account does not exist - {error, _Error} -> - false %% Typical error is that table doesn't exist - catch - _:_ -> - false %% Typical error is database not accessible - end - end +%% @spec (User, AuthzId, Server, Password) -> true | false | {error, Error} +check_password(User, AuthzId, Server, Password) -> + if AuthzId /= <<>> andalso AuthzId /= User -> + false; + true -> + LServer = jlib:nameprep(Server), + LUser = jlib:nodeprep(User), + if (LUser == error) or (LServer == error) -> + false; + (LUser == <<>>) or (LServer == <<>>) -> + false; + true -> + Username = ejabberd_odbc:escape(LUser), + case is_scrammed() of + true -> + try odbc_queries:get_password_scram(LServer, Username) of + {selected, [<<"password">>, <<"serverkey">>, + <<"salt">>, <<"iterationcount">>], + [[StoredKey, ServerKey, Salt, IterationCount]]} -> + Scram = + #scram{storedkey = StoredKey, + serverkey = ServerKey, + salt = Salt, + iterationcount = jlib:binary_to_integer( + IterationCount)}, + is_password_scram_valid(Password, Scram); + {selected, [<<"password">>, <<"serverkey">>, + <<"salt">>, <<"iterationcount">>], []} -> + false; %% Account does not exist + {error, _Error} -> + false %% Typical error is that table doesn't exist + catch + _:_ -> + false %% Typical error is database not accessible + end; + false -> + try odbc_queries:get_password(LServer, Username) of + {selected, [<<"password">>], [[Password]]} -> + Password /= <<"">>; + {selected, [<<"password">>], [[_Password2]]} -> + false; %% Password is not correct + {selected, [<<"password">>], []} -> + false; %% Account does not exist + {error, _Error} -> + false %% Typical error is that table doesn't exist + catch + _:_ -> + false %% Typical error is database not accessible + end + end + end end. -%% @spec (User, Server, Password, Digest, DigestGen) -> true | false | {error, Error} -check_password(User, Server, Password, Digest, +%% @spec (User, AuthzId, Server, Password, Digest, DigestGen) -> true | false | {error, Error} +check_password(User, AuthzId, Server, Password, Digest, DigestGen) -> - LServer = jlib:nameprep(Server), - LUser = jlib:nodeprep(User), - if (LUser == error) or (LServer == error) -> - false; - (LUser == <<>>) or (LServer == <<>>) -> - false; - true -> - case is_scrammed() of - false -> - Username = ejabberd_odbc:escape(LUser), - try odbc_queries:get_password(LServer, Username) of - %% Account exists, check if password is valid - {selected, [<<"password">>], [[Passwd]]} -> - DigRes = if Digest /= <<"">> -> - Digest == DigestGen(Passwd); - true -> false - end, - if DigRes -> true; - true -> (Passwd == Password) and (Password /= <<"">>) - end; - {selected, [<<"password">>], []} -> - false; %% Account does not exist - {error, _Error} -> - false %% Typical error is that table doesn't exist - catch - _:_ -> - false %% Typical error is database not accessible - end; - true -> - false - end + if AuthzId /= <<>> andalso AuthzId /= User -> + false; + true -> + LServer = jlib:nameprep(Server), + LUser = jlib:nodeprep(User), + if (LUser == error) or (LServer == error) -> + false; + (LUser == <<>>) or (LServer == <<>>) -> + false; + true -> + case is_scrammed() of + false -> + Username = ejabberd_odbc:escape(LUser), + try odbc_queries:get_password(LServer, Username) of + %% Account exists, check if password is valid + {selected, [<<"password">>], [[Passwd]]} -> + DigRes = if Digest /= <<"">> -> + Digest == DigestGen(Passwd); + true -> false + end, + if DigRes -> true; + true -> (Passwd == Password) and (Password /= <<"">>) + end; + {selected, [<<"password">>], []} -> + false; %% Account does not exist + {error, _Error} -> + false %% Typical error is that table doesn't exist + catch + _:_ -> + false %% Typical error is database not accessible + end; + true -> + false + end + end end. %% @spec (User::string(), Server::string(), Password::string()) -> @@ -352,7 +360,7 @@ remove_user(User, Server, Password) -> true -> case is_scrammed() of true -> - case check_password(User, Server, Password) of + case check_password(User, <<"">>, Server, Password) of true -> remove_user(User, Server), ok; diff --git a/src/ejabberd_auth_pam.erl b/src/ejabberd_auth_pam.erl index f3fdf628..da893eb4 100644 --- a/src/ejabberd_auth_pam.erl +++ b/src/ejabberd_auth_pam.erl @@ -32,8 +32,8 @@ %%==================================================================== %% API %%==================================================================== --export([start/1, set_password/3, check_password/3, - check_password/5, try_register/3, +-export([start/1, set_password/3, check_password/4, + check_password/6, try_register/3, dirty_get_registered_users/0, get_vh_registered_users/1, get_vh_registered_users/2, get_vh_registered_users_number/1, get_vh_registered_users_number/2, @@ -47,21 +47,25 @@ start(_Host) -> set_password(_User, _Server, _Password) -> {error, not_allowed}. -check_password(User, Server, Password, _Digest, +check_password(User, AuthzId, Server, Password, _Digest, _DigestGen) -> - check_password(User, Server, Password). - -check_password(User, Host, Password) -> - Service = get_pam_service(Host), - UserInfo = case get_pam_userinfotype(Host) of - username -> User; - jid -> <<User/binary, "@", Host/binary>> - end, - case catch epam:authenticate(Service, UserInfo, - Password) - of - true -> true; - _ -> false + check_password(User, AuthzId, Server, Password). + +check_password(User, AuthzId, Host, Password) -> + if AuthzId /= <<>> andalso AuthzId /= User -> + false; + true -> + Service = get_pam_service(Host), + UserInfo = case get_pam_userinfotype(Host) of + username -> User; + jid -> <<User/binary, "@", Host/binary>> + end, + case catch epam:authenticate(Service, UserInfo, + Password) + of + true -> true; + _ -> false + end end. try_register(_User, _Server, _Password) -> diff --git a/src/ejabberd_auth_riak.erl b/src/ejabberd_auth_riak.erl index 3f3484c1..8c926f4b 100644 --- a/src/ejabberd_auth_riak.erl +++ b/src/ejabberd_auth_riak.erl @@ -30,8 +30,8 @@ -behaviour(ejabberd_auth). %% External exports --export([start/1, set_password/3, check_password/3, - check_password/5, try_register/3, +-export([start/1, set_password/3, check_password/4, + check_password/6, try_register/3, dirty_get_registered_users/0, get_vh_registered_users/1, get_vh_registered_users/2, get_vh_registered_users_number/1, @@ -66,42 +66,50 @@ store_type() -> passwd_schema() -> {record_info(fields, passwd), #passwd{}}. -check_password(User, Server, Password) -> - LUser = jlib:nodeprep(User), - LServer = jlib:nameprep(Server), - case ejabberd_riak:get(passwd, passwd_schema(), {LUser, LServer}) of - {ok, #passwd{password = Password}} when is_binary(Password) -> - Password /= <<"">>; - {ok, #passwd{password = Scram}} when is_record(Scram, scram) -> - is_password_scram_valid(Password, Scram); - _ -> - false +check_password(User, AuthzId, Server, Password) -> + if AuthzId /= <<>> andalso AuthzId /= User -> + false; + true -> + LUser = jlib:nodeprep(User), + LServer = jlib:nameprep(Server), + case ejabberd_riak:get(passwd, passwd_schema(), {LUser, LServer}) of + {ok, #passwd{password = Password}} when is_binary(Password) -> + Password /= <<"">>; + {ok, #passwd{password = Scram}} when is_record(Scram, scram) -> + is_password_scram_valid(Password, Scram); + _ -> + false + end end. -check_password(User, Server, Password, Digest, +check_password(User, AuthzId, Server, Password, Digest, DigestGen) -> - LUser = jlib:nodeprep(User), - LServer = jlib:nameprep(Server), - case ejabberd_riak:get(passwd, passwd_schema(), {LUser, LServer}) of - {ok, #passwd{password = Passwd}} when is_binary(Passwd) -> - DigRes = if Digest /= <<"">> -> - Digest == DigestGen(Passwd); - true -> false - end, - if DigRes -> true; - true -> (Passwd == Password) and (Password /= <<"">>) - end; - {ok, #passwd{password = Scram}} - when is_record(Scram, scram) -> - Passwd = jlib:decode_base64(Scram#scram.storedkey), - DigRes = if Digest /= <<"">> -> - Digest == DigestGen(Passwd); - true -> false - end, - if DigRes -> true; - true -> (Passwd == Password) and (Password /= <<"">>) - end; - _ -> false + if AuthzId /= <<>> andalso AuthzId /= User -> + false; + true -> + LUser = jlib:nodeprep(User), + LServer = jlib:nameprep(Server), + case ejabberd_riak:get(passwd, passwd_schema(), {LUser, LServer}) of + {ok, #passwd{password = Passwd}} when is_binary(Passwd) -> + DigRes = if Digest /= <<"">> -> + Digest == DigestGen(Passwd); + true -> false + end, + if DigRes -> true; + true -> (Passwd == Password) and (Password /= <<"">>) + end; + {ok, #passwd{password = Scram}} + when is_record(Scram, scram) -> + Passwd = jlib:decode_base64(Scram#scram.storedkey), + DigRes = if Digest /= <<"">> -> + Digest == DigestGen(Passwd); + true -> false + end, + if DigRes -> true; + true -> (Passwd == Password) and (Password /= <<"">>) + end; + _ -> false + end end. set_password(User, Server, Password) -> diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index f2d16e87..22e17bee 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -397,13 +397,13 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) -> ejabberd_auth:get_password_with_authmodule( U, Server) end, - fun(U, P) -> + fun(U, AuthzId, P) -> ejabberd_auth:check_password_with_authmodule( - U, Server, P) + U, AuthzId, Server, P) end, - fun(U, P, D, DG) -> + fun(U, AuthzId, P, D, DG) -> ejabberd_auth:check_password_with_authmodule( - U, Server, P, D, DG) + U, AuthzId, Server, P, D, DG) end), Mechs = case TLSEnabled or not TLSRequired of @@ -635,7 +635,7 @@ wait_for_auth({xmlstreamelement, El}, StateData) -> DGen = fun (PW) -> p1_sha:sha(<<(StateData#state.streamid)/binary, PW/binary>>) end, - case ejabberd_auth:check_password_with_authmodule(U, + case ejabberd_auth:check_password_with_authmodule(U, U, StateData#state.server, P, D, DGen) of @@ -753,9 +753,7 @@ wait_for_feature_request({xmlstreamelement, El}, of {ok, Props} -> (StateData#state.sockmod):reset_stream(StateData#state.socket), - %U = xml:get_attr_s(username, Props), - U = proplists:get_value(username, Props, <<>>), - %AuthModule = xml:get_attr_s(auth_module, Props), + U = identity(Props), AuthModule = proplists:get_value(auth_module, Props, undefined), ?INFO_MSG("(~w) Accepted authentication for ~s " "by ~p from ~s", @@ -906,9 +904,7 @@ wait_for_sasl_response({xmlstreamelement, El}, {ok, Props} -> catch (StateData#state.sockmod):reset_stream(StateData#state.socket), -% U = xml:get_attr_s(username, Props), - U = proplists:get_value(username, Props, <<>>), -% AuthModule = xml:get_attr_s(auth_module, Props), + U = identity(Props), AuthModule = proplists:get_value(auth_module, Props, <<>>), ?INFO_MSG("(~w) Accepted authentication for ~s " "by ~p from ~s", @@ -929,9 +925,7 @@ wait_for_sasl_response({xmlstreamelement, El}, user = U}); {ok, Props, ServerOut} -> (StateData#state.sockmod):reset_stream(StateData#state.socket), -% U = xml:get_attr_s(username, Props), - U = proplists:get_value(username, Props, <<>>), -% AuthModule = xml:get_attr_s(auth_module, Props), + U = identity(Props), AuthModule = proplists:get_value(auth_module, Props, undefined), ?INFO_MSG("(~w) Accepted authentication for ~s " "by ~p from ~s", @@ -3126,3 +3120,9 @@ pack_string(String, Pack) -> transform_listen_option(Opt, Opts) -> [Opt|Opts]. + +identity(Props) -> + case proplists:get_value(authzid, Props, <<>>) of + <<>> -> proplists:get_value(username, Props, <<>>); + AuthzId -> AuthzId + end. diff --git a/src/ejabberd_commands.erl b/src/ejabberd_commands.erl index a4f38e83..ca40d5dc 100644 --- a/src/ejabberd_commands.erl +++ b/src/ejabberd_commands.erl @@ -397,7 +397,7 @@ check_auth(noauth) -> no_auth_provided; check_auth({User, Server, Password}) -> %% Check the account exists and password is valid - case ejabberd_auth:check_password(User, Server, Password) of + case ejabberd_auth:check_password(User, <<"">>, Server, Password) of true -> {ok, User, Server}; _ -> throw({error, invalid_account_data}) end. diff --git a/src/ejabberd_web_admin.erl b/src/ejabberd_web_admin.erl index 29ecb734..7cf15210 100644 --- a/src/ejabberd_web_admin.erl +++ b/src/ejabberd_web_admin.erl @@ -263,7 +263,7 @@ get_auth_admin(Auth, HostHTTP, RPath, Method) -> get_auth_account(HostOfRule, AccessRule, User, Server, Pass) -> - case ejabberd_auth:check_password(User, Server, Pass) of + case ejabberd_auth:check_password(User, <<"">>, Server, Pass) of true -> case is_acl_match(HostOfRule, AccessRule, jlib:make_jid(User, Server, <<"">>)) diff --git a/src/mod_proxy65_stream.erl b/src/mod_proxy65_stream.erl index 663fbf72..db894de7 100644 --- a/src/mod_proxy65_stream.erl +++ b/src/mod_proxy65_stream.erl @@ -154,7 +154,7 @@ wait_for_auth(Packet, #state{socket = Socket, host = Host} = StateData) -> case mod_proxy65_lib:unpack_auth_request(Packet) of {User, Pass} -> - Result = ejabberd_auth:check_password(User, Host, Pass), + Result = ejabberd_auth:check_password(User, <<"">>, Host, Pass), gen_tcp:send(Socket, mod_proxy65_lib:make_auth_reply(Result)), case Result of diff --git a/src/mod_register_web.erl b/src/mod_register_web.erl index b9f799b4..b415d85e 100644 --- a/src/mod_register_web.erl +++ b/src/mod_register_web.erl @@ -437,7 +437,7 @@ check_account_exists(Username, Host) -> end. check_password(Username, Host, Password) -> - case ejabberd_auth:check_password(Username, Host, + case ejabberd_auth:check_password(Username, <<"">>, Host, Password) of true -> password_correct; |