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:
parent
4403b4f5ce
commit
0aeb2cd77f
|
@ -1781,7 +1781,9 @@ mqtt_listener(Bind) ->
|
||||||
hoconsc:array(string()),
|
hoconsc:array(string()),
|
||||||
#{
|
#{
|
||||||
desc => ?DESC(mqtt_listener_access_rules),
|
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",
|
{"proxy_protocol",
|
||||||
|
@ -1802,6 +1804,48 @@ mqtt_listener(Bind) ->
|
||||||
)}
|
)}
|
||||||
] ++ emqx_schema_hooks:injection_point('mqtt.listener').
|
] ++ 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) ->
|
base_listener(Bind) ->
|
||||||
[
|
[
|
||||||
{"enable",
|
{"enable",
|
||||||
|
|
Loading…
Reference in New Issue