Skip to content

Commit acee094

Browse files
Add ssl_options to schema
1 parent ea9c637 commit acee094

File tree

7 files changed

+344
-27
lines changed

7 files changed

+344
-27
lines changed

deps/rabbitmq_auth_backend_http/BUILD.bazel

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,15 +94,14 @@ eunit(
9494

9595
broker_for_integration_suites()
9696

97-
rabbitmq_suite(
97+
rabbitmq_integration_suite(
9898
name = "auth_SUITE",
9999
size = "small",
100100
additional_beam = [
101101
"test/auth_http_mock.beam",
102102
],
103103
deps = [
104-
"//deps/rabbit_common:erlang_app",
105-
"@cowboy//:erlang_app",
104+
"@cowboy//:erlang_app"
106105
],
107106
)
108107

deps/rabbitmq_auth_backend_http/priv/schema/rabbitmq_auth_backend_http.schema

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,131 @@
2525

2626
{mapping, "auth_http.connection_timeout", "rabbitmq_auth_backend_http.connection_timeout",
2727
[{datatype, integer}]}.
28+
29+
30+
%% TLS options
31+
32+
33+
{mapping, "auth_http.ssl_options", "rabbitmq_auth_backend_http.ssl_options", [
34+
{datatype, {enum, [none]}}
35+
]}.
36+
37+
{translation, "rabbitmq_auth_backend_http.ssl_options",
38+
fun(Conf) ->
39+
case cuttlefish:conf_get("auth_http.ssl_options", Conf, undefined) of
40+
none -> [];
41+
_ -> cuttlefish:invalid("Invalid auth_http.ssl_options")
42+
end
43+
end}.
44+
45+
{mapping, "auth_http.ssl_options.verify", "rabbitmq_auth_backend_http.ssl_options.verify", [
46+
{datatype, {enum, [verify_peer, verify_none]}}]}.
47+
48+
{mapping, "auth_http.ssl_options.fail_if_no_peer_cert", "rabbitmq_auth_backend_http.ssl_options.fail_if_no_peer_cert", [
49+
{datatype, {enum, [true, false]}}]}.
50+
51+
{mapping, "auth_http.ssl_options.cacertfile", "rabbitmq_auth_backend_http.ssl_options.cacertfile",
52+
[{datatype, string}, {validators, ["file_accessible"]}]}.
53+
54+
{mapping, "auth_http.ssl_options.certfile", "rabbitmq_auth_backend_http.ssl_options.certfile",
55+
[{datatype, string}, {validators, ["file_accessible"]}]}.
56+
57+
{mapping, "auth_http.ssl_options.cacerts.$name", "rabbitmq_auth_backend_http.ssl_options.cacerts",
58+
[{datatype, string}]}.
59+
60+
{translation, "rabbitmq_auth_backend_http.ssl_options.cacerts",
61+
fun(Conf) ->
62+
Settings = cuttlefish_variable:filter_by_prefix("auth_http.ssl_options.cacerts", Conf),
63+
[ list_to_binary(V) || {_, V} <- Settings ]
64+
end}.
65+
66+
{mapping, "auth_http.ssl_options.cert", "rabbitmq_auth_backend_http.ssl_options.cert",
67+
[{datatype, string}]}.
68+
69+
{translation, "rabbitmq_auth_backend_http.ssl_options.cert",
70+
fun(Conf) ->
71+
list_to_binary(cuttlefish:conf_get("auth_http.ssl_options.cert", Conf))
72+
end}.
73+
74+
{mapping, "auth_http.ssl_options.client_renegotiation", "rabbitmq_auth_backend_http.ssl_options.client_renegotiation",
75+
[{datatype, {enum, [true, false]}}]}.
76+
77+
{mapping, "auth_http.ssl_options.crl_check", "rabbitmq_auth_backend_http.ssl_options.crl_check",
78+
[{datatype, [{enum, [true, false, peer, best_effort]}]}]}.
79+
80+
{mapping, "auth_http.ssl_options.depth", "rabbitmq_auth_backend_http.ssl_options.depth",
81+
[{datatype, integer}, {validators, ["byte"]}]}.
82+
83+
{mapping, "auth_http.ssl_options.dh", "rabbitmq_auth_backend_http.ssl_options.dh",
84+
[{datatype, string}]}.
85+
86+
{translation, "rabbitmq_auth_backend_http.ssl_options.dh",
87+
fun(Conf) ->
88+
list_to_binary(cuttlefish:conf_get("auth_http.ssl_options.dh", Conf))
89+
end}.
90+
91+
{mapping, "auth_http.ssl_options.dhfile", "rabbitmq_auth_backend_http.ssl_options.dhfile",
92+
[{datatype, string}, {validators, ["file_accessible"]}]}.
93+
94+
{mapping, "auth_http.ssl_options.honor_cipher_order", "rabbitmq_auth_backend_http.ssl_options.honor_cipher_order",
95+
[{datatype, {enum, [true, false]}}]}.
96+
97+
{mapping, "auth_http.ssl_options.honor_ecc_order", "rabbitmq_auth_backend_http.ssl_options.honor_ecc_order",
98+
[{datatype, {enum, [true, false]}}]}.
99+
100+
{mapping, "auth_http.ssl_options.key.RSAPrivateKey", "rabbitmq_auth_backend_http.ssl_options.key",
101+
[{datatype, string}]}.
102+
103+
{mapping, "auth_http.ssl_options.key.DSAPrivateKey", "rabbitmq_auth_backend_http.ssl_options.key",
104+
[{datatype, string}]}.
105+
106+
{mapping, "auth_http.ssl_options.key.PrivateKeyInfo", "rabbitmq_auth_backend_http.ssl_options.key",
107+
[{datatype, string}]}.
108+
109+
{translation, "rabbitmq_auth_backend_http.ssl_options.key",
110+
fun(Conf) ->
111+
case cuttlefish_variable:filter_by_prefix("auth_http.ssl_options.key", Conf) of
112+
[{[_,_,Key], Val}|_] -> {list_to_atom(Key), list_to_binary(Val)};
113+
_ -> undefined
114+
end
115+
end}.
116+
117+
{mapping, "auth_http.ssl_options.keyfile", "rabbitmq_auth_backend_http.ssl_options.keyfile",
118+
[{datatype, string}, {validators, ["file_accessible"]}]}.
119+
120+
{mapping, "auth_http.ssl_options.log_alert", "rabbitmq_auth_backend_http.ssl_options.log_alert",
121+
[{datatype, {enum, [true, false]}}]}.
122+
123+
{mapping, "auth_http.ssl_options.password", "rabbitmq_auth_backend_http.ssl_options.password",
124+
[{datatype, string}]}.
125+
126+
{mapping, "auth_http.ssl_options.psk_identity", "rabbitmq_auth_backend_http.ssl_options.psk_identity",
127+
[{datatype, string}]}.
128+
129+
{mapping, "auth_http.ssl_options.reuse_sessions", "rabbitmq_auth_backend_http.ssl_options.reuse_sessions",
130+
[{datatype, {enum, [true, false]}}]}.
131+
132+
{mapping, "auth_http.ssl_options.secure_renegotiate", "rabbitmq_auth_backend_http.ssl_options.secure_renegotiate",
133+
[{datatype, {enum, [true, false]}}]}.
134+
135+
{mapping, "auth_http.ssl_options.versions.$version", "rabbitmq_auth_backend_http.ssl_options.versions",
136+
[{datatype, atom}]}.
137+
138+
{translation, "rabbitmq_auth_backend_http.ssl_options.versions",
139+
fun(Conf) ->
140+
Settings = cuttlefish_variable:filter_by_prefix("auth_http.ssl_options.versions", Conf),
141+
[ V || {_, V} <- Settings ]
142+
end}.
143+
144+
{mapping, "auth_http.ssl_options.sni", "rabbitmq_auth_backend_http.ssl_options.server_name_indication",
145+
[{datatype, [{enum, [none]}, string]}]}.
146+
147+
{translation, "rabbitmq_auth_backend_http.ssl_options.server_name_indication",
148+
fun(Conf) ->
149+
case cuttlefish:conf_get("auth_http.ssl_options.sni", Conf, undefined) of
150+
undefined -> cuttlefish:unset();
151+
none -> cuttlefish:unset();
152+
Hostname -> Hostname
153+
end
154+
end}.
155+

deps/rabbitmq_auth_backend_http/test/auth_SUITE.erl

Lines changed: 87 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,6 @@
1414

1515
-define(AUTH_PORT, 8000).
1616
-define(USER_PATH, "/auth/user").
17-
-define(BACKEND_CONFIG,
18-
[{http_method, get},
19-
{user_path, "http://localhost:" ++ integer_to_list(?AUTH_PORT) ++ ?USER_PATH},
20-
{vhost_path, "http://localhost:" ++ integer_to_list(?AUTH_PORT) ++ "/auth/vhost"},
21-
{resource_path, "http://localhost:" ++ integer_to_list(?AUTH_PORT) ++ "/auth/resource"},
22-
{topic_path, "http://localhost:" ++ integer_to_list(?AUTH_PORT) ++ "/auth/topic"}]).
2317
-define(ALLOWED_USER, #{username => <<"Ala1">>,
2418
password => <<"Kocur">>,
2519
expected_credentials => [username, password],
@@ -33,26 +27,62 @@
3327
password => <<"Cat">>
3428
}).
3529

36-
all() -> [grants_access_to_user,
37-
denies_access_to_user,
38-
grants_access_to_user_passing_additional_required_authprops,
39-
grants_access_to_user_skipping_internal_authprops,
40-
grants_access_to_user_with_credentials_in_rabbit_auth_backend_http,
41-
grants_access_to_user_with_credentials_in_rabbit_auth_backend_cache].
42-
43-
init_per_suite(Config) ->
44-
configure_http_auth_backend(),
30+
all() ->
31+
[
32+
{group, over_https},
33+
{group, over_http}
34+
].
35+
36+
groups() ->
37+
[
38+
{over_http, [], shared()},
39+
{over_https, [], shared()}
40+
].
41+
42+
shared() ->
43+
[
44+
grants_access_to_user,
45+
denies_access_to_user,
46+
grants_access_to_user_passing_additional_required_authprops,
47+
grants_access_to_user_skipping_internal_authprops,
48+
grants_access_to_user_with_credentials_in_rabbit_auth_backend_http,
49+
grants_access_to_user_with_credentials_in_rabbit_auth_backend_cache
50+
].
51+
52+
init_per_suite(Config) ->
53+
rabbit_ct_helpers:run_setup_steps(Config) ++
54+
[{allowed_user, ?ALLOWED_USER},
55+
{allowed_user_with_extra_credentials, ?ALLOWED_USER_WITH_EXTRA_CREDENTIALS},
56+
{denied_user, ?DENIED_USER}].
57+
58+
init_per_group(over_http, Config) ->
59+
configure_http_auth_backend("http", Config),
4560
{User1, Tuple1} = extractUserTuple(?ALLOWED_USER),
46-
{User2, Tuple2} = extractUserTuple(?ALLOWED_USER_WITH_EXTRA_CREDENTIALS),
61+
{User2, Tuple2} = extractUserTuple(?ALLOWED_USER_WITH_EXTRA_CREDENTIALS),
4762
start_http_auth_server(?AUTH_PORT, ?USER_PATH, #{User1 => Tuple1, User2 => Tuple2}),
48-
[{allowed_user, ?ALLOWED_USER},
49-
{allowed_user_with_extra_credentials, ?ALLOWED_USER_WITH_EXTRA_CREDENTIALS},
50-
{denied_user, ?DENIED_USER} | Config].
63+
Config;
64+
65+
init_per_group(over_https, Config) ->
66+
configure_http_auth_backend("https", Config),
67+
{User1, Tuple1} = extractUserTuple(?ALLOWED_USER),
68+
{User2, Tuple2} = extractUserTuple(?ALLOWED_USER_WITH_EXTRA_CREDENTIALS),
69+
CertsDir = ?config(rmq_certsdir, Config),
70+
start_https_auth_server(?AUTH_PORT, CertsDir, ?USER_PATH, #{User1 => Tuple1, User2 => Tuple2}),
71+
Config.
72+
73+
5174
extractUserTuple(User) ->
5275
#{username := Username, password := Password, tags := Tags, expected_credentials := ExpectedCredentials} = User,
5376
{Username, {Password, Tags, ExpectedCredentials}}.
5477

55-
end_per_suite(_Config) ->
78+
end_per_suite(Config) ->
79+
Config.
80+
81+
end_per_group(over_http, Config) ->
82+
undo_configure_http_auth_backend("http", Config),
83+
stop_http_auth_server();
84+
end_per_group(over_https, Config) ->
85+
undo_configure_http_auth_backend("https", Config),
5686
stop_http_auth_server().
5787

5888
grants_access_to_user(Config) ->
@@ -102,15 +132,49 @@ grants_access_to_user_with_credentials_in_rabbit_auth_backend_cache(Config) ->
102132

103133
%%% HELPERS
104134

105-
configure_http_auth_backend() ->
106-
{ok, _} = application:ensure_all_started(inets),
107-
[application:set_env(rabbitmq_auth_backend_http, K, V) || {K, V} <- ?BACKEND_CONFIG].
135+
configure_http_auth_backend(Scheme, Config) ->
136+
[application:set_env(rabbitmq_auth_backend_http, K, V) || {K, V} <- generate_backend_config(Scheme, Config)].
137+
undo_configure_http_auth_backend(Scheme, Config) ->
138+
[application:unset_env(rabbitmq_auth_backend_http, K) || {K, _V} <- generate_backend_config(Scheme, Config)].
108139

109140
start_http_auth_server(Port, Path, Users) ->
141+
{ok, _} = application:ensure_all_started(inets),
110142
application:ensure_all_started(cowboy),
111143
Dispatch = cowboy_router:compile([{'_', [{Path, auth_http_mock, Users}]}]),
112144
{ok, _} = cowboy:start_clear(
113145
mock_http_auth_listener, [{port, Port}], #{env => #{dispatch => Dispatch}}).
114146

147+
start_https_auth_server(Port, CertsDir, Path, Users) ->
148+
{ok, _} = application:ensure_all_started(inets),
149+
{ok, _} = application:ensure_all_started(ssl),
150+
{ok, _} = application:ensure_all_started(cowboy),
151+
152+
Dispatch = cowboy_router:compile([{'_', [{Path, auth_http_mock, Users}]}]),
153+
{ok, _} = cowboy:start_tls(mock_http_auth_listener,
154+
[{port, Port},
155+
{certfile, filename:join([CertsDir, "server", "cert.pem"])},
156+
{keyfile, filename:join([CertsDir, "server", "key.pem"])}],
157+
#{env => #{dispatch => Dispatch}}).
158+
115159
stop_http_auth_server() ->
116160
cowboy:stop_listener(mock_http_auth_listener).
161+
162+
generate_backend_config(Scheme, Config) ->
163+
Config0 = [{http_method, get},
164+
{user_path, Scheme ++ "://localhost:" ++ integer_to_list(?AUTH_PORT) ++ ?USER_PATH},
165+
{vhost_path, Scheme ++ "://localhost:" ++ integer_to_list(?AUTH_PORT) ++ "/auth/vhost"},
166+
{resource_path, Scheme ++ "://localhost:" ++ integer_to_list(?AUTH_PORT) ++ "/auth/resource"},
167+
{topic_path, Scheme ++ "://localhost:" ++ integer_to_list(?AUTH_PORT) ++ "/auth/topic"}],
168+
Config1 = case Scheme of
169+
"https" ->
170+
CertsDir = ?config(rmq_certsdir, Config),
171+
[{ssl_options, [
172+
{cacertfile, filename:join([CertsDir, "testca", "cacert.pem"])},
173+
{certfile, filename:join([CertsDir, "server", "cert.pem"])},
174+
{keyfile, filename:join([CertsDir, "server", "key.pem"])},
175+
{verify, verify_peer},
176+
{fail_if_no_peer_cert, false}]
177+
}];
178+
"http" -> []
179+
end,
180+
Config0 ++ Config1.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
I'm not a certificate
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
I'm not a certificate
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
I'm not a certificate

0 commit comments

Comments
 (0)