25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-22 16:20:52 +01:00

* src/cyrsasl.erl: Change API of check_password: pass a function

to generate the digest (thanks to Graham Whitted)(EJAB-863)
* src/cyrsasl_anonymous.erl: Likewise
* src/cyrsasl_digest.erl: Likewise
* src/cyrsasl_plain.erl: Likewise
* src/ejabberd_auth.erl: Likewise
* src/ejabberd_auth_anonymous.erl: Likewise
* src/ejabberd_auth_external.erl: Likewise
* src/ejabberd_auth_internal.erl: Likewise
* src/ejabberd_auth_ldap.erl: Likewise
* src/ejabberd_auth_odbc.erl: Likewise
* src/ejabberd_auth_pam.erl: Likewise
* src/ejabberd_c2s.erl: Likewise

SVN Revision: 2033
This commit is contained in:
Badlop 2009-04-22 11:44:03 +00:00
parent 240e37c387
commit 43b59911e2
13 changed files with 79 additions and 52 deletions

View File

@ -1,5 +1,22 @@
2009-04-22 Badlop <badlop@process-one.net> 2009-04-22 Badlop <badlop@process-one.net>
* src/cyrsasl.erl: Change API of check_password: pass a function
to generate the digest (thanks to Graham Whitted)(EJAB-863)
* src/cyrsasl_anonymous.erl: Likewise
* src/cyrsasl_digest.erl: Likewise
* src/cyrsasl_plain.erl: Likewise
* src/ejabberd_auth.erl: Likewise
* src/ejabberd_auth_anonymous.erl: Likewise
* src/ejabberd_auth_external.erl: Likewise
* src/ejabberd_auth_internal.erl: Likewise
* src/ejabberd_auth_ldap.erl: Likewise
* src/ejabberd_auth_odbc.erl: Likewise
* src/ejabberd_auth_pam.erl: Likewise
* src/ejabberd_c2s.erl: Likewise
* src/ejabberd_c2s.erl: Fix for SASL Anonymous connections not
stored or purged (thanks to Andy Skelton)(EJAB-912)
* src/ejabberd_c2s.erl: Fix for SASL Anonymous connections not * src/ejabberd_c2s.erl: Fix for SASL Anonymous connections not
stored or purged (thanks to Andy Skelton)(EJAB-912) stored or purged (thanks to Andy Skelton)(EJAB-912)

View File

@ -30,7 +30,7 @@
-export([start/0, -export([start/0,
register_mechanism/3, register_mechanism/3,
listmech/1, listmech/1,
server_new/6, server_new/7,
server_start/3, server_start/3,
server_step/2]). server_step/2]).
@ -53,7 +53,7 @@
%% State of this process. %% State of this process.
-record(sasl_state, {service, myname, realm, -record(sasl_state, {service, myname, realm,
get_password, check_password, get_password, check_password, check_password_digest,
mech_mod, mech_state}). mech_mod, mech_state}).
-export([behaviour_info/1]). -export([behaviour_info/1]).
@ -61,7 +61,7 @@
%% @hidden %% @hidden
behaviour_info(callbacks) -> behaviour_info(callbacks) ->
[{mech_new, 3}, {mech_step, 2}]; [{mech_new, 4}, {mech_step, 2}];
behaviour_info(_Other) -> behaviour_info(_Other) ->
undefined. undefined.
@ -157,12 +157,13 @@ listmech(Host) ->
%% CheckPassword = function() %% CheckPassword = function()
server_new(Service, ServerFQDN, UserRealm, _SecFlags, server_new(Service, ServerFQDN, UserRealm, _SecFlags,
GetPassword, CheckPassword) -> GetPassword, CheckPassword, CheckPasswordDigest) ->
#sasl_state{service = Service, #sasl_state{service = Service,
myname = ServerFQDN, myname = ServerFQDN,
realm = UserRealm, realm = UserRealm,
get_password = GetPassword, get_password = GetPassword,
check_password = CheckPassword}. check_password = CheckPassword,
check_password_digest= CheckPasswordDigest}.
%% @spec (State, Mech, ClientIn) -> Ok | Continue | Error %% @spec (State, Mech, ClientIn) -> Ok | Continue | Error
%% State = saslstate() %% State = saslstate()
@ -188,7 +189,8 @@ server_start(State, Mech, ClientIn) ->
{ok, MechState} = Module:mech_new( {ok, MechState} = Module:mech_new(
State#sasl_state.myname, State#sasl_state.myname,
State#sasl_state.get_password, State#sasl_state.get_password,
State#sasl_state.check_password), State#sasl_state.check_password,
State#sasl_state.check_password_digest),
server_step(State#sasl_state{mech_mod = Module, server_step(State#sasl_state{mech_mod = Module,
mech_state = MechState}, mech_state = MechState},
ClientIn); ClientIn);

