[Pkg-privacy-commits] [onionshare] 09/53: Moved hidden service login into separate file. Prefer to use ephemeral hidden services now if they are available. Ephermal does not yet work, but old hidservdir still works.
Ulrike Uhlig
u-guest at moszumanska.debian.org
Wed Dec 30 00:20:10 UTC 2015
This is an automated email from the git hooks/post-receive script.
u-guest pushed a commit to branch debian
in repository onionshare.
commit eba6dbb84339136bababb20b8d36f27f99671ddf
Author: Micah Lee <micah at micahflee.com>
Date: Mon Sep 7 22:34:54 2015 -0700
Moved hidden service login into separate file. Prefer to use ephemeral hidden services now if they are available. Ephermal does not yet work, but old hidservdir still works.
---
locale/en.json | 3 +-
onionshare/hs.py | 140 +++++++++++++++++++++++++++++++++++++++++++++++
onionshare/onionshare.py | 134 +++++++++------------------------------------
3 files changed, 169 insertions(+), 108 deletions(-)
diff --git a/locale/en.json b/locale/en.json
index bd3d29c..164a784 100644
--- a/locale/en.json
+++ b/locale/en.json
@@ -43,5 +43,6 @@
"gui_starting_server3": "Waiting for Tor hidden service...",
"gui_please_wait": "Please wait...",
"error_hs_dir_cannot_create": "Cannot create hidden service dir {0:s}",
- "error_hs_dir_not_writable": "Hidden service dir {0:s} is not writable"
+ "error_hs_dir_not_writable": "Hidden service dir {0:s} is not writable",
+ "using_ephemeral": "Using ephemeral Tor hidden service"
}
diff --git a/onionshare/hs.py b/onionshare/hs.py
new file mode 100644
index 0000000..fd28b64
--- /dev/null
+++ b/onionshare/hs.py
@@ -0,0 +1,140 @@
+# -*- coding: utf-8 -*-
+"""
+OnionShare | https://onionshare.org/
+
+Copyright (C) 2015 Micah Lee <micah at micahflee.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""
+
+from stem.control import Controller
+import os, tempfile, shutil
+
+import helpers, strings
+
+class NoTor(Exception):
+ pass
+
+class HSDirError(Exception):
+ pass
+
+class HS(object):
+ def __init__(self, transparent_torification=False):
+ self.transparent_torification = transparent_torification
+
+ # files and dirs to delete on shutdown
+ self.cleanup_filenames = []
+
+ # connect to the tor controlport
+ self.c = None
+ ports = [9051, 9151]
+ for port in ports:
+ try:
+ self.c = Controller.from_port(port=port)
+ self.c.authenticate()
+ break
+ except:
+ pass
+ if not self.c:
+ raise NoTor(strings._("cant_connect_ctrlport").format(ports))
+
+ # do the versions of stem and tor that I'm using support ephemeral hidden services?
+ tor_version = self.c.get_version().version_str
+ list_ephemeral_hidden_services = getattr(self.c, "list_ephemeral_hidden_services", None)
+ self.supports_ephemeral = callable(list_ephemeral_hidden_services) and tor_version >= '0.2.7.1'
+
+ def start(self, port):
+ if self.supports_ephemeral:
+ print strings._('using_ephemeral')
+ res = self.c.create_ephemeral_hidden_service(port)
+ onion_host = res.content()[0][2].split('=')[1] + '.onion'
+ return onion_host
+
+ else:
+ # come up with a hidden service directory name
+ if helpers.get_platform() == 'Windows':
+ path = '{0:s}/onionshare'.format(os.environ['Temp'].replace('\\', '/'))
+ else:
+ path = '/tmp/onionshare'
+
+ try:
+ if not os.path.exists(path):
+ os.makedirs(path, 0700)
+ except:
+ raise HSDirError(strings._("error_hs_dir_cannot_create").format(path))
+ if not os.access(path, os.W_OK):
+ raise HSDirError(strings._("error_hs_dir_not_writable").format(path))
+
+ hidserv_dir = tempfile.mkdtemp(dir=path)
+ self.cleanup_filenames.append(hidserv_dir)
+
+ # set up hidden service
+ hsdic = self.c.get_conf_map('HiddenServiceOptions') or {
+ 'HiddenServiceDir': [], 'HiddenServicePort': []
+ }
+ if hidserv_dir in hsdic.get('HiddenServiceDir', []):
+ # Maybe a stale service with the wrong local port
+ dropme = hsdic['HiddenServiceDir'].index(hidserv_dir)
+ del hsdic['HiddenServiceDir'][dropme]
+ del hsdic['HiddenServicePort'][dropme]
+ hsdic['HiddenServiceDir'] = hsdic.get('HiddenServiceDir', [])+[hidserv_dir]
+ hsdic['HiddenServicePort'] = hsdic.get('HiddenServicePort', [])+[
+ '80 127.0.0.1:{0:d}'.format(port)]
+
+ self.c.set_options(self._hsdic2list(hsdic))
+
+ # figure out the .onion hostname
+ hostname_file = '{0:s}/hostname'.format(hidserv_dir)
+ onion_host = open(hostname_file, 'r').read().strip()
+ return onion_host
+
+ def cleanup(self):
+ if self.supports_ephemeral:
+ # todo: cleanup the ephemeral hidden service
+ pass
+ else:
+ # cleanup hidden service
+ try:
+ if self.controller:
+ # Get fresh hidden services (maybe changed since last time)
+ # and remove ourselves
+ hsdic = self.controller.get_conf_map('HiddenServiceOptions') or {
+ 'HiddenServiceDir': [], 'HiddenServicePort': []
+ }
+ if self.hidserv_dir and self.hidserv_dir in hsdic.get('HiddenServiceDir', []):
+ dropme = hsdic['HiddenServiceDir'].index(self.hidserv_dir)
+ del hsdic['HiddenServiceDir'][dropme]
+ del hsdic['HiddenServicePort'][dropme]
+ self.controller.set_options(self._hsdic2list(hsdic))
+ # Politely close the controller
+ self.controller.close()
+ except:
+ pass
+
+ # cleanup files
+ for filename in self.cleanup_filenames:
+ if os.path.isfile(filename):
+ os.remove(filename)
+ elif os.path.isdir(filename):
+ shutil.rmtree(filename)
+ self.cleanup_filenames = []
+
+ def _hsdic2list(self, dic):
+ """Convert what we get from get_conf_map to what we need for set_options"""
+ return [
+ pair for pairs in [
+ [('HiddenServiceDir', vals[0]), ('HiddenServicePort', vals[1])]
+ for vals in zip(dic.get('HiddenServiceDir', []), dic.get('HiddenServicePort', []))
+ ] for pair in pairs
+ ]
diff --git a/onionshare/onionshare.py b/onionshare/onionshare.py
index cf1bbce..34e57b4 100644
--- a/onionshare/onionshare.py
+++ b/onionshare/onionshare.py
@@ -17,38 +17,20 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
-import os, sys, subprocess, time, argparse, inspect, shutil, socket, threading, urllib2, httplib, tempfile
+import os, sys, subprocess, time, argparse, inspect, shutil, socket, threading, urllib2, httplib
import socks
-from stem.control import Controller
-
-import strings, helpers, web
-
-
-class NoTor(Exception):
- pass
-
-
-class HSDirError(Exception):
- pass
-
-
-def hsdic2list(dic):
- """Convert what we get from get_conf_map to what we need for set_options"""
- return [
- pair for pairs in [
- [('HiddenServiceDir', vals[0]), ('HiddenServicePort', vals[1])]
- for vals in zip(dic.get('HiddenServiceDir', []), dic.get('HiddenServicePort', []))
- ] for pair in pairs
- ]
-
+import strings, helpers, web, hs
class OnionShare(object):
def __init__(self, debug=False, local_only=False, stay_open=False, transparent_torification=False):
self.port = None
- self.controller = None
+ self.hs = None
self.hidserv_dir = None
+ # files and dirs to delete on shutdown
+ self.cleanup_filenames = []
+
# debug mode
if debug:
web.debug_mode()
@@ -62,36 +44,6 @@ class OnionShare(object):
# traffic automatically goes through Tor
self.transparent_torification = transparent_torification
- # files and dirs to delete on shutdown
- self.cleanup_filenames = []
-
- def cleanup(self):
- # cleanup hidden service
- try:
- if self.controller:
- # Get fresh hidden services (maybe changed since last time)
- # and remove ourselves
- hsdic = self.controller.get_conf_map('HiddenServiceOptions') or {
- 'HiddenServiceDir': [], 'HiddenServicePort': []
- }
- if self.hidserv_dir and self.hidserv_dir in hsdic.get('HiddenServiceDir', []):
- dropme = hsdic['HiddenServiceDir'].index(self.hidserv_dir)
- del hsdic['HiddenServiceDir'][dropme]
- del hsdic['HiddenServicePort'][dropme]
- self.controller.set_options(hsdic2list(hsdic))
- # Politely close the controller
- self.controller.close()
- except:
- pass
-
- # cleanup files
- for filename in self.cleanup_filenames:
- if os.path.isfile(filename):
- os.remove(filename)
- elif os.path.isdir(filename):
- shutil.rmtree(filename)
- self.cleanup_filenames = []
-
def choose_port(self):
# let the OS choose a port
tmpsock = socket.socket()
@@ -107,54 +59,10 @@ class OnionShare(object):
self.onion_host = '127.0.0.1:{0:d}'.format(self.port)
return
- # come up with a hidden service directory name
- if helpers.get_platform() == 'Windows':
- path = '{0:s}/onionshare'.format(os.environ['Temp'].replace('\\', '/'))
- else:
- path = '/tmp/onionshare'
-
- try:
- if not os.path.exists(path):
- os.makedirs(path, 0700)
- except:
- raise HSDirError(strings._("error_hs_dir_cannot_create").format(path))
- if not os.access(path, os.W_OK):
- raise HSDirError(strings._("error_hs_dir_not_writable").format(path))
-
- self.hidserv_dir = tempfile.mkdtemp(dir=path)
- self.cleanup_filenames.append(self.hidserv_dir)
-
- # connect to the tor controlport
- self.controller = None
- tor_control_ports = [9051, 9151]
- for tor_control_port in tor_control_ports:
- try:
- self.controller = Controller.from_port(port=tor_control_port)
- self.controller.authenticate()
- break
- except:
- pass
- if not self.controller:
- raise NoTor(strings._("cant_connect_ctrlport").format(tor_control_ports))
-
- # set up hidden service
- hsdic = self.controller.get_conf_map('HiddenServiceOptions') or {
- 'HiddenServiceDir': [], 'HiddenServicePort': []
- }
- if self.hidserv_dir in hsdic.get('HiddenServiceDir', []):
- # Maybe a stale service with the wrong local port
- dropme = hsdic['HiddenServiceDir'].index(self.hidserv_dir)
- del hsdic['HiddenServiceDir'][dropme]
- del hsdic['HiddenServicePort'][dropme]
- hsdic['HiddenServiceDir'] = hsdic.get('HiddenServiceDir', [])+[self.hidserv_dir]
- hsdic['HiddenServicePort'] = hsdic.get('HiddenServicePort', [])+[
- '80 127.0.0.1:{0:d}'.format(self.port)]
-
- self.controller.set_options(hsdic2list(hsdic))
-
- # figure out the .onion hostname
- hostname_file = '{0:s}/hostname'.format(self.hidserv_dir)
- self.onion_host = open(hostname_file, 'r').read().strip()
+ if not self.hs:
+ self.hs = hs.HS(self.transparent_torification)
+
+ self.onion_host = self.hs.start(self.port)
def wait_for_hs(self):
if self.local_only:
@@ -173,11 +81,11 @@ class OnionShare(object):
urllib2.urlopen('http://{0:s}'.format(self.onion_host))
else:
tor_exists = False
- tor_socks_ports = [9050, 9150]
- for tor_socks_port in tor_socks_ports:
+ ports = [9050, 9150]
+ for port in ports:
try:
s = socks.socksocket()
- s.setproxy(socks.PROXY_TYPE_SOCKS5, '127.0.0.1', tor_socks_port)
+ s.setproxy(socks.PROXY_TYPE_SOCKS5, '127.0.0.1', port)
s.connect((self.onion_host, 80))
s.close()
tor_exists = True
@@ -202,6 +110,18 @@ class OnionShare(object):
return False
return True
+ def cleanup(self):
+ # cleanup files
+ for filename in self.cleanup_filenames:
+ if os.path.isfile(filename):
+ os.remove(filename)
+ elif os.path.isdir(filename):
+ shutil.rmtree(filename)
+ self.cleanup_filenames = []
+
+ # call hs's cleanup
+ self.hs.cleanup()
+
def main(cwd=None):
strings.load_strings()
@@ -244,9 +164,9 @@ def main(cwd=None):
app.choose_port()
print strings._("connecting_ctrlport").format(int(app.port))
app.start_hidden_service()
- except NoTor as e:
+ except hs.NoTor as e:
sys.exit(e.args[0])
- except HSDirError as e:
+ except hs.HSDirError as e:
sys.exit(e.args[0])
# prepare files to share
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/onionshare.git
More information about the Pkg-privacy-commits
mailing list