Migration of scram passwords with piefxis (riak and internal only)

This commit is contained in:
Feotov Daniil 2015-02-05 18:44:08 +03:00
parent ed502673f4
commit eb52c118d0
3 changed files with 65 additions and 6 deletions

View File

@ -151,7 +151,10 @@ set_password(User, Server, Password) ->
try_register(User, Server, PasswordList) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
Password = iolist_to_binary(PasswordList),
Password = if is_list(PasswordList); is_binary(PasswordList) ->
iolist_to_binary(PasswordList);
true -> PasswordList
end,
US = {LUser, LServer},
if (LUser == error) or (LServer == error) ->
{error, invalid_jid};

View File

@ -125,7 +125,10 @@ set_password(User, Server, Password) ->
try_register(User, Server, PasswordList) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
Password = iolist_to_binary(PasswordList),
Password = if is_list(PasswordList); is_binary(PasswordList) ->
iolist_to_binary(PasswordList);
true -> PasswordList
end,
US = {LUser, LServer},
if (LUser == error) or (LServer == error) ->
{error, invalid_jid};

View File

@ -238,7 +238,17 @@ export_users([], _Server, _Fd) ->
%%%==================================
%%%% Utilities
export_user(User, Server, Fd) ->
Pass = ejabberd_auth:get_password_s(User, Server),
Password = ejabberd_auth:get_password_s(User, Server),
LServer = jlib:nameprep(Server),
PasswordFormat = ejabberd_config:get_option({auth_password_format, LServer}, fun(X) -> X end, plain),
Pass = case Password of
{_,_,_,_} ->
case PasswordFormat of
scram -> format_scram_password(Password);
_ -> <<"">>
end;
_ -> Password
end,
Els = get_offline(User, Server) ++
get_vcard(User, Server) ++
get_privacy(User, Server) ++
@ -250,6 +260,23 @@ export_user(User, Server, Fd) ->
{<<"password">>, Pass}],
children = Els})).
format_scram_password({StoredKey, ServerKey, Salt, IterationCount}) ->
StoredKeyB64 = base64:encode(StoredKey),
ServerKeyB64 = base64:encode(ServerKey),
SaltB64 = base64:encode(Salt),
IterationCountBin = list_to_binary(integer_to_list(IterationCount)),
<<"scram:", StoredKeyB64/binary, ",", ServerKeyB64/binary, ",", SaltB64/binary, ",", IterationCountBin/binary>>.
parse_scram_password(PassData) ->
Split = binary:split(PassData, <<",">>, [global]),
[StoredKeyB64, ServerKeyB64, SaltB64, IterationCountBin] = Split,
#scram{
storedkey = StoredKeyB64,
serverkey = ServerKeyB64,
salt = SaltB64,
iterationcount = list_to_integer(binary_to_list(IterationCountBin))
}.
get_vcard(User, Server) ->
JID = jlib:make_jid(User, Server, <<>>),
case mod_vcard:process_sm_iq(JID, JID, #iq{type = get}) of
@ -457,7 +484,18 @@ process_users([], State) ->
process_user(#xmlel{name = <<"user">>, attrs = Attrs, children = Els},
#state{server = LServer} = State) ->
Name = xml:get_attr_s(<<"name">>, Attrs),
Pass = xml:get_attr_s(<<"password">>, Attrs),
Password = xml:get_attr_s(<<"password">>, Attrs),
PasswordFormat = ejabberd_config:get_option({auth_password_format, LServer}, fun(X) -> X end, plain),
Pass = case PasswordFormat of
scram ->
case Password of
<<"scram:", PassData/binary>> ->
parse_scram_password(PassData);
P -> P
end;
_ -> Password
end,
case jlib:nodeprep(Name) of
error ->
stop("Invalid 'user': ~s", [Name]);
@ -541,8 +579,23 @@ process_privacy(El, State = #state{user = U, server = S}) ->
JID = jlib:make_jid(U, S, <<"">>),
case mod_privacy:process_iq_set(
[], JID, JID, #iq{type = set, sub_el = El}) of
{error, _} = Err ->
stop("Failed to write privacy: ~p", [Err]);
{error, Error} = Err ->
#xmlel{children = Els} = El,
Name = case xml:remove_cdata(Els) of
[#xmlel{name = N}] -> N;
_ -> undefined
end,
#xmlel{attrs = Attrs} = Error,
ErrorCode = case lists:keysearch(<<"code">>, 1, Attrs) of
{value, {_, V}} -> V;
false -> undefined
end,
if
ErrorCode == <<"404">>, Name == <<"default">> ->
{ok, State};
true ->
stop("Failed to write privacy: ~p", [Err])
end;
_ ->
{ok, State}
end.