Ensure we don't consider the Tor connection 'lost' if we're still in the connection dialog process (wait for that thread to finish).

Also various implementations of onion.is_authenticated() for a more robust check than onion.connected_to_tor,
which seemed to help some corner cases
This commit is contained in:
Miguel Jacq 2017-12-21 12:15:17 +11:00
parent bcd4363769
commit b442b5d41b
No known key found for this signature in database
GPG key ID: EEA4341C6D97A0B6
4 changed files with 42 additions and 48 deletions

View file

@ -375,11 +375,16 @@ class Onion(object):
# ephemeral stealth onion services are not supported # ephemeral stealth onion services are not supported
self.supports_stealth = False self.supports_stealth = False
def is_authenticated(self): def is_authenticated(self):
""" """
Returns True if the Tor connection is still working, or False otherwise. Returns True if the Tor connection is still working, or False otherwise.
""" """
return self.c.is_authenticated() if self.c:
return self.c.is_authenticated()
else:
return False
def start_onion_service(self, port): def start_onion_service(self, port):
""" """

View file

@ -142,10 +142,10 @@ class OnionShareGui(QtWidgets.QMainWindow):
self.set_server_active(False) self.set_server_active(False)
# Start the "Connecting to Tor" dialog, which calls onion.connect() # Start the "Connecting to Tor" dialog, which calls onion.connect()
tor_con = TorConnectionDialog(self.qtapp, self.settings, self.onion) self.tor_con = TorConnectionDialog(self.qtapp, self.settings, self.onion)
tor_con.canceled.connect(self._tor_connection_canceled) self.tor_con.canceled.connect(self._tor_connection_canceled)
tor_con.open_settings.connect(self._tor_connection_open_settings) self.tor_con.open_settings.connect(self._tor_connection_open_settings)
tor_con.start() self.tor_con.start()
# After connecting to Tor, check for updates # After connecting to Tor, check for updates
self.check_for_updates() self.check_for_updates()
@ -394,17 +394,11 @@ class OnionShareGui(QtWidgets.QMainWindow):
""" """
self.update() self.update()
# Have we lost connection to Tor somehow? # Has the Tor Connection dialog finished, but we've since lost connection to Tor somehow?
try: if not self.onion.is_authenticated() and self.tor_con.t.isFinished():
# Tor Browser may not even have been open when we started OnionShare, self.timer.stop()
# in which case onion.is_authenticated() throws a NoneType error self.start_server_error(strings._('error_tor_protocol_error'))
self.onion self._tor_connection_canceled()
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 # scroll to the bottom of the dl progress bar log pane
# if a new download has been added # if a new download has been added

View file

@ -459,31 +459,26 @@ class SettingsDialog(QtWidgets.QDialog):
# If Tor isn't connected, or if Tor settings have changed, Reinitialize # If Tor isn't connected, or if Tor settings have changed, Reinitialize
# the Onion object # the Onion object
reboot_onion = False reboot_onion = False
try: if self.onion.is_authenticated():
self.onion def changed(s1, s2, keys):
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.
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):
for key in keys: return True
if s1.get(key) != s2.get(key): return False
return True
return False
if changed(settings, self.old_settings, [ if changed(settings, self.old_settings, [
'connection_type', 'control_port_address', 'connection_type', 'control_port_address',
'control_port_port', 'socks_address', 'socks_port', 'control_port_port', 'socks_address', 'socks_port',
'socket_file_path', 'auth_type', 'auth_password']): 'socket_file_path', 'auth_type', 'auth_password']):
reboot_onion = True
else:
# Tor isn't connected, so try connecting
reboot_onion = True reboot_onion = True
except:
# We definitely aren't connected, as the onion object had no attribute is_authenticated() else:
# Tor isn't connected, so try connecting
reboot_onion = True reboot_onion = True
# Do we need to reinitialize Tor? # Do we need to reinitialize Tor?
@ -497,7 +492,7 @@ class SettingsDialog(QtWidgets.QDialog):
common.log('SettingsDialog', 'save_clicked', 'Onion done rebooting, connected to Tor: {}'.format(self.onion.connected_to_tor)) common.log('SettingsDialog', 'save_clicked', 'Onion done rebooting, connected to Tor: {}'.format(self.onion.connected_to_tor))
if self.onion.connected_to_tor and not tor_con.wasCanceled(): if self.onion.is_authenticated() and not tor_con.wasCanceled():
self.settings_saved.emit() self.settings_saved.emit()
self.close() self.close()
@ -510,7 +505,7 @@ class SettingsDialog(QtWidgets.QDialog):
Cancel button clicked. Cancel button clicked.
""" """
common.log('SettingsDialog', 'cancel_clicked') common.log('SettingsDialog', 'cancel_clicked')
if not self.onion.connected_to_tor: if not self.onion.is_authenticated():
Alert(strings._('gui_tor_connection_canceled', True), QtWidgets.QMessageBox.Warning) Alert(strings._('gui_tor_connection_canceled', True), QtWidgets.QMessageBox.Warning)
sys.exit() sys.exit()
else: else:
@ -565,7 +560,7 @@ class SettingsDialog(QtWidgets.QDialog):
common.log('SettingsDialog', 'closeEvent') common.log('SettingsDialog', 'closeEvent')
# On close, if Tor isn't connected, then quit OnionShare altogether # On close, if Tor isn't connected, then quit OnionShare altogether
if not self.onion.connected_to_tor: if not self.onion.is_authenticated():
common.log('SettingsDialog', 'closeEvent', 'Closing while not connected to Tor') common.log('SettingsDialog', 'closeEvent', 'Closing while not connected to Tor')
# Wait 1ms for the event loop to finish, then quit # Wait 1ms for the event loop to finish, then quit

View file

@ -57,12 +57,12 @@ class TorConnectionDialog(QtWidgets.QProgressDialog):
def start(self): def start(self):
common.log('TorConnectionDialog', 'start') common.log('TorConnectionDialog', 'start')
t = TorConnectionThread(self, self.settings, self.onion) self.t = TorConnectionThread(self, self.settings, self.onion)
t.tor_status_update.connect(self._tor_status_update) self.t.tor_status_update.connect(self._tor_status_update)
t.connected_to_tor.connect(self._connected_to_tor) self.t.connected_to_tor.connect(self._connected_to_tor)
t.canceled_connecting_to_tor.connect(self._canceled_connecting_to_tor) self.t.canceled_connecting_to_tor.connect(self._canceled_connecting_to_tor)
t.error_connecting_to_tor.connect(self._error_connecting_to_tor) self.t.error_connecting_to_tor.connect(self._error_connecting_to_tor)
t.start() self.t.start()
# The main thread needs to remain active, and checkign for Qt events, # The main thread needs to remain active, and checkign for Qt events,
# until the thread is finished. Otherwise it won't be able to handle # until the thread is finished. Otherwise it won't be able to handle
@ -126,7 +126,7 @@ class TorConnectionThread(QtCore.QThread):
# Connect to the Onion # Connect to the Onion
try: try:
self.onion.connect(self.settings, False, self._tor_status_update) self.onion.connect(self.settings, False, self._tor_status_update)
if self.onion.connected_to_tor: if self.onion.is_authenticated():
self.connected_to_tor.emit() self.connected_to_tor.emit()
else: else:
self.canceled_connecting_to_tor.emit() self.canceled_connecting_to_tor.emit()