예제 #1
0
def ssl_wrap_socket(schannel, address, options=None, remote_host=None):
    # Wrap the socket using the Pyhton SSL socket library
    schannel._socket = ssl_wrap_socket(
        socket=schannel._socket,
        ssl_options=options,
        server_hostname=remote_host,
        do_handshake_on_connect=False)
예제 #2
0
 def _handle_connection(self, connection, address):
     if self.ssl_options is not None:
         assert ssl, "Python 2.6+ and OpenSSL required for SSL"
         try:
             connection = ssl_wrap_socket(connection,
                                          self.ssl_options,
                                          server_side=True,
                                          do_handshake_on_connect=False)
         except ssl.SSLError as err:
             if err.args[0] == ssl.SSL_ERROR_EOF:
                 return connection.close()
             else:
                 raise
         except socket.error as err:
             if err.args[0] == errno.ECONNABORTED:
                 return connection.close()
             else:
                 raise
     try:
         if self.ssl_options is not None:
             stream = SSLIOStream(connection, io_loop=self.io_loop)
         else:
             stream = IOStream(connection, io_loop=self.io_loop)
         self.handle_stream(stream, address)
     except Exception:
         app_log.error("Error in connection callback", exc_info=True)
 def _handle_connection(self, connection, address):
     if self.ssl_options is not None:
         assert ssl, "Python 2.6+ and OpenSSL required for SSL"
         try:
             connection = ssl_wrap_socket(connection,
                                          self.ssl_options,
                                          server_side=True,
                                          do_handshake_on_connect=False)
         except ssl.SSLError as err:
             if err.args[0] == ssl.SSL_ERROR_EOF:
                 return connection.close()
             else:
                 raise
         except socket.error as err:
             if err.args[0] == errno.ECONNABORTED:
                 return connection.close()
             else:
                 raise
     try:
         if self.ssl_options is not None:
             stream = SSLIOStream(connection, io_loop=self.io_loop)
         else:
             stream = IOStream(connection, io_loop=self.io_loop)
         self.handle_stream(stream, address)
     except Exception:
         app_log.error("Error in connection callback", exc_info=True)
예제 #4
0
 def _make_server_iostream(self, connection, **kwargs):
     context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
     context.load_cert_chain(
         os.path.join(os.path.dirname(__file__), "test.crt"), os.path.join(os.path.dirname(__file__), "test.key")
     )
     connection = ssl_wrap_socket(connection, context, server_side=True, do_handshake_on_connect=False)
     return SSLIOStream(connection, io_loop=self.io_loop, **kwargs)
예제 #5
0
 def _make_server_iostream(self, connection, **kwargs):
     context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
     context.load_cert_chain(
         os.path.join(os.path.dirname(__file__), 'test.crt'),
         os.path.join(os.path.dirname(__file__), 'test.key'))
     connection = ssl_wrap_socket(connection, context,
                                  server_side=True,
                                  do_handshake_on_connect=False)
     return SSLIOStream(connection, io_loop=self.io_loop, **kwargs)
예제 #6
0
파일: iostream.py 프로젝트: 08opt/tornado
 def _handle_connect(self):
     # When the connection is complete, wrap the socket for SSL
     # traffic.  Note that we do this by overriding _handle_connect
     # instead of by passing a callback to super().connect because
     # user callbacks are enqueued asynchronously on the IOLoop,
     # but since _handle_events calls _handle_connect immediately
     # followed by _handle_write we need this to be synchronous.
     self.socket = ssl_wrap_socket(self.socket, self._ssl_options,
                                   server_hostname=self._server_hostname,
                                   do_handshake_on_connect=False)
     super(SSLIOStream, self)._handle_connect()
예제 #7
0
 def _make_server_iostream(self, connection, **kwargs):
     context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
     context.load_cert_chain(
         os.path.join(os.path.dirname(__file__), "test.crt"),
         os.path.join(os.path.dirname(__file__), "test.key"),
     )
     connection = ssl_wrap_socket(connection,
                                  context,
                                  server_side=True,
                                  do_handshake_on_connect=False)
     return SSLIOStream(connection, **kwargs)