View File

@ -27,7 +27,7 @@
-module(cyrsasl_anonymous). -module(cyrsasl_anonymous).
-export([start/1, stop/0, mech_new/3, mech_step/2]). -export([start/1, stop/0, mech_new/4, mech_step/2]).
-behaviour(cyrsasl). -behaviour(cyrsasl).
@ -48,13 +48,13 @@ start(_Opts) ->
stop() -> stop() ->
ok. ok.
%% @spec (Host, GetPassword, CheckPassword) -> {ok, State} %% @spec (Host, GetPassword, CheckPassword, CheckPasswordDigest) -> {ok, State}
%% Host = string() %% Host = string()
%% GetPassword = function() %% GetPassword = function()
%% CheckPassword = function() %% CheckPassword = function()
%% State = mechstate() %% State = mechstate()
mech_new(Host, _GetPassword, _CheckPassword) -> mech_new(Host, _GetPassword, _CheckPassword, _CheckPasswordDigest) ->
{ok, #state{server = Host}}. {ok, #state{server = Host}}.
%% @spec (State, ClientIn) -> Ok | Error %% @spec (State, ClientIn) -> Ok | Error

View File

@ -11,14 +11,14 @@
-export([start/1, -export([start/1,
stop/0, stop/0,
mech_new/3, mech_new/4,
mech_step/2]). mech_step/2]).
-include("ejabberd.hrl"). -include("ejabberd.hrl").
-behaviour(cyrsasl). -behaviour(cyrsasl).
%% @type mechstate() = {state, Step, Nonce, Username, AuthzId, GetPassword, AuthModule, Host} %% @type mechstate() = {state, Step, Nonce, Username, AuthzId, GetPassword, CheckPassword, AuthModule, Host}
%% Step = 1 | 3 | 5 %% Step = 1 | 3 | 5
%% Nonce = string() %% Nonce = string()
%% Username = string() %% Username = string()
@ -27,7 +27,7 @@
%% AuthModule = atom() %% AuthModule = atom()
%% Host = string(). %% Host = string().
-record(state, {step, nonce, username, authzid, get_password, auth_module, -record(state, {step, nonce, username, authzid, get_password, check_password, auth_module,
host}). host}).
%% @spec (Opts) -> true %% @spec (Opts) -> true
@ -41,17 +41,18 @@ start(_Opts) ->
stop() -> stop() ->
ok. ok.
%% @spec (Host, GetPassword, CheckPassword) -> {ok, State} %% @spec (Host, GetPassword, CheckPassword, CheckPasswordDigest) -> {ok, State}
%% Host = string() %% Host = string()
%% GetPassword = function() %% GetPassword = function()
%% CheckPassword = function() %% CheckPassword = function()
%% State = mechstate() %% State = mechstate()
mech_new(Host, GetPassword, _CheckPassword) -> mech_new(Host, GetPassword, _CheckPassword, CheckPasswordDigest) ->
{ok, #state{step = 1, {ok, #state{step = 1,
nonce = randoms:get_string(), nonce = randoms:get_string(),
host = Host, host = Host,
get_password = GetPassword}}. get_password = GetPassword,
check_password = CheckPasswordDigest}}.
%% @spec (State, ClientIn) -> Ok | Continue | Error %% @spec (State, ClientIn) -> Ok | Continue | Error
%% State = mechstate() %% State = mechstate()
@ -91,10 +92,11 @@ mech_step(#state{step = 3, nonce = Nonce} = State, ClientIn) ->
{false, _} -> {false, _} ->
{error, 'not-authorized', UserName}; {error, 'not-authorized', UserName};
{Passwd, AuthModule} -> {Passwd, AuthModule} ->
Response = response(KeyVals, UserName, Passwd, case (State#state.check_password)(UserName, Passwd,
Nonce, AuthzId, "AUTHENTICATE"), proplists:get_value("response", KeyVals, ""),
case proplists:get_value("response", KeyVals, "") of fun(PW) -> response(KeyVals, UserName, PW, Nonce, AuthzId,
Response -> "AUTHENTICATE") end) of
{true, _} ->
RspAuth = response(KeyVals, RspAuth = response(KeyVals,
UserName, Passwd, UserName, Passwd,
Nonce, AuthzId, ""), Nonce, AuthzId, ""),
@ -104,7 +106,7 @@ mech_step(#state{step = 3, nonce = Nonce} = State, ClientIn) ->
auth_module = AuthModule, auth_module = AuthModule,
username = UserName, username = UserName,
authzid = AuthzId}}; authzid = AuthzId}};
_ -> {false, _} ->
{error, 'not-authorized', UserName} {error, 'not-authorized', UserName}
end end
end end

