def __make_server_conn(self, server_address): if self.config.options.spoof_source_address and self.config.options.upstream_bind_address == '': return connections.ServerConnection( server_address, (self.ctx.client_conn.address[0], 0), True) else: return connections.ServerConnection( server_address, (self.config.options.upstream_bind_address, 0), self.config.options.spoof_source_address)
def __init__(self, server_address=None): super().__init__() self.server_conn = None if self.config.options.spoof_source_address: self.server_conn = connections.ServerConnection( server_address, (self.ctx.client_conn.address.host, 0), True) else: self.server_conn = connections.ServerConnection( server_address, (self.config.options.listen_host, 0)) self.__check_self_connect()
def __init__(self, server_address=None): super().__init__() self.server_conn = None if self.config.options.spoof_source_address and self.config.options.upstream_bind_address == '': self.server_conn = connections.ServerConnection( server_address, (self.ctx.client_conn.address[0], 0), True) else: self.server_conn = connections.ServerConnection( server_address, (self.config.options.upstream_bind_address, 0), self.config.options.spoof_source_address) self.__check_self_connect()
def __make_server_conn(self, server_address): if self.config.options.spoof_source_address and self.config.options.upstream_bind_address == '': return connections.ServerConnection( address=server_address, source_address=(self.ctx.client_conn.address[0], 0), spoof_source_address=True, channel=self.ctx.channel) else: return connections.ServerConnection( address=server_address, source_address=(self.config.options.upstream_bind_address, 0), spoof_source_address=self.config.options.spoof_source_address, channel=self.ctx.channel, connection_idle_seconds=self.ctx.config.options. connection_idle_seconds, dns_resolving_delay_ms=self.ctx.config.options. dns_resolving_delay_ms)
def test_tls(self, client_certs): c = connections.ServerConnection(("127.0.0.1", self.port)) c.connect() c.establish_tls(client_certs=client_certs) assert c.connected() assert c.tls_established c.close() c.finish()
def test_terminate_error(self): self.d = test.Daemon() sc = connections.ServerConnection((self.d.IFACE, self.d.port)) sc.connect() sc.connection = mock.Mock() sc.connection.recv = mock.Mock(return_value=False) sc.connection.flush = mock.Mock(side_effect=exceptions.TcpDisconnect) sc.finish() self.d.shutdown()
def test_tls(self, clientcert): c = connections.ServerConnection(("127.0.0.1", self.port)) c.connect() c.establish_tls(clientcert, "foo.com") assert c.connected() assert c.sni == "foo.com" assert c.tls_established c.close() c.finish()
def test_terminate_error(self): d = test.Daemon() c = connections.ServerConnection((d.IFACE, d.port)) c.connect() c.close() c.connection = mock.Mock() c.connection.recv = mock.Mock(return_value=False) c.connection.flush = mock.Mock(side_effect=exceptions.TcpDisconnect) d.shutdown()
def disconnect(self): """ Deletes (and closes) an existing server connection. Must not be called if there is no existing connection. """ self.log("serverdisconnect", "debug", [repr(self.server_conn.address)]) address = self.server_conn.address self.server_conn.finish() self.server_conn.close() self.channel.tell("serverdisconnect", self.server_conn) self.server_conn = connections.ServerConnection( address, (self.server_conn.source_address[0], 0), self.config.options.spoof_source_address)
def test_simple(self): self.d = test.Daemon() sc = connections.ServerConnection((self.d.IFACE, self.d.port)) sc.connect() f = tflow.tflow() f.server_conn = sc f.request.path = "/p/200:da" # use this protocol just to assemble - not for actual sending sc.wfile.write(http1.assemble_request(f.request)) sc.wfile.flush() assert http1.read_response(sc.rfile, f.request, 1000) assert self.d.last_log() sc.finish() self.d.shutdown()
def run(self): r = self.f.request first_line_format_backup = r.first_line_format server = None try: self.f.response = None # If we have a channel, run script hooks. if self.channel: request_reply = self.channel.ask("request", self.f) if isinstance(request_reply, http.HTTPResponse): self.f.response = request_reply if not self.f.response: # In all modes, we directly connect to the server displayed if self.config.options.mode == "upstream": server_address = self.config.upstream_server.address server = connections.ServerConnection(server_address, (self.config.options.listen_host, 0)) server.connect() if r.scheme == "https": connect_request = http.make_connect_request((r.data.host, r.port)) server.wfile.write(http1.assemble_request(connect_request)) server.wfile.flush() resp = http1.read_response( server.rfile, connect_request, body_size_limit=self.config.options.body_size_limit ) if resp.status_code != 200: raise exceptions.ReplayException("Upstream server refuses CONNECT request") server.establish_ssl( self.config.clientcerts, sni=self.f.server_conn.sni ) r.first_line_format = "relative" else: r.first_line_format = "absolute" else: server_address = (r.host, r.port) server = connections.ServerConnection( server_address, (self.config.options.listen_host, 0) ) server.connect() if r.scheme == "https": server.establish_ssl( self.config.clientcerts, sni=self.f.server_conn.sni ) r.first_line_format = "relative" server.wfile.write(http1.assemble_request(r)) server.wfile.flush() self.f.server_conn = server self.f.response = http.HTTPResponse.wrap( http1.read_response( server.rfile, r, body_size_limit=self.config.options.body_size_limit ) ) if self.channel: response_reply = self.channel.ask("response", self.f) if response_reply == exceptions.Kill: raise exceptions.Kill() except (exceptions.ReplayException, exceptions.NetlibException) as e: self.f.error = flow.Error(str(e)) if self.channel: self.channel.ask("error", self.f) except exceptions.Kill: # Kill should only be raised if there's a channel in the # first place. self.channel.tell( "log", log.LogEntry("Connection killed", "info") ) except Exception: self.channel.tell( "log", log.LogEntry(traceback.format_exc(), "error") ) finally: r.first_line_format = first_line_format_backup self.f.live = False if server.connected(): server.finish()
def replay(self, f): # pragma: no cover f.live = True r = f.request bsl = human.parse_size(self.options.body_size_limit) first_line_format_backup = r.first_line_format server = None global new, cur_cycle, cur_group try: f.response = None # If we have a channel, run script hooks. request_reply = self.channel.ask("request", f) if isinstance(request_reply, http.HTTPResponse): f.response = request_reply if not f.response: # In all modes, we directly connect to the server displayed if self.options.mode.startswith("upstream:"): server_address = server_spec.parse_with_mode( self.options.mode)[1].address server = connections.ServerConnection(server_address) server.connect() if r.scheme == "https": connect_request = http.make_connect_request( (r.data.host, r.port)) server.wfile.write( http1.assemble_request(connect_request)) server.wfile.flush() resp = http1.read_response(server.rfile, connect_request, body_size_limit=bsl) if resp.status_code != 200: raise exceptions.ReplayException( "Upstream server refuses CONNECT request") server.establish_tls( sni=f.server_conn.sni, **tls.client_arguments_from_options(self.options)) r.first_line_format = "relative" else: r.first_line_format = "absolute" else: server_address = (r.host, r.port) server = connections.ServerConnection(server_address) server.connect() if r.scheme == "https": server.establish_tls( sni=f.server_conn.sni, **tls.client_arguments_from_options(self.options)) r.first_line_format = "relative" server.wfile.write(http1.assemble_request(r)) server.wfile.flush() if f.server_conn: f.server_conn.close() f.server_conn = server f.response = http.HTTPResponse.wrap( http1.read_response(server.rfile, r, body_size_limit=bsl)) response_reply = self.channel.ask("response", f) #new.append(f) #record the response cur_cycle[cur_group] = f if response_reply == exceptions.Kill: raise exceptions.Kill() except (exceptions.ReplayException, exceptions.NetlibException) as e: f.error = flow.Error(str(e)) self.channel.ask("error", f) except exceptions.Kill: self.channel.tell("log", log.LogEntry("Connection killed", "info")) except Exception as e: self.channel.tell("log", log.LogEntry(repr(e), "error")) finally: r.first_line_format = first_line_format_backup f.live = False if server.connected(): server.finish() server.close()
def replay(self, f): # pragma: no cover f.live = True r = f.request bsl = human.parse_size(self.options.body_size_limit) authority_backup = r.authority server = None try: f.response = None # If we have a channel, run script hooks. request_reply = self.channel.ask("request", f) if isinstance(request_reply, http.HTTPResponse): f.response = request_reply if not f.response: # In all modes, we directly connect to the server displayed if self.options.mode.startswith("upstream:"): server_address = server_spec.parse_with_mode( self.options.mode)[1].address server = connections.ServerConnection(server_address) server.connect() if r.scheme == "https": connect_request = http.make_connect_request( (r.data.host, r.port)) server.wfile.write( http1.assemble_request(connect_request)) server.wfile.flush() resp = http1.read_response(server.rfile, connect_request, body_size_limit=bsl) if resp.status_code != 200: raise exceptions.ReplayException( "Upstream server refuses CONNECT request") server.establish_tls( sni=f.server_conn.sni, **tls.client_arguments_from_options(self.options)) r.authority = b"" else: r.authority = hostport(r.scheme, r.host, r.port) else: server_address = (r.host, r.port) server = connections.ServerConnection(server_address) server.connect() if r.scheme == "https": server.establish_tls( sni=f.server_conn.sni, **tls.client_arguments_from_options(self.options)) r.authority = "" server.wfile.write(http1.assemble_request(r)) server.wfile.flush() r.timestamp_start = r.timestamp_end = time.time() if f.server_conn: f.server_conn.close() f.server_conn = server f.response = http1.read_response(server.rfile, r, body_size_limit=bsl) response_reply = self.channel.ask("response", f) if response_reply == exceptions.Kill: raise exceptions.Kill() except (exceptions.ReplayException, exceptions.NetlibException) as e: f.error = flow.Error(str(e)) self.channel.ask("error", f) except exceptions.Kill: self.channel.tell("log", log.LogEntry(flow.Error.KILLED_MESSAGE, "info")) except Exception as e: self.channel.tell("log", log.LogEntry(repr(e), "error")) finally: r.authority = authority_backup f.live = False if server and server.connected(): server.finish() server.close()
def test_sni(self): c = connections.ServerConnection(('', 1234)) with pytest.raises(ValueError, matches='sni must be str, not '): c.establish_tls(None, b'foobar')