예제 #8
0
 def _handle_connect(self):
     # When the connection is complete, wrap the socket for SSL
     # traffic.  Note that we do this by overriding _handle_connect
     # instead of by passing a callback to super().connect because
     # user callbacks are enqueued asynchronously on the IOLoop,
     # but since _handle_events calls _handle_connect immediately
     # followed by _handle_write we need this to be synchronous.
     self.socket = ssl_wrap_socket(self.socket, self._ssl_options,
                                   server_hostname=self._server_hostname,
                                   do_handshake_on_connect=False)
     super(SSLIOStream, self)._handle_connect()
예제 #9
0
    def _handle_connection(self, connection: socket.socket, address: Any) -> None:
        # 此处获取到的是sock.accept() 返回的两个数据, 也就是request和address嘛
        # 每当有用户建立连接, 都会进入此处
        if self.ssl_options is not None:
            assert ssl, "Python 2.6+ and OpenSSL required for SSL"
            try:
                connection = ssl_wrap_socket(
                    connection,
                    self.ssl_options,
                    server_side=True,
                    do_handshake_on_connect=False,
                )
            except ssl.SSLError as err:
                if err.args[0] == ssl.SSL_ERROR_EOF:
                    return connection.close()
                else:
                    raise
            except socket.error as err:
                # If the connection is closed immediately after it is created
                # (as in a port scan), we can get one of several errors.
                # wrap_socket makes an internal call to getpeername,
                # which may return either EINVAL (Mac OS X) or ENOTCONN
                # (Linux).  If it returns ENOTCONN, this error is
                # silently swallowed by the ssl module, so we need to
                # catch another error later on (AttributeError in
                # SSLIOStream._do_ssl_handshake).
                # To test this behavior, try nmap with the -sT flag.
                # https://github.com/tornadoweb/tornado/pull/750
                if errno_from_exception(err) in (errno.ECONNABORTED, errno.EINVAL):
                    return connection.close()
                else:
                    raise
        try:
            if self.ssl_options is not None:
                stream = SSLIOStream(
                    connection,
                    max_buffer_size=self.max_buffer_size,
                    read_chunk_size=self.read_chunk_size,
                )  # type: IOStream
            else:
                stream = IOStream(
                    connection,
                    max_buffer_size=self.max_buffer_size,
                    read_chunk_size=self.read_chunk_size,
                )

            future = self.handle_stream(stream, address)  # 会注册一个未来对象到loop里面
            if future is not None:  # 也就是说一个http连接到了这之后接结束了, 剩下的事都在loop中
                IOLoop.current().add_future(
                    gen.convert_yielded(future), lambda f: f.result()
                )
        except Exception:
            app_log.error("Error in connection callback", exc_info=True)
예제 #10
0
    def _handle_connection(self, connection: socket.socket, address: Any) -> None:
        if self.ssl_options is not None:
            assert ssl, "Python 2.6+ and OpenSSL required for SSL"
            try:
                connection = ssl_wrap_socket(
                    connection,
                    self.ssl_options,
                    server_side=True,
                    do_handshake_on_connect=False,
                )
            except ssl.SSLError as err:
                if err.args[0] == ssl.SSL_ERROR_EOF:
                    return connection.close()
                else:
                    raise
            except socket.error as err:
                # If the connection is closed immediately after it is created
                # (as in a port scan), we can get one of several errors.
                # wrap_socket makes an internal call to getpeername,
                # which may return either EINVAL (Mac OS X) or ENOTCONN
                # (Linux).  If it returns ENOTCONN, this error is
                # silently swallowed by the ssl module, so we need to
                # catch another error later on (AttributeError in
                # SSLIOStream._do_ssl_handshake).
                # To test this behavior, try nmap with the -sT flag.
                # https://github.com/tornadoweb/tornado/pull/750
                if errno_from_exception(err) in (errno.ECONNABORTED, errno.EINVAL):
                    return connection.close()
                else:
                    raise
        try:
            if self.ssl_options is not None:
                stream = SSLIOStream(
                    connection,
                    max_buffer_size=self.max_buffer_size,
                    read_chunk_size=self.read_chunk_size,
                )  # type: IOStream
            else:
                stream = IOStream(
                    connection,
                    max_buffer_size=self.max_buffer_size,
                    read_chunk_size=self.read_chunk_size,
                )

            future = self.handle_stream(stream, address)
            if future is not None:
                IOLoop.current().add_future(
                    gen.convert_yielded(future), lambda f: f.result()
                )
        except Exception:
            app_log.error("Error in connection callback", exc_info=True)
