From b13fb41555bdb612a4cca8d5152f552ca88c4696 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Fri, 9 Feb 2018 18:43:57 +1100 Subject: [PATCH 1/3] Allow the user to cancel a share that is still starting up --- onionshare/onion.py | 20 +++++++++------- onionshare_gui/onionshare_gui.py | 39 +++++++++++++++++++++++++++++--- onionshare_gui/server_status.py | 15 +++++++++++- share/locale/en.json | 2 +- 4 files changed, 63 insertions(+), 13 deletions(-) diff --git a/onionshare/onion.py b/onionshare/onion.py index 28f03f2d..5b4ae1bb 100644 --- a/onionshare/onion.py +++ b/onionshare/onion.py @@ -472,8 +472,8 @@ class Onion(object): auth_cookie = list(res.client_auth.values())[0] self.auth_string = 'HidServAuth {} {}'.format(onion_host, auth_cookie) - self.settings.save() if onion_host is not None: + self.settings.save() return onion_host else: raise TorErrorProtocolError(strings._('error_tor_protocol_error')) @@ -484,13 +484,17 @@ class Onion(object): """ common.log('Onion', 'cleanup') - # Cleanup the ephemeral onion service - if self.service_id: - try: - self.c.remove_ephemeral_hidden_service(self.service_id) - except: - pass - self.service_id = None + # Cleanup the ephemeral onion services, if we have any + try: + onions = self.c.list_ephemeral_hidden_services() + for onion in onions: + try: + self.c.delete_ephemeral_hidden_service(service_id) + except: + pass + except: + pass + self.service_id = None if stop_tor: # Stop tor process diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index 7fdc3491..722ba82f 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -78,6 +78,7 @@ class OnionShareGui(QtWidgets.QMainWindow): self.server_status.server_stopped.connect(self.stop_server) self.server_status.server_stopped.connect(self.update_server_status_indicator) self.server_status.server_stopped.connect(self.update_primary_action) + self.server_status.server_canceled.connect(self.cancel_server) self.start_server_finished.connect(self.clear_message) self.start_server_finished.connect(self.server_status.start_server_finished) self.start_server_finished.connect(self.update_server_status_indicator) @@ -341,9 +342,10 @@ class OnionShareGui(QtWidgets.QMainWindow): # wait for modules in thread to load, preventing a thread-related cx_Freeze crash time.sleep(0.2) - t = threading.Thread(target=start_onion_service, kwargs={'self': self}) - t.daemon = True - t.start() + common.log('OnionshareGui', 'start_server', 'Starting an onion thread') + self.t = OnionThread(function=start_onion_service, kwargs={'self': self}) + self.t.daemon = True + self.t.start() def start_server_step2(self): """ @@ -427,6 +429,14 @@ class OnionShareGui(QtWidgets.QMainWindow): self._zip_progress_bar = None self.status_bar.clearMessage() + def cancel_server(self): + """ + Cancel the server while it is preparing to start + """ + if self.t: + self.t.terminate() + self.stop_server() + def stop_server(self): """ Stop the onionshare server. @@ -667,3 +677,26 @@ class ZipProgressBar(QtWidgets.QProgressBar): self.setValue(100) else: self.setValue(0) + + +class OnionThread(QtCore.QThread): + """ + A QThread for starting our Onion Service. + By using QThread rather than threading.Thread, we are able + to call quit() or terminate() on the startup if the user + decided to cancel (in which case do not proceed with obtaining + the Onion address and starting the web server). + """ + def __init__(self, function, kwargs=None): + super(OnionThread, self).__init__() + common.log('OnionThread', '__init__') + self.function = function + if not kwargs: + self.kwargs = {} + else: + self.kwargs = kwargs + + def run(self): + common.log('OnionThread', 'run') + + self.function(**self.kwargs) diff --git a/onionshare_gui/server_status.py b/onionshare_gui/server_status.py index 786deb64..2715d57b 100644 --- a/onionshare_gui/server_status.py +++ b/onionshare_gui/server_status.py @@ -29,6 +29,7 @@ class ServerStatus(QtWidgets.QWidget): """ server_started = QtCore.pyqtSignal() server_stopped = QtCore.pyqtSignal() + server_canceled = QtCore.pyqtSignal() url_copied = QtCore.pyqtSignal() hidservauth_copied = QtCore.pyqtSignal() @@ -198,7 +199,7 @@ class ServerStatus(QtWidgets.QWidget): self.shutdown_timeout.setEnabled(False) elif self.status == self.STATUS_WORKING: self.server_button.setStyleSheet(button_working_style) - self.server_button.setEnabled(False) + self.server_button.setEnabled(True) self.server_button.setText(strings._('gui_please_wait')) self.shutdown_timeout.setEnabled(False) else: @@ -224,6 +225,8 @@ class ServerStatus(QtWidgets.QWidget): self.start_server() elif self.status == self.STATUS_STARTED: self.stop_server() + elif self.status == self.STATUS_WORKING: + self.cancel_server() def start_server(self): """ @@ -250,6 +253,16 @@ class ServerStatus(QtWidgets.QWidget): self.update() self.server_stopped.emit() + def cancel_server(self): + """ + Cancel the server. + """ + common.log('ServerStatus', 'cancel_server', 'Canceling the server mid-startup') + self.status = self.STATUS_WORKING + self.shutdown_timeout_reset() + self.update() + self.server_canceled.emit() + def stop_server_finished(self): """ The server has finished stopping. diff --git a/share/locale/en.json b/share/locale/en.json index 5473a88f..fd112845 100644 --- a/share/locale/en.json +++ b/share/locale/en.json @@ -48,7 +48,7 @@ "gui_copied_hidservauth": "Copied HidServAuth line to clipboard", "gui_starting_server1": "Starting Tor onion service...", "gui_starting_server2": "Crunching files...", - "gui_please_wait": "Please wait...", + "gui_please_wait": "Starting... Click to cancel", "error_hs_dir_cannot_create": "Cannot create onion service dir {0:s}", "error_hs_dir_not_writable": "onion service dir {0:s} is not writable", "using_ephemeral": "Starting ephemeral Tor onion service and awaiting publication", From 575d445de8fb70dc6976de5f91d48d7412d18467 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Mon, 12 Feb 2018 13:17:28 +1100 Subject: [PATCH 2/3] Fix function name remove_ephemeral_onion_service --- onionshare/onion.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onionshare/onion.py b/onionshare/onion.py index 5b4ae1bb..0bf12bb3 100644 --- a/onionshare/onion.py +++ b/onionshare/onion.py @@ -489,7 +489,7 @@ class Onion(object): onions = self.c.list_ephemeral_hidden_services() for onion in onions: try: - self.c.delete_ephemeral_hidden_service(service_id) + self.c.remove_ephemeral_hidden_service(service_id) except: pass except: From fd034f5cb18811c236b33096037a7f12d78f05b0 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Mon, 12 Feb 2018 13:43:34 +1100 Subject: [PATCH 3/3] Pass the correct parameter to remove_ephemeral_hidden_service() Add debug logs to verify if an onion was successfully deleted or not --- onionshare/onion.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/onionshare/onion.py b/onionshare/onion.py index 0bf12bb3..668de051 100644 --- a/onionshare/onion.py +++ b/onionshare/onion.py @@ -489,8 +489,10 @@ class Onion(object): onions = self.c.list_ephemeral_hidden_services() for onion in onions: try: - self.c.remove_ephemeral_hidden_service(service_id) + common.log('Onion', 'cleanup', 'trying to remove onion {}'.format(onion)) + self.c.remove_ephemeral_hidden_service(onion) except: + common.log('Onion', 'cleanup', 'could not remove onion {}.. moving on anyway'.format(onion)) pass except: pass