mirror of
https://github.com/python/cpython.git
synced 2025-07-15 23:35:23 +00:00
Merged revisions 80454 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k ................ r80454 | antoine.pitrou | 2010-04-24 23:26:44 +0200 (sam., 24 avril 2010) | 15 lines Merged revisions 80451-80452 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r80451 | antoine.pitrou | 2010-04-24 21:57:01 +0200 (sam., 24 avril 2010) | 4 lines The do_handshake() method of SSL objects now adjusts the blocking mode of the SSL structure if necessary (as other methods already do). ........ r80452 | antoine.pitrou | 2010-04-24 22:04:58 +0200 (sam., 24 avril 2010) | 4 lines Issue #5103: SSL handshake would ignore the socket timeout and block indefinitely if the other end didn't respond. ........ ................
This commit is contained in:
parent
44bb1f7eab
commit
ec146185c4
4 changed files with 126 additions and 23 deletions
|
@ -580,11 +580,8 @@ else:
|
|||
certfile=certfile,
|
||||
do_handshake_on_connect=False)
|
||||
asyncore.dispatcher_with_send.__init__(self, self.socket)
|
||||
# now we have to do the handshake
|
||||
# we'll just do it the easy way, and block the connection
|
||||
# till it's finished. If we were doing it right, we'd
|
||||
# do this in multiple calls to handle_read...
|
||||
self.do_handshake(block=True)
|
||||
self._ssl_accepting = True
|
||||
self._do_ssl_handshake()
|
||||
|
||||
def readable(self):
|
||||
if isinstance(self.socket, ssl.SSLSocket):
|
||||
|
@ -592,18 +589,37 @@ else:
|
|||
self.handle_read_event()
|
||||
return True
|
||||
|
||||
def handle_read(self):
|
||||
data = self.recv(1024)
|
||||
if support.verbose:
|
||||
sys.stdout.write(" server: read %s from client\n" % repr(data))
|
||||
if not data:
|
||||
self.close()
|
||||
def _do_ssl_handshake(self):
|
||||
try:
|
||||
self.socket.do_handshake()
|
||||
except ssl.SSLError as err:
|
||||
if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
|
||||
ssl.SSL_ERROR_WANT_WRITE):
|
||||
return
|
||||
elif err.args[0] == ssl.SSL_ERROR_EOF:
|
||||
return self.handle_close()
|
||||
raise
|
||||
except socket.error as err:
|
||||
if err.args[0] == errno.ECONNABORTED:
|
||||
return self.handle_close()
|
||||
else:
|
||||
self.send(str(data, 'ASCII', 'strict').lower().encode('ASCII', 'strict'))
|
||||
self._ssl_accepting = False
|
||||
|
||||
def handle_read(self):
|
||||
if self._ssl_accepting:
|
||||
self._do_ssl_handshake()
|
||||
else:
|
||||
data = self.recv(1024)
|
||||
if support.verbose:
|
||||
sys.stdout.write(" server: read %s from client\n" % repr(data))
|
||||
if not data:
|
||||
self.close()
|
||||
else:
|
||||
self.send(str(data, 'ASCII', 'strict').lower().encode('ASCII', 'strict'))
|
||||
|
||||
def handle_close(self):
|
||||
self.close()
|
||||
if support.verbose:
|
||||
if test_support.verbose:
|
||||
sys.stdout.write(" server: closed connection %s\n" % self.socket)
|
||||
|
||||
def handle_error(self):
|
||||
|
@ -1222,6 +1238,55 @@ else:
|
|||
server.stop()
|
||||
server.join()
|
||||
|
||||
def test_handshake_timeout(self):
|
||||
# Issue #5103: SSL handshake must respect the socket timeout
|
||||
server = socket.socket(socket.AF_INET)
|
||||
host = "127.0.0.1"
|
||||
port = support.bind_port(server)
|
||||
started = threading.Event()
|
||||
finish = False
|
||||
|
||||
def serve():
|
||||
server.listen(5)
|
||||
started.set()
|
||||
conns = []
|
||||
while not finish:
|
||||
r, w, e = select.select([server], [], [], 0.1)
|
||||
if server in r:
|
||||
# Let the socket hang around rather than having
|
||||
# it closed by garbage collection.
|
||||
conns.append(server.accept()[0])
|
||||
|
||||
t = threading.Thread(target=serve)
|
||||
t.start()
|
||||
started.wait()
|
||||
|
||||
try:
|
||||
if 0:
|
||||
# Disabled until #8524 finds a solution
|
||||
try:
|
||||
c = socket.socket(socket.AF_INET)
|
||||
c.settimeout(1.0)
|
||||
c.connect((host, port))
|
||||
# Will attempt handshake and time out
|
||||
self.assertRaisesRegexp(ssl.SSLError, "timed out",
|
||||
ssl.wrap_socket, c)
|
||||
finally:
|
||||
c.close()
|
||||
try:
|
||||
c = socket.socket(socket.AF_INET)
|
||||
c = ssl.wrap_socket(c)
|
||||
c.settimeout(0.2)
|
||||
# Will attempt handshake and time out
|
||||
self.assertRaisesRegexp(ssl.SSLError, "timed out",
|
||||
c.connect, (host, port))
|
||||
finally:
|
||||
c.close()
|
||||
finally:
|
||||
finish = True
|
||||
t.join()
|
||||
server.close()
|
||||
|
||||
|
||||
def test_main(verbose=False):
|
||||
if skip_expected:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue