From 4047617ed0b31235135e5d0186f17a17106b00b4 Mon Sep 17 00:00:00 2001 From: Shawn <506895667@qq.com> Date: Thu, 21 Apr 2022 12:13:25 +0800 Subject: [PATCH] fix: only delete SSL files generated by us --- apps/emqx/src/emqx_tls_lib.erl | 24 +++++++++++++++++++++--- apps/emqx/test/emqx_tls_lib_tests.erl | 16 ++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/apps/emqx/src/emqx_tls_lib.erl b/apps/emqx/src/emqx_tls_lib.erl index ebb258840..ffa13194f 100644 --- a/apps/emqx/src/emqx_tls_lib.erl +++ b/apps/emqx/src/emqx_tls_lib.erl @@ -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) -> <> = 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]) || <> <= Bin]). diff --git a/apps/emqx/test/emqx_tls_lib_tests.erl b/apps/emqx/test/emqx_tls_lib_tests.erl index ca0dfa553..fb441e4db 100644 --- a/apps/emqx/test/emqx_tls_lib_tests.erl +++ b/apps/emqx/test/emqx_tls_lib_tests.erl @@ -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())},