Ejemplo n.º 1
0
    def test_happened_already(self):
        proto = FakeControlProtocol([])
        events = []

        def event_cb(*args, **kw):
            events.append((args, kw))

        proto.event_happened("something", "arg")
        proto.add_event_listener("something", event_cb)

        self.assertEqual(
            [(("arg",), {})],
            events
        )
Ejemplo n.º 2
0
    def test_set_dir(self):
        protocol = FakeControlProtocol([])
        config = TorConfig(protocol)
        hsdir0 = self.mktemp()
        os.mkdir(hsdir0)
        hsdir1 = self.mktemp()
        os.mkdir(hsdir1)

        with open(join(hsdir0, "hostname"), "w") as f:
            f.write('{}.onion'.format(_test_onion_id))

        hs_d = FilesystemOnionService.create(
            Mock(),
            config,
            hsdir=hsdir0,
            ports=["80 127.0.0.1:4321"],
            version=3,
        )

        # arrange HS_DESC callbacks so we get the hs instance back
        cb = protocol.events['HS_DESC']
        cb('UPLOAD {} UNKNOWN hsdir0'.format(_test_onion_id))
        cb('UPLOADED {} UNKNOWN hsdir0'.format(_test_onion_id))

        hs = yield hs_d

        hs.dir = hsdir1
        self.assertEqual(hs.dir, hsdir1)
Ejemplo n.º 3
0
    def test_tor_version_v3_progress(self):
        protocol = FakeControlProtocol([])
        config = TorConfig(protocol)
        hsdir = self.mktemp()
        os.mkdir(hsdir)
        with open(join(hsdir, "hostname"), "w") as f:
            f.write('{}.onion'.format(_test_onion_id))

        def my_progress(a, b, c):
            pass

        eph_d = FilesystemOnionService.create(
            Mock(),
            config,
            hsdir,
            ports=["80 127.0.0.1:80"],
            progress=my_progress,
            version=3,
        )

        # arrange HS_DESC callbacks so we get the hs instance back
        cb = protocol.events['HS_DESC']
        cb('UPLOAD {} UNKNOWN hsdir0'.format(_test_onion_id))
        cb('UPLOADED {} UNKNOWN hsdir0'.format(_test_onion_id))

        yield eph_d
Ejemplo n.º 4
0
    def test_tor_version_v3_progress_await_all(self):
        protocol = FakeControlProtocol([])
        config = TorConfig(protocol)
        hsdir = self.mktemp()
        os.mkdir(hsdir)
        with open(join(hsdir, "hostname"), "w") as f:
            f.write('{}.onion'.format(_test_onion_id))

        class Bad(Exception):
            pass

        def my_progress(a, b, c):
            raise Bad("it's bad")

        eph_d = FilesystemOnionService.create(
            Mock(),
            config,
            hsdir,
            ports=["80 127.0.0.1:80"],
            progress=my_progress,
            version=3,
            await_all_uploads=True,
        )

        # arrange HS_DESC callbacks so we get the hs instance back
        cb = protocol.events['HS_DESC']
        cb('UPLOAD {} UNKNOWN hsdir0'.format(_test_onion_id))
        cb('UPLOADED {} UNKNOWN hsdir0'.format(_test_onion_id))

        yield eph_d
        errs = self.flushLoggedErrors(Bad)
        self.assertEqual(3, len(errs))  # because there's a "100%" one too
Ejemplo n.º 5
0
    def test_ephemeral_bad_return_value(self):
        protocol = FakeControlProtocol([])
        config = TorConfig(protocol)
        progress_messages = []

        def progress(*args):
            progress_messages.append(args)
        eph_d = EphemeralOnionService.create(
            Mock(),
            config,
            ports=["80 127.0.0.1:80"],
            progress=progress,
            private_key=DISCARD,
        )

        cmd, d = protocol.commands[0]
        self.assertEqual(u"ADD_ONION NEW:BEST Port=80,127.0.0.1:80 Flags=DiscardPK", cmd)

        d.callback("BadKey=nothing")

        def check(f):
            self.assertIn("Expected ADD_ONION to return ServiceID", str(f.value))
            return None
        eph_d.addCallbacks(self.fail, check)
        return eph_d
