def handle_AUTHENTICATION_REQUEST(self, data, context): # Int32 - An authentication code that represents different # authentication messages: # 0 = AuthenticationOk # 5 = MD5 pwd # 2 = Kerberos v5 (not supported by pg8000) # 3 = Cleartext pwd # 4 = crypt() pwd (not supported by pg8000) # 6 = SCM credential (not supported by pg8000) # 7 = GSSAPI (not supported by pg8000) # 8 = GSSAPI data (not supported by pg8000) # 9 = SSPI (not supported by pg8000) # Some authentication messages have additional data following the # authentication code. That data is documented in the appropriate # class. auth_code = i_unpack(data)[0] if auth_code == 0: pass elif auth_code == 3: if self.password is None: raise InterfaceError( "server requesting password authentication, but no password was " "provided") self._send_message(PASSWORD, self.password + NULL_BYTE) self._flush() elif auth_code == 5: ## # A message representing the backend requesting an MD5 hashed # password response. The response will be sent as # md5(md5(pwd + login) + salt). # Additional message data: # Byte4 - Hash salt. salt = b"".join(cccc_unpack(data, 4)) if self.password is None: raise InterfaceError( "server requesting MD5 password authentication, but no password " "was provided") pwd = b"md5" + md5( md5(self.password + self.user).hexdigest().encode("ascii") + salt).hexdigest().encode("ascii") # Byte1('p') - Identifies the message as a password message. # Int32 - Message length including self. # String - The password. Password may be encrypted. self._send_message(PASSWORD, pwd + NULL_BYTE) self._flush() elif auth_code == 10: # AuthenticationSASL mechanisms = [ m.decode("ascii") for m in data[4:-2].split(NULL_BYTE) ] self.auth = scramp.ScramClient( mechanisms, self.user.decode("utf8"), self.password.decode("utf8"), channel_binding=self.channel_binding, ) init = self.auth.get_client_first().encode("utf8") mech = self.auth.mechanism_name.encode("ascii") + NULL_BYTE # SASLInitialResponse self._write( create_message(PASSWORD, mech + i_pack(len(init)) + init)) self._flush() elif auth_code == 11: # AuthenticationSASLContinue self.auth.set_server_first(data[4:].decode("utf8")) # SASLResponse msg = self.auth.get_client_final().encode("utf8") self._write(create_message(PASSWORD, msg)) self._flush() elif auth_code == 12: # AuthenticationSASLFinal self.auth.set_server_final(data[4:].decode("utf8")) elif auth_code in (2, 4, 6, 7, 8, 9): raise InterfaceError( f"Authentication method {auth_code} not supported by pg8000.") else: raise InterfaceError( f"Authentication method {auth_code} not recognized by pg8000.")
def handle_AUTHENTICATION_REQUEST(self, data, context): """https://www.postgresql.org/docs/current/protocol-message-formats.html""" auth_code = i_unpack(data)[0] if auth_code == 0: pass elif auth_code == 3: if self.password is None: raise InterfaceError( "server requesting password authentication, but no password was " "provided") self._send_message(PASSWORD, self.password + NULL_BYTE) self._flush() elif auth_code == 5: salt = b"".join(cccc_unpack(data, 4)) if self.password is None: raise InterfaceError( "server requesting MD5 password authentication, but no password " "was provided") pwd = b"md5" + md5( md5(self.password + self.user).hexdigest().encode("ascii") + salt).hexdigest().encode("ascii") self._send_message(PASSWORD, pwd + NULL_BYTE) self._flush() elif auth_code == 10: # AuthenticationSASL mechanisms = [ m.decode("ascii") for m in data[4:-2].split(NULL_BYTE) ] self.auth = scramp.ScramClient( mechanisms, self.user.decode("utf8"), self.password.decode("utf8"), channel_binding=self.channel_binding, ) init = self.auth.get_client_first().encode("utf8") mech = self.auth.mechanism_name.encode("ascii") + NULL_BYTE # SASLInitialResponse self._send_message(PASSWORD, mech + i_pack(len(init)) + init) self._flush() elif auth_code == 11: # AuthenticationSASLContinue self.auth.set_server_first(data[4:].decode("utf8")) # SASLResponse msg = self.auth.get_client_final().encode("utf8") self._send_message(PASSWORD, msg) self._flush() elif auth_code == 12: # AuthenticationSASLFinal self.auth.set_server_final(data[4:].decode("utf8")) elif auth_code in (2, 4, 6, 7, 8, 9): raise InterfaceError( f"Authentication method {auth_code} not supported by pg8000.") else: raise InterfaceError( f"Authentication method {auth_code} not recognized by pg8000.")