diff --git a/onionshare/onion.py b/onionshare/onion.py index 2f79719b..adfb4dbf 100644 --- a/onionshare/onion.py +++ b/onionshare/onion.py @@ -375,6 +375,12 @@ class Onion(object): # ephemeral stealth onion services are not supported self.supports_stealth = False + def is_authenticated(self): + """ + Returns True if the Tor connection is still working, or False otherwise. + """ + return self.c.is_authenticated() + def start_onion_service(self, port): """ Start a onion service on port 80, pointing to the given port, and diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index 3ed30db7..f6ebf6be 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -219,6 +219,11 @@ class OnionShareGui(QtWidgets.QMainWindow): def reload_settings(): common.log('OnionShareGui', 'open_settings', 'settings have changed, reloading') self.settings.load() + # We might've stopped the main requests timer if a Tor connection failed. + # If we've reloaded settings, we probably succeeded in obtaining a new + # connection. If so, restart the timer. + if not self.timer.isActive(): + self.timer.start() d = SettingsDialog(self.onion, self.qtapp, self.config) d.settings_saved.connect(reload_settings) @@ -389,6 +394,18 @@ class OnionShareGui(QtWidgets.QMainWindow): """ self.update() + # Have we lost connection to Tor somehow? + try: + # Tor Browser may not even have been open when we started OnionShare, + # in which case onion.is_authenticated() throws a NoneType error + self.onion + if not self.onion.is_authenticated(): + self.timer.stop() + self.start_server_error(strings._('error_tor_protocol_error')) + self._tor_connection_canceled() + except: + pass + # scroll to the bottom of the dl progress bar log pane # if a new download has been added if self.new_download: diff --git a/onionshare_gui/settings_dialog.py b/onionshare_gui/settings_dialog.py index df806a06..7ead3f1b 100644 --- a/onionshare_gui/settings_dialog.py +++ b/onionshare_gui/settings_dialog.py @@ -459,26 +459,31 @@ class SettingsDialog(QtWidgets.QDialog): # If Tor isn't connected, or if Tor settings have changed, Reinitialize # the Onion object reboot_onion = False - if self.onion.connected_to_tor: - def changed(s1, s2, keys): - """ - Compare the Settings objects s1 and s2 and return true if any values - have changed for the given keys. - """ - for key in keys: - if s1.get(key) != s2.get(key): - return True - return False + try: + self.onion + if self.onion.is_authenticated(): + def changed(s1, s2, keys): + """ + Compare the Settings objects s1 and s2 and return true if any values + have changed for the given keys. + """ + for key in keys: + if s1.get(key) != s2.get(key): + return True + return False - if changed(settings, self.old_settings, [ - 'connection_type', 'control_port_address', - 'control_port_port', 'socks_address', 'socks_port', - 'socket_file_path', 'auth_type', 'auth_password']): + if changed(settings, self.old_settings, [ + 'connection_type', 'control_port_address', + 'control_port_port', 'socks_address', 'socks_port', + 'socket_file_path', 'auth_type', 'auth_password']): + reboot_onion = True + + else: + # Tor isn't connected, so try connecting reboot_onion = True - - else: - # Tor isn't connected, so try connecting + except: + # We definitely aren't connected, as the onion object had no attribute is_authenticated() reboot_onion = True # Do we need to reinitialize Tor?