diff --git a/install/get-tor-osx.py b/install/get-tor-osx.py index a9f68aaa..b8c17fba 100644 --- a/install/get-tor-osx.py +++ b/install/get-tor-osx.py @@ -28,9 +28,9 @@ import inspect, os, sys, hashlib, zipfile, io, shutil, subprocess import urllib.request def main(): - dmg_url = 'https://www.torproject.org/dist/torbrowser/6.5.2/TorBrowser-6.5.2-osx64_en-US.dmg' - dmg_filename = 'TorBrowser-6.5.2-osx64_en-US.dmg' - expected_dmg_sha256 = '0b11d12f9ff0d82ceb2a9a4dba9c4ba234da47640c8e25e76e4092a7d3a90ef6' + dmg_url = 'https://archive.torproject.org/tor-package-archive/torbrowser/7.0.10/TorBrowser-7.0.10-osx64_en-US.dmg' + dmg_filename = 'TorBrowser-7.0.10-osx64_en-US.dmg' + expected_dmg_sha256 = '2de32de962d14ecb55f8008078875f3d0b0875dba4a140726714e67ce329fe9a' # Build paths root_path = os.path.dirname(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))) diff --git a/install/get-tor-windows.py b/install/get-tor-windows.py index 2c069d4f..d6cbfed5 100644 --- a/install/get-tor-windows.py +++ b/install/get-tor-windows.py @@ -28,9 +28,9 @@ import inspect, os, sys, hashlib, zipfile, io, shutil import urllib.request def main(): - zip_url = 'https://www.torproject.org/dist/torbrowser/6.5.1/tor-win32-0.2.9.10.zip' - zip_filename = 'tor-win32-0.2.9.10.zip' - expected_zip_sha256 = '56e639cd73c48f383fd638568e01ca07750211fca79c87e668cf8baccbf9d38a' + zip_url = 'https://archive.torproject.org/tor-package-archive/torbrowser/7.0.10/tor-win32-0.3.1.8.zip' + zip_filename = 'tor-win32-0.3.1.8.zip' + expected_zip_sha256 = '101defd239cda42f364815e91809fad16b17f03843a169ffbeb8cb91183b6ba8' # Build paths root_path = os.path.dirname(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))) diff --git a/install/scripts/onionshare-nautilus.py b/install/scripts/onionshare-nautilus.py index d5e83919..6674dd18 100644 --- a/install/scripts/onionshare-nautilus.py +++ b/install/scripts/onionshare-nautilus.py @@ -93,3 +93,7 @@ class OnionShareExtension(GObject.GObject, Nautilus.MenuProvider): for file in files: file_list.append(self.url2path(file)) self.exec_onionshare(file_list) + + # Workaround https://bugzilla.gnome.org/show_bug.cgi?id=784278 + def get_background_items(self, window, file): + return None diff --git a/onionshare/common.py b/onionshare/common.py index 6916f886..562c71f2 100644 --- a/onionshare/common.py +++ b/onionshare/common.py @@ -104,7 +104,7 @@ def get_tor_paths(): tor_path = os.path.join(base_path, 'Resources', 'Tor', 'tor') tor_geo_ip_file_path = os.path.join(base_path, 'Resources', 'Tor', 'geoip') tor_geo_ipv6_file_path = os.path.join(base_path, 'Resources', 'Tor', 'geoip6') - elif p == 'OpenBSD': + elif p == 'OpenBSD' or p == 'FreeBSD': tor_path = '/usr/local/bin/tor' tor_geo_ip_file_path = '/usr/local/share/tor/geoip' tor_geo_ipv6_file_path = '/usr/local/share/tor/geoip6' diff --git a/onionshare/onion.py b/onionshare/onion.py index cf761bb9..db1dfeaf 100644 --- a/onionshare/onion.py +++ b/onionshare/onion.py @@ -254,8 +254,8 @@ class Onion(object): break time.sleep(0.2) - # Timeout after 45 seconds - if time.time() - start_ts > 45: + # Timeout after 90 seconds + if time.time() - start_ts > 90: print("") self.tor_proc.terminate() raise BundledTorTimeout(strings._('settings_error_bundled_tor_timeout')) @@ -375,6 +375,17 @@ 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. + """ + if self.c is not None: + return self.c.is_authenticated() + else: + return False + + def start_onion_service(self, port): """ Start a onion service on port 80, pointing to the given port, and @@ -419,7 +430,7 @@ class Onion(object): except ProtocolError: raise TorErrorProtocolError(strings._('error_tor_protocol_error')) - self.service_id = res.content()[0][2].split('=')[1] + self.service_id = res.service_id onion_host = self.service_id + '.onion' # A new private key was generated and is in the Control port response. diff --git a/onionshare_gui/file_selection.py b/onionshare_gui/file_selection.py index 54321370..da03d24d 100644 --- a/onionshare_gui/file_selection.py +++ b/onionshare_gui/file_selection.py @@ -229,6 +229,7 @@ class FileSelection(QtWidgets.QVBoxLayout): itemrow = self.file_list.row(item) self.file_list.filenames.pop(itemrow) self.file_list.takeItem(itemrow) + self.file_list.files_updated.emit() self.update() def server_started(self): diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index ca332f74..452e58db 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -136,23 +136,25 @@ class OnionShareGui(QtWidgets.QMainWindow): self.setCentralWidget(central_widget) self.show() - # Check for requests frequently - self.timer = QtCore.QTimer() - self.timer.timeout.connect(self.check_for_requests) - self.timer.start(500) - # Always start with focus on file selection self.file_selection.setFocus() # The server isn't active yet self.set_server_active(False) + # Create the timer + self.timer = QtCore.QTimer() + self.timer.timeout.connect(self.check_for_requests) + # Start the "Connecting to Tor" dialog, which calls onion.connect() tor_con = TorConnectionDialog(self.qtapp, self.settings, self.onion) tor_con.canceled.connect(self._tor_connection_canceled) tor_con.open_settings.connect(self._tor_connection_open_settings) tor_con.start() + # Start the timer + self.timer.start(500) + # After connecting to Tor, check for updates self.check_for_updates() @@ -225,6 +227,17 @@ 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 self.onion.is_authenticated(): + if not self.timer.isActive(): + self.timer.start(500) + # If there were some files listed for sharing, we should be ok to + # re-enable the 'Start Sharing' button now. + if self.server_status.file_selection.get_num_files() > 0: + self.server_status.server_button.setEnabled(True) + self.status_bar.clearMessage() d = SettingsDialog(self.onion, self.qtapp, self.config) d.settings_saved.connect(reload_settings) @@ -244,6 +257,7 @@ class OnionShareGui(QtWidgets.QMainWindow): # Hide and reset the downloads if we have previously shared self.downloads_container.hide() self.downloads.reset_downloads() + self.status_bar.clearMessage() # Reset web counters web.download_count = 0 @@ -284,7 +298,6 @@ class OnionShareGui(QtWidgets.QMainWindow): self._zip_progress_bar = ZipProgressBar(0) self._zip_progress_bar.total_files_size = OnionShareGui._compute_total_size( self.file_selection.file_list.filenames) - self.status_bar.clearMessage() self.status_bar.insertWidget(0, self._zip_progress_bar) # prepare the files for sending in a new thread @@ -293,12 +306,16 @@ class OnionShareGui(QtWidgets.QMainWindow): def _set_processed_size(x): if self._zip_progress_bar != None: self._zip_progress_bar.update_processed_size_signal.emit(x) - web.set_file_info(self.file_selection.file_list.filenames, processed_size_callback=_set_processed_size) - self.app.cleanup_filenames.append(web.zip_filename) - self.starting_server_step3.emit() + try: + web.set_file_info(self.file_selection.file_list.filenames, processed_size_callback=_set_processed_size) + self.app.cleanup_filenames.append(web.zip_filename) + self.starting_server_step3.emit() - # done - self.start_server_finished.emit() + # done + self.start_server_finished.emit() + except OSError as e: + self.starting_server_error.emit(e.strerror) + return #self.status_bar.showMessage(strings._('gui_starting_server2', True)) t = threading.Thread(target=finish_starting_server, kwargs={'self': self}) @@ -348,6 +365,9 @@ class OnionShareGui(QtWidgets.QMainWindow): Alert(error, QtWidgets.QMessageBox.Warning) self.server_status.stop_server() + if self._zip_progress_bar is not None: + self.status_bar.removeWidget(self._zip_progress_bar) + self._zip_progress_bar = None self.status_bar.clearMessage() def stop_server(self): @@ -401,6 +421,16 @@ class OnionShareGui(QtWidgets.QMainWindow): """ self.update() + # Have we lost connection to Tor somehow? + if not self.onion.is_authenticated(): + self.timer.stop() + if self.server_status.status != self.server_status.STATUS_STOPPED: + self.server_status.stop_server() + self.server_status.server_button.setEnabled(False) + self.status_bar.showMessage(strings._('gui_tor_connection_lost', True)) + if self.systemTray.supportsMessages() and self.settings.get('systray_notifications'): + self.systemTray.showMessage(strings._('gui_tor_connection_lost', True), strings._('gui_tor_connection_error_settings', True)) + # 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 2aaaab47..a978c403 100644 --- a/onionshare_gui/settings_dialog.py +++ b/onionshare_gui/settings_dialog.py @@ -78,6 +78,8 @@ class SettingsDialog(QtWidgets.QDialog): # Stealth stealth_details = QtWidgets.QLabel(strings._("gui_settings_stealth_option_details", True)) stealth_details.setWordWrap(True) + stealth_details.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) + stealth_details.setOpenExternalLinks(True) self.stealth_checkbox = QtWidgets.QCheckBox() self.stealth_checkbox.setCheckState(QtCore.Qt.Unchecked) self.stealth_checkbox.setText(strings._("gui_settings_stealth_option", True)) @@ -493,7 +495,8 @@ 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: + if self.onion.is_authenticated(): + common.log('SettingsDialog', 'save_clicked', 'Connected to Tor') def changed(s1, s2, keys): """ Compare the Settings objects s1 and s2 and return true if any values @@ -512,6 +515,7 @@ class SettingsDialog(QtWidgets.QDialog): reboot_onion = True else: + common.log('SettingsDialog', 'save_clicked', 'Not connected to Tor') # Tor isn't connected, so try connecting reboot_onion = True @@ -526,7 +530,7 @@ class SettingsDialog(QtWidgets.QDialog): 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.close() @@ -539,7 +543,7 @@ class SettingsDialog(QtWidgets.QDialog): Cancel button 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) sys.exit() else: @@ -606,7 +610,7 @@ class SettingsDialog(QtWidgets.QDialog): common.log('SettingsDialog', 'closeEvent') # 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') # Wait 1ms for the event loop to finish, then quit diff --git a/onionshare_gui/tor_connection_dialog.py b/onionshare_gui/tor_connection_dialog.py index fa4c7860..dc472725 100644 --- a/onionshare_gui/tor_connection_dialog.py +++ b/onionshare_gui/tor_connection_dialog.py @@ -64,7 +64,7 @@ class TorConnectionDialog(QtWidgets.QProgressDialog): t.error_connecting_to_tor.connect(self._error_connecting_to_tor) t.start() - # The main thread needs to remain active, and checkign for Qt events, + # The main thread needs to remain active, and checking for Qt events, # until the thread is finished. Otherwise it won't be able to handle # accepting signals. self.active = True @@ -86,6 +86,7 @@ class TorConnectionDialog(QtWidgets.QProgressDialog): def _canceled_connecting_to_tor(self): common.log('TorConnectionDialog', '_canceled_connecting_to_tor') self.active = False + self.onion.cleanup() # Cancel connecting to Tor QtCore.QTimer.singleShot(1, self.cancel) diff --git a/share/locale/en.json b/share/locale/en.json index d52e0434..30e0c196 100644 --- a/share/locale/en.json +++ b/share/locale/en.json @@ -120,6 +120,7 @@ "gui_tor_connection_ask_quit": "Quit", "gui_tor_connection_error_settings": "Try adjusting how OnionShare connects to the Tor network in Settings.", "gui_tor_connection_canceled": "OnionShare cannot connect to Tor.\n\nMake sure you're connected to the internet, then re-open OnionShare to configure the Tor connection.", + "gui_tor_connection_lost": "Disconnected from Tor.", "gui_server_started_after_timeout": "The server started after your chosen auto-timeout.\nPlease start a new share.", "gui_server_timeout_expired": "The chosen timeout has already expired.\nPlease update the timeout and then you may start sharing.", "share_via_onionshare": "Share via OnionShare", diff --git a/share/locale/nl.json b/share/locale/nl.json index 90a84ca6..1203f2ee 100644 --- a/share/locale/nl.json +++ b/share/locale/nl.json @@ -9,18 +9,31 @@ "give_this_url_stealth": "Geef deze URL en de HidServAuth regel aan de persoon aan wie je dit bestand verzend:", "ctrlc_to_stop": "Druk Ctrl-C om de server te stoppen", "not_a_file": "{0:s} is geen bestand.", + "not_a_readable_file": "{0:s} is geen leesbaar bestand.", + "no_available_port": "Kan de Onion service niet starten, er zijn geen poorten beschikbaar.", "download_page_loaded": "Downloadpagina geladen", "other_page_loaded": "URL geladen", - "closing_automatically": "Sluit nu automatisch omdat download gereed is", + "close_on_timeout": "Sluit automatisch omdat timeout bereikt is", + "closing_automatically": "Sluit automatisch omdat download gereed is", + "timeout_download_still_running": "Wachten totdat download gereed is voor automatisch sluiten", "large_filesize": "Waarschuwing: Versturen van grote bestanden kan uren duren", "error_tails_invalid_port": "Ongeldige waarde, poort moet een integer zijn", "error_tails_unknown_root": "Onbekende fout met het Tails root proces", + "systray_menu_exit": "Afsluiten", + "systray_download_started_title": "OnionShare download gestart", + "systray_download_started_message": "Een gebruiker is begonnen met downloaden van je bestanden", + "systray_download_completed_title": "OnionShare download gereed", + "systray_download_completed_message": "De gebruiker is klaar met downloaden", + "systray_download_canceled_title": "OnionShare download afgebroken", + "systray_download_canceled_message": "De gebruiker heeft de download afgebroken", "help_local_only": "Maak geen gebruik van Tor, alleen voor ontwikkeling", "help_stay_open": "Laat verborgen service draaien nadat download gereed is", + "help_shutdown_timeout": "Sluit de Onion service na N seconden", "help_transparent_torification": "Mijn systeem gebruikt Tor als proxyserver", - "help_stealth": "Maak geheime onion service (geavanceerd)", + "help_stealth": "Maak stealth Onion service (geavanceerd)", "help_debug": "Log fouten naar harde schijf", "help_filename": "Lijst van bestanden of mappen om te delen", + "help_config": "Pad naar een JSON configuratie bestand (optioneel)", "gui_drag_and_drop": "Sleep en zet\nbestanden hier neer", "gui_add": "Toevoegen", "gui_delete": "Verwijder", @@ -50,25 +63,39 @@ "zip_progress_bar_format": "Bestanden verwerken: %p%", "error_stealth_not_supported": "Om een geheime onion service te maken heb je minstens Tor 0.2.9.1-alpha (of Tor Browser 6.5) en minstens python3-stem 1.5.0 nodig.", "error_ephemeral_not_supported": "OnionShare vereist minstens Tor 0.2.7.1 en minstens python3-stem 1.4.0.", - "gui_menu_file_menu": "&Bestand", - "gui_menu_settings_action": "&Instellingen", - "gui_menu_quit_action": "&Afsluiten", "gui_settings_window_title": "Instellingen", + "gui_settings_window_title": "Instellingen", + "gui_settings_stealth_label": "Stealth (geavanceerd)", + "gui_settings_stealth_option": "Maak stealth onion services", + "gui_settings_stealth_option_details": "Dit maakt OnionShare veiliger, maar ook lastiger voor de ontvanger om te verbinden.
Meer informatie.", + "gui_settings_autoupdate_label": "Controleer voor updates", + "gui_settings_autoupdate_option": "Notificeer me als er updates beschikbaar zijn", + "gui_settings_autoupdate_timestamp": "Laatste controle: {}", + "gui_settings_autoupdate_timestamp_never": "Nooit", + "gui_settings_autoupdate_check_button": "Controleer voor update", + "gui_settings_sharing_label": "Deel opties", + "gui_settings_close_after_first_download_option": "Stop delen na eerste download", + "gui_settings_systray_notifications": "Laat desktop notificaties zien", "gui_settings_connection_type_label": "Hoe moet OnionShare verbinden met Tor?", + "gui_settings_connection_type_bundled_option": "Gebruik Tor die is meegeleverd met OnionShare", "gui_settings_connection_type_automatic_option": "Probeer automatische configuratie met Tor Browser", "gui_settings_connection_type_control_port_option": "Verbinden via controle poort", "gui_settings_connection_type_socket_file_option": "Verbinden via socket bestand", + "gui_settings_connection_type_test_button": "Test Tor instellingen", "gui_settings_control_port_label": "Controle poort", "gui_settings_socket_file_label": "Socket bestand", + "gui_settings_socks_label": "SOCKS poort", "gui_settings_authenticate_label": "Tor authenticatie opties", "gui_settings_authenticate_no_auth_option": "Geen authenticatie of cookie authenticatie", "gui_settings_authenticate_password_option": "Wachtwoord", "gui_settings_authenticate_cookie_option": "Cookie", "gui_settings_password_label": "Wachtwoord", "gui_settings_cookie_label": "Cookie pad", - "gui_settings_button_test": "Test Instellingen", "gui_settings_button_save": "Opslaan", "gui_settings_button_cancel": "Annuleren", + "gui_settings_button_help": "Help", + "gui_settings_shutdown_timeout_choice": "Auto-stop timer instellen?", + "gui_settings_shutdown_timeout": "Stop delen om:", "settings_saved": "Instellingen opgeslagen in {}", "settings_error_unknown": "Kan geen verbinding maken met de Tor controller omdat de instellingen niet kloppen.", "settings_error_automatic": "Kan geen verbinding maken met de Tor controller. Draait Tor Browser in de achtergrond? Deze kan je verkrijgen via https://www.torproject.org/.", @@ -77,6 +104,23 @@ "settings_error_auth": "Verbonden met {}:{}, maar kan niet authenticeren. Misschien is het geen Tor controller?", "settings_error_missing_password": "Verbonden met Tor controller, maar het heeft een wachtwoord nodig voor authenticatie.", "settings_error_unreadable_cookie_file": "Verbonden met Tor controller, maar kan niet authenticeren omdat wachtwoord onjuist is en gebruiker heeft niet de permissies om cookie bestand te lezen.", + "settings_error_bundled_tor_not_supported": "Meegeleverde Tor is niet onersteunt wanneer je niet de ontwikkelaarsmodus gebruikt in Windows or macOS.", + "settings_error_bundled_tor_timeout": "Verbinden met Tor duurt te lang. Misschien is je computer offline, of je klok is niet accuraat.", + "settings_error_bundled_tor_canceled": "Het Tor is afgesloten voordat het kon verbinden.", + "settings_error_bundled_tor_broken": "OnionShare kan niet verbinden met Tor op de achtergrond:\n{}", "settings_test_success": "Gefeliciteerd, OnionShare kan verbinden met de Tor controller.\n\nTor version: {}\nOndersteunt kortstondige onion services: {}\nOndersteunt geheime onion services: {}", - "error_tor_protocol_error": "Fout bij praten met de Tor controller.\nAls je Whonix gebruikt, kijk dan hier https://www.whonix.org/wiki/onionshare om OnionShare werkend te krijgen." + "error_tor_protocol_error": "Fout bij praten met de Tor controller.\nAls je Whonix gebruikt, kijk dan hier https://www.whonix.org/wiki/onionshare om OnionShare werkend te krijgen.", + "connecting_to_tor": "Verbinden met het Tor network", + "update_available": "Er is een OnionShare update beschikbaar. Klik hier om te downloaden.

