예제 #1
0
    def test_stream_changed_with_detach(self):
        "Change a stream-id mid-stream, but with a DETACHED message"
        self.circuits[123] = FakeCircuit(123)
        self.circuits[456] = FakeCircuit(456)

        listener = Listener([('new', {
            'target_host': 'www.yahoo.com',
            'target_port': 80
        }), ('attach', {}),
                             ('detach', {
                                 'kwargs':
                                 dict(reason='END', remote_reason='MISC')
                             }), ('attach', {})])

        stream = Stream(self)
        stream.listen(listener)
        stream.update(
            "999 NEW 0 www.yahoo.com:80 SOURCE_ADDR=127.0.0.1:55877 PURPOSE=USER"
            .split())
        stream.update("999 SENTCONNECT 123 1.2.3.4:80".split())
        self.assertEqual(len(self.circuits[123].streams), 1)
        self.assertEqual(self.circuits[123].streams[0], stream)

        stream.update(
            "999 DETACHED 123 1.2.3.4:80 REASON=END REMOTE_REASON=MISC".split(
            ))
        self.assertEqual(len(self.circuits[123].streams), 0)

        stream.update("999 SENTCONNECT 456 1.2.3.4:80 SOURCE=EXIT".split())
        self.assertEqual(len(self.circuits[456].streams), 1)
        self.assertEqual(self.circuits[456].streams[0], stream)
예제 #2
0
 def test_args_in_ctor(self):
     stream = Stream(self)
     stream.update(
         "1 NEW 0 94.23.164.42.$43ED8310EB968746970896E8835C2F1991E50B69.exit:9001 SOURCE_ADDR=(Tor_internal):0 PURPOSE=DIR_FETCH"
         .split())
     self.assertEqual(stream.id, 1)
     self.assertEqual(stream.state, 'NEW')
예제 #3
0
    def test_close_stream_with_stream(self):
        stream = Stream(self.state)
        stream.id = 1

        self.state.streams[1] = stream
        self.state.close_stream(stream.id)
        self.assertEqual(self.transport.value(), 'CLOSESTREAM 1 1\r\n')
예제 #4
0
 def test_str(self):
     stream = Stream(self)
     stream.update(
         "316 NEW 0 www.yahoo.com:80 SOURCE_ADDR=127.0.0.1:55877 PURPOSE=USER"
         .split())
     stream.circuit = FakeCircuit(1)
     str(stream)
예제 #5
0
    def test_attach_stream_failure(self):

        @implementer(ICircuitContainer)
        class FakeContainer(object):
            pass

        container = FakeContainer()
        stream = Stream(container)
        stream.source_addr = ipaddress.IPv4Address(u'0.0.0.0')
        stream.source_port = 12345
        circuit = Mock()
        circuit.when_built = Mock(return_value=Failure(Exception('testing1234')))
        target_endpoint = Mock()
        src_addr = Mock()
        src_addr.host = u'0.0.0.0'
        src_addr.port = 12345
        target_endpoint._get_address = Mock(return_value=defer.succeed(src_addr))
        reactor = Mock()
        state = Mock()

        TorCircuitEndpoint(
            reactor, state, circuit, target_endpoint,
        )

        attacher = yield _get_circuit_attacher(reactor, state)
        d = attacher.add_endpoint(target_endpoint, circuit)
        self.assertEquals(len(attacher._circuit_targets), 1)
        # this will fail, but should be ignored
        yield attacher.attach_stream(stream, [])
        with self.assertRaises(Exception) as ctx:
            yield d
        self.assertTrue("testing1234" in str(ctx.exception))
예제 #6
0
    def test_listener_new(self):
        listener = Listener([('new', {'target_port': 9001})])

        stream = Stream(self)
        stream.listen(listener)
        stream.update(
            "1 NEW 0 94.23.164.42.$43ED8310EB968746970896E8835C2F1991E50B69.exit:9001 SOURCE_ADDR=(Tor_internal):0 PURPOSE=DIR_FETCH"
            .split())
예제 #7
0
 def test_magic_circuit_detach(self):
     stream = Stream(self)
     stream.circuit = FakeCircuit(1)
     stream.circuit.streams = [stream]
     stream.update(
         "1 SENTCONNECT 0 94.23.164.42.$43ED8310EB968746970896E8835C2F1991E50B69.exit:9001 SOURCE_ADDR=(Tor_internal):0 PURPOSE=DIR_FETCH"
         .split())
     self.assertTrue(stream.circuit is None)
예제 #8
0
 def test_circuit_already_valid_in_new(self):
     stream = Stream(self)
     stream.circuit = FakeCircuit(1)
     stream.update(
         "1 NEW 0 94.23.164.42.$43ED8310EB968746970896E8835C2F1991E50B69.exit:9001 SOURCE_ADDR=(Tor_internal):0 PURPOSE=DIR_FETCH"
         .split())
     errs = self.flushLoggedErrors()
     self.assertEqual(len(errs), 1)
     self.assertTrue('Weird' in errs[0].getErrorMessage())
