Updated the authentication failures counter logic

This commit is contained in:
Alexey Gerasimchuck 2024-01-30 23:52:33 +00:00
parent b1d2c0d93a
commit 076fb1de31
3 changed files with 99 additions and 99 deletions

View File

@ -565,19 +565,31 @@ AuthResult AccessControl::authenticate(const Credentials & credentials, const Po
// Then user_id is not generated, and the authentication quota will always be nullptr.
auto authentication_quota = getAuthenticationQuota(credentials.getUserName(), address, forwarded_address);
if (authentication_quota)
authentication_quota->checkExceeded(QuotaType::FAILED_SEQUENTIAL_AUTHENTICATIONS);
{
/// Reserve a single try from the quota to check whether we have another authentication try.
/// This is required for correct behavior in this situation:
/// User has 1 login failures quota.
/// * At the first login with an invalid password: Increase the quota counter. 1 (used) > 1 (max) is false.
///   Then try to authenticate the user and throw an AUTHENTICATION_FAILED error.
/// * In case of the second try: increase quota counter, 2 (used) > 1 (max), then throw QUOTA_EXCEED
///   and don't let the user authenticate.
///
/// The authentication failures counter will be reset after successful authentication.
authentication_quota->used(QuotaType::FAILED_SEQUENTIAL_AUTHENTICATIONS, 1);
}
AuthResult auth_result;
try
{
auth_result = MultipleAccessStorage::authenticate(credentials, address, *external_authenticators, allow_no_password,
allow_plaintext_password);
const auto auth_result = MultipleAccessStorage::authenticate(credentials, address, *external_authenticators, allow_no_password,
allow_plaintext_password);
if (authentication_quota)
authentication_quota->reset(QuotaType::FAILED_SEQUENTIAL_AUTHENTICATIONS);
return auth_result;
}
catch (...)
{
tryLogCurrentException(getLogger(), "from: " + address.toString() + ", user: " + credentials.getUserName() + ": Authentication failed");
if (authentication_quota)
authentication_quota->used(QuotaType::FAILED_SEQUENTIAL_AUTHENTICATIONS, 1, true);
WriteBufferFromOwnString message;
message << credentials.getUserName() << ": Authentication failed: password is incorrect, or there is no user with such name.";
@ -597,11 +609,6 @@ AuthResult AccessControl::authenticate(const Credentials & credentials, const Po
"{}: Authentication failed: password is incorrect, or there is no user with such name.{}"},
ErrorCodes::AUTHENTICATION_FAILED);
}
if (authentication_quota)
authentication_quota->reset(QuotaType::FAILED_SEQUENTIAL_AUTHENTICATIONS);
return auth_result;
}
void AccessControl::restoreFromBackup(RestorerFromBackup & restorer)

View File

