Exemple #1
0
 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)
Exemple #2
0
    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()
Exemple #3
0
    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()
Exemple #4
0
 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)
Exemple #5
0
 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()
Exemple #6
0
 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()
Exemple #9
0
    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)
Exemple #10
0
    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()
Exemple #11
0
    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()
Exemple #12
0
    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')