fix: listener crash if access_rules config option is incorrect

Previously when changing the access_rules configuration option of a
listener to something that was not a valid rule, the listener would
crash. This has now been fixed by the addition of a configuration
validator that checks the access_rules field.

Additionally, a configuration option converter has been added to the
access_rules field so that one can specify several rules in a single
string by using "," (comma) as separator.

Fixes:
https://emqx.atlassian.net/browse/EMQX-12315
This commit is contained in:
Kjell Winblad 2024-05-10 12:27:04 +02:00
parent 4403b4f5ce
commit 0aeb2cd77f
1 changed files with 45 additions and 1 deletions

View File

@ -1781,7 +1781,9 @@ mqtt_listener(Bind) ->
hoconsc:array(string()),
#{
desc => ?DESC(mqtt_listener_access_rules),
default => [<<"allow all">>]
default => [<<"allow all">>],
converter => fun access_rules_converter/1,
validator => fun access_rules_validator/1
}
)},
{"proxy_protocol",
@ -1802,6 +1804,48 @@ mqtt_listener(Bind) ->
)}
] ++ emqx_schema_hooks:injection_point('mqtt.listener').
access_rules_converter(AccessRules) ->
DeepRules =
lists:foldr(
fun(Rule, Acc) ->
Rules = re:split(Rule, <<"\\s*,\\s*">>, [{return, binary}]),
[Rules | Acc]
end,
[],
AccessRules
),
[unicode:characters_to_list(RuleBin) || RuleBin <- lists:flatten(DeepRules)].
access_rules_validator(AccessRules) ->
InvalidRules = [Rule || Rule <- AccessRules, is_invalid_rule(Rule)],
case InvalidRules of
[] ->
ok;
_ ->
MsgStr = io_lib:format("invalid_rule(s): ~ts", [string:join(InvalidRules, ", ")]),
MsgBin = unicode:characters_to_binary(MsgStr),
{error, MsgBin}
end.
is_invalid_rule(S) ->
try
[Action, CIDR] = string:tokens(S, " "),
case Action of
"allow" -> ok;
"deny" -> ok
end,
case CIDR of
"all" ->
ok;
_ ->
%% should not crash
_ = esockd_cidr:parse(CIDR, true)
end,
false
catch
_:_ -> true
end.
base_listener(Bind) ->
[
{"enable",