Ejemplo n.º 6
0
    def test_ephemeral_remove_not_ok(self):
        protocol = FakeControlProtocol([])
        config = TorConfig(protocol)

        eph_d = EphemeralOnionService.create(
            Mock(),
            config,
            ports=["80 127.0.0.1:80"],
        )

        cmd, d = protocol.commands[0]
        self.assertEqual(u"ADD_ONION NEW:BEST Port=80,127.0.0.1:80", cmd)

        d.callback("PrivateKey={}\nServiceID={}".format(_test_private_key_blob, _test_onion_id))
        cb = protocol.events['HS_DESC']

        for x in range(6):
            cb('UPLOAD {} UNKNOWN hsdir_{}'.format(_test_onion_id, x))

        for x in range(6):
            cb('UPLOADED {} UNKNOWN hsdir_{}'.format(_test_onion_id, x))

        hs = yield eph_d
        remove_d = hs.remove()
        cmd, d = protocol.commands[-1]
        self.assertEqual(u"DEL_ONION {}".format(_test_onion_id), cmd)
        d.callback('bad stuff')
        with self.assertRaises(RuntimeError):
            yield remove_d
Ejemplo n.º 7
0
    def test_set_ports(self):
        protocol = FakeControlProtocol([])
        config = TorConfig(protocol)
        hsdir = self.mktemp()
        os.mkdir(hsdir)
        with open(join(hsdir, 'hs_ed25519_secret_key'), 'wb') as f:
            f.write(b'\x01\x02\x03\x04')
        with open(join(hsdir, 'hostname'), 'w') as f:
            f.write('{}.onion'.format(_test_onion_id))

        hs_d = FilesystemOnionService.create(
            Mock(),
            config,
            hsdir=hsdir,
            ports=["80 127.0.0.1:4321"],
            version=3,
        )

        # arrange HS_DESC callbacks so we get the hs instance back
        cb = protocol.events['HS_DESC']
        cb('UPLOAD {} UNKNOWN hsdir0'.format(_test_onion_id))
        cb('UPLOADED {} UNKNOWN hsdir0'.format(_test_onion_id))

        hs = yield hs_d
        hs.ports = ["443 127.0.0.1:443"]
        self.assertEqual(1, len(hs.ports))
Ejemplo n.º 8
0
    def test_old_tor_version(self):
        protocol = FakeControlProtocol([])
        protocol.version = "0.1.2.3"
        config = TorConfig(protocol)
        hsdir = self.mktemp()

        def my_progress(a, b, c):
            pass

        eph_d = FilesystemOnionService.create(
            Mock(),
            config,
            hsdir,
            ports=["80 127.0.0.1:80"],
            progress=my_progress,
        )
        yield eph_d
Ejemplo n.º 9
0
    def test_old_tor_version(self):
        protocol = FakeControlProtocol([])
        protocol.version = "0.1.2.3"
        config = TorConfig(protocol)
        hsdir = self.mktemp()

        def my_progress(a, b, c):
            pass

        eph_d = FilesystemOnionService.create(
            Mock(),
            config,
            hsdir,
            ports=["80 127.0.0.1:80"],
            progress=my_progress,
        )
        yield eph_d
Ejemplo n.º 10
0
    def test_unknown_version(self):
        protocol = FakeControlProtocol([])
        protocol.version = "0.1.1.1"
        config = TorConfig(protocol)
        hsdir = self.mktemp()
        os.mkdir(hsdir)

        hs = yield FilesystemOnionService.create(
            Mock(),
            config,
            hsdir=hsdir,
            ports=["80 127.0.0.1:4321"],
            version=99,
        )

        with self.assertRaises(RuntimeError) as ctx:
            hs.private_key
        self.assertIn("Don't know how to load", str(ctx.exception))
Ejemplo n.º 11
0
    def test_unknown_version(self):
        protocol = FakeControlProtocol([])
        protocol.version = "0.1.1.1"
        config = TorConfig(protocol)
        hsdir = self.mktemp()
        os.mkdir(hsdir)

        hs = yield FilesystemOnionService.create(
            Mock(),
            config,
            hsdir=hsdir,
            ports=["80 127.0.0.1:4321"],
            version=99,
        )

        with self.assertRaises(RuntimeError) as ctx:
            hs.private_key
        self.assertIn("Don't know how to load", str(ctx.exception))