예제 #11
0
    def _handle_connection(self, connection, address):
        # Copy-paste of tornado.httpserver.HTTPServer._handle_connection to use
        # our custom stream class.
        #
        # Actually, connection is just a socket.
        try:
            connection = ssl_wrap_socket(connection,
                                         self.ssl_options,
                                         server_side=True,
                                         do_handshake_on_connect=False)
        except ssl.SSLError as err:
            if err.args[0] == ssl.SSL_ERROR_EOF:
                return connection.close()
            else:
                raise
        except socket.error as err:
            # If the connection is closed immediately after it is created
            # (as in a port scan), we can get one of several errors.
            # wrap_socket makes an internal call to getpeername,
            # which may return either EINVAL (Mac OS X) or ENOTCONN
            # (Linux).  If it returns ENOTCONN, this error is
            # silently swallowed by the ssl module, so we need to
            # catch another error later on (AttributeError in
            # SSLIOStream._do_ssl_handshake).
            # To test this behavior, try nmap with the -sT flag.
            # https://github.com/tornadoweb/tornado/pull/750
            if errno_from_exception(err) in (errno.ECONNABORTED, errno.EINVAL):  # noqa
                return connection.close()
            else:
                raise
        try:
            io_loop = self.io_loop
            kw = dict(io_loop=io_loop)
        except AttributeError:
            # We are on Tornado 5+. Just don't pass ioloop
            kw = {}
            io_loop = IOLoop.current()

        try:
            stream = EasySSLIOStream(
                connection,
                max_buffer_size=self.max_buffer_size,
                read_chunk_size=self.read_chunk_size,
                **kw
            )
            future = self.handle_stream(stream, address)
            if future is not None:
                io_loop.add_future(future, lambda f: f.result())
        except Exception:
            app_log.error("Error in connection callback", exc_info=True)
예제 #12
0
 def _handle_connection(self, connection, address):
     # 如果可以的话,启用ssl
     # address = ('127.0.0.1', 63959)
     # connection : socket object
     if self.ssl_options is not None:
         assert ssl, "Python 2.6+ and OpenSSL required for SSL"
         try:
             connection = ssl_wrap_socket(connection,
                                          self.ssl_options,
                                          server_side=True,
                                          do_handshake_on_connect=False)
         except ssl.SSLError as err:
             if err.args[0] == ssl.SSL_ERROR_EOF:
                 return connection.close()
             else:
                 raise
         except socket.error as err:
             # If the connection is closed immediately after it is created
             # (as in a port scan), we can get one of several errors.
             # wrap_socket makes an internal call to getpeername,
             # which may return either EINVAL (Mac OS X) or ENOTCONN
             # (Linux).  If it returns ENOTCONN, this error is
             # silently swallowed by the ssl module, so we need to
             # catch another error later on (AttributeError in
             # SSLIOStream._do_ssl_handshake).
             # To test this behavior, try nmap with the -sT flag.
             # https://github.com/tornadoweb/tornado/pull/750
             if errno_from_exception(err) in (errno.ECONNABORTED,
                                              errno.EINVAL):
                 return connection.close()
             else:
                 raise
     try:
         if self.ssl_options is not None:
             stream = SSLIOStream(connection,
                                  io_loop=self.io_loop,
                                  max_buffer_size=self.max_buffer_size,
                                  read_chunk_size=self.read_chunk_size)
         else:
             # 根据connection获得一个IOStream的对象,便于数据的读取
             stream = IOStream(connection,
                               io_loop=self.io_loop,
                               max_buffer_size=self.max_buffer_size,
                               read_chunk_size=self.read_chunk_size)
         # 开始处理进来的数据连接
         self.handle_stream(stream, address)
     except Exception:
         app_log.error("Error in connection callback", exc_info=True)
