postgrespro.git / summary / log / commit / refs

commit    87c346a35ee869e401e736163ec9d21632cc3b0d
Author:   Michael Paquier <michael@paquier.xyz>
Date:     Thu Feb 28 00:40:28 2019 +0000

    Fix SCRAM authentication via SSL when mixing versions of OpenSSL
    
    When using a libpq client linked with OpenSSL 1.0.1 or older to connect
    to a backend linked with OpenSSL 1.0.2 or newer, the server would send
    SCRAM-SHA-256-PLUS and SCRAM-SHA-256 as valid mechanisms for the SASL
    exchange, and the client would choose SCRAM-SHA-256-PLUS even if it does
    not support channel binding, leading to a confusing error.  In this
    case, what the client ought to do is switch to SCRAM-SHA-256 so as the
    authentication can move on and succeed.
    
    So for a SCRAM authentication over SSL, here are all the cases present
    and how we deal with them using libpq:
    1) Server supports channel binding, it sends SCRAM-SHA-256-PLUS and
    SCRAM-SHA-256 as allowed mechanisms.
    1-1) Client supports channel binding, chooses SCRAM-SHA-256-PLUS.
    1-2) Client does not support channel binding, chooses SCRAM-SHA-256.
    2) Server does not support channel binding, sends SCRAM-SHA-256 as
    allowed mechanism.
    2-1) Client supports channel binding, still it has no choice but to
    choose SCRAM-SHA-256.
    2-2) Client does not support channel binding, it chooses SCRAM-SHA-256.
    In all these scenarios the connection should succeed, and the one which
    was handled incorrectly prior this commit is 1-2), causing the
    connection attempt to fail because client chose SCRAM-SHA-256-PLUS over
    SCRAM-SHA-256.
    
    Reported-by: Hugh Ranalli
    Diagnosed-by: Peter Eisentraut
    Author: Michael Paquier
    Reviewed-by: Peter Eisentraut
    Discussion: https://postgr.es/m/CAAhbUMO89SqUk-5mMY+OapgWf-twF2NA5sCucbHEzMfGbvcepA@mail.gmail.com
    Backpatch-through: 11


src/interfaces/libpq/fe-auth.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/interfaces/libpq/fe-auth.c b/src/interfaces/libpq/fe-auth.c index 08a5a9c1f3..4cbe64ceb5 100644 --- a/src/interfaces/libpq/fe-auth.c +++ b/src/interfaces/libpq/fe-auth.c @@ -526,14 +526,24 @@ pg_SASL_init(PGconn *conn, int payloadlen) /* * Select the mechanism to use. Pick SCRAM-SHA-256-PLUS over anything - * else if a channel binding type is set. Pick SCRAM-SHA-256 if - * nothing else has already been picked. If we add more mechanisms, a - * more refined priority mechanism might become necessary. + * else if a channel binding type is set and if the client supports + * it. Pick SCRAM-SHA-256 if nothing else has already been picked. If + * we add more mechanisms, a more refined priority mechanism might + * become necessary. */ if (strcmp(mechanism_buf.data, SCRAM_SHA_256_PLUS_NAME) == 0) { if (conn->ssl_in_use) + { + /* + * The server has offered SCRAM-SHA-256-PLUS, which is only + * supported by the client if a hash of the peer certificate + * can be created. + */ +#ifdef HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH selected_mechanism = SCRAM_SHA_256_PLUS_NAME; +#endif + } else { /* [parent: da35d1480624]