Exemple #1
0
    def test_bootstrap_callback(self):
        '''
        FIXME: something is still screwy with this; try throwing an
        exception from TorState.bootstrap and we'll just hang...
        '''

        from test_torconfig import FakeControlProtocol
        protocol = FakeControlProtocol([
            "ns/all=",  # ns/all
            "",  # circuit-status
            "",  # stream-status
            "",  # address-mappings/all
            "entry-guards=\r\n$0000000000000000000000000000000000000000=name up\r\n$1111111111111111111111111111111111111111=foo up\r\n$9999999999999999999999999999999999999999=eman unusable 2012-01-01 22:00:00\r\n",  # entry-guards
            "99999",  # process/pid
            "??",  # ip-to-country/0.0.0.0
        ])

        state = yield TorState.from_protocol(protocol)

        self.assertEqual(len(state.entry_guards), 2)
        self.assertTrue(
            '$0000000000000000000000000000000000000000' in state.entry_guards)
        self.assertTrue(
            '$1111111111111111111111111111111111111111' in state.entry_guards)
        self.assertEqual(len(state.unusable_entry_guards), 1)
        self.assertTrue('$9999999999999999999999999999999999999999' in
                        state.unusable_entry_guards[0])
Exemple #2
0
 def setUp(self):
     from txtorcon import endpoints
     endpoints._global_tor_config = None
     del endpoints._global_tor_lock
     endpoints._global_tor_lock = defer.DeferredLock()
     self.reactor = FakeReactorTcp(self)
     self.protocol = FakeControlProtocol([])
     self.protocol.event_happened('INFO', 'something craaaaaaazy')
     self.protocol.event_happened(
         'INFO', 'connection_dir_client_reached_eof(): Uploaded rendezvous '
         'descriptor (status 200 ("Service descriptor (v2) stored"))')
     self.config = TorConfig(self.protocol)
     self.protocol.answers.append(
         'config/names=\nHiddenServiceOptions Virtual')
     self.protocol.answers.append('HiddenServiceOptions')
     self.patcher = patch('txtorcon.torconfig.find_tor_binary',
                          return_value='/not/tor')
     self.patcher.start()
Exemple #3
0
 def setUp(self):
     from txtorcon import endpoints
     endpoints._global_tor_config = None
     del endpoints._global_tor_lock
     endpoints._global_tor_lock = defer.DeferredLock()
     self.reactor = FakeReactorTcp(self)
     self.protocol = FakeControlProtocol([])
     self.config = TorConfig(self.protocol)
     self.protocol.answers.append(
         'config/names=\nHiddenServiceOptions Virtual')
     self.protocol.answers.append('HiddenServiceOptions')
     self.patcher = patch('txtorcon.torconfig.find_tor_binary',
                          return_value='/not/tor')
     self.patcher.start()
    def setUp(self):
        from txtorcon import endpoints

        endpoints._global_tor_config = None
        del endpoints._global_tor_lock
        endpoints._global_tor_lock = defer.DeferredLock()
        self.reactor = FakeReactorTcp(self)
        self.protocol = FakeControlProtocol([])
        self.protocol.event_happened("INFO", "something craaaaaaazy")
        self.protocol.event_happened(
            "INFO",
            "connection_dir_client_reached_eof(): Uploaded rendezvous "
            'descriptor (status 200 ("Service descriptor (v2) stored"))',
        )
        self.config = TorConfig(self.protocol)
        self.protocol.answers.append("config/names=\nHiddenServiceOptions Virtual")
        self.protocol.answers.append("HiddenServiceOptions")
        self.patcher = patch("txtorcon.torconfig.find_tor_binary", return_value="/not/tor")
        self.patcher.start()
