summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Klishin <mklishin@pivotal.io>2018-01-05 16:22:43 +0300
committerMichael Klishin <mklishin@pivotal.io>2018-01-05 16:22:43 +0300
commitbd40475057446c841c9531515d452df532841ec0 (patch)
tree852c20ca4e522a6f4d7559ad11781942ea123dc7
parent82ed78914bf0c121f1ba367c15966b51219e142e (diff)
downloadrabbitmq-server-git-bd40475057446c841c9531515d452df532841ec0.tar.gz
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]
-rw-r--r--src/rabbit_auth_backend_internal.erl11
-rw-r--r--test/unit_inbroker_parallel_SUITE.erl59
2 files changed, 69 insertions, 1 deletions
diff --git a/src/rabbit_auth_backend_internal.erl b/src/rabbit_auth_backend_internal.erl
index bd0acd1360..42360a5833 100644
--- a/src/rabbit_auth_backend_internal.erl
+++ b/src/rabbit_auth_backend_internal.erl
@@ -98,6 +98,11 @@ hashing_module_for_user(#internal_user{
hashing_algorithm = ModOrUndefined}) ->
rabbit_password:hashing_mod(ModOrUndefined).
+-define(BLANK_PASSWORD_REJECTION_MESSAGE,
+ "user '~s' attempted to log in with a blank password, which is prohibited by the internal authN backend. "
+ "To use TLS/x509 certificate-based autentication, set the rabbitmq_auth_mechanism_ssl plugin and configure the client to use the EXTERNAL authentication mechanism. "
+ "Alternatively change the password for the user to be non-blank.").
+
%% For cases when we do not have a set of credentials,
%% namely when x509 (TLS) certificates are used. This should only be
%% possible when the EXTERNAL authentication mechanism is used, see
@@ -108,6 +113,12 @@ user_login_authentication(Username, []) ->
%% performs initial validation.
user_login_authentication(Username, AuthProps) ->
case lists:keyfind(password, 1, AuthProps) of
+ {password, <<"">>} ->
+ {refused, ?BLANK_PASSWORD_REJECTION_MESSAGE,
+ [Username]};
+ {password, ""} ->
+ {refused, ?BLANK_PASSWORD_REJECTION_MESSAGE,
+ [Username]};
{password, Cleartext} ->
internal_check_user_login(
Username,
diff --git a/test/unit_inbroker_parallel_SUITE.erl b/test/unit_inbroker_parallel_SUITE.erl
index 89fd8fc659..c4c8740b7a 100644
--- a/test/unit_inbroker_parallel_SUITE.erl
+++ b/test/unit_inbroker_parallel_SUITE.erl
@@ -19,6 +19,7 @@
-include_lib("common_test/include/ct.hrl").
-include_lib("kernel/include/file.hrl").
-include_lib("amqp_client/include/amqp_client.hrl").
+-include_lib("eunit/include/eunit.hrl").
-compile(export_all).
@@ -49,6 +50,10 @@ groups() ->
password_hashing,
change_password
]},
+ {auth_backend_internal, [parallel], [
+ login_with_credentials_but_no_password,
+ login_of_passwordless_user
+ ]},
set_disk_free_limit_command,
set_vm_memory_high_watermark_command,
topic_matching,
@@ -517,6 +522,58 @@ change_password1(_Config) ->
UserName, [{password, Password}]),
passed.
+
+%% -------------------------------------------------------------------
+%% rabbit_auth_backend_internal
+%% -------------------------------------------------------------------
+
+login_with_credentials_but_no_password(Config) ->
+ passed = rabbit_ct_broker_helpers:rpc(Config, 0,
+ ?MODULE, login_with_credentials_but_no_password1, [Config]).
+
+login_with_credentials_but_no_password1(_Config) ->
+ Username = <<"login_with_credentials_but_no_password-user">>,
+ Password = <<"login_with_credentials_but_no_password-password">>,
+ ok = rabbit_auth_backend_internal:add_user(Username, Password, <<"acting-user">>),
+
+ try
+ rabbit_auth_backend_internal:user_login_authentication(Username,
+ [{key, <<"value">>}]),
+ ?assert(false)
+ catch exit:{unknown_auth_props, Username, [{key, <<"value">>}]} ->
+ ok
+ end,
+
+ ok = rabbit_auth_backend_internal:delete_user(Username, <<"acting-user">>),
+
+ passed.
+
+%% passwordless users are not supposed to be used with
+%% this backend (and PLAIN authentication mechanism in general)
+login_of_passwordless_user(Config) ->
+ passed = rabbit_ct_broker_helpers:rpc(Config, 0,
+ ?MODULE, login_of_passwordless_user1, [Config]).
+
+login_of_passwordless_user1(_Config) ->
+ Username = <<"login_of_passwordless_user-user">>,
+ Password = <<"">>,
+ ok = rabbit_auth_backend_internal:add_user(Username, Password, <<"acting-user">>),
+
+ ?assertMatch(
+ {refused, _Message, [Username]},
+ rabbit_auth_backend_internal:user_login_authentication(Username,
+ [{password, <<"">>}])),
+
+ ?assertMatch(
+ {refused, _Format, [Username]},
+ rabbit_auth_backend_internal:user_login_authentication(Username,
+ [{password, ""}])),
+
+ ok = rabbit_auth_backend_internal:delete_user(Username, <<"acting-user">>),
+
+ passed.
+
+
%% -------------------------------------------------------------------
%% rabbitmqctl.
%% -------------------------------------------------------------------
@@ -1220,4 +1277,4 @@ expand_options(As, Bs) ->
flush() ->
receive _ -> flush()
after 10 -> ok
- end. \ No newline at end of file
+ end.