feat(tls): ee only: TLS partial_chain and Keyusage
This commit is contained in:
parent
2b50610a60
commit
7c37bf9965
|
@ -75,6 +75,10 @@
|
||||||
-define(TYPES_STRING, ["tcp", "ssl", "ws", "wss", "quic"]).
|
-define(TYPES_STRING, ["tcp", "ssl", "ws", "wss", "quic"]).
|
||||||
-define(MARK_DEL, ?TOMBSTONE_CONFIG_CHANGE_REQ).
|
-define(MARK_DEL, ?TOMBSTONE_CONFIG_CHANGE_REQ).
|
||||||
|
|
||||||
|
-ifndef(EMQX_RELEASE_EDITION).
|
||||||
|
-define(EMQX_RELEASE_EDITION, ce).
|
||||||
|
-endif.
|
||||||
|
|
||||||
-spec id_example() -> atom().
|
-spec id_example() -> atom().
|
||||||
id_example() -> 'tcp:default'.
|
id_example() -> 'tcp:default'.
|
||||||
|
|
||||||
|
@ -974,15 +978,21 @@ quic_listener_optional_settings() ->
|
||||||
stateless_operation_expiration_ms
|
stateless_operation_expiration_ms
|
||||||
].
|
].
|
||||||
|
|
||||||
|
-if(?EMQX_RELEASE_EDITION == ee).
|
||||||
inject_root_fun(#{ssl_options := SslOpts} = Opts) ->
|
inject_root_fun(#{ssl_options := SslOpts} = Opts) ->
|
||||||
Opts#{ssl_options := emqx_tls_lib:opt_partial_chain(SslOpts)};
|
Opts#{ssl_options := emqx_auth_ext_tls_lib:opt_partial_chain(SslOpts)}.
|
||||||
|
-else.
|
||||||
inject_root_fun(Opts) ->
|
inject_root_fun(Opts) ->
|
||||||
Opts.
|
Opts.
|
||||||
|
-endif.
|
||||||
|
|
||||||
|
-if(?EMQX_RELEASE_EDITION == ee).
|
||||||
inject_verify_fun(#{ssl_options := SslOpts} = Opts) ->
|
inject_verify_fun(#{ssl_options := SslOpts} = Opts) ->
|
||||||
Opts#{ssl_options := emqx_tls_lib:opt_verify_fun(SslOpts)};
|
Opts#{ssl_options := emqx_auth_ext_tls_lib:opt_verify_fun(SslOpts)}.
|
||||||
|
-else.
|
||||||
inject_verify_fun(Opts) ->
|
inject_verify_fun(Opts) ->
|
||||||
Opts.
|
Opts.
|
||||||
|
-endif.
|
||||||
|
|
||||||
inject_sni_fun(ListenerId, Conf = #{ssl_options := #{ocsp := #{enable_ocsp_stapling := true}}}) ->
|
inject_sni_fun(ListenerId, Conf = #{ssl_options := #{ocsp := #{enable_ocsp_stapling := true}}}) ->
|
||||||
emqx_ocsp_cache:inject_sni_fun(ListenerId, Conf);
|
emqx_ocsp_cache:inject_sni_fun(ListenerId, Conf);
|
||||||
|
|
|
@ -191,6 +191,8 @@
|
||||||
-define(DEFAULT_MULTIPLIER, 1.5).
|
-define(DEFAULT_MULTIPLIER, 1.5).
|
||||||
-define(DEFAULT_BACKOFF, 0.75).
|
-define(DEFAULT_BACKOFF, 0.75).
|
||||||
|
|
||||||
|
-define(INJECTING_CONFIGS, [?AUTH_EXT_SCHEMA_MODS]).
|
||||||
|
|
||||||
namespace() -> emqx.
|
namespace() -> emqx.
|
||||||
|
|
||||||
tags() ->
|
tags() ->
|
||||||
|
@ -2178,22 +2180,6 @@ common_ssl_opts_schema(Defaults, Type) ->
|
||||||
desc => ?DESC(common_ssl_opts_schema_verify)
|
desc => ?DESC(common_ssl_opts_schema_verify)
|
||||||
}
|
}
|
||||||
)},
|
)},
|
||||||
{"partial_chain",
|
|
||||||
sc(
|
|
||||||
hoconsc:enum([true, false, two_cacerts_from_cacertfile, cacert_from_cacertfile]),
|
|
||||||
#{
|
|
||||||
default => Df(partial_chain, false),
|
|
||||||
desc => ?DESC(common_ssl_opts_schema_partial_chain)
|
|
||||||
}
|
|
||||||
)},
|
|
||||||
{"verify_peer_ext_key_usage",
|
|
||||||
sc(
|
|
||||||
string(),
|
|
||||||
#{
|
|
||||||
required => false,
|
|
||||||
desc => ?DESC(common_ssl_opts_verify_peer_ext_key_usage)
|
|
||||||
}
|
|
||||||
)},
|
|
||||||
{"reuse_sessions",
|
{"reuse_sessions",
|
||||||
sc(
|
sc(
|
||||||
boolean(),
|
boolean(),
|
||||||
|
@ -2263,7 +2249,7 @@ common_ssl_opts_schema(Defaults, Type) ->
|
||||||
desc => ?DESC(common_ssl_opts_schema_hibernate_after)
|
desc => ?DESC(common_ssl_opts_schema_hibernate_after)
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
].
|
] ++ emqx_schema_hooks:injection_point('common_ssl_opts_schema').
|
||||||
|
|
||||||
%% @doc Make schema for SSL listener options.
|
%% @doc Make schema for SSL listener options.
|
||||||
-spec server_ssl_opts_schema(map(), boolean()) -> hocon_schema:field_schema().
|
-spec server_ssl_opts_schema(map(), boolean()) -> hocon_schema:field_schema().
|
||||||
|
|
|
@ -24,8 +24,6 @@
|
||||||
default_ciphers/0,
|
default_ciphers/0,
|
||||||
selected_ciphers/1,
|
selected_ciphers/1,
|
||||||
integral_ciphers/2,
|
integral_ciphers/2,
|
||||||
opt_partial_chain/1,
|
|
||||||
opt_verify_fun/1,
|
|
||||||
all_ciphers_set_cached/0
|
all_ciphers_set_cached/0
|
||||||
]).
|
]).
|
||||||
|
|
||||||
|
@ -688,55 +686,3 @@ ensure_ssl_file_key(SSL, RequiredKeyPaths) ->
|
||||||
[] -> ok;
|
[] -> ok;
|
||||||
Miss -> {error, #{reason => ssl_file_option_not_found, which_options => Miss}}
|
Miss -> {error, #{reason => ssl_file_option_not_found, which_options => Miss}}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%% @doc enable TLS partial_chain validation if set.
|
|
||||||
-spec opt_partial_chain(SslOpts :: map()) -> NewSslOpts :: map().
|
|
||||||
opt_partial_chain(#{partial_chain := false} = SslOpts) ->
|
|
||||||
maps:remove(partial_chain, SslOpts);
|
|
||||||
opt_partial_chain(#{partial_chain := true} = SslOpts) ->
|
|
||||||
SslOpts#{partial_chain := rootfun_trusted_ca_from_cacertfile(1, SslOpts)};
|
|
||||||
opt_partial_chain(#{partial_chain := cacert_from_cacertfile} = SslOpts) ->
|
|
||||||
SslOpts#{partial_chain := rootfun_trusted_ca_from_cacertfile(1, SslOpts)};
|
|
||||||
opt_partial_chain(#{partial_chain := two_cacerts_from_cacertfile} = SslOpts) ->
|
|
||||||
SslOpts#{partial_chain := rootfun_trusted_ca_from_cacertfile(2, SslOpts)};
|
|
||||||
opt_partial_chain(SslOpts) ->
|
|
||||||
SslOpts.
|
|
||||||
|
|
||||||
%% @doc make verify_fun if set.
|
|
||||||
-spec opt_verify_fun(SslOpts :: map()) -> NewSslOpts :: map().
|
|
||||||
opt_verify_fun(#{verify_peer_ext_key_usage := V} = SslOpts) when V =/= undefined ->
|
|
||||||
SslOpts#{verify_fun => emqx_const_v2:make_tls_verify_fun(verify_cert_extKeyUsage, V)};
|
|
||||||
opt_verify_fun(SslOpts) ->
|
|
||||||
SslOpts.
|
|
||||||
|
|
||||||
%% @doc Helper, make TLS root_fun
|
|
||||||
rootfun_trusted_ca_from_cacertfile(NumOfCerts, #{cacertfile := Cacertfile}) ->
|
|
||||||
case file:read_file(Cacertfile) of
|
|
||||||
{ok, PemBin} ->
|
|
||||||
try
|
|
||||||
do_rootfun_trusted_ca_from_cacertfile(NumOfCerts, PemBin)
|
|
||||||
catch
|
|
||||||
_Error:_Info:ST ->
|
|
||||||
%% The cacertfile will be checked by OTP SSL as well and OTP choice to be silent on this.
|
|
||||||
%% We are touching security sutffs, don't leak extra info..
|
|
||||||
?SLOG(error, #{
|
|
||||||
msg => "trusted_cacert_not_found_in_cacertfile", stacktrace => ST
|
|
||||||
}),
|
|
||||||
throw({error, ?FUNCTION_NAME})
|
|
||||||
end;
|
|
||||||
{error, Reason} ->
|
|
||||||
throw({error, {read_cacertfile_error, Cacertfile, Reason}})
|
|
||||||
end;
|
|
||||||
rootfun_trusted_ca_from_cacertfile(_NumOfCerts, _SslOpts) ->
|
|
||||||
throw({error, cacertfile_unset}).
|
|
||||||
|
|
||||||
do_rootfun_trusted_ca_from_cacertfile(NumOfCerts, PemBin) ->
|
|
||||||
%% The last one or two should be the top parent in the chain if it is a chain
|
|
||||||
Certs = public_key:pem_decode(PemBin),
|
|
||||||
Pos = length(Certs) - NumOfCerts + 1,
|
|
||||||
Trusted = [
|
|
||||||
CADer
|
|
||||||
|| {'Certificate', CADer, _} <-
|
|
||||||
lists:sublist(public_key:pem_decode(PemBin), Pos, NumOfCerts)
|
|
||||||
],
|
|
||||||
emqx_const_v2:make_tls_root_fun(cacert_from_cacertfile, Trusted).
|
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
.rebar3
|
||||||
|
_build
|
||||||
|
_checkouts
|
||||||
|
_vendor
|
||||||
|
.eunit
|
||||||
|
*.o
|
||||||
|
*.beam
|
||||||
|
*.plt
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
.erlang.cookie
|
||||||
|
ebin
|
||||||
|
log
|
||||||
|
erl_crash.dump
|
||||||
|
.rebar
|
||||||
|
logs
|
||||||
|
.idea
|
||||||
|
*.iml
|
||||||
|
rebar3.crashdump
|
||||||
|
*~
|
|
@ -0,0 +1,94 @@
|
||||||
|
Business Source License 1.1
|
||||||
|
|
||||||
|
Licensor: Hangzhou EMQ Technologies Co., Ltd.
|
||||||
|
Licensed Work: EMQX Enterprise Edition
|
||||||
|
The Licensed Work is (c) 2023
|
||||||
|
Hangzhou EMQ Technologies Co., Ltd.
|
||||||
|
Additional Use Grant: Students and educators are granted right to copy,
|
||||||
|
modify, and create derivative work for research
|
||||||
|
or education.
|
||||||
|
Change Date: 2028-01-26
|
||||||
|
Change License: Apache License, Version 2.0
|
||||||
|
|
||||||
|
For information about alternative licensing arrangements for the Software,
|
||||||
|
please contact Licensor: https://www.emqx.com/en/contact
|
||||||
|
|
||||||
|
Notice
|
||||||
|
|
||||||
|
The Business Source License (this document, or the “License”) is not an Open
|
||||||
|
Source license. However, the Licensed Work will eventually be made available
|
||||||
|
under an Open Source License, as stated in this License.
|
||||||
|
|
||||||
|
License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved.
|
||||||
|
“Business Source License” is a trademark of MariaDB Corporation Ab.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Business Source License 1.1
|
||||||
|
|
||||||
|
Terms
|
||||||
|
|
||||||
|
The Licensor hereby grants you the right to copy, modify, create derivative
|
||||||
|
works, redistribute, and make non-production use of the Licensed Work. The
|
||||||
|
Licensor may make an Additional Use Grant, above, permitting limited
|
||||||
|
production use.
|
||||||
|
|
||||||
|
Effective on the Change Date, or the fourth anniversary of the first publicly
|
||||||
|
available distribution of a specific version of the Licensed Work under this
|
||||||
|
License, whichever comes first, the Licensor hereby grants you rights under
|
||||||
|
the terms of the Change License, and the rights granted in the paragraph
|
||||||
|
above terminate.
|
||||||
|
|
||||||
|
If your use of the Licensed Work does not comply with the requirements
|
||||||
|
currently in effect as described in this License, you must purchase a
|
||||||
|
commercial license from the Licensor, its affiliated entities, or authorized
|
||||||
|
resellers, or you must refrain from using the Licensed Work.
|
||||||
|
|
||||||
|
All copies of the original and modified Licensed Work, and derivative works
|
||||||
|
of the Licensed Work, are subject to this License. This License applies
|
||||||
|
separately for each version of the Licensed Work and the Change Date may vary
|
||||||
|
for each version of the Licensed Work released by Licensor.
|
||||||
|
|
||||||
|
You must conspicuously display this License on each original or modified copy
|
||||||
|
of the Licensed Work. If you receive the Licensed Work in original or
|
||||||
|
modified form from a third party, the terms and conditions set forth in this
|
||||||
|
License apply to your use of that work.
|
||||||
|
|
||||||
|
Any use of the Licensed Work in violation of this License will automatically
|
||||||
|
terminate your rights under this License for the current and all other
|
||||||
|
versions of the Licensed Work.
|
||||||
|
|
||||||
|
This License does not grant you any right in any trademark or logo of
|
||||||
|
Licensor or its affiliates (provided that you may use a trademark or logo of
|
||||||
|
Licensor as expressly required by this License).
|
||||||
|
|
||||||
|
TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
|
||||||
|
AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
|
||||||
|
TITLE.
|
||||||
|
|
||||||
|
MariaDB hereby grants you permission to use this License’s text to license
|
||||||
|
your works, and to refer to it using the trademark “Business Source License”,
|
||||||
|
as long as you comply with the Covenants of Licensor below.
|
||||||
|
|
||||||
|
Covenants of Licensor
|
||||||
|
|
||||||
|
In consideration of the right to use this License’s text and the “Business
|
||||||
|
Source License” name and trademark, Licensor covenants to MariaDB, and to all
|
||||||
|
other recipients of the licensed work to be provided by Licensor:
|
||||||
|
|
||||||
|
1. To specify as the Change License the GPL Version 2.0 or any later version,
|
||||||
|
or a license that is compatible with GPL Version 2.0 or a later version,
|
||||||
|
where “compatible” means that software provided under the Change License can
|
||||||
|
be included in a program with software provided under GPL Version 2.0 or a
|
||||||
|
later version. Licensor may specify additional Change Licenses without
|
||||||
|
limitation.
|
||||||
|
|
||||||
|
2. To either: (a) specify an additional grant of rights to use that does not
|
||||||
|
impose any additional restriction on the right granted in this License, as
|
||||||
|
the Additional Use Grant; or (b) insert the text “None”.
|
||||||
|
|
||||||
|
3. To specify a Change Date.
|
||||||
|
|
||||||
|
4. Not to modify this License in any other way.
|
|
@ -0,0 +1,7 @@
|
||||||
|
# EMQX Extended Auth Library
|
||||||
|
|
||||||
|
Library that extends EMQX authentication capbility for enterprise.
|
||||||
|
|
||||||
|
# License
|
||||||
|
|
||||||
|
EMQ Business Source License 1.1, refer to [LICENSE](BSL.txt).
|
|
@ -0,0 +1,2 @@
|
||||||
|
{erl_opts, [debug_info]}.
|
||||||
|
{deps, [{emqx, {path, "../emqx"}}]}.
|
|
@ -0,0 +1,21 @@
|
||||||
|
{application, emqx_auth_ext, [
|
||||||
|
{description, "EMQX Extended Auth Library"},
|
||||||
|
{vsn, "0.1.0"},
|
||||||
|
{registered, []},
|
||||||
|
{applications, [
|
||||||
|
kernel,
|
||||||
|
stdlib,
|
||||||
|
ssl,
|
||||||
|
emqx
|
||||||
|
]},
|
||||||
|
{env, []},
|
||||||
|
{modules, [
|
||||||
|
emqx_auth_ext,
|
||||||
|
emqx_auth_ext_schema,
|
||||||
|
emqx_auth_ext_tls_lib,
|
||||||
|
emqx_auth_ext_tls_const_v1
|
||||||
|
]},
|
||||||
|
|
||||||
|
{licenses, ["Apache-2.0"]},
|
||||||
|
{links, []}
|
||||||
|
]}.
|
|
@ -0,0 +1,6 @@
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Copyright (c) 2022-2024 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
-module(emqx_auth_ext).
|
||||||
|
|
||||||
|
-export([]).
|
|
@ -0,0 +1,42 @@
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Copyright (c) 2022-2024 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(emqx_auth_ext_schema).
|
||||||
|
-behaviour(emqx_schema_hooks).
|
||||||
|
|
||||||
|
-include_lib("typerefl/include/types.hrl").
|
||||||
|
-include_lib("hocon/include/hoconsc.hrl").
|
||||||
|
|
||||||
|
%%------------------------------------------------------------------------------
|
||||||
|
%% emqx_schema_hooks callbacks
|
||||||
|
%%------------------------------------------------------------------------------
|
||||||
|
-export([injected_fields/0]).
|
||||||
|
|
||||||
|
-spec injected_fields() -> #{emqx_schema_hooks:hookpoint() => [hocon_schema:field()]}.
|
||||||
|
injected_fields() ->
|
||||||
|
#{
|
||||||
|
'common_ssl_opts_schema' => fields(auth_ext)
|
||||||
|
}.
|
||||||
|
|
||||||
|
fields(auth_ext) ->
|
||||||
|
[
|
||||||
|
{"partial_chain",
|
||||||
|
sc(
|
||||||
|
hoconsc:enum([true, false, two_cacerts_from_cacertfile, cacert_from_cacertfile]),
|
||||||
|
#{
|
||||||
|
default => false,
|
||||||
|
desc => ?DESC(common_ssl_opts_schema_partial_chain)
|
||||||
|
}
|
||||||
|
)},
|
||||||
|
{"verify_peer_ext_key_usage",
|
||||||
|
sc(
|
||||||
|
string(),
|
||||||
|
#{
|
||||||
|
required => false,
|
||||||
|
desc => ?DESC(common_ssl_opts_verify_peer_ext_key_usage)
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
].
|
||||||
|
|
||||||
|
sc(Type, Meta) -> hoconsc:mk(Type, Meta).
|
|
@ -1,22 +1,8 @@
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Copyright (c) 2024 EMQ Technologies Co., Ltd. All Rights Reserved.
|
%% Copyright (c) 2024 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||||
%%
|
|
||||||
%% Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
%% you may not use this file except in compliance with the License.
|
|
||||||
%% You may obtain a copy of the License at
|
|
||||||
%%
|
|
||||||
%% http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
%%
|
|
||||||
%% Unless required by applicable law or agreed to in writing, software
|
|
||||||
%% distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
%% See the License for the specific language governing permissions and
|
|
||||||
%% limitations under the License.
|
|
||||||
%%
|
|
||||||
%% @doc Never update this module, create a v3 instead.
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
-module(emqx_const_v2).
|
-module(emqx_auth_ext_tls_const_v1).
|
||||||
-elvis([{elvis_style, atom_naming_convention, #{regex => "^([a-z][a-z0-9A-Z]*_?)*(_SUITE)?$"}}]).
|
-elvis([{elvis_style, atom_naming_convention, #{regex => "^([a-z][a-z0-9A-Z]*_?)*(_SUITE)?$"}}]).
|
||||||
|
|
||||||
-export([
|
-export([
|
|
@ -0,0 +1,66 @@
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Copyright (c) 2024 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(emqx_auth_ext_tls_lib).
|
||||||
|
-elvis([{elvis_style, atom_naming_convention, #{regex => "^([a-z][a-z0-9A-Z]*_?)*(_SUITE)?$"}}]).
|
||||||
|
|
||||||
|
-export([
|
||||||
|
opt_partial_chain/1,
|
||||||
|
opt_verify_fun/1
|
||||||
|
]).
|
||||||
|
|
||||||
|
-include_lib("emqx/include/logger.hrl").
|
||||||
|
|
||||||
|
-define(CONST_MOD_V1, emqx_auth_ext_tls_const_v1).
|
||||||
|
%% @doc enable TLS partial_chain validation if set.
|
||||||
|
-spec opt_partial_chain(SslOpts :: map()) -> NewSslOpts :: map().
|
||||||
|
opt_partial_chain(#{partial_chain := false} = SslOpts) ->
|
||||||
|
maps:remove(partial_chain, SslOpts);
|
||||||
|
opt_partial_chain(#{partial_chain := true} = SslOpts) ->
|
||||||
|
SslOpts#{partial_chain := rootfun_trusted_ca_from_cacertfile(1, SslOpts)};
|
||||||
|
opt_partial_chain(#{partial_chain := cacert_from_cacertfile} = SslOpts) ->
|
||||||
|
SslOpts#{partial_chain := rootfun_trusted_ca_from_cacertfile(1, SslOpts)};
|
||||||
|
opt_partial_chain(#{partial_chain := two_cacerts_from_cacertfile} = SslOpts) ->
|
||||||
|
SslOpts#{partial_chain := rootfun_trusted_ca_from_cacertfile(2, SslOpts)};
|
||||||
|
opt_partial_chain(SslOpts) ->
|
||||||
|
SslOpts.
|
||||||
|
|
||||||
|
%% @doc make verify_fun if set.
|
||||||
|
-spec opt_verify_fun(SslOpts :: map()) -> NewSslOpts :: map().
|
||||||
|
opt_verify_fun(#{verify_peer_ext_key_usage := V} = SslOpts) when V =/= undefined ->
|
||||||
|
SslOpts#{verify_fun => ?CONST_MOD_V1:make_tls_verify_fun(verify_cert_extKeyUsage, V)};
|
||||||
|
opt_verify_fun(SslOpts) ->
|
||||||
|
SslOpts.
|
||||||
|
|
||||||
|
%% @doc Helper, make TLS root_fun
|
||||||
|
rootfun_trusted_ca_from_cacertfile(NumOfCerts, #{cacertfile := Cacertfile}) ->
|
||||||
|
case file:read_file(emqx_schema:naive_env_interpolation(Cacertfile)) of
|
||||||
|
{ok, PemBin} ->
|
||||||
|
try
|
||||||
|
do_rootfun_trusted_ca_from_cacertfile(NumOfCerts, PemBin)
|
||||||
|
catch
|
||||||
|
_Error:_Info:ST ->
|
||||||
|
%% The cacertfile will be checked by OTP SSL as well and OTP choice to be silent on this.
|
||||||
|
%% We are touching security sutffs, don't leak extra info..
|
||||||
|
?SLOG(error, #{
|
||||||
|
msg => "trusted_cacert_not_found_in_cacertfile", stacktrace => ST
|
||||||
|
}),
|
||||||
|
throw({error, ?FUNCTION_NAME})
|
||||||
|
end;
|
||||||
|
{error, Reason} ->
|
||||||
|
throw({error, {read_cacertfile_error, Cacertfile, Reason}})
|
||||||
|
end;
|
||||||
|
rootfun_trusted_ca_from_cacertfile(_NumOfCerts, _SslOpts) ->
|
||||||
|
throw({error, cacertfile_unset}).
|
||||||
|
|
||||||
|
do_rootfun_trusted_ca_from_cacertfile(NumOfCerts, PemBin) ->
|
||||||
|
%% The last one or two should be the top parent in the chain if it is a chain
|
||||||
|
Certs = public_key:pem_decode(PemBin),
|
||||||
|
Pos = length(Certs) - NumOfCerts + 1,
|
||||||
|
Trusted = [
|
||||||
|
CADer
|
||||||
|
|| {'Certificate', CADer, _} <-
|
||||||
|
lists:sublist(public_key:pem_decode(PemBin), Pos, NumOfCerts)
|
||||||
|
],
|
||||||
|
?CONST_MOD_V1:make_tls_root_fun(cacert_from_cacertfile, Trusted).
|
|
@ -1,19 +1,8 @@
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Copyright (c) 2024 EMQ Technologies Co., Ltd. All Rights Reserved.
|
%% Copyright (c) 2024 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||||
%%
|
|
||||||
%% Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
%% you may not use this file except in compliance with the License.
|
|
||||||
%% You may obtain a copy of the License at
|
|
||||||
%%
|
|
||||||
%% http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
%%
|
|
||||||
%% Unless required by applicable law or agreed to in writing, software
|
|
||||||
%% distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
%% See the License for the specific language governing permissions and
|
|
||||||
%% limitations under the License.
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
-module(emqx_listener_tls_verify_chain_SUITE).
|
|
||||||
|
-module(emqx_auth_ext_listener_tls_verify_chain_SUITE).
|
||||||
|
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
@ -22,12 +11,13 @@
|
||||||
-include_lib("common_test/include/ct.hrl").
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
|
||||||
-import(
|
-import(
|
||||||
emqx_test_tls_certs_helper,
|
emqx_auth_ext_test_tls_certs_helper,
|
||||||
[
|
[
|
||||||
emqx_start_listener/4,
|
emqx_start_listener/4,
|
||||||
fail_when_ssl_error/1,
|
fail_when_ssl_error/1,
|
||||||
fail_when_no_ssl_alert/2,
|
fail_when_no_ssl_alert/2,
|
||||||
generate_tls_certs/1
|
generate_tls_certs/1,
|
||||||
|
select_free_port/1
|
||||||
]
|
]
|
||||||
).
|
).
|
||||||
|
|
||||||
|
@ -42,7 +32,7 @@ end_per_suite(_Config) ->
|
||||||
application:stop(esockd).
|
application:stop(esockd).
|
||||||
|
|
||||||
t_conn_fail_with_intermediate_ca_cert(Config) ->
|
t_conn_fail_with_intermediate_ca_cert(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options, [
|
{ssl_options, [
|
||||||
|
@ -68,7 +58,7 @@ t_conn_fail_with_intermediate_ca_cert(Config) ->
|
||||||
ok = ssl:close(Socket).
|
ok = ssl:close(Socket).
|
||||||
|
|
||||||
t_conn_fail_with_other_intermediate_ca_cert(Config) ->
|
t_conn_fail_with_other_intermediate_ca_cert(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options, [
|
{ssl_options, [
|
||||||
|
@ -94,7 +84,7 @@ t_conn_fail_with_other_intermediate_ca_cert(Config) ->
|
||||||
ok = ssl:close(Socket).
|
ok = ssl:close(Socket).
|
||||||
|
|
||||||
t_conn_success_with_server_client_composed_complete_chain(Config) ->
|
t_conn_success_with_server_client_composed_complete_chain(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
%% Server has root ca cert
|
%% Server has root ca cert
|
||||||
Options = [
|
Options = [
|
||||||
|
@ -121,7 +111,7 @@ t_conn_success_with_server_client_composed_complete_chain(Config) ->
|
||||||
ok = ssl:close(Socket).
|
ok = ssl:close(Socket).
|
||||||
|
|
||||||
t_conn_success_with_other_signed_client_composed_complete_chain(Config) ->
|
t_conn_success_with_other_signed_client_composed_complete_chain(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
%% Server has root ca cert
|
%% Server has root ca cert
|
||||||
Options = [
|
Options = [
|
||||||
|
@ -148,7 +138,7 @@ t_conn_success_with_other_signed_client_composed_complete_chain(Config) ->
|
||||||
ok = ssl:close(Socket).
|
ok = ssl:close(Socket).
|
||||||
|
|
||||||
t_conn_success_with_renewed_intermediate_root_bundle(Config) ->
|
t_conn_success_with_renewed_intermediate_root_bundle(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
%% Server has root ca cert
|
%% Server has root ca cert
|
||||||
Options = [
|
Options = [
|
||||||
|
@ -174,7 +164,7 @@ t_conn_success_with_renewed_intermediate_root_bundle(Config) ->
|
||||||
ok = ssl:close(Socket).
|
ok = ssl:close(Socket).
|
||||||
|
|
||||||
t_conn_success_with_client_complete_cert_chain(Config) ->
|
t_conn_success_with_client_complete_cert_chain(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options, [
|
{ssl_options, [
|
||||||
|
@ -199,7 +189,7 @@ t_conn_success_with_client_complete_cert_chain(Config) ->
|
||||||
ok = ssl:close(Socket).
|
ok = ssl:close(Socket).
|
||||||
|
|
||||||
t_conn_fail_with_server_partial_chain(Config) ->
|
t_conn_fail_with_server_partial_chain(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
%% imcomplete at server side
|
%% imcomplete at server side
|
||||||
Options = [
|
Options = [
|
||||||
|
@ -225,7 +215,7 @@ t_conn_fail_with_server_partial_chain(Config) ->
|
||||||
fail_when_no_ssl_alert(Res, unknown_ca).
|
fail_when_no_ssl_alert(Res, unknown_ca).
|
||||||
|
|
||||||
t_conn_fail_without_root_cacert(Config) ->
|
t_conn_fail_without_root_cacert(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options, [
|
{ssl_options, [
|
|
@ -1,19 +1,8 @@
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Copyright (c) 2024 EMQ Technologies Co., Ltd. All Rights Reserved.
|
%% Copyright (c) 2024 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||||
%%
|
|
||||||
%% Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
%% you may not use this file except in compliance with the License.
|
|
||||||
%% You may obtain a copy of the License at
|
|
||||||
%%
|
|
||||||
%% http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
%%
|
|
||||||
%% Unless required by applicable law or agreed to in writing, software
|
|
||||||
%% distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
%% See the License for the specific language governing permissions and
|
|
||||||
%% limitations under the License.
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
-module(emqx_listener_tls_verify_keyusage_SUITE).
|
|
||||||
|
-module(emqx_auth_ext_listener_tls_verify_keyusage_SUITE).
|
||||||
|
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
@ -22,13 +11,14 @@
|
||||||
-include_lib("common_test/include/ct.hrl").
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
|
||||||
-import(
|
-import(
|
||||||
emqx_test_tls_certs_helper,
|
emqx_auth_ext_test_tls_certs_helper,
|
||||||
[
|
[
|
||||||
fail_when_ssl_error/1,
|
fail_when_ssl_error/1,
|
||||||
fail_when_no_ssl_alert/2,
|
fail_when_no_ssl_alert/2,
|
||||||
generate_tls_certs/1,
|
generate_tls_certs/1,
|
||||||
gen_host_cert/4,
|
gen_host_cert/4,
|
||||||
emqx_start_listener/4
|
emqx_start_listener/4,
|
||||||
|
select_free_port/1
|
||||||
]
|
]
|
||||||
).
|
).
|
||||||
|
|
||||||
|
@ -66,7 +56,7 @@ end_per_group(_, Config) ->
|
||||||
Config.
|
Config.
|
||||||
|
|
||||||
t_conn_success_verify_peer_ext_key_usage_unset(Config) ->
|
t_conn_success_verify_peer_ext_key_usage_unset(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
%% Given listener keyusage unset
|
%% Given listener keyusage unset
|
||||||
Options = [{ssl_options, ?config(ssl_config, Config)}],
|
Options = [{ssl_options, ?config(ssl_config, Config)}],
|
||||||
|
@ -87,7 +77,7 @@ t_conn_success_verify_peer_ext_key_usage_unset(Config) ->
|
||||||
ok = ssl:close(Socket).
|
ok = ssl:close(Socket).
|
||||||
|
|
||||||
t_conn_success_verify_peer_ext_key_usage_undefined(Config) ->
|
t_conn_success_verify_peer_ext_key_usage_undefined(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
%% Give listener keyusage is set to undefined
|
%% Give listener keyusage is set to undefined
|
||||||
Options = [
|
Options = [
|
||||||
|
@ -113,7 +103,7 @@ t_conn_success_verify_peer_ext_key_usage_undefined(Config) ->
|
||||||
ok = ssl:close(Socket).
|
ok = ssl:close(Socket).
|
||||||
|
|
||||||
t_conn_success_verify_peer_ext_key_usage_matched_predefined(Config) ->
|
t_conn_success_verify_peer_ext_key_usage_matched_predefined(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
%% Give listener keyusage is set to clientAuth
|
%% Give listener keyusage is set to clientAuth
|
||||||
Options = [
|
Options = [
|
||||||
|
@ -141,7 +131,7 @@ t_conn_success_verify_peer_ext_key_usage_matched_predefined(Config) ->
|
||||||
ok = ssl:close(Socket).
|
ok = ssl:close(Socket).
|
||||||
|
|
||||||
t_conn_success_verify_peer_ext_key_usage_matched_raw_oid(Config) ->
|
t_conn_success_verify_peer_ext_key_usage_matched_raw_oid(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
%% Give listener keyusage is set to raw OID
|
%% Give listener keyusage is set to raw OID
|
||||||
|
|
||||||
|
@ -170,7 +160,7 @@ t_conn_success_verify_peer_ext_key_usage_matched_raw_oid(Config) ->
|
||||||
ok = ssl:close(Socket).
|
ok = ssl:close(Socket).
|
||||||
|
|
||||||
t_conn_success_verify_peer_ext_key_usage_matched_ordered_list(Config) ->
|
t_conn_success_verify_peer_ext_key_usage_matched_ordered_list(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
|
|
||||||
%% Give listener keyusage is clientAuth,serverAuth
|
%% Give listener keyusage is clientAuth,serverAuth
|
||||||
|
@ -198,7 +188,7 @@ t_conn_success_verify_peer_ext_key_usage_matched_ordered_list(Config) ->
|
||||||
ok = ssl:close(Socket).
|
ok = ssl:close(Socket).
|
||||||
|
|
||||||
t_conn_success_verify_peer_ext_key_usage_matched_unordered_list(Config) ->
|
t_conn_success_verify_peer_ext_key_usage_matched_unordered_list(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
%% Give listener keyusage is clientAuth,serverAuth
|
%% Give listener keyusage is clientAuth,serverAuth
|
||||||
Options = [
|
Options = [
|
||||||
|
@ -225,7 +215,7 @@ t_conn_success_verify_peer_ext_key_usage_matched_unordered_list(Config) ->
|
||||||
ok = ssl:close(Socket).
|
ok = ssl:close(Socket).
|
||||||
|
|
||||||
t_conn_fail_verify_peer_ext_key_usage_unmatched_raw_oid(Config) ->
|
t_conn_fail_verify_peer_ext_key_usage_unmatched_raw_oid(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
%% Give listener keyusage is using OID
|
%% Give listener keyusage is using OID
|
||||||
Options = [
|
Options = [
|
||||||
|
@ -254,7 +244,7 @@ t_conn_fail_verify_peer_ext_key_usage_unmatched_raw_oid(Config) ->
|
||||||
ok = ssl:close(Socket).
|
ok = ssl:close(Socket).
|
||||||
|
|
||||||
t_conn_fail_verify_peer_ext_key_usage_empty_str(Config) ->
|
t_conn_fail_verify_peer_ext_key_usage_empty_str(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options, [
|
{ssl_options, [
|
||||||
|
@ -280,7 +270,7 @@ t_conn_fail_verify_peer_ext_key_usage_empty_str(Config) ->
|
||||||
ok = ssl:close(Socket).
|
ok = ssl:close(Socket).
|
||||||
|
|
||||||
t_conn_fail_client_keyusage_unmatch(Config) ->
|
t_conn_fail_client_keyusage_unmatch(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
|
|
||||||
%% Give listener keyusage is clientAuth
|
%% Give listener keyusage is clientAuth
|
||||||
|
@ -308,7 +298,7 @@ t_conn_fail_client_keyusage_unmatch(Config) ->
|
||||||
ok = ssl:close(Socket).
|
ok = ssl:close(Socket).
|
||||||
|
|
||||||
t_conn_fail_client_keyusage_incomplete(Config) ->
|
t_conn_fail_client_keyusage_incomplete(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
%% Give listener keyusage is codeSigning,clientAuth
|
%% Give listener keyusage is codeSigning,clientAuth
|
||||||
Options = [
|
Options = [
|
|
@ -13,7 +13,7 @@
|
||||||
%% See the License for the specific language governing permissions and
|
%% See the License for the specific language governing permissions and
|
||||||
%% limitations under the License.
|
%% limitations under the License.
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
-module(emqx_listener_tls_verify_partial_chain_SUITE).
|
-module(emqx_auth_ext_listener_tls_verify_partial_chain_SUITE).
|
||||||
|
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
@ -22,12 +22,13 @@
|
||||||
-include_lib("common_test/include/ct.hrl").
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
|
||||||
-import(
|
-import(
|
||||||
emqx_test_tls_certs_helper,
|
emqx_auth_ext_test_tls_certs_helper,
|
||||||
[
|
[
|
||||||
emqx_start_listener/4,
|
emqx_start_listener/4,
|
||||||
fail_when_ssl_error/1,
|
fail_when_ssl_error/1,
|
||||||
fail_when_no_ssl_alert/2,
|
fail_when_no_ssl_alert/2,
|
||||||
generate_tls_certs/1
|
generate_tls_certs/1,
|
||||||
|
select_free_port/1
|
||||||
]
|
]
|
||||||
).
|
).
|
||||||
|
|
||||||
|
@ -42,7 +43,7 @@ end_per_suite(_Config) ->
|
||||||
application:stop(esockd).
|
application:stop(esockd).
|
||||||
|
|
||||||
t_conn_success_with_server_intermediate_cacert_and_client_cert(Config) ->
|
t_conn_success_with_server_intermediate_cacert_and_client_cert(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options,
|
{ssl_options,
|
||||||
|
@ -68,7 +69,7 @@ t_conn_success_with_server_intermediate_cacert_and_client_cert(Config) ->
|
||||||
ssl:close(Socket).
|
ssl:close(Socket).
|
||||||
|
|
||||||
t_conn_success_with_intermediate_cacert_bundle(Config) ->
|
t_conn_success_with_intermediate_cacert_bundle(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options,
|
{ssl_options,
|
||||||
|
@ -94,7 +95,7 @@ t_conn_success_with_intermediate_cacert_bundle(Config) ->
|
||||||
ssl:close(Socket).
|
ssl:close(Socket).
|
||||||
|
|
||||||
t_conn_success_with_renewed_intermediate_cacert(Config) ->
|
t_conn_success_with_renewed_intermediate_cacert(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options,
|
{ssl_options,
|
||||||
|
@ -120,7 +121,7 @@ t_conn_success_with_renewed_intermediate_cacert(Config) ->
|
||||||
ssl:close(Socket).
|
ssl:close(Socket).
|
||||||
|
|
||||||
t_conn_fail_with_renewed_intermediate_cacert_and_client_using_old_complete_bundle(Config) ->
|
t_conn_fail_with_renewed_intermediate_cacert_and_client_using_old_complete_bundle(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options,
|
{ssl_options,
|
||||||
|
@ -145,7 +146,7 @@ t_conn_fail_with_renewed_intermediate_cacert_and_client_using_old_complete_bundl
|
||||||
fail_when_no_ssl_alert(Res, unknown_ca).
|
fail_when_no_ssl_alert(Res, unknown_ca).
|
||||||
|
|
||||||
t_conn_fail_with_renewed_intermediate_cacert_and_client_using_old_bundle(Config) ->
|
t_conn_fail_with_renewed_intermediate_cacert_and_client_using_old_bundle(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options,
|
{ssl_options,
|
||||||
|
@ -172,7 +173,7 @@ t_conn_fail_with_renewed_intermediate_cacert_and_client_using_old_bundle(Config)
|
||||||
t_conn_success_with_old_and_renewed_intermediate_cacert_and_client_provides_renewed_client_cert(
|
t_conn_success_with_old_and_renewed_intermediate_cacert_and_client_provides_renewed_client_cert(
|
||||||
Config
|
Config
|
||||||
) ->
|
) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options,
|
{ssl_options,
|
||||||
|
@ -202,7 +203,7 @@ t_conn_success_with_old_and_renewed_intermediate_cacert_and_client_provides_rene
|
||||||
t_conn_success_with_new_intermediate_cacert_and_client_provides_renewed_client_cert_signed_by_old_intermediate(
|
t_conn_success_with_new_intermediate_cacert_and_client_provides_renewed_client_cert_signed_by_old_intermediate(
|
||||||
Config
|
Config
|
||||||
) ->
|
) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options,
|
{ssl_options,
|
||||||
|
@ -229,7 +230,7 @@ t_conn_success_with_new_intermediate_cacert_and_client_provides_renewed_client_c
|
||||||
|
|
||||||
%% @doc server should build a partial_chain with old version of ca cert.
|
%% @doc server should build a partial_chain with old version of ca cert.
|
||||||
t_conn_success_with_old_and_renewed_intermediate_cacert_and_client_provides_client_cert(Config) ->
|
t_conn_success_with_old_and_renewed_intermediate_cacert_and_client_provides_client_cert(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options,
|
{ssl_options,
|
||||||
|
@ -257,7 +258,7 @@ t_conn_success_with_old_and_renewed_intermediate_cacert_and_client_provides_clie
|
||||||
|
|
||||||
%% @doc verify when config does not allow two versions of certs from same trusted CA.
|
%% @doc verify when config does not allow two versions of certs from same trusted CA.
|
||||||
t_conn_fail_with_renewed_and_old_intermediate_cacert_and_client_using_old_bundle(Config) ->
|
t_conn_fail_with_renewed_and_old_intermediate_cacert_and_client_using_old_bundle(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options,
|
{ssl_options,
|
||||||
|
@ -285,7 +286,7 @@ t_conn_fail_with_renewed_and_old_intermediate_cacert_and_client_using_old_bundle
|
||||||
t_001_conn_success_with_old_and_renewed_intermediate_cacert_bundle_and_client_using_old_bundle(
|
t_001_conn_success_with_old_and_renewed_intermediate_cacert_bundle_and_client_using_old_bundle(
|
||||||
Config
|
Config
|
||||||
) ->
|
) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options,
|
{ssl_options,
|
||||||
|
@ -318,7 +319,7 @@ t_001_conn_success_with_old_and_renewed_intermediate_cacert_bundle_and_client_us
|
||||||
%% Oldintermediate2Cert (trusted CA cert).
|
%% Oldintermediate2Cert (trusted CA cert).
|
||||||
%% @end
|
%% @end
|
||||||
t_conn_fail_with_old_and_renewed_intermediate_cacert_bundle_and_client_using_all_CAcerts(Config) ->
|
t_conn_fail_with_old_and_renewed_intermediate_cacert_bundle_and_client_using_all_CAcerts(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options,
|
{ssl_options,
|
||||||
|
@ -344,7 +345,7 @@ t_conn_fail_with_old_and_renewed_intermediate_cacert_bundle_and_client_using_all
|
||||||
fail_when_no_ssl_alert(Res, unknown_ca).
|
fail_when_no_ssl_alert(Res, unknown_ca).
|
||||||
|
|
||||||
t_conn_fail_with_renewed_intermediate_cacert_other_client(Config) ->
|
t_conn_fail_with_renewed_intermediate_cacert_other_client(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options,
|
{ssl_options,
|
||||||
|
@ -369,7 +370,7 @@ t_conn_fail_with_renewed_intermediate_cacert_other_client(Config) ->
|
||||||
fail_when_no_ssl_alert(Res, unknown_ca).
|
fail_when_no_ssl_alert(Res, unknown_ca).
|
||||||
|
|
||||||
t_conn_fail_with_intermediate_cacert_bundle_but_incorrect_order(Config) ->
|
t_conn_fail_with_intermediate_cacert_bundle_but_incorrect_order(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options,
|
{ssl_options,
|
||||||
|
@ -394,7 +395,7 @@ t_conn_fail_with_intermediate_cacert_bundle_but_incorrect_order(Config) ->
|
||||||
fail_when_no_ssl_alert(Res, unknown_ca).
|
fail_when_no_ssl_alert(Res, unknown_ca).
|
||||||
|
|
||||||
t_conn_fail_when_singed_by_other_intermediate_ca(Config) ->
|
t_conn_fail_when_singed_by_other_intermediate_ca(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options,
|
{ssl_options,
|
||||||
|
@ -419,7 +420,7 @@ t_conn_fail_when_singed_by_other_intermediate_ca(Config) ->
|
||||||
fail_when_no_ssl_alert(Res, unknown_ca).
|
fail_when_no_ssl_alert(Res, unknown_ca).
|
||||||
|
|
||||||
t_conn_success_with_complete_chain_that_server_root_cacert_and_client_complete_cert_chain(Config) ->
|
t_conn_success_with_complete_chain_that_server_root_cacert_and_client_complete_cert_chain(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options,
|
{ssl_options,
|
||||||
|
@ -445,7 +446,7 @@ t_conn_success_with_complete_chain_that_server_root_cacert_and_client_complete_c
|
||||||
ok = ssl:close(Socket).
|
ok = ssl:close(Socket).
|
||||||
|
|
||||||
t_conn_fail_with_other_client_complete_cert_chain(Config) ->
|
t_conn_fail_with_other_client_complete_cert_chain(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options,
|
{ssl_options,
|
||||||
|
@ -470,7 +471,7 @@ t_conn_fail_with_other_client_complete_cert_chain(Config) ->
|
||||||
fail_when_no_ssl_alert(Res, unknown_ca).
|
fail_when_no_ssl_alert(Res, unknown_ca).
|
||||||
|
|
||||||
t_conn_fail_with_server_intermediate_and_other_client_complete_cert_chain(Config) ->
|
t_conn_fail_with_server_intermediate_and_other_client_complete_cert_chain(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options,
|
{ssl_options,
|
||||||
|
@ -496,7 +497,7 @@ t_conn_fail_with_server_intermediate_and_other_client_complete_cert_chain(Config
|
||||||
ok = ssl:close(Socket).
|
ok = ssl:close(Socket).
|
||||||
|
|
||||||
t_conn_success_with_server_intermediate_cacert_and_client_complete_chain(Config) ->
|
t_conn_success_with_server_intermediate_cacert_and_client_complete_chain(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options,
|
{ssl_options,
|
||||||
|
@ -522,7 +523,7 @@ t_conn_success_with_server_intermediate_cacert_and_client_complete_chain(Config)
|
||||||
ok = ssl:close(Socket).
|
ok = ssl:close(Socket).
|
||||||
|
|
||||||
t_conn_fail_with_server_intermediate_chain_and_client_other_incomplete_cert_chain(Config) ->
|
t_conn_fail_with_server_intermediate_chain_and_client_other_incomplete_cert_chain(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options,
|
{ssl_options,
|
||||||
|
@ -547,7 +548,7 @@ t_conn_fail_with_server_intermediate_chain_and_client_other_incomplete_cert_chai
|
||||||
fail_when_no_ssl_alert(Res, unknown_ca).
|
fail_when_no_ssl_alert(Res, unknown_ca).
|
||||||
|
|
||||||
t_conn_fail_with_server_intermediate_and_other_client_root_chain(Config) ->
|
t_conn_fail_with_server_intermediate_and_other_client_root_chain(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options,
|
{ssl_options,
|
||||||
|
@ -572,7 +573,7 @@ t_conn_fail_with_server_intermediate_and_other_client_root_chain(Config) ->
|
||||||
fail_when_no_ssl_alert(Res, unknown_ca).
|
fail_when_no_ssl_alert(Res, unknown_ca).
|
||||||
|
|
||||||
t_conn_success_with_server_intermediate_and_client_root_chain(Config) ->
|
t_conn_success_with_server_intermediate_and_client_root_chain(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options,
|
{ssl_options,
|
||||||
|
@ -599,7 +600,7 @@ t_conn_success_with_server_intermediate_and_client_root_chain(Config) ->
|
||||||
|
|
||||||
%% @doc once rootCA cert present in cacertfile, sibling CA signed Client cert could connect.
|
%% @doc once rootCA cert present in cacertfile, sibling CA signed Client cert could connect.
|
||||||
t_conn_success_with_server_all_CA_bundle_and_client_root_chain(Config) ->
|
t_conn_success_with_server_all_CA_bundle_and_client_root_chain(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options,
|
{ssl_options,
|
||||||
|
@ -625,7 +626,7 @@ t_conn_success_with_server_all_CA_bundle_and_client_root_chain(Config) ->
|
||||||
ok = ssl:close(Socket).
|
ok = ssl:close(Socket).
|
||||||
|
|
||||||
t_conn_fail_with_server_two_IA_bundle_and_client_root_chain(Config) ->
|
t_conn_fail_with_server_two_IA_bundle_and_client_root_chain(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options,
|
{ssl_options,
|
||||||
|
@ -650,7 +651,7 @@ t_conn_fail_with_server_two_IA_bundle_and_client_root_chain(Config) ->
|
||||||
fail_when_no_ssl_alert(Res, unknown_ca).
|
fail_when_no_ssl_alert(Res, unknown_ca).
|
||||||
|
|
||||||
t_conn_fail_with_server_partial_chain_false_intermediate_cacert_and_client_cert(Config) ->
|
t_conn_fail_with_server_partial_chain_false_intermediate_cacert_and_client_cert(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Options = [
|
Options = [
|
||||||
{ssl_options,
|
{ssl_options,
|
||||||
|
@ -676,7 +677,7 @@ t_conn_fail_with_server_partial_chain_false_intermediate_cacert_and_client_cert(
|
||||||
fail_when_no_ssl_alert(Res, unknown_ca).
|
fail_when_no_ssl_alert(Res, unknown_ca).
|
||||||
|
|
||||||
t_error_handling_invalid_cacertfile(Config) ->
|
t_error_handling_invalid_cacertfile(Config) ->
|
||||||
Port = emqx_test_tls_certs_helper:select_free_port(ssl),
|
Port = select_free_port(ssl),
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
%% trigger error
|
%% trigger error
|
||||||
Options = [
|
Options = [
|
|
@ -1,20 +1,8 @@
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Copyright (c) 2024 EMQ Technologies Co., Ltd. All Rights Reserved.
|
%% Copyright (c) 2024 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||||
%%
|
|
||||||
%% Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
%% you may not use this file except in compliance with the License.
|
|
||||||
%% You may obtain a copy of the License at
|
|
||||||
%%
|
|
||||||
%% http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
%%
|
|
||||||
%% Unless required by applicable law or agreed to in writing, software
|
|
||||||
%% distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
%% See the License for the specific language governing permissions and
|
|
||||||
%% limitations under the License.
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
-module(emqx_test_tls_certs_helper).
|
-module(emqx_auth_ext_test_tls_certs_helper).
|
||||||
-export([
|
-export([
|
||||||
gen_ca/2,
|
gen_ca/2,
|
||||||
gen_host_cert/3,
|
gen_host_cert/3,
|
|
@ -1,6 +1,6 @@
|
||||||
{application, emqx_conf, [
|
{application, emqx_conf, [
|
||||||
{description, "EMQX configuration management"},
|
{description, "EMQX configuration management"},
|
||||||
{vsn, "0.2.0"},
|
{vsn, "0.2.1"},
|
||||||
{registered, []},
|
{registered, []},
|
||||||
{mod, {emqx_conf_app, []}},
|
{mod, {emqx_conf_app, []}},
|
||||||
{applications, [kernel, stdlib]},
|
{applications, [kernel, stdlib]},
|
||||||
|
|
|
@ -70,9 +70,19 @@
|
||||||
emqx_otel_schema,
|
emqx_otel_schema,
|
||||||
emqx_mgmt_api_key_schema
|
emqx_mgmt_api_key_schema
|
||||||
]).
|
]).
|
||||||
|
|
||||||
|
-define(AUTH_EXT_SCHEMA_MODS, [emqx_auth_ext_schema]).
|
||||||
|
|
||||||
|
-if(defined(EMQX_RELEASE_EDITION) andalso ?EMQX_RELEASE_EDITION == ee).
|
||||||
|
-define(OTHER_INJECTING_CONFIGS, ?AUTH_EXT_SCHEMA_MODS).
|
||||||
|
-else.
|
||||||
|
-define(OTHER_INJECTING_CONFIGS, []).
|
||||||
|
-endif.
|
||||||
|
|
||||||
-define(INJECTING_CONFIGS, [
|
-define(INJECTING_CONFIGS, [
|
||||||
{emqx_authn_schema, ?AUTHN_PROVIDER_SCHEMA_MODS},
|
{emqx_authn_schema, ?AUTHN_PROVIDER_SCHEMA_MODS},
|
||||||
{emqx_authz_schema, ?AUTHZ_SOURCE_SCHEMA_MODS}
|
{emqx_authz_schema, ?AUTHZ_SOURCE_SCHEMA_MODS}
|
||||||
|
| ?OTHER_INJECTING_CONFIGS
|
||||||
]).
|
]).
|
||||||
|
|
||||||
%% 1 million default ports counter
|
%% 1 million default ports counter
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
%% -*- mode: erlang -*-
|
%% -*- mode: erlang -*-
|
||||||
{application, emqx_gateway, [
|
{application, emqx_gateway, [
|
||||||
{description, "The Gateway management application"},
|
{description, "The Gateway management application"},
|
||||||
{vsn, "0.1.32"},
|
{vsn, "0.1.33"},
|
||||||
{registered, []},
|
{registered, []},
|
||||||
{mod, {emqx_gateway_app, []}},
|
{mod, {emqx_gateway_app, []}},
|
||||||
{applications, [kernel, stdlib, emqx, emqx_auth, emqx_ctl]},
|
{applications, [kernel, stdlib, emqx, emqx_auth, emqx_ctl]},
|
||||||
|
|
|
@ -588,11 +588,21 @@ ssl_server_opts(SSLOpts, ssl_options) ->
|
||||||
ssl_server_opts(SSLOpts, dtls_options) ->
|
ssl_server_opts(SSLOpts, dtls_options) ->
|
||||||
emqx_tls_lib:to_server_opts(dtls, SSLOpts).
|
emqx_tls_lib:to_server_opts(dtls, SSLOpts).
|
||||||
|
|
||||||
|
-if(defined(EMQX_RELEASE_EDITION) andalso ?EMQX_RELEASE_EDITION == ee).
|
||||||
ssl_partial_chain(SSLOpts, _Options) ->
|
ssl_partial_chain(SSLOpts, _Options) ->
|
||||||
emqx_tls_lib:opt_partial_chain(SSLOpts).
|
emqx_auth_ext_tls_lib:opt_partial_chain(SSLOpts).
|
||||||
|
-else.
|
||||||
|
ssl_partial_chain(SSLOpts, _) ->
|
||||||
|
SSLOpts.
|
||||||
|
-endif.
|
||||||
|
|
||||||
|
-if(defined(EMQX_RELEASE_EDITION) andalso ?EMQX_RELEASE_EDITION == ee).
|
||||||
ssl_verify_fun(SSLOpts, _Options) ->
|
ssl_verify_fun(SSLOpts, _Options) ->
|
||||||
emqx_tls_lib:opt_verify_fun(SSLOpts).
|
emqx_auth_ext_tls_lib:opt_verify_fun(SSLOpts).
|
||||||
|
-else.
|
||||||
|
ssl_verify_fun(SSLOpts, _) ->
|
||||||
|
SSLOpts.
|
||||||
|
-endif.
|
||||||
|
|
||||||
ranch_opts(Type, ListenOn, Opts) ->
|
ranch_opts(Type, ListenOn, Opts) ->
|
||||||
NumAcceptors = maps:get(acceptors, Opts, 4),
|
NumAcceptors = maps:get(acceptors, Opts, 4),
|
||||||
|
|
|
@ -129,7 +129,8 @@
|
||||||
emqx_gateway_ocpp,
|
emqx_gateway_ocpp,
|
||||||
emqx_gateway_jt808,
|
emqx_gateway_jt808,
|
||||||
emqx_bridge_syskeeper,
|
emqx_bridge_syskeeper,
|
||||||
emqx_bridge_confluent
|
emqx_bridge_confluent,
|
||||||
|
emqx_auth_ext
|
||||||
],
|
],
|
||||||
%% must always be of type `load'
|
%% must always be of type `load'
|
||||||
ce_business_apps =>
|
ce_business_apps =>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
{id, "emqx_machine"},
|
{id, "emqx_machine"},
|
||||||
{description, "The EMQX Machine"},
|
{description, "The EMQX Machine"},
|
||||||
% strict semver, bump manually!
|
% strict semver, bump manually!
|
||||||
{vsn, "0.3.0"},
|
{vsn, "0.3.1"},
|
||||||
{modules, []},
|
{modules, []},
|
||||||
{registered, []},
|
{registered, []},
|
||||||
{applications, [kernel, stdlib, emqx_ctl]},
|
{applications, [kernel, stdlib, emqx_ctl]},
|
||||||
|
|
3
mix.exs
3
mix.exs
|
@ -200,7 +200,8 @@ defmodule EMQXUmbrella.MixProject do
|
||||||
:emqx_gateway_gbt32960,
|
:emqx_gateway_gbt32960,
|
||||||
:emqx_gateway_ocpp,
|
:emqx_gateway_ocpp,
|
||||||
:emqx_gateway_jt808,
|
:emqx_gateway_jt808,
|
||||||
:emqx_bridge_syskeeper
|
:emqx_bridge_syskeeper,
|
||||||
|
:emqx_auth_ext
|
||||||
])
|
])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -119,6 +119,7 @@ is_community_umbrella_app("apps/emqx_bridge_syskeeper") -> false;
|
||||||
is_community_umbrella_app("apps/emqx_schema_validation") -> false;
|
is_community_umbrella_app("apps/emqx_schema_validation") -> false;
|
||||||
is_community_umbrella_app("apps/emqx_eviction_agent") -> false;
|
is_community_umbrella_app("apps/emqx_eviction_agent") -> false;
|
||||||
is_community_umbrella_app("apps/emqx_node_rebalance") -> false;
|
is_community_umbrella_app("apps/emqx_node_rebalance") -> false;
|
||||||
|
is_community_umbrella_app("apps/emqx_auth_ext") -> false;
|
||||||
is_community_umbrella_app(_) -> true.
|
is_community_umbrella_app(_) -> true.
|
||||||
|
|
||||||
%% BUILD_WITHOUT_JQ
|
%% BUILD_WITHOUT_JQ
|
||||||
|
|
Loading…
Reference in New Issue