Explorar o código

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

Ilya Averyanov %!s(int64=2) %!d(string=hai) anos
pai
achega
cba0287439

+ 2 - 0
apps/emqx/src/emqx_channel.erl

@@ -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)).
 

+ 6 - 4
apps/emqx_authn/src/enhanced_authn/emqx_enhanced_authn_scram_mnesia.erl

@@ -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) ->

+ 32 - 2
apps/emqx_authn/test/emqx_enhanced_authn_scram_mnesia_SUITE.erl

@@ -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">>,

+ 1 - 0
changes/ce/fix-10100.en.md

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

+ 1 - 0
changes/ce/fix-10100.zh.md

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