mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-28 16:34:13 +01:00
fix eldap certificate verification (#3528)
Reported in #3527. Add hostname matching function, and specify SNI Also, OTP 23 dropped backwards compatibility for 0, 1, 2 values for verify, so replace with combination of verify_none/verify_peer and fail_if_no_peer_cert as appropriate
This commit is contained in:
parent
e3fd120fd4
commit
1f194e417d
@ -96,6 +96,7 @@
|
|||||||
{if_version_above, "20", {d, 'DEPRECATED_GET_STACKTRACE'}},
|
{if_version_above, "20", {d, 'DEPRECATED_GET_STACKTRACE'}},
|
||||||
{if_version_below, "21", {d, 'USE_OLD_HTTP_URI'}},
|
{if_version_below, "21", {d, 'USE_OLD_HTTP_URI'}},
|
||||||
{if_version_below, "22", {d, 'LAGER'}},
|
{if_version_below, "22", {d, 'LAGER'}},
|
||||||
|
{if_version_below, "21", {d, 'NO_CUSTOMIZE_HOSTNAME_CHECK'}},
|
||||||
{if_version_below, "23", {d, 'USE_OLD_CRYPTO_HMAC'}},
|
{if_version_below, "23", {d, 'USE_OLD_CRYPTO_HMAC'}},
|
||||||
{if_version_below, "23", {d, 'USE_OLD_PG2'}},
|
{if_version_below, "23", {d, 'USE_OLD_PG2'}},
|
||||||
{if_var_match, db_type, mssql, {d, 'mssql'}},
|
{if_var_match, db_type, mssql, {d, 'mssql'}},
|
||||||
|
@ -132,7 +132,8 @@
|
|||||||
tls_options = [] :: [{certfile, string()} |
|
tls_options = [] :: [{certfile, string()} |
|
||||||
{cacertfile, string()} |
|
{cacertfile, string()} |
|
||||||
{depth, non_neg_integer()} |
|
{depth, non_neg_integer()} |
|
||||||
{verify, non_neg_integer()}],
|
{verify, non_neg_integer()} |
|
||||||
|
{fail_if_no_peer_cert, boolean()}],
|
||||||
fd :: gen_tcp:socket() | undefined,
|
fd :: gen_tcp:socket() | undefined,
|
||||||
rootdn = <<"">> :: binary(),
|
rootdn = <<"">> :: binary(),
|
||||||
passwd = <<"">> :: binary(),
|
passwd = <<"">> :: binary(),
|
||||||
@ -604,9 +605,9 @@ init([Hosts, Port, Rootdn, Passwd, Opts]) ->
|
|||||||
[]),
|
[]),
|
||||||
CertOpts;
|
CertOpts;
|
||||||
Verify == soft ->
|
Verify == soft ->
|
||||||
[{verify, 1}] ++ CertOpts ++ CacertOpts ++ DepthOpts;
|
[{verify, verify_peer}, {fail_if_no_peer_cert, false}] ++ CertOpts ++ CacertOpts ++ DepthOpts;
|
||||||
Verify == hard ->
|
Verify == hard ->
|
||||||
[{verify, 2}] ++ CertOpts ++ CacertOpts ++ DepthOpts;
|
[{verify, verify_peer}, {fail_if_no_peer_cert, true}] ++ CertOpts ++ CacertOpts ++ DepthOpts;
|
||||||
true -> []
|
true -> []
|
||||||
end,
|
end,
|
||||||
{ok, connecting,
|
{ok, connecting,
|
||||||
@ -1035,22 +1036,40 @@ polish([H | T], Res,
|
|||||||
polish(T, Res, [H | Ref]);
|
polish(T, Res, [H | Ref]);
|
||||||
polish([], Res, Ref) -> {Res, Ref}.
|
polish([], Res, Ref) -> {Res, Ref}.
|
||||||
|
|
||||||
|
|
||||||
|
-ifdef(NO_CUSTOMIZE_HOSTNAME_CHECK).
|
||||||
|
check_hostname_opt(TLSOpts) ->
|
||||||
|
TLSOpts.
|
||||||
|
-else.
|
||||||
|
check_hostname_opt(TLSOpts) ->
|
||||||
|
MatchFun = public_key:pkix_verify_hostname_match_fun(https),
|
||||||
|
[{customize_hostname_check, [{match_fun, MatchFun}]} | TLSOpts].
|
||||||
|
-endif.
|
||||||
|
|
||||||
|
host_tls_options(Host, TLSOpts) ->
|
||||||
|
case proplists:get_value(verify, TLSOpts) of
|
||||||
|
verify_peer ->
|
||||||
|
check_hostname_opt([{server_name_indication, Host} | TLSOpts]);
|
||||||
|
_ ->
|
||||||
|
TLSOpts
|
||||||
|
end.
|
||||||
|
|
||||||
%%-----------------------------------------------------------------------
|
%%-----------------------------------------------------------------------
|
||||||
%% Connect to next server in list and attempt to bind to it.
|
%% Connect to next server in list and attempt to bind to it.
|
||||||
%%-----------------------------------------------------------------------
|
%%-----------------------------------------------------------------------
|
||||||
connect_bind(S) ->
|
connect_bind(S) ->
|
||||||
Host = next_host(S#eldap.host, S#eldap.hosts),
|
Host = next_host(S#eldap.host, S#eldap.hosts),
|
||||||
|
HostS = binary_to_list(Host),
|
||||||
Opts = if S#eldap.tls == tls ->
|
Opts = if S#eldap.tls == tls ->
|
||||||
[{packet, asn1}, {active, true}, {keepalive, true},
|
[{packet, asn1}, {active, true}, {keepalive, true},
|
||||||
binary
|
binary
|
||||||
| S#eldap.tls_options];
|
| host_tls_options(HostS, S#eldap.tls_options)];
|
||||||
true ->
|
true ->
|
||||||
[{packet, asn1}, {active, true}, {keepalive, true},
|
[{packet, asn1}, {active, true}, {keepalive, true},
|
||||||
{send_timeout, ?SEND_TIMEOUT}, binary]
|
{send_timeout, ?SEND_TIMEOUT}, binary]
|
||||||
end,
|
end,
|
||||||
?DEBUG("Connecting to LDAP server at ~ts:~p with options ~p",
|
?DEBUG("Connecting to LDAP server at ~ts:~p with options ~p",
|
||||||
[Host, S#eldap.port, Opts]),
|
[Host, S#eldap.port, Opts]),
|
||||||
HostS = binary_to_list(Host),
|
|
||||||
SockMod = case S#eldap.tls of
|
SockMod = case S#eldap.tls of
|
||||||
tls -> ssl;
|
tls -> ssl;
|
||||||
_ -> gen_tcp
|
_ -> gen_tcp
|
||||||
|
Loading…
Reference in New Issue
Block a user