Skip to content

Commit 501f2fe

Browse files
Fixed a bug that caused TLS renegotiation to be skipped in some
configurations (#34).
1 parent 9c6db58 commit 501f2fe

File tree

6 files changed

+37
-18
lines changed

6 files changed

+37
-18
lines changed

doc/src/release_notes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ Thin Mode Changes
2323
#) When using the connection parameter `https_proxy` while using protocol
2424
`tcp`, a more meaningful exception is now raised:
2525
`DPY-2029: https_proxy requires use of the tcps protocol`.
26+
#) Fixed a bug that caused TLS renegotiation to be skipped in some
27+
configurations
28+
(https://github.com/oracle/python-oracledb/discussions/34).
2629
#) Internally make use of the `TCP_NODELAY` socket option to remove delays
2730
in socket reads.
2831

src/oracledb/impl/thin/buffer.pyx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -324,14 +324,14 @@ cdef class ReadBuffer:
324324
"""
325325
cdef:
326326
ssize_t num_bytes_left, num_bytes_split, max_split_data
327+
uint8_t packet_type, packet_flags
327328
const char_type *source_ptr
328-
uint8_t packet_type
329329
char_type *dest_ptr
330330

331331
# if no bytes are left in the buffer, a new packet needs to be fetched
332332
# before anything else can take place
333333
if self._offset == self._size:
334-
self.receive_packet(&packet_type)
334+
self.receive_packet(&packet_type, &packet_flags)
335335
self.skip_raw_bytes(2) # skip data flags
336336

337337
# if there is enough room in the buffer to satisfy the number of bytes
@@ -367,7 +367,7 @@ cdef class ReadBuffer:
367367
while num_bytes > 0:
368368

369369
# acquire new packet
370-
self.receive_packet(&packet_type)
370+
self.receive_packet(&packet_type, &packet_flags)
371371
self.skip_raw_bytes(2) # skip data flags
372372

373373
# copy data into the chunked buffer or split buffer, as appropriate
@@ -405,7 +405,8 @@ cdef class ReadBuffer:
405405
errors._raise_err(errors.ERR_UNSUPPORTED_INBAND_NOTIFICATION,
406406
err_num=error_num)
407407

408-
cdef int _receive_packet_helper(self, uint8_t *packet_type) except -1:
408+
cdef int _receive_packet_helper(self, uint8_t *packet_type,
409+
uint8_t *packet_flags) except -1:
409410
"""
410411
Receives a packet and updates the pointers appropriately. Note that
411412
multiple packets may be received if they are small enough or a portion
@@ -475,7 +476,8 @@ cdef class ReadBuffer:
475476
if self._caps.protocol_version < TNS_VERSION_MIN_LARGE_SDU:
476477
self.skip_raw_bytes(2) # skip packet checksum
477478
self.read_ub1(packet_type)
478-
self.skip_raw_bytes(3) # skip reserved byte, header checksum
479+
self.read_ub1(packet_flags)
480+
self.skip_raw_bytes(2) # header checksum
479481

480482
# display packet if requested
481483
if DEBUG_PACKETS:
@@ -1079,14 +1081,15 @@ cdef class ReadBuffer:
10791081

10801082
return bytes(output_value).decode()
10811083

1082-
cdef int receive_packet(self, uint8_t *packet_type) except -1:
1084+
cdef int receive_packet(self, uint8_t *packet_type,
1085+
uint8_t *packet_flags) except -1:
10831086
"""
10841087
Calls _receive_packet_helper() and checks the packet type. If a
10851088
control packet is received, it is processed and the next packet is
10861089
received.
10871090
"""
10881091
while True:
1089-
self._receive_packet_helper(packet_type)
1092+
self._receive_packet_helper(packet_type, packet_flags)
10901093
if packet_type[0] == TNS_PACKET_TYPE_CONTROL:
10911094
self._process_control_packet()
10921095
continue

src/oracledb/impl/thin/constants.pxi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ DEF TNS_PACKET_TYPE_MARKER = 12
3939
DEF TNS_PACKET_TYPE_CONTROL = 14
4040
DEF TNS_PACKET_TYPE_REDIRECT = 5
4141

42+
# packet flags
43+
DEF TNS_PACKET_FLAG_TLS_RENEG = 0x08
44+
4245
# marker types
4346
DEF TNS_MARKER_TYPE_BREAK = 1
4447
DEF TNS_MARKER_TYPE_RESET = 2

src/oracledb/impl/thin/crypto.pyx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,14 @@ def get_ssl_socket(sock, ConnectParamsImpl params, Description description,
117117
ssl_context.load_verify_locations(pem_file_name)
118118
ssl_context.load_cert_chain(pem_file_name,
119119
password=params._get_wallet_password())
120+
return perform_tls_negotiation(sock, ssl_context, description, address)
121+
122+
123+
def perform_tls_negotiation(sock, ssl_context, Description description,
124+
Address address):
125+
"""
126+
Peforms TLS negotiation.
127+
"""
120128
if description.ssl_server_dn_match \
121129
and description.ssl_server_cert_dn is None:
122130
sock = ssl_context.wrap_socket(sock, server_hostname=address.host)

src/oracledb/impl/thin/messages.pyx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ cdef class Message:
5151
uint32_t call_status
5252
uint16_t end_to_end_seq_num
5353
uint8_t packet_type
54+
uint8_t packet_flags
5455
bint error_occurred
5556
bint flush_out_binds
5657
bint processed_error
@@ -1543,7 +1544,7 @@ cdef class ConnectMessage(Message):
15431544
const char_type *redirect_data
15441545
if self.packet_type == TNS_PACKET_TYPE_REDIRECT:
15451546
buf.read_uint16(&redirect_data_length)
1546-
buf.receive_packet(&self.packet_type)
1547+
buf.receive_packet(&self.packet_type, &self.packet_flags)
15471548
buf.skip_raw_bytes(2) # skip data flags
15481549
redirect_data = buf._get_raw(redirect_data_length)
15491550
self.redirect_data = \

src/oracledb/impl/thin/protocol.pyx

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -157,17 +157,16 @@ cdef class Protocol:
157157
if connect_message.packet_type == TNS_PACKET_TYPE_ACCEPT:
158158
break
159159

160-
# for TCPS connections, OOB processing is not supported; if a
161-
# wallet is required, the socket must be rewrapped in order to
162-
# be usable; disable the check on the host name, however, as that
163-
# has already been done successfully
160+
# for TCPS connections, OOB processing is not supported; if the
161+
# packet flags indicate that TLS renegotiation is required, this is
162+
# performed now
164163
if address.protocol == "tcps":
165164
self._caps.supports_oob = False
166-
if description.wallet_location is not None:
165+
if connect_message.packet_flags & TNS_PACKET_FLAG_TLS_RENEG:
167166
ssl_context = self._socket.context
168-
ssl_context.check_hostname = False
169167
sock = socket.socket(fileno=self._socket.detach())
170-
sock = ssl_context.wrap_socket(sock)
168+
sock = perform_tls_negotiation(sock, ssl_context,
169+
description, address)
171170
self._set_socket(sock)
172171

173172
cdef int _connect_phase_two(self, ThinConnImpl conn_impl,
@@ -306,7 +305,7 @@ cdef class Protocol:
306305

307306
cdef int _receive_packet(self, Message message) except -1:
308307
cdef ReadBuffer buf = self._read_buf
309-
buf.receive_packet(&message.packet_type)
308+
buf.receive_packet(&message.packet_type, &message.packet_flags)
310309
if message.packet_type == TNS_PACKET_TYPE_MARKER:
311310
self._reset(message)
312311
elif message.packet_type == TNS_PACKET_TYPE_REFUSE:
@@ -342,15 +341,17 @@ cdef class Protocol:
342341
self._read_buf.read_ub1(&marker_type)
343342
if marker_type == TNS_MARKER_TYPE_RESET:
344343
break
345-
self._read_buf.receive_packet(&message.packet_type)
344+
self._read_buf.receive_packet(&message.packet_type,
345+
&message.packet_flags)
346346

347347
# read error packet; first skip as many marker packets as may be sent
348348
# by the server; if the server doesn't handle out-of-band breaks
349349
# properly, some quit immediately and others send multiple reset
350350
# markers (this addresses both situations without resulting in strange
351351
# errors)
352352
while message.packet_type == TNS_PACKET_TYPE_MARKER:
353-
self._read_buf.receive_packet(&message.packet_type)
353+
self._read_buf.receive_packet(&message.packet_type,
354+
&message.packet_flags)
354355
self._break_in_progress = False
355356

356357
cdef int _send_marker(self, WriteBuffer buf, uint8_t marker_type):

0 commit comments

Comments
 (0)