Skip to content

Commit b73c537

Browse files
Removed unneeded packet for changing the password of the connected user.
1 parent d56f257 commit b73c537

File tree

3 files changed

+65
-32
lines changed

3 files changed

+65
-32
lines changed

doc/src/release_notes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ Thin Mode Changes
4747
be timed out.
4848
- Removed packet for negotiating network services which are not supported
4949
in thin mode.
50+
- Removed unneeded packet for changing the password of the connected user.
5051

5152

5253
Thick Mode Changes

src/oracledb/impl/thin/connection.pyx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ cdef class ThinConnImpl(BaseConnImpl):
6666
uint32_t _call_timeout
6767
str _cclass
6868
int _dbobject_type_cache_num
69+
bytes _combo_key
6970

7071
def __init__(self, str dsn, ConnectParamsImpl params):
7172
if not HAS_CRYPTOGRAPHY:
@@ -296,8 +297,8 @@ cdef class ThinConnImpl(BaseConnImpl):
296297
self._protocol._break_external()
297298

298299
def change_password(self, str old_password, str new_password):
299-
cdef AuthMessage message
300-
message = self._create_message(AuthMessage)
300+
cdef ChangePasswordMessage message
301+
message = self._create_message(ChangePasswordMessage)
301302
message.password = old_password.encode()
302303
message.newpassword = new_password.encode()
303304
self._protocol._process_single_message(message)

src/oracledb/impl/thin/messages.pyx

Lines changed: 61 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1284,7 +1284,6 @@ cdef class MessageWithData(Message):
12841284
self._write_close_temp_lobs_piggyback(buf)
12851285

12861286

1287-
@cython.final
12881287
cdef class AuthMessage(Message):
12891288
cdef:
12901289
str encoded_password
@@ -1305,6 +1304,26 @@ cdef class AuthMessage(Message):
13051304
dict session_data
13061305
uint32_t auth_mode
13071306
uint32_t verifier_type
1307+
bint change_password
1308+
1309+
cdef int _encrypt_passwords(self) except -1:
1310+
"""
1311+
Encrypts the passwords using the session key.
1312+
"""
1313+
1314+
# encrypt password
1315+
salt = secrets.token_bytes(16)
1316+
password_with_salt = salt + self.password
1317+
encrypted_password = encrypt_cbc(self.conn_impl._combo_key,
1318+
password_with_salt)
1319+
self.encoded_password = encrypted_password.hex().upper()
1320+
1321+
# encrypt new password
1322+
if self.newpassword is not None:
1323+
newpassword_with_salt = salt + self.newpassword
1324+
encrypted_newpassword = encrypt_cbc(self.conn_impl._combo_key,
1325+
newpassword_with_salt)
1326+
self.encoded_newpassword = encrypted_newpassword.hex().upper()
13081327

