GithubHelp home page GithubHelp logo

meejah / txtorcon Goto Github PK

View Code? Open in Web Editor NEW
247.0 27.0 71.0 3.84 MB

Twisted-based asynchronous Tor control protocol implementation. Includes unit-tests, examples, state-tracking code and configuration abstraction.

Home Page: http://fjblvrw2jrxnhtg67qpbzi45r7ofojaoo3orzykesly2j3c2m3htapid.onion/

License: MIT License

Makefile 0.49% Python 99.26% Shell 0.17% Dockerfile 0.09%
python twisted tor async-programming async privacy

txtorcon's Introduction

github-actions coveralls codecov ReadTheDocs ReadTheDocs

txtorcon

Ten Thousand Feet

txtorcon is an implementation of the control-spec for Tor using the Twisted networking library for Python.

This is useful for writing utilities to control or make use of Tor in event-based Python programs. If your Twisted program supports endpoints (like twistd does) your server or client can make use of Tor immediately, with no code changes. Start your own Tor or connect to one and get live stream, circuit, relay updates; read and change config; monitor events; build circuits; create onion services; etcetera (ReadTheDocs).

Some Possibly Motivational Example Code

download

from twisted.internet.task import react
from twisted.internet.defer import inlineCallbacks, 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))

Try It Now On Debian/Ubuntu

For example, serve some files via an onion service (aka hidden service):

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

Read More

All the documentation starts in docs/index.rst. Also hosted at txtorcon.rtfd.org.

You'll want to start with the introductions (hosted at RTD).

txtorcon's People

Contributors

aagbsn avatar arlolra avatar david415 avatar decentral1se avatar eayin2 avatar enriquefynn avatar evilaliv3 avatar exarkun avatar felipedau avatar gdrosos avatar glowatsk avatar hellais avatar hlieberman avatar isislovecruft avatar itamarst avatar jelly avatar jiivan avatar kalikaneko avatar kneufeld avatar kristapsk avatar lukaslueg avatar meejah avatar mmaker avatar pythonspeed avatar rodrigc avatar ryman avatar sambuddhabasu avatar tirkarthi avatar warner avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

txtorcon's Issues

track all flags in "stream.flags"?

As mentioned in Issue #18 it might be correct to simply keep the union of all received flags on a stream in a "stream.flags" hashtable. This would allow anyone with the stream reference to see the latest flags, without (necessarily) having to listen to stream or circuit events.

It's not 100% clear to me from the control-spec, but it seems that the correct state of the stream is reflected by the union of all received flags for events on the stream.

require psutil

Stop waffling with psutil and make it a requirement. Simplify tests.

example: pygame

Note to self: Distill one of my proof-of-concept pygame things into a minimal example illustrating pygame and twisted/txtorcon integration.

NS event parsing incorrect

With the re-factored state-machine incremental parsing of router descriptors, the NS events are broken because they don't contain a throwaway line first. Remove the first-line thing from the statemachine and throw it away for the initial status update.

.pyc files in 0.10.0

Lunar reports there's a few .pyc files in the _themes/alabaster area in the 0.10.0 release; should ignore in MANIFEST.in

reconnect

If our connection to Tor is dropped, at least TorState should reconnect. Might need additional hooks in TorControlProtocol to allow this to work easily.