class EndpointTests(unittest.TestCase):

    def setUp(self):
        from txtorcon import endpoints
        endpoints._global_tor_config = None
        del endpoints._global_tor_lock
        endpoints._global_tor_lock = defer.DeferredLock()
        self.reactor = FakeReactorTcp(self)
        self.protocol = FakeControlProtocol([])
        self.protocol.event_happened('INFO', 'something craaaaaaazy')
        self.protocol.event_happened(
            'INFO',
            'connection_dir_client_reached_eof(): Uploaded rendezvous '
            'descriptor (status 200 ("Service descriptor (v2) stored"))'
        )
        self.config = TorConfig(self.protocol)
        self.protocol.answers.append(
            'config/names=\nHiddenServiceOptions Virtual'
        )
        self.protocol.answers.append('HiddenServiceOptions')
        self.patcher = patch(
            'txtorcon.torconfig.find_tor_binary',
            return_value='/not/tor'
        )
        self.patcher.start()

    def tearDown(self):
        from txtorcon import endpoints
        endpoints._global_tor_config = None
        del endpoints._global_tor_lock
        endpoints._global_tor_lock = defer.DeferredLock()
        self.patcher.stop()

    @defer.inlineCallbacks
    def test_global_tor(self):
        config = yield get_global_tor(
            Mock(),
            _tor_launcher=lambda x, y, z: True
        )
        self.assertEqual(0, config.SOCKSPort)

    @defer.inlineCallbacks
    def test_global_tor_error(self):
        config0 = yield get_global_tor(
            Mock(),
            _tor_launcher=lambda x, y, z: True
        )
        # now if we specify a control_port it should be an error since
        # the above should have launched one.
        try:
            config1 = yield get_global_tor(Mock(), control_port=111,
                                           _tor_launcher=lambda x, y, z: True)
            self.fail()
        except RuntimeError as e:
            # should be an error
            pass

    @defer.inlineCallbacks
    def test_endpoint_properties(self):
        ep = yield TCPHiddenServiceEndpoint.private_tor(Mock(), 80)
        self.assertEqual(None, ep.onion_private_key)
        self.assertEqual(None, ep.onion_uri)
        ep.hiddenservice = Mock()
        ep.hiddenservice.private_key = 'mumble'
        self.assertEqual('mumble', ep.onion_private_key)

    @defer.inlineCallbacks
    def test_private_tor(self):
        m = Mock()
        from txtorcon import endpoints
        endpoints.launch_tor = m
        ep = yield TCPHiddenServiceEndpoint.private_tor(Mock(), 80,
                                                        control_port=1234)
        self.assertTrue(m.called)

    @defer.inlineCallbacks
    def test_private_tor_no_control_port(self):
        m = Mock()
        from txtorcon import endpoints
        endpoints.launch_tor = m
        ep = yield TCPHiddenServiceEndpoint.private_tor(Mock(), 80)
        self.assertTrue(m.called)

    @defer.inlineCallbacks
    def test_system_tor(self):
        from test_torconfig import FakeControlProtocol

        def boom(*args):
            # why does the new_callable thing need a callable that
            # returns a callable? Feels like I must be doing something
            # wrong somewhere...
            def bam(*args, **kw):
                return self.protocol
            return bam
        with patch('txtorcon.endpoints.launch_tor') as launch_mock:
            with patch('txtorcon.endpoints.build_tor_connection', new_callable=boom) as btc:
                client = clientFromString(
                    self.reactor,
                    "tcp:host=localhost:port=9050"
                )
                ep = yield TCPHiddenServiceEndpoint.system_tor(self.reactor,
                                                               client, 80)
                port = yield ep.listen(NoOpProtocolFactory())
                toa = port.getHost()
                self.assertTrue(hasattr(toa, 'onion_uri'))
                self.assertTrue(hasattr(toa, 'onion_port'))
                port.startListening()
                str(port)
                port.tor_config
                # system_tor should be connecting to a running one,
                # *not* launching a new one.
                self.assertFalse(launch_mock.called)

    @defer.inlineCallbacks
    def test_basic(self):
        listen = RuntimeError("listen")
        connect = RuntimeError("connect")
        reactor = proto_helpers.RaisingMemoryReactor(listen, connect)
        reactor.addSystemEventTrigger = Mock()

        ep = TCPHiddenServiceEndpoint(reactor, self.config, 123)
        self.config.bootstrap()
        yield self.config.post_bootstrap
        self.assertTrue(IProgressProvider.providedBy(ep))

        try:
            port = yield ep.listen(NoOpProtocolFactory())
            self.fail("Should have been an exception")
        except RuntimeError as e:
            # make sure we called listenTCP not connectTCP
            self.assertEqual(e, listen)

        repr(self.config.HiddenServices)

    def test_progress_updates(self):
        config = TorConfig()
        ep = TCPHiddenServiceEndpoint(self.reactor, config, 123)

        self.assertTrue(IProgressProvider.providedBy(ep))
        prog = IProgressProvider(ep)
        ding = Mock()
        prog.add_progress_listener(ding)
        args = (50, "blarg", "Doing that thing we talked about.")
        # kind-of cheating, test-wise?
        ep._tor_progress_update(*args)
        self.assertTrue(ding.called_with(*args))

    @patch('txtorcon.endpoints.launch_tor')
    def test_progress_updates_private_tor(self, tor):
        ep = TCPHiddenServiceEndpoint.private_tor(self.reactor, 1234)
        tor.call_args[1]['progress_updates'](40, 'FOO', 'foo to the bar')
        return ep

    def __test_progress_updates_system_tor(self):
        ep = TCPHiddenServiceEndpoint.system_tor(self.reactor, 1234)
        ep._tor_progress_update(40, "FOO", "foo to bar")
        return ep

    @patch('txtorcon.endpoints.get_global_tor')
    def test_progress_updates_global_tor(self, tor):
        ep = TCPHiddenServiceEndpoint.global_tor(self.reactor, 1234)
        tor.call_args[1]['progress_updates'](40, 'FOO', 'foo to the bar')
        return ep

    def test_hiddenservice_key_unfound(self):
        ep = TCPHiddenServiceEndpoint.private_tor(
            self.reactor,
            1234,
            hidden_service_dir='/dev/null'
        )

        # FIXME Mock() should work somehow for this, but I couldn't
        # make it "go"
        class Blam(object):
            @property
            def private_key(self):
                raise IOError("blam")
        ep.hiddenservice = Blam()
        self.assertEqual(ep.onion_private_key, None)
        return ep

    def test_multiple_listen(self):
        ep = TCPHiddenServiceEndpoint(self.reactor, self.config, 123)
        d0 = ep.listen(NoOpProtocolFactory())

        @defer.inlineCallbacks
        def more_listen(arg):
            yield arg.stopListening()
            d1 = ep.listen(NoOpProtocolFactory())

            def foo(arg):
                return arg
            d1.addBoth(foo)
            defer.returnValue(arg)
            return
        d0.addBoth(more_listen)
        self.config.bootstrap()

        def check(arg):
            self.assertEqual('127.0.0.1', ep.tcp_endpoint._interface)
            self.assertEqual(len(self.config.HiddenServices), 1)
        d0.addCallback(check).addErrback(self.fail)
        return d0

    def test_already_bootstrapped(self):
        self.config.bootstrap()
        ep = TCPHiddenServiceEndpoint(self.reactor, self.config, 123)
        d = ep.listen(NoOpProtocolFactory())
        return d

    @defer.inlineCallbacks
    def test_explicit_data_dir(self):
        d = tempfile.mkdtemp()
        try:
            with open(os.path.join(d, 'hostname'), 'w') as f:
                f.write('public')

            config = TorConfig(self.protocol)
            ep = TCPHiddenServiceEndpoint(self.reactor, config, 123, d)

            # make sure listen() correctly configures our hidden-serivce
            # with the explicit directory we passed in above
            port = yield ep.listen(NoOpProtocolFactory())

            self.assertEqual(1, len(config.HiddenServices))
            self.assertEqual(config.HiddenServices[0].dir, d)
            self.assertEqual(config.HiddenServices[0].hostname, 'public')

        finally:
            shutil.rmtree(d, ignore_errors=True)

    def test_failure(self):
        self.reactor.failures = 1
        ep = TCPHiddenServiceEndpoint(self.reactor, self.config, 123)
        d = ep.listen(NoOpProtocolFactory())
        self.config.bootstrap()
        d.addErrback(self.check_error)
        return d

    def check_error(self, failure):
        self.assertEqual(failure.type, error.CannotListenError)
        return None

    def test_parse_via_plugin(self):
        # make sure we have a valid thing from get_global_tor without
        # actually launching tor
        config = TorConfig()
        config.post_bootstrap = defer.succeed(config)
        from txtorcon import torconfig
        torconfig._global_tor_config = None
        get_global_tor(
            self.reactor,
            _tor_launcher=lambda react, config, prog: defer.succeed(config)
        )
        ep = serverFromString(
            self.reactor,
            'onion:88:localPort=1234:hiddenServiceDir=/foo/bar'
        )
        self.assertEqual(ep.public_port, 88)
        self.assertEqual(ep.local_port, 1234)
        self.assertEqual(ep.hidden_service_dir, '/foo/bar')

    def test_parse_user_path(self):
        # this makes sure we expand users and symlinks in
        # hiddenServiceDir args. see Issue #77

        # make sure we have a valid thing from get_global_tor without
        # actually launching tor
        config = TorConfig()
        config.post_bootstrap = defer.succeed(config)
        from txtorcon import torconfig
        torconfig._global_tor_config = None
        get_global_tor(
            self.reactor,
            _tor_launcher=lambda react, config, prog: defer.succeed(config)
        )
        ep = serverFromString(
            self.reactor,
            'onion:88:localPort=1234:hiddenServiceDir=~/blam/blarg'
        )
        # would be nice to have a fixed path here, but then would have
        # to run as a known user :/
        # maybe using the docker stuff to run integration tests better here?
        self.assertEqual(
            os.path.expanduser('~/blam/blarg'),
            ep.hidden_service_dir
        )

    def test_parse_relative_path(self):
        # this makes sure we convert a relative path to absolute
        # hiddenServiceDir args. see Issue #77

        # make sure we have a valid thing from get_global_tor without
        # actually launching tor
        config = TorConfig()
        config.post_bootstrap = defer.succeed(config)
        from txtorcon import torconfig
        torconfig._global_tor_config = None
        get_global_tor(
            self.reactor,
            _tor_launcher=lambda react, config, prog: defer.succeed(config)
        )

        orig = os.path.realpath('.')
        try:
            with util.TempDir() as t:
                t = str(t)
                os.chdir(t)
                os.mkdir(os.path.join(t, 'foo'))
                hsdir = os.path.join(t, 'foo', 'blam')
                os.mkdir(hsdir)

                ep = serverFromString(
                    self.reactor,
                    'onion:88:localPort=1234:hiddenServiceDir=foo/blam'
                )
                self.assertEqual(
                    os.path.realpath(hsdir),
                    ep.hidden_service_dir
                )

        finally:
            os.chdir(orig)

    @defer.inlineCallbacks
    def test_stealth_auth(self):
        '''
        make sure we produce a HiddenService instance with stealth-auth
        lines if we had authentication specified in the first place.
        '''

        config = TorConfig(self.protocol)
        ep = TCPHiddenServiceEndpoint(self.reactor, config, 123, '/dev/null',
                                      stealth_auth=['alice', 'bob'])

        # make sure listen() correctly configures our hidden-serivce
        # with the explicit directory we passed in above
        d = ep.listen(NoOpProtocolFactory())

        def foo(fail):
            print "ERROR", fail
        d.addErrback(foo)
        port = yield d
        self.assertEqual(1, len(config.HiddenServices))
        self.assertEqual(config.HiddenServices[0].dir, '/dev/null')
        self.assertEqual(config.HiddenServices[0].authorize_client[0], 'stealth alice,bob')
        self.assertEqual(None, ep.onion_uri)
        config.HiddenServices[0].hostname = 'oh my'
        self.assertEqual('oh my', ep.onion_uri)
