fix: ensure tls option keys

This commit is contained in:
Zhongwen Deng 2022-04-29 09:52:37 +08:00
parent 352984efe7
commit e91d6f9806
2 changed files with 41 additions and 16 deletions

View File

@ -285,23 +285,19 @@ ensure_ssl_files(_Dir, #{<<"enable">> := False} = Opts, _DryRun) when ?IS_FALSE(
ensure_ssl_files(_Dir, #{enable := False} = Opts, _DryRun) when ?IS_FALSE(False) -> ensure_ssl_files(_Dir, #{enable := False} = Opts, _DryRun) when ?IS_FALSE(False) ->
{ok, Opts}; {ok, Opts};
ensure_ssl_files(Dir, Opts, DryRun) -> ensure_ssl_files(Dir, Opts, DryRun) ->
case ensure_ssl_files(Dir, Opts, ?SSL_FILE_OPT_NAMES_A, DryRun) of case ensure_ssl_file_key(Opts) of
{ok, NewOpts} -> {ok, Keys} -> ensure_ssl_files(Dir, Opts, Keys, DryRun);
{ok, NewOpts}; {error, _} = Error -> Error
{error, #{reason := file_path_or_pem_string_not_found}} ->
ensure_ssl_files(Dir, Opts, ?SSL_FILE_OPT_NAMES, DryRun);
{error, Reason} ->
{error, Reason}
end. end.
ensure_ssl_files(_Dir, Opts, [], _DryRun) -> ensure_ssl_files(_Dir, Opts, [], _DryRun) ->
{ok, Opts}; {ok, Opts};
ensure_ssl_files(Dir, Opts, [Key | Keys], DryRun) -> ensure_ssl_files(Dir, Opts, [Key | Keys], DryRun) ->
case ensure_ssl_file(Dir, Key, Opts, maps:find(Key, Opts), DryRun) of case ensure_ssl_file(Dir, Key, Opts, maps:get(Key, Opts), DryRun) of
{ok, NewOpts} -> {ok, NewOpts} ->
ensure_ssl_files(Dir, NewOpts, Keys, DryRun); ensure_ssl_files(Dir, NewOpts, Keys, DryRun);
{error, Reason} -> {error, Reason} ->
{error, Reason#{which_option => Key}} {error, Reason#{which_options => [Key]}}
end. end.
%% @doc Compare old and new config, delete the ones in old but not in new. %% @doc Compare old and new config, delete the ones in old but not in new.
@ -336,9 +332,7 @@ delete_old_file(_New, Old) ->
?SLOG(error, #{msg => "failed_to_delete_ssl_file", file_path => Old, reason => Reason}) ?SLOG(error, #{msg => "failed_to_delete_ssl_file", file_path => Old, reason => Reason})
end. end.
ensure_ssl_file(_Dir, _Key, _Opts, error, _DryRun) -> ensure_ssl_file(Dir, Key, Opts, MaybePem, DryRun) ->
{error, #{reason => file_path_or_pem_string_not_found}};
ensure_ssl_file(Dir, Key, Opts, {ok, MaybePem}, DryRun) ->
case is_valid_string(MaybePem) of case is_valid_string(MaybePem) of
true -> true ->
do_ensure_ssl_file(Dir, Key, Opts, MaybePem, DryRun); do_ensure_ssl_file(Dir, Key, Opts, MaybePem, DryRun);
@ -524,6 +518,23 @@ ensure_str(B) when is_binary(B) -> unicode:characters_to_list(B, utf8).
ensure_bin(B) when is_binary(B) -> B; ensure_bin(B) when is_binary(B) -> B;
ensure_bin(A) when is_atom(A) -> atom_to_binary(A, utf8). ensure_bin(A) when is_atom(A) -> atom_to_binary(A, utf8).
ensure_ssl_file_key(Opts) ->
Filter = fun(Key) -> not maps:is_key(Key, Opts) end,
case lists:filter(Filter, ?SSL_FILE_OPT_NAMES) of
[] ->
{ok, ?SSL_FILE_OPT_NAMES};
?SSL_FILE_OPT_NAMES ->
case lists:filter(Filter, ?SSL_FILE_OPT_NAMES_A) of
[] -> {ok, ?SSL_FILE_OPT_NAMES_A};
Miss2 -> not_found_key_error(Miss2)
end;
Miss1 ->
not_found_key_error(Miss1)
end.
not_found_key_error(Keys) ->
{error, #{reason => ssl_file_option_not_found, which_options => Keys}}.
-if(?OTP_RELEASE > 22). -if(?OTP_RELEASE > 22).
-ifdef(TEST). -ifdef(TEST).
-include_lib("eunit/include/eunit.hrl"). -include_lib("eunit/include/eunit.hrl").

View File

@ -96,19 +96,33 @@ ssl_files_failure_test_() ->
), ),
?assertMatch( ?assertMatch(
{error, #{file_read := enoent, pem_check := invalid_pem}}, {error, #{file_read := enoent, pem_check := invalid_pem}},
emqx_tls_lib:ensure_ssl_files("/tmp", #{<<"keyfile">> => NonExistingFile}) emqx_tls_lib:ensure_ssl_files("/tmp", #{
<<"keyfile">> => NonExistingFile,
<<"certfile">> => bin(test_key()),
<<"cacertfile">> => bin(test_key())
})
) )
end}, end},
{"bad_pem_string", fun() -> {"bad_pem_string", fun() ->
%% not valid unicode %% not valid unicode
?assertMatch( ?assertMatch(
{error, #{reason := invalid_file_path_or_pem_string, which_option := <<"keyfile">>}}, {error, #{
emqx_tls_lib:ensure_ssl_files("/tmp", #{<<"keyfile">> => <<255, 255>>}) reason := invalid_file_path_or_pem_string, which_options := [<<"keyfile">>]
}},
emqx_tls_lib:ensure_ssl_files("/tmp", #{
<<"keyfile">> => <<255, 255>>,
<<"certfile">> => bin(test_key()),
<<"cacertfile">> => bin(test_key())
})
), ),
%% not printable %% not printable
?assertMatch( ?assertMatch(
{error, #{reason := invalid_file_path_or_pem_string}}, {error, #{reason := invalid_file_path_or_pem_string}},
emqx_tls_lib:ensure_ssl_files("/tmp", #{<<"keyfile">> => <<33, 22>>}) emqx_tls_lib:ensure_ssl_files("/tmp", #{
<<"keyfile">> => <<33, 22>>,
<<"certfile">> => bin(test_key()),
<<"cacertfile">> => bin(test_key())
})
), ),
TmpFile = filename:join("/tmp", integer_to_list(erlang:system_time(microsecond))), TmpFile = filename:join("/tmp", integer_to_list(erlang:system_time(microsecond))),
try try