From 0302dca77f8e9797c8a31ce3296baa4b2a4e7669 Mon Sep 17 00:00:00 2001 From: The Dod Date: Mon, 13 Oct 2014 11:36:10 +0700 Subject: [PATCH 1/4] Don't disable existing hidden services Still not perfect: can't seem to remove our temporary hs (master branch doesn't do that either, but that's no excuse ;) ) probably something I don't understand re stem and hidden services --- onionshare/onionshare.py | 65 ++++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 19 deletions(-) diff --git a/onionshare/onionshare.py b/onionshare/onionshare.py index 5c0acde9..c81048b6 100644 --- a/onionshare/onionshare.py +++ b/onionshare/onionshare.py @@ -28,9 +28,20 @@ import strings, helpers, web class NoTor(Exception): pass class TailsError(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['HiddenServiceDir'],dic['HiddenServicePort']) + ] for pair in pairs + ] + class OnionShare(object): def __init__(self, debug=False, local_only=False, stay_open=False): self.port = None + self.controller = None + self.original_hs = None # debug mode if debug: @@ -45,7 +56,13 @@ class OnionShare(object): # files and dirs to delete on shutdown self.cleanup_filenames = [] + def cleanup(self): + if self.controller: + if self.original_hs: + # This doesn't seem to remove soon-to-be-stale hs. Why??? + self.controller.set_options(hsdic2list(self.original_hs)) + self.controller.close() for filename in self.cleanup_filenames: if os.path.isfile(filename): os.remove(filename) @@ -91,23 +108,33 @@ class OnionShare(object): self.cleanup_filenames.append(hidserv_dir) # connect to the tor controlport - controller = False + self.controller = None tor_control_ports = [9051, 9151] for tor_control_port in tor_control_ports: try: - controller = Controller.from_port(port=tor_control_port) + self.controller = Controller.from_port(port=tor_control_port) break except SocketError: pass - if not controller: + if not self.controller: raise NoTor(strings._("cant_connect_ctrlport").format(tor_control_ports)) controller.authenticate() # set up hidden service - controller.set_options([ - ('HiddenServiceDir', hidserv_dir), - ('HiddenServicePort', '80 127.0.0.1:{0}'.format(self.port)) - ]) + self.original_hs = self.controller.get_conf_map('HiddenServiceOptions') or { + 'HiddenServiceDir': [], 'HiddenServicePort': [] + } + print hsdic2list(self.original_hs) + new_hs = self.original_hs.copy() + if not hidserv_dir in new_hs['HiddenServiceDir']: + # Unless another instance has opened + # the same persistent_hs_dir already + new_hs['HiddenServiceDir'].append(hidserv_dir) + new_hs['HiddenServicePort'].append( + '80 127.0.0.1:{0}'.format(self.port)) + + self.controller.set_options(hsdic2list(new_hs)) + print self.controller.get_conf_map('HiddenServiceOptions') # figure out the .onion hostname hostname_file = '{0}/hostname'.format(hidserv_dir) @@ -249,18 +276,18 @@ def main(): t.daemon = True t.start() - # wait for hs - ready = app.wait_for_hs() - if not ready: - sys.exit() - - print strings._("give_this_url") - print 'http://{0}/{1}'.format(app.onion_host, web.slug) - print '' - print strings._("ctrlc_to_stop") - - # wait for app to close - try: + try: # Trap Ctrl-C + # wait for hs + ready = app.wait_for_hs() + if not ready: + sys.exit() + + print strings._("give_this_url") + print 'http://{0}/{1}'.format(app.onion_host, web.slug) + print '' + print strings._("ctrlc_to_stop") + + # wait for app to close while True: time.sleep(0.5) except KeyboardInterrupt: From aab094d0e28ba1f9fb360096fdf5e83a730bd2f8 Mon Sep 17 00:00:00 2001 From: The Dod Date: Mon, 13 Oct 2014 11:42:48 +0700 Subject: [PATCH 2/4] Remove debug prints :s --- onionshare/onionshare.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/onionshare/onionshare.py b/onionshare/onionshare.py index c81048b6..f99d482e 100644 --- a/onionshare/onionshare.py +++ b/onionshare/onionshare.py @@ -124,7 +124,6 @@ class OnionShare(object): self.original_hs = self.controller.get_conf_map('HiddenServiceOptions') or { 'HiddenServiceDir': [], 'HiddenServicePort': [] } - print hsdic2list(self.original_hs) new_hs = self.original_hs.copy() if not hidserv_dir in new_hs['HiddenServiceDir']: # Unless another instance has opened @@ -134,7 +133,6 @@ class OnionShare(object): '80 127.0.0.1:{0}'.format(self.port)) self.controller.set_options(hsdic2list(new_hs)) - print self.controller.get_conf_map('HiddenServiceOptions') # figure out the .onion hostname hostname_file = '{0}/hostname'.format(hidserv_dir) From 1786b5a8915c80c76cbb7d1dbd6b9bd56d1d98ce Mon Sep 17 00:00:00 2001 From: The Dod Date: Mon, 13 Oct 2014 14:14:15 +0700 Subject: [PATCH 3/4] Typo Overlooked because I can only use a password-auth branch on my PC --- onionshare/onionshare.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onionshare/onionshare.py b/onionshare/onionshare.py index f99d482e..04c20485 100644 --- a/onionshare/onionshare.py +++ b/onionshare/onionshare.py @@ -118,7 +118,7 @@ class OnionShare(object): pass if not self.controller: raise NoTor(strings._("cant_connect_ctrlport").format(tor_control_ports)) - controller.authenticate() + self.controller.authenticate() # set up hidden service self.original_hs = self.controller.get_conf_map('HiddenServiceOptions') or { From 0b50829695a6e14b514717e0bbabb85e05dd0077 Mon Sep 17 00:00:00 2001 From: The Dod Date: Tue, 21 Oct 2014 06:08:31 +0700 Subject: [PATCH 4/4] Allow for arbitrary order of service open/close d'Oh --- onionshare/onionshare.py | 43 ++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/onionshare/onionshare.py b/onionshare/onionshare.py index 04c20485..daf35e5c 100644 --- a/onionshare/onionshare.py +++ b/onionshare/onionshare.py @@ -33,7 +33,7 @@ def hsdic2list(dic): return [ pair for pairs in [ [('HiddenServiceDir',vals[0]),('HiddenServicePort',vals[1])] - for vals in zip(dic['HiddenServiceDir'],dic['HiddenServicePort']) + for vals in zip(dic.get('HiddenServiceDir',[]),dic.get('HiddenServicePort',[])) ] for pair in pairs ] @@ -41,7 +41,7 @@ class OnionShare(object): def __init__(self, debug=False, local_only=False, stay_open=False): self.port = None self.controller = None - self.original_hs = None + self.hidserv_dir = None # debug mode if debug: @@ -59,9 +59,17 @@ class OnionShare(object): def cleanup(self): if self.controller: - if self.original_hs: - # This doesn't seem to remove soon-to-be-stale hs. Why??? - self.controller.set_options(hsdic2list(self.original_hs)) + # 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() for filename in self.cleanup_filenames: if os.path.isfile(filename): @@ -104,8 +112,8 @@ class OnionShare(object): else: # come up with a hidden service directory name - hidserv_dir = '{0}/onionshare_{1}'.format(helpers.get_tmp_dir(), helpers.random_string(8)) - self.cleanup_filenames.append(hidserv_dir) + self.hidserv_dir = '{0}/onionshare_{1}'.format(helpers.get_tmp_dir(), helpers.random_string(8)) + self.cleanup_filenames.append(self.hidserv_dir) # connect to the tor controlport self.controller = None @@ -121,21 +129,22 @@ class OnionShare(object): self.controller.authenticate() # set up hidden service - self.original_hs = self.controller.get_conf_map('HiddenServiceOptions') or { + hsdic = self.controller.get_conf_map('HiddenServiceOptions') or { 'HiddenServiceDir': [], 'HiddenServicePort': [] } - new_hs = self.original_hs.copy() - if not hidserv_dir in new_hs['HiddenServiceDir']: - # Unless another instance has opened - # the same persistent_hs_dir already - new_hs['HiddenServiceDir'].append(hidserv_dir) - new_hs['HiddenServicePort'].append( - '80 127.0.0.1:{0}'.format(self.port)) + 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}'.format(self.port) ] - self.controller.set_options(hsdic2list(new_hs)) + self.controller.set_options(hsdic2list(hsdic)) # figure out the .onion hostname - hostname_file = '{0}/hostname'.format(hidserv_dir) + hostname_file = '{0}/hostname'.format(self.hidserv_dir) self.onion_host = open(hostname_file, 'r').read().strip() def wait_for_hs(self):