Ejemplo n.º 12
0
 def setUp(self):
     self.thedir = self.mktemp()
     os.mkdir(self.thedir)
     protocol = FakeControlProtocol([])
     self.config = TorConfig(protocol)
     self.hs = FilesystemAuthenticatedOnionService(
         config=self.config,
         thedir=self.thedir,
         ports=["80 127.0.0.1:1234"],
         auth=AuthBasic(['foo', 'bar']))
Ejemplo n.º 13
0
    def test_ephemeral_ver_option(self):
        protocol = FakeControlProtocol([])
        config = TorConfig(protocol)

        hs = EphemeralOnionService(
            config,
            ports=["80 127.0.0.1:80"],
            ver=2,
        )
        self.assertEqual(2, hs.version)
Ejemplo n.º 14
0
    def test_ephemeral_key_whitespace1(self):
        protocol = FakeControlProtocol([])
        config = TorConfig(protocol)

        d = EphemeralOnionService.create(
            Mock(),
            config,
            ports=["80 127.0.0.1:80"],
            private_key=_test_private_key_blob + '\n',
            detach=True,
        )
        return self.assertFailure(d, ValueError)
Ejemplo n.º 15
0
    def test_filesystem_wrong_ports(self):
        protocol = FakeControlProtocol([])
        config = TorConfig(protocol)

        with self.assertRaises(ValueError) as ctx:
            yield FilesystemOnionService.create(
                Mock(),
                config,
                "/dev/null",
                ports="80 127.0.0.1:80",
            )
        self.assertIn("'ports' must be a list of strings", str(ctx.exception))
Ejemplo n.º 16
0
    def test_ephemeral_v3_ip_addr_tuple_non_local(self):
        protocol = FakeControlProtocol([])
        config = TorConfig(protocol)

        # returns a Deferred we're ignoring
        with self.assertRaises(ValueError):
            yield EphemeralOnionService.create(
                Mock(),
                config,
                ports=[(80, "hostname:80")],
                detach=True,
                version=3,
            )
Ejemplo n.º 17
0
    def test_ephemeral_ports_no_spaces(self):
        protocol = FakeControlProtocol([])
        config = TorConfig(protocol)
        privkey = 'a' * 32

        with self.assertRaises(ValueError) as ctx:
            yield EphemeralOnionService.create(
                Mock(),
                config,
                ports=["80:127.0.0.1:80"],
                private_key=privkey,
            )
        self.assertIn("exactly one space", str(ctx.exception))
Ejemplo n.º 18
0
    def test_ephemeral_ports_non_local(self):
        protocol = FakeControlProtocol([])
        config = TorConfig(protocol)
        privkey = 'a' * 32

        with self.assertRaises(ValueError) as ctx:
            yield EphemeralOnionService.create(
                Mock(),
                config,
                ports=["80 8.8.8.8:80"],
                private_key=privkey,
            )
        self.assertIn("should be a local address", str(ctx.exception))
Ejemplo n.º 19
0
    def test_ephemeral_ports_not_an_int(self):
        protocol = FakeControlProtocol([])
        config = TorConfig(protocol)
        privkey = 'a' * 32

        with self.assertRaises(ValueError) as ctx:
            yield EphemeralOnionService.create(
                Mock(),
                config,
                ports=["web 127.0.0.1:80"],
                private_key=privkey,
            )
        self.assertIn("external port isn't an int", str(ctx.exception))
Ejemplo n.º 20
0
    def test_ephemeral_ports_not_a_list(self):
        protocol = FakeControlProtocol([])
        config = TorConfig(protocol)
        privkey = 'a' * 32

        with self.assertRaises(ValueError) as ctx:
            yield EphemeralOnionService.create(
                Mock(),
                config,
                ports="80 127.0.0.1:80",
                private_key=privkey,
            )
        self.assertIn("'ports' must be a list of strings", str(ctx.exception))
Ejemplo n.º 21
0
    def test_ephemeral_auth_stealth(self):
        protocol = FakeControlProtocol([])
        config = TorConfig(protocol)

        with self.assertRaises(ValueError) as ctx:
            yield EphemeralAuthenticatedOnionService.create(
                Mock(),
                config,
                ports=["80 127.0.0.1:80"],
                auth=AuthStealth(["steve", "carol"]),
            )
        self.assertIn(
            "Tor does not yet support",
            str(ctx.exception),
        )
