25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-24 16:23:40 +01:00

* src/cyrsasl_digest.erl: Check digest-uri in SASL digest

authentication (thanks to Paul Guyot)(EJAB-569)

SVN Revision: 1743
This commit is contained in:
Badlop 2008-12-23 01:02:44 +00:00
parent 74f15f790a
commit af2fa5b5f5
2 changed files with 51 additions and 25 deletions

View File

@ -1,5 +1,8 @@
2008-12-23 Badlop <badlop@process-one.net> 2008-12-23 Badlop <badlop@process-one.net>
* src/cyrsasl_digest.erl: Check digest-uri in SASL digest
authentication (thanks to Paul Guyot)(EJAB-569)
* src/odbc/odbc_queries.erl: Fix removal of private_storage of an * src/odbc/odbc_queries.erl: Fix removal of private_storage of an
account when the account is removed account when the account is removed
@ -7,9 +10,6 @@
account is removed (EJAB-720) account is removed (EJAB-720)
* src/mod_privacy_odbc.erl: Likewise * src/mod_privacy_odbc.erl: Likewise
2008-12-19 Christophe Romain <christophe.romain@process-one.net>
2008-12-19 Christophe Romain <christophe.romain@process-one.net> 2008-12-19 Christophe Romain <christophe.romain@process-one.net>
* src/mod_pubsub/mod_pubsub.erl: Fix send_last_published_item issue * src/mod_pubsub/mod_pubsub.erl: Fix send_last_published_item issue

View File

@ -18,7 +18,8 @@
-behaviour(cyrsasl). -behaviour(cyrsasl).
-record(state, {step, nonce, username, authzid, get_password, auth_module}). -record(state, {step, nonce, username, authzid, get_password, auth_module,
host}).
start(_Opts) -> start(_Opts) ->
cyrsasl:register_mechanism("DIGEST-MD5", ?MODULE, true). cyrsasl:register_mechanism("DIGEST-MD5", ?MODULE, true).
@ -26,9 +27,10 @@ start(_Opts) ->
stop() -> stop() ->
ok. ok.
mech_new(_Host, GetPassword, _CheckPassword) -> mech_new(Host, GetPassword, _CheckPassword) ->
{ok, #state{step = 1, {ok, #state{step = 1,
nonce = randoms:get_string(), nonce = randoms:get_string(),
host = Host,
get_password = GetPassword}}. get_password = GetPassword}}.
mech_step(#state{step = 1, nonce = Nonce} = State, _) -> mech_step(#state{step = 1, nonce = Nonce} = State, _) ->
@ -41,27 +43,35 @@ mech_step(#state{step = 3, nonce = Nonce} = State, ClientIn) ->
bad -> bad ->
{error, "bad-protocol"}; {error, "bad-protocol"};
KeyVals -> KeyVals ->
DigestURI = xml:get_attr_s("digest-uri", KeyVals),
UserName = xml:get_attr_s("username", KeyVals), UserName = xml:get_attr_s("username", KeyVals),
AuthzId = xml:get_attr_s("authzid", KeyVals), case is_digesturi_valid(DigestURI, State#state.host) of
case (State#state.get_password)(UserName) of false ->
{false, _} -> ?DEBUG("User login not authorized because digest-uri "
"seems invalid: ~p", [DigestURI]),
{error, "not-authorized", UserName}; {error, "not-authorized", UserName};
{Passwd, AuthModule} -> true ->
Response = response(KeyVals, UserName, Passwd, AuthzId = xml:get_attr_s("authzid", KeyVals),
Nonce, AuthzId, "AUTHENTICATE"), case (State#state.get_password)(UserName) of
case xml:get_attr_s("response", KeyVals) of {false, _} ->
Response -> {error, "not-authorized", UserName};
RspAuth = response(KeyVals, {Passwd, AuthModule} ->
UserName, Passwd, Response = response(KeyVals, UserName, Passwd,
Nonce, AuthzId, ""), Nonce, AuthzId, "AUTHENTICATE"),
{continue, case xml:get_attr_s("response", KeyVals) of
"rspauth=" ++ RspAuth, Response ->
State#state{step = 5, RspAuth = response(KeyVals,
auth_module = AuthModule, UserName, Passwd,
username = UserName, Nonce, AuthzId, ""),
authzid = AuthzId}}; {continue,
_ -> "rspauth=" ++ RspAuth,
{error, "not-authorized", UserName} State#state{step = 5,
auth_module = AuthModule,
username = UserName,
authzid = AuthzId}};
_ ->
{error, "not-authorized", UserName}
end
end end
end end
end; end;
@ -75,7 +85,6 @@ mech_step(A, B) ->
?DEBUG("SASL DIGEST: A ~p B ~p", [A,B]), ?DEBUG("SASL DIGEST: A ~p B ~p", [A,B]),
{error, "bad-protocol"}. {error, "bad-protocol"}.
parse(S) -> parse(S) ->
parse1(S, "", []). parse1(S, "", []).
@ -118,6 +127,23 @@ parse4([], Key, Val, Ts) ->
parse1([], "", [{Key, lists:reverse(Val)} | Ts]). parse1([], "", [{Key, lists:reverse(Val)} | Ts]).
%% @doc Check if the digest-uri is valid.
%% RFC-2831 allows to provide the IP address in Host,
%% however ejabberd doesn't allow that.
%% If the service (for example jabber.example.org)
%% is provided by several hosts (being one of them server3.example.org),
%% then digest-uri can be like xmpp/server3.example.org/jabber.example.org
%% In that case, ejabberd only checks the service name, not the host.
is_digesturi_valid(DigestURICase, JabberHost) ->
DigestURI = stringprep:tolower(DigestURICase),
case catch string:tokens(DigestURI, "/") of
["xmpp", Host] when Host == JabberHost ->
true;
["xmpp", _Host, ServName] when ServName == JabberHost ->
true;
_ ->
false
end.