SSL fixes

- uses constants for service flags
- requires SSL to use TLSv1 version (protection against POODLE-style
attacks)
- retry if sock.recv incomplete
This commit is contained in:
mailchuck 2015-11-13 17:01:09 +01:00 committed by Peter Surda
parent 2f874e41be
commit c7fb9e6a43
3 changed files with 11 additions and 7 deletions

View File

@ -81,7 +81,7 @@ class receiveDataThread(threading.Thread):
shared.numberOfBytesReceivedLastSecond = 0 shared.numberOfBytesReceivedLastSecond = 0
dataLen = len(self.data) dataLen = len(self.data)
try: try:
if (self.services & 2 == 2) and self.connectionIsOrWasFullyEstablished: if (self.services & shared.NODE_SSL == shared.NODE_SSL) and self.connectionIsOrWasFullyEstablished:
dataRecv = self.sslSock.recv(1024) dataRecv = self.sslSock.recv(1024)
else: else:
dataRecv = self.sock.recv(1024) dataRecv = self.sock.recv(1024)
@ -93,11 +93,11 @@ class receiveDataThread(threading.Thread):
print 'Timeout occurred waiting for data from', self.peer, '. Closing receiveData thread. (ID:', str(id(self)) + ')' print 'Timeout occurred waiting for data from', self.peer, '. Closing receiveData thread. (ID:', str(id(self)) + ')'
break break
except Exception as err: except Exception as err:
if (sys.platform == 'win32' and err.errno == 10035) or (sys.platform != 'win32' and err.errno == errno.EWOULDBLOCK): if (sys.platform == 'win32' and err.errno in ([2, 10035])) or (sys.platform != 'win32' and err.errno == errno.EWOULDBLOCK):
select.select([self.sslSock], [], []) select.select([self.sslSock], [], [])
continue continue
with shared.printLock: with shared.printLock:
print 'sock.recv error. Closing receiveData thread (' + str(self.peer) + ', Thread ID:', str(id(self)) + ').', err print 'sock.recv error. Closing receiveData thread (' + str(self.peer) + ', Thread ID:', str(id(self)) + ').', str(err.errno), "/", err
break break
# print 'Received', repr(self.data) # print 'Received', repr(self.data)
if len(self.data) == dataLen: # If self.sock.recv returned no data: if len(self.data) == dataLen: # If self.sock.recv returned no data:
@ -265,8 +265,8 @@ class receiveDataThread(threading.Thread):
self.connectionIsOrWasFullyEstablished = True self.connectionIsOrWasFullyEstablished = True
self.sslSock = self.sock self.sslSock = self.sock
if (self.services & 2 == 2): if (self.services & shared.NODE_SSL == shared.NODE_SSL):
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_SSLv23, do_handshake_on_connect=False, ciphers='AECDH-AES256-SHA') 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')
while True: while True:
try: try:
self.sslSock.do_handshake() self.sslSock.do_handshake()

View File

@ -83,7 +83,7 @@ class sendDataThread(threading.Thread):
uploadRateLimitBytes = 999999999 # float("inf") doesn't work uploadRateLimitBytes = 999999999 # float("inf") doesn't work
else: else:
uploadRateLimitBytes = shared.config.getint('bitmessagesettings', 'maxuploadrate') * 1000 uploadRateLimitBytes = shared.config.getint('bitmessagesettings', 'maxuploadrate') * 1000
if self.services & 2 == 2 and self.connectionIsOrWasFullyEstablished: if self.services & shared.NODE_SSL == shared.NODE_SSL and self.connectionIsOrWasFullyEstablished:
amountSent = self.sslSock.send(data[:1000]) amountSent = self.sslSock.send(data[:1000])
else: else:
amountSent = self.sock.send(data[:1000]) amountSent = self.sock.send(data[:1000])

View File

@ -120,6 +120,10 @@ trustedPeer = None
#New code should use CreatePacket instead of Header.pack #New code should use CreatePacket instead of Header.pack
Header = Struct('!L12sL4s') Header = Struct('!L12sL4s')
#Service flags
NODE_NETWORK = 1
NODE_SSL = 2
#Create a packet #Create a packet
def CreatePacket(command, payload=''): def CreatePacket(command, payload=''):
payload_length = len(payload) payload_length = len(payload)
@ -144,7 +148,7 @@ def encodeHost(host):
def assembleVersionMessage(remoteHost, remotePort, myStreamNumber): def assembleVersionMessage(remoteHost, remotePort, myStreamNumber):
payload = '' payload = ''
payload += pack('>L', 3) # protocol version. payload += pack('>L', 3) # protocol version.
payload += pack('>q', 3) # bitflags of the services I offer. payload += pack('>q', NODE_NETWORK|NODE_SSL) # bitflags of the services I offer.
payload += pack('>q', int(time.time())) payload += pack('>q', int(time.time()))
payload += pack( payload += pack(