Fix incorrect client authentication in some cases.
If enable_pool_hba = on, it's auth method is "password", no password
is registered in pool_passwd, and auth method in pg_hba.conf is
"scram-sha-256" or "md5", for the first time when a client connects to
pgpool, authentication is performed as expected. But if a client
connects to the cached connection, any password from the client is
accepted.
authenticate_frontend() asks password to the client and stores it in
frontend->password. When pgpool authenticate backend,
authenticate_frontend_SCRAM() or authenticate_frontend_md5() is called
depending on pg_hba.conf setting. authenticate_frontend_*() calls
get_auth_password() to get backend cached password but it mistakenly
returned frontend->password if pool_passwd does not have an entry for
the user. Then authenticate_frontend_*() tries to challenge based on
frontend->password. As a result, they compared frontend->password
itself, which always succeed. To fix this, when get_auth_password() is
called with reauth parameter being non 0, return backend->password.
Also if enable_pool_hba = off, in some cases a client is not asked
password for the first time, or when a client connects to cached
connection, even if it should be.
If pool_hba.conf is disabled, get_backend_connection() does not call
Client_authentication(), thus frontend->password is not set. Then
pool_do_reauth() calls do_clear_text_password(). It should have called
authenticate_frontend_clear_text() to get a password from the client,
but a mistake in a if statement prevented it. The mistake was fixed in
this commit.
Pgpool-II versions affected: v4.0 or later.
Also this commit does followings:
- Remove single PostgreSQL code path to simplify the authentication
code. As a result, following cases are no more Ok.
- Remove crypt authentication support for frontend and backend. The
feature had not been documented and never tested. Moreover crypt
authentication was removed long time ago in PostgreSQL (8.4, 2009).
- Add new regression test "040.client_auth". The test performs
exhaustive client authentication tests using a test specification
file formatted in CSV.
The csv files have 7 fields:
username: the username used for the test case
pool_hba.conf: takes "scram", "md5", "password", "pam", "ldap" or
"off". If "scram", "md5" , "password", "pam" or "ldap", the user
will have an entry in pool_hba.conf accordingly. If "off",
enable_pool_hba.conf will be off.
allow_clear_text_frontend_auth: takes "on" or "off".
pool_passwd: takes "AES", "md5" or "off". If "AES" or "md5" the
user's password will be stored in pool_passwd using ASE256 or md5
encryption method accordingly. If "off" is specified, no entry will
be created.
pg_hba.conf: almost same as pool_hba.conf except this is for
pg_hba.conf.
expected: takes "ok" or "fail". If ok, the authentication is
expected to be succeeded. If failed, the test is regarded as
failed. "fail" is opposite. The authentication is expected to be
failed. If succeeds, the test regarded as failed.
comment: arbitrary comment
By changing these fields, we can easily modify or add test
cases. The merit of this method is possible higher test
coverage. For human, it is easier to find uncovered test cases in a
table than in a program code.
Backpatch-through: v4.2
The patch was created by Tatsuo Ishii.
13 files changed: