def test_handle_layer_error(self): context = LayerContext(mode="socks", src_stream=self.src_stream, port=443, scheme="h2") layer_manager._handle_layer_error(gen.TimeoutError("timeout"), context) context.src_stream.close.assert_called_once_with() context.src_stream.reset_mock() layer_manager._handle_layer_error( DestNotConnectedError("stream closed"), context) context.src_stream.close.assert_not_called() context.src_stream.reset_mock() layer_manager._handle_layer_error( DestStreamClosedError("stream closed"), context) context.src_stream.close.assert_called_once_with() context.src_stream.reset_mock() layer_manager._handle_layer_error( SrcStreamClosedError("stream closed"), context) context.src_stream.close.assert_not_called() context.src_stream.reset_mock() layer_manager._handle_layer_error( iostream.StreamClosedError("stream closed"), context) context.src_stream.close.assert_called_once_with()
def test_handle_unhandled_layer_error(self): context = LayerContext(mode="socks", src_stream=Mock(), port=443, scheme="h2") layer_manager._handle_layer_error(ValueError, context) context.src_stream.close.assert_called_once_with()
def test_get_forward_layer_from_socks_replay(self): context = LayerContext(mode="socks", port=5555) socks_layer = SocksLayer(context) layer = layer_manager._next_layer(self.server_state, socks_layer, context) self.assertIsInstance(layer, ForwardLayer) context.scheme = "test" replay_layer = ReplayLayer(context) layer = layer_manager._next_layer(self.server_state, replay_layer, context) self.assertIsInstance(layer, ForwardLayer) context.scheme = "test" tls_layer = TlsLayer(self.server_state, context) layer = layer_manager._next_layer(self.server_state, tls_layer, context) self.assertIsInstance(layer, ForwardLayer)
def test_get_tls_layer_from_socks(self): context = LayerContext(mode="socks", port=443) socks_layer = SocksLayer(context) layer = layer_manager._next_layer(self.server_state, socks_layer, context) self.assertIsInstance(layer, TlsLayer)
def test_get_http1_layer_from_socks_replay(self): context = LayerContext(mode="socks", port=80) socks_layer = SocksLayer(context) layer = layer_manager._next_layer(self.server_state, socks_layer, context) self.assertIsInstance(layer, Http1Layer) context.scheme = "http" replay_layer = ReplayLayer(context) layer = layer_manager._next_layer(self.server_state, replay_layer, context) self.assertIsInstance(layer, Http1Layer) context.scheme = "https" tls_layer = TlsLayer(self.server_state, context) layer = layer_manager._next_layer(self.server_state, tls_layer, context) self.assertIsInstance(layer, Http1Layer)
def test_get_http_layer_from_http_layer(self): context = LayerContext(mode="http", scheme="http", port=80) http_layer = Http1Layer(self.server_state, context) layer = layer_manager._next_layer(self.server_state, http_layer, context) self.assertIsInstance(layer, Http1Layer)
def handle(self, event): logger.debug("start handling replay event") try: viewer_context = ViewerContext.deserialize(event.context) write_stream, read_stream = self._create_streams() if viewer_context.scheme in ("http", "https"): self._send_http1_request(write_stream, viewer_context) elif viewer_context.scheme == "h2": self._send_http2_request(write_stream, viewer_context) else: raise ValueError("not support replay with: {0}".format( viewer_context.scheme)) layer_context = LayerContext( mode="replay", src_stream=read_stream, host=viewer_context.host, port=viewer_context.port, scheme=viewer_context.scheme) initial_layer = self.layer_manager.get_first_layer(layer_context) yield self.layer_manager.run_layers( self.server_state, initial_layer, layer_context) except Exception as e: logger.exception(e) else: logger.debug("replay event successfully")
def asyncSetUp(self): self.client_stream, src_stream = yield self.create_iostream_pair() dest_stream, self.server_stream = yield self.create_iostream_pair() self.context = LayerContext(mode="socks", src_stream=src_stream, dest_stream=dest_stream) self.forward_layer = ForwardLayer(mock.Mock(), self.context)
def test_get_http2_layer(self): context = LayerContext(mode="socks", port=443, scheme="h2") replay_layer = ReplayLayer(context) layer = layer_manager._next_layer(self.server_state, replay_layer, context) self.assertIsInstance(layer, Http2Layer) tls_layer = TlsLayer(self.server_state, context) layer = layer_manager._next_layer(self.server_state, tls_layer, context) self.assertIsInstance(layer, Http2Layer)
def asyncSetUp(self): self.client_stream, self.src_stream = yield self.create_iostream_pair() self.context = LayerContext(mode="socks", src_stream=self.src_stream) self.layer = SocksLayer(self.context) self.listener, self.port = bind_unused_port() def dest_accept_callback(conn, addr): self.dest_server_stream = MicroProxyIOStream(conn) self.addCleanup(self.dest_server_stream.close) add_accept_handler(self.listener, dest_accept_callback) self.addCleanup(self.listener.close)
def asyncSetUp(self): self.client_stream, src_stream = yield self.create_iostream_pair() dest_stream, self.server_stream = yield self.create_iostream_pair() server_state = ServerContext(config={}, interceptor=mock.Mock( **{ "publish.return_value": None, "request.return_value": None, "response.return_value": None, })) self.http_layer = Http2Layer( server_state, LayerContext(mode="socks", src_stream=src_stream, dest_stream=dest_stream))
def handle_stream(self, stream): src_info = "{0}:{1}".format(*stream.fileno().getpeername()) try: initial_context = LayerContext(mode=self.config["mode"], src_stream=stream, src_info=src_info) logger.debug("Start new layer manager") initial_layer = layer_manager.get_first_layer(initial_context) yield layer_manager.run_layers(self.server_state, initial_layer, initial_context) except Exception as e: # NOTE: not handle exception, log it and close the stream logger.exception( "Unhandled exception occured at {0} with {1}".format( src_info, e)) stream.close()
def asyncSetUp(self): self.client_stream, src_stream = yield self.create_iostream_pair() dest_stream, self.server_stream = yield self.create_iostream_pair() self.config = dict(client_certs="microproxy/test/test.crt", insecure=True) cert_store = CertStore( dict(certfile="microproxy/test/test.crt", keyfile="microproxy/test/test.key")) server_state = ServerContext(cert_store=cert_store, config=self.config) # src_stream.pause() context = LayerContext(mode="socks", src_stream=src_stream, dest_stream=dest_stream, host="127.0.0.1", port="443") self.tls_layer = TlsLayer(server_state, context)
def process_and_return_context(self): # NOTE: peeking src stream client hello. raw_client_hello = self.peek_client_hello() client_hello = TlsClientHello(raw_client_hello[4:]) hostname = client_hello.sni or self.context.host try: dest_stream, select_alpn = yield self.start_dest_tls( hostname, client_hello.alpn_protocols) except: if not self.src_stream.closed(): self.src_stream.close() raise try: src_stream = yield self.start_src_tls(hostname, select_alpn) except: if not dest_stream.closed(): dest_stream.close() raise try: ctx = LayerContext(mode=self.context.mode, src_stream=src_stream, dest_stream=dest_stream, scheme=self.alpn_to_scheme(select_alpn), host=hostname or self.context.host, port=self.context.port, client_tls=self._resolve_tls_info(src_stream), server_tls=self._resolve_tls_info(dest_stream), src_info=self.context.src_info) except: src_stream.close() dest_stream.close() raise raise gen.Return(ctx)
def test_get_transparent_layer_linux(self): context = LayerContext(mode="transparent", port=443) layer = layer_manager.get_first_layer(context) self.assertIsInstance(layer, TransparentLayer)
def test_get_http1_layer_from_transparent(self): context = LayerContext(mode="socks", port=80) transparent_layer = TransparentLayer(context) layer = layer_manager._next_layer(self.server_state, transparent_layer, context) self.assertIsInstance(layer, Http1Layer)
def test_get_replay_layer(self): context = LayerContext(mode="replay", port=443) layer = layer_manager.get_first_layer(context) self.assertIsInstance(layer, ReplayLayer)
def test_get_socks_layer(self): context = LayerContext(mode="socks", port=443) layer = layer_manager.get_first_layer(context) self.assertIsInstance(layer, SocksLayer)
def test_get_http_proxy_layer(self): context = LayerContext(mode="http", port=80) layer = layer_manager.get_first_layer(context) self.assertIsInstance(layer, HttpProxyLayer)
def test_invalid_mode(self): with self.assertRaises(ValueError): LayerContext(mode="test")
def test_get_transparent_layer_non_linux(self): context = LayerContext(mode="transparent", port=443) with self.assertRaises(NotImplementedError): layer_manager.get_first_layer(context)