diff --git a/apps/emqx_psk/rebar.config b/apps/emqx_psk/rebar.config index 4bdb7b3c6..432c2944c 100644 --- a/apps/emqx_psk/rebar.config +++ b/apps/emqx_psk/rebar.config @@ -1,21 +1,29 @@ %% -*- mode: erlang -*- -{deps, [ {emqx, {path, "../emqx"}} - ]}. +{deps, [{emqx, {path, "../emqx"}}]}. {edoc_opts, [{preprocess, true}]}. -{erl_opts, [warn_unused_vars, - warn_shadow_vars, - warnings_as_errors, - warn_unused_import, - warn_obsolete_guard, - debug_info, - {parse_transform}]}. +{erl_opts, [ + warn_unused_vars, + warn_shadow_vars, + warnings_as_errors, + warn_unused_import, + warn_obsolete_guard, + debug_info, + {parse_transform} +]}. -{xref_checks, [undefined_function_calls, undefined_functions, - locals_not_used, deprecated_function_calls, - warnings_as_errors, deprecated_functions]}. +{xref_checks, [ + undefined_function_calls, + undefined_functions, + locals_not_used, + deprecated_function_calls, + warnings_as_errors, + deprecated_functions +]}. {cover_enabled, true}. {cover_opts, [verbose]}. {cover_export_enabled, true}. + +{project_plugins, [erlfmt]}. diff --git a/apps/emqx_psk/src/emqx_psk.app.src b/apps/emqx_psk/src/emqx_psk.app.src index 10c7656c5..4b405dd08 100644 --- a/apps/emqx_psk/src/emqx_psk.app.src +++ b/apps/emqx_psk/src/emqx_psk.app.src @@ -1,15 +1,17 @@ %% -*- mode: erlang -*- -{application, emqx_psk, - [{description, "EMQX PSK"}, - {vsn, "5.0.0"}, % strict semver, bump manually! - {modules, []}, - {registered, [emqx_psk_sup]}, - {applications, [kernel,stdlib]}, - {mod, {emqx_psk_app,[]}}, - {env, []}, - {licenses, ["Apache-2.0"]}, - {maintainers, ["EMQX Team "]}, - {links, [{"Homepage", "https://emqx.io/"}, - {"Github", "https://github.com/emqx/emqx"} - ]} - ]}. +{application, emqx_psk, [ + {description, "EMQX PSK"}, + % strict semver, bump manually! + {vsn, "5.0.0"}, + {modules, []}, + {registered, [emqx_psk_sup]}, + {applications, [kernel, stdlib]}, + {mod, {emqx_psk_app, []}}, + {env, []}, + {licenses, ["Apache-2.0"]}, + {maintainers, ["EMQX Team "]}, + {links, [ + {"Homepage", "https://emqx.io/"}, + {"Github", "https://github.com/emqx/emqx"} + ]} +]}. diff --git a/apps/emqx_psk/src/emqx_psk.erl b/apps/emqx_psk/src/emqx_psk.erl index 01f3cfa09..294a969c2 100644 --- a/apps/emqx_psk/src/emqx_psk.erl +++ b/apps/emqx_psk/src/emqx_psk.erl @@ -20,29 +20,33 @@ -include_lib("emqx/include/logger.hrl"). --export([ load/0 - , unload/0 - , on_psk_lookup/2 - , import/1 - ]). +-export([ + load/0, + unload/0, + on_psk_lookup/2, + import/1 +]). --export([ start_link/0 - , stop/0 - ]). +-export([ + start_link/0, + stop/0 +]). %% gen_server callbacks --export([ init/1 - , handle_call/3 - , handle_cast/2 - , handle_info/2 - , terminate/2 - , code_change/3 - ]). +-export([ + init/1, + handle_call/3, + handle_cast/2, + handle_info/2, + terminate/2, + code_change/3 +]). --record(psk_entry, {psk_id :: binary(), - shared_secret :: binary(), - extra :: term() - }). +-record(psk_entry, { + psk_id :: binary(), + shared_secret :: binary(), + extra :: term() +}). -export([mnesia/1]). @@ -65,15 +69,16 @@ %%------------------------------------------------------------------------------ %% @doc Create or replicate tables. --spec(mnesia(boot | copy) -> ok). +-spec mnesia(boot | copy) -> ok. mnesia(boot) -> ok = mria:create_table(?TAB, [ - {rlog_shard, ?PSK_SHARD}, - {type, ordered_set}, - {storage, disc_copies}, - {record_name, psk_entry}, - {attributes, record_info(fields, psk_entry)}, - {storage_properties, [{ets, [{read_concurrency, true}]}]}]). + {rlog_shard, ?PSK_SHARD}, + {type, ordered_set}, + {storage, disc_copies}, + {record_name, psk_entry}, + {attributes, record_info(fields, psk_entry)}, + {storage_properties, [{ets, [{read_concurrency, true}]}]} + ]). %%------------------------------------------------------------------------------ %% APIs @@ -109,11 +114,13 @@ stop() -> %%-------------------------------------------------------------------- init(_Opts) -> - _ = case get_config(enable) of + _ = + case get_config(enable) of true -> load(); false -> ?SLOG(info, #{msg => "emqx_psk_disabled"}) end, - _ = case get_config(init_file) of + _ = + case get_config(init_file) of undefined -> ok; InitFile -> import_psks(InitFile) end, @@ -121,7 +128,6 @@ init(_Opts) -> handle_call({import, SrcFile}, _From, State) -> {reply, import_psks(SrcFile), State}; - handle_call(Req, _From, State) -> ?SLOG(info, #{msg => "unexpected_call_discarded", req => Req}), {reply, {error, unexpected}, State}. @@ -157,25 +163,32 @@ get_config(chunk_size) -> import_psks(SrcFile) -> case file:open(SrcFile, [read, raw, binary, read_ahead]) of {error, Reason} -> - ?SLOG(error, #{msg => "failed_to_open_psk_file", - file => SrcFile, - reason => Reason}), + ?SLOG(error, #{ + msg => "failed_to_open_psk_file", + file => SrcFile, + reason => Reason + }), {error, Reason}; {ok, Io} -> try import_psks(Io, get_config(separator), get_config(chunk_size), 0) of - ok -> ok; + ok -> + ok; {error, Reason} -> - ?SLOG(error, #{msg => "failed_to_import_psk_file", - file => SrcFile, - reason => Reason}), + ?SLOG(error, #{ + msg => "failed_to_import_psk_file", + file => SrcFile, + reason => Reason + }), {error, Reason} catch Exception:Reason:Stacktrace -> - ?SLOG(error, #{msg => "failed_to_import_psk_file", - file => SrcFile, - exception => Exception, - reason => Reason, - stacktrace => Stacktrace}), + ?SLOG(error, #{ + msg => "failed_to_import_psk_file", + file => SrcFile, + exception => Exception, + reason => Reason, + stacktrace => Stacktrace + }), {error, Reason} after _ = file:close(Io) @@ -218,9 +231,12 @@ get_psks(Io, Delimiter, Remaining, Acc) -> end. insert_psks(Entries) -> - lists:foreach(fun(Entry) -> - insert_psk(Entry) - end, Entries). + lists:foreach( + fun(Entry) -> + insert_psk(Entry) + end, + Entries + ). insert_psk({PSKIdentity, SharedSecret}) -> mnesia:write(?TAB, #psk_entry{psk_id = PSKIdentity, shared_secret = SharedSecret}, write). @@ -233,7 +249,8 @@ trim_crlf(Bin) -> ?CR -> binary:part(Bin, 0, Size - 2); _ -> binary:part(Bin, 0, Size - 1) end; - _ -> Bin + _ -> + Bin end. trans(Fun, Args) -> diff --git a/apps/emqx_psk/src/emqx_psk_app.erl b/apps/emqx_psk/src/emqx_psk_app.erl index 288f0a20f..3e5936783 100644 --- a/apps/emqx_psk/src/emqx_psk_app.erl +++ b/apps/emqx_psk/src/emqx_psk_app.erl @@ -18,9 +18,10 @@ -behaviour(application). --export([ start/2 - , stop/1 - ]). +-export([ + start/2, + stop/1 +]). start(_Type, _Args) -> {ok, Sup} = emqx_psk_sup:start_link(), diff --git a/apps/emqx_psk/src/emqx_psk_schema.erl b/apps/emqx_psk/src/emqx_psk_schema.erl index f2979529b..1b1c26255 100644 --- a/apps/emqx_psk/src/emqx_psk_schema.erl +++ b/apps/emqx_psk/src/emqx_psk_schema.erl @@ -20,51 +20,74 @@ -include_lib("typerefl/include/types.hrl"). --export([ roots/0 - , fields/1 - ]). +-export([ + roots/0, + fields/1 +]). -import(emqx_schema, [sc/2]). roots() -> ["psk_authentication"]. fields("psk_authentication") -> - #{fields => fields(), - desc => """PSK stands for 'Pre-Shared Keys'. -This config to enable TLS-PSK authentication. - -Important! Make sure the SSL listener with -only tlsv1.2 enabled, and also PSK cipher suites -configured, such as RSA-PSK-AES256-GCM-SHA384. -See listener SSL options config for more details. - -The IDs and secrets can be provided from a file the path -to which is configurable by the init_file field. -""" - }. + #{ + fields => fields(), + desc => + "" + "PSK stands for 'Pre-Shared Keys'.\n" + "This config to enable TLS-PSK authentication.\n" + "\n" + "Important! Make sure the SSL listener with\n" + "only tlsv1.2 enabled, and also PSK cipher suites\n" + "configured, such as RSA-PSK-AES256-GCM-SHA384.\n" + "See listener SSL options config for more details.\n" + "\n" + "The IDs and secrets can be provided from a file the path\n" + "to which is configurable by the init_file field.\n" + "" + }. fields() -> - [ {enable, sc(boolean(), #{default => false, - desc => <<"Whether to enable TLS PSK support">> - })} - , {init_file, sc(binary(), - #{required => false, - desc => - <<"If init_file is specified, emqx will import PSKs from the file ", - "into the built-in database at startup for use by the runtime. ", - "The file has to be structured line-by-line, each line must be in ", - "the format of PSKIdentity:SharedSecret. For example: ", - "mydevice1:c2VjcmV0">> - })} - , {separator, sc(binary(), - #{default => <<":">>, - desc => - <<"The separator between PSKIdentity" - " and SharedSecret in the psk file">> - })} - , {chunk_size, sc(integer(), - #{default => 50, - desc => <<"The size of each chunk used to import to" - " the built-in database from psk file">> - })} + [ + {enable, + sc(boolean(), #{ + default => false, + desc => <<"Whether to enable TLS PSK support">> + })}, + {init_file, + sc( + binary(), + #{ + required => false, + desc => + <<"If init_file is specified, emqx will import PSKs from the file ", + "into the built-in database at startup for use by the runtime. ", + "The file has to be structured line-by-line, each line must be in ", + "the format of PSKIdentity:SharedSecret. For example: ", + "mydevice1:c2VjcmV0">> + } + )}, + {separator, + sc( + binary(), + #{ + default => <<":">>, + desc => + << + "The separator between PSKIdentity" + " and SharedSecret in the psk file" + >> + } + )}, + {chunk_size, + sc( + integer(), + #{ + default => 50, + desc => << + "The size of each chunk used to import to" + " the built-in database from psk file" + >> + } + )} ]. diff --git a/apps/emqx_psk/src/emqx_psk_sup.erl b/apps/emqx_psk/src/emqx_psk_sup.erl index 0d677aa41..17e9f171d 100644 --- a/apps/emqx_psk/src/emqx_psk_sup.erl +++ b/apps/emqx_psk/src/emqx_psk_sup.erl @@ -26,10 +26,14 @@ start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). init([]) -> - {ok, {{one_for_one, 10, 3600}, - [#{id => emqx_psk, - start => {emqx_psk, start_link, []}, - restart => permanent, - shutdown => 5000, - type => worker, - modules => [emqx_psk]}]}}. + {ok, + {{one_for_one, 10, 3600}, [ + #{ + id => emqx_psk, + start => {emqx_psk, start_link, []}, + restart => permanent, + shutdown => 5000, + type => worker, + modules => [emqx_psk] + } + ]}}. diff --git a/apps/emqx_psk/test/emqx_psk_SUITE.erl b/apps/emqx_psk/test/emqx_psk_SUITE.erl index f22570b4a..7a5a35646 100644 --- a/apps/emqx_psk/test/emqx_psk_SUITE.erl +++ b/apps/emqx_psk/test/emqx_psk_SUITE.erl @@ -29,16 +29,22 @@ all() -> init_per_suite(Config) -> meck:new(emqx_config, [non_strict, passthrough, no_history, no_link]), - meck:expect(emqx_config, get, fun([psk_authentication, enable]) -> true; - ([psk_authentication, chunk_size]) -> 50; - (KeyPath) -> meck:passthrough([KeyPath]) - end), - meck:expect(emqx_config, get, fun([psk_authentication, init_file], _) -> - filename:join([code:lib_dir(emqx_psk, test), - "data/init.psk"]); - ([psk_authentication, separator], _) -> <<":">>; - (KeyPath, Default) -> meck:passthrough([KeyPath, Default]) - end), + meck:expect(emqx_config, get, fun + ([psk_authentication, enable]) -> true; + ([psk_authentication, chunk_size]) -> 50; + (KeyPath) -> meck:passthrough([KeyPath]) + end), + meck:expect(emqx_config, get, fun + ([psk_authentication, init_file], _) -> + filename:join([ + code:lib_dir(emqx_psk, test), + "data/init.psk" + ]); + ([psk_authentication, separator], _) -> + <<":">>; + (KeyPath, Default) -> + meck:passthrough([KeyPath, Default]) + end), emqx_common_test_helpers:start_apps([emqx_psk]), Config. @@ -48,7 +54,6 @@ end_per_suite(_) -> ok. t_psk_lookup(_) -> - PSKIdentity1 = <<"myclient1">>, SharedSecret1 = <<"8c701116e9127c57a99d5563709af3deaca75563e2c4dd0865701ae839fb6d79">>, ?assertEqual({stop, {ok, SharedSecret1}}, emqx_psk:on_psk_lookup(PSKIdentity1, any)), @@ -59,24 +64,27 @@ t_psk_lookup(_) -> ?assertEqual(ignore, emqx_psk:on_psk_lookup(<<"myclient3">>, any)), - ClientLookup = fun(psk, undefined, _) -> {ok, SharedSecret1}; - (psk, _, _) -> error - end, + ClientLookup = fun + (psk, undefined, _) -> {ok, SharedSecret1}; + (psk, _, _) -> error + end, - ClientTLSOpts = #{ versions => ['tlsv1.2'] - , ciphers => ["PSK-AES256-CBC-SHA"] - , psk_identity => "myclient1" - , verify => verify_none - , user_lookup_fun => {ClientLookup, undefined} - }, + ClientTLSOpts = #{ + versions => ['tlsv1.2'], + ciphers => ["PSK-AES256-CBC-SHA"], + psk_identity => "myclient1", + verify => verify_none, + user_lookup_fun => {ClientLookup, undefined} + }, - ServerTLSOpts = #{ versions => ['tlsv1.2'] - , ciphers => ["PSK-AES256-CBC-SHA"] - , verify => verify_none - , reuseaddr => true - , user_lookup_fun => {fun emqx_tls_psk:lookup/3, undefined} - }, - emqx_config:put([listeners, ssl ,default, ssl], ServerTLSOpts), + ServerTLSOpts = #{ + versions => ['tlsv1.2'], + ciphers => ["PSK-AES256-CBC-SHA"], + verify => verify_none, + reuseaddr => true, + user_lookup_fun => {fun emqx_tls_psk:lookup/3, undefined} + }, + emqx_config:put([listeners, ssl, default, ssl], ServerTLSOpts), emqx_listeners:restart_listener('ssl:default'), {ok, Socket} = ssl:connect("127.0.0.1", 8883, maps:to_list(ClientTLSOpts)), diff --git a/scripts/check-format.sh b/scripts/check-format.sh index 81108192b..8289c27f5 100755 --- a/scripts/check-format.sh +++ b/scripts/check-format.sh @@ -14,6 +14,7 @@ APPS+=( 'lib-ee/emqx_enterprise_conf' 'lib-ee/emqx_license' ) APPS+=( 'apps/emqx_exhook') APPS+=( 'apps/emqx_retainer' 'apps/emqx_slow_subs') APPS+=( 'apps/emqx_management') +APPS+=( 'apps/emqx_psk') for app in "${APPS[@]}"; do echo "$app ..."