From 18f7ef06e24c423ea26ffd2cca9a6e9ea661a466 Mon Sep 17 00:00:00 2001 From: mailchuck Date: Sun, 22 Nov 2015 16:43:53 +0100 Subject: [PATCH] SSL fixes Handle old Python compatibility better. --- src/class_receiveDataThread.py | 9 ++++++--- src/class_sendDataThread.py | 7 +++++-- src/shared.py | 13 ++++++++++--- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/class_receiveDataThread.py b/src/class_receiveDataThread.py index c227648a..c745569e 100644 --- a/src/class_receiveDataThread.py +++ b/src/class_receiveDataThread.py @@ -81,7 +81,9 @@ class receiveDataThread(threading.Thread): shared.numberOfBytesReceivedLastSecond = 0 dataLen = len(self.data) try: - if (self.services & shared.NODE_SSL == shared.NODE_SSL) and self.connectionIsOrWasFullyEstablished: + if ((self.services & shared.NODE_SSL == shared.NODE_SSL) and + self.connectionIsOrWasFullyEstablished and + shared.haveSSL(not self.initiatedConnection)): dataRecv = self.sslSock.recv(1024) else: dataRecv = self.sock.recv(1024) @@ -251,7 +253,8 @@ class receiveDataThread(threading.Thread): self.connectionIsOrWasFullyEstablished = True self.sslSock = self.sock - if (self.services & shared.NODE_SSL == shared.NODE_SSL and (self.initiatedConnection or sys.version_info >= (2, 7, 9))): + if (self.services & shared.NODE_SSL == shared.NODE_SSL and + shared.haveSSL(not self.initiatedConnection)): self.sslSock = ssl.wrap_socket(self.sock, keyfile = os.path.join(shared.codePath(), 'sslkeys', 'key.pem'), certfile = os.path.join(shared.codePath(), 'sslkeys', 'cert.pem'), server_side = not self.initiatedConnection, ssl_version=ssl.PROTOCOL_TLSv1, do_handshake_on_connect=False, ciphers='AECDH-AES256-SHA') if hasattr(self.sslSock, "context"): self.sslSock.context.set_ecdh_curve("secp256k1") @@ -267,7 +270,7 @@ class receiveDataThread(threading.Thread): except: break # Command the corresponding sendDataThread to set its own connectionIsOrWasFullyEstablished variable to True also - self.sendDataThreadQueue.put((0, 'connectionIsOrWasFullyEstablished', (self.services, self.sslSock))) + self.sendDataThreadQueue.put((0, 'connectionIsOrWasFullyEstablished', (self.services, self.sslSock, self.initiatedConnection))) if not self.initiatedConnection: shared.clientHasReceivedIncomingConnections = True diff --git a/src/class_sendDataThread.py b/src/class_sendDataThread.py index 665bbb1b..869f7425 100644 --- a/src/class_sendDataThread.py +++ b/src/class_sendDataThread.py @@ -39,6 +39,7 @@ class sendDataThread(threading.Thread): self.name = "sendData-" + self.peer.host self.streamNumber = streamNumber self.services = 0 + self.initiatedConnection = False self.remoteProtocolVersion = - \ 1 # This must be set using setRemoteProtocolVersion command which is sent through the self.sendDataThreadQueue queue. self.lastTimeISentData = int( @@ -82,7 +83,9 @@ class sendDataThread(threading.Thread): uploadRateLimitBytes = 999999999 # float("inf") doesn't work else: uploadRateLimitBytes = shared.config.getint('bitmessagesettings', 'maxuploadrate') * 1000 - if self.services & shared.NODE_SSL == shared.NODE_SSL and self.connectionIsOrWasFullyEstablished: + if ((self.services & shared.NODE_SSL == shared.NODE_SSL) and + self.connectionIsOrWasFullyEstablished and + shared.haveSSL(not self.initiatedConnection)): amountSent = self.sslSock.send(data[:1000]) else: amountSent = self.sock.send(data[:1000]) @@ -172,7 +175,7 @@ class sendDataThread(threading.Thread): break elif command == 'connectionIsOrWasFullyEstablished': self.connectionIsOrWasFullyEstablished = True - self.services, self.sslSock = data + self.services, self.sslSock, self.initiatedConnection = data else: logger.error('sendDataThread ID: ' + str(id(self)) + ' ignoring command ' + command + ' because the thread is not in stream' + str(deststream)) diff --git a/src/shared.py b/src/shared.py index 6cc29116..72a48516 100644 --- a/src/shared.py +++ b/src/shared.py @@ -149,11 +149,18 @@ def encodeHost(host): else: return socket.inet_pton(socket.AF_INET6, host) -def assembleVersionMessage(remoteHost, remotePort, myStreamNumber): +def haveSSL(server = False): + # python < 2.7.9's ssl library does not support ECDSA server due to missing initialisation of available curves, but client works ok + if server == False: + return True + elif sys.version_info >= (2,7,9): + return True + return False + +def assembleVersionMessage(remoteHost, remotePort, myStreamNumber, server = False): payload = '' payload += pack('>L', 3) # protocol version. - payload += pack('>q', NODE_NETWORK|(NODE_SSL if sys.version_info >= (2, 7, 9) else 0)) # bitflags of the services I offer. - # python < 2.7.9's ssl library does not support ECDSA server due to missing initialisation of available curves, but client works ok + payload += pack('>q', NODE_NETWORK|(NODE_SSL if haveSSL(server) else 0)) # bitflags of the services I offer. payload += pack('>q', int(time.time())) payload += pack(