Runnable with both Python3 and Python2, with PyQt4 #2249
|
@ -58,25 +58,44 @@ class TLSDispatcher(AdvancedDispatcher):
|
||||||
self.tlsDone = False
|
self.tlsDone = False
|
||||||
self.tlsVersion = "N/A"
|
self.tlsVersion = "N/A"
|
||||||
self.isSSL = False
|
self.isSSL = False
|
||||||
|
if ssl.OPENSSL_VERSION_NUMBER >= 0x30000000:
|
||||||
|
self.tlsPrepared = False
|
||||||
|
|
||||||
def state_tls_init(self):
|
def state_tls_init(self):
|
||||||
"""Prepare sockets for TLS handshake"""
|
"""Prepare sockets for TLS handshake"""
|
||||||
self.isSSL = True
|
self.isSSL = True
|
||||||
self.tlsStarted = True
|
self.tlsStarted = True
|
||||||
|
|
||||||
|
if ssl.OPENSSL_VERSION_NUMBER >= 0x30000000:
|
||||||
|
self.want_read = self.want_write = True
|
||||||
|
self.set_state("tls_handshake")
|
||||||
|
return False
|
||||||
|
|
||||||
|
do_tls_init(self)
|
||||||
|
|
||||||
|
def do_tls_init(self):
|
||||||
# Once the connection has been established,
|
# Once the connection has been established,
|
||||||
# it's safe to wrap the socket.
|
# it's safe to wrap the socket.
|
||||||
if sys.version_info >= (2, 7, 9):
|
if sys.version_info >= (2, 7, 9):
|
||||||
context = ssl.create_default_context(
|
if ssl.OPENSSL_VERSION_NUMBER >= 0x30000000:
|
||||||
purpose=ssl.Purpose.SERVER_AUTH
|
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
|
||||||
if self.server_side else ssl.Purpose.CLIENT_AUTH)
|
else:
|
||||||
|
context = ssl.create_default_context(
|
||||||
|
purpose=ssl.Purpose.SERVER_AUTH
|
||||||
|
if self.server_side else ssl.Purpose.CLIENT_AUTH)
|
||||||
context.set_ciphers(self.ciphers)
|
context.set_ciphers(self.ciphers)
|
||||||
context.set_ecdh_curve("secp256k1")
|
context.set_ecdh_curve("secp256k1")
|
||||||
context.check_hostname = False
|
context.check_hostname = False
|
||||||
context.verify_mode = ssl.CERT_NONE
|
context.verify_mode = ssl.CERT_NONE
|
||||||
# also exclude TLSv1 and TLSv1.1 in the future
|
# also exclude TLSv1 and TLSv1.1 in the future
|
||||||
context.options = ssl.OP_ALL | ssl.OP_NO_SSLv2 |\
|
if ssl.OPENSSL_VERSION_NUMBER >= 0x30000000:
|
||||||
ssl.OP_NO_SSLv3 | ssl.OP_SINGLE_ECDH_USE |\
|
context.options = ssl.OP_ALL | ssl.OP_NO_SSLv2 |\
|
||||||
ssl.OP_CIPHER_SERVER_PREFERENCE
|
ssl.OP_NO_SSLv3 | ssl.OP_SINGLE_ECDH_USE |\
|
||||||
|
ssl.OP_CIPHER_SERVER_PREFERENCE | ssl.OP_NO_TLS1_3
|
||||||
|
else:
|
||||||
|
context.options = ssl.OP_ALL | ssl.OP_NO_SSLv2 |\
|
||||||
|
ssl.OP_NO_SSLv3 | ssl.OP_SINGLE_ECDH_USE |\
|
||||||
|
ssl.OP_CIPHER_SERVER_PREFERENCE
|
||||||
self.sslSocket = context.wrap_socket(
|
self.sslSocket = context.wrap_socket(
|
||||||
self.socket, server_side=self.server_side,
|
self.socket, server_side=self.server_side,
|
||||||
do_handshake_on_connect=False)
|
do_handshake_on_connect=False)
|
||||||
|
@ -88,7 +107,10 @@ class TLSDispatcher(AdvancedDispatcher):
|
||||||
ciphers=self.ciphers, do_handshake_on_connect=False)
|
ciphers=self.ciphers, do_handshake_on_connect=False)
|
||||||
self.sslSocket.setblocking(0)
|
self.sslSocket.setblocking(0)
|
||||||
self.want_read = self.want_write = True
|
self.want_read = self.want_write = True
|
||||||
self.set_state("tls_handshake")
|
if ssl.OPENSSL_VERSION_NUMBER >= 0x30000000:
|
||||||
|
self.tlsPrepared = True
|
||||||
|
else:
|
||||||
|
self.set_state("tls_handshake")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -114,7 +136,9 @@ class TLSDispatcher(AdvancedDispatcher):
|
||||||
# during TLS handshake, and after flushing write buffer,
|
# during TLS handshake, and after flushing write buffer,
|
||||||
# return status of last handshake attempt
|
# return status of last handshake attempt
|
||||||
if self.tlsStarted and not self.tlsDone and not self.write_buf:
|
if self.tlsStarted and not self.tlsDone and not self.write_buf:
|
||||||
logger.debug('tls readable, %r', self.want_read)
|
# with OpenSSL 3, excessive logs are spitted
|
||||||
|
if ssl.OPENSSL_VERSION_NUMBER < 0x30000000:
|
||||||
|
logger.debug('tls readable, %r', self.want_read)
|
||||||
return self.want_read
|
return self.want_read
|
||||||
# prior to TLS handshake,
|
# prior to TLS handshake,
|
||||||
# receiveDataThread should emulate synchronous behaviour
|
# receiveDataThread should emulate synchronous behaviour
|
||||||
|
@ -134,6 +158,10 @@ class TLSDispatcher(AdvancedDispatcher):
|
||||||
try:
|
try:
|
||||||
# wait for write buffer flush
|
# wait for write buffer flush
|
||||||
if self.tlsStarted and not self.tlsDone and not self.write_buf:
|
if self.tlsStarted and not self.tlsDone and not self.write_buf:
|
||||||
|
if ssl.OPENSSL_VERSION_NUMBER >= 0x30000000:
|
||||||
|
if not self.tlsPrepared:
|
||||||
|
self.do_tls_init()
|
||||||
|
return
|
||||||
self.tls_handshake()
|
self.tls_handshake()
|
||||||
else:
|
else:
|
||||||
AdvancedDispatcher.handle_read(self)
|
AdvancedDispatcher.handle_read(self)
|
||||||
|
@ -156,6 +184,10 @@ class TLSDispatcher(AdvancedDispatcher):
|
||||||
try:
|
try:
|
||||||
# wait for write buffer flush
|
# wait for write buffer flush
|
||||||
if self.tlsStarted and not self.tlsDone and not self.write_buf:
|
if self.tlsStarted and not self.tlsDone and not self.write_buf:
|
||||||
|
if ssl.OPENSSL_VERSION_NUMBER >= 0x30000000:
|
||||||
|
if not self.tlsPrepared:
|
||||||
|
self.do_tls_init()
|
||||||
|
return
|
||||||
self.tls_handshake()
|
self.tls_handshake()
|
||||||
else:
|
else:
|
||||||
AdvancedDispatcher.handle_write(self)
|
AdvancedDispatcher.handle_write(self)
|
||||||
|
|
Reference in New Issue
Block a user