Re: Logging of PAM Authentication Failure - Mailing list pgsql-hackers

From Kyotaro HORIGUCHI
Subject Re: Logging of PAM Authentication Failure
Date
Msg-id CAM103DsmeuPpT4D8d_9bxNpADeUUEJwNmXRSKnEa0X4FPBBmUQ@mail.gmail.com
Whole thread Raw
In response to Re: Logging of PAM Authentication Failure  (Amit Langote <amitlangote09@gmail.com>)
Responses Re: Logging of PAM Authentication Failure  (Amit Langote <amitlangote09@gmail.com>)
List pgsql-hackers
> Is it right that it is only in the case a password prompt is needed
> that a new connection is created after dropping the just-failed
> connection?

It's quite doubtful.\:-p The sequense seems fragile to say the
least. Inserting password request state into the client-side state
machine looks quite reasonable.

> I created a patch which enables it to use the existing connection in
> such a case (unlike what we currently do). It modifies
> connectDBComplete() and PQconnectPoll() to also include states
> pertaining to password being accepted from the user. That is, the
> state machine in PQconnectPoll() is further extended to include a
> connection state called CONNECTION_ASKING_PASSWORD which is entered
> when server sends AUTH_REQ_MD5 or AUTH_REQ_PASSWORD auth requests.

Great! The new client state seems to be effective also for MD5.  But
it seems to break existing libpq client doing the same authentication
sequence as current psql. Some means would be necessary to switch the
behavior when password is not previously provided but needed by the
server, or make the first half of the connection sequence to be
compatible to the current sequence - in other words - It should be
that when the user finds stauts is CONNECTION_BAD and
PQconnectionNeedsPassword() == true, the user can throw away the
connection and make new connection providing password, and also can
send password on existing connection.

the old style

|   db = PQconnectXXXX();
|   if (PQstatus(db) == CONNECTION_BAD && PQconnectionNeedsPassword(db))
|   {
|     PQfinish(db);
|     value[..] = password = <some means to read password>;
|     db = PQconnectXXXX();
|     if (PQstatus(db) == CONNECTION_BAD)
|        <error>

and the new style

|   db = PQconnectXXXX();
|   if (PQconnectionNeedsPassword(db))
|      PQsendPassword(db, password);
|   if (PQstatus(db) == CONNECTION_BAD)
|      <error>

should be standing together.

Where, PQsendPassword is combined function of PQcopyPassword and
PQcontinuedbConnect. If the only porpose of these functions is sending
password then these functions are needed to be separately.

What do you think for the compatibility and simpler API.

> These two request types require a password to be entered by the user.
> There is a new PostgresPollingStatusType value called
> PGRES_POLLING_WAITING_PASSWORD which is the polling status while a
> password is being entered by the user.
>
> When user enters the password the PQconnectPoll() continues forward in
> CONNECTION_ASKING_PASSWORD wherein it sends the password to the server
> (by calling pg_fe_sendauth() and this time with a potentially correct
> password) and later goes back to CONNECTION_AWAITING_RESPONSE to read
> server's response to the password just entered where it either
> receives authorization OK or error response thus completing the
> connection start-up process.
>
> The backend waits for the password until authentication timeout
> happens in which case the client can not send the password anymore
> since the backend has exited due to authentication timeout. I wonder
> if this is one of the reasons why this has not already been
> implemented?
>
> Comments?

Hmmm. On current implement, server is not running while the client is
reading password so the authentication timeout is provided only for
hostile clients.  Conversely, the new sequence can enforce true
authentication timeout. It results in error after leaving the password
prompt for 60 seconds. I suppose that more desirable behavior in spite of
the poor message..

| Password: <waiting over 60 seconds and ENTER RETURN>
| psql: fe_sendauth: error sending password authentication

The point at issue now seems how to inform the timeout to the client
under reading password, especially prohibiting using thread nor
SIGALRM.

Providing password input function in libpq like below might make it
viable using select(2).

PQsendPassword(prompt="Passowrd: ", in_fd = stdin)

Any thoughts?

regareds,

--
Kyotaro Horiguchi



pgsql-hackers by date:

Previous
From: Peter Eisentraut
Date:
Subject: Re: PostgreSQL 9.3 beta breaks some extensions "make install"
Next
From: Tom Lane
Date:
Subject: Re: PostgreSQL 9.3 beta breaks some extensions "make install"