• Kirill Smelkov's avatar
    ssl: Don't ignore non-ragged EOF · 061cd5d8
    Kirill Smelkov authored
    Testing NEO/go client wrt NEO/py server revealed a bug in NEO/py SSL
    handling: proper non-ragged EOF from a peer is ignored, and so leads to
    hang in infinite loop inside _SSL.receive with read_buf memory growing
    indefinitely. Details are below:
    
    NEO/py wraps raw sockets with
    
    	ssl.wrap_socket(suppress_ragged_eofs=False)
    
    which instructs SSL layer to convert unexpected EOF when receiving a TLS
    record into SSLEOFError exception. However when remote peer properly
    closes its side of the connection, socket.read() still returns b'' to
    report non-ragged regular EOF:
    
    https://github.com/python/cpython/blob/v2.7.18/Lib/ssl.py#L630-L650
    
    The code was handling SSLEOFError but not b'' return from socket recv.
    Thus after NEO/go client was disconnecting and properly closing its side
    of the connection, the code started to loop indefinitely in _SSL.receive
    under `while 1` with  b'' returned by self.socket.recv() appended to
    read_buf again and again.
    
    -> Fix it by detecting non-ragged EOF as well and, similarly to how
    SSLEOFError is handled, converting them into self._error('recv', None).
    
    See merge request nexedi/neoppod!17
    061cd5d8
connector.py 12.8 KB