# Introduction

txtorcon is an implementation of the control-spec for Tor using the Twisted networking library for Python (supports Py2, PyPy and Py3).

txtorcon gives you a live view of all Tor state and the ability to control most aspects of Tor’s operation. With txtorcon you can launch tor; connect to already-running tor instances; use tor as a client (via SOCKS5); set up (onion) services over tor; change all aspects of configuration; track live state (active circuits and streams, etc); do DNS via Tor; and query other information from the tor daemon.

txtorcon is the library to use if you want to write event-based software in Python that uses the Tor network as a client or a service (or integrate Tor support for existing Twisted-using applications, or display information about a locally running tor). Twisted already provides many robust protocol implementations, deployment, logging and integration with GTK, Qt and other graphics frameworks – so txtorcon can be used for command-line or GUI applications or integrate with long-lived daemons easily.

In fact, due to support for endpoints (adding the `tor:` and `onion:` plugins), many Twisted applications can now integrate with Tor with no code changes. For example, you can use the existing Twisted webserver via `twistd` to serve your `~/public_html` directory over an onion service:

    $ sudo apt-get install --install-suggests python-txtorcon
    $ twistd web --port "onion:80" --path ~/public_html

(You should ideally enable the Tor project repositories first).

txtorcon strives to provide sane and safe defaults. txtorcon is a Tor project. The applications Tahoe-LAFS and Crossbar.io have successfully integrated Tor support using txtorcon.

## Features Overview

Currently, txtorcon is capable of:

- making arbitrary client connections to other services over Tor;

- configuring twisted.web.client.Agent instances to do Web requests over Tor;

- doing both of the above over specific circuits;

- listening as an Onion service;

- maintaining up-to-date (live) state information about Tor: Circuits, Streams and Routers (relays);

- maintaining current (live) configuration information;

- maintaining representation of Tor’s address mappings (with expiry);

- interrogating initial state of all three of the above;

- listening for and altering stream -> circuit mappings;

- building custom circuits;

- Circuit and Stream state listeners;

- listening for any Tor EVENT;

- launching and/or controlling a Tor instance (including Tor Browser Bundle);

- complete Twisted endpoint support (both “onion”/server side and client-side). This means you may be able to use existing Twisted software via Tor with no code changes. It also is the preferred way to connect (or listen) in Twisted.

Comments (positive or negative) appreciated. Even better if they come with patches 😉

## Shell-cast Overview

A text-only screencast-type overview of some of txtorcon’s features is available on asciinema:

https://asciinema.org/a/eh2gxfz3rc1ztgapkcol47d6o/

## Example Code

download (also python3 style)

    from twisted.internet.task import react
    from twisted.internet.defer import ensureDeferred
    from twisted.internet.endpoints import UNIXClientEndpoint

    import treq
    import txtorcon

    async def main(reactor):
        tor = await txtorcon.connect(
            reactor,
            UNIXClientEndpoint(reactor, "/var/run/tor/control")
        )

        print("Connected to Tor version {}".format(tor.version))

        url = u'https://www.torproject.org:443'
        print(u"Downloading {}".format(repr(url)))
        resp = await treq.get(url, agent=tor.web_agent())

        print(u"   {} bytes".format(resp.length))
        data = await resp.text()
        print(u"Got {} bytes:\n{}\n[...]{}".format(
            len(data),
            data[:120],
            data[-120:],
        ))

        print(u"Creating a circuit")
        state = await tor.create_state()
        circ = await state.build_circuit()
        await circ.when_built()
        print(u"  path: {}".format(" -> ".join([r.ip for r in circ.path])))

        print(u"Downloading meejah's public key via above circuit...")
        config = await tor.get_config()
        resp = await treq.get(
            u'https://meejah.ca/meejah.asc',
            agent=circ.web_agent(reactor, config.socks_endpoint(reactor)),
        )
        data = await resp.text()
        print(data)

    @react
    def _main(reactor):
        return ensureDeferred(main(reactor))

## Testimonials

- @thegrugq: “Holy fucking shit, the awesomeness of this project cannot be denied!” (July 2013)

## Known Users

- magic-wormhole “get things from one computer to another, safely”

- Tahoe-LAFS a Free and Open encrypted distributed storage system

- Crossbar.io a Free and Open distributed-systems (RPC and PubSub) protocol (called WAMP) router. Supports e2e-encrypted payloads.

- txtorcon received a brief mention at 29C3 starting at 12:20 (or via youtube).

- carml command-line utilities for Tor

- foolscap RPC system inspired by Twisted’s built-in “Perspective Broker” package.

- bwscanner next-gen bandwidth scanner for Tor network

- unmessage Privacy enhanced instant messenger

- GlobaLeaks Free and open source software enabling anyone to easily set up and maintain a secure whistleblowing platform

- OONI the Open Observatory of Network Interference

- exitaddr scan Tor exit addresses

- txtorhttpproxy simple HTTP proxy in Twisted

- bulb Web-based Tor status monitor

- onionvpn “ipv6 to onion service virtual public network adapter”

- torperf2 new Tor node network performance measurement service

- torweb web-based Tor controller/monitor

- potator “A Tor-based Decentralized Virtual Private Network Application”

- JoinMarket Bitcoin CoinJoin (privacy technique) implementation with incentive structure to convince people to take part