fix(banned): verify delayed/taken over/retained messages against clientid_re rules

This commit is contained in:
Ilya Averyanov 2024-05-09 23:43:37 +03:00
parent e67b078775
commit 78a87ab5a6
8 changed files with 38 additions and 11 deletions

View File

@ -31,6 +31,7 @@
-export([ -export([
check/1, check/1,
check_clientid/1,
create/1, create/1,
look_up/1, look_up/1,
delete/1, delete/1,
@ -114,6 +115,10 @@ check(ClientInfo) ->
do_check({peerhost, maps:get(peerhost, ClientInfo, undefined)}) orelse do_check({peerhost, maps:get(peerhost, ClientInfo, undefined)}) orelse
do_check_rules(ClientInfo). do_check_rules(ClientInfo).
-spec check_clientid(emqx_types:clientid()) -> boolean().
check_clientid(ClientId) ->
do_check({clientid, ClientId}) orelse do_check_rules(#{clientid => ClientId}).
-spec format(emqx_types:banned()) -> map(). -spec format(emqx_types:banned()) -> map().
format(#banned{ format(#banned{
who = Who0, who = Who0,

View File

@ -601,7 +601,7 @@ should_keep(MsgDeliver) ->
not is_banned_msg(MsgDeliver). not is_banned_msg(MsgDeliver).
is_banned_msg(#message{from = ClientId}) -> is_banned_msg(#message{from = ClientId}) ->
[] =/= emqx_banned:look_up({clientid, ClientId}). emqx_banned:check_clientid(ClientId).
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------

View File

@ -112,6 +112,10 @@ t_check(_) ->
?assertNot(emqx_banned:check(ClientInfoValidFull)), ?assertNot(emqx_banned:check(ClientInfoValidFull)),
?assertNot(emqx_banned:check(ClientInfoValidEmpty)), ?assertNot(emqx_banned:check(ClientInfoValidEmpty)),
?assertNot(emqx_banned:check(ClientInfoValidOnlyClientId)), ?assertNot(emqx_banned:check(ClientInfoValidOnlyClientId)),
?assert(emqx_banned:check_clientid(<<"BannedClient">>)),
?assert(emqx_banned:check_clientid(<<"BannedClientRE">>)),
ok = emqx_banned:delete(emqx_banned:who(clientid, <<"BannedClient">>)), ok = emqx_banned:delete(emqx_banned:who(clientid, <<"BannedClient">>)),
ok = emqx_banned:delete(emqx_banned:who(username, <<"BannedUser">>)), ok = emqx_banned:delete(emqx_banned:who(username, <<"BannedUser">>)),
ok = emqx_banned:delete(emqx_banned:who(peerhost, {192, 168, 0, 1})), ok = emqx_banned:delete(emqx_banned:who(peerhost, {192, 168, 0, 1})),
@ -127,6 +131,10 @@ t_check(_) ->
?assertNot(emqx_banned:check(ClientInfoBannedUsernameRE)), ?assertNot(emqx_banned:check(ClientInfoBannedUsernameRE)),
?assertNot(emqx_banned:check(ClientInfoBannedAddrNet)), ?assertNot(emqx_banned:check(ClientInfoBannedAddrNet)),
?assertNot(emqx_banned:check(ClientInfoValidFull)), ?assertNot(emqx_banned:check(ClientInfoValidFull)),
?assertNot(emqx_banned:check_clientid(<<"BannedClient">>)),
?assertNot(emqx_banned:check_clientid(<<"BannedClientRE">>)),
?assertEqual(0, emqx_banned:info(size)). ?assertEqual(0, emqx_banned:info(size)).
t_unused(_) -> t_unused(_) ->

View File

@ -461,10 +461,10 @@ do_publish(Key = {Ts, _Id}, Now, Acc) when Ts =< Now ->
[] -> [] ->
ok; ok;
[#delayed_message{msg = Msg}] -> [#delayed_message{msg = Msg}] ->
case emqx_banned:look_up({clientid, Msg#message.from}) of case emqx_banned:check_clientid(Msg#message.from) of
[] -> false ->
emqx_pool:async_submit(fun emqx:publish/1, [Msg]); emqx_pool:async_submit(fun emqx:publish/1, [Msg]);
_ -> true ->
?tp( ?tp(
notice, notice,
ignore_delayed_message_publish, ignore_delayed_message_publish,

View File

@ -1,7 +1,7 @@
%% -*- mode: erlang -*- %% -*- mode: erlang -*-
{application, emqx_modules, [ {application, emqx_modules, [
{description, "EMQX Modules"}, {description, "EMQX Modules"},
{vsn, "5.0.26"}, {vsn, "5.0.27"},
{modules, []}, {modules, []},
{applications, [kernel, stdlib, emqx, emqx_ctl, observer_cli]}, {applications, [kernel, stdlib, emqx, emqx_ctl, observer_cli]},
{mod, {emqx_modules_app, []}}, {mod, {emqx_modules_app, []}},

View File

@ -215,8 +215,10 @@ t_banned_delayed(_) ->
emqx:update_config([delayed, max_delayed_messages], 10000), emqx:update_config([delayed, max_delayed_messages], 10000),
ClientId1 = <<"bc1">>, ClientId1 = <<"bc1">>,
ClientId2 = <<"bc2">>, ClientId2 = <<"bc2">>,
ClientId3 = <<"bc3">>,
Now = erlang:system_time(second), Now = erlang:system_time(second),
Who = emqx_banned:who(clientid, ClientId2), Who = emqx_banned:who(clientid, ClientId2),
emqx_banned:create(#{ emqx_banned:create(#{
who => Who, who => Who,
@ -225,12 +227,20 @@ t_banned_delayed(_) ->
at => Now, at => Now,
until => Now + 120 until => Now + 120
}), }),
WhoRE = emqx_banned:who(clientid_re, <<"c3">>),
emqx_banned:create(#{
who => WhoRE,
by => <<"test">>,
reason => <<"test">>,
at => Now,
until => Now + 120
}),
snabbkaffe:start_trace(), snabbkaffe:start_trace(),
{ok, SubRef} = {ok, SubRef} =
snabbkaffe:subscribe( snabbkaffe:subscribe(
?match_event(#{?snk_kind := ignore_delayed_message_publish}), ?match_event(#{?snk_kind := ignore_delayed_message_publish}),
_NEvents = 2, _NEvents = 4,
_Timeout = 10000, _Timeout = 10000,
0 0
), ),
@ -240,15 +250,16 @@ t_banned_delayed(_) ->
Msg = emqx_message:make(ClientId, <<"$delayed/1/bc">>, <<"payload">>), Msg = emqx_message:make(ClientId, <<"$delayed/1/bc">>, <<"payload">>),
emqx_delayed:on_message_publish(Msg) emqx_delayed:on_message_publish(Msg)
end, end,
[ClientId1, ClientId1, ClientId1, ClientId2, ClientId2] [ClientId1, ClientId1, ClientId1, ClientId2, ClientId2, ClientId3, ClientId3]
), ),
{ok, Trace} = snabbkaffe:receive_events(SubRef), {ok, Trace} = snabbkaffe:receive_events(SubRef),
snabbkaffe:stop(), snabbkaffe:stop(),
emqx_banned:delete(Who), emqx_banned:delete(Who),
emqx_banned:delete(WhoRE),
mnesia:clear_table(emqx_delayed), mnesia:clear_table(emqx_delayed),
?assertEqual(2, length(?of_kind(ignore_delayed_message_publish, Trace))). ?assertEqual(4, length(?of_kind(ignore_delayed_message_publish, Trace))).
subscribe_proc() -> subscribe_proc() ->
Self = self(), Self = self(),

View File

@ -336,10 +336,10 @@ deliver_in_batches(Msgs, BatchSize, Pid, Topic, Limiter0) ->
deliver_to_client([Msg | T], Pid, Topic) -> deliver_to_client([Msg | T], Pid, Topic) ->
_ = _ =
case emqx_banned:look_up({clientid, Msg#message.from}) of case emqx_banned:check_clientid(Msg#message.from) of
[] -> false ->
Pid ! {deliver, Topic, Msg}; Pid ! {deliver, Topic, Msg};
_ -> true ->
?tp( ?tp(
notice, notice,
ignore_retained_message_deliver, ignore_retained_message_deliver,

View File

@ -0,0 +1,3 @@
Check retained messages, delayed messages and taken over session messages against actual banned client regular expressions.
Previously, messages that were delayed by some reasons, could surpass actual client ID ban specified with regular expression.