mirror of
https://github.com/postgres/postgres.git
synced 2025-10-25 13:17:41 +03:00
Add libpq parameter 'channel_binding'.
Allow clients to require channel binding to enhance security against untrusted servers. Author: Jeff Davis Reviewed-by: Michael Paquier Discussion: https://postgr.es/m/227015d8417f2b4fef03f8966dbfa5cbcc4f44da.camel%40j-davis.com
This commit is contained in:
@@ -119,6 +119,35 @@ pg_fe_scram_init(PGconn *conn,
|
||||
return state;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if channel binding was employed and the SCRAM exchange
|
||||
* completed. This should be used after a successful exchange to determine
|
||||
* whether the server authenticated itself to the client.
|
||||
*
|
||||
* Note that the caller must also ensure that the exchange was actually
|
||||
* successful.
|
||||
*/
|
||||
bool
|
||||
pg_fe_scram_channel_bound(void *opaq)
|
||||
{
|
||||
fe_scram_state *state = (fe_scram_state *) opaq;
|
||||
|
||||
/* no SCRAM exchange done */
|
||||
if (state == NULL)
|
||||
return false;
|
||||
|
||||
/* SCRAM exchange not completed */
|
||||
if (state->state != FE_SCRAM_FINISHED)
|
||||
return false;
|
||||
|
||||
/* channel binding mechanism not used */
|
||||
if (strcmp(state->sasl_mechanism, SCRAM_SHA_256_PLUS_NAME) != 0)
|
||||
return false;
|
||||
|
||||
/* all clear! */
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free SCRAM exchange status
|
||||
*/
|
||||
@@ -225,9 +254,7 @@ pg_fe_scram_exchange(void *opaq, char *input, int inputlen,
|
||||
|
||||
/*
|
||||
* Verify server signature, to make sure we're talking to the
|
||||
* genuine server. XXX: A fake server could simply not require
|
||||
* authentication, though. There is currently no option in libpq
|
||||
* to reject a connection, if SCRAM authentication did not happen.
|
||||
* genuine server.
|
||||
*/
|
||||
if (verify_server_signature(state))
|
||||
*success = true;
|
||||
@@ -358,7 +385,8 @@ build_client_first_message(fe_scram_state *state)
|
||||
appendPQExpBufferStr(&buf, "p=tls-server-end-point");
|
||||
}
|
||||
#ifdef HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH
|
||||
else if (conn->ssl_in_use)
|
||||
else if (conn->channel_binding[0] != 'd' && /* disable */
|
||||
conn->ssl_in_use)
|
||||
{
|
||||
/*
|
||||
* Client supports channel binding, but thinks the server does not.
|
||||
@@ -369,7 +397,7 @@ build_client_first_message(fe_scram_state *state)
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Client does not support channel binding.
|
||||
* Client does not support channel binding, or has disabled it.
|
||||
*/
|
||||
appendPQExpBufferChar(&buf, 'n');
|
||||
}
|
||||
@@ -498,7 +526,8 @@ build_client_final_message(fe_scram_state *state)
|
||||
#endif /* HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH */
|
||||
}
|
||||
#ifdef HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH
|
||||
else if (conn->ssl_in_use)
|
||||
else if (conn->channel_binding[0] != 'd' && /* disable */
|
||||
conn->ssl_in_use)
|
||||
appendPQExpBufferStr(&buf, "c=eSws"); /* base64 of "y,," */
|
||||
#endif
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user