mirror of
https://github.com/processone/ejabberd.git
synced 2024-06-02 21:17:12 +02:00
Apply SASLprep before storing/converting passwords
Fixes #996 and #1295
This commit is contained in:
parent
67c9de6461
commit
fd885d0818
|
@ -143,9 +143,12 @@ check_password(User, AuthzId, Server, Password, Digest,
|
||||||
set_password(User, Server, Password) ->
|
set_password(User, Server, Password) ->
|
||||||
LUser = jid:nodeprep(User),
|
LUser = jid:nodeprep(User),
|
||||||
LServer = jid:nameprep(Server),
|
LServer = jid:nameprep(Server),
|
||||||
|
LPassword = jid:resourceprep(Password),
|
||||||
US = {LUser, LServer},
|
US = {LUser, LServer},
|
||||||
if (LUser == error) or (LServer == error) ->
|
if (LUser == error) or (LServer == error) ->
|
||||||
{error, invalid_jid};
|
{error, invalid_jid};
|
||||||
|
LPassword == error ->
|
||||||
|
{error, invalid_password};
|
||||||
true ->
|
true ->
|
||||||
F = fun () ->
|
F = fun () ->
|
||||||
Password2 = case is_scrammed() and is_binary(Password)
|
Password2 = case is_scrammed() and is_binary(Password)
|
||||||
|
@ -167,9 +170,12 @@ try_register(User, Server, PasswordList) ->
|
||||||
iolist_to_binary(PasswordList);
|
iolist_to_binary(PasswordList);
|
||||||
true -> PasswordList
|
true -> PasswordList
|
||||||
end,
|
end,
|
||||||
|
LPassword = jid:resourceprep(Password),
|
||||||
US = {LUser, LServer},
|
US = {LUser, LServer},
|
||||||
if (LUser == error) or (LServer == error) ->
|
if (LUser == error) or (LServer == error) ->
|
||||||
{error, invalid_jid};
|
{error, invalid_jid};
|
||||||
|
LPassword == error ->
|
||||||
|
{error, invalid_password};
|
||||||
true ->
|
true ->
|
||||||
F = fun () ->
|
F = fun () ->
|
||||||
case mnesia:read({passwd, US}) of
|
case mnesia:read({passwd, US}) of
|
||||||
|
@ -441,9 +447,21 @@ scram_passwords() ->
|
||||||
?INFO_MSG("Converting the stored passwords into "
|
?INFO_MSG("Converting the stored passwords into "
|
||||||
"SCRAM bits",
|
"SCRAM bits",
|
||||||
[]),
|
[]),
|
||||||
Fun = fun (#passwd{password = Password} = P) ->
|
Fun = fun (#passwd{us = {U, S}, password = Password} = P)
|
||||||
|
when is_binary(Password) ->
|
||||||
|
case jid:resourceprep(Password) of
|
||||||
|
error ->
|
||||||
|
?ERROR_MSG(
|
||||||
|
"SASLprep failed for "
|
||||||
|
"password of user ~s@~s",
|
||||||
|
[U, S]),
|
||||||
|
P;
|
||||||
|
_ ->
|
||||||
Scram = password_to_scram(Password),
|
Scram = password_to_scram(Password),
|
||||||
P#passwd{password = Scram}
|
P#passwd{password = Scram}
|
||||||
|
end;
|
||||||
|
(P) ->
|
||||||
|
P
|
||||||
end,
|
end,
|
||||||
Fields = record_info(fields, passwd),
|
Fields = record_info(fields, passwd),
|
||||||
mnesia:transform_table(passwd, Fun, Fields).
|
mnesia:transform_table(passwd, Fun, Fields).
|
||||||
|
@ -465,13 +483,18 @@ password_to_scram(Password, IterationCount) ->
|
||||||
iterationcount = IterationCount}.
|
iterationcount = IterationCount}.
|
||||||
|
|
||||||
is_password_scram_valid(Password, Scram) ->
|
is_password_scram_valid(Password, Scram) ->
|
||||||
|
case jid:resourceprep(Password) of
|
||||||
|
error ->
|
||||||
|
false;
|
||||||
|
_ ->
|
||||||
IterationCount = Scram#scram.iterationcount,
|
IterationCount = Scram#scram.iterationcount,
|
||||||
Salt = jlib:decode_base64(Scram#scram.salt),
|
Salt = jlib:decode_base64(Scram#scram.salt),
|
||||||
SaltedPassword = scram:salted_password(Password, Salt,
|
SaltedPassword = scram:salted_password(Password, Salt,
|
||||||
IterationCount),
|
IterationCount),
|
||||||
StoredKey =
|
StoredKey =
|
||||||
scram:stored_key(scram:client_key(SaltedPassword)),
|
scram:stored_key(scram:client_key(SaltedPassword)),
|
||||||
jlib:decode_base64(Scram#scram.storedkey) == StoredKey.
|
jlib:decode_base64(Scram#scram.storedkey) == StoredKey
|
||||||
|
end.
|
||||||
|
|
||||||
export(_Server) ->
|
export(_Server) ->
|
||||||
[{passwd,
|
[{passwd,
|
||||||
|
|
|
@ -120,9 +120,12 @@ check_password(User, AuthzId, Server, Password, Digest,
|
||||||
set_password(User, Server, Password) ->
|
set_password(User, Server, Password) ->
|
||||||
LUser = jid:nodeprep(User),
|
LUser = jid:nodeprep(User),
|
||||||
LServer = jid:nameprep(Server),
|
LServer = jid:nameprep(Server),
|
||||||
|
LPassword = jid:resourceprep(Password),
|
||||||
US = {LUser, LServer},
|
US = {LUser, LServer},
|
||||||
if (LUser == error) or (LServer == error) ->
|
if (LUser == error) or (LServer == error) ->
|
||||||
{error, invalid_jid};
|
{error, invalid_jid};
|
||||||
|
LPassword == error ->
|
||||||
|
{error, invalid_password};
|
||||||
true ->
|
true ->
|
||||||
Password2 = case is_scrammed() and is_binary(Password)
|
Password2 = case is_scrammed() and is_binary(Password)
|
||||||
of
|
of
|
||||||
|
@ -141,9 +144,12 @@ try_register(User, Server, PasswordList) ->
|
||||||
iolist_to_binary(PasswordList);
|
iolist_to_binary(PasswordList);
|
||||||
true -> PasswordList
|
true -> PasswordList
|
||||||
end,
|
end,
|
||||||
|
LPassword = jid:resourceprep(Password),
|
||||||
US = {LUser, LServer},
|
US = {LUser, LServer},
|
||||||
if (LUser == error) or (LServer == error) ->
|
if (LUser == error) or (LServer == error) ->
|
||||||
{error, invalid_jid};
|
{error, invalid_jid};
|
||||||
|
LPassword == error ->
|
||||||
|
{error, invalid_password};
|
||||||
true ->
|
true ->
|
||||||
case ejabberd_riak:get(passwd, passwd_schema(), US) of
|
case ejabberd_riak:get(passwd, passwd_schema(), US) of
|
||||||
{error, notfound} ->
|
{error, notfound} ->
|
||||||
|
@ -284,13 +290,18 @@ password_to_scram(Password, IterationCount) ->
|
||||||
iterationcount = IterationCount}.
|
iterationcount = IterationCount}.
|
||||||
|
|
||||||
is_password_scram_valid(Password, Scram) ->
|
is_password_scram_valid(Password, Scram) ->
|
||||||
|
case jid:resourceprep(Password) of
|
||||||
|
error ->
|
||||||
|
false;
|
||||||
|
_ ->
|
||||||
IterationCount = Scram#scram.iterationcount,
|
IterationCount = Scram#scram.iterationcount,
|
||||||
Salt = jlib:decode_base64(Scram#scram.salt),
|
Salt = jlib:decode_base64(Scram#scram.salt),
|
||||||
SaltedPassword = scram:salted_password(Password, Salt,
|
SaltedPassword = scram:salted_password(Password, Salt,
|
||||||
IterationCount),
|
IterationCount),
|
||||||
StoredKey =
|
StoredKey =
|
||||||
scram:stored_key(scram:client_key(SaltedPassword)),
|
scram:stored_key(scram:client_key(SaltedPassword)),
|
||||||
jlib:decode_base64(Scram#scram.storedkey) == StoredKey.
|
jlib:decode_base64(Scram#scram.storedkey) == StoredKey
|
||||||
|
end.
|
||||||
|
|
||||||
export(_Server) ->
|
export(_Server) ->
|
||||||
[{passwd,
|
[{passwd,
|
||||||
|
|
|
@ -159,10 +159,13 @@ check_password(User, AuthzId, Server, Password, Digest,
|
||||||
set_password(User, Server, Password) ->
|
set_password(User, Server, Password) ->
|
||||||
LServer = jid:nameprep(Server),
|
LServer = jid:nameprep(Server),
|
||||||
LUser = jid:nodeprep(User),
|
LUser = jid:nodeprep(User),
|
||||||
|
LPassword = jid:resourceprep(Password),
|
||||||
if (LUser == error) or (LServer == error) ->
|
if (LUser == error) or (LServer == error) ->
|
||||||
{error, invalid_jid};
|
{error, invalid_jid};
|
||||||
(LUser == <<>>) or (LServer == <<>>) ->
|
(LUser == <<>>) or (LServer == <<>>) ->
|
||||||
{error, invalid_jid};
|
{error, invalid_jid};
|
||||||
|
LPassword == error ->
|
||||||
|
{error, invalid_password};
|
||||||
true ->
|
true ->
|
||||||
case is_scrammed() of
|
case is_scrammed() of
|
||||||
true ->
|
true ->
|
||||||
|
@ -193,10 +196,13 @@ set_password(User, Server, Password) ->
|
||||||
try_register(User, Server, Password) ->
|
try_register(User, Server, Password) ->
|
||||||
LServer = jid:nameprep(Server),
|
LServer = jid:nameprep(Server),
|
||||||
LUser = jid:nodeprep(User),
|
LUser = jid:nodeprep(User),
|
||||||
|
LPassword = jid:resourceprep(Password),
|
||||||
if (LUser == error) or (LServer == error) ->
|
if (LUser == error) or (LServer == error) ->
|
||||||
{error, invalid_jid};
|
{error, invalid_jid};
|
||||||
(LUser == <<>>) or (LServer == <<>>) ->
|
(LUser == <<>>) or (LServer == <<>>) ->
|
||||||
{error, invalid_jid};
|
{error, invalid_jid};
|
||||||
|
LPassword == error ->
|
||||||
|
{error, invalid_password};
|
||||||
true ->
|
true ->
|
||||||
case is_scrammed() of
|
case is_scrammed() of
|
||||||
true ->
|
true ->
|
||||||
|
@ -427,13 +433,18 @@ is_password_scram_valid_stored(Password, Scram, _, _) ->
|
||||||
is_password_scram_valid(Password, Scram).
|
is_password_scram_valid(Password, Scram).
|
||||||
|
|
||||||
is_password_scram_valid(Password, Scram) ->
|
is_password_scram_valid(Password, Scram) ->
|
||||||
|
case jid:resourceprep(Password) of
|
||||||
|
error ->
|
||||||
|
false;
|
||||||
|
_ ->
|
||||||
IterationCount = Scram#scram.iterationcount,
|
IterationCount = Scram#scram.iterationcount,
|
||||||
Salt = jlib:decode_base64(Scram#scram.salt),
|
Salt = jlib:decode_base64(Scram#scram.salt),
|
||||||
SaltedPassword = scram:salted_password(Password, Salt,
|
SaltedPassword = scram:salted_password(Password, Salt,
|
||||||
IterationCount),
|
IterationCount),
|
||||||
StoredKey =
|
StoredKey =
|
||||||
scram:stored_key(scram:client_key(SaltedPassword)),
|
scram:stored_key(scram:client_key(SaltedPassword)),
|
||||||
jlib:decode_base64(Scram#scram.storedkey) == StoredKey.
|
jlib:decode_base64(Scram#scram.storedkey) == StoredKey
|
||||||
|
end.
|
||||||
|
|
||||||
-define(BATCH_SIZE, 1000).
|
-define(BATCH_SIZE, 1000).
|
||||||
|
|
||||||
|
@ -466,14 +477,21 @@ convert_to_scram(Server) ->
|
||||||
{selected, Rs} ->
|
{selected, Rs} ->
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun({LUser, Password}) ->
|
fun({LUser, Password}) ->
|
||||||
|
case jid:resourceprep(Password) of
|
||||||
|
error ->
|
||||||
|
?ERROR_MSG(
|
||||||
|
"SASLprep failed for "
|
||||||
|
"password of user ~s@~s",
|
||||||
|
[LUser, LServer]);
|
||||||
|
_ ->
|
||||||
Scram = password_to_scram(Password),
|
Scram = password_to_scram(Password),
|
||||||
set_password_scram_t(
|
set_password_scram_t(
|
||||||
LUser,
|
LUser,
|
||||||
Scram#scram.storedkey,
|
Scram#scram.storedkey,
|
||||||
Scram#scram.serverkey,
|
Scram#scram.serverkey,
|
||||||
Scram#scram.salt,
|
Scram#scram.salt,
|
||||||
Scram#scram.iterationcount
|
Scram#scram.iterationcount)
|
||||||
)
|
end
|
||||||
end, Rs),
|
end, Rs),
|
||||||
continue;
|
continue;
|
||||||
Err -> {bad_reply, Err}
|
Err -> {bad_reply, Err}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user