@@ -19,6 +19,9 @@ module PostgresPR
1919
2020PROTO_VERSION = 3 << 16 #196608
2121
22+ class AuthenticationMethodMismatch < StandardError
23+ end
24+
2225class Connection
2326
2427 # Allow easy access to these instance variables
@@ -58,7 +61,10 @@ def initialize(database, user, password=nil, uri = nil)
5861 @transaction_status = nil
5962 @params = { }
6063 establish_connection ( uri )
61-
64+
65+ # Check if the password supplied is a Postgres-style md5 hash
66+ md5_hash_match = password . match ( /^md5([a-f0-9]{32})$/ )
67+
6268 @conn << StartupMessage . new ( PROTO_VERSION , 'user' => user , 'database' => database ) . dump
6369
6470 loop do
@@ -67,19 +73,24 @@ def initialize(database, user, password=nil, uri = nil)
6773 case msg
6874 when AuthentificationClearTextPassword
6975 raise ArgumentError , "no password specified" if password . nil?
76+ raise AuthenticationMethodMismatch , "Server expected clear text password auth" if md5_hash_match
7077 @conn << PasswordMessage . new ( password ) . dump
71-
7278 when AuthentificationCryptPassword
7379 raise ArgumentError , "no password specified" if password . nil?
80+ raise AuthenticationMethodMismatch , "Server expected crypt password auth" if md5_hash_match
7481 @conn << PasswordMessage . new ( password . crypt ( msg . salt ) ) . dump
75-
7682 when AuthentificationMD5Password
7783 raise ArgumentError , "no password specified" if password . nil?
7884 require 'digest/md5'
7985
80- m = Digest ::MD5 . hexdigest ( password + user )
86+ if md5_hash_match
87+ m = md5_hash_match [ 1 ]
88+ else
89+ m = Digest ::MD5 . hexdigest ( password + user )
90+ end
8191 m = Digest ::MD5 . hexdigest ( m + msg . salt )
8292 m = 'md5' + m
93+
8394 @conn << PasswordMessage . new ( m ) . dump
8495
8596 when AuthentificationKerberosV4 , AuthentificationKerberosV5 , AuthentificationSCMCredential
0 commit comments