Exemple #6
0
class EndpointTests(unittest.TestCase):
    def setUp(self):
        from txtorcon import endpoints
        endpoints._global_tor_config = None
        del endpoints._global_tor_lock
        endpoints._global_tor_lock = defer.DeferredLock()
        self.reactor = FakeReactorTcp(self)
        self.protocol = FakeControlProtocol([])
        self.protocol.event_happened('INFO', 'something craaaaaaazy')
        self.protocol.event_happened(
            'INFO', 'connection_dir_client_reached_eof(): Uploaded rendezvous '
            'descriptor (status 200 ("Service descriptor (v2) stored"))')
        self.config = TorConfig(self.protocol)
        self.protocol.answers.append(
            'config/names=\nHiddenServiceOptions Virtual')
        self.protocol.answers.append('HiddenServiceOptions')
        self.patcher = patch('txtorcon.torconfig.find_tor_binary',
                             return_value='/not/tor')
        self.patcher.start()

    def tearDown(self):
        from txtorcon import endpoints
        endpoints._global_tor_config = None
        del endpoints._global_tor_lock
        endpoints._global_tor_lock = defer.DeferredLock()
        self.patcher.stop()

    @defer.inlineCallbacks
    def test_global_tor(self):
        config = yield get_global_tor(Mock(),
                                      _tor_launcher=lambda x, y, z: True)
        self.assertEqual(0, config.SOCKSPort)

    @defer.inlineCallbacks
    def test_global_tor_error(self):
        config0 = yield get_global_tor(Mock(),
                                       _tor_launcher=lambda x, y, z: True)
        # now if we specify a control_port it should be an error since
        # the above should have launched one.
        try:
            config1 = yield get_global_tor(Mock(),
                                           control_port=111,
                                           _tor_launcher=lambda x, y, z: True)
            self.fail()
        except RuntimeError as e:
            # should be an error
            pass

    @defer.inlineCallbacks
    def test_endpoint_properties(self):
        ep = yield TCPHiddenServiceEndpoint.private_tor(Mock(), 80)
        self.assertEqual(None, ep.onion_private_key)
        self.assertEqual(None, ep.onion_uri)
        ep.hiddenservice = Mock()
        ep.hiddenservice.private_key = 'mumble'
        self.assertEqual('mumble', ep.onion_private_key)

    @defer.inlineCallbacks
    def test_private_tor(self):
        m = Mock()
        from txtorcon import endpoints
        endpoints.launch_tor = m
        ep = yield TCPHiddenServiceEndpoint.private_tor(Mock(),
                                                        80,
                                                        control_port=1234)
        self.assertTrue(m.called)

    @defer.inlineCallbacks
    def test_private_tor_no_control_port(self):
        m = Mock()
        from txtorcon import endpoints
        endpoints.launch_tor = m
        ep = yield TCPHiddenServiceEndpoint.private_tor(Mock(), 80)
        self.assertTrue(m.called)

    @defer.inlineCallbacks
    def test_system_tor(self):
        from test_torconfig import FakeControlProtocol

        def boom(*args):
            # why does the new_callable thing need a callable that
            # returns a callable? Feels like I must be doing something
            # wrong somewhere...
            def bam(*args, **kw):
                return self.protocol

            return bam

        with patch('txtorcon.endpoints.launch_tor') as launch_mock:
            with patch('txtorcon.endpoints.build_tor_connection',
                       new_callable=boom) as btc:
                client = clientFromString(self.reactor,
                                          "tcp:host=localhost:port=9050")
                ep = yield TCPHiddenServiceEndpoint.system_tor(
                    self.reactor, client, 80)
                port = yield ep.listen(NoOpProtocolFactory())
                toa = port.getHost()
                self.assertTrue(hasattr(toa, 'onion_uri'))
                self.assertTrue(hasattr(toa, 'onion_port'))
                port.startListening()
                str(port)
                port.tor_config
                # system_tor should be connecting to a running one,
                # *not* launching a new one.
                self.assertFalse(launch_mock.called)

    @defer.inlineCallbacks
    def test_basic(self):
        listen = RuntimeError("listen")
        connect = RuntimeError("connect")
        reactor = proto_helpers.RaisingMemoryReactor(listen, connect)
        reactor.addSystemEventTrigger = Mock()

        ep = TCPHiddenServiceEndpoint(reactor, self.config, 123)
        self.config.bootstrap()
        yield self.config.post_bootstrap
        self.assertTrue(IProgressProvider.providedBy(ep))

        try:
            port = yield ep.listen(NoOpProtocolFactory())
            self.fail("Should have been an exception")
        except RuntimeError as e:
            # make sure we called listenTCP not connectTCP
            self.assertEqual(e, listen)

        repr(self.config.HiddenServices)

    def test_progress_updates(self):
        config = TorConfig()
        ep = TCPHiddenServiceEndpoint(self.reactor, config, 123)

        self.assertTrue(IProgressProvider.providedBy(ep))
        prog = IProgressProvider(ep)
        ding = Mock()
        prog.add_progress_listener(ding)
        args = (50, "blarg", "Doing that thing we talked about.")
        # kind-of cheating, test-wise?
        ep._tor_progress_update(*args)
        self.assertTrue(ding.called_with(*args))

    @patch('txtorcon.endpoints.launch_tor')
    def test_progress_updates_private_tor(self, tor):
        ep = TCPHiddenServiceEndpoint.private_tor(self.reactor, 1234)
        tor.call_args[1]['progress_updates'](40, 'FOO', 'foo to the bar')
        return ep

    def __test_progress_updates_system_tor(self):
        ep = TCPHiddenServiceEndpoint.system_tor(self.reactor, 1234)
        ep._tor_progress_update(40, "FOO", "foo to bar")
        return ep

    @patch('txtorcon.endpoints.get_global_tor')
    def test_progress_updates_global_tor(self, tor):
        ep = TCPHiddenServiceEndpoint.global_tor(self.reactor, 1234)
        tor.call_args[1]['progress_updates'](40, 'FOO', 'foo to the bar')
        return ep

    def test_hiddenservice_key_unfound(self):
        ep = TCPHiddenServiceEndpoint.private_tor(
            self.reactor, 1234, hidden_service_dir='/dev/null')

        # FIXME Mock() should work somehow for this, but I couldn't
        # make it "go"
        class Blam(object):
            @property
            def private_key(self):
                raise IOError("blam")

        ep.hiddenservice = Blam()
        self.assertEqual(ep.onion_private_key, None)
        return ep

    def test_multiple_listen(self):
        ep = TCPHiddenServiceEndpoint(self.reactor, self.config, 123)
        d0 = ep.listen(NoOpProtocolFactory())

        @defer.inlineCallbacks
        def more_listen(arg):
            yield arg.stopListening()
            d1 = ep.listen(NoOpProtocolFactory())

            def foo(arg):
                return arg

            d1.addBoth(foo)
            defer.returnValue(arg)
            return

        d0.addBoth(more_listen)
        self.config.bootstrap()

        def check(arg):
            self.assertEqual('127.0.0.1', ep.tcp_endpoint._interface)
            self.assertEqual(len(self.config.HiddenServices), 1)

        d0.addCallback(check).addErrback(self.fail)
        return d0

    def test_already_bootstrapped(self):
        self.config.bootstrap()
        ep = TCPHiddenServiceEndpoint(self.reactor, self.config, 123)
        d = ep.listen(NoOpProtocolFactory())
        return d

    @defer.inlineCallbacks
    def test_explicit_data_dir(self):
        d = tempfile.mkdtemp()
        try:
            with open(os.path.join(d, 'hostname'), 'w') as f:
                f.write('public')

            config = TorConfig(self.protocol)
            ep = TCPHiddenServiceEndpoint(self.reactor, config, 123, d)

            # make sure listen() correctly configures our hidden-serivce
            # with the explicit directory we passed in above
            port = yield ep.listen(NoOpProtocolFactory())

            self.assertEqual(1, len(config.HiddenServices))
            self.assertEqual(config.HiddenServices[0].dir, d)
            self.assertEqual(config.HiddenServices[0].hostname, 'public')

        finally:
            shutil.rmtree(d, ignore_errors=True)

    def test_failure(self):
        self.reactor.failures = 1
        ep = TCPHiddenServiceEndpoint(self.reactor, self.config, 123)
        d = ep.listen(NoOpProtocolFactory())
        self.config.bootstrap()
        d.addErrback(self.check_error)
        return d

    def check_error(self, failure):
        self.assertEqual(failure.type, error.CannotListenError)
        return None

    def test_parse_via_plugin(self):
        # make sure we have a valid thing from get_global_tor without
        # actually launching tor
        config = TorConfig()
        config.post_bootstrap = defer.succeed(config)
        from txtorcon import torconfig
        torconfig._global_tor_config = None
        get_global_tor(
            self.reactor,
            _tor_launcher=lambda react, config, prog: defer.succeed(config))
        ep = serverFromString(
            self.reactor, 'onion:88:localPort=1234:hiddenServiceDir=/foo/bar')
        self.assertEqual(ep.public_port, 88)
        self.assertEqual(ep.local_port, 1234)
        self.assertEqual(ep.hidden_service_dir, '/foo/bar')

    def test_parse_user_path(self):
        # this makes sure we expand users and symlinks in
        # hiddenServiceDir args. see Issue #77

        # make sure we have a valid thing from get_global_tor without
        # actually launching tor
        config = TorConfig()
        config.post_bootstrap = defer.succeed(config)
        from txtorcon import torconfig
        torconfig._global_tor_config = None
        get_global_tor(
            self.reactor,
            _tor_launcher=lambda react, config, prog: defer.succeed(config))
        ep = serverFromString(
            self.reactor,
            'onion:88:localPort=1234:hiddenServiceDir=~/blam/blarg')
        # would be nice to have a fixed path here, but then would have
        # to run as a known user :/
        # maybe using the docker stuff to run integration tests better here?
        self.assertEqual(os.path.expanduser('~/blam/blarg'),
                         ep.hidden_service_dir)

    def test_parse_relative_path(self):
        # this makes sure we convert a relative path to absolute
        # hiddenServiceDir args. see Issue #77

        # make sure we have a valid thing from get_global_tor without
        # actually launching tor
        config = TorConfig()
        config.post_bootstrap = defer.succeed(config)
        from txtorcon import torconfig
        torconfig._global_tor_config = None
        get_global_tor(
            self.reactor,
            _tor_launcher=lambda react, config, prog: defer.succeed(config))

        orig = os.path.realpath('.')
        try:
            with util.TempDir() as t:
                t = str(t)
                os.chdir(t)
                os.mkdir(os.path.join(t, 'foo'))
                hsdir = os.path.join(t, 'foo', 'blam')
                os.mkdir(hsdir)

                ep = serverFromString(
                    self.reactor,
                    'onion:88:localPort=1234:hiddenServiceDir=foo/blam')
                self.assertEqual(os.path.realpath(hsdir),
                                 ep.hidden_service_dir)

        finally:
            os.chdir(orig)

    @defer.inlineCallbacks
    def test_stealth_auth(self):
        '''
        make sure we produce a HiddenService instance with stealth-auth
        lines if we had authentication specified in the first place.
        '''

        config = TorConfig(self.protocol)
        ep = TCPHiddenServiceEndpoint(self.reactor,
                                      config,
                                      123,
                                      '/dev/null',
                                      stealth_auth=['alice', 'bob'])

        # make sure listen() correctly configures our hidden-serivce
        # with the explicit directory we passed in above
        d = ep.listen(NoOpProtocolFactory())

        def foo(fail):
            print "ERROR", fail

        d.addErrback(foo)
        port = yield d
        self.assertEqual(1, len(config.HiddenServices))
        self.assertEqual(config.HiddenServices[0].dir, '/dev/null')
        self.assertEqual(config.HiddenServices[0].authorize_client[0],
                         'stealth alice,bob')
        self.assertEqual(None, ep.onion_uri)
        config.HiddenServices[0].hostname = 'oh my'
        self.assertEqual('oh my', ep.onion_uri)
Exemple #7
0
 def setUp(self):
     self.reactor = FakeReactorTcp(self)
     self.protocol = FakeControlProtocol([])