예제 #9
0
 def test_close_stream_invalid_reason(self):
     stream = Stream(self.state)
     stream.id = 1
     self.state.streams[1] = stream
     self.assertRaises(
         ValueError,
         self.state.close_stream,
         stream,
         'FOO_INVALID_REASON'
     )
예제 #10
0
    def test_listen_unlisten(self):
        self.circuits[186] = FakeCircuit(186)

        listener = Listener([])

        stream = Stream(self)
        stream.listen(listener)
        stream.listen(listener)
        self.assertEqual(len(stream.listeners), 1)
        stream.unlisten(listener)
        self.assertEqual(len(stream.listeners), 0)
예제 #11
0
    def test_update_illegal_state(self):
        self.circuits[186] = FakeCircuit(186)

        stream = Stream(self)
        try:
            stream.update(
                "316 FOO 0 www.yahoo.com:80 SOURCE_ADDR=127.0.0.1:55877 PURPOSE=USER"
                .split())
            self.fail()
        except Exception as e:
            self.assertTrue('Unknown state' in str(e))
예제 #12
0
    def test_ipv6(self):
        listener = Listener([('new', {
            'target_host': '::1',
            'target_port': 80
        })])

        stream = Stream(self)
        stream.listen(listener)
        stream.update(
            "1234 NEW 0 ::1:80 SOURCE_ADDR=127.0.0.1:57349 PURPOSE=USER".split(
            ))
예제 #13
0
    def test_ipv6_source(self):
        listener = Listener([('new', {
            'source_addr': maybe_ip_addr('::1'),
            'source_port': 12345
        })])

        stream = Stream(self)
        stream.listen(listener)
        stream.update(
            "1234 NEW 0 127.0.0.1:80 SOURCE_ADDR=::1:12345 PURPOSE=USER".split(
            ))
예제 #14
0
    def test_update_wrong_stream(self):
        self.circuits[186] = FakeCircuit(186)

        stream = Stream(self)
        stream.update(
            "316 NEW 0 www.yahoo.com:80 SOURCE_ADDR=127.0.0.1:55877 PURPOSE=USER"
            .split())
        try:
            stream.update("999 SENTCONNECT 186 1.2.3.4:80 SOURCE=EXIT".split())
            self.fail()
        except Exception as e:
            self.assertTrue('wrong stream' in str(e))
예제 #15
0
    def test_close_stream(self):
        stream = Stream(self.state)
        stream.id = 1
        try:
            self.state.close_stream(stream)
            self.assertTrue(False)
        except KeyError:
            pass

        self.state.streams[1] = stream
        self.state.close_stream(stream)
        self.assertEqual(self.transport.value(), 'CLOSESTREAM 1 1\r\n')
예제 #16
0
    def test_lowercase_flags(self):
        # testing an internal method, maybe a no-no?
        stream = Stream(self)
        kw = dict(FOO='bar', BAR='baz')
        flags = stream._create_flags(kw)
        self.assertTrue('FOO' in flags)
        self.assertTrue('foo' in flags)
        self.assertTrue(flags['foo'] is flags['FOO'])

        self.assertTrue('BAR' in flags)
        self.assertTrue('bar' in flags)
        self.assertTrue(flags['bar'] is flags['BAR'])
예제 #17
0
    def test_attach_failure_unfound(self):
        @implementer(ICircuitContainer)
        class FakeContainer(object):
            pass

        reactor = Mock()
        container = FakeContainer()
        stream = Stream(container)
        state = Mock()

        attacher = yield _get_circuit_attacher(reactor, state)
        attacher.attach_stream_failure(stream, None)
예제 #18
0
    def test_closed_remaining_streams(self):
        tor = FakeTorController()
        circuit = Circuit(tor)
        circuit.listen(tor)
        circuit.update('1 LAUNCHED PURPOSE=GENERAL'.split())
        stream = Stream(tor)
        stream.update("1 NEW 0 94.23.164.42.$43ED8310EB968746970896E8835C2F1991E50B69.exit:9001 SOURCE_ADDR=(Tor_internal):0 PURPOSE=DIR_FETCH".split())
        circuit.streams.append(stream)
        self.assertEqual(len(circuit.streams), 1)

        circuit.update('1 CLOSED $E11D2B2269CC25E67CA6C9FB5843497539A74FD0=eris,$50DD343021E509EB3A5A7FD0D8A4F8364AFBDCB5=venus,$253DFF1838A2B7782BE7735F74E50090D46CA1BC=chomsky PURPOSE=GENERAL REASON=FINISHED'.split())
        circuit.update('1 FAILED $E11D2B2269CC25E67CA6C9FB5843497539A74FD0=eris,$50DD343021E509EB3A5A7FD0D8A4F8364AFBDCB5=venus,$253DFF1838A2B7782BE7735F74E50090D46CA1BC=chomsky PURPOSE=GENERAL REASON=TIMEOUT'.split())
        errs = self.flushLoggedErrors()
        self.assertEqual(len(errs), 2)