@ -2,51 +2,53 @@
> Create the user with quota with the maximum single authentication attempt.
> Check if the quota has been created.
1
> Try to login to the user account with correct password
> Login to the user account using the wrong password.
password is incorrect
> Check the failed_sequential_authentications, max_failed_sequential_authentications fields.
1 1
> Try to login to the user account again. It should be allowed to login. Current tries 1 <= 1 max tries, so quota not exceed.
> Check the failed_sequential_authentications, max_failed_sequential_authentications fields.
0 1
> Login to the user account using the wrong password 2 times to exceed the quota.
password is incorrect
QUOTA_EXCEEDED
> Login to the user account using the correct password, but login is unsuccesful (quota exceed).
> Quota is exceeded 1 >= 1. Login with correct password should fail.
QUOTA_EXCEEDED
> Check the failed_sequential_authentications, max_failed_sequential_authentications fields.
2 1
> Alter the quota with MAX FAILED SEQUENTIAL AUTHENTICATIONS = 3
> Login to the user account using the wrong password.
> Alter the quota with MAX FAILED SEQUENTIAL AUTHENTICATIONS = 4
> Try to login to the user account with correct password
> Successfull login should reset failed authentications counter. Check the failed_sequential_authentications, max_failed_sequential_authentications fields.
0 4
> Login to the user account using the wrong password before exeeding the quota.
password is incorrect
password is incorrect
password is incorrect
password is incorrect
QUOTA_EXCEEDED
> Also try to login with correct password. Quota should stay exceeded.
QUOTA_EXCEEDED
> Check the failed_sequential_authentications, max_failed_sequential_authentications fields.
3 3
> Increaseing MAX FAILED SEQUENTIAL AUTHENTICATIONS should now allow the user to login.
> Check the failed_sequential_authentications, max_failed_sequential_authentications fields.
0 3
6 4
> Reset the quota by increasing MAX FAILED SEQUENTIAL AUTHENTICATIONS and succesfull login
> and check failed_sequential_authentications, max_failed_sequential_authentications.
0 7
---------------------------------------------------------------------------
> Create the role with quota with the maximum single authentication attempt.
> Try to login to the user account with correct password
> Login to the user account using the wrong password.
password is incorrect
> Check the failed_sequential_authentications, max_failed_sequential_authentications fields.
1 1
> Try to login to the user account again. It should be allowed to login. Current tries 1 <= 1 max tries, so quota not exceed.
> Check the failed_sequential_authentications, max_failed_sequential_authentications fields.
0 1
> Login to the user account using the wrong password 2 times to exceed the quota.
password is incorrect
> Quota is exceeded 1 >= 1. Login with correct password should fail.
QUOTA_EXCEEDED
> Check the failed_sequential_authentications, max_failed_sequential_authentications fields.
QUOTA_EXCEEDED
> Alter the quota connected with role by setting MAX FAILED SEQUENTIAL AUTHENTICATIONS = 3
> Login to the user account using the wrong password.
2 1
> Alter the quota with MAX FAILED SEQUENTIAL AUTHENTICATIONS = 4
> Try to login to the user account with correct password
> Successfull login should reset failed authentications counter. Check the failed_sequential_authentications, max_failed_sequential_authentications fields.
0 4
> Login to the user account using the wrong password before exeeding the quota.
password is incorrect
password is incorrect
password is incorrect
> Login to the user account using the correct password.
> Alter the quota connected with role by setting MAX FAILED SEQUENTIAL AUTHENTICATIONS = 1
> Login 2 times to the user account using the wrong password to exceed the quota
password is incorrect
> Login to the user account using wrong password and check that the error is 'QUOTA_EXCEEDED'.
QUOTA_EXCEEDED
> Login to the user account using correct password and that the error is 'QUOTA_EXCEEDED'.
QUOTA_EXCEEDED
> Login to the user account using correct password and that the error is 'QUOTA_EXCEEDED'.
> Also try to login with correct password. Quota should stay exceeded.
QUOTA_EXCEEDED
> Check the failed_sequential_authentications, max_failed_sequential_authentications fields.
6 4
> Reset the quota by increasing MAX FAILED SEQUENTIAL AUTHENTICATIONS and succesfull login
> and check failed_sequential_authentications, max_failed_sequential_authentications.
0 7

View File

