Skip to content

Commit 3c79f6d

Browse files
committed
Add support for various TLS options:
* versions * depth * multiple CA cert pem data
1 parent 6e52133 commit 3c79f6d

File tree

2 files changed

+124
-30
lines changed

2 files changed

+124
-30
lines changed

deps/rabbitmq_auth_backend_ldap/src/rabbit_auth_backend_ldap_mgmt.erl

Lines changed: 82 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
accept_content/2]).
2020

2121

22+
-include_lib("kernel/include/logger.hrl").
2223
-include_lib("rabbitmq_web_dispatch/include/rabbitmq_web_dispatch_records.hrl").
2324

2425
dispatcher() -> [{"/ldap/validate/simple-bind", ?MODULE, []}].
@@ -54,31 +55,35 @@ accept_content(ReqData0, Context) ->
5455
{port, Port},
5556
{timeout, 5000}
5657
],
57-
{ok, Options1} = maybe_add_ssl_options(Options0, UseSsl, BodyMap),
58-
case eldap:open(Servers, Options1) of
59-
{ok, LDAP} ->
60-
Result = case maybe_starttls(LDAP, UseStartTls, BodyMap) of
61-
ok ->
62-
case eldap:simple_bind(LDAP, UserDN, Password) of
63-
ok ->
64-
{true, ReqData1, Context};
65-
{error, invalidCredentials} ->
66-
rabbit_mgmt_util:not_authorised("invalid credentials", ReqData1, Context);
67-
{error, unwillingToPerform} ->
68-
rabbit_mgmt_util:not_authorised("invalid credentials", ReqData1, Context);
69-
{error, E} ->
70-
Reason = unicode_format(E),
71-
rabbit_mgmt_util:bad_request(Reason, ReqData1, Context)
72-
end;
73-
Error ->
74-
Reason = unicode_format(Error),
75-
rabbit_mgmt_util:bad_request(Reason, ReqData1, Context)
76-
end,
77-
eldap:close(LDAP),
78-
Result;
79-
{error, E} ->
80-
Reason = unicode_format(E),
81-
rabbit_mgmt_util:bad_request(Reason, ReqData1, Context)
58+
try
59+
{ok, Options1} = maybe_add_ssl_options(Options0, UseSsl, BodyMap),
60+
case eldap:open(Servers, Options1) of
61+
{ok, LDAP} ->
62+
Result = case maybe_starttls(LDAP, UseStartTls, BodyMap) of
63+
ok ->
64+
case eldap:simple_bind(LDAP, UserDN, Password) of
65+
ok ->
66+
{true, ReqData1, Context};
67+
{error, invalidCredentials} ->
68+
rabbit_mgmt_util:not_authorised("invalid credentials", ReqData1, Context);
69+
{error, unwillingToPerform} ->
70+
rabbit_mgmt_util:not_authorised("invalid credentials", ReqData1, Context);
71+
{error, E} ->
72+
Reason = unicode_format(E),
73+
rabbit_mgmt_util:bad_request(Reason, ReqData1, Context)
74+
end;
75+
Error ->
76+
Reason = unicode_format(Error),
77+
rabbit_mgmt_util:bad_request(Reason, ReqData1, Context)
78+
end,
79+
eldap:close(LDAP),
80+
Result;
81+
{error, E} ->
82+
Reason = unicode_format(E),
83+
rabbit_mgmt_util:bad_request(Reason, ReqData1, Context)
84+
end
85+
catch throw:{bad_request, ErrMsg} ->
86+
rabbit_mgmt_util:bad_request(ErrMsg, ReqData1, Context)
8287
end
8388
end,
8489
rabbit_mgmt_util:with_decode([], ReqData0, Context, F).
@@ -119,11 +124,59 @@ tls_options(BodyMap) ->
119124
CaCertfile ->
120125
[{cacertfile, CaCertfile}]
121126
end,
122-
TlsOpts1 = case maps:get(<<"server_name_indication">>, SslOptionsMap, disable) of
123-
disable ->
127+
TlsOpts1 = case maps:get(<<"cacert_pem_data">>, SslOptionsMap, undefined) of
128+
undefined ->
124129
TlsOpts0;
130+
CaCertPems when is_list(CaCertPems) ->
131+
F0 = fun (P) ->
132+
case public_key:pem_decode(P) of
133+
[{'Certificate', CaCertDerEncoded, not_encrypted}] ->
134+
{true, CaCertDerEncoded};
135+
_Unexpected ->
136+
throw({bad_request, "unexpected cacert_pem_data passed to "
137+
"/ldap/validate/simple-bind ssl_options.cacerts"})
138+
end
139+
end,
140+
CaCertsDerEncoded = lists:filtermap(F0, CaCertPems),
141+
[{cacerts, CaCertsDerEncoded} | TlsOpts0];
142+
_ ->
143+
TlsOpts0
144+
end,
145+
TlsOpts2 = case maps:get(<<"verify">>, SslOptionsMap, undefined) of
146+
undefined ->
147+
TlsOpts1;
148+
Verify ->
149+
VerifyStr = unicode:characters_to_list(Verify),
150+
[{verify, list_to_existing_atom(VerifyStr)} | TlsOpts1]
151+
end,
152+
TlsOpts3 = case maps:get(<<"server_name_indication">>, SslOptionsMap, disable) of
153+
disable ->
154+
TlsOpts2;
125155
SniValue ->
126-
[{server_name_indication, SniValue} | TlsOpts0]
156+
SniStr = unicode:characters_to_list(SniValue),
157+
[{server_name_indication, SniStr} | TlsOpts2]
158+
end,
159+
TlsOpts4 = case maps:get(<<"depth">>, SslOptionsMap, undefined) of
160+
undefined ->
161+
TlsOpts3;
162+
DepthValue ->
163+
Depth = rabbit_data_coercion:to_integer(DepthValue),
164+
[{depth, Depth} | TlsOpts3]
165+
end,
166+
TlsOpts5 = case maps:get(<<"versions">>, SslOptionsMap, undefined) of
167+
undefined ->
168+
TlsOpts4;
169+
VersionStrs when is_list(VersionStrs) ->
170+
F1 = fun (VStr) ->
171+
try
172+
{true, list_to_existing_atom(VStr)}
173+
catch error:badarg ->
174+
throw({bad_request, "invalid TLS version passed to "
175+
"/ldap/validate/simple-bind ssl_options.versions"})
176+
end
177+
end,
178+
Versions = lists:filtermap(F1, VersionStrs),
179+
[{versions, Versions} | TlsOpts4]
127180
end,
128-
{ok, TlsOpts1}
181+
{ok, TlsOpts5}
129182
end.

