mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-22 16:20:52 +01:00
Rely on Server Name Indication for incoming Direct-TLS connections
This commit also deprecates `certfile` option for ejabberd_http listener.
This commit is contained in:
parent
b54e1e49ba
commit
1698956f34
@ -22,7 +22,7 @@
|
|||||||
{tag, {if_version_above, "17", "3.4.2", "3.2.1"}}}},
|
{tag, {if_version_above, "17", "3.4.2", "3.2.1"}}}},
|
||||||
{p1_utils, ".*", {git, "https://github.com/processone/p1_utils", {tag, "1.0.10"}}},
|
{p1_utils, ".*", {git, "https://github.com/processone/p1_utils", {tag, "1.0.10"}}},
|
||||||
{cache_tab, ".*", {git, "https://github.com/processone/cache_tab", {tag, "1.0.12"}}},
|
{cache_tab, ".*", {git, "https://github.com/processone/cache_tab", {tag, "1.0.12"}}},
|
||||||
{fast_tls, ".*", {git, "https://github.com/processone/fast_tls", {tag, "1.0.17"}}},
|
{fast_tls, ".*", {git, "https://github.com/processone/fast_tls", "ac507f2"}},
|
||||||
{stringprep, ".*", {git, "https://github.com/processone/stringprep", {tag, "1.0.10"}}},
|
{stringprep, ".*", {git, "https://github.com/processone/stringprep", {tag, "1.0.10"}}},
|
||||||
{fast_xml, ".*", {git, "https://github.com/processone/fast_xml", "f22a56d"}},
|
{fast_xml, ".*", {git, "https://github.com/processone/fast_xml", "f22a56d"}},
|
||||||
{xmpp, ".*", {git, "https://github.com/processone/xmpp", "597d78b"}},
|
{xmpp, ".*", {git, "https://github.com/processone/xmpp", "597d78b"}},
|
||||||
|
@ -97,8 +97,7 @@ start_link(SockData, Opts) ->
|
|||||||
|
|
||||||
init({SockMod, Socket}, Opts) ->
|
init({SockMod, Socket}, Opts) ->
|
||||||
TLSEnabled = proplists:get_bool(tls, Opts),
|
TLSEnabled = proplists:get_bool(tls, Opts),
|
||||||
TLSOpts1 = lists:filter(fun ({certfile, _}) -> true;
|
TLSOpts1 = lists:filter(fun ({ciphers, _}) -> true;
|
||||||
({ciphers, _}) -> true;
|
|
||||||
({dhfile, _}) -> true;
|
({dhfile, _}) -> true;
|
||||||
({protocol_options, _}) -> true;
|
({protocol_options, _}) -> true;
|
||||||
(_) -> false
|
(_) -> false
|
||||||
@ -108,7 +107,11 @@ init({SockMod, Socket}, Opts) ->
|
|||||||
false -> [compression_none | TLSOpts1];
|
false -> [compression_none | TLSOpts1];
|
||||||
true -> TLSOpts1
|
true -> TLSOpts1
|
||||||
end,
|
end,
|
||||||
TLSOpts = [verify_none | TLSOpts2],
|
TLSOpts3 = case get_certfile(Opts) of
|
||||||
|
undefined -> TLSOpts2;
|
||||||
|
CertFile -> [{certfile, CertFile}|TLSOpts2]
|
||||||
|
end,
|
||||||
|
TLSOpts = [verify_none | TLSOpts3],
|
||||||
{SockMod1, Socket1} = if TLSEnabled ->
|
{SockMod1, Socket1} = if TLSEnabled ->
|
||||||
inet:setopts(Socket, [{recbuf, 8192}]),
|
inet:setopts(Socket, [{recbuf, 8192}]),
|
||||||
{ok, TLSSocket} = fast_tls:tcp_to_tls(Socket,
|
{ok, TLSSocket} = fast_tls:tcp_to_tls(Socket,
|
||||||
@ -885,6 +888,20 @@ normalize_path([_Parent, <<"..">>|Path], Norm) ->
|
|||||||
normalize_path([Part | Path], Norm) ->
|
normalize_path([Part | Path], Norm) ->
|
||||||
normalize_path(Path, [Part|Norm]).
|
normalize_path(Path, [Part|Norm]).
|
||||||
|
|
||||||
|
-spec get_certfile([proplists:property()]) -> binary() | undefined.
|
||||||
|
get_certfile(Opts) ->
|
||||||
|
case lists:keyfind(certfile, 1, Opts) of
|
||||||
|
{_, CertFile} ->
|
||||||
|
CertFile;
|
||||||
|
false ->
|
||||||
|
case ejabberd_pkix:get_certfile(?MYNAME) of
|
||||||
|
{ok, CertFile} ->
|
||||||
|
CertFile;
|
||||||
|
error ->
|
||||||
|
ejabberd_config:get_option({domain_certfile, ?MYNAME})
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
||||||
transform_listen_option(captcha, Opts) ->
|
transform_listen_option(captcha, Opts) ->
|
||||||
[{captcha, true}|Opts];
|
[{captcha, true}|Opts];
|
||||||
transform_listen_option(register, Opts) ->
|
transform_listen_option(register, Opts) ->
|
||||||
@ -933,8 +950,10 @@ opt_type(_) -> [trusted_proxies].
|
|||||||
(atom()) -> [atom()].
|
(atom()) -> [atom()].
|
||||||
listen_opt_type(tls) ->
|
listen_opt_type(tls) ->
|
||||||
fun(B) when is_boolean(B) -> B end;
|
fun(B) when is_boolean(B) -> B end;
|
||||||
listen_opt_type(certfile) ->
|
listen_opt_type(certfile = Opt) ->
|
||||||
fun(S) ->
|
fun(S) ->
|
||||||
|
?WARNING_MSG("Listening option '~s' for ~s is deprecated, use "
|
||||||
|
"'certfiles' global option instead", [Opt, ?MODULE]),
|
||||||
ejabberd_pkix:add_certfile(S),
|
ejabberd_pkix:add_certfile(S),
|
||||||
iolist_to_binary(S)
|
iolist_to_binary(S)
|
||||||
end;
|
end;
|
||||||
|
@ -390,6 +390,7 @@ build_chain_and_check(State) ->
|
|||||||
ets:delete_all_objects(?MODULE),
|
ets:delete_all_objects(?MODULE),
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun({Path, Domain}) ->
|
fun({Path, Domain}) ->
|
||||||
|
fast_tls:add_certfile(Domain, Path),
|
||||||
ets:insert(?MODULE, {Domain, Path})
|
ets:insert(?MODULE, {Domain, Path})
|
||||||
end, CertFilesWithDomains),
|
end, CertFilesWithDomains),
|
||||||
?DEBUG("Validating certificates", []),
|
?DEBUG("Validating certificates", []),
|
||||||
|
@ -44,12 +44,14 @@ start(_, _) ->
|
|||||||
-export([tcp_init/2, udp_init/2, udp_recv/5, start/2,
|
-export([tcp_init/2, udp_init/2, udp_recv/5, start/2,
|
||||||
socket_type/0, listen_opt_type/1]).
|
socket_type/0, listen_opt_type/1]).
|
||||||
|
|
||||||
|
-include("ejabberd.hrl").
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% API
|
%%% API
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
tcp_init(Socket, Opts) ->
|
tcp_init(Socket, Opts) ->
|
||||||
ejabberd:start_app(esip),
|
ejabberd:start_app(esip),
|
||||||
esip_socket:tcp_init(Socket, Opts).
|
esip_socket:tcp_init(Socket, set_certfile(Opts)).
|
||||||
|
|
||||||
udp_init(Socket, Opts) ->
|
udp_init(Socket, Opts) ->
|
||||||
ejabberd:start_app(esip),
|
ejabberd:start_app(esip),
|
||||||
@ -64,8 +66,28 @@ start(Opaque, Opts) ->
|
|||||||
socket_type() ->
|
socket_type() ->
|
||||||
raw.
|
raw.
|
||||||
|
|
||||||
|
set_certfile(Opts) ->
|
||||||
|
case lists:keymember(certfile, 1, Opts) of
|
||||||
|
true ->
|
||||||
|
Opts;
|
||||||
|
false ->
|
||||||
|
case ejabberd_pkix:get_certfile(?MYNAME) of
|
||||||
|
{ok, CertFile} ->
|
||||||
|
[{certfile, CertFile}|Opts];
|
||||||
|
error ->
|
||||||
|
case ejabberd_config:get_option({domain_certfile, ?MYNAME}) of
|
||||||
|
undefined ->
|
||||||
|
Opts;
|
||||||
|
CertFile ->
|
||||||
|
[{certfile, CertFile}|Opts]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
||||||
listen_opt_type(certfile) ->
|
listen_opt_type(certfile) ->
|
||||||
fun(S) ->
|
fun(S) ->
|
||||||
|
%% We cannot deprecate the option for now:
|
||||||
|
%% I think STUN/TURN clients are too stupid to set SNI
|
||||||
ejabberd_pkix:add_certfile(S),
|
ejabberd_pkix:add_certfile(S),
|
||||||
iolist_to_binary(S)
|
iolist_to_binary(S)
|
||||||
end;
|
end;
|
||||||
|
@ -77,7 +77,7 @@ prepare_turn_opts(Opts) ->
|
|||||||
prepare_turn_opts(Opts, UseTurn).
|
prepare_turn_opts(Opts, UseTurn).
|
||||||
|
|
||||||
prepare_turn_opts(Opts, _UseTurn = false) ->
|
prepare_turn_opts(Opts, _UseTurn = false) ->
|
||||||
Opts;
|
set_certfile(Opts);
|
||||||
prepare_turn_opts(Opts, _UseTurn = true) ->
|
prepare_turn_opts(Opts, _UseTurn = true) ->
|
||||||
NumberOfMyHosts = length(?MYHOSTS),
|
NumberOfMyHosts = length(?MYHOSTS),
|
||||||
case proplists:get_value(turn_ip, Opts) of
|
case proplists:get_value(turn_ip, Opts) of
|
||||||
@ -109,8 +109,28 @@ prepare_turn_opts(Opts, _UseTurn = true) ->
|
|||||||
[]
|
[]
|
||||||
end,
|
end,
|
||||||
MaxRate = shaper:get_max_rate(Shaper),
|
MaxRate = shaper:get_max_rate(Shaper),
|
||||||
Realm ++ [{auth_fun, AuthFun},{shaper, MaxRate} |
|
Opts1 = Realm ++ [{auth_fun, AuthFun},{shaper, MaxRate} |
|
||||||
lists:keydelete(shaper, 1, Opts)].
|
lists:keydelete(shaper, 1, Opts)],
|
||||||
|
set_certfile(Opts1).
|
||||||
|
|
||||||
|
set_certfile(Opts) ->
|
||||||
|
case lists:keymember(certfile, 1, Opts) of
|
||||||
|
true ->
|
||||||
|
Opts;
|
||||||
|
false ->
|
||||||
|
Realm = proplists:get_value(auth_realm, Opts, ?MYNAME),
|
||||||
|
case ejabberd_pkix:get_certfile(Realm) of
|
||||||
|
{ok, CertFile} ->
|
||||||
|
[{certfile, CertFile}|Opts];
|
||||||
|
error ->
|
||||||
|
case ejabberd_config:get_option({domain_certfile, Realm}) of
|
||||||
|
undefined ->
|
||||||
|
Opts;
|
||||||
|
CertFile ->
|
||||||
|
[{certfile, CertFile}|Opts]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
||||||
listen_opt_type(use_turn) ->
|
listen_opt_type(use_turn) ->
|
||||||
fun(B) when is_boolean(B) -> B end;
|
fun(B) when is_boolean(B) -> B end;
|
||||||
@ -131,6 +151,8 @@ listen_opt_type(tls) ->
|
|||||||
fun(B) when is_boolean(B) -> B end;
|
fun(B) when is_boolean(B) -> B end;
|
||||||
listen_opt_type(certfile) ->
|
listen_opt_type(certfile) ->
|
||||||
fun(S) ->
|
fun(S) ->
|
||||||
|
%% We cannot deprecate the option for now:
|
||||||
|
%% I think STUN/TURN clients are too stupid to set SNI
|
||||||
ejabberd_pkix:add_certfile(S),
|
ejabberd_pkix:add_certfile(S),
|
||||||
iolist_to_binary(S)
|
iolist_to_binary(S)
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user