[Pkg-privacy-commits] [onionshare] 07/53: Removed all of the Tails-specific code. If we use ephemeral hidden services, we no longer need to touch the filesystem, and hopefully no longer need root in Tails.

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 5d37d9b7b240a4b17d00a04db91cc117c5725078
Author: Micah Lee <micah at micahflee.com>
Date:   Mon Sep 7 21:44:29 2015 -0700

    Removed all of the Tails-specific code. If we use ephemeral hidden services, we no longer need to touch the filesystem, and hopefully no longer need root in Tails.
---
 locale/en.json                   |   1 +
 onionshare/helpers.py            |   5 +-
 onionshare/onionshare.py         | 198 ++++++++++++---------------------------
 onionshare/strings.py            |   2 +-
 onionshare/web.py                |  17 ++--
 onionshare_gui/onionshare_gui.py |   7 +-
 test/onionshare_helpers_test.py  |   8 --
 7 files changed, 75 insertions(+), 163 deletions(-)

diff --git a/locale/en.json b/locale/en.json
index c7c9ffd..bd3d29c 100644
--- a/locale/en.json
+++ b/locale/en.json
@@ -23,6 +23,7 @@
     "help_tails_port": "Tails only: port for opening firewall, starting hidden service",
     "help_local_only": "Do not attempt to use tor: for development only",
     "help_stay_open": "Keep hidden service running after download has finished",
+    "help_transparent_torification": "My system is transparently torified",
     "help_debug": "Log errors to disk",
     "help_filename": "List of files or folders to share",
     "gui_drag_and_drop": "Drag and drop\nfiles here",
diff --git a/onionshare/helpers.py b/onionshare/helpers.py
index 8c30c2e..c385351 100644
--- a/onionshare/helpers.py
+++ b/onionshare/helpers.py
@@ -27,10 +27,7 @@ sys.setdefaultencoding("utf-8")
 
 
 def get_platform():
-    p = platform.system()
-    if p == 'Linux' and platform.uname()[0:2] == ('Linux', 'amnesia'):
-        p = 'Tails'
-    return p
+    return platform.system()
 
 if get_platform() == 'Darwin':
     # this is hacky, but it ultimate ends up returning the absolute path to
diff --git a/onionshare/onionshare.py b/onionshare/onionshare.py
index d29b09c..f2f7514 100644
--- a/onionshare/onionshare.py
+++ b/onionshare/onionshare.py
@@ -29,10 +29,6 @@ class NoTor(Exception):
     pass
 
 
-class TailsError(Exception):
-    pass
-
-
 class HSDirError(Exception):
     pass
 
@@ -48,7 +44,7 @@ def hsdic2list(dic):
 
 
 class OnionShare(object):
-    def __init__(self, debug=False, local_only=False, stay_open=False):
+    def __init__(self, debug=False, local_only=False, stay_open=False, transparent_torification=False):
         self.port = None
         self.controller = None
         self.hidserv_dir = None
@@ -63,6 +59,9 @@ class OnionShare(object):
         # automatically close when download is finished
         self.stay_open = stay_open
 
+        # traffic automatically goes through Tor
+        self.transparent_torification = transparent_torification
+
         # files and dirs to delete on shutdown
         self.cleanup_filenames = []
 
@@ -100,92 +99,62 @@ class OnionShare(object):
         self.port = tmpsock.getsockname()[1]
         tmpsock.close()
 
-    def start_hidden_service(self, gui=False, tails_root=False):
+    def start_hidden_service(self, gui=False):
         if not self.port:
             self.choose_port()
 
-        if helpers.get_platform() == 'Tails' and not tails_root:
-            # in Tails, start the hidden service in a root process
-            if gui:
-                args = ['/usr/bin/gksudo', '-D', 'OnionShare', '--', '/usr/bin/onionshare']
-            else:
-                args = ['/usr/bin/sudo', '--', '/usr/bin/onionshare']
-            print "Executing: {0:s}".format(args+[str(self.port)])
-            p = subprocess.Popen(args+[str(self.port)], stderr=subprocess.PIPE, stdout=subprocess.PIPE)
-            stdout = p.stdout.read(22) # .onion URLs are 22 chars long
-
-            if stdout:
-                self.onion_host = stdout
-                print 'Got onion_host: {0:s}'.format(self.onion_host)
-            else:
-                if p.poll() == -1:
-                    raise TailsError(o.stderr.read())
-                else:
-                    raise TailsError(strings._("error_tails_unknown_root"))
+        if self.local_only:
+            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:
-            if self.local_only:
-                self.onion_host = '127.0.0.1:{0:d}'.format(self.port)
-
-            else:
-                # come up with a hidden service directory name
-                if helpers.get_platform() == 'Tails':
-                    # need to create HS directory in /var/lib/tor because of AppArmor rules included in Tails
-                    self.hidserv_dir = tempfile.mkdtemp(dir='/var/lib/tor')
-
-                    # change owner to debian-tor
-                    import pwd
-                    import grp
-                    uid = pwd.getpwnam("debian-tor").pw_uid
-                    gid = grp.getgrnam("debian-tor").gr_gid
-                    os.chown(self.hidserv_dir, uid, gid)
-                else:
-                    # in non-Tails linux, onionshare will create HS dir in /tmp/onionshare/*
-                    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
-                if helpers.get_platform() == 'Windows':
-                    self.hidserv_dir = self.hidserv_dir.replace('\\', '/')
-                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)]
+            path = '/tmp/onionshare'
 