deps/rabbitmq_auth_backend_ldap/test/system_SUITE.erl

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,18 @@ validate_ldap_configuration_via_api(Config) ->
341341
'cacertfile' => CaCertfile
342342
}
343343
}, ?NO_CONTENT),
344+
http_put(Config, "/ldap/validate/simple-bind",
345+
#{
346+
'user_dn' => AliceUserDN,
347+
'password' => Password,
348+
'servers' => ["localhost"],
349+
'port' => LdapTlsPort,
350+
'use_ssl' => true,
351+
'ssl_options' => #{
352+
'server_name_indication' => "localhost",
353+
'cacertfile' => CaCertfile
354+
}
355+
}, ?NO_CONTENT),
344356
http_put(Config, "/ldap/validate/simple-bind",
345357
#{
346358
'user_dn' => AliceUserDN,
@@ -353,7 +365,36 @@ validate_ldap_configuration_via_api(Config) ->
353365
'server_name_indication' => "localhost",
354366
'cacertfile' => CaCertfile
355367
}
356-
}, ?NO_CONTENT).
368+
}, ?NO_CONTENT),
369+
{ok, CaCertfileContent} = file:read_file(CaCertfile),
370+
http_put(Config, "/ldap/validate/simple-bind",
371+
#{
372+
'user_dn' => AliceUserDN,
373+
'password' => Password,
374+
'servers' => ["localhost"],
375+
'port' => LdapTlsPort,
376+
'use_ssl' => true,
377+
'ssl_options' => #{
378+
'versions' => ["tlsv1.2", "tlsv1.3"],
379+
'depth' => 8,
380+
'verify' => "verify_peer",
381+
'cacert_pem_data' => [CaCertfileContent, CaCertfileContent]
382+
}
383+
}, ?NO_CONTENT),
384+
http_put(Config, "/ldap/validate/simple-bind",
385+
#{
386+
'user_dn' => AliceUserDN,
387+
'password' => Password,
388+
'servers' => ["localhost"],
389+
'port' => LdapTlsPort,
390+
'use_ssl' => true,
391+
'ssl_options' => #{
392+
'versions' => ["tlsfoobar", "tlsv1.3"],
393+
'depth' => 8,
394+
'verify' => "verify_peer",
395+
'cacert_pem_data' => [CaCertfileContent, CaCertfileContent]
396+
}
397+
}, ?BAD_REQUEST).
357398

358399
purge_connection(Config) ->
359400
{ok, _} = rabbit_ct_broker_helpers:rpc(Config, 0,

0 commit comments

Comments
 (0)