예제 #13
0
 def _handle_connection(self, connection, address):
     # 如果可以的话,启用ssl
     # address = ('127.0.0.1', 63959)
     # connection : socket object
     if self.ssl_options is not None:
         assert ssl, "Python 2.6+ and OpenSSL required for SSL"
         try:
             connection = ssl_wrap_socket(connection,
                                          self.ssl_options,
                                          server_side=True,
                                          do_handshake_on_connect=False)
         except ssl.SSLError as err:
             if err.args[0] == ssl.SSL_ERROR_EOF:
                 return connection.close()
             else:
                 raise
         except socket.error as err:
             # If the connection is closed immediately after it is created
             # (as in a port scan), we can get one of several errors.
             # wrap_socket makes an internal call to getpeername,
             # which may return either EINVAL (Mac OS X) or ENOTCONN
             # (Linux).  If it returns ENOTCONN, this error is
             # silently swallowed by the ssl module, so we need to
             # catch another error later on (AttributeError in
             # SSLIOStream._do_ssl_handshake).
             # To test this behavior, try nmap with the -sT flag.
             # https://github.com/tornadoweb/tornado/pull/750
             if errno_from_exception(err) in (errno.ECONNABORTED, errno.EINVAL):
                 return connection.close()
             else:
                 raise
     try:
         if self.ssl_options is not None:
             stream = SSLIOStream(connection, io_loop=self.io_loop,
                                  max_buffer_size=self.max_buffer_size,
                                  read_chunk_size=self.read_chunk_size)
         else:
             # 根据connection获得一个IOStream的对象,便于数据的读取
             stream = IOStream(connection, io_loop=self.io_loop,
                               max_buffer_size=self.max_buffer_size,
                               read_chunk_size=self.read_chunk_size)
         # 开始处理进来的数据连接
         self.handle_stream(stream, address)
     except Exception:
         app_log.error("Error in connection callback", exc_info=True)
예제 #14
0
 def _handle_connect(self):
     # When the connection is complete, wrap the socket for SSL
     # traffic.  Note that we do this by overriding _handle_connect
     # instead of by passing a callback to super().connect because
     # user callbacks are enqueued asynchronously on the IOLoop,
     # but since _handle_events calls _handle_connect immediately
     # followed by _handle_write we need this to be synchronous.
     #
     # The IOLoop will get confused if we swap out self.socket while the
     # fd is registered, so remove it now and re-register after
     # wrap_socket().
     self.io_loop.remove_handler(self.socket)
     old_state = self._state
     self._state = None
     self.socket = ssl_wrap_socket(self.socket, self._ssl_options,
                                   server_hostname=self._server_hostname,
                                   do_handshake_on_connect=False)
     self._add_io_state(old_state)
     super(SSLIOStream, self)._handle_connect()
예제 #15
0
 def _handle_connect(self):
     # When the connection is complete, wrap the socket for SSL
     # traffic.  Note that we do this by overriding _handle_connect
     # instead of by passing a callback to super().connect because
     # user callbacks are enqueued asynchronously on the IOLoop,
     # but since _handle_events calls _handle_connect immediately
     # followed by _handle_write we need this to be synchronous.
     #
     # The IOLoop will get confused if we swap out self.socket while the
     # fd is registered, so remove it now and re-register after
     # wrap_socket().
     self.io_loop.remove_handler(self.socket)
     old_state = self._state
     self._state = None
     self.socket = ssl_wrap_socket(self.socket, self._ssl_options,
                                   server_hostname=self._server_hostname,
                                   do_handshake_on_connect=False)
     self._add_io_state(old_state)
     super(SSLIOStream, self)._handle_connect()
