[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