%%-------------------------------------------------------------------- %% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %%-------------------------------------------------------------------- -module(emqx_sasl_scram_SUITE). -compile(export_all). -compile(nowarn_export_all). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). init_per_suite(Config) -> emqx_ct_helpers:start_apps([emqx_sasl]), Config. end_per_suite(_Config) -> emqx_ct_helpers:stop_apps([]). all() -> emqx_ct:all(?MODULE). t_crud(_) -> Username = <<"test">>, Password = <<"public">>, Salt = <<"emqx">>, IterationCount = 4096, EncodedSalt = base64:encode(Salt), SaltedPassword = emqx_sasl_scram:pbkdf2_sha_1(Password, Salt, IterationCount), ClientKey = emqx_sasl_scram:client_key(SaltedPassword), ServerKey = base64:encode(emqx_sasl_scram:server_key(SaltedPassword)), StoredKey = base64:encode(crypto:hash(sha, ClientKey)), {error, not_found} = emqx_sasl_scram:lookup(Username), ok = emqx_sasl_scram:add(Username, Password, Salt), {error, already_existed} = emqx_sasl_scram:add(Username, Password, Salt), {ok, #{username := Username, stored_key := StoredKey, server_key := ServerKey, salt := EncodedSalt, iteration_count := IterationCount}} = emqx_sasl_scram:lookup(Username), NewSalt = <<"new salt">>, NewEncodedSalt = base64:encode(NewSalt), emqx_sasl_scram:update(Username, Password, NewSalt), {ok, #{username := Username, salt := NewEncodedSalt}} = emqx_sasl_scram:lookup(Username), emqx_sasl_scram:delete(Username), {error, not_found} = emqx_sasl_scram:lookup(Username). t_scram(_) -> AuthMethod = <<"SCRAM-SHA-1">>, [AuthMethod] = emqx_sasl:supported(), Username = <<"test">>, Password = <<"public">>, Salt = <<"emqx">>, ok = emqx_sasl_scram:add(Username, Password, Salt), ClientFirst = emqx_sasl_scram:make_client_first(Username), {ok, {continue, ServerFirst, Cache}} = emqx_sasl:check(AuthMethod, ClientFirst, #{}), {ok, {continue, ClientFinal, ClientCache}} = emqx_sasl:check(AuthMethod, ServerFirst, #{password => Password, client_first => ClientFirst}), {ok, {ok, ServerFinal, #{}}} = emqx_sasl:check(AuthMethod, ClientFinal, Cache), {ok, _} = emqx_sasl:check(AuthMethod, ServerFinal, ClientCache). %t_proto(_) -> % process_flag(trap_exit, true), % % Username = <<"username">>, % Password = <<"password">>, % Salt = <<"emqx">>, % AuthMethod = <<"SCRAM-SHA-1">>, % % {ok, Client0} = emqtt:start_link([{clean_start, true}, % {proto_ver, v5}, % {enhanced_auth, #{method => AuthMethod, % params => #{username => Username, % password => Password, % salt => Salt}}}, % {connect_timeout, 6000}]), % {error,{not_authorized,#{}}} = emqtt:connect(Client0), % % ok = emqx_sasl_scram:add(Username, Password, Salt), % {ok, Client1} = emqtt:start_link([{clean_start, true}, % {proto_ver, v5}, % {enhanced_auth, #{method => AuthMethod, % params => #{username => Username, % password => Password, % salt => Salt}}}, % {connect_timeout, 6000}]), % {ok, _} = emqtt:connect(Client1), % % timer:sleep(200), % ok = emqtt:reauthentication(Client1, #{params => #{username => Username, % password => Password, % salt => Salt}}), % % timer:sleep(200), % ErrorFun = fun (_State) -> {ok, <<>>, #{}} end, % ok = emqtt:reauthentication(Client1, #{params => #{},function => ErrorFun}), % receive % {disconnected,ReasonCode2,#{}} -> % ?assertEqual(ReasonCode2, 135) % after 500 -> % error("emqx re-authentication failed") % end, % % {ok, Client2} = emqtt:start_link([{clean_start, true}, % {proto_ver, v5}, % {enhanced_auth, #{method => AuthMethod, % params => #{}, % function =>fun (_State) -> {ok, <<>>, #{}} end}}, % {connect_timeout, 6000}]), % {error,{not_authorized,#{}}} = emqtt:connect(Client2), % % receive_msg(), % process_flag(trap_exit, false). receive_msg() -> receive {'EXIT', Msg} -> ct:print("==========+~p~n", [Msg]), receive_msg() after 200 -> ok end.