@ -9,6 +9,50 @@ QUOTA="2884_quota_$$"
USER="2884_user_$$"
ROLE="2884_role_$$"
function login_test()
{
echo "> Try to login to the user account with correct password"
${CLICKHOUSE_CLIENT} --user ${USER} --password "pass" --query "select 1 format Null"
echo "> Login to the user account using the wrong password."
${CLICKHOUSE_CLIENT} --user ${USER} --password "wrong_pass" --query "select 1 format Null" 2>&1 | grep -m1 -o 'password is incorrect'
echo "> Quota is exceeded 1 >= 1. Login with correct password should fail."
${CLICKHOUSE_CLIENT} --user ${USER} --password "pass" --query "select 1 format Null" 2>&1 | grep -m1 -o 'QUOTA_EXCEEDED'
echo "> Check the failed_sequential_authentications, max_failed_sequential_authentications fields."
${CLICKHOUSE_CLIENT} -q "SELECT failed_sequential_authentications, max_failed_sequential_authentications FROM system.quotas_usage WHERE quota_name = '${QUOTA}'"
echo "> Alter the quota with MAX FAILED SEQUENTIAL AUTHENTICATIONS = 4"
${CLICKHOUSE_CLIENT} -q "ALTER QUOTA ${QUOTA} FOR INTERVAL 100 YEAR MAX FAILED SEQUENTIAL AUTHENTICATIONS = 4 TO ${USER}"
echo "> Try to login to the user account with correct password"
${CLICKHOUSE_CLIENT} --user ${USER} --password "pass" --query "select 1 format Null"
echo "> Successfull login should reset failed authentications counter. Check the failed_sequential_authentications, max_failed_sequential_authentications fields."
${CLICKHOUSE_CLIENT} -q "SELECT failed_sequential_authentications, max_failed_sequential_authentications FROM system.quotas_usage WHERE quota_name = '${QUOTA}'"
echo "> Login to the user account using the wrong password before exeeding the quota."
${CLICKHOUSE_CLIENT} --user ${USER} --password "wrong_pass" --query "select 1 format Null" 2>&1 | grep -m1 -o 'password is incorrect'
${CLICKHOUSE_CLIENT} --user ${USER} --password "wrong_pass" --query "select 1 format Null" 2>&1 | grep -m1 -o 'password is incorrect'
${CLICKHOUSE_CLIENT} --user ${USER} --password "wrong_pass" --query "select 1 format Null" 2>&1 | grep -m1 -o 'password is incorrect'
${CLICKHOUSE_CLIENT} --user ${USER} --password "wrong_pass" --query "select 1 format Null" 2>&1 | grep -m1 -o 'password is incorrect'
${CLICKHOUSE_CLIENT} --user ${USER} --password "wrong_pass" --query "select 1 format Null" 2>&1 | grep -m1 -o 'QUOTA_EXCEEDED'
echo "> Also try to login with correct password. Quota should stay exceeded."
${CLICKHOUSE_CLIENT} --user ${USER} --password "pass" --query "select 1 format Null" 2>&1 | grep -m1 -o 'QUOTA_EXCEEDED'
echo "> Check the failed_sequential_authentications, max_failed_sequential_authentications fields."
${CLICKHOUSE_CLIENT} -q "SELECT failed_sequential_authentications, max_failed_sequential_authentications FROM system.quotas_usage WHERE quota_name = '${QUOTA}'"
echo "> Reset the quota by increasing MAX FAILED SEQUENTIAL AUTHENTICATIONS and succesfull login"
echo "> and check failed_sequential_authentications, max_failed_sequential_authentications."
${CLICKHOUSE_CLIENT} -q "ALTER QUOTA ${QUOTA} FOR INTERVAL 100 YEAR MAX FAILED SEQUENTIAL AUTHENTICATIONS = 7 TO ${USER}"
${CLICKHOUSE_CLIENT} --user ${USER} --password "pass" --query "select 1 format Null"
${CLICKHOUSE_CLIENT} -q "SELECT failed_sequential_authentications, max_failed_sequential_authentications FROM system.quotas_usage WHERE quota_name = '${QUOTA}'"
}
echo "> Drop the user, quota, and role if those were created."
${CLICKHOUSE_CLIENT} -q "DROP USER IF EXISTS ${USER}"
${CLICKHOUSE_CLIENT} -q "DROP QUOTA IF EXISTS ${QUOTA}"
@ -21,69 +65,16 @@ ${CLICKHOUSE_CLIENT} -q "CREATE QUOTA ${QUOTA} FOR INTERVAL 100 YEAR MAX FAILED
echo "> Check if the quota has been created."
${CLICKHOUSE_CLIENT} -q "SELECT COUNT(*) FROM system.quotas WHERE name = '${QUOTA}'"
echo "> Login to the user account using the wrong password."
${CLICKHOUSE_CLIENT} --user ${USER} --password "wrong_pass" --query "select 1 format Null" 2>&1 | grep -m1 -o 'password is incorrect'
echo "> Check the failed_sequential_authentications, max_failed_sequential_authentications fields."
${CLICKHOUSE_CLIENT} -q "SELECT failed_sequential_authentications, max_failed_sequential_authentications FROM system.quotas_usage WHERE quota_name = '${QUOTA}'"
echo "> Try to login to the user account again. It should be allowed to login. Current tries 1 <= 1 max tries, so quota not exceed."
${CLICKHOUSE_CLIENT} --user ${USER} --password "pass" --query "select 1 format Null"
echo "> Check the failed_sequential_authentications, max_failed_sequential_authentications fields."
${CLICKHOUSE_CLIENT} -q "SELECT failed_sequential_authentications, max_failed_sequential_authentications FROM system.quotas_usage WHERE quota_name = '${QUOTA}'"
echo "> Login to the user account using the wrong password 2 times to exceed the quota."
${CLICKHOUSE_CLIENT} --user ${USER} --password "wrong_pass" --query "select 1 format Null" 2>&1 | grep -m1 -o 'password is incorrect'
${CLICKHOUSE_CLIENT} --user ${USER} --password "wrong_pass" --query "select 1 format Null" 2>&1 | grep -m1 -o 'QUOTA_EXCEEDED'
echo "> Login to the user account using the correct password, but login is unsuccesful (quota exceed)."
${CLICKHOUSE_CLIENT} --user ${USER} --password "pass" --query "select 1 format Null" 2>&1 | grep -m1 -o 'QUOTA_EXCEEDED'
echo "> Check the failed_sequential_authentications, max_failed_sequential_authentications fields."
${CLICKHOUSE_CLIENT} -q "SELECT failed_sequential_authentications, max_failed_sequential_authentications FROM system.quotas_usage WHERE quota_name = '${QUOTA}'"
echo "> Alter the quota with MAX FAILED SEQUENTIAL AUTHENTICATIONS = 3"
${CLICKHOUSE_CLIENT} -q "ALTER QUOTA ${QUOTA} FOR INTERVAL 100 YEAR MAX FAILED SEQUENTIAL AUTHENTICATIONS = 3 TO ${USER}"
echo "> Login to the user account using the wrong password."
${CLICKHOUSE_CLIENT} --user ${USER} --password "wrong_pass" --query "select 1 format Null" 2>&1 | grep -m1 -o 'password is incorrect'
echo "> Check the failed_sequential_authentications, max_failed_sequential_authentications fields."
${CLICKHOUSE_CLIENT} -q "SELECT failed_sequential_authentications, max_failed_sequential_authentications FROM system.quotas_usage WHERE quota_name = '${QUOTA}'"
echo "> Increaseing MAX FAILED SEQUENTIAL AUTHENTICATIONS should now allow the user to login."
${CLICKHOUSE_CLIENT} --user ${USER} --password "pass" --query "select 1 format Null"
echo "> Check the failed_sequential_authentications, max_failed_sequential_authentications fields."
${CLICKHOUSE_CLIENT} -q "SELECT failed_sequential_authentications, max_failed_sequential_authentications FROM system.quotas_usage WHERE quota_name = '${QUOTA}'"
login_test
echo " ---------------------------------------------------------------------------"
echo "> Create the role with quota with the maximum single authentication attempt."
${CLICKHOUSE_CLIENT} -q "CREATE ROLE ${ROLE}"
${CLICKHOUSE_CLIENT} -q "GRANT ALL ON *.* TO ${ROLE}"
${CLICKHOUSE_CLIENT} -q "GRANT ${ROLE} to ${USER}"
${CLICKHOUSE_CLIENT} -q "ALTER QUOTA ${QUOTA} FOR INTERVAL 100 YEAR MAX FAILED SEQUENTIAL AUTHENTICATIONS = 1 TO ${ROLE}"
echo "> Login to the user account using the wrong password."
${CLICKHOUSE_CLIENT} --user ${USER} --password "wrong_pass" --query "select 1 format Null" 2>&1 | grep -m1 -o 'password is incorrect'
echo "> Check the failed_sequential_authentications, max_failed_sequential_authentications fields."
${CLICKHOUSE_CLIENT} -q "SELECT failed_sequential_authentications, max_failed_sequential_authentications FROM system.quotas_usage WHERE quota_name = '${QUOTA}'"
echo "> Try to login to the user account again. It should be allowed to login. Current tries 1 <= 1 max tries, so quota not exceed."
${CLICKHOUSE_CLIENT} --user ${USER} --password "pass" --query "select 1 format Null"
echo "> Check the failed_sequential_authentications, max_failed_sequential_authentications fields."
${CLICKHOUSE_CLIENT} -q "SELECT failed_sequential_authentications, max_failed_sequential_authentications FROM system.quotas_usage WHERE quota_name = '${QUOTA}'"
echo "> Login to the user account using the wrong password 2 times to exceed the quota."
${CLICKHOUSE_CLIENT} --user ${USER} --password "wrong_pass" --query "select 1 format Null" 2>&1 | grep -m1 -o 'password is incorrect'
${CLICKHOUSE_CLIENT} --user ${USER} --password "wrong_pass" --query "select 1 format Null" 2>&1 | grep -m1 -o 'QUOTA_EXCEEDED'
echo "> Check the failed_sequential_authentications, max_failed_sequential_authentications fields."
${CLICKHOUSE_CLIENT} --user ${USER} --password "pass" --query "select 1 format Null" 2>&1 | grep -m1 -o 'QUOTA_EXCEEDED'
echo "> Alter the quota connected with role by setting MAX FAILED SEQUENTIAL AUTHENTICATIONS = 3"
${CLICKHOUSE_CLIENT} -q "ALTER QUOTA ${QUOTA} FOR INTERVAL 100 YEAR MAX FAILED SEQUENTIAL AUTHENTICATIONS = 3 TO ${USER}"
echo "> Login to the user account using the wrong password."
${CLICKHOUSE_CLIENT} --user ${USER} --password "wrong_pass" --query "select 1 format Null" 2>&1 | grep -m1 -o 'password is incorrect'
echo "> Login to the user account using the correct password."
${CLICKHOUSE_CLIENT} --user ${USER} --password "pass" --query "select 1 format Null"
echo "> Alter the quota connected with role by setting MAX FAILED SEQUENTIAL AUTHENTICATIONS = 1"
${CLICKHOUSE_CLIENT} -q "ALTER QUOTA ${QUOTA} FOR INTERVAL 100 YEAR MAX FAILED SEQUENTIAL AUTHENTICATIONS = 1 TO ${USER}"
echo "> Login 2 times to the user account using the wrong password to exceed the quota"
${CLICKHOUSE_CLIENT} --user ${USER} --password "wrong_pass" --query "select 1 format Null" 2>&1 | grep -m1 -o 'password is incorrect'
${CLICKHOUSE_CLIENT} --user ${USER} --password "wrong_pass" --query "select 1 format Null" 2>&1 | grep -m1 -o 'password is incorrect'
echo "> Login to the user account using wrong password and check that the error is 'QUOTA_EXCEEDED'."
${CLICKHOUSE_CLIENT} --user ${USER} --password "wrong_pass" --query "select 1 format Null" 2>&1 | grep -m1 -o 'QUOTA_EXCEEDED'
echo "> Login to the user account using correct password and that the error is 'QUOTA_EXCEEDED'."
${CLICKHOUSE_CLIENT} --user ${USER} --password "pass" --query "select 1 format Null" 2>&1 | grep -m1 -o 'QUOTA_EXCEEDED'
echo "> Login to the user account using correct password and that the error is 'QUOTA_EXCEEDED'."
${CLICKHOUSE_CLIENT} --user ${USER} --password "wrong_pass" --query "select 1 format Null" 2>&1 | grep -m1 -o 'QUOTA_EXCEEDED'
login_test
${CLICKHOUSE_CLIENT} -q "DROP USER IF EXISTS ${USER}"
${CLICKHOUSE_CLIENT} -q "DROP QUOTA IF EXISTS ${QUOTA}"