I just wrote a little program called OnionShare, that makes it simple to share a file securely using a password-protected Tor hidden service: https://github.com/micahflee/onionshare
Right now it only runs in Tails. I'd like to make a versin that runs in OSX and Windows, too. How can I make software for OSX and Windows that relies on Tor like this, but without having to bundle Tor with it? I would really like to not be in the business of distributing Tor myself.
When you run onionshare.py, it modifies /etc/tor/torrc and reloads the Tor config, and when it's done it restores the original torrc and reloads again.
I could require people to open Tor Browser and have it just use the Tor that comes with that, except the fact that it needs to modify torrc makes that complicated.
Micah Lee micah@micahflee.com writes:
When you run onionshare.py, it modifies /etc/tor/torrc and reloads the Tor config, and when it's done it restores the original torrc and reloads again.
You could use one of the controller libraries (stem if you want synchronous, txtorcon if async/Twisted) to do this; they don't have to modify the torrc directly, just manipulate configuration via GETCONF and SETCONF. For Tails, this probably won't work unless you're root until #11291 is fixed + merged.
Even better, with some work that David Stainton has been pushing forward in txtorcon [1] for use with Tahoe-LAFS, very soon making "whatever stuff" happen so you can cause a new hidden service to appear will be one line (serverFromString is a pluggable Twisted endpoint API):
d = serverFromString("onion:80").listen(...)
or, if you already have keys:
d = serverFromString("onion:80:hiddenServiceDir=/foo/bar").listen(...)
The "stuff" will depend, but will be a newly launched tor worst-case or a suitable local tor best-case. I realize this doesn't help you right away ;) but there are APIs to make this pretty straightforward with txtorcon right now; see these lines for an example:
https://github.com/meejah/txtorcon/blob/master/examples/launch_tor_with_hidd...
In the above save() will write to a file if you want, or to a currently-connecting running Tor. txtorcon concentrates on configuring running Tor instances; there may be better torrc-manipulation things in Stem but I don't know off the top of my head.
(For the other way, David has a pull-request into txsocksx so that things like "clientFromString('tor:blarg.onion')" will work via SOCKS to 9050 or 9150).
[1] -- gruesome details of his latest branch here, and there are some relevant ones in my repository as well: https://github.com/david415/txtorcon/compare/meejah:master...endpoint_parser...
You could use one of the controller libraries (stem if you want synchronous, txtorcon if async/Twisted) to do this; they don't have to modify the torrc directly, just manipulate configuration via GETCONF and SETCONF. For Tails, this probably won't work unless you're root until #11291 is fixed + merged.
I'm not saying that this would be appropriate for your python app... but there are definitely ways for Twisted to interoperate with blocking APIs. Laurens Van Houtven gave a pretty good talk about this at PyCon 2014: https://www.youtube.com/watch?v=A_NnHC2LcaE
d = serverFromString("onion:80:hiddenServiceDir=/foo/bar").listen(...)
This Twisted endpoints plugin system allows us to keep our Twisted apps endpoint agnostic... but requires that the appropriate Twisted endpoint parser is installed.
Tahoe-LAFS in particular gets a big win from this native Tor integration because Foolscap (the wire protocol library used) gets to be endpoint agnostic while Tahoe-LAFS can take care of some Tor specific features.
(For the other way, David has a pull-request into txsocksx so that things like "clientFromString('tor:blarg.onion')" will work via SOCKS to 9050 or 9150).
In my latest branch I wrote a DeferredDispatcher class ( which will be replaced by core Twisted api once twisted trac ticket #6365 is resolved: https://twistedmatrix.com/trac/ticket/6365 ). which can be used to coordinate multiple Tor client and server Twisted endpoints with a single Tor process (per python process). Work in progress in this branch here:
https://github.com/david415/txsocksx/tree/tor_deferred_dispatcher
Here's an example program that uses Tor client and server endpoints. It sets up a simple webserver listening to the hidden service endpoint, retrieves the new onion and then uses the Tor client endpoint to connect and query the webserver.
https://github.com/david415/txsocksx/blob/tor_deferred_dispatcher/examples/t...
Eventually (soon maybe?) I'm going to write extensive documentation and example code for assisting Python developers to write apps with native Tor integration and Tor-friendly features. The native Tor integration for Tahoe-LAFS will serve as an excellent example case.
Cheers!
David
Thanks, this is really helpful.
On 05/20/14 21:10, meejah wrote:
Micah Lee micah@micahflee.com writes:
When you run onionshare.py, it modifies /etc/tor/torrc and reloads the Tor config, and when it's done it restores the original torrc and reloads again.
You could use one of the controller libraries (stem if you want synchronous, txtorcon if async/Twisted) to do this; they don't have to modify the torrc directly, just manipulate configuration via GETCONF and SETCONF. For Tails, this probably won't work unless you're root until #11291 is fixed + merged.
Even better, with some work that David Stainton has been pushing forward in txtorcon [1] for use with Tahoe-LAFS, very soon making "whatever stuff" happen so you can cause a new hidden service to appear will be one line (serverFromString is a pluggable Twisted endpoint API):
d = serverFromString("onion:80").listen(...)
or, if you already have keys:
d = serverFromString("onion:80:hiddenServiceDir=/foo/bar").listen(...)
The "stuff" will depend, but will be a newly launched tor worst-case or a suitable local tor best-case. I realize this doesn't help you right away ;) but there are APIs to make this pretty straightforward with txtorcon right now; see these lines for an example:
https://github.com/meejah/txtorcon/blob/master/examples/launch_tor_with_hidd...
In the above save() will write to a file if you want, or to a currently-connecting running Tor. txtorcon concentrates on configuring running Tor instances; there may be better torrc-manipulation things in Stem but I don't know off the top of my head.
(For the other way, David has a pull-request into txsocksx so that things like "clientFromString('tor:blarg.onion')" will work via SOCKS to 9050 or 9150).
[1] -- gruesome details of his latest branch here, and there are some relevant ones in my repository as well: https://github.com/david415/txtorcon/compare/meejah:master...endpoint_parser...
On Tue, May 20, 2014 at 8:38 PM, Micah Lee micah@micahflee.com wrote:
I just wrote a little program called OnionShare, that makes it simple to share a file securely using a password-protected Tor hidden service: https://github.com/micahflee/onionshare
Seeing the examples on that page, why you're not simply making the GET /hash in the url be the hash of the file itself. If not behind a location anon system it may help hide in a tiny way. But we are anon, so making easier for the requestor to not download the same hash as is already on their filesystem again, perhaps they got from elsewhere, etc, would make more sense. A bunch of people all sharing different apparent hash links (to the same thing they all host), on say IRC mob, seems wasteful and/or confusing. Even if presented filename index is the same. It would avoid needing to load that.
Or you are trying to give a one-time unique hash to a user, but then the server should instead shut down after the first DL to ensure [1] this. [1] only so far as you really know what that user/system does with the link after you give it out, leave keyboard, etc.
So probably some options and new defaults to add.