1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-15 19:21:59 +03:00

Refactor channel binding code to fetch cbind_data only when necessary

As things stand now, channel binding data is fetched from OpenSSL and
saved into the SCRAM exchange context for any SSL connection attempted
for a SCRAM authentication, resulting in data fetched but not used if no
channel binding is used or if a different channel binding type is used
than what the data is here for.

Refactor the code in such a way that binding data is fetched from the
SSL stack only when a specific channel binding is used for both the
frontend and the backend.  In order to achieve that, save the libpq
connection context directly in the SCRAM exchange state, and add a
dependency to SSL in the low-level SCRAM routines.

This makes the interface in charge of initializing the SCRAM context
cleaner as all its data comes from either PGconn* (for frontend) or
Port* (for the backend).

Author: Michael Paquier <michael.paquier@gmail.com>
This commit is contained in:
Peter Eisentraut
2018-01-04 13:53:09 -05:00
parent 3ad2afc2e9
commit f3049a603a
6 changed files with 102 additions and 152 deletions

View File

@ -491,8 +491,6 @@ pg_SASL_init(PGconn *conn, int payloadlen)
bool success;
const char *selected_mechanism;
PQExpBufferData mechanism_buf;
char *tls_finished = NULL;
size_t tls_finished_len = 0;
char *password;
initPQExpBuffer(&mechanism_buf);
@ -570,32 +568,15 @@ pg_SASL_init(PGconn *conn, int payloadlen)
goto error;
}
#ifdef USE_SSL
/*
* Get data for channel binding.
*/
if (strcmp(selected_mechanism, SCRAM_SHA256_PLUS_NAME) == 0)
{
tls_finished = pgtls_get_finished(conn, &tls_finished_len);
if (tls_finished == NULL)
goto oom_error;
}
#endif
/*
* Initialize the SASL state information with all the information gathered
* during the initial exchange.
*
* Note: Only tls-unique is supported for the moment.
*/
conn->sasl_state = pg_fe_scram_init(conn->pguser,
conn->sasl_state = pg_fe_scram_init(conn,
password,
conn->ssl_in_use,
selected_mechanism,
conn->scram_channel_binding,
tls_finished,
tls_finished_len);
selected_mechanism);
if (!conn->sasl_state)
goto oom_error;
@ -603,7 +584,7 @@ pg_SASL_init(PGconn *conn, int payloadlen)
pg_fe_scram_exchange(conn->sasl_state,
NULL, -1,
&initialresponse, &initialresponselen,
&done, &success, &conn->errorMessage);
&done, &success);
if (done && !success)
goto error;
@ -684,7 +665,7 @@ pg_SASL_continue(PGconn *conn, int payloadlen, bool final)
pg_fe_scram_exchange(conn->sasl_state,
challenge, payloadlen,
&output, &outputlen,
&done, &success, &conn->errorMessage);
&done, &success);
free(challenge); /* don't need the input anymore */
if (final && !done)