Maintain order of configured SASL mechanisms

RabbitMQ should advertise the SASL mechanisms in the order as
configured in `rabbitmq.conf`.

Starting RabbitMQ with the following `rabbitmq.conf`:
```
auth_mechanisms.1 = PLAIN
auth_mechanisms.2 = AMQPLAIN
auth_mechanisms.3 = ANONYMOUS
```

translates prior to this commit to:
```
1> application:get_env(rabbit, auth_mechanisms).
{ok,['ANONYMOUS','AMQPLAIN','PLAIN']}
```

and after this commit to:
```
1> application:get_env(rabbit, auth_mechanisms).
{ok,['PLAIN','AMQPLAIN','ANONYMOUS']}
```

In our 4.0 docs we write:
> The server mechanisms are ordered in decreasing level of preference.

which complies with https://docs.oasis-open.org/amqp/core/v1.0/os/amqp-core-security-v1.0-os.html#type-sasl-mechanisms
This commit is contained in:
David Ansari 2024-08-16 14:38:36 +02:00
parent 3e7f5a00e2
commit b6fbc0292a
3 changed files with 34 additions and 11 deletions

View File

@ -455,10 +455,11 @@ end}.
{datatype, atom}]}.
{translation, "rabbit.auth_mechanisms",
fun(Conf) ->
Settings = cuttlefish_variable:filter_by_prefix("auth_mechanisms", Conf),
[ V || {_, V} <- Settings ]
end}.
fun(Conf) ->
Settings = cuttlefish_variable:filter_by_prefix("auth_mechanisms", Conf),
Sorted = lists:keysort(1, Settings),
[V || {_, V} <- Sorted]
end}.
%% Select an authentication backend to use. RabbitMQ provides an

View File

@ -239,6 +239,20 @@ default_permissions.write = .*",
[{rabbit,
[{anonymous_login_user, none}]}],
[]},
{auth_mechanisms_ordered,
"auth_mechanisms.1 = PLAIN
auth_mechanisms.2 = AMQPLAIN
auth_mechanisms.3 = ANONYMOUS",
[],
[{rabbit,
%% We expect the mechanisms in the order as declared.
[{auth_mechanisms, ['PLAIN', 'AMQPLAIN', 'ANONYMOUS']}]
}],
[],
nosort
},
{cluster_formation,
"cluster_formation.peer_discovery_backend = rabbit_peer_discovery_classic_config
cluster_formation.classic_config.nodes.peer1 = rabbit@hostname1

View File

@ -25,10 +25,14 @@ run_snippets(Config) ->
{ok, [Snippets]} = file:consult(?config(conf_snippets, Config)),
ct:pal("Loaded config schema snippets: ~tp", [Snippets]),
lists:map(
fun({N, S, C, P}) -> ok = test_snippet(Config, {snippet_id(N), S, []}, C, P);
({N, S, A, C, P}) -> ok = test_snippet(Config, {snippet_id(N), S, A}, C, P)
end,
Snippets),
fun({N, S, C, P}) ->
ok = test_snippet(Config, {snippet_id(N), S, []}, C, P, true);
({N, S, A, C, P}) ->
ok = test_snippet(Config, {snippet_id(N), S, A}, C, P, true);
({N, S, A, C, P, nosort}) ->
ok = test_snippet(Config, {snippet_id(N), S, A}, C, P, false)
end,
Snippets),
ok.
snippet_id(N) when is_integer(N) ->
@ -40,7 +44,7 @@ snippet_id(A) when is_atom(A) ->
snippet_id(L) when is_list(L) ->
L.
test_snippet(Config, Snippet = {SnipID, _, _}, Expected, _Plugins) ->
test_snippet(Config, Snippet = {SnipID, _, _}, Expected, _Plugins, Sort) ->
{ConfFile, AdvancedFile} = write_snippet(Config, Snippet),
%% We ignore the rabbit -> log portion of the config on v3.9+, where the lager
%% dependency has been dropped
@ -50,8 +54,12 @@ test_snippet(Config, Snippet = {SnipID, _, _}, Expected, _Plugins) ->
_ ->
generate_config(ConfFile, AdvancedFile)
end,
Gen = deepsort(Generated),
Exp = deepsort(Expected),
{Exp, Gen} = case Sort of
true ->
{deepsort(Expected), deepsort(Generated)};
false ->
{Expected, Generated}
end,
case Exp of
Gen -> ok;
_ ->