-                self.controller.set_options(hsdic2list(hsdic))
+        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))
 
-                # figure out the .onion hostname
-                hostname_file = '{0:s}/hostname'.format(self.hidserv_dir)
-                self.onion_host = open(hostname_file, 'r').read().strip()
+        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()
 
     def wait_for_hs(self):
         if self.local_only:
@@ -199,9 +168,8 @@ class OnionShare(object):
                 sys.stdout.write('{0:s} '.format(strings._('wait_for_hs_trying')))
                 sys.stdout.flush()
 
-                if helpers.get_platform() == 'Tails':
-                    # in Tails everything is proxies over Tor already
-                    # so no need to set the socks5 proxy
+                if self.transparent_torification:
+                    # no need to set the socks5 proxy
                     urllib2.urlopen('http://{0:s}'.format(self.onion_host))
                 else:
                     tor_exists = False
@@ -221,13 +189,13 @@ class OnionShare(object):
                 ready = True
 
                 sys.stdout.write('{0:s}\n'.format(strings._('wait_for_hs_yup')))
-            except socks.SOCKS5Error:  # non-Tails error
+            except socks.SOCKS5Error:
                 sys.stdout.write('{0:s}\n'.format(strings._('wait_for_hs_nope')))
                 sys.stdout.flush()
-            except urllib2.HTTPError:  # Tails error
+            except urllib2.HTTPError:  # torification error
                 sys.stdout.write('{0:s}\n'.format(strings._('wait_for_hs_nope')))
                 sys.stdout.flush()
-            except httplib.BadStatusLine: # Tails (with bridge) error
+            except httplib.BadStatusLine: # torification (with bridge) error
                 sys.stdout.write('{0:s}\n'.format(strings._('wait_for_hs_nope')))
                 sys.stdout.flush()
             except KeyboardInterrupt:
@@ -235,46 +203,6 @@ class OnionShare(object):
         return True
 
 
-def tails_root():
-    # if running in Tails and as root, do only the things that require root
-    if helpers.get_platform() == 'Tails' and helpers.is_root():
-        parser = argparse.ArgumentParser()
-        parser.add_argument('port', nargs=1, help=strings._("help_tails_port"))
-        args = parser.parse_args()
-
-        try:
-            port = int(args.port[0])
-        except ValueError:
-            sys.stderr.write('{0:s}\n'.format(strings._("error_tails_invalid_port")))
-            sys.exit(-1)
-
-        # open hole in firewall
-        subprocess.call(['/sbin/iptables', '-I', 'OUTPUT', '-o', 'lo',
-                         '-p', 'tcp', '--dport', str(port), '-j', 'ACCEPT'])
-
-        # start hidden service
-        app = OnionShare()
-        app.choose_port()
-        app.port = port
-        app.start_hidden_service(False, True)
-        sys.stdout.write(app.onion_host)
-        sys.stdout.flush()
-
-        # close hole in firewall on shutdown
-        import signal
-
-        def handler(signum=None, frame=None):
-            subprocess.call(['/sbin/iptables', '-D', 'OUTPUT', '-o', 'lo',
-                             '-p', 'tcp', '--dport', str(port), '-j', 'ACCEPT'])
-            sys.exit()
-        for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGHUP, signal.SIGQUIT]:
-            signal.signal(sig, handler)
-
-        # stay open until killed
-        while True:
-            time.sleep(1)
-
-
 def main(cwd=None):
     strings.load_strings()
 
@@ -283,12 +211,11 @@ def main(cwd=None):
         if cwd:
             os.chdir(cwd)
 
-    tails_root()
-
     # parse arguments
     parser = argparse.ArgumentParser()
     parser.add_argument('--local-only', action='store_true', dest='local_only', help=strings._("help_local_only"))
     parser.add_argument('--stay-open', action='store_true', dest='stay_open', help=strings._("help_stay_open"))
+    parser.add_argument('--transparent', action='store_true', dest='transparent_torification', help=strings._("help_transparent_torification"))
     parser.add_argument('--debug', action='store_true', dest='debug', help=strings._("help_debug"))
     parser.add_argument('filename', metavar='filename', nargs='+', help=strings._('help_filename'))
     args = parser.parse_args()
@@ -300,6 +227,7 @@ def main(cwd=None):
     local_only = bool(args.local_only)
     debug = bool(args.debug)
     stay_open = bool(args.stay_open)
