fix(mqtt): fix channel crash for slow clients with enhanced authn

This commit is contained in:
Ilya Averyanov 2023-03-08 21:37:36 +02:00
parent 37c17b120f
commit cba0287439
5 changed files with 42 additions and 6 deletions

View File

@ -224,6 +224,8 @@ set_session(Session, Channel = #channel{conninfo = ConnInfo, clientinfo = Client
Channel#channel{session = Session1}.
-spec stats(channel()) -> emqx_types:stats().
stats(#channel{session = undefined}) ->
emqx_pd:get_counters(?CHANNEL_METRICS);
stats(#channel{session = Session}) ->
lists:append(emqx_session:stats(Session), emqx_pd:get_counters(?CHANNEL_METRICS)).

View File

@ -168,7 +168,7 @@ authenticate(
},
State
) ->
case ensure_auth_method(AuthMethod, State) of
case ensure_auth_method(AuthMethod, AuthData, State) of
true ->
case AuthCache of
#{next_step := client_final} ->
@ -304,11 +304,13 @@ run_fuzzy_filter(
%% Internal functions
%%------------------------------------------------------------------------------
ensure_auth_method(<<"SCRAM-SHA-256">>, #{algorithm := sha256}) ->
ensure_auth_method(_AuthMethod, undefined, _State) ->
false;
ensure_auth_method(<<"SCRAM-SHA-256">>, _AuthData, #{algorithm := sha256}) ->
true;
ensure_auth_method(<<"SCRAM-SHA-512">>, #{algorithm := sha512}) ->
ensure_auth_method(<<"SCRAM-SHA-512">>, _AuthData, #{algorithm := sha512}) ->
true;
ensure_auth_method(_, _) ->
ensure_auth_method(_AuthMethod, _AuthData, _State) ->
false.
check_client_first_message(Bin, _Cache, #{iteration_count := IterationCount} = State) ->

View File

@ -20,6 +20,7 @@
-compile(nowarn_export_all).
-include_lib("eunit/include/eunit.hrl").
-include_lib("common_test/include/ct.hrl").
-include_lib("emqx/include/emqx_mqtt.hrl").
-include("emqx_authn.hrl").
@ -37,9 +38,11 @@ all() ->
init_per_suite(Config) ->
_ = application:load(emqx_conf),
ok = emqx_common_test_helpers:start_apps([emqx_authn]),
Config.
IdleTimeout = emqx_config:get([mqtt, idle_timeout]),
[{idle_timeout, IdleTimeout} | Config].
end_per_suite(_Config) ->
end_per_suite(Config) ->
ok = emqx_config:put([mqtt, idle_timeout], ?config(idle_timeout, Config)),
ok = emqx_common_test_helpers:stop_apps([emqx_authn]).
init_per_testcase(_Case, Config) ->
@ -99,6 +102,8 @@ t_authenticate(_Config) ->
init_auth(Username, Password, Algorithm),
ok = emqx_config:put([mqtt, idle_timeout], 500),
{ok, Pid} = emqx_authn_mqtt_test_client:start_link("127.0.0.1", 1883),
ClientFirstMessage = esasl_scram:client_first_message(Username),
@ -115,6 +120,9 @@ t_authenticate(_Config) ->
ok = emqx_authn_mqtt_test_client:send(Pid, ConnectPacket),
%% Intentional sleep to trigger idle timeout for the connection not yet authenticated
ok = ct:sleep(1000),
?AUTH_PACKET(
?RC_CONTINUE_AUTHENTICATION,
#{'Authentication-Data' := ServerFirstMessage}
@ -150,6 +158,28 @@ t_authenticate(_Config) ->
ServerFinalMessage, ClientCache#{algorithm => Algorithm}
).
t_authenticate_bad_props(_Config) ->
Algorithm = sha512,
Username = <<"u">>,
Password = <<"p">>,
init_auth(Username, Password, Algorithm),
{ok, Pid} = emqx_authn_mqtt_test_client:start_link("127.0.0.1", 1883),
ConnectPacket = ?CONNECT_PACKET(
#mqtt_packet_connect{
proto_ver = ?MQTT_PROTO_V5,
properties = #{
'Authentication-Method' => <<"SCRAM-SHA-512">>
}
}
),
ok = emqx_authn_mqtt_test_client:send(Pid, ConnectPacket),
?CONNACK_PACKET(?RC_NOT_AUTHORIZED) = receive_packet().
t_authenticate_bad_username(_Config) ->
Algorithm = sha512,
Username = <<"u">>,

View File

@ -0,0 +1 @@
Fix channel crash for slow clients with enhanced authentication.

View File

@ -0,0 +1 @@
修复响应较慢的客户端在使用增强认证时可能出现崩溃的问题。