SSL communication errors when data was not sent via Twisted TLSConnection

I am starting to look for explicit FTP, expanding the current Twisted FTP.

Most of the code was straightforward, and the implementation of AUTH, PBSZ, PROT was simple, and I got a working secure control channel.

My problem is with the data feed.

Client side error: SSL routines', 'SSL3_READ_BYTES', 'ssl handshake failure'

It seems that SSL handshaking and disabling are only called up when some data is transmitted over the data channel. This affects the case of sending empty files or listing empty folders, because before closing the connection, the client causes SSL to be turned off.

I am caring for some suggestion on how and where I should look for a TLS handshake fix from Twisted TLS when no data is sent.

This code works when listing folders that are not empty ... but will fail if the folder does not contain files or folders.

Thank you very much!

 def getDTPPort(self, factory): """ Return a port for passive access, using C{self.passivePortRange} attribute. """ for portn in self.passivePortRange: try: if self.protected_data: dtpPort = reactor.listenSSL( port=portn, factory=factory, contextFactory=self.ssl_context) else: dtpPort = self.listenFactory(portn, factory) except error.CannotListenError: continue else: return dtpPort raise error.CannotListenError('', portn, "No port available in range %s" % (self.passivePortRange,)) 

Update 1

I will update this text as comments are poorly formed:

So, I ended up with:

 def getDTPPort(self, factory): """ Return a port for passive access, using C{self.passivePortRange} attribute. """ for portn in self.passivePortRange: try: if self.protected_data: tls_factory = TLSMemoryBIOFactory( contextFactory=self.ssl_context, isClient=False, wrappedFactory=factory) dtpPort = reactor.listenTCP( port=portn, factory=tls_factory) else: dtpPort = self.listenFactory(portn, factory) except error.CannotListenError: continue else: return dtpPort raise error.CannotListenError('', portn, "No port available in range %s" % (self.passivePortRange,)) 

Update 2

The problem is that the connection is closed while the handshake is still working. I do not know how to test the connection with an empty connection that was made using SSL.

So I ended up with this stupid code

 def loseConnection(self): """ Send a TLS close alert and close the underlying connection. """ self.disconnecting = True def close_connection(): if not self._writeBlockedOnRead: self._tlsConnection.shutdown() self._flushSendBIO() self.transport.loseConnection() # If we don't know if the handshake was done, we wait for a bit # and the close the connection. # This is done to avoid closing the connection in the middle of a # handshake. if not self._handshakeDone: reactor.callLater(0.1, close_connection) else: close_connection() 
0
source share
1 answer

SSL do_handshake initiated using the do_handshake method of the pyOpenSSL Connection object. It can also be triggered by an implicit call to send or recv . The transport configured on reactor.connectSSL and reactor.listenSSL depends on the latter. So, your conclusion is correct - a handshake is never executed if no data is sent over the connection.

However, twisted.protocols.tls calls do_handshake as soon as the connection is established. If you configured your SSL server with this API, I think you will see that your problem is resolved.

There is also a plan to redefine the former using the latter , since the latter seems to work better at all.

+2
source

Source: https://habr.com/ru/post/1339143/


All Articles