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: