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

@ -457,7 +457,8 @@ end}.
{translation, "rabbit.auth_mechanisms", {translation, "rabbit.auth_mechanisms",
fun(Conf) -> fun(Conf) ->
Settings = cuttlefish_variable:filter_by_prefix("auth_mechanisms", Conf), Settings = cuttlefish_variable:filter_by_prefix("auth_mechanisms", Conf),
[ V || {_, V} <- Settings ] Sorted = lists:keysort(1, Settings),
[V || {_, V} <- Sorted]
end}. end}.

View File

@ -239,6 +239,20 @@ default_permissions.write = .*",
[{rabbit, [{rabbit,
[{anonymous_login_user, none}]}], [{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,
"cluster_formation.peer_discovery_backend = rabbit_peer_discovery_classic_config "cluster_formation.peer_discovery_backend = rabbit_peer_discovery_classic_config
cluster_formation.classic_config.nodes.peer1 = rabbit@hostname1 cluster_formation.classic_config.nodes.peer1 = rabbit@hostname1

View File

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