예제 #16
0
 def _handle_connection(self, connection, address):
     if self.ssl_options is not None:
         assert ssl, "Python 2.6+ and OpenSSL required for SSL"
         try:
             connection = ssl_wrap_socket(connection,
                                          self.ssl_options,
                                          server_side=True,
                                          do_handshake_on_connect=False)
         except ssl.SSLError as err:
             if err.args[0] == ssl.SSL_ERROR_EOF:
                 return connection.close()
             else:
                 raise
         except socket.error as err:
             # If the connection is closed immediately after it is created
             # (as in a port scan), we can get one of several errors.
             # wrap_socket makes an internal call to getpeername,
             # which may return either EINVAL (Mac OS X) or ENOTCONN
             # (Linux).  If it returns ENOTCONN, this error is
             # silently swallowed by the ssl module, so we need to
             # catch another error later on (AttributeError in
             # SSLIOStream._do_ssl_handshake).
             # To test this behavior, try nmap with the -sT flag.
             # https://github.com/facebook/tornado/pull/750
             if err.args[0] in (errno.ECONNABORTED, errno.EINVAL):
                 return connection.close()
             else:
                 raise
     try:
         if self.ssl_options is not None:
             stream = SSLIOStream(connection,
                                  io_loop=self.io_loop,
                                  max_buffer_size=self.max_buffer_size)
         else:
             stream = IOStream(connection,
                               io_loop=self.io_loop,
                               max_buffer_size=self.max_buffer_size)
         self.handle_stream(stream, address)
         # 这个_handle_conntion基本是用在底层iostream的处理上面,
         # 而路由的分发,我猜测应该是在生成request对象那个时候才开始的
     except Exception:
         app_log.error("Error in connection callback", exc_info=True)
예제 #17
0
 def _handle_connection(self, connection, address):
     if self.ssl_options is not None:
         assert ssl, "Python 2.6+ and OpenSSL required for SSL"
         try:
             connection = ssl_wrap_socket(connection,
                                          self.ssl_options,
                                          server_side=True,
                                          do_handshake_on_connect=False)
         except ssl.SSLError as err:
             if err.args[0] == ssl.SSL_ERROR_EOF:
                 return connection.close()
             else:
                 raise
         except socket.error as err:
             # If the connection is closed immediately after it is created
             # (as in a port scan), we can get one of several errors.
             # wrap_socket makes an internal call to getpeername,
             # which may return either EINVAL (Mac OS X) or ENOTCONN
             # (Linux).  If it returns ENOTCONN, this error is
             # silently swallowed by the ssl module, so we need to
             # catch another error later on (AttributeError in
             # SSLIOStream._do_ssl_handshake).
             # To test this behavior, try nmap with the -sT flag.
             # https://github.com/facebook/tornado/pull/750
             if err.args[0] in (errno.ECONNABORTED, errno.EINVAL):
                 return connection.close()
             else:
                 raise
     try:
         if self.ssl_options is not None:
             stream = SSLIOStream(connection, io_loop=self.io_loop, max_buffer_size=self.max_buffer_size)
         else:
             stream = IOStream(connection, io_loop=self.io_loop, max_buffer_size=self.max_buffer_size)
         self.handle_stream(stream, address)
         # 这个_handle_conntion基本是用在底层iostream的处理上面,
         # 而路由的分发,我猜测应该是在生成request对象那个时候才开始的
     except Exception:
         app_log.error("Error in connection callback", exc_info=True)
예제 #18
0
    def _handle_connection(self, connection, address):
        if self.ssl_options is not None:
            assert ssl, "Python 2.6+ and OpenSSL required for SSL"
            try:
                connection = ssl_wrap_socket(connection,
                                             self.ssl_options,
                                             server_side=True,
                                             do_handshake_on_connect=False)
            except ssl.SSLError as err:
                if err.args[0] == ssl.SSL_ERROR_EOF:
                    return connection.close()
                else:
                    raise
            except socket.error as err:
                if errno_from_exception(err) in (errno.ECONNABORTED,
                                                 errno.EINVAL):
                    return connection.close()
                else:
                    raise
        try:
            if self.ssl_options is not None:
                stream = SSLIOStream(connection,
                                     io_loop=self.io_loop,
                                     max_buffer_size=self.max_buffer_size,
                                     read_chunk_size=self.read_chunk_size)
            else:
                stream = IOStream(connection,
                                  io_loop=self.io_loop,
                                  max_buffer_size=self.max_buffer_size,
                                  read_chunk_size=self.read_chunk_size)
            future = self.handle_stream(stream, address)

            if future is not None:
                self.io_loop.add_future(future, lambda f: f.result())

        except Exception:
            app_log.error("Error in connection callback", exc_info=True)
