@@ -481,54 +481,57 @@ where
481
481
let process_id: i32 = rand:: random ( ) ;
482
482
let secret_key: i32 = rand:: random ( ) ;
483
483
484
- // Perform MD5 authentication.
485
- // TODO: Add SASL support.
486
- let salt = md5_challenge ( & mut write) . await ?;
484
+ let mut prepared_statements_enabled = false ;
487
485
488
- let code = match read. read_u8 ( ) . await {
489
- Ok ( p) => p,
490
- Err ( _) => {
491
- return Err ( Error :: ClientSocketError (
492
- "password code" . into ( ) ,
493
- client_identifier,
494
- ) )
495
- }
496
- } ;
486
+ // Authenticate admin user.
487
+ let ( transaction_mode, mut server_parameters) = if admin {
497
488
498
- // PasswordMessage
499
- if code as char != 'p' {
500
- return Err ( Error :: ProtocolSyncError ( format ! (
501
- "Expected p, got {}" ,
502
- code as char
503
- ) ) ) ;
504
- }
505
489
506
- let len = match read. read_i32 ( ) . await {
507
- Ok ( len) => len,
508
- Err ( _) => {
509
- return Err ( Error :: ClientSocketError (
510
- "password message length" . into ( ) ,
511
- client_identifier,
512
- ) )
513
- }
514
- } ;
490
+ // Perform MD5 authentication.
491
+ // TODO: Add SASL support.
492
+ let salt = md5_challenge ( & mut write) . await ?;
515
493
516
- let mut password_response = vec ! [ 0u8 ; ( len - 4 ) as usize ] ;
494
+ let code = match read. read_u8 ( ) . await {
495
+ Ok ( p) => p,
496
+ Err ( _) => {
497
+ return Err ( Error :: ClientSocketError (
498
+ "password code" . into ( ) ,
499
+ client_identifier,
500
+ ) )
501
+ }
502
+ } ;
517
503
518
- match read. read_exact ( & mut password_response) . await {
519
- Ok ( _) => ( ) ,
520
- Err ( _) => {
521
- return Err ( Error :: ClientSocketError (
522
- "password message" . into ( ) ,
523
- client_identifier,
524
- ) )
504
+ // PasswordMessage
505
+ if code as char != 'p' {
506
+ return Err ( Error :: ProtocolSyncError ( format ! (
507
+ "Expected p, got {}" ,
508
+ code as char
509
+ ) ) ) ;
525
510
}
526
- } ;
527
511
528
- let mut prepared_statements_enabled = false ;
512
+ let len = match read. read_i32 ( ) . await {
513
+ Ok ( len) => len,
514
+ Err ( _) => {
515
+ return Err ( Error :: ClientSocketError (
516
+ "password message length" . into ( ) ,
517
+ client_identifier,
518
+ ) )
519
+ }
520
+ } ;
521
+
522
+ let mut password_response = vec ! [ 0u8 ; ( len - 4 ) as usize ] ;
523
+
524
+ match read. read_exact ( & mut password_response) . await {
525
+ Ok ( _) => ( ) ,
526
+ Err ( _) => {
527
+ return Err ( Error :: ClientSocketError (
528
+ "password message" . into ( ) ,
529
+ client_identifier,
530
+ ) )
531
+ }
532
+ } ;
533
+
529
534
530
- // Authenticate admin user.
531
- let ( transaction_mode, mut server_parameters) = if admin {
532
535
let config = get_config ( ) ;
533
536
534
537
// Compare server and client hashes.
@@ -573,89 +576,136 @@ where
573
576
// Obtain the hash to compare, we give preference to that written in cleartext in config
574
577
// if there is nothing set in cleartext and auth passthrough (auth_query) is configured, we use the hash obtained
575
578
// when the pool was created. If there is no hash there, we try to fetch it one more time.
576
- let password_hash = if let Some ( password) = & pool. settings . user . password {
577
- Some ( md5_hash_password ( username, password, & salt) )
578
- } else {
579
- if !get_config ( ) . is_auth_query_configured ( ) {
580
- wrong_password ( & mut write, username) . await ?;
581
- return Err ( Error :: ClientAuthImpossible ( username. into ( ) ) ) ;
579
+ if let "md5" = pool. settings . user . auth_type . as_str ( ) {
580
+ // Perform MD5 authentication.
581
+ // TODO: Add SASL support.
582
+ let salt = md5_challenge ( & mut write) . await ?;
583
+
584
+ let code = match read. read_u8 ( ) . await {
585
+ Ok ( p) => p,
586
+ Err ( _) => {
587
+ return Err ( Error :: ClientSocketError (
588
+ "password code" . into ( ) ,
589
+ client_identifier,
590
+ ) )
591
+ }
592
+ } ;
593
+
594
+ // PasswordMessage
595
+ if code as char != 'p' {
596
+ return Err ( Error :: ProtocolSyncError ( format ! (
597
+ "Expected p, got {}" ,
598
+ code as char
599
+ ) ) ) ;
582
600
}
583
601
584
- let mut hash = ( * pool. auth_hash . read ( ) ) . clone ( ) ;
602
+ let len = match read. read_i32 ( ) . await {
603
+ Ok ( len) => len,
604
+ Err ( _) => {
605
+ return Err ( Error :: ClientSocketError (
606
+ "password message length" . into ( ) ,
607
+ client_identifier,
608
+ ) )
609
+ }
610
+ } ;
585
611
586
- if hash. is_none ( ) {
587
- warn ! (
588
- "Query auth configured \
589
- but no hash password found \
590
- for pool {}. Will try to refetch it.",
591
- pool_name
592
- ) ;
612
+ let mut password_response = vec ! [ 0u8 ; ( len - 4 ) as usize ] ;
593
613
594
- match refetch_auth_hash ( & pool) . await {
595
- Ok ( fetched_hash) => {
596
- warn ! ( "Password for {}, obtained. Updating." , client_identifier) ;
614
+ match read. read_exact ( & mut password_response) . await {
615
+ Ok ( _) => ( ) ,
616
+ Err ( _) => {
617
+ return Err ( Error :: ClientSocketError (
618
+ "password message" . into ( ) ,
619
+ client_identifier,
620
+ ) )
621
+ }
622
+ } ;
597
623
598
- {
599
- let mut pool_auth_hash = pool. auth_hash . write ( ) ;
600
- * pool_auth_hash = Some ( fetched_hash. clone ( ) ) ;
601
- }
624
+ let password_hash = if let Some ( password) = & pool. settings . user . password {
602
625
603
- hash = Some ( fetched_hash) ;
604
- }
626
+ Some ( md5_hash_password ( username, password, & salt) )
627
+ } else {
628
+ if !get_config ( ) . is_auth_query_configured ( ) {
629
+ wrong_password ( & mut write, username) . await ?;
630
+ return Err ( Error :: ClientAuthImpossible ( username. into ( ) ) ) ;
631
+ }
605
632
606
- Err ( err) => {
607
- wrong_password ( & mut write, username) . await ?;
633
+ let mut hash = ( * pool. auth_hash . read ( ) ) . clone ( ) ;
608
634
609
- return Err ( Error :: ClientAuthPassthroughError (
610
- err . to_string ( ) ,
611
- client_identifier ,
612
- ) ) ;
613
- }
614
- }
615
- } ;
635
+ if hash . is_none ( ) {
636
+ warn ! (
637
+ "Query auth configured \
638
+ but no hash password found \
639
+ for pool {}. Will try to refetch it." ,
640
+ pool_name
641
+ ) ;
616
642
617
- Some ( md5_hash_second_pass ( & hash. unwrap ( ) , & salt) )
618
- } ;
643
+ match refetch_auth_hash ( & pool) . await {
644
+ Ok ( fetched_hash) => {
645
+ warn ! ( "Password for {}, obtained. Updating." , client_identifier) ;
619
646
620
- // Once we have the resulting hash, we compare with what the client gave us.
621
- // If they do not match and auth query is set up, we try to refetch the hash one more time
622
- // to see if the password has changed since the pool was created.
623
- //
624
- // @TODO: we could end up fetching again the same password twice (see above).
625
- if password_hash. unwrap ( ) != password_response {
626
- warn ! (
627
- "Invalid password {}, will try to refetch it." ,
628
- client_identifier
629
- ) ;
647
+ {
648
+ let mut pool_auth_hash = pool. auth_hash . write ( ) ;
649
+ * pool_auth_hash = Some ( fetched_hash. clone ( ) ) ;
650
+ }
630
651
631
- let fetched_hash = match refetch_auth_hash ( & pool) . await {
632
- Ok ( fetched_hash) => fetched_hash,
633
- Err ( err) => {
634
- wrong_password ( & mut write, username) . await ?;
652
+ hash = Some ( fetched_hash) ;
653
+ }
635
654
636
- return Err ( err) ;
637
- }
638
- } ;
655
+ Err ( err) => {
656
+ wrong_password ( & mut write, username) . await ?;
639
657
640
- let new_password_hash = md5_hash_second_pass ( & fetched_hash, & salt) ;
658
+ return Err ( Error :: ClientAuthPassthroughError (
659
+ err. to_string ( ) ,
660
+ client_identifier,
661
+ ) ) ;
662
+ }
663
+ }
664
+ } ;
641
665
642
- // Ok password changed in server an auth is possible.
643
- if new_password_hash == password_response {
666
+ Some ( md5_hash_second_pass ( & hash. unwrap ( ) , & salt) )
667
+ } ;
668
+
669
+ // Once we have the resulting hash, we compare with what the client gave us.
670
+ // If they do not match and auth query is set up, we try to refetch the hash one more time
671
+ // to see if the password has changed since the pool was created.
672
+ //
673
+ // @TODO: we could end up fetching again the same password twice (see above).
674
+ if password_hash. unwrap ( ) != password_response {
644
675
warn ! (
645
- "Password for {}, changed in server. Updating ." ,
676
+ "Invalid password {}, will try to refetch it ." ,
646
677
client_identifier
647
678
) ;
648
679
649
- {
650
- let mut pool_auth_hash = pool. auth_hash . write ( ) ;
651
- * pool_auth_hash = Some ( fetched_hash) ;
680
+ let fetched_hash = match refetch_auth_hash ( & pool) . await {
681
+ Ok ( fetched_hash) => fetched_hash,
682
+ Err ( err) => {
683
+ wrong_password ( & mut write, username) . await ?;
684
+
685
+ return Err ( err) ;
686
+ }
687
+ } ;
688
+
689
+ let new_password_hash = md5_hash_second_pass ( & fetched_hash, & salt) ;
690
+
691
+ // Ok password changed in server an auth is possible.
692
+ if new_password_hash == password_response {
693
+ warn ! (
694
+ "Password for {}, changed in server. Updating." ,
695
+ client_identifier
696
+ ) ;
697
+
698
+ {
699
+ let mut pool_auth_hash = pool. auth_hash . write ( ) ;
700
+ * pool_auth_hash = Some ( fetched_hash) ;
701
+ }
702
+ } else {
703
+ wrong_password ( & mut write, username) . await ?;
704
+ return Err ( Error :: ClientGeneralError (
705
+ "Invalid password" . into ( ) ,
706
+ client_identifier,
707
+ ) ) ;
652
708
}
653
- } else {
654
- wrong_password ( & mut write, username) . await ?;
655
- return Err ( Error :: ClientGeneralError (
656
- "Invalid password" . into ( ) ,
657
- client_identifier,
658
- ) ) ;
659
709
}
660
710
}
661
711
0 commit comments