lost status 'STATUS_EOF' for authentication when using 'MD5' or 'scram-sha-256'

Поиск
Список
Период
Сортировка
От liulang
Тема lost status 'STATUS_EOF' for authentication when using 'MD5' or 'scram-sha-256'
Дата
Msg-id b725238c-539d-cb09-2bff-b5e6cb2c069c@esgyn.cn
обсуждение исходный текст
Ответы Re: lost status 'STATUS_EOF' for authentication when using 'MD5' or 'scram-sha-256'  (Tom Lane <tgl@sss.pgh.pa.us>)
Список 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!

В списке pgsql-bugs по дате отправления:

Предыдущее
От: Peter Eisentraut
Дата:
Сообщение: Re: BUG #18252: Assert in CheckOpSlotCompatibility() fails when recursive union filters tuples in non-recursive term
Следующее
От: PG Bug reporting form
Дата:
Сообщение: BUG #18266: Restore process request way too many archive log files via pgbackrest