fix: only delete SSL files generated by us

This commit is contained in:
Shawn 2022-04-21 12:13:25 +08:00
parent 19630e9a99
commit 4047617ed0
2 changed files with 37 additions and 3 deletions

View File

@ -319,11 +319,10 @@ delete_old_file(New, Old) when New =:= Old -> ok;
delete_old_file(_New, _Old = undefined) ->
ok;
delete_old_file(_New, Old) ->
case filelib:is_regular(Old) andalso file:delete(Old) of
case is_generated_file(Old) andalso filelib:is_regular(Old) andalso file:delete(Old) of
ok ->
ok;
%% already deleted
false ->
false -> %% the file is not generated by us, or it is already deleted
ok;
{error, Reason} ->
?SLOG(error, #{msg => "failed_to_delete_ssl_file", file_path => Old, reason => Reason})
@ -397,6 +396,12 @@ save_pem_file(Dir, Key, Pem, DryRun) ->
%% the filename is prefixed by the option name without the 'file' part
%% and suffixed with the first 8 byets the PEM content's md5 checksum.
%% e.g. key-1234567890abcdef, cert-1234567890abcdef, and cacert-1234567890abcdef
is_generated_file(Filename) ->
case string:split(filename:basename(Filename), "-") of
[_Name, Suffix] -> is_hex_str(Suffix);
_ -> false
end.
pem_file_name(Dir, Key, Pem) ->
<<CK:8/binary, _/binary>> = crypto:hash(md5, Pem),
Suffix = hex_str(CK),
@ -406,6 +411,19 @@ pem_file_name(Dir, Key, Pem) ->
pem_dir(Dir) ->
filename:join([emqx:mutable_certs_dir(), Dir]).
is_hex_str(HexStr) ->
try is_hex_str2(ensure_str(HexStr))
catch throw: not_hex -> false
end.
is_hex_str2(HexStr) ->
_ = [case S of
S when S >= $0, S =< $9 -> S;
S when S >= $a, S =< $f -> S;
_ -> throw(not_hex)
end || S <- HexStr],
true.
hex_str(Bin) ->
iolist_to_binary([io_lib:format("~2.16.0b", [X]) || <<X:8>> <= Bin]).

View File

@ -143,6 +143,22 @@ ssl_files_save_delete_test() ->
ok = emqx_tls_lib:delete_ssl_files(Dir, undefined, SSL),
ok.
ssl_files_handle_non_generated_file_test() ->
TmpKeyFile = <<"my-key-file.pem">>,
KeyFileContent = bin(test_key()),
ok = file:write_file(TmpKeyFile, KeyFileContent),
?assert(filelib:is_regular(TmpKeyFile)),
SSL0 = #{<<"keyfile">> => TmpKeyFile},
Dir = filename:join(["/tmp", "ssl-test-dir-00"]),
{ok, SSL2} = emqx_tls_lib:ensure_ssl_files(Dir, SSL0),
File1 = maps:get(<<"keyfile">>, SSL2),
%% verify the filename and path is not changed by the emqx_tls_lib
?assertEqual(TmpKeyFile, File1),
ok = emqx_tls_lib:delete_ssl_files(Dir, undefined, SSL2),
%% verify the file is not delete and not changed, because it is not generated by
%% emqx_tls_lib
?assertEqual({ok, KeyFileContent}, file:read_file(TmpKeyFile)).
ssl_file_replace_test() ->
SSL0 = #{<<"keyfile">> => bin(test_key())},
SSL1 = #{<<"keyfile">> => bin(test_key2())},