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:
parent
774c0a3d7f
commit
cd3565d357
|
@ -129,6 +129,7 @@ do_update({key, Content}, _Conf) when is_binary(Content); is_list(Content) ->
|
||||||
{ok, _License} ->
|
{ok, _License} ->
|
||||||
#{<<"key">> => Content};
|
#{<<"key">> => Content};
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
|
?SLOG(error, #{msg => "failed_to_parse_license", reason => Reason}),
|
||||||
error(Reason)
|
error(Reason)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@ max_connections(#{module := Module, data := LicenseData}) ->
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
do_parse(_Content, _Key, [], Errors) ->
|
do_parse(_Content, _Key, [], Errors) ->
|
||||||
{error, {unknown_format, lists:reverse(Errors)}};
|
{error, lists:reverse(Errors)};
|
||||||
|
|
||||||
do_parse(Content, Key, [Module | Modules], Errors) ->
|
do_parse(Content, Key, [Module | Modules], Errors) ->
|
||||||
try Module:parse(Content, Key) of
|
try Module:parse(Content, Key) of
|
||||||
|
@ -107,7 +107,7 @@ do_parse(Content, Key, [Module | Modules], Errors) ->
|
||||||
{error, Error} ->
|
{error, Error} ->
|
||||||
do_parse(Content, Key, Modules, [{Module, Error} | Errors])
|
do_parse(Content, Key, Modules, [{Module, Error} | Errors])
|
||||||
catch
|
catch
|
||||||
_Class:Error:_Stk ->
|
_Class : Error ->
|
||||||
do_parse(Content, Key, Modules, [{Module, Error} | Errors])
|
do_parse(Content, Key, Modules, [{Module, Error} | Errors])
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
|
@ -24,12 +24,14 @@
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
|
|
||||||
parse(Content, Key) ->
|
parse(Content, Key) ->
|
||||||
[EncodedPayload, EncodedSignature] = binary:split(Content, <<".">>),
|
case do_parse(Content) of
|
||||||
Payload = base64:decode(EncodedPayload),
|
{ok, {Payload, Signature}} ->
|
||||||
Signature = base64:decode(EncodedSignature),
|
case verify_signature(Payload, Signature, Key) of
|
||||||
case verify_signature(Payload, Signature, Key) of
|
true -> parse_payload(Payload);
|
||||||
true -> parse_payload(Payload);
|
false -> {error, invalid_signature}
|
||||||
false -> {error, invalid_signature}
|
end;
|
||||||
|
{error, Reason} ->
|
||||||
|
{error, Reason}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
dump(#{type := Type,
|
dump(#{type := Type,
|
||||||
|
@ -67,6 +69,17 @@ max_connections(#{max_connections := MaxConns}) ->
|
||||||
%% Private functions
|
%% 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) ->
|
verify_signature(Payload, Signature, Key) ->
|
||||||
RSAPublicKey = public_key:der_decode('RSAPublicKey', Key),
|
RSAPublicKey = public_key:der_decode('RSAPublicKey', Key),
|
||||||
public_key:verify(Payload, ?DIGEST_TYPE, Signature, RSAPublicKey).
|
public_key:verify(Payload, ?DIGEST_TYPE, Signature, RSAPublicKey).
|
||||||
|
|
|
@ -68,7 +68,7 @@ t_update_file(_Config) ->
|
||||||
|
|
||||||
ok = file:write_file("license_with_invalid_content.lic", <<"bad license">>),
|
ok = file:write_file("license_with_invalid_content.lic", <<"bad license">>),
|
||||||
?assertMatch(
|
?assertMatch(
|
||||||
{error, {unknown_format, _}},
|
{error, [_ | _]},
|
||||||
emqx_license:update_file("license_with_invalid_content.lic")),
|
emqx_license:update_file("license_with_invalid_content.lic")),
|
||||||
|
|
||||||
?assertMatch(
|
?assertMatch(
|
||||||
|
@ -77,7 +77,7 @@ t_update_file(_Config) ->
|
||||||
|
|
||||||
t_update_value(_Config) ->
|
t_update_value(_Config) ->
|
||||||
?assertMatch(
|
?assertMatch(
|
||||||
{error, {unknown_format, _}},
|
{error, [_ | _]},
|
||||||
emqx_license:update_key("invalid.license")),
|
emqx_license:update_key("invalid.license")),
|
||||||
|
|
||||||
{ok, LicenseValue} = file:read_file(emqx_license_test_lib:default_license()),
|
{ok, LicenseValue} = file:read_file(emqx_license_test_lib:default_license()),
|
||||||
|
|
|
@ -45,8 +45,7 @@ t_parse(_Config) ->
|
||||||
%% invalid version
|
%% invalid version
|
||||||
?assertMatch(
|
?assertMatch(
|
||||||
{error,
|
{error,
|
||||||
{unknown_format,
|
[{emqx_license_parser_v20220101,invalid_version}]},
|
||||||
[{emqx_license_parser_v20220101,invalid_version}]}},
|
|
||||||
emqx_license_parser:parse(
|
emqx_license_parser:parse(
|
||||||
emqx_license_test_lib:make_license(
|
emqx_license_test_lib:make_license(
|
||||||
["220101",
|
["220101",
|
||||||
|
@ -63,8 +62,7 @@ t_parse(_Config) ->
|
||||||
%% invalid field number
|
%% invalid field number
|
||||||
?assertMatch(
|
?assertMatch(
|
||||||
{error,
|
{error,
|
||||||
{unknown_format,
|
[{emqx_license_parser_v20220101,invalid_field_number}]},
|
||||||
[{emqx_license_parser_v20220101,invalid_field_number}]}},
|
|
||||||
emqx_license_parser:parse(
|
emqx_license_parser:parse(
|
||||||
emqx_license_test_lib:make_license(
|
emqx_license_test_lib:make_license(
|
||||||
["220111",
|
["220111",
|
||||||
|
@ -80,12 +78,11 @@ t_parse(_Config) ->
|
||||||
|
|
||||||
?assertMatch(
|
?assertMatch(
|
||||||
{error,
|
{error,
|
||||||
{unknown_format,
|
|
||||||
[{emqx_license_parser_v20220101,
|
[{emqx_license_parser_v20220101,
|
||||||
[{type,invalid_license_type},
|
[{type,invalid_license_type},
|
||||||
{customer_type,invalid_customer_type},
|
{customer_type,invalid_customer_type},
|
||||||
{date_start,invalid_date},
|
{date_start,invalid_date},
|
||||||
{days,invalid_int_value}]}]}},
|
{days,invalid_int_value}]}]},
|
||||||
emqx_license_parser:parse(
|
emqx_license_parser:parse(
|
||||||
emqx_license_test_lib:make_license(
|
emqx_license_test_lib:make_license(
|
||||||
["220111",
|
["220111",
|
||||||
|
@ -125,21 +122,20 @@ t_parse(_Config) ->
|
||||||
|
|
||||||
?assertMatch(
|
?assertMatch(
|
||||||
{error,
|
{error,
|
||||||
{unknown_format,
|
[{emqx_license_parser_v20220101,invalid_signature}]},
|
||||||
[{emqx_license_parser_v20220101,invalid_signature}]}},
|
|
||||||
emqx_license_parser:parse(
|
emqx_license_parser:parse(
|
||||||
iolist_to_binary([LicensePart, <<".">>, SignaturePart]),
|
iolist_to_binary([LicensePart, <<".">>, SignaturePart]),
|
||||||
public_key_encoded())),
|
public_key_encoded())),
|
||||||
|
|
||||||
%% totally invalid strings as license
|
%% totally invalid strings as license
|
||||||
?assertMatch(
|
?assertMatch(
|
||||||
{error, {unknown_format, _}},
|
{error, [_ | _]},
|
||||||
emqx_license_parser:parse(
|
emqx_license_parser:parse(
|
||||||
<<"badlicense">>,
|
<<"badlicense">>,
|
||||||
public_key_encoded())),
|
public_key_encoded())),
|
||||||
|
|
||||||
?assertMatch(
|
?assertMatch(
|
||||||
{error, {unknown_format, _}},
|
{error, [_ | _]},
|
||||||
emqx_license_parser:parse(
|
emqx_license_parser:parse(
|
||||||
<<"bad.license">>,
|
<<"bad.license">>,
|
||||||
public_key_encoded())).
|
public_key_encoded())).
|
||||||
|
|
Loading…
Reference in New Issue