Merge remote-tracking branch 'ce/main-v4.3' into merge-main-v4.3-into-v4.4

This commit is contained in:
JianBo He 2022-01-24 15:25:01 +08:00
commit e5fab4df25
5 changed files with 74 additions and 18 deletions

View File

@ -32,27 +32,32 @@
, description/0 , description/0
]). ]).
-export([match_password/3]). -export([ match_password/3
, hash_type/0
]).
init(#{clientid_list := ClientidList, username_list := UsernameList}) -> init(#{clientid_list := ClientidList, username_list := UsernameList}) ->
ok = ekka_mnesia:create_table(?TABLE, [ ok = ekka_mnesia:create_table(?TABLE, [
{disc_copies, [node()]}, {disc_copies, [node()]},
{attributes, record_info(fields, emqx_user)}, {attributes, record_info(fields, emqx_user)},
{storage_properties, [{ets, [{read_concurrency, true}]}]}]), {storage_properties, [{ets, [{read_concurrency, true}]}]}]),
_ = [ add_default_user({{clientid, iolist_to_binary(Clientid)}, iolist_to_binary(Password)}) lists:foreach(fun({Clientid, Password}) ->
|| {Clientid, Password} <- ClientidList], emqx_auth_mnesia_cli:add_default_user(clientid, iolist_to_binary(Clientid), iolist_to_binary(Password))
_ = [ add_default_user({{username, iolist_to_binary(Username)}, iolist_to_binary(Password)}) end, ClientidList),
|| {Username, Password} <- UsernameList],
ok = ekka_mnesia:copy_table(?TABLE, disc_copies).
%% @private lists:foreach(fun({Username, Password}) ->
add_default_user({Login, Password}) when is_tuple(Login) -> emqx_auth_mnesia_cli:add_default_user(username, iolist_to_binary(Username), iolist_to_binary(Password))
emqx_auth_mnesia_cli:force_add_user(Login, Password). end, UsernameList),
ok = ekka_mnesia:copy_table(?TABLE, disc_copies).
-spec(register_metrics() -> ok). -spec(register_metrics() -> ok).
register_metrics() -> register_metrics() ->
lists:foreach(fun emqx_metrics:ensure/1, ?AUTH_METRICS). lists:foreach(fun emqx_metrics:ensure/1, ?AUTH_METRICS).
hash_type() ->
application:get_env(emqx_auth_mnesia, password_hash, sha256).
check(ClientInfo = #{ clientid := Clientid check(ClientInfo = #{ clientid := Clientid
, password := NPassword , password := NPassword
}, AuthResult, #{hash_type := HashType}) -> }, AuthResult, #{hash_type := HashType}) ->

View File

@ -57,9 +57,7 @@ load_auth_hook() ->
UsernameList = application:get_env(?APP, username_list, []), UsernameList = application:get_env(?APP, username_list, []),
ok = emqx_auth_mnesia:init(#{clientid_list => ClientidList, username_list => UsernameList}), ok = emqx_auth_mnesia:init(#{clientid_list => ClientidList, username_list => UsernameList}),
ok = emqx_auth_mnesia:register_metrics(), ok = emqx_auth_mnesia:register_metrics(),
Params = #{ Params = #{hash_type => emqx_auth_mnesia:hash_type()},
hash_type => application:get_env(emqx_auth_mnesia, password_hash, sha256)
},
emqx:hook('client.authenticate', fun emqx_auth_mnesia:check/3, [Params]). emqx:hook('client.authenticate', fun emqx_auth_mnesia:check/3, [Params]).
load_acl_hook() -> load_acl_hook() ->

View File

@ -23,6 +23,7 @@
%% Auth APIs %% Auth APIs
-export([ add_user/2 -export([ add_user/2
, force_add_user/2 , force_add_user/2
, add_default_user/3
, update_user/2 , update_user/2
, remove_user/1 , remove_user/1
, lookup_user/1 , lookup_user/1
@ -57,6 +58,39 @@ insert_user(User = #emqx_user{login = Login}) ->
[_|_] -> mnesia:abort(existed) [_|_] -> mnesia:abort(existed)
end. end.
-spec(add_default_user(clientid | username, tuple(), binary()) -> ok | {error, any()}).
add_default_user(Type, Key, Password) ->
Login = {Type, Key},
case add_user(Login, Password) of
ok -> ok;
{error, existed} ->
NewPwd = encrypted_data(Password),
[#emqx_user{password = OldPwd}] = emqx_auth_mnesia_cli:lookup_user(Login),
HashType = emqx_auth_mnesia:hash_type(),
case emqx_auth_mnesia:match_password(NewPwd, HashType, [OldPwd]) of
true -> ok;
false ->
%% We can't force add default,
%% otherwise passwords that have been updated via HTTP API will be reset after reboot.
TypeCtl =
case Type of
clientid -> clientid;
username -> user
end,
?LOG(warning,
"[Auth Mnesia] auth.client.x.~p=~s's password in the emqx_auth_mnesia.conf\n"
"does not match the password in the database(mnesia).\n"
"1. If you have already changed the password via the HTTP API, this warning has no effect.\n"
"You can remove the warning from emqx_auth_mnesia.conf to resolve the warning.\n"
"2. If you just want to update the password by manually changing the configuration file,\n"
"you need to delete the old user and password using `emqx_ctl ~p delete ~s` first\n"
"the new password in emqx_auth_mnesia.conf can take effect after reboot.",
[Type, Key, TypeCtl, Key]),
ok
end;
Error -> Error
end.
force_add_user(Login, Password) -> force_add_user(Login, Password) ->
User = #emqx_user{ User = #emqx_user{
login = Login, login = Login,
@ -74,7 +108,7 @@ insert_or_update_user(NewPwd, User = #emqx_user{login = Login}) ->
case mnesia:read(?TABLE, Login) of case mnesia:read(?TABLE, Login) of
[] -> mnesia:write(User); [] -> mnesia:write(User);
[#emqx_user{password = Pwd}] -> [#emqx_user{password = Pwd}] ->
case emqx_auth_mnesia:match_password(NewPwd, hash_type(), [Pwd]) of case emqx_auth_mnesia:match_password(NewPwd, emqx_auth_mnesia:hash_type(), [Pwd]) of
true -> ok; true -> ok;
false -> false ->
ok = mnesia:write(User), ok = mnesia:write(User),
@ -136,7 +170,7 @@ ret({atomic, Res}) -> Res;
ret({aborted, Error}) -> {error, Error}. ret({aborted, Error}) -> {error, Error}.
encrypted_data(Password) -> encrypted_data(Password) ->
HashType = hash_type(), HashType = emqx_auth_mnesia:hash_type(),
SaltBin = salt(), SaltBin = salt(),
<<SaltBin/binary, (hash(Password, SaltBin, HashType))/binary>>. <<SaltBin/binary, (hash(Password, SaltBin, HashType))/binary>>.
@ -219,5 +253,3 @@ auth_username_cli(_) ->
{"user add <Username> <Password>", "Add username auth rule"}, {"user add <Username> <Password>", "Add username auth rule"},
{"user update <Username> <NewPassword>", "Update username auth rule"}, {"user update <Username> <NewPassword>", "Update username auth rule"},
{"user delete <Username>", "Delete username auth rule"}]). {"user delete <Username>", "Delete username auth rule"}]).
hash_type() ->
application:get_env(emqx_auth_mnesia, password_hash, sha256).

View File

@ -103,6 +103,17 @@ t_boot(_Config) ->
%% change default pwd %% change default pwd
NewPwd = <<"emqx654321">>, NewPwd = <<"emqx654321">>,
ok = emqx_ct_helpers:start_apps([emqx_auth_mnesia],
fun(_) -> set_default(ClientId, UserName, NewPwd, sha256) end),
?assertEqual(Failed,
emqx_auth_mnesia:check(#{clientid => ClientId, password => NewPwd},
#{}, #{hash_type => sha256})),
?assertEqual(Failed,
emqx_auth_mnesia:check(#{clientid => <<"NotExited">>, username => UserName, password => NewPwd},
#{}, #{hash_type => sha256})),
clean_all_users(),
emqx_ct_helpers:stop_apps([emqx_auth_mnesia]),
ok = emqx_ct_helpers:start_apps([emqx_auth_mnesia], ok = emqx_ct_helpers:start_apps([emqx_auth_mnesia],
fun(_) -> set_default(ClientId, UserName, NewPwd, sha256) end), fun(_) -> set_default(ClientId, UserName, NewPwd, sha256) end),
?assertEqual(Ok, ?assertEqual(Ok,
@ -115,6 +126,17 @@ t_boot(_Config) ->
%% change hash_type %% change hash_type
NewPwd2 = <<"emqx6543210">>, NewPwd2 = <<"emqx6543210">>,
ok = emqx_ct_helpers:start_apps([emqx_auth_mnesia],
fun(_) -> set_default(ClientId, UserName, NewPwd2, plain) end),
?assertEqual(Failed,
emqx_auth_mnesia:check(#{clientid => ClientId, password => NewPwd2},
#{}, #{hash_type => plain})),
?assertEqual(Failed,
emqx_auth_mnesia:check(#{clientid => <<"NotExited">>, username => UserName, password => NewPwd2},
#{}, #{hash_type => plain})),
clean_all_users(),
emqx_ct_helpers:stop_apps([emqx_auth_mnesia]),
ok = emqx_ct_helpers:start_apps([emqx_auth_mnesia], ok = emqx_ct_helpers:start_apps([emqx_auth_mnesia],
fun(_) -> set_default(ClientId, UserName, NewPwd2, plain) end), fun(_) -> set_default(ClientId, UserName, NewPwd2, plain) end),
?assertEqual(Ok, ?assertEqual(Ok,

View File

@ -98,8 +98,7 @@ add_meta(Params, List) ->
page => Page, page => Page,
limit => Limit, limit => Limit,
hasnext => Start + Limit - 1 < Count, hasnext => Start + Limit - 1 < Count,
count => Count count => Count},
},
data => Data, data => Data,
code => 0 code => 0
}. }.