Ejemplo n.º 22
0
    def test_ephemeral_extra_kwargs(self):
        protocol = FakeControlProtocol([])
        config = TorConfig(protocol)

        with self.assertRaises(ValueError) as ctx:
            EphemeralOnionService(
                config,
                ports=["80 127.0.0.1:80"],
                ver=2,
                something_funny="foo",
            )
        self.assertIn(
            "Unknown kwarg",
            str(ctx.exception),
        )
Ejemplo n.º 23
0
    def test_ephemeral_ports_bad0(self):
        protocol = FakeControlProtocol([])
        config = TorConfig(protocol)

        with self.assertRaises(ValueError) as ctx:
            yield EphemeralAuthenticatedOnionService.create(
                Mock(),
                config,
                ports="80 127.0.0.1:80",
                auth=AuthBasic(["xavier"]),
            )
        self.assertIn(
            "'ports' must be a list of strings",
            str(ctx.exception),
        )
Ejemplo n.º 24
0
    def test_ephemeral_auth_unknown(self):
        protocol = FakeControlProtocol([])
        config = TorConfig(protocol)

        with self.assertRaises(ValueError) as ctx:
            yield EphemeralAuthenticatedOnionService.create(
                Mock(),
                config,
                ports=["80 127.0.0.1:80"],
                auth=["carol", "steve"],
            )
        self.assertIn(
            "'auth' should be an AuthBasic or AuthStealth instance",
            str(ctx.exception),
        )
Ejemplo n.º 25
0
    def test_ephemeral_v3_no_key(self):
        protocol = FakeControlProtocol([])
        config = TorConfig(protocol)

        # returns a Deferred we're ignoring
        EphemeralOnionService.create(
            Mock(),
            config,
            ports=["80 127.0.0.1:80"],
            detach=True,
            version=3,
        )

        cmd, d = protocol.commands[0]
        self.assertEqual(u"ADD_ONION NEW:ED25519-V3 Port=80,127.0.0.1:80 Flags=Detach", cmd)
        d.callback("PrivateKey={}\nServiceID={}".format(_test_private_key_blob, _test_onion_id))
Ejemplo n.º 26
0
    def test_happened_already(self):
        proto = FakeControlProtocol([])
        events = []

        def event_cb(*args, **kw):
            events.append((args, kw))

        proto.event_happened("something", "arg")
        proto.add_event_listener("something", event_cb)

        self.assertEqual([(("arg", ), {})], events)
Ejemplo n.º 27
0
    def test_ephemeral_v3_wrong_key_type(self):
        protocol = FakeControlProtocol([])
        config = TorConfig(protocol)
        privkey = 'RSA1024:{}'.format('a' * 32)

        with self.assertRaises(ValueError) as ctx:
            yield EphemeralOnionService.create(
                Mock(),
                config,
                ports=["80 127.0.0.1:80"],
                detach=True,
                version=3,
                private_key=privkey,
            )
        self.assertIn(
            "but private key isn't",
            str(ctx.exception),
        )
Ejemplo n.º 28
0
    def test_ephemeral_v3_non_anonymous(self):
        protocol = FakeControlProtocol([])
        config = TorConfig(protocol)

        # returns a Deferred we're ignoring
        EphemeralOnionService.create(
            Mock(),
            config,
            ports=[(80, "192.168.1.2:80")],
            version=3,
            detach=True,
            single_hop=True,
        )

        cmd, d = protocol.commands[0]
        self.assertEqual(
            u"ADD_ONION NEW:ED25519-V3 Port=80,192.168.1.2:80 Flags=Detach,NonAnonymous",
            cmd)
        d.callback("PrivateKey={}\nServiceID={}".format(
            _test_private_key_blob, _test_onion_id))
