Skip to content

Commit 7051a9d

Browse files
Prevent internal authN backend from accepting blank passwords
Passwordless users were never meant to be used this way. Since the EXTERNAL authentication mechanism won't use this backend at all, this is a reasonable safeguard to put in place. [#153435857]
1 parent 20945a9 commit 7051a9d

File tree

3 files changed

+79
-8
lines changed

3 files changed

+79
-8
lines changed

src/rabbit_auth_backend_internal.erl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ hashing_module_for_user(#internal_user{
9393
hashing_algorithm = ModOrUndefined}) ->
9494
rabbit_password:hashing_mod(ModOrUndefined).
9595

96+
-define(BLANK_PASSWORD_REJECTION_MESSAGE,
97+
"user '~s' attempted to log in with a blank password, which is prohibited by the internal authN backend. "
98+
"To use TLS/x509 certificate-based autentication, set the rabbitmq_auth_mechanism_ssl plugin and configure the client to use the EXTERNAL authentication mechanism. "
99+
"Alternatively change the password for the user to be non-blank.").
100+
96101
%% For cases when we do not have a set of credentials,
97102
%% namely when x509 (TLS) certificates are used. This should only be
98103
%% possible when the EXTERNAL authentication mechanism is used, see
@@ -103,6 +108,14 @@ user_login_authentication(Username, []) ->
103108
%% performs initial validation.
104109
user_login_authentication(Username, AuthProps) ->
105110
case lists:keyfind(password, 1, AuthProps) of
111+
%% Passwordless users are not supposed to be used with
112+
%% this backend (and PLAIN authentication mechanism in general).
113+
{password, <<"">>} ->
114+
{refused, ?BLANK_PASSWORD_REJECTION_MESSAGE,
115+
[Username]};
116+
{password, ""} ->
117+
{refused, ?BLANK_PASSWORD_REJECTION_MESSAGE,
118+
[Username]};
106119
{password, Cleartext} ->
107120
internal_check_user_login(
108121
Username,
@@ -111,6 +124,13 @@ user_login_authentication(Username, AuthProps) ->
111124
} = U) ->
112125
Hash =:= rabbit_password:salted_hash(
113126
hashing_module_for_user(U), Salt, Cleartext);
127+
%% rabbitmqctl clear_password will set password_hash to an empty
128+
%% binary.
129+
%%
130+
%% See the comment on passwordless users above.
131+
(#internal_user{
132+
password_hash = <<"">>}) ->
133+
false;
114134
(#internal_user{}) ->
115135
false
116136
end);

src/rabbit_auth_mechanism_plain.erl

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,6 @@
2828
{requires, rabbit_registry},
2929
{enables, kernel_ready}]}).
3030

31-
%% SASL PLAIN, as used by the Qpid Java client and our clients. Also,
32-
%% apparently, by OpenAMQ.
33-
34-
%% TODO: reimplement this using the binary module? - that makes use of
35-
%% BIFs to do binary matching and will thus be much faster.
36-
3731
description() ->
3832
[{description, <<"SASL PLAIN authentication mechanism">>}].
3933

test/unit_inbroker_parallel_SUITE.erl

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
-include_lib("common_test/include/ct.hrl").
2020
-include_lib("kernel/include/file.hrl").
2121
-include_lib("amqp_client/include/amqp_client.hrl").
22+
-include_lib("eunit/include/eunit.hrl").
2223

2324
-compile(export_all).
2425

@@ -47,6 +48,10 @@ groups() ->
4748
password_hashing,
4849
change_password
4950
]},
51+
{auth_backend_internal, [parallel], [
52+
login_with_credentials_but_no_password,
53+
login_of_passwordless_user
54+
]},
5055
{policy_validation, [parallel, {repeat, 20}], [
5156
ha_policy_validation,
5257
policy_validation,
@@ -684,9 +689,12 @@ user_management1(_Config) ->
684689
%% user authentication
685690
ok = control_action(authenticate_user,
686691
["user_management-user", "user_management-newpassword"]),
687-
{refused, _User, _Format, _Params} =
692+
?assertMatch({refused, _User, _Format, _Params},
688693
control_action(authenticate_user,
689-
["user_management-user", "user_management-password"]),
694+
["user_management-user", "user_management-password"])),
695+
?assertMatch({refused, _User, _Format, _Params},
696+
control_action(authenticate_user,
697+
["user_management-user", ""])),
690698

691699
%% vhost creation
692700
ok = control_action(add_vhost,
@@ -748,6 +756,55 @@ user_management1(_Config) ->
748756

749757
passed.
750758

759+
760+
login_with_credentials_but_no_password(Config) ->
761+
passed = rabbit_ct_broker_helpers:rpc(Config, 0,
762+
?MODULE, login_with_credentials_but_no_password1, [Config]).
763+
764+
login_with_credentials_but_no_password1(_Config) ->
765+
Username = "login_with_credentials_but_no_password-user",
766+
Password = "login_with_credentials_but_no_password-password",
767+
ok = control_action(add_user, [Username, Password]),
768+
769+
try
770+
rabbit_auth_backend_internal:user_login_authentication(Username,
771+
[{key, <<"value">>}]),
772+
?assert(false)
773+
catch exit:{unknown_auth_props, Username, [{key, <<"value">>}]} ->
774+
ok
775+
end,
776+
777+
ok = control_action(delete_user,
778+
[Username]),
779+
780+
passed.
781+
782+
%% passwordless users are not supposed to be used with
783+
%% this backend (and PLAIN authentication mechanism in general)
784+
login_of_passwordless_user(Config) ->
785+
passed = rabbit_ct_broker_helpers:rpc(Config, 0,
786+
?MODULE, login_of_passwordless_user1, [Config]).
787+
788+
login_of_passwordless_user1(_Config) ->
789+
Username = "login_of_passwordless_user-user",
790+
Password = "",
791+
ok = control_action(add_user, [Username, Password]),
792+
793+
?assertMatch(
794+
{refused, _Message, [Username]},
795+
rabbit_auth_backend_internal:user_login_authentication(Username,
796+
[{password, <<"">>}])),
797+
798+
?assertMatch(
799+
{refused, _Format, [Username]},
800+
rabbit_auth_backend_internal:user_login_authentication(Username,
801+
[{password, ""}])),
802+
803+
ok = control_action(delete_user,
804+
[Username]),
805+
806+
passed.
807+
751808
runtime_parameters(Config) ->
752809
passed = rabbit_ct_broker_helpers:rpc(Config, 0,
753810
?MODULE, runtime_parameters1, [Config]).

0 commit comments

Comments
 (0)