in redshift_connector/core.py [0:0]
def handle_AUTHENTICATION_REQUEST(self: "Connection", data: bytes, cursor: Cursor) -> None:
# Int32 - An authentication code that represents different
# authentication messages:
# 0 = AuthenticationOk
# 5 = MD5 pwd
# 2 = Kerberos v5 (not supported)
# 3 = Cleartext pwd
# 4 = crypt() pwd (not supported)
# 6 = SCM credential (not supported)
# 7 = GSSAPI (not supported)
# 8 = GSSAPI data (not supported)
# 9 = SSPI (not supported)
# Some authentication messages have additional data following the
# authentication code. That data is documented in the appropriate
# class.
auth_code: int = 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: bytes = b"".join(cccc_unpack(data, 4))
if self.password is None:
raise InterfaceError("server requesting MD5 password authentication, but no " "password was provided")
pwd: bytes = 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: typing.List[str] = [m.decode("ascii") for m in data[4:-1].split(NULL_BYTE)]
self.auth: ScramClient = ScramClient(mechanisms, self.user.decode("utf8"), self.password.decode("utf8"))
init: bytes = self.auth.get_client_first().encode("utf8")
# SASLInitialResponse
self._write(create_message(PASSWORD, b"SCRAM-SHA-256" + NULL_BYTE + i_pack(len(init)) + init))
self._flush()
elif auth_code == 11:
# AuthenticationSASLContinue
self.auth.set_server_first(data[4:].decode("utf8"))
# SASLResponse
msg: bytes = 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("Authentication method " + str(auth_code) + " not supported by redshift_connector.")
else:
raise InterfaceError("Authentication method " + str(auth_code) + " not recognized by redshift_connector.")