(self)
| 1382 | return self._handshake_writing or super().writing() |
| 1383 | |
| 1384 | def _do_ssl_handshake(self) -> None: |
| 1385 | # Based on code from test_ssl.py in the python stdlib |
| 1386 | try: |
| 1387 | self._handshake_reading = False |
| 1388 | self._handshake_writing = False |
| 1389 | self.socket.do_handshake() |
| 1390 | except ssl.SSLError as err: |
| 1391 | if err.args[0] == ssl.SSL_ERROR_WANT_READ: |
| 1392 | self._handshake_reading = True |
| 1393 | return |
| 1394 | elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE: |
| 1395 | self._handshake_writing = True |
| 1396 | return |
| 1397 | elif err.args[0] in (ssl.SSL_ERROR_EOF, ssl.SSL_ERROR_ZERO_RETURN): |
| 1398 | return self.close(exc_info=err) |
| 1399 | elif err.args[0] == ssl.SSL_ERROR_SSL: |
| 1400 | try: |
| 1401 | peer = self.socket.getpeername() |
| 1402 | except Exception: |
| 1403 | peer = "(not connected)" |
| 1404 | gen_log.warning( |
| 1405 | "SSL Error on %s %s: %s", self.socket.fileno(), peer, err |
| 1406 | ) |
| 1407 | return self.close(exc_info=err) |
| 1408 | raise |
| 1409 | except ssl.CertificateError as err: |
| 1410 | # CertificateError can happen during handshake (hostname |
| 1411 | # verification) and should be passed to user. Starting |
| 1412 | # in Python 3.7, this error is a subclass of SSLError |
| 1413 | # and will be handled by the previous block instead. |
| 1414 | return self.close(exc_info=err) |
| 1415 | except socket.error as err: |
| 1416 | # Some port scans (e.g. nmap in -sT mode) have been known |
| 1417 | # to cause do_handshake to raise EBADF and ENOTCONN, so make |
| 1418 | # those errors quiet as well. |
| 1419 | # https://groups.google.com/forum/?fromgroups#!topic/python-tornado/ApucKJat1_0 |
| 1420 | # Errno 0 is also possible in some cases (nc -z). |
| 1421 | # https://github.com/tornadoweb/tornado/issues/2504 |
| 1422 | if self._is_connreset(err) or err.args[0] in ( |
| 1423 | 0, |
| 1424 | errno.EBADF, |
| 1425 | errno.ENOTCONN, |
| 1426 | ): |
| 1427 | return self.close(exc_info=err) |
| 1428 | raise |
| 1429 | except AttributeError as err: |
| 1430 | # On Linux, if the connection was reset before the call to |
| 1431 | # wrap_socket, do_handshake will fail with an |
| 1432 | # AttributeError. |
| 1433 | return self.close(exc_info=err) |
| 1434 | else: |
| 1435 | self._ssl_accepting = False |
| 1436 | if not self._verify_cert(self.socket.getpeercert()): |
| 1437 | self.close() |
| 1438 | return |
| 1439 | self._finish_ssl_connect() |
| 1440 | |
| 1441 | def _finish_ssl_connect(self) -> None: |
no test coverage detected