예제 #19
0
    def test_states_and_uris(self):
        self.circuits[1] = FakeCircuit(1)

        stream = Stream(self)
        for address in [
                '1.2.3.4:80',
                '1.2.3.4.315D5684D5343580D409F16119F78D776A58AEFB.exit:80',
                'timaq4ygg2iegci7.onion:80'
        ]:

            line = "316 %s 1 %s REASON=FOO"
            for state in [
                    'NEW', 'SUCCEEDED', 'REMAP', 'SENTCONNECT', 'DETACHED',
                    'NEWRESOLVE', 'SENTRESOLVE', 'FAILED', 'CLOSED'
            ]:
                stream.update((line % (state, address)).split(' '))
                self.assertEqual(stream.state, state)
예제 #20
0
    def test_listener_attach_no_remap(self):
        "Attachment is via SENTCONNECT on .onion addresses (for example)"
        self.circuits[186] = FakeCircuit(186)

        listener = Listener([('new', {
            'target_host': 'www.yahoo.com',
            'target_port': 80
        }), ('attach', {})])

        stream = Stream(self)
        stream.listen(listener)
        stream.update(
            "316 NEW 0 www.yahoo.com:80 SOURCE_ADDR=127.0.0.1:55877 PURPOSE=USER"
            .split())
        stream.update("316 SENTCONNECT 186 1.2.3.4:80 SOURCE=EXIT".split())

        self.assertEqual(self.circuits[186].streams[0], stream)
예제 #21
0
    def test_close_stream(self):
        self.circuits[186] = FakeCircuit(186)
        stream = Stream(self)
        stream.update(
            "316 NEW 0 www.yahoo.com:80 SOURCE_ADDR=127.0.0.1:55877 PURPOSE=USER"
            .split())
        stream.update("316 REMAP 186 1.2.3.4:80 SOURCE=EXIT".split())

        self.assertEqual(len(self.circuits[186].streams), 1)

        d = stream.close()
        self.assertTrue(not d.called)
        self.assertEqual(len(self.circuits[186].streams), 1)

        stream.update(
            "316 CLOSED 186 1.2.3.4:80 REASON=END REMOTE_REASON=DONE".split())
        self.assertTrue(d.called)
        self.assertEqual(len(self.circuits[186].streams), 0)
예제 #22
0
    def test_listener_attach(self):
        self.circuits[186] = FakeCircuit(186)

        listener = Listener([('new', {
            'target_host': 'www.yahoo.com',
            'target_port': 80
        }), ('attach', {
            'target_addr': maybe_ip_addr('1.2.3.4')
        })])

        stream = Stream(self)
        stream.listen(listener)
        stream.update(
            "316 NEW 0 www.yahoo.com:80 SOURCE_ADDR=127.0.0.1:55877 PURPOSE=USER"
            .split())
        stream.update("316 REMAP 186 1.2.3.4:80 SOURCE=EXIT".split())

        self.assertEqual(self.circuits[186].streams[0], stream)
예제 #23
0
    def test_attach(self):

        @implementer(ICircuitContainer)
        class FakeContainer(object):
            pass

        container = FakeContainer()
        stream = Stream(container)
        circuit = Mock()
        target_endpoint = Mock()
        reactor = Mock()
        state = Mock()

        TorCircuitEndpoint(
            reactor, state, circuit, target_endpoint,
        )

        attacher = yield _get_circuit_attacher(reactor, state)
        attacher.add_endpoint(target_endpoint, circuit)
        yield attacher.attach_stream(stream, [])
예제 #24
0
    def test_listener_exception(self):
        """A listener throws an exception during notify"""

        exc = Exception("the bad stuff happened")

        class Bad(StreamListenerMixin):
            def stream_new(*args, **kw):
                raise exc

        listener = Bad()

        stream = Stream(self)
        stream.listen(listener)
        stream.update(
            "1 NEW 0 94.23.164.42.$43ED8310EB968746970896E8835C2F1991E50B69.exit:9001 SOURCE_ADDR=(Tor_internal):0 PURPOSE=DIR_FETCH"
            .split())

        errors = self.flushLoggedErrors()
        self.assertEqual(1, len(errors))
        self.assertEqual(errors[0].value, exc)
