@@ -423,6 +423,14 @@ pg_SASL_init(PGconn *conn, int payloadlen)
423
423
424
424
initPQExpBuffer (& mechanism_buf );
425
425
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
+
426
434
if (conn -> sasl_state )
427
435
{
428
436
printfPQExpBuffer (& conn -> errorMessage ,
@@ -454,10 +462,10 @@ pg_SASL_init(PGconn *conn, int payloadlen)
454
462
455
463
/*
456
464
* 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.
461
469
*/
462
470
if (strcmp (mechanism_buf .data , SCRAM_SHA_256_PLUS_NAME ) == 0 )
463
471
{
@@ -466,10 +474,11 @@ pg_SASL_init(PGconn *conn, int payloadlen)
466
474
/*
467
475
* The server has offered SCRAM-SHA-256-PLUS, which is only
468
476
* 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 .
470
478
*/
471
479
#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 ;
473
482
#endif
474
483
}
475
484
else
@@ -493,6 +502,14 @@ pg_SASL_init(PGconn *conn, int payloadlen)
493
502
selected_mechanism = SCRAM_SHA_256_NAME ;
494
503
}
495
504
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
+
496
513
if (!selected_mechanism )
497
514
{
498
515
printfPQExpBuffer (& conn -> errorMessage ,
@@ -774,6 +791,50 @@ pg_password_sendauth(PGconn *conn, const char *password, AuthRequest areq)
774
791
return ret ;
775
792
}
776
793
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
+
777
838
/*
778
839
* pg_fe_sendauth
779
840
* client demux routine for processing an authentication request
@@ -788,6 +849,9 @@ pg_password_sendauth(PGconn *conn, const char *password, AuthRequest areq)
788
849
int
789
850
pg_fe_sendauth (AuthRequest areq , int payloadlen , PGconn * conn )
790
851
{
852
+ if (!check_expected_areq (areq , conn ))
853
+ return STATUS_ERROR ;
854
+
791
855
switch (areq )
792
856
{
793
857
case AUTH_REQ_OK :
0 commit comments