Ejemplo n.º 29
0
    def test_descriptor_all_uploads_fail(self):
        protocol = FakeControlProtocol([])
        config = TorConfig(protocol)
        progress_messages = []

        def progress(*args):
            progress_messages.append(args)

        eph_d = EphemeralOnionService.create(
            Mock(),
            config,
            ports=["80 127.0.0.1:80"],
            progress=progress,
            private_key=DISCARD,
        )

        cmd, d = protocol.commands[0]
        self.assertEqual(
            u"ADD_ONION NEW:BEST Port=80,127.0.0.1:80 Flags=DiscardPK", cmd)
        d.callback("PrivateKey={}\nServiceID={}".format(
            _test_private_key_blob, _test_onion_id))

        # get the event-listener callback that torconfig code added
        cb = protocol.events['HS_DESC']

        for x in range(6):
            cb('UPLOAD {} UNKNOWN hsdir_{}'.format(_test_onion_id, x))

        for x in range(6):
            cb('FAILED {} UNKNOWN hsdir_{}'.format(_test_onion_id, x))

        # now when we wait for our onion, it should already be failed
        # because all 6 uploads failed.
        with self.assertRaises(RuntimeError) as ctx:
            yield eph_d

        self.assertIn("Failed to upload", str(ctx.exception))
        for x in range(6):
            self.assertIn("hsdir_{}".format(x), str(ctx.exception))
Ejemplo n.º 30
0
    def test_dir_ioerror(self):
        protocol = FakeControlProtocol([])
        config = TorConfig(protocol)
        hsdir = self.mktemp()
        os.mkdir(hsdir)
        with open(join(hsdir, "hostname"), "w") as f:
            f.write("{}.onion".format(_test_onion_id))

        hs_d = FilesystemOnionService.create(
            Mock(),
            config,
            hsdir=hsdir,
            ports=["80 127.0.0.1:4321"],
        )

        # arrange HS_DESC callbacks so we get the hs instance back
        cb = protocol.events['HS_DESC']
        cb('UPLOAD {} UNKNOWN hsdir0'.format(_test_onion_id))
        cb('UPLOADED {} UNKNOWN hsdir0'.format(_test_onion_id))

        hs = yield hs_d
        self.assertIs(None, hs.private_key)
Ejemplo n.º 31
0
    def test_ephemeral_auth_basic_remove_fails(self):
        protocol = FakeControlProtocol([])
        config = TorConfig(protocol)

        eph_d = EphemeralAuthenticatedOnionService.create(
            Mock(),
            config,
            ports=["80 127.0.0.1:80"],
            auth=AuthBasic([
                "steve",
                ("carol", "c4r0ls33kr1t"),
            ]),
        )
        cmd, d = protocol.commands[0]
        self.assertTrue(
            cmd.startswith(
                u"ADD_ONION NEW:BEST Port=80,127.0.0.1:80 Flags=BasicAuth "
            )
        )
        self.assertIn(u"ClientAuth=steve", cmd)
        self.assertIn(u"ClientAuth=carol:c4r0ls33kr1t", cmd)

        d.callback(
            "PrivateKey={}\nServiceID={}\nClientAuth=steve:aseekritofsomekind".format(
                _test_private_key_blob,
                _test_onion_id,
            )
        )
        cb = protocol.events['HS_DESC']

        for x in range(6):
            cb('UPLOAD {} UNKNOWN hsdir_{}'.format(_test_onion_id, x))

        for x in range(6):
            cb('UPLOADED {} UNKNOWN hsdir_{}'.format(_test_onion_id, x))

        hs = yield eph_d

        self.assertEqual(
            set(["steve", "carol"]),
            set(hs.client_names()),
        )
        steve = hs.get_client("steve")
        self.assertEqual(
            "aseekritofsomekind",
            steve.auth_token,
        )
        self.assertEqual(
            "{}.onion".format(_test_onion_id),
            steve.hostname,
        )
        self.assertEqual(
            set(["80 127.0.0.1:80"]),
            steve.ports,
        )
        self.assertTrue(steve.parent is hs)
        self.assertEqual("steve", steve.name)
        self.assertEqual(2, steve.version)

        carol = hs.get_client("carol")
        self.assertEqual(
            "c4r0ls33kr1t",
            carol.auth_token,
        )
        self.assertEqual(
            "{}.onion".format(_test_onion_id),
            carol.hostname,
        )

        remove_d = hs.remove()
        cmd, d = protocol.commands[-1]
        self.assertEqual(u"DEL_ONION {}".format(_test_onion_id), cmd)
        d.callback('not okay')
        with self.assertRaises(RuntimeError):
            yield remove_d