Просмотр исходного кода

feat: ensure_ssl_files/2,3 which respects given dir

- May fail due to file/path permissions issues
JimMoen 1 год назад
Родитель
Сommit
7dc5c0a257
1 измененных файлов с 24 добавлено и 8 удалено
  1. 24 8
      apps/emqx/src/emqx_tls_lib.erl

+ 24 - 8
apps/emqx/src/emqx_tls_lib.erl

@@ -31,6 +31,8 @@
 -export([
     ensure_ssl_files_in_mutable_certs_dir/2,
     ensure_ssl_files_in_mutable_certs_dir/3,
+    ensure_ssl_files/2,
+    ensure_ssl_files/3,
     drop_invalid_certs/1,
     ssl_file_conf_keypaths/0,
     pem_dir/1,
@@ -326,6 +328,13 @@ ensure_ssl_files_in_mutable_certs_dir(_Dir, #{enable := False} = SSL, _Opts) whe
 ->
     {ok, SSL};
 ensure_ssl_files_in_mutable_certs_dir(Dir, SSL, Opts) ->
+    %% NOTE:
+    %% Pass Raw Dir to keep the file name hash consistent with the previous version
+    ensure_ssl_files(pem_dir(Dir), SSL, Opts#{raw_dir => Dir}).
+
+ensure_ssl_files(Dir, SSL) ->
+    ensure_ssl_files(Dir, SSL, #{dry_run => false, required_keys => [], raw_dir => Dir}).
+ensure_ssl_files(Dir, SSL, Opts) ->
     RequiredKeys = maps:get(required_keys, Opts, []),
     case ensure_ssl_file_key(SSL, RequiredKeys) of
         ok ->
@@ -360,15 +369,22 @@ ensure_ssl_file(Dir, KeyPath, SSL, MaybePem, Opts) ->
     case is_valid_string(MaybePem) of
         true ->
             DryRun = maps:get(dry_run, Opts, false),
-            do_ensure_ssl_file(Dir, KeyPath, SSL, MaybePem, DryRun);
+            RawDir = maps:get(raw_dir, Opts, Dir),
+            do_ensure_ssl_file({Dir, RawDir}, KeyPath, SSL, MaybePem, DryRun);
         false ->
             {error, #{reason => invalid_file_path_or_pem_string}}
     end.
 
-do_ensure_ssl_file(Dir, KeyPath, SSL, MaybePem, DryRun) ->
+do_ensure_ssl_file(Dir, KeyPath, SSL, MaybePem, DryRun) when not is_tuple(Dir) ->
+    %% {Dir, RawDir} = {Dir, Dir}
+    %% for backward compatibility
+    %% when RawDir is not given, it is the same as Dir
+    %% to keep the file name hash consistent with the previous version (Depends on RawDir)
+    do_ensure_ssl_file({Dir, Dir}, KeyPath, SSL, MaybePem, DryRun);
+do_ensure_ssl_file({Dir, RawDir}, KeyPath, SSL, MaybePem, DryRun) ->
     case is_pem(MaybePem) of
         true ->
-            case save_pem_file(Dir, KeyPath, MaybePem, DryRun) of
+            case save_pem_file(Dir, RawDir, KeyPath, MaybePem, DryRun) of
                 {ok, Path} ->
                     NewSSL = emqx_utils_maps:deep_put(KeyPath, SSL, Path),
                     {ok, NewSSL};
@@ -414,8 +430,8 @@ is_pem(MaybePem) ->
 %% To make it simple, the file is always overwritten.
 %% Also a potentially half-written PEM file (e.g. due to power outage)
 %% can be corrected with an overwrite.
-save_pem_file(Dir, KeyPath, Pem, DryRun) ->
-    Path = pem_file_name(Dir, KeyPath, Pem),
+save_pem_file(Dir, RawDir, KeyPath, Pem, DryRun) ->
+    Path = pem_file_path(Dir, RawDir, KeyPath, Pem),
     case filelib:ensure_dir(Path) of
         ok when DryRun ->
             {ok, Path};
@@ -438,16 +454,16 @@ is_managed_ssl_file(Filename) ->
         _ -> false
     end.
 
-pem_file_name(Dir, KeyPath, Pem) ->
+pem_file_path(Dir, RawDir, KeyPath, Pem) ->
     % NOTE
     % Wee need to have the same filename on every cluster node.
     Segments = lists:map(fun ensure_bin/1, KeyPath),
     Filename0 = iolist_to_binary(lists:join(<<"_">>, Segments)),
     Filename1 = binary:replace(Filename0, <<"file">>, <<>>),
-    Fingerprint = crypto:hash(md5, [Dir, Filename1, Pem]),
+    Fingerprint = crypto:hash(md5, [RawDir, Filename1, Pem]),
     Suffix = binary:encode_hex(binary:part(Fingerprint, 0, 8)),
     Filename = <<Filename1/binary, "-", Suffix/binary>>,
-    filename:join([pem_dir(Dir), Filename]).
+    filename:join([Dir, Filename]).
 
 pem_dir(Dir) ->
     filename:join([emqx:mutable_certs_dir(), Dir]).