Example #1
0
def run(reactor, cfg, tor, ports):
    def info(msg):
        if 'Service descriptor (v2) stored' in msg:
            got_upload.callback(None)

    got_upload = Deferred()
    tor.protocol.add_event_listener('INFO', info)

    hs = txtorcon.EphemeralHiddenService(ports)
    yield hs.add_to_tor(tor.protocol)
    print("Created HS", hs.hostname)

    def remove():
        print("removing hidden-service")
        return hs.remove_from_tor(tor.protocol)

    reactor.addSystemEventTrigger('before', 'shutdown', remove)

    print("...waiting for descriptor upload")
    yield got_upload
    print("Got one.", time.asctime())

    # we never callback() on this, so we serve forever
    d = Deferred()
    yield d
Example #2
0
    def run(self, options, mainoptions, proto):
        "ICarmlCommand API"

        def info(msg):
            if 'Service descriptor (v2) stored' in msg:
                got_upload.callback(None)

        got_upload = Deferred()
        proto.add_event_listener('INFO', info)

        hs = txtorcon.EphemeralHiddenService(options['ports'])
        yield hs.add_to_tor(proto)
        print("Created HS", hs.hostname)

        def remove():
            print("removing hidden-service")
            return hs.remove_from_tor(proto)

        reactor.addSystemEventTrigger('before', 'shutdown', remove)

        print("...waiting for descriptor upload")
        yield got_upload
        print("Got one.", time.asctime())

        # we never callback() on this, so we serve forever
        d = Deferred()
        yield d
Example #3
0
            def listen(self, proto_factory):
                # we don't care which local TCP port we listen on, but
                # we do need to know it
                local_ep = TCP4ServerEndpoint(reactor,
                                              0,
                                              interface=u"127.0.0.1")
                target_port = yield local_ep.listen(proto_factory)
                tor = yield txtorcon.connect(
                    reactor,
                    tor_control_ep,
                )

                # create and add the service
                hs = txtorcon.EphemeralHiddenService(
                    ports=[
                        "{} 127.0.0.1:{}".format(port,
                                                 target_port.getHost().port)
                    ],
                    key_blob_or_type=private_key
                    if private_key else "NEW:BEST",
                )
                log.info("Uploading descriptors can take more than 30s")
                yield hs.add_to_tor(tor.protocol)

                # if it's new, store our private key
                # XXX better "if private_key is None"?
                if not exists(private_key_fname):
                    with open(private_key_fname, 'w') as f:
                        f.write(hs.private_key)
                    log.info("Wrote private key to '{fname}'",
                             fname=private_key_fname)

                addr = txtorcon.TorOnionAddress(hs.hostname, port)
                log.info(
                    "Listening on Tor onion service {addr.onion_uri}:{addr.onion_port}"
                    " with local port {local_port}",
                    addr=addr,
                    local_port=target_port.getHost().port,
                )
                defer.returnValue(addr)
Example #4
0
def main(reactor):
    ep = TCP4ClientEndpoint(reactor, "localhost", 9251)
    tor_protocol = yield txtorcon.build_tor_connection(ep, build_state=False)
    print "Connected to Tor"

    hs_public_port = 80
    hs_port = yield txtorcon.util.available_tcp_port(reactor)
    hs_string = '%s 127.0.0.1:%d' % (hs_public_port, hs_port)
    print "Adding ephemeral service", hs_string
    print "(this can take some time; please be patient)"
    hs = txtorcon.EphemeralHiddenService([hs_string])
    yield hs.add_to_tor(tor_protocol)
    print "Added ephemeral HS to Tor:", hs.hostname

    print "Starting site"
    site = server.Site(Simple())
    hs_endpoint = TCP4ServerEndpoint(reactor, hs_port, interface='127.0.0.1')
    yield hs_endpoint.listen(site)

    # in 5 seconds, remove the hidden service -- obviously this is
    # where you'd do your "real work" or whatever.
    d = defer.Deferred()

    @defer.inlineCallbacks
    def remove():
        print "Removing the hiddenservice. Private key was"
        print hs.private_key
        yield hs.remove_from_tor(tor_protocol)
        d.callback(None)

    if False:
        reactor.callLater(5, remove)
        print "waiting 5 seconds"
    else:
        print "waiting forever"
    yield d
Example #5
0
def create_config(reactor, cli_config):
    txtorcon = _import_txtorcon()
    if not txtorcon:
        raise ValueError("Cannot create onion without txtorcon. "
                         "Please 'pip install tahoe-lafs[tor]' to fix this.")
    tahoe_config_tor = {}  # written into tahoe.cfg:[tor]
    private_dir = os.path.abspath(
        os.path.join(cli_config["basedir"], "private"))
    stdout = cli_config.stdout
    if cli_config["tor-launch"]:
        tahoe_config_tor["launch"] = "true"
        tor_executable = cli_config["tor-executable"]
        if tor_executable:
            tahoe_config_tor["tor.executable"] = tor_executable
        print("launching Tor (to allocate .onion address)..", file=stdout)
        (_, tor_control_proto) = yield _launch_tor(reactor, tor_executable,
                                                   private_dir, txtorcon)
        print("Tor launched", file=stdout)
    else:
        print("connecting to Tor (to allocate .onion address)..", file=stdout)
        (port,
         tor_control_proto) = yield _connect_to_tor(reactor, cli_config,
                                                    txtorcon)
        print("Tor connection established", file=stdout)
        tahoe_config_tor["control.port"] = port

    external_port = 3457  # TODO: pick this randomly? there's no contention.

    local_port = allocate_tcp_port()
    ehs = txtorcon.EphemeralHiddenService("%d 127.0.0.1:%d" %
                                          (external_port, local_port))
    print("allocating .onion address (takes ~40s)..", file=stdout)
    yield ehs.add_to_tor(tor_control_proto)
    print(".onion address allocated", file=stdout)
    tor_port = "tcp:%d:interface=127.0.0.1" % local_port
    tor_location = "tor:%s:%d" % (ehs.hostname, external_port)
    privkey = ehs.private_key
    yield ehs.remove_from_tor(tor_control_proto)

    # in addition to the "how to launch/connect-to tor" keys above, we also
    # record information about the onion service into tahoe.cfg.
    # * "local_port" is a server endpont string, which should match
    #   "tor_port" (which will be added to tahoe.cfg [node] tub.port)
    # * "external_port" is the random "public onion port" (integer), which
    #   (when combined with the .onion address) should match "tor_location"
    #   (which will be added to tub.location)
    # * "private_key_file" points to the on-disk copy of the private key
    #   material (although we always write it to the same place)

    tahoe_config_tor["onion"] = "true"
    tahoe_config_tor["onion.local_port"] = str(local_port)
    tahoe_config_tor["onion.external_port"] = str(external_port)
    assert privkey
    tahoe_config_tor["onion.private_key_file"] = os.path.join(
        "private", "tor_onion.privkey")
    privkeyfile = os.path.join(private_dir, "tor_onion.privkey")
    with open(privkeyfile, "wb") as f:
        f.write(privkey)

    # tahoe_config_tor: this is a dictionary of keys/values to add to the
    # "[tor]" section of tahoe.cfg, which tells the new node how to launch
    # Tor in the right way.

    # tor_port: a server endpoint string, it will be added to tub.port=

    # tor_location: a foolscap connection hint, "tor:ONION:EXTERNAL_PORT"

    # We assume/require that the Node gives us the same data_directory=
    # at both create-node and startup time. The data directory is not
    # recorded in tahoe.cfg

    returnValue((tahoe_config_tor, tor_port, tor_location))