From: | liulang <lang(dot)liu(at)esgyn(dot)cn> |
---|---|
To: | pgsql-bugs(at)lists(dot)postgresql(dot)org |
Subject: | lost status 'STATUS_EOF' for authentication when using 'MD5' or 'scram-sha-256' |
Date: | 2024-01-02 10:31:00 |
Message-ID: | b725238c-539d-cb09-2bff-b5e6cb2c069c@esgyn.cn |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-bugs |
Hello:
I'm an extension writer and I wrote an extension to lock users who
tried to enter the wrong password too much. This extension is hooking
'ClientAuthentication_hook' and checking the hook's 'status' parameter
to count the times of wrong password. It’s work fine when auth is
'password', but get double count when auth is'MD5'or'scram-sha-256'.
problem reappearance:
1. *create an user without password*
2. set pg_hba.conf with ‘MD5’ or ‘scram-sha-256’
3. use psql without -W or -w or .pgpass file or env PGPASSFILE
4. It's ok when client is pgadmin or another
5. all of version pg can reappearance
when I read the source, find an incorret logical way on
CheckPWChallengeAuth at src/backend/libpq/auth.c
Like
static int
CheckPWChallengeAuth(Port *port, char **logdetail)
{
...
/* the CheckMD5Auth or CheckSCRAMAuth returns STATUS_EOF because
psql is not provide password,
* It will prompt user to type and send the password to other
backend process next time.
* The current backend will exit normally.
*/
if (port->hba->auth_method == uaMD5 && pwtype == PASSWORD_TYPE_MD5)
auth_result = CheckMD5Auth(port, shadow_pass, logdetail);
else
auth_result = CheckSCRAMAuth(port, shadow_pass, logdetail);
...
/*
* If get_role_password() returned error, return error, even if the
* authentication succeeded.
*/
/* The get_role_password returns NULL when the user without password */
if (!shadow_pass)
{
Assert(auth_result != STATUS_OK);
/* lost STATUS_EOF */
*return STATUS_ERROR;*
}
...
}
The above code does not affect the database execution,but
ClientAuthentication_hook will be confused whether the password is
incorrect or not currently entered?
so.. The CheckPWChallengeAuth should returns STATUS_EOF when It is, I think.
Try to change the code
static int
CheckPWChallengeAuth(Port *port, char **logdetail)
{
if (port->hba->auth_method == uaMD5 && pwtype == PASSWORD_TYPE_MD5)
auth_result = CheckMD5Auth(port, shadow_pass, logdetail);
else
auth_result = CheckSCRAMAuth(port, shadow_pass, logdetail);
...
if (STATUS_EOF == auth_result)
{
*/* do nothing */*
}
else if (!shadow_pass)
{
Assert(auth_result != STATUS_OK);
return STATUS_ERROR;
}
else if (auth_result == STATUS_OK)
set_authn_id(port, port->user_name);
return auth_result;
}
I don't know if this is right, please point out. thanks!
From | Date | Subject | |
---|---|---|---|
Next Message | PG Bug reporting form | 2024-01-02 13:38:31 | BUG #18266: Restore process request way too many archive log files via pgbackrest |
Previous Message | Peter Eisentraut | 2024-01-02 09:22:34 | Re: BUG #18252: Assert in CheckOpSlotCompatibility() fails when recursive union filters tuples in non-recursive term |