def __init__( self, client: connection.Client, options: Options, ) -> None: self.client = client self.options = options self.server = connection.Server(None) self.layers = []
def receive_handshake_data( self, data: bytes) -> layer.CommandGenerator[Tuple[bool, Optional[str]]]: if self.client_hello_parsed: return (yield from super().receive_handshake_data(data)) self.recv_buffer.extend(data) try: client_hello = parse_client_hello(self.recv_buffer) except ValueError: return False, f"Cannot parse ClientHello: {self.recv_buffer.hex()}" if client_hello: self.client_hello_parsed = True else: return False, None self.conn.sni = client_hello.sni self.conn.alpn_offers = client_hello.alpn_protocols tls_clienthello = ClientHelloData(self.context, client_hello) yield TlsClienthelloHook(tls_clienthello) if tls_clienthello.ignore_connection: # we've figured out that we don't want to intercept this connection, so we assign fake connection objects # to all TLS layers. This makes the real connection contents just go through. self.conn = self.tunnel_connection = connection.Client( ("ignore-conn", 0), ("ignore-conn", 0), time.time()) parent_layer = self.context.layers[self.context.layers.index(self) - 1] if isinstance(parent_layer, ServerTLSLayer): parent_layer.conn = parent_layer.tunnel_connection = connection.Server( None) self.child_layer = tcp.TCPLayer(self.context, ignore=True) yield from self.event_to_child( events.DataReceived(self.context.client, bytes(self.recv_buffer))) self.recv_buffer.clear() return True, None if tls_clienthello.establish_server_tls_first and not self.context.server.tls_established: err = yield from self.start_server_tls() if err: yield commands.Log( f"Unable to establish TLS connection with server ({err}). " f"Trying to establish TLS with client anyway.") yield from self.start_tls() if not self.conn.connected: return False, "connection closed early" ret = yield from super().receive_handshake_data(bytes( self.recv_buffer)) self.recv_buffer.clear() return ret
def create(self, method: str, url: str) -> None: try: req = http.Request.make(method.upper(), url) except ValueError as e: raise exceptions.CommandError("Invalid URL: %s" % e) c = connection.Client(("", 0), ("", 0), req.timestamp_start - 0.0001) s = connection.Server((req.host, req.port)) f = http.HTTPFlow(c, s) f.request = req f.request.headers["Host"] = req.host self.add([f])
def make(cls, ctx: context.Context, send_connect: bool) -> tunnel.LayerStack: spec = ctx.server.via assert spec assert spec.scheme in ("http", "https") http_proxy = connection.Server(spec.address) stack = tunnel.LayerStack() if spec.scheme == "https": http_proxy.alpn_offers = tls.HTTP1_ALPNS http_proxy.sni = spec.address[0] stack /= tls.ServerTLSLayer(ctx, http_proxy) stack /= cls(ctx, http_proxy, send_connect) return stack
def tconn() -> connection.Server: return connection.Server(None)
def __init__(self, ctx: context.Context): super().__init__(ctx, connection.Server(None))