@@ -423,6 +423,14 @@ pg_SASL_init(PGconn *conn, int payloadlen)
423423
424424 initPQExpBuffer (& mechanism_buf );
425425
426+ if (conn -> channel_binding [0 ] == 'r' && /* require */
427+ !conn -> ssl_in_use )
428+ {
429+ printfPQExpBuffer (& conn -> errorMessage ,
430+ libpq_gettext ("Channel binding required, but SSL not in use\n" ));
431+ goto error ;
432+ }
433+
426434 if (conn -> sasl_state )
427435 {
428436 printfPQExpBuffer (& conn -> errorMessage ,
@@ -454,10 +462,10 @@ pg_SASL_init(PGconn *conn, int payloadlen)
454462
455463 /*
456464 * Select the mechanism to use. Pick SCRAM-SHA-256-PLUS over anything
457- * else if a channel binding type is set and if the client supports
458- * it . Pick SCRAM-SHA-256 if nothing else has already been picked. If
459- * we add more mechanisms, a more refined priority mechanism might
460- * become necessary.
465+ * else if a channel binding type is set and if the client supports it
466+ * (and did not set channel_binding=disable) . Pick SCRAM-SHA-256 if
467+ * nothing else has already been picked. If we add more mechanisms, a
468+ * more refined priority mechanism might become necessary.
461469 */
462470 if (strcmp (mechanism_buf .data , SCRAM_SHA_256_PLUS_NAME ) == 0 )
463471 {
@@ -466,10 +474,11 @@ pg_SASL_init(PGconn *conn, int payloadlen)
466474 /*
467475 * The server has offered SCRAM-SHA-256-PLUS, which is only
468476 * supported by the client if a hash of the peer certificate
469- * can be created.
477+ * can be created, and if channel_binding is not disabled .
470478 */
471479#ifdef HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH
472- selected_mechanism = SCRAM_SHA_256_PLUS_NAME ;
480+ if (conn -> channel_binding [0 ] != 'd' ) /* disable */
481+ selected_mechanism = SCRAM_SHA_256_PLUS_NAME ;
473482#endif
474483 }
475484 else
@@ -493,6 +502,14 @@ pg_SASL_init(PGconn *conn, int payloadlen)
493502 selected_mechanism = SCRAM_SHA_256_NAME ;
494503 }
495504
505+ if (conn -> channel_binding [0 ] == 'r' && /* require */
506+ strcmp (selected_mechanism , SCRAM_SHA_256_PLUS_NAME ) != 0 )
507+ {
508+ printfPQExpBuffer (& conn -> errorMessage ,
509+ libpq_gettext ("channel binding is required, but server did not offer an authentication method that supports channel binding\n" ));
510+ goto error ;
511+ }
512+
496513 if (!selected_mechanism )
497514 {
498515 printfPQExpBuffer (& conn -> errorMessage ,
@@ -774,6 +791,50 @@ pg_password_sendauth(PGconn *conn, const char *password, AuthRequest areq)
774791 return ret ;
775792}
776793
794+ /*
795+ * Verify that the authentication request is expected, given the connection
796+ * parameters. This is especially important when the client wishes to
797+ * authenticate the server before any sensitive information is exchanged.
798+ */
799+ static bool
800+ check_expected_areq (AuthRequest areq , PGconn * conn )
801+ {
802+ bool result = true;
803+
804+ /*
805+ * When channel_binding=require, we must protect against two cases: (1) we
806+ * must not respond to non-SASL authentication requests, which might leak
807+ * information such as the client's password; and (2) even if we receive
808+ * AUTH_REQ_OK, we still must ensure that channel binding has happened in
809+ * order to authenticate the server.
810+ */
811+ if (conn -> channel_binding [0 ] == 'r' /* require */ )
812+ {
813+ switch (areq )
814+ {
815+ case AUTH_REQ_SASL :
816+ case AUTH_REQ_SASL_CONT :
817+ case AUTH_REQ_SASL_FIN :
818+ break ;
819+ case AUTH_REQ_OK :
820+ if (!pg_fe_scram_channel_bound (conn -> sasl_state ))
821+ {
822+ printfPQExpBuffer (& conn -> errorMessage ,
823+ libpq_gettext ("Channel binding required, but server authenticated client without channel binding\n" ));
824+ result = false;
825+ }
826+ break ;
827+ default :
828+ printfPQExpBuffer (& conn -> errorMessage ,
829+ libpq_gettext ("Channel binding required but not supported by server's authentication request\n" ));
830+ result = false;
831+ break ;
832+ }
833+ }
834+
835+ return result ;
836+ }
837+
777838/*
778839 * pg_fe_sendauth
779840 * client demux routine for processing an authentication request
@@ -788,6 +849,9 @@ pg_password_sendauth(PGconn *conn, const char *password, AuthRequest areq)
788849int
789850pg_fe_sendauth (AuthRequest areq , int payloadlen , PGconn * conn )
790851{
852+ if (!check_expected_areq (areq , conn ))
853+ return STATUS_ERROR ;
854+
791855 switch (areq )
792856 {
793857 case AUTH_REQ_OK :
0 commit comments