+    transparent_torification = bool(args.transparent_torification)
 
     # validation
     valid = True
@@ -312,14 +240,12 @@ def main(cwd=None):
 
     # start the onionshare app
     try:
-        app = OnionShare(debug, local_only, stay_open)
+        app = OnionShare(debug, local_only, stay_open, transparent_torification)
         app.choose_port()
         print strings._("connecting_ctrlport").format(int(app.port))
         app.start_hidden_service()
     except NoTor as e:
         sys.exit(e.args[0])
-    except TailsError as e:
-        sys.exit(e.args[0])
     except HSDirError as e:
         sys.exit(e.args[0])
 
@@ -335,7 +261,7 @@ def main(cwd=None):
         print ''
 
     # start onionshare service in new thread
-    t = threading.Thread(target=web.start, args=(app.port, app.stay_open))
+    t = threading.Thread(target=web.start, args=(app.port, app.stay_open, app.transparent_torification))
     t.daemon = True
     t.start()
 
diff --git a/onionshare/strings.py b/onionshare/strings.py
index fe4fc0e..ea61eb0 100644
--- a/onionshare/strings.py
+++ b/onionshare/strings.py
@@ -28,7 +28,7 @@ def load_strings(default="en"):
     p = helpers.get_platform()
 
     # find locale dir
-    if p == 'Linux' or p == 'Tails':
+    if p == 'Linux':
         locale_dir = os.path.join(sys.prefix, 'share/onionshare/locale')
     elif p == 'Darwin':
         locale_dir = os.path.join(helpers.osx_resources_dir, 'locale')
diff --git a/onionshare/web.py b/onionshare/web.py
index 059475a..83c42e0 100644
--- a/onionshare/web.py
+++ b/onionshare/web.py
@@ -83,16 +83,18 @@ slug = helpers.random_string(16)
 download_count = 0
 
 stay_open = False
-
-
 def set_stay_open(new_stay_open):
     global stay_open
     stay_open = new_stay_open
-
-
 def get_stay_open():
     return stay_open
 
+transparent_torification = False
+def set_transparent_torification(new_transparent_torification):
+    global transparent_torification
+    stay_open = new_transparent_torification
+def get_transparent_torification():
+    return transparent_torification
 
 def debug_mode():
     import logging
@@ -224,16 +226,15 @@ def shutdown(shutdown_slug_candidate):
     return ""
 
 
-def start(port, stay_open=False):
+def start(port, stay_open=False, transparent_torification=False):
     set_stay_open(stay_open)
+    set_transparent_torification(transparent_torification)
     app.run(port=port, threaded=True)
 
 
 def stop(port):
     # to stop flask, load http://127.0.0.1:<port>/<shutdown_slug>/shutdown
-    if helpers.get_platform() == 'Tails':
-        # in Tails everything is proxies over Tor, so we need to get lower level
-        # to connect not over the proxy
+    if transparent_torification:
         import socket
 
         s = socket.socket()
diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py
index b2642db..9f8e48a 100644
--- a/onionshare_gui/onionshare_gui.py
+++ b/onionshare_gui/onionshare_gui.py
@@ -39,7 +39,7 @@ from options import Options
 class Application(QtGui.QApplication):
     def __init__(self):
         platform = helpers.get_platform()
-        if platform == 'Tails' or platform == 'Linux':
+        if platform == 'Linux':
             self.setAttribute(QtCore.Qt.AA_X11InitThreads, True)
         QtGui.QApplication.__init__(self, sys.argv)
 
@@ -128,11 +128,6 @@ class OnionShareGui(QtGui.QWidget):
             self.server_status.stop_server()
             self.status_bar.clearMessage()
             return
-        except onionshare.TailsError as e:
-            alert(e.args[0], QtGui.QMessageBox.Warning)
-            self.server_status.stop_server()
-            self.status_bar.clearMessage()
-            return
 
         # start onionshare service in new thread
         t = threading.Thread(target=web.start, args=(self.app.port, self.app.stay_open))
diff --git a/test/onionshare_helpers_test.py b/test/onionshare_helpers_test.py
index a20e3e9..f7fa13e 100644
--- a/test/onionshare_helpers_test.py
+++ b/test/onionshare_helpers_test.py
@@ -21,14 +21,6 @@ from nose import with_setup
 
 import test_helpers
 
-
-def test_get_platform_on_tails():
-    """get_platform() returns 'Tails' when hostname is 'amnesia'"""
-    helpers.platform.uname = lambda: ('Linux', 'amnesia', '3.14-1-amd64',
-                                      '#1 SMP Debian 3.14.4-1 (2014-05-13)', 'x86_64', '')
-    assert helpers.get_platform() == 'Tails'
-
-
 def test_get_platform_returns_platform_system():
     """get_platform() returns platform.system() when ONIONSHARE_PLATFORM is not defined"""
     helpers.platform.system = lambda: 'Sega Saturn'

-- 
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