Microdescriptor parsing (expecting `s', but receiving `a')?

Running the included launch_tor.py script yields:

$ python launch_tor.py 
10%: Finishing handshake with directory server
15%: Establishing an encrypted directory connection
20%: Asking for networkstatus consensus
25%: Loading networkstatus consensus
40%: Loading authority key certs
45%: Asking for relay descriptors
50%: Loading relay descriptors
53%: Loading relay descriptors
56%: Loading relay descriptors
59%: Loading relay descriptors
63%: Loading relay descriptors
66%: Loading relay descriptors
69%: Loading relay descriptors
73%: Loading relay descriptors
76%: Loading relay descriptors
76%: Loading relay descriptors
80%: Connecting to the Tor network
85%: Finishing handshake with first hop
90%: Establishing a Tor circuit
100%: Done
setup complete: <txtorcon.torconfig.TorProcessProtocol instance at 0x2902dd0>
Building a TorState
Unhandled Error
Traceback (most recent call last):
  File "/usr/lib64/python2.7/site-packages/twisted/python/log.py", line 84, in callWithLogger
    return callWithContext({"system": lp}, func, *args, **kw)
  File "/usr/lib64/python2.7/site-packages/twisted/python/log.py", line 69, in callWithContext
    return context.call({ILogContext: newCtx}, func, *args, **kw)
  File "/usr/lib64/python2.7/site-packages/twisted/python/context.py", line 118, in callWithContext
    return self.currentContext().callWithContext(ctx, func, *args, **kw)
  File "/usr/lib64/python2.7/site-packages/twisted/python/context.py", line 81, in callWithContext
    return func(*args,**kw)
--- <exception caught here> ---
  File "/usr/lib64/python2.7/site-packages/twisted/internet/posixbase.py", line 614, in _doReadOrWrite
    why = selectable.doRead()
  File "/usr/lib64/python2.7/site-packages/twisted/internet/tcp.py", line 203, in doRead
    return self._dataReceived(data)
  File "/usr/lib64/python2.7/site-packages/twisted/internet/tcp.py", line 209, in _dataReceived
    rval = self.protocol.dataReceived(data)
  File "/usr/lib64/python2.7/site-packages/twisted/internet/endpoints.py", line 86, in dataReceived
    return self._wrappedProtocol.dataReceived(data)
  File "/usr/lib64/python2.7/site-packages/twisted/protocols/basic.py", line 455, in dataReceived
    self.lineReceived(line)
  File "/usr/lib/python2.7/site-packages/txtorcon-0.7-py2.7.egg/txtorcon/torcontrolprotocol.py", line 492, in lineReceived
    self.fsm.process(line)
  File "/usr/lib/python2.7/site-packages/txtorcon-0.7-py2.7.egg/txtorcon/spaghetti.py", line 28, in process
    next_state = self.state.process(data)
  File "/usr/lib/python2.7/site-packages/txtorcon-0.7-py2.7.egg/txtorcon/spaghetti.py", line 57, in process
    r = t.process(data)
  File "/usr/lib/python2.7/site-packages/txtorcon-0.7-py2.7.egg/txtorcon/spaghetti.py", line 127, in process
    return self.handle(data)
  File "/usr/lib/python2.7/site-packages/txtorcon-0.7-py2.7.egg/txtorcon/spaghetti.py", line 116, in handle
    state = self.handler(data)
  File "/usr/lib/python2.7/site-packages/txtorcon-0.7-py2.7.egg/txtorcon/torcontrolprotocol.py", line 706, in _accumulate_multi_response
    self.command[2](line)
  File "/usr/lib/python2.7/site-packages/txtorcon-0.7-py2.7.egg/txtorcon/spaghetti.py", line 28, in process
    next_state = self.state.process(data)
  File "/usr/lib/python2.7/site-packages/txtorcon-0.7-py2.7.egg/txtorcon/spaghetti.py", line 57, in process
    r = t.process(data)
  File "/usr/lib/python2.7/site-packages/txtorcon-0.7-py2.7.egg/txtorcon/spaghetti.py", line 127, in process
    return self.handle(data)
  File "/usr/lib/python2.7/site-packages/txtorcon-0.7-py2.7.egg/txtorcon/spaghetti.py", line 116, in handle
    state = self.handler(data)
  File "/usr/lib/python2.7/site-packages/txtorcon-0.7-py2.7.egg/txtorcon/torstate.py", line 194, in __call__
    raise RuntimeError(self.msg % tuple(args))
exceptions.RuntimeError: Expected "s " while parsing routers not "a [x:x:x:x::x]:x"

where x is a placeholder.

example: pyglet

Note to self: take my existing pyglet things which use txtorcon and make a minimal example that illustrates how to integrate with Twisted and the event-based core of pyglet.

Refactor build_tor_connection

It was discussed to give torstate.build_tor_connection() some refactoring in order to prevent crufty code in clients.

Consider build_tor_connection() accepting various objects as first parameter:

  • Any instance of twisted.internet.endpoints
  • A tuple of (reactor:host:port) from which build_tor_connection() builds a new TCP4ClientEndpoint
  • A tuple of (reactor:path) from which build_tor_connection() builds a new UNIXClientEndpoint

Also consider a new function torstate.build_local_tor_connection() which will try to connect via socket first and by tcp if the control socket is not there.

The argument 'endpoint' in build_tor_connection() is changed to 'connection' to reflect the change.

def build_tor_connection(connection, build_state=True, password=None):
    if isinstance(connection, twisted.internet.endpoints.yaddayadda):
        endpoint = connection
    elif isinstance(connection, tuple):
        if len(connection) == 2:
            reactor, socket = connection
            if os.stat(socket).st_mode & (stat.S_IRGRP | stat.S_IRUSR | stat.S_IROTH):
                endpoint = UNIXClientEndpoint(reactor, socket)
            else:
                raise ValueError("Can't use '%s' as a socket" % (socket, ))
        elif len(connection) == 3:
            endpoint = TCP4ClientEndpoint(*connection)
        else:
            raise ValueError("Expected either a (reactor, socket)- or a (reactor, host, port)-tuple for argument 'connection'")
    else:
        raise ValueError("Expected instance from twisted.internet.endpoints or tuple for argument 'connection'")
    d = endpoint.connect(TorProtocolFactory(password=password))
    if build_state:
        d.addCallback(_build_state)
    else:
        d.addCallback(_wait_for_proto)
    return d


def build_local_tor_connection(reactor, host='127.0.0.1', port=9051, socket='/var/run/tor/control', **args):
    if os.path.exists(socket):
        try:
            return build_tor_connection((reactor, socket), **args)
        except:
            pass
    return build_tor_connection((reactor, host, port), **args)

Any comments?

app idea: publish documents

Expand the launch_tor_endpoint example into apps/torpublish which will publish a collection of documents at a hidden service endpoint. Should include robust command-line handling, simple instructions, etcetera.

Key-handling should be considered -- although a quick publish to a random .onion is okay, most people would likely want the ability to re-launch their service at the same onion address and hence would need to save the private key somewhere.

The existing Twisted Web stuff is probably sufficient for this use-case, although it may be worth exploring Cyclone (the clone of Tornado which uses Twisted's tested async core instead of custom untested stuff) having the advantage of covering another use-case with an example.

tests fail on twisted 12.0.0

Lunar reports:

"test fails with "exceptions.TypeError: _parseClientTCP() takes exactly 0 arguments (2 given)" when run with Twisted 0.12"

So, either we need a fix for Twisted 12 or depend on a higher version.

Debian stable ships Twisted 12.0.0 so it'd be nice to keep dependency >= 12.0.0

Document compatibility

txtorcon's git :head passes all tests and should work just fine both on MacOS 10.8 and Fedora 18. One might update the readme

emacs backups in release tarballs

Lunar noticed that at least 0.8.1 has four backup files (all in examples/) in it. Should figure out why and how to stop this for next release.

launch_tor hangs when ControlPort is set to 0

If you run the following snipped you will see what I mean:

from twisted.internet import reactor
import txtorcon

config = txtorcon.TorConfig()
config.SocksPort = 9999
config.ControlPort = 0

def progress_updates(prog, tag, summary):
    print "%s %s %s" % (prog, tag, summary)

d = txtorcon.launch_tor(config, reactor, progress_updates=progress_updates)
@d.addErrback
def eb(failure):
     print failure
@d.addCallback
def cb(result):
     print result
reactor.run()

I would expect either to see some of the progress updates or some errback being fired message to be triggerred, but instead it just hangs.

Note that if the config.ControlPort = 0 line is commented out it works just fine.

Embed Tor as a python module starting in a python thread to avoid starting a "process"

This ticket is to provide a different approach to start Tor from within txtorcon by using a custom patched Tor version.

The idea is to enable building desktop application with a modern language like HTML5/CSS3 supported by TideSDK that support extending application with Python, including binary modules: http://tidesdk.multipart.net/docs/user-dev/generated/#!/guide/using_python

So, if "Tor process" would be compiled with the minor modifications to be embeddable as a python module (i'd say as a txtorconn module), it would be possible to make desktop application including Tor as a python module extending TideSDK.

The very same approach has been used by CovertBrowser in order to run Tor as a thread on iPhone, because an iPhone application cannot run "multiple executable" .

What do you think?

REMOTE_REASON not supported for circuit failure

As reported by mikeperry the REMOTE_REASON is not passed back to circuit_failed.

Also, in general, we are going to completely fail on any new flags introduced. It might be most-future-proof to store the keyword-args we get in Circuit, and interested code can ask the circuit object itself in circuit_failed (etcetera).

python-ipaddr is not optional

The README lists python-ipaddr as an optional dependency. txtorcon/stream.py however imports ipaddr without any fallback, so trying to use txtorcon without python-ipaddr fails:

Traceback (most recent call last):
  File "/usr/share/txtorcon/examples/dump_config.py", line 18, in 
    from txtorcon import TorProtocolFactory, TorConfig, DEFAULT_VALUE
  File "/usr/lib/python2.7/site-packages/txtorcon/__init__.py", line 13, in 
    from txtorcon.stream import Stream
  File "/usr/lib/python2.7/site-packages/txtorcon/stream.py", line 14, in 
    import ipaddr
ImportError: No module named ipaddr

Problems when running launch tor as root

When doing launch_tor as root I get the following error:

unexpected error in processEnded
Traceback (most recent call last):
File "/home/ooni/.virtualenvs/ooniprobe/lib/python2.6/site-packages/twisted/internet/abstract.py", line 291, in readConnectionLost
self.connectionLost(reason)
File "/home/ooni/.virtualenvs/ooniprobe/lib/python2.6/site-packages/twisted/internet/process.py", line 275, in connectionLost
self.proc.childConnectionLost(self.name, reason)
File "/home/ooni/.virtualenvs/ooniprobe/lib/python2.6/site-packages/twisted/internet/process.py", line 911, in childConnectionLost
self.maybeCallProcessEnded()
File "/home/ooni/.virtualenvs/ooniprobe/lib/python2.6/site-packages/twisted/internet/process.py", line 924, in maybeCallProcessEnded
_BaseProcess.maybeCallProcessEnded(self)
--- ---
File "/home/ooni/.virtualenvs/ooniprobe/lib/python2.6/site-packages/twisted/internet/_baseprocess.py", line 60, in maybeCallProcessEnded
proto.processEnded(Failure(reason))
File "/home/ooni/.virtualenvs/ooniprobe/lib/python2.6/site-packages/txtorcon-0.7-py2.6.egg/txtorcon/torconfig.py", line 322, in processEnded
raise RuntimeError('\n'.join(self.stdout) + "\n\nTor exited with error-code %d" % status.value.exitCode)
exceptions.RuntimeError: Dec 09 05:38:06.295 [notice] Tor v0.2.2.39 (git-2f7e71c2e896772f). This is experimental software. Do not rely on it for strong anonymity. (Running on Linux i686)
Dec 09 05:38:06.296 [notice] Initialized libevent version 1.4.13-stable using method epoll. Good.
Dec 09 05:38:06.296 [notice] Opening Socks listener on 127.0.0.1:5974
Dec 09 05:38:06.296 [notice] Opening Control listener on 127.0.0.1:18445
Dec 09 05:38:06.296 [warn] /tmp/tortmpNJRBUn is not owned by this user (debian-tor, 106) but by root (0). Perhaps you are running Tor as the wrong user?
Dec 09 05:38:06.296 [warn] Failed to parse/validate config: Couldn't access/create private data directory "/tmp/tortmpNJRBUn"
Dec 09 05:38:06.296 [err] Reading config failed--see warnings above.

I believe this has to do with the fact that Tor runs as a reduced privilege user when doing mktmp as root the permissions on these files are set to be root and not of the user under which tor runs.

I am not sure what the most clean solution to this problem is.

File Descriptors

Currently txtorcon opens a couple o files without removing/closing them.

For example, when trying to fetch the .onion username, it uses a raw open, while a with statement should be used, also for preventing errors.
Another more important bug concerning file descriptors left open, is the file for logging opened here[0] which writes a file in the current directory without letting the user configure the debug.

I would propose to use standard twisted.python.log for logging events, and use the with statement on hiddenservice's getattr.
If that's ok for @meejah I would start wrtiting a patch :)

[0] https://github.com/mmaker/txtorcon/blob/master/txtorcon/torcontrolprotocol.py#L165

strip OK lines?

Should all OK lines be simply stripped from responses before being give to, e.g. TorState code (and other client code)? It seems like overall this would be a win for simplicity.

get_info not behaving always

It seems if two getinfo keys are listed in the same request, and they're both multiline responses, something gets confused (e.g. try two ns/name/blah keys in one get_info).

Broken README link kills setup.py install?

Not sure if that's the true root of the problem or not.

vagrant@precise32:~/txtorcon$ python setup.py install
Traceback (most recent call last):
File "setup.py", line 36, in
long_description = open('README','r').read(),
IOError: [Errno 2] No such file or directory: 'README'

Tested in FreeBSD

I tested in freeBSD 10, and txtorcon passes all tests
(probably works in older versions of FreeBSD and other BSDs)
Info:
-I had to install "lsof"

torcontrolprotocol && GETINFO command

I have a problem while parsing the result of a "GETINFO status/bootstrap-phase"

The code:
apaf.torctl.get_info(sp_keyword).addCallback( lambda infos: self.finish(json_encode(infos)))

Tor returns:
status/bootstrap-phase=NOTICE BOOTSTRAP PROGRESS=100 TAG=done SUMMARY="Done"

The exception

    --- <exception caught here> ---
      File "/Library/Python/2.7/site-packages/twisted/internet/defer.py", line 551, in _runCallbacks
        current.result = callback(current.result, *args, **kw)
      File "......virtualenv/lib/python2.7/site-packages/txtorcon-0.2-py2.7.egg/txtorcon/torcontrolprotocol.py", line 128, in parse_keywords
        (key, value) = line.split('=')
    exceptions.ValueError: too many values to unpack

The patch: 26c4636

Some hiddenServiceDirs don't make sense when passed directly through to the Tor configuration.

I've found a few cases where hiddenServiceDir being passed through to the underlying tor configuration causes a violent crash with very few clues as to what the problem is.

An example with a ~/ path:

↪︎ twistd -n web --port "onion:80:hiddenServiceDir=~/hs" --path ~/Public
2014-06-16 12:19:04-0700 [-] Log opened.
2014-06-16 12:19:04-0700 [-] twistd 14.0.0 (/Users/dreid/.virtualenvs/tempenv-15f922967276f/bin/python 2.7.5) starting up.
2014-06-16 12:19:04-0700 [-] reactor class: twisted.internet.selectreactor.SelectReactor.
2014-06-16 12:19:04-0700 [-] (TCP Port 65116 Closed)
2014-06-16 12:19:04-0700 [-] Config was unsaved when launch_tor() called; calling save().
2014-06-16 12:19:04-0700 [-] Spawning tor process with DataDirectory /var/folders/fb/bfn8yfln3_d_3bb8r1h_yhkc0000gn/T/tortmpcJpG5f
2014-06-16 12:19:06-0700 [TorControlProtocol,client] 10% Finishing handshake with directory server
2014-06-16 12:19:06-0700 [TorControlProtocol,client] 15% Establishing an encrypted directory connection
2014-06-16 12:19:07-0700 [TorControlProtocol,client] 20% Asking for networkstatus consensus
2014-06-16 12:19:07-0700 [TorControlProtocol,client] 25% Loading networkstatus consensus
2014-06-16 12:19:11-0700 [TorControlProtocol,client] 40% Loading authority key certs
2014-06-16 12:19:11-0700 [TorControlProtocol,client] 45% Asking for relay descriptors
2014-06-16 12:19:13-0700 [TorControlProtocol,client] 50% Loading relay descriptors
2014-06-16 12:19:13-0700 [TorControlProtocol,client] 51% Loading relay descriptors
2014-06-16 12:19:13-0700 [TorControlProtocol,client] 53% Loading relay descriptors
2014-06-16 12:19:13-0700 [TorControlProtocol,client] 55% Loading relay descriptors
2014-06-16 12:19:13-0700 [TorControlProtocol,client] 57% Loading relay descriptors
2014-06-16 12:19:13-0700 [TorControlProtocol,client] 59% Loading relay descriptors
2014-06-16 12:19:14-0700 [TorControlProtocol,client] 61% Loading relay descriptors
2014-06-16 12:19:14-0700 [TorControlProtocol,client] 63% Loading relay descriptors
2014-06-16 12:19:14-0700 [TorControlProtocol,client] 64% Loading relay descriptors
2014-06-16 12:19:14-0700 [TorControlProtocol,client] 66% Loading relay descriptors
2014-06-16 12:19:14-0700 [TorControlProtocol,client] 68% Loading relay descriptors
2014-06-16 12:19:14-0700 [TorControlProtocol,client] 70% Loading relay descriptors
2014-06-16 12:19:14-0700 [TorControlProtocol,client] 72% Loading relay descriptors
2014-06-16 12:19:14-0700 [TorControlProtocol,client] 74% Loading relay descriptors
2014-06-16 12:19:14-0700 [TorControlProtocol,client] 76% Loading relay descriptors
2014-06-16 12:19:14-0700 [TorControlProtocol,client] 78% Loading relay descriptors
2014-06-16 12:19:19-0700 [TorControlProtocol,client] 80% Connecting to the Tor network
2014-06-16 12:19:19-0700 [TorControlProtocol,client] 90% Establishing a Tor circuit
2014-06-16 12:19:20-0700 [TorControlProtocol,client] 100% Done
2014-06-16 12:19:20-0700 [TorControlProtocol,client] Site starting on 65123
2014-06-16 12:19:20-0700 [TorControlProtocol,client] Starting factory <twisted.web.server.Site instance at 0x10cc06128>
2014-06-16 12:19:20-0700 [-] unexpected error in processEnded
    Traceback (most recent call last):
      File "/Users/dreid/.virtualenvs/tempenv-15f922967276f/lib/python2.7/site-packages/twisted/internet/process.py", line 910, in maybeCallProcessEnded
        self.reapProcess()
      File "/Users/dreid/.virtualenvs/tempenv-15f922967276f/lib/python2.7/site-packages/twisted/internet/process.py", line 312, in reapProcess
        self.processEnded(status)
      File "/Users/dreid/.virtualenvs/tempenv-15f922967276f/lib/python2.7/site-packages/twisted/internet/_baseprocess.py", line 51, in processEnded
        self.maybeCallProcessEnded()
      File "/Users/dreid/.virtualenvs/tempenv-15f922967276f/lib/python2.7/site-packages/twisted/internet/process.py", line 912, in maybeCallProcessEnded
        _BaseProcess.maybeCallProcessEnded(self)
    --- <exception caught here> ---
      File "/Users/dreid/.virtualenvs/tempenv-15f922967276f/lib/python2.7/site-packages/twisted/internet/_baseprocess.py", line 63, in maybeCallProcessEnded
        proto.processEnded(Failure(reason))
      File "/Users/dreid/.virtualenvs/tempenv-15f922967276f/lib/python2.7/site-packages/txtorcon/torconfig.py", line 179, in processEnded
        self.connected_cb.errback(err)
      File "/Users/dreid/.virtualenvs/tempenv-15f922967276f/lib/python2.7/site-packages/twisted/internet/defer.py", line 423, in errback
        self._startRunCallbacks(fail)
      File "/Users/dreid/.virtualenvs/tempenv-15f922967276f/lib/python2.7/site-packages/twisted/internet/defer.py", line 483, in _startRunCallbacks
        raise AlreadyCalledError
    twisted.internet.defer.AlreadyCalledError:  

I assume this is because the value is passed directly through to the tor configuration file and Tor doesn't know how to expand these paths.

Other things that fail are relative paths with more than one segment: foo/bar.

Relative paths with one segment fail in a slightly different way:

↪︎ twistd -n web --port "onion:80:hiddenServiceDir=foo" --path ~/Public
2014-06-16 12:27:32-0700 [-] Log opened.
2014-06-16 12:27:32-0700 [-] twistd 14.0.0 (/Users/dreid/.virtualenvs/tempenv-15f922967276f/bin/python 2.7.5) starting up.
2014-06-16 12:27:32-0700 [-] reactor class: twisted.internet.selectreactor.SelectReactor.
2014-06-16 12:27:32-0700 [-] (TCP Port 65208 Closed)
2014-06-16 12:27:32-0700 [-] Config was unsaved when launch_tor() called; calling save().
2014-06-16 12:27:32-0700 [-] Spawning tor process with DataDirectory /var/folders/fb/bfn8yfln3_d_3bb8r1h_yhkc0000gn/T/tortmp3brmZ8
2014-06-16 12:27:33-0700 [TorControlProtocol,client] 10% Finishing handshake with directory server
2014-06-16 12:27:37-0700 [TorControlProtocol,client] 15% Establishing an encrypted directory connection
2014-06-16 12:27:38-0700 [TorControlProtocol,client] 20% Asking for networkstatus consensus
2014-06-16 12:27:38-0700 [TorControlProtocol,client] 25% Loading networkstatus consensus
2014-06-16 12:27:48-0700 [TorControlProtocol,client] 40% Loading authority key certs
2014-06-16 12:27:49-0700 [TorControlProtocol,client] 45% Asking for relay descriptors
2014-06-16 12:27:50-0700 [TorControlProtocol,client] 50% Loading relay descriptors
2014-06-16 12:27:50-0700 [TorControlProtocol,client] 51% Loading relay descriptors
2014-06-16 12:27:50-0700 [TorControlProtocol,client] 53% Loading relay descriptors
2014-06-16 12:27:50-0700 [TorControlProtocol,client] 55% Loading relay descriptors
2014-06-16 12:27:51-0700 [TorControlProtocol,client] 57% Loading relay descriptors
2014-06-16 12:27:51-0700 [TorControlProtocol,client] 59% Loading relay descriptors
2014-06-16 12:27:51-0700 [TorControlProtocol,client] 61% Loading relay descriptors
2014-06-16 12:27:51-0700 [TorControlProtocol,client] 63% Loading relay descriptors
2014-06-16 12:27:51-0700 [TorControlProtocol,client] 65% Loading relay descriptors
2014-06-16 12:27:51-0700 [TorControlProtocol,client] 67% Loading relay descriptors
2014-06-16 12:27:51-0700 [TorControlProtocol,client] 68% Loading relay descriptors
2014-06-16 12:27:51-0700 [TorControlProtocol,client] 70% Loading relay descriptors
2014-06-16 12:27:51-0700 [TorControlProtocol,client] 72% Loading relay descriptors
2014-06-16 12:27:51-0700 [TorControlProtocol,client] 74% Loading relay descriptors
2014-06-16 12:27:51-0700 [TorControlProtocol,client] 76% Loading relay descriptors
2014-06-16 12:27:51-0700 [TorControlProtocol,client] 78% Loading relay descriptors
2014-06-16 12:27:56-0700 [TorControlProtocol,client] 80% Connecting to the Tor network
2014-06-16 12:27:56-0700 [TorControlProtocol,client] 90% Establishing a Tor circuit
2014-06-16 12:27:57-0700 [TorControlProtocol,client] 100% Done
2014-06-16 12:27:57-0700 [TorControlProtocol,client] Site starting on 65219
2014-06-16 12:27:57-0700 [TorControlProtocol,client] Starting factory <twisted.web.server.Site instance at 0x1012c0128>
2014-06-16 12:27:57-0700 [TorControlProtocol,client] Started hidden service "None" on port 80
2014-06-16 12:27:57-0700 [TorControlProtocol,client] Keys are in "foo".

This causes a directory foo to be created under the DataDirectory, which is a valid hidden service directory unfortunately txtorcon no longer knows about it and can't display the hostname in the output. Also it now gets destroyed when the reactor is shut down, which seems to defeat the purpose of specifying your own hiddenServiceDir.

It'd be nice if txtorcon could resolve relative and ~ paths.

launch_tor should use TorConfig.ControlPort if available

see the "bridget" plugin in OONI -- it might be nicer if launch_tor at least checked if ControlPort was specified in the config its given. Probably even better to have one way to configure the control port (i.e. via the config) and default to 9051 if it isn't specified in there.

Support more endpoint goodness

Using the Twisted endpoint plugin APIs, I should be able to support a "tor:" endpoint-string to set up client or server endpoints that route via Tor.

Probably should discuss on twisted lists to increase the chances of creating something useful ;)

pip install txtorcon doesn't work

< maker> meejah: why $ pip search txtorcon shows me the correct result, but $ pip install txtorcon gives me a "could not find ...." message?

Improve support for getting stderr and stdout output of tor

Currently it is not simple to obtain the stdout and stderr output of tor when invoking it via launch_tor. This is because if tor does not reach 100% bootstrap then the deferred returned by launch_tor() does not fire and it is not possible to access the TorProcessProtocol.

It would be very useful to have a way of logging all stdout and stderr output even if no errback is triggered.

Tor-binary not always in /usr/sbin/

torconfig.launch_tor() has a default tor-binary-path of "/usr/sbin/tor". Is this where debian stores the tor-executable? It's in /usr/bin/ on Fedora (where it belongs IMHO).

It should be save to just call 'tor' without any path and let the OS decide what to do.

Support "setup.py develop"

As per a comment in #56 it would be nice to support "python setup.py develop" for in-place install.

Note that you can just do "export PYTHONPATH=." however that's not quite the same.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.