예제 #19
0
    def _handle_connection(self, connection, address):

        # _handle_connection就比较简单了,跳过那些ssl的处理,简化为两句:
        # stream = IOStream(connection, io_loop=self.io_loop)和
        # self.handle_stream()。
        # 这里IOStream代表了【IO层】(也就是读写方面的东西),以后再说,反正读写是不愁了。
        # 接着是调用handle_stream。我们可以看到,不论应用层是什么协议
        # (或者自定义协议),当有新连接到来时走的流程是差不多的,都要经历一番上诉的回调,
        # 不同之处就在于这个handle_stream方法。这个方法是由【子类自定义覆盖的】,
        # 它的HTTP实现已经在上一节看过了。

        #

        if self.ssl_options is not None:
            assert ssl, "Python 2.6+ and OpenSSL required for SSL"
            try:
                connection = ssl_wrap_socket(connection,
                                             self.ssl_options,
                                             server_side=True,
                                             do_handshake_on_connect=False)
            except ssl.SSLError as err:
                if err.args[0] == ssl.SSL_ERROR_EOF:
                    return connection.close()
                else:
                    raise
            except socket.error as err:
                # If the connection is closed immediately after it is created
                # (as in a port scan), we can get one of several errors.
                # wrap_socket makes an internal call to getpeername,
                # which may return either EINVAL (Mac OS X) or ENOTCONN
                # (Linux).  If it returns ENOTCONN, this error is
                # silently swallowed by the ssl module, so we need to
                # catch another error later on (AttributeError in
                # SSLIOStream._do_ssl_handshake).
                # To test this behavior, try nmap with the -sT flag.
                # https://github.com/facebook/tornado/pull/750
                if err.args[0] in (errno.ECONNABORTED, errno.EINVAL):
                    return connection.close()
                else:
                    raise
        try:
            if self.ssl_options is not None:
                stream = SSLIOStream(connection,
                                     io_loop=self.io_loop,
                                     max_buffer_size=self.max_buffer_size)
            else:
                stream = IOStream(connection,
                                  io_loop=self.io_loop,
                                  max_buffer_size=self.max_buffer_size)

            # 调用handle_stream,传入创建的IOStream对象初始化一个HTTPConnection对象,
            # HTTPConnection封装了IOStream的一些操作,用于处理HTTPRequest并返回。

            # 1.1.0 中的写法:
            # ====important=====#
            # HTTPConnection(stream, address, self.request_callback, self.no_keep_alive, self.xheaders)

            self.handle_stream(stream, address)

        # 思路是很清晰的,客户端连接在这里被转化成一个IOStream。然后由handle_stream函数处理。
        # 这个handle_stream就是我们前面提到过的未直接实现的接口,它是由HTTPServer类实现的。
        # def handle_stream(self, stream, address):
        #     HTTPConnection(stream, address, self.request_callback,
        #         self.no_keep_alive, self.xheaders, self.protocol)
        # 最后,处理流程又回到了HTTPServer类中。可以预见,在HTTConnection这个类中,
        # stream将和我们注册的RequestHandler协作,一边读客户端请求,一边调用相应的handler处理。

        except Exception:
            app_log.error("Error in connection callback", exc_info=True)
예제 #20
0
def ssl_wrap_socket(schannel, address, options=None, remote_host=None):
    # Wrap the socket using the Pyhton SSL socket library
    schannel._socket = ssl_wrap_socket(socket=schannel._socket,
                                       ssl_options=options,
                                       server_hostname=remote_host,
                                       do_handshake_on_connect=False)