13091328
cdef int _generate_verifier(self, bint verifier_11g) except -1:
13101329
"""
@@ -1342,35 +1361,27 @@ cdef class AuthMessage(Message):
13421361
# create session key from combo key
13431362
mixing_salt = bytes.fromhex(self.session_data['AUTH_PBKDF2_CSK_SALT'])
13441363
iterations = int(self.session_data['AUTH_PBKDF2_SDER_COUNT'])
1345-
combo_key = session_key_part_b[:keylen] + session_key_part_a[:keylen]
1346-
session_key = get_derived_key(combo_key.hex().upper().encode(),
1347-
mixing_salt, keylen, iterations)
1364+
temp_key = session_key_part_b[:keylen] + session_key_part_a[:keylen]
1365+
combo_key = get_derived_key(temp_key.hex().upper().encode(),
1366+
mixing_salt, keylen, iterations)
1367+
1368+
# retain session key for use by the change password API
1369+
self.conn_impl._combo_key = combo_key
13481370

13491371
# generate speedy key for 12c verifiers
13501372
if not verifier_11g:
13511373
salt = secrets.token_bytes(16)
1352-
speedy_key = encrypt_cbc(session_key, salt + password_key)
1374+
speedy_key = encrypt_cbc(combo_key, salt + password_key)
13531375
self.speedy_key = speedy_key[:80].hex().upper()
13541376

1355-
# encrypt password
1356-
salt = secrets.token_bytes(16)
1357-
password_with_salt = salt + self.password
1358-
encrypted_password = encrypt_cbc(session_key, password_with_salt)
1359-
self.encoded_password = encrypted_password.hex().upper()
1360-
1361-
# encrypt new password
1362-
if self.newpassword is not None:
1363-
newpassword_with_salt = salt + self.newpassword
1364-
encrypted_newpassword = encrypt_cbc(session_key,
1365-
newpassword_with_salt)
1366-
self.encoded_newpassword = encrypted_newpassword.hex().upper()
1377+
# encrypts the passwords
1378+
self._encrypt_passwords()
13671379

13681380
# check if debug_jdwp is set. if set, encode the data using the
13691381
# combo session key with zeros padding
13701382
if self.debug_jdwp is not None:
13711383
jdwp_data = self.debug_jdwp.encode()
1372-
encrypted_jdwp_data = encrypt_cbc(session_key, jdwp_data,
1373-
zeros=True)
1384+
encrypted_jdwp_data = encrypt_cbc(combo_key, jdwp_data, zeros=True)
13741385
# Add a "01" at the end of the hex encrypted data to indicate the
13751386
# use of AES encryption
13761387
self.encoded_jdwp_data = encrypted_jdwp_data.hex().upper() + "01"
@@ -1427,7 +1438,7 @@ cdef class AuthMessage(Message):
14271438
self.session_data[key] = value
14281439
if self.function_code == TNS_FUNC_AUTH_PHASE_ONE:
14291440
self.function_code = TNS_FUNC_AUTH_PHASE_TWO
1430-
else:
1441+
elif not self.change_password:
14311442
self.conn_impl._session_id = \
14321443
<uint32_t> int(self.session_data["AUTH_SESSION_ID"])
14331444
self.conn_impl._serial_num = \
@@ -1513,6 +1524,9 @@ cdef class AuthMessage(Message):
15131524
# perform final determination of data to write
15141525
if self.function_code == TNS_FUNC_AUTH_PHASE_ONE:
15151526
num_pairs = 5
1527+
elif self.change_password:
1528+
self._encrypt_passwords()
1529+
num_pairs = 2
15161530
else:
15171531
num_pairs = 3
15181532

@@ -1578,22 +1592,24 @@ cdef class AuthMessage(Message):
15781592
self.proxy_user)
15791593
if self.token is not None:
15801594
self._write_key_value(buf, "AUTH_TOKEN", self.token)
1581-
else:
1595+
elif not self.change_password:
15821596
self._write_key_value(buf, "AUTH_SESSKEY", self.session_key, 1)
1583-
self._write_key_value(buf, "AUTH_PASSWORD",
1584-
self.encoded_password)
15851597
if not verifier_11g:
15861598
self._write_key_value(buf, "AUTH_PBKDF2_SPEEDY_KEY",
15871599
self.speedy_key)
1588-
if self.newpassword is not None:
1600+
if self.encoded_password is not None:
1601+
self._write_key_value(buf, "AUTH_PASSWORD",
1602+
self.encoded_password)
1603+
if self.encoded_newpassword is not None:
15891604
self._write_key_value(buf, "AUTH_NEWPASSWORD",
15901605
self.encoded_newpassword)
1591-
self._write_key_value(buf, "SESSION_CLIENT_CHARSET", "873")
1592-
driver_name = f"{constants.DRIVER_NAME} thn : {VERSION}"
1593-
self._write_key_value(buf, "SESSION_CLIENT_DRIVER_NAME",
1594-
driver_name)
1595-
self._write_key_value(buf, "SESSION_CLIENT_VERSION",
1596-
str(_connect_constants.full_version_num))
1606+
if not self.change_password:
1607+
self._write_key_value(buf, "SESSION_CLIENT_CHARSET", "873")
1608+
driver_name = f"{constants.DRIVER_NAME} thn : {VERSION}"
1609+
self._write_key_value(buf, "SESSION_CLIENT_DRIVER_NAME",
1610+
driver_name)
1611+
self._write_key_value(buf, "SESSION_CLIENT_VERSION",
1612+
str(_connect_constants.full_version_num))
15971613
if self.conn_impl._cclass is not None:
15981614
self._write_key_value(buf, "AUTH_KPPL_CONN_CLASS",
15991615
self.conn_impl._cclass)
@@ -1615,6 +1631,21 @@ cdef class AuthMessage(Message):
16151631
self.encoded_jdwp_data)
16161632

16171633

1634+
@cython.final
1635+
cdef class ChangePasswordMessage(AuthMessage):
1636+
1637+
cdef int _initialize_hook(self) except -1:
1638+
"""
1639+
Perform initialization.
1640+
"""
1641+
self.change_password = True
1642+
self.function_code = TNS_FUNC_AUTH_PHASE_TWO
1643+
self.user_bytes = self.conn_impl.username.encode()
1644+
self.user_bytes_len = len(self.user_bytes)
1645+
self.auth_mode = TNS_AUTH_MODE_WITH_PASSWORD | \
1646+
TNS_AUTH_MODE_CHANGE_PASSWORD
1647+
1648+
16181649
@cython.final
16191650
cdef class CommitMessage(Message):
16201651

0 commit comments

Comments
 (0)