diff --git a/apps/emqx/src/emqx_channel.erl b/apps/emqx/src/emqx_channel.erl index e82adc786..9acad4d57 100644 --- a/apps/emqx/src/emqx_channel.erl +++ b/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)). diff --git a/apps/emqx_authn/src/enhanced_authn/emqx_enhanced_authn_scram_mnesia.erl b/apps/emqx_authn/src/enhanced_authn/emqx_enhanced_authn_scram_mnesia.erl index 6ce59d4f9..84f2c9525 100644 --- a/apps/emqx_authn/src/enhanced_authn/emqx_enhanced_authn_scram_mnesia.erl +++ b/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) -> diff --git a/apps/emqx_authn/test/emqx_enhanced_authn_scram_mnesia_SUITE.erl b/apps/emqx_authn/test/emqx_enhanced_authn_scram_mnesia_SUITE.erl index b143903b5..f52e895cc 100644 --- a/apps/emqx_authn/test/emqx_enhanced_authn_scram_mnesia_SUITE.erl +++ b/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">>, diff --git a/changes/ce/fix-10100.en.md b/changes/ce/fix-10100.en.md new file mode 100644 index 000000000..002fb6f08 --- /dev/null +++ b/changes/ce/fix-10100.en.md @@ -0,0 +1 @@ +Fix channel crash for slow clients with enhanced authentication. diff --git a/changes/ce/fix-10100.zh.md b/changes/ce/fix-10100.zh.md new file mode 100644 index 000000000..6adb5e7e1 --- /dev/null +++ b/changes/ce/fix-10100.zh.md @@ -0,0 +1 @@ +修复响应较慢的客户端在使用增强认证时可能出现崩溃的问题。