Geinstalleerde versie: {}
Laatste versie: {}", + "update_error_check_error": "Fout bij controleren voor updates: Misschien ben je niet verbonden met Tor, of misschien is de OnionShare website down.", + "update_error_invalid_latest_version": "Fout bij controleren voor updates: De OnionShare website zegt dat de laatste versie '{}' is, maar dat lijkt geen valide versie te zijn.", + "update_not_available": "Je draait de laatste versie van OnionShare.", + "gui_tor_connection_ask": "Wil je de OnionShare instellingen openen om het verbindingsprobleem met Tor op te lossen?", + "gui_tor_connection_ask_open_settings": "Open Instellingen", + "gui_tor_connection_ask_quit": "Afsluiten", + "gui_tor_connection_error_settings": "Probeer de instellingen hoe OnionShare verbind met het Tor network aan te passen in Instellingen.", + "gui_tor_connection_canceled": "OnionShare kan niet verbinden met Tor.\n\nControleer of je verbonden bent met het internet, herstart OnionShare om de Tor verbinding te configureren.", + "gui_server_started_after_timeout": "De server startte na de gekozen auto-timeout.\nDeel opnieuw.", + "gui_server_timeout_expired": "De gekozen timeout is al verlopen.\nKies nieuwe timeout deel opnieuw.", + "share_via_onionshare": "Deel via OnionShare" }