예제 #25
0
    def test_listener_close(self):
        self.circuits[186] = FakeCircuit(186)

        listener = Listener([('new', {
            'target_host': 'www.yahoo.com',
            'target_port': 80
        }), ('attach', {
            'target_addr': maybe_ip_addr('1.2.3.4')
        }), ('closed', {
            'kwargs': dict(REASON='END', REMOTE_REASON='DONE')
        })])
        stream = Stream(self)
        stream.listen(listener)
        stream.update(
            "316 NEW 0 www.yahoo.com:80 SOURCE_ADDR=127.0.0.1:55877 PURPOSE=USER"
            .split())
        stream.update("316 REMAP 186 1.2.3.4:80 SOURCE=EXIT".split())
        stream.update(
            "316 CLOSED 186 1.2.3.4:80 REASON=END REMOTE_REASON=DONE".split())

        self.assertEqual(len(self.circuits[186].streams), 0)
예제 #26
0
 def test_listener_fail(self):
     listener = Listener([('new', {
         'target_host': 'www.yahoo.com',
         'target_port': 80
     }), ('attach', {
         'target_addr': maybe_ip_addr('1.2.3.4')
     }),
                          ('failed', {
                              'kwargs':
                              dict(REASON='TIMEOUT',
                                   REMOTE_REASON='DESTROYED')
                          })])
     stream = Stream(self)
     stream.listen(listener)
     stream.update(
         "316 NEW 0 www.yahoo.com:80 SOURCE_ADDR=127.0.0.1:55877 PURPOSE=USER"
         .split())
     self.circuits[186] = FakeCircuit(186)
     stream.update("316 REMAP 186 1.2.3.4:80 SOURCE=EXIT".split())
     stream.update(
         "316 FAILED 0 1.2.3.4:80 REASON=TIMEOUT REMOTE_REASON=DESTROYED".
         split())
예제 #27
0
    def test_attacher_errors(self):
        class MyAttacher(object):
            implements(IStreamAttacher)

            def __init__(self, answer):
                self.streams = []
                self.answer = answer

            def attach_stream(self, stream, circuits):
                return self.answer

        self.state.circuits[1] = FakeCircuit(1)
        attacher = MyAttacher(FakeCircuit(2))
        self.state.set_attacher(attacher, FakeReactor(self))

        stream = Stream(self.state)
        stream.id = 3
        msg = ''
        try:
            self.state._maybe_attach(stream)
        except Exception, e:
            msg = str(e)
예제 #28
0
    def test_attacher_errors(self):
        @implementer(IStreamAttacher)
        class MyAttacher(object):
            def __init__(self, answer):
                self.streams = []
                self.answer = answer

            def attach_stream(self, stream, circuits):
                return self.answer

        self.state.circuits[1] = FakeCircuit(1)
        attacher = MyAttacher(FakeCircuit(2))
        self.state.set_attacher(attacher, FakeReactor(self))

        stream = Stream(self.state)
        stream.id = 3
        msg = ''
        try:
            yield self.state._maybe_attach(stream)
        except Exception as e:
            msg = str(e)
        self.assertTrue('circuit unknown' in msg)

        attacher.answer = self.state.circuits[1]
        msg = ''
        try:
            yield self.state._maybe_attach(stream)
        except Exception as e:
            msg = str(e)
        self.assertTrue('only attach to BUILT' in msg)

        attacher.answer = 'not a Circuit instance'
        msg = ''
        try:
            yield self.state._maybe_attach(stream)
        except Exception as e:
            msg = str(e)
        self.assertTrue('Circuit instance' in msg)
예제 #29
0
    def test_stream_changed(self):
        "Change a stream-id mid-stream."
        self.circuits[186] = FakeCircuit(186)

        listener = Listener([('new', {
            'target_host': 'www.yahoo.com',
            'target_port': 80
        }), ('attach', {}), ('succeeded', {})])

        stream = Stream(self)
        stream.listen(listener)
        stream.update(
            "316 NEW 0 www.yahoo.com:80 SOURCE_ADDR=127.0.0.1:55877 PURPOSE=USER"
            .split())
        stream.update("316 SENTCONNECT 186 1.2.3.4:80 SOURCE=EXIT".split())
        self.assertEqual(self.circuits[186].streams[0], stream)

        # magically change circuit ID without a DETACHED, should fail
        stream.update("316 SUCCEEDED 999 1.2.3.4:80 SOURCE=EXIT".split())
        errs = self.flushLoggedErrors()
        self.assertEqual(len(errs), 1)
        # kind of fragile to look at strings, but...
        self.assertTrue('186 to 999' in str(errs[0]))
예제 #30
0
 def test_ipv6_remap(self):
     stream = Stream(self)
     stream.update(
         "1234 REMAP 0 ::1:80 SOURCE_ADDR=127.0.0.1:57349 PURPOSE=USER".
         split())
     self.assertEqual(stream.target_addr, maybe_ip_addr('::1'))