refactor(emqx_license): simplify parser errors

prior to this change, badmatch exception may cause the license key
to be dumped in logs
This commit is contained in:
Zaiming (Stone) Shi 2022-02-08 17:57:37 +01:00
parent 774c0a3d7f
commit cd3565d357
5 changed files with 30 additions and 20 deletions

View File

@ -129,6 +129,7 @@ do_update({key, Content}, _Conf) when is_binary(Content); is_list(Content) ->
{ok, _License} ->
#{<<"key">> => Content};
{error, Reason} ->
?SLOG(error, #{msg => "failed_to_parse_license", reason => Reason}),
error(Reason)
end.

View File

@ -98,7 +98,7 @@ max_connections(#{module := Module, data := LicenseData}) ->
%%--------------------------------------------------------------------
do_parse(_Content, _Key, [], Errors) ->
{error, {unknown_format, lists:reverse(Errors)}};
{error, lists:reverse(Errors)};
do_parse(Content, Key, [Module | Modules], Errors) ->
try Module:parse(Content, Key) of
@ -107,7 +107,7 @@ do_parse(Content, Key, [Module | Modules], Errors) ->
{error, Error} ->
do_parse(Content, Key, Modules, [{Module, Error} | Errors])
catch
_Class:Error:_Stk ->
_Class : Error ->
do_parse(Content, Key, Modules, [{Module, Error} | Errors])
end.

View File

@ -24,12 +24,14 @@
%%------------------------------------------------------------------------------
parse(Content, Key) ->
[EncodedPayload, EncodedSignature] = binary:split(Content, <<".">>),
Payload = base64:decode(EncodedPayload),
Signature = base64:decode(EncodedSignature),
case verify_signature(Payload, Signature, Key) of
true -> parse_payload(Payload);
false -> {error, invalid_signature}
case do_parse(Content) of
{ok, {Payload, Signature}} ->
case verify_signature(Payload, Signature, Key) of
true -> parse_payload(Payload);
false -> {error, invalid_signature}
end;
{error, Reason} ->
{error, Reason}
end.
dump(#{type := Type,
@ -67,6 +69,17 @@ max_connections(#{max_connections := MaxConns}) ->
%% Private functions
%%------------------------------------------------------------------------------
do_parse(Content) ->
try
[EncodedPayload, EncodedSignature] = binary:split(Content, <<".">>),
Payload = base64:decode(EncodedPayload),
Signature = base64:decode(EncodedSignature),
{ok, {Payload, Signature}}
catch
_ : _ ->
{error, bad_license_format}
end.
verify_signature(Payload, Signature, Key) ->
RSAPublicKey = public_key:der_decode('RSAPublicKey', Key),
public_key:verify(Payload, ?DIGEST_TYPE, Signature, RSAPublicKey).

View File

@ -68,7 +68,7 @@ t_update_file(_Config) ->
ok = file:write_file("license_with_invalid_content.lic", <<"bad license">>),
?assertMatch(
{error, {unknown_format, _}},
{error, [_ | _]},
emqx_license:update_file("license_with_invalid_content.lic")),
?assertMatch(
@ -77,7 +77,7 @@ t_update_file(_Config) ->
t_update_value(_Config) ->
?assertMatch(
{error, {unknown_format, _}},
{error, [_ | _]},
emqx_license:update_key("invalid.license")),
{ok, LicenseValue} = file:read_file(emqx_license_test_lib:default_license()),

View File

@ -45,8 +45,7 @@ t_parse(_Config) ->
%% invalid version
?assertMatch(
{error,
{unknown_format,
[{emqx_license_parser_v20220101,invalid_version}]}},
[{emqx_license_parser_v20220101,invalid_version}]},
emqx_license_parser:parse(
emqx_license_test_lib:make_license(
["220101",
@ -63,8 +62,7 @@ t_parse(_Config) ->
%% invalid field number
?assertMatch(
{error,
{unknown_format,
[{emqx_license_parser_v20220101,invalid_field_number}]}},
[{emqx_license_parser_v20220101,invalid_field_number}]},
emqx_license_parser:parse(
emqx_license_test_lib:make_license(
["220111",
@ -80,12 +78,11 @@ t_parse(_Config) ->
?assertMatch(
{error,
{unknown_format,
[{emqx_license_parser_v20220101,
[{type,invalid_license_type},
{customer_type,invalid_customer_type},
{date_start,invalid_date},
{days,invalid_int_value}]}]}},
{days,invalid_int_value}]}]},
emqx_license_parser:parse(
emqx_license_test_lib:make_license(
["220111",
@ -125,21 +122,20 @@ t_parse(_Config) ->
?assertMatch(
{error,
{unknown_format,
[{emqx_license_parser_v20220101,invalid_signature}]}},
[{emqx_license_parser_v20220101,invalid_signature}]},
emqx_license_parser:parse(
iolist_to_binary([LicensePart, <<".">>, SignaturePart]),
public_key_encoded())),
%% totally invalid strings as license
?assertMatch(
{error, {unknown_format, _}},
{error, [_ | _]},
emqx_license_parser:parse(
<<"badlicense">>,
public_key_encoded())),
?assertMatch(
{error, {unknown_format, _}},
{error, [_ | _]},
emqx_license_parser:parse(
<<"bad.license">>,
public_key_encoded())).