View File

@ -27,7 +27,7 @@
-module(cyrsasl_plain). -module(cyrsasl_plain).
-author('alexey@process-one.net'). -author('alexey@process-one.net').
-export([start/1, stop/0, mech_new/3, mech_step/2, parse/1]). -export([start/1, stop/0, mech_new/4, mech_step/2, parse/1]).
-behaviour(cyrsasl). -behaviour(cyrsasl).
@ -48,13 +48,13 @@ start(_Opts) ->
stop() -> stop() ->
ok. ok.
%% @spec (Host, GetPassword, CheckPassword) -> {ok, State} %% @spec (Host, GetPassword, CheckPassword, CheckPasswordDigest) -> {ok, State}
%% Host = string() %% Host = string()
%% GetPassword = function() %% GetPassword = function()
%% CheckPassword = function() %% CheckPassword = function()
%% State = mechstate() %% State = mechstate()
mech_new(_Host, _GetPassword, CheckPassword) -> mech_new(_Host, _GetPassword, CheckPassword, _CheckPasswordDigest) ->
{ok, #state{check_password = CheckPassword}}. {ok, #state{check_password = CheckPassword}}.
%% @spec (State, ClientIn) -> Ok | Error %% @spec (State, ClientIn) -> Ok | Error

View File

@ -97,19 +97,19 @@ check_password(User, Server, Password)
false -> false false -> false
end. end.
%% @spec (User, Server, Password, StreamID, Digest) -> bool() %% @spec (User, Server, Password, Digest, DigestGen) -> bool()
%% User = string() %% User = string()
%% Server = string() %% Server = string()
%% Password = string() %% Password = string()
%% StreamID = string()
%% Digest = string() %% Digest = string()
%% DigestGen = function()
%% @doc Check if the user and password can login in server. %% @doc Check if the user and password can login in server.
check_password(User, Server, Password, StreamID, Digest) check_password(User, Server, Password, Digest, DigestGen)
when is_list(User), is_list(Server), is_list(Password), when is_list(User), is_list(Server), is_list(Password),
is_list(StreamID), is_list(Digest) -> is_list(Digest), is_function(DigestGen) ->
case check_password_with_authmodule(User, Server, Password, case check_password_with_authmodule(User, Server, Password,
StreamID, Digest) of Digest, DigestGen) of
{true, _AuthModule} -> true; {true, _AuthModule} -> true;
false -> false false -> false
end. end.
@ -128,22 +128,22 @@ check_password_with_authmodule(User, Server, Password)
when is_list(User), is_list(Server), is_list(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, StreamID, Digest) -> {true, AuthModule} | false %% @spec (User, Server, Password, Digest, DigestGen) -> {true, AuthModule} | false
%% User = string() %% User = string()
%% Server = string() %% Server = string()
%% Password = string() | undefined %% Password = string() | undefined
%% StreamID = string()
%% Digest = string() | undefined %% Digest = string() | undefined
%% DigestGen = function()
%% AuthModule = authmodule() %% AuthModule = authmodule()
%% The password is 'undefined' if the client %% The password is 'undefined' if the client
%% authenticates using the digest method as defined in %% authenticates using the digest method as defined in
%% XEP-0078: Non-SASL Authentication %% XEP-0078: Non-SASL Authentication
check_password_with_authmodule(User, Server, Password, StreamID, Digest) check_password_with_authmodule(User, Server, Password, Digest, DigestGen)
when is_list(User), is_list(Server), (is_list(Password) orelse Password == 'undefined'), when is_list(User), is_list(Server), (is_list(Password) orelse Password == 'undefined'),
is_list(StreamID), (is_list(Digest) orelse Digest == 'undefined')-> is_function(DigestGen), (is_list(Digest) orelse Digest == 'undefined')->
check_password_loop(auth_modules(Server), [User, Server, Password, check_password_loop(auth_modules(Server), [User, Server, Password,
StreamID, Digest]). Digest, DigestGen]).
check_password_loop([], _Args) -> check_password_loop([], _Args) ->
false; false;

View File

@ -229,7 +229,7 @@ purge_hook(true, LUser, LServer) when is_list(LUser), is_list(LServer) ->
check_password(User, Server, Password) -> check_password(User, Server, Password) ->
check_password(User, Server, Password, undefined, undefined). check_password(User, Server, Password, undefined, undefined).
check_password(User, Server, _Password, _StreamID, _Digest) -> check_password(User, Server, _Password, _Digest, _DigestGen) ->
%% We refuse login for registered accounts (They cannot logged but %% We refuse login for registered accounts (They cannot logged but
%% they however are "reserved") %% they however are "reserved")
case ejabberd_auth:is_user_exists_in_other_modules(?MODULE, case ejabberd_auth:is_user_exists_in_other_modules(?MODULE,
@ -310,7 +310,7 @@ get_password(User, Server) ->
%% DefaultValue = string() %% DefaultValue = string()
get_password(User, Server, DefaultValue) -> get_password(User, Server, DefaultValue) ->
case anonymous_user_exist(User, Server) of case anonymous_user_exist(User, Server) or login(User, Server) of
%% We return the default value if the user is anonymous %% We return the default value if the user is anonymous
true -> true ->
DefaultValue; DefaultValue;

View File

@ -68,14 +68,14 @@ plain_password_required() ->
check_password(User, Server, Password) -> check_password(User, Server, Password) ->
extauth:check_password(User, Server, Password) andalso Password /= "". extauth:check_password(User, Server, Password) andalso Password /= "".
%% @spec (User, Server, Password, StreamID, Digest) -> bool() %% @spec (User, Server, Password, Digest, DigestGen) -> bool()
%% User = string() %% User = string()
%% Server = string() %% Server = string()
%% Password = string() %% Password = string()
%% StreamID = string()
%% Digest = string() %% Digest = string()
%% DigestGen = function()
check_password(User, Server, Password, _StreamID, _Digest) -> check_password(User, Server, Password, _Digest, _DigestGen) ->
check_password(User, Server, Password). check_password(User, Server, Password).
%% @spec (User, Server, Password) -> ok | {error, unknown_problem} %% @spec (User, Server, Password) -> ok | {error, unknown_problem}

View File

@ -84,14 +84,14 @@ check_password(User, Server, Password) ->
false false
end. end.
%% @spec (User, Server, Password, StreamID, Digest) -> bool() %% @spec (User, Server, Password, Digest, DigestGen) -> bool()
%% User = string() %% User = string()
%% Server = string() %% Server = string()
%% Password = string() %% Password = string()
%% StreamID = string()
%% Digest = string() %% Digest = string()
%% DigestGen = function()
check_password(User, Server, Password, StreamID, Digest) -> check_password(User, Server, Password, Digest, DigestGen) ->
LUser = exmpp_stringprep:nodeprep(User), LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server), LServer = exmpp_stringprep:nameprep(Server),
US = {LUser, LServer}, US = {LUser, LServer},
@ -99,7 +99,7 @@ check_password(User, Server, Password, StreamID, Digest) ->
[#passwd{password = Passwd}] -> [#passwd{password = Passwd}] ->
DigRes = if DigRes = if
Digest /= "" -> Digest /= "" ->
Digest == sha:sha(StreamID ++ Passwd); Digest == DigestGen(Passwd);
true -> true ->
false false
end, end,

View File

@ -169,14 +169,14 @@ check_password(User, Server, Password) ->
end end
end. end.
%% @spec (User, Server, Password, StreamID, Digest) -> bool() %% @spec (User, Server, Password, Digest, DigestGen) -> bool()
%% User = string() %% User = string()
%% Server = string() %% Server = string()
%% Password = string() %% Password = string()
%% StreamID = string()
%% Digest = string() %% Digest = string()
%% DigestGen = function()
check_password(User, Server, Password, _StreamID, _Digest) -> check_password(User, Server, Password, _Digest, _DigestGen) ->
check_password(User, Server, Password). check_password(User, Server, Password).
%% @spec (User, Server, Password) -> {error, not_allowed} %% @spec (User, Server, Password) -> {error, not_allowed}

View File

@ -91,14 +91,14 @@ check_password(User, Server, Password) ->
false false
end. end.
%% @spec (User, Server, Password, StreamID, Digest) -> bool() %% @spec (User, Server, Password, Digest, DigestGen) -> bool()
%% User = string() %% User = string()
%% Server = string() %% Server = string()
%% Password = string() %% Password = string()
%% StreamID = string()
%% Digest = string() %% Digest = string()
%% DigestGen = function()
check_password(User, Server, Password, StreamID, Digest) -> check_password(User, Server, Password, Digest, DigestGen) ->
try try
LUser = exmpp_stringprep:nodeprep(User), LUser = exmpp_stringprep:nodeprep(User),
Username = ejabberd_odbc:escape(LUser), Username = ejabberd_odbc:escape(LUser),
@ -108,7 +108,7 @@ check_password(User, Server, Password, StreamID, Digest) ->
{selected, ["password"], [{Passwd}]} -> {selected, ["password"], [{Passwd}]} ->
DigRes = if DigRes = if
Digest /= "" -> Digest /= "" ->
Digest == sha:sha(StreamID ++ Passwd); Digest == DigestGen(Passwd);
true -> true ->
false false
end, end,

View File

@ -64,12 +64,12 @@ start(_Host) ->
set_password(_User, _Server, _Password) -> set_password(_User, _Server, _Password) ->
{error, not_allowed}. {error, not_allowed}.
%% @spec (User, Server, Password, StreamID, Digest) -> bool() %% @spec (User, Server, Password, Digest, DigestGen) -> bool()
%% User = string() %% User = string()
%% Server = string() %% Server = string()
%% Password = string() %% Password = string()
%% StreamID = string()
%% Digest = string() %% Digest = string()
%% DigestGen = function()
check_password(User, Server, Password, _StreamID, _Digest) -> check_password(User, Server, Password, _StreamID, _Digest) ->
check_password(User, Server, Password). check_password(User, Server, Password).

View File

@ -257,6 +257,10 @@ wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
fun(U, P) -> fun(U, P) ->
ejabberd_auth:check_password_with_authmodule( ejabberd_auth:check_password_with_authmodule(
U, Server, P) U, Server, P)
end,
fun(U, P, D, DG) ->
ejabberd_auth:check_password_with_authmodule(
U, Server, P, D, DG)
end), end),
SASL_Mechs = [exmpp_server_sasl:feature( SASL_Mechs = [exmpp_server_sasl:feature(
cyrsasl:listmech(Server))], cyrsasl:listmech(Server))],
@ -402,9 +406,11 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
case acl:match_rule(ServerString, case acl:match_rule(ServerString,
StateData#state.access, JID) of StateData#state.access, JID) of
allow -> allow ->
DGen = fun(PW) ->
sha:sha(StateData#state.streamid ++ PW) end,
case ejabberd_auth:check_password_with_authmodule( case ejabberd_auth:check_password_with_authmodule(
U, ServerString, P, U, ServerString, P,
StateData#state.streamid, D) of D, DGen) of
{true, AuthModule} -> {true, AuthModule} ->
?INFO_MSG( ?INFO_MSG(
"(~w) Accepted legacy authentication for ~s by ~s", "(~w) Accepted legacy authentication for ~s by ~s",