def test_get_tor_paths_windows(self, platform_windows, sys_frozen): base_path = os.path.join( os.path.dirname(os.path.dirname(common.get_resource_path(''))), 'tor') tor_path = os.path.join(os.path.join(base_path, 'Tor'), "tor.exe") tor_geo_ip_file_path = os.path.join( os.path.join(os.path.join(base_path, 'Data'), 'Tor'), 'geoip') tor_geo_ipv6_file_path = os.path.join( os.path.join(os.path.join(base_path, 'Data'), 'Tor'), 'geoip6') assert (common.get_tor_paths() == (tor_path, tor_geo_ip_file_path, tor_geo_ipv6_file_path))
def test_get_tor_paths_darwin(self, platform_darwin, sys_frozen, sys_meipass): base_path = os.path.dirname( os.path.dirname(os.path.dirname(common.get_resource_path('')))) 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') assert (common.get_tor_paths() == (tor_path, tor_geo_ip_file_path, tor_geo_ipv6_file_path))
def test_get_tor_paths_darwin(self, platform_darwin, sys_frozen, sys_meipass): base_path = os.path.dirname( os.path.dirname( os.path.dirname( common.get_resource_path('')))) 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') assert (common.get_tor_paths() == (tor_path, tor_geo_ip_file_path, tor_geo_ipv6_file_path))
def test_get_tor_paths_windows(self, platform_windows, sys_frozen): base_path = os.path.join( os.path.dirname( os.path.dirname( common.get_resource_path(''))), 'tor') tor_path = os.path.join( os.path.join(base_path, 'Tor'), "tor.exe") tor_geo_ip_file_path = os.path.join( os.path.join( os.path.join(base_path, 'Data'), 'Tor'), 'geoip') tor_geo_ipv6_file_path = os.path.join( os.path.join( os.path.join(base_path, 'Data'), 'Tor'), 'geoip6') assert (common.get_tor_paths() == (tor_path, tor_geo_ip_file_path, tor_geo_ipv6_file_path))
def __init__(self, onion, qtapp, config=False): super(SettingsDialog, self).__init__() common.log('SettingsDialog', '__init__') self.onion = onion self.qtapp = qtapp self.config = config self.setModal(True) self.setWindowTitle(strings._('gui_settings_window_title', True)) self.setWindowIcon(QtGui.QIcon(common.get_resource_path('images/logo.png'))) self.system = platform.system() # Sharing options # Close after first download self.close_after_first_download_checkbox = QtWidgets.QCheckBox() self.close_after_first_download_checkbox.setCheckState(QtCore.Qt.Checked) self.close_after_first_download_checkbox.setText(strings._("gui_settings_close_after_first_download_option", True)) # Whether or not to show systray notifications self.systray_notifications_checkbox = QtWidgets.QCheckBox() self.systray_notifications_checkbox.setCheckState(QtCore.Qt.Checked) self.systray_notifications_checkbox.setText(strings._("gui_settings_systray_notifications", True)) # Whether or not to use a shutdown timer self.shutdown_timeout_checkbox = QtWidgets.QCheckBox() self.shutdown_timeout_checkbox.setCheckState(QtCore.Qt.Checked) self.shutdown_timeout_checkbox.setText(strings._("gui_settings_shutdown_timeout_checkbox", True)) # Whether or not to save the Onion private key for reuse self.save_private_key_checkbox = QtWidgets.QCheckBox() self.save_private_key_checkbox.setCheckState(QtCore.Qt.Unchecked) self.save_private_key_checkbox.setText(strings._("gui_save_private_key_checkbox", True)) # Sharing options layout sharing_group_layout = QtWidgets.QVBoxLayout() sharing_group_layout.addWidget(self.close_after_first_download_checkbox) sharing_group_layout.addWidget(self.systray_notifications_checkbox) sharing_group_layout.addWidget(self.shutdown_timeout_checkbox) sharing_group_layout.addWidget(self.save_private_key_checkbox) sharing_group = QtWidgets.QGroupBox(strings._("gui_settings_sharing_label", True)) sharing_group.setLayout(sharing_group_layout) # Stealth options # 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) stealth_details.setMinimumSize(stealth_details.sizeHint()) self.stealth_checkbox = QtWidgets.QCheckBox() self.stealth_checkbox.setCheckState(QtCore.Qt.Unchecked) self.stealth_checkbox.setText(strings._("gui_settings_stealth_option", True)) hidservauth_details = QtWidgets.QLabel(strings._('gui_settings_stealth_hidservauth_string', True)) hidservauth_details.setWordWrap(True) hidservauth_details.setMinimumSize(hidservauth_details.sizeHint()) hidservauth_details.hide() self.hidservauth_copy_button = QtWidgets.QPushButton(strings._('gui_copy_hidservauth', True)) self.hidservauth_copy_button.clicked.connect(self.hidservauth_copy_button_clicked) self.hidservauth_copy_button.hide() # Stealth options layout stealth_group_layout = QtWidgets.QVBoxLayout() stealth_group_layout.addWidget(stealth_details) stealth_group_layout.addWidget(self.stealth_checkbox) stealth_group_layout.addWidget(hidservauth_details) stealth_group_layout.addWidget(self.hidservauth_copy_button) stealth_group = QtWidgets.QGroupBox(strings._("gui_settings_stealth_label", True)) stealth_group.setLayout(stealth_group_layout) # Automatic updates options # Autoupdate self.autoupdate_checkbox = QtWidgets.QCheckBox() self.autoupdate_checkbox.setCheckState(QtCore.Qt.Unchecked) self.autoupdate_checkbox.setText(strings._("gui_settings_autoupdate_option", True)) # Last update time self.autoupdate_timestamp = QtWidgets.QLabel() # Check for updates button self.check_for_updates_button = QtWidgets.QPushButton(strings._('gui_settings_autoupdate_check_button', True)) self.check_for_updates_button.clicked.connect(self.check_for_updates) # We can't check for updates if not connected to Tor if not self.onion.connected_to_tor: self.check_for_updates_button.setEnabled(False) # Autoupdate options layout autoupdate_group_layout = QtWidgets.QVBoxLayout() autoupdate_group_layout.addWidget(self.autoupdate_checkbox) autoupdate_group_layout.addWidget(self.autoupdate_timestamp) autoupdate_group_layout.addWidget(self.check_for_updates_button) autoupdate_group = QtWidgets.QGroupBox(strings._("gui_settings_autoupdate_label", True)) autoupdate_group.setLayout(autoupdate_group_layout) # Autoupdate is only available for Windows and Mac (Linux updates using package manager) if self.system != 'Windows' and self.system != 'Darwin': autoupdate_group.hide() # Connection type: either automatic, control port, or socket file # Bundled Tor self.connection_type_bundled_radio = QtWidgets.QRadioButton(strings._('gui_settings_connection_type_bundled_option', True)) self.connection_type_bundled_radio.toggled.connect(self.connection_type_bundled_toggled) # Bundled Tor doesn't work on dev mode in Windows or Mac if (self.system == 'Windows' or self.system == 'Darwin') and getattr(sys, 'onionshare_dev_mode', False): self.connection_type_bundled_radio.setEnabled(False) # Bridge options for bundled tor # No bridges option radio self.tor_bridges_no_bridges_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_no_bridges_radio_option', True)) self.tor_bridges_no_bridges_radio.toggled.connect(self.tor_bridges_no_bridges_radio_toggled) # obfs4 option radio # if the obfs4proxy binary is missing, we can't use obfs4 transports (self.tor_path, self.tor_geo_ip_file_path, self.tor_geo_ipv6_file_path, self.obfs4proxy_file_path) = common.get_tor_paths() if not os.path.isfile(self.obfs4proxy_file_path): self.tor_bridges_use_obfs4_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_obfs4_radio_option_no_obfs4proxy', True)) self.tor_bridges_use_obfs4_radio.setEnabled(False) else: self.tor_bridges_use_obfs4_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_obfs4_radio_option', True)) self.tor_bridges_use_obfs4_radio.toggled.connect(self.tor_bridges_use_obfs4_radio_toggled) # meek_lite-amazon option radio # if the obfs4proxy binary is missing, we can't use meek_lite-amazon transports (self.tor_path, self.tor_geo_ip_file_path, self.tor_geo_ipv6_file_path, self.obfs4proxy_file_path) = common.get_tor_paths() if not os.path.isfile(self.obfs4proxy_file_path): self.tor_bridges_use_meek_lite_amazon_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_meek_lite_amazon_radio_option_no_obfs4proxy', True)) self.tor_bridges_use_meek_lite_amazon_radio.setEnabled(False) else: self.tor_bridges_use_meek_lite_amazon_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_meek_lite_amazon_radio_option', True)) self.tor_bridges_use_meek_lite_amazon_radio.toggled.connect(self.tor_bridges_use_meek_lite_amazon_radio_toggled) # meek_lite-azure option radio # if the obfs4proxy binary is missing, we can't use meek_lite-azure transports (self.tor_path, self.tor_geo_ip_file_path, self.tor_geo_ipv6_file_path, self.obfs4proxy_file_path) = common.get_tor_paths() if not os.path.isfile(self.obfs4proxy_file_path): self.tor_bridges_use_meek_lite_azure_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_meek_lite_azure_radio_option_no_obfs4proxy', True)) self.tor_bridges_use_meek_lite_azure_radio.setEnabled(False) else: self.tor_bridges_use_meek_lite_azure_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_meek_lite_azure_radio_option', True)) self.tor_bridges_use_meek_lite_azure_radio.toggled.connect(self.tor_bridges_use_meek_lite_azure_radio_toggled) # meek_lite currently not supported on the version of obfs4proxy bundled with TorBrowser if self.system == 'Windows' or self.system == 'Darwin': self.tor_bridges_use_meek_lite_amazon_radio.hide() self.tor_bridges_use_meek_lite_azure_radio.hide() # Custom bridges radio and textbox self.tor_bridges_use_custom_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_custom_radio_option', True)) self.tor_bridges_use_custom_radio.toggled.connect(self.tor_bridges_use_custom_radio_toggled) self.tor_bridges_use_custom_label = QtWidgets.QLabel(strings._('gui_settings_tor_bridges_custom_label', True)) self.tor_bridges_use_custom_label.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) self.tor_bridges_use_custom_label.setOpenExternalLinks(True) self.tor_bridges_use_custom_textbox = QtWidgets.QPlainTextEdit() self.tor_bridges_use_custom_textbox.setMaximumHeight(200) self.tor_bridges_use_custom_textbox.setPlaceholderText('[address:port] [identifier]') tor_bridges_use_custom_textbox_options_layout = QtWidgets.QVBoxLayout() tor_bridges_use_custom_textbox_options_layout.addWidget(self.tor_bridges_use_custom_label) tor_bridges_use_custom_textbox_options_layout.addWidget(self.tor_bridges_use_custom_textbox) self.tor_bridges_use_custom_textbox_options = QtWidgets.QWidget() self.tor_bridges_use_custom_textbox_options.setLayout(tor_bridges_use_custom_textbox_options_layout) self.tor_bridges_use_custom_textbox_options.hide() # Bridges layout/widget bridges_layout = QtWidgets.QVBoxLayout() bridges_layout.addWidget(self.tor_bridges_no_bridges_radio) bridges_layout.addWidget(self.tor_bridges_use_obfs4_radio) bridges_layout.addWidget(self.tor_bridges_use_meek_lite_amazon_radio) bridges_layout.addWidget(self.tor_bridges_use_meek_lite_azure_radio) bridges_layout.addWidget(self.tor_bridges_use_custom_radio) bridges_layout.addWidget(self.tor_bridges_use_custom_textbox_options) self.bridges = QtWidgets.QWidget() self.bridges.setLayout(bridges_layout) # Automatic self.connection_type_automatic_radio = QtWidgets.QRadioButton(strings._('gui_settings_connection_type_automatic_option', True)) self.connection_type_automatic_radio.toggled.connect(self.connection_type_automatic_toggled) # Control port self.connection_type_control_port_radio = QtWidgets.QRadioButton(strings._('gui_settings_connection_type_control_port_option', True)) self.connection_type_control_port_radio.toggled.connect(self.connection_type_control_port_toggled) connection_type_control_port_extras_label = QtWidgets.QLabel(strings._('gui_settings_control_port_label', True)) self.connection_type_control_port_extras_address = QtWidgets.QLineEdit() self.connection_type_control_port_extras_port = QtWidgets.QLineEdit() connection_type_control_port_extras_layout = QtWidgets.QHBoxLayout() connection_type_control_port_extras_layout.addWidget(connection_type_control_port_extras_label) connection_type_control_port_extras_layout.addWidget(self.connection_type_control_port_extras_address) connection_type_control_port_extras_layout.addWidget(self.connection_type_control_port_extras_port) self.connection_type_control_port_extras = QtWidgets.QWidget() self.connection_type_control_port_extras.setLayout(connection_type_control_port_extras_layout) self.connection_type_control_port_extras.hide() # Socket file self.connection_type_socket_file_radio = QtWidgets.QRadioButton(strings._('gui_settings_connection_type_socket_file_option', True)) self.connection_type_socket_file_radio.toggled.connect(self.connection_type_socket_file_toggled) connection_type_socket_file_extras_label = QtWidgets.QLabel(strings._('gui_settings_socket_file_label', True)) self.connection_type_socket_file_extras_path = QtWidgets.QLineEdit() connection_type_socket_file_extras_layout = QtWidgets.QHBoxLayout() connection_type_socket_file_extras_layout.addWidget(connection_type_socket_file_extras_label) connection_type_socket_file_extras_layout.addWidget(self.connection_type_socket_file_extras_path) self.connection_type_socket_file_extras = QtWidgets.QWidget() self.connection_type_socket_file_extras.setLayout(connection_type_socket_file_extras_layout) self.connection_type_socket_file_extras.hide() # Tor SOCKS address and port gui_settings_socks_label = QtWidgets.QLabel(strings._('gui_settings_socks_label', True)) self.connection_type_socks_address = QtWidgets.QLineEdit() self.connection_type_socks_port = QtWidgets.QLineEdit() connection_type_socks_layout = QtWidgets.QHBoxLayout() connection_type_socks_layout.addWidget(gui_settings_socks_label) connection_type_socks_layout.addWidget(self.connection_type_socks_address) connection_type_socks_layout.addWidget(self.connection_type_socks_port) self.connection_type_socks = QtWidgets.QWidget() self.connection_type_socks.setLayout(connection_type_socks_layout) self.connection_type_socks.hide() # Authentication options # No authentication self.authenticate_no_auth_radio = QtWidgets.QRadioButton(strings._('gui_settings_authenticate_no_auth_option', True)) self.authenticate_no_auth_radio.toggled.connect(self.authenticate_no_auth_toggled) # Password self.authenticate_password_radio = QtWidgets.QRadioButton(strings._('gui_settings_authenticate_password_option', True)) self.authenticate_password_radio.toggled.connect(self.authenticate_password_toggled) authenticate_password_extras_label = QtWidgets.QLabel(strings._('gui_settings_password_label', True)) self.authenticate_password_extras_password = QtWidgets.QLineEdit('') authenticate_password_extras_layout = QtWidgets.QHBoxLayout() authenticate_password_extras_layout.addWidget(authenticate_password_extras_label) authenticate_password_extras_layout.addWidget(self.authenticate_password_extras_password) self.authenticate_password_extras = QtWidgets.QWidget() self.authenticate_password_extras.setLayout(authenticate_password_extras_layout) self.authenticate_password_extras.hide() # Authentication options layout authenticate_group_layout = QtWidgets.QVBoxLayout() authenticate_group_layout.addWidget(self.authenticate_no_auth_radio) authenticate_group_layout.addWidget(self.authenticate_password_radio) authenticate_group_layout.addWidget(self.authenticate_password_extras) self.authenticate_group = QtWidgets.QGroupBox(strings._("gui_settings_authenticate_label", True)) self.authenticate_group.setLayout(authenticate_group_layout) # Test tor settings button self.connection_type_test_button = QtWidgets.QPushButton(strings._('gui_settings_connection_type_test_button', True)) self.connection_type_test_button.clicked.connect(self.test_tor_clicked) # Put the radios into their own group so they are exclusive connection_type_radio_group_layout = QtWidgets.QVBoxLayout() connection_type_radio_group_layout.addWidget(self.connection_type_bundled_radio) connection_type_radio_group_layout.addWidget(self.connection_type_automatic_radio) connection_type_radio_group_layout.addWidget(self.connection_type_control_port_radio) connection_type_radio_group_layout.addWidget(self.connection_type_socket_file_radio) connection_type_radio_group = QtWidgets.QGroupBox(strings._("gui_settings_connection_type_label", True)) connection_type_radio_group.setLayout(connection_type_radio_group_layout) # Connection type layout connection_type_group_layout = QtWidgets.QVBoxLayout() connection_type_group_layout.addWidget(self.connection_type_control_port_extras) connection_type_group_layout.addWidget(self.connection_type_socket_file_extras) connection_type_group_layout.addWidget(self.connection_type_socks) connection_type_group_layout.addWidget(self.authenticate_group) connection_type_group_layout.addWidget(self.connection_type_test_button) connection_type_group = QtWidgets.QGroupBox() connection_type_group.setLayout(connection_type_group_layout) # The Bridges options are not exclusive (enabling Bridges offers obfs4 or custom bridges) connection_type_bridges_radio_group_layout = QtWidgets.QVBoxLayout() connection_type_bridges_radio_group_layout.addWidget(self.bridges) self.connection_type_bridges_radio_group = QtWidgets.QGroupBox(strings._("gui_settings_tor_bridges", True)) self.connection_type_bridges_radio_group.setLayout(connection_type_bridges_radio_group_layout) self.connection_type_bridges_radio_group.hide() # Buttons self.save_button = QtWidgets.QPushButton(strings._('gui_settings_button_save', True)) self.save_button.clicked.connect(self.save_clicked) self.cancel_button = QtWidgets.QPushButton(strings._('gui_settings_button_cancel', True)) self.cancel_button.clicked.connect(self.cancel_clicked) version_label = QtWidgets.QLabel('OnionShare {0:s}'.format(common.get_version())) version_label.setStyleSheet('color: #666666') self.help_button = QtWidgets.QPushButton(strings._('gui_settings_button_help', True)) self.help_button.clicked.connect(self.help_clicked) buttons_layout = QtWidgets.QHBoxLayout() buttons_layout.addWidget(version_label) buttons_layout.addWidget(self.help_button) buttons_layout.addStretch() buttons_layout.addWidget(self.save_button) buttons_layout.addWidget(self.cancel_button) # Tor network connection status self.tor_status = QtWidgets.QLabel() self.tor_status.setStyleSheet('background-color: #ffffff; color: #000000; padding: 10px') self.tor_status.hide() # Layout left_col_layout = QtWidgets.QVBoxLayout() left_col_layout.addWidget(sharing_group) left_col_layout.addWidget(stealth_group) left_col_layout.addWidget(autoupdate_group) left_col_layout.addStretch() right_col_layout = QtWidgets.QVBoxLayout() right_col_layout.addWidget(connection_type_radio_group) right_col_layout.addWidget(connection_type_group) right_col_layout.addWidget(self.connection_type_bridges_radio_group) right_col_layout.addWidget(self.tor_status) right_col_layout.addStretch() col_layout = QtWidgets.QHBoxLayout() col_layout.addLayout(left_col_layout) col_layout.addLayout(right_col_layout) layout = QtWidgets.QVBoxLayout() layout.addLayout(col_layout) layout.addLayout(buttons_layout) self.setLayout(layout) self.cancel_button.setFocus() # Load settings, and fill them in self.old_settings = Settings(self.config) self.old_settings.load() close_after_first_download = self.old_settings.get('close_after_first_download') if close_after_first_download: self.close_after_first_download_checkbox.setCheckState(QtCore.Qt.Checked) else: self.close_after_first_download_checkbox.setCheckState(QtCore.Qt.Unchecked) systray_notifications = self.old_settings.get('systray_notifications') if systray_notifications: self.systray_notifications_checkbox.setCheckState(QtCore.Qt.Checked) else: self.systray_notifications_checkbox.setCheckState(QtCore.Qt.Unchecked) shutdown_timeout = self.old_settings.get('shutdown_timeout') if shutdown_timeout: self.shutdown_timeout_checkbox.setCheckState(QtCore.Qt.Checked) else: self.shutdown_timeout_checkbox.setCheckState(QtCore.Qt.Unchecked) save_private_key = self.old_settings.get('save_private_key') if save_private_key: self.save_private_key_checkbox.setCheckState(QtCore.Qt.Checked) else: self.save_private_key_checkbox.setCheckState(QtCore.Qt.Unchecked) use_stealth = self.old_settings.get('use_stealth') if use_stealth: self.stealth_checkbox.setCheckState(QtCore.Qt.Checked) if save_private_key: hidservauth_details.show() self.hidservauth_copy_button.show() else: self.stealth_checkbox.setCheckState(QtCore.Qt.Unchecked) use_autoupdate = self.old_settings.get('use_autoupdate') if use_autoupdate: self.autoupdate_checkbox.setCheckState(QtCore.Qt.Checked) else: self.autoupdate_checkbox.setCheckState(QtCore.Qt.Unchecked) autoupdate_timestamp = self.old_settings.get('autoupdate_timestamp') self._update_autoupdate_timestamp(autoupdate_timestamp) connection_type = self.old_settings.get('connection_type') if connection_type == 'bundled': if self.connection_type_bundled_radio.isEnabled(): self.connection_type_bundled_radio.setChecked(True) else: # If bundled tor is disabled, fallback to automatic self.connection_type_automatic_radio.setChecked(True) elif connection_type == 'automatic': self.connection_type_automatic_radio.setChecked(True) elif connection_type == 'control_port': self.connection_type_control_port_radio.setChecked(True) elif connection_type == 'socket_file': self.connection_type_socket_file_radio.setChecked(True) self.connection_type_control_port_extras_address.setText(self.old_settings.get('control_port_address')) self.connection_type_control_port_extras_port.setText(str(self.old_settings.get('control_port_port'))) self.connection_type_socket_file_extras_path.setText(self.old_settings.get('socket_file_path')) self.connection_type_socks_address.setText(self.old_settings.get('socks_address')) self.connection_type_socks_port.setText(str(self.old_settings.get('socks_port'))) auth_type = self.old_settings.get('auth_type') if auth_type == 'no_auth': self.authenticate_no_auth_radio.setChecked(True) elif auth_type == 'password': self.authenticate_password_radio.setChecked(True) self.authenticate_password_extras_password.setText(self.old_settings.get('auth_password')) if self.old_settings.get('no_bridges'): self.tor_bridges_no_bridges_radio.setChecked(True) self.tor_bridges_use_obfs4_radio.setChecked(False) self.tor_bridges_use_meek_lite_amazon_radio.setChecked(False) self.tor_bridges_use_meek_lite_azure_radio.setChecked(False) self.tor_bridges_use_custom_radio.setChecked(False) else: self.tor_bridges_no_bridges_radio.setChecked(False) self.tor_bridges_use_obfs4_radio.setChecked(self.old_settings.get('tor_bridges_use_obfs4')) self.tor_bridges_use_meek_lite_amazon_radio.setChecked(self.old_settings.get('tor_bridges_use_meek_lite_amazon')) self.tor_bridges_use_meek_lite_azure_radio.setChecked(self.old_settings.get('tor_bridges_use_meek_lite_azure')) if self.old_settings.get('tor_bridges_use_custom_bridges'): self.tor_bridges_use_custom_radio.setChecked(True) # Remove the 'Bridge' lines at the start of each bridge. # They are added automatically to provide compatibility with # copying/pasting bridges provided from https://bridges.torproject.org new_bridges = [] bridges = self.old_settings.get('tor_bridges_use_custom_bridges').split('Bridge ') for bridge in bridges: new_bridges.append(bridge) new_bridges = ''.join(new_bridges) self.tor_bridges_use_custom_textbox.setPlainText(new_bridges)
def test_get_tor_paths_linux(self, platform_linux): assert (common.get_tor_paths() == ('/usr/bin/tor', '/usr/share/tor/geoip', '/usr/share/tor/geoip6'))
def __init__(self, onion, qtapp, config=False): super(SettingsDialog, self).__init__() common.log('SettingsDialog', '__init__') self.onion = onion self.qtapp = qtapp self.config = config self.setModal(True) self.setWindowTitle(strings._('gui_settings_window_title', True)) self.setWindowIcon( QtGui.QIcon(common.get_resource_path('images/logo.png'))) system = platform.system() # Sharing options # Close after first download self.close_after_first_download_checkbox = QtWidgets.QCheckBox() self.close_after_first_download_checkbox.setCheckState( QtCore.Qt.Checked) self.close_after_first_download_checkbox.setText( strings._("gui_settings_close_after_first_download_option", True)) # Whether or not to show systray notifications self.systray_notifications_checkbox = QtWidgets.QCheckBox() self.systray_notifications_checkbox.setCheckState(QtCore.Qt.Checked) self.systray_notifications_checkbox.setText( strings._("gui_settings_systray_notifications", True)) # Whether or not to save the Onion private key for reuse self.save_private_key_checkbox = QtWidgets.QCheckBox() self.save_private_key_checkbox.setCheckState(QtCore.Qt.Unchecked) self.save_private_key_checkbox.setText( strings._("gui_save_private_key_checkbox", True)) # Sharing options layout sharing_group_layout = QtWidgets.QVBoxLayout() sharing_group_layout.addWidget( self.close_after_first_download_checkbox) sharing_group_layout.addWidget(self.systray_notifications_checkbox) sharing_group_layout.addWidget(self.save_private_key_checkbox) sharing_group = QtWidgets.QGroupBox( strings._("gui_settings_sharing_label", True)) sharing_group.setLayout(sharing_group_layout) # Stealth options # 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)) hidservauth_details = QtWidgets.QLabel( strings._('gui_settings_stealth_hidservauth_string', True)) hidservauth_details.setWordWrap(True) hidservauth_details.hide() self.hidservauth_copy_button = QtWidgets.QPushButton( strings._('gui_copy_hidservauth', True)) self.hidservauth_copy_button.clicked.connect( self.hidservauth_copy_button_clicked) self.hidservauth_copy_button.hide() # Stealth options layout stealth_group_layout = QtWidgets.QVBoxLayout() stealth_group_layout.addWidget(stealth_details) stealth_group_layout.addWidget(self.stealth_checkbox) stealth_group_layout.addWidget(hidservauth_details) stealth_group_layout.addWidget(self.hidservauth_copy_button) stealth_group = QtWidgets.QGroupBox( strings._("gui_settings_stealth_label", True)) stealth_group.setLayout(stealth_group_layout) # Automatic updates options # Autoupdate self.autoupdate_checkbox = QtWidgets.QCheckBox() self.autoupdate_checkbox.setCheckState(QtCore.Qt.Unchecked) self.autoupdate_checkbox.setText( strings._("gui_settings_autoupdate_option", True)) # Last update time self.autoupdate_timestamp = QtWidgets.QLabel() # Check for updates button self.check_for_updates_button = QtWidgets.QPushButton( strings._('gui_settings_autoupdate_check_button', True)) self.check_for_updates_button.clicked.connect(self.check_for_updates) # We can't check for updates if not connected to Tor if not self.onion.connected_to_tor: self.check_for_updates_button.setEnabled(False) # Autoupdate options layout autoupdate_group_layout = QtWidgets.QVBoxLayout() autoupdate_group_layout.addWidget(self.autoupdate_checkbox) autoupdate_group_layout.addWidget(self.autoupdate_timestamp) autoupdate_group_layout.addWidget(self.check_for_updates_button) autoupdate_group = QtWidgets.QGroupBox( strings._("gui_settings_autoupdate_label", True)) autoupdate_group.setLayout(autoupdate_group_layout) # Autoupdate is only available for Windows and Mac (Linux updates using package manager) if system != 'Windows' and system != 'Darwin': autoupdate_group.hide() # Connection type: either automatic, control port, or socket file # Bundled Tor self.connection_type_bundled_radio = QtWidgets.QRadioButton( strings._('gui_settings_connection_type_bundled_option', True)) self.connection_type_bundled_radio.toggled.connect( self.connection_type_bundled_toggled) # Bundled Tor doesn't work on dev mode in Windows or Mac if (system == 'Windows' or system == 'Darwin') and getattr( sys, 'onionshare_dev_mode', False): self.connection_type_bundled_radio.setEnabled(False) # Bridge options for bundled tor # No bridges option radio self.tor_bridges_no_bridges_radio = QtWidgets.QRadioButton( strings._('gui_settings_tor_bridges_no_bridges_radio_option', True)) self.tor_bridges_no_bridges_radio.toggled.connect( self.tor_bridges_no_bridges_radio_toggled) # obfs4 option radio # if the obfs4proxy binary is missing, we can't use obfs4 transports (self.tor_path, self.tor_geo_ip_file_path, self.tor_geo_ipv6_file_path, self.obfs4proxy_file_path) = common.get_tor_paths() if not os.path.isfile(self.obfs4proxy_file_path): self.tor_bridges_use_obfs4_radio = QtWidgets.QRadioButton( strings. _('gui_settings_tor_bridges_obfs4_radio_option_no_obfs4proxy', True)) self.tor_bridges_use_obfs4_radio.setEnabled(False) else: self.tor_bridges_use_obfs4_radio = QtWidgets.QRadioButton( strings._('gui_settings_tor_bridges_obfs4_radio_option', True)) self.tor_bridges_use_obfs4_radio.toggled.connect( self.tor_bridges_use_obfs4_radio_toggled) # Custom bridges radio and textbox self.tor_bridges_use_custom_radio = QtWidgets.QRadioButton( strings._('gui_settings_tor_bridges_custom_radio_option', True)) self.tor_bridges_use_custom_radio.toggled.connect( self.tor_bridges_use_custom_radio_toggled) self.tor_bridges_use_custom_label = QtWidgets.QLabel( strings._('gui_settings_tor_bridges_custom_label', True)) self.tor_bridges_use_custom_label.setTextInteractionFlags( QtCore.Qt.TextBrowserInteraction) self.tor_bridges_use_custom_label.setOpenExternalLinks(True) self.tor_bridges_use_custom_textbox = QtWidgets.QPlainTextEdit() self.tor_bridges_use_custom_textbox.setMaximumHeight(200) self.tor_bridges_use_custom_textbox.setPlaceholderText( '[address:port] [identifier]') tor_bridges_use_custom_textbox_options_layout = QtWidgets.QVBoxLayout() tor_bridges_use_custom_textbox_options_layout.addWidget( self.tor_bridges_use_custom_label) tor_bridges_use_custom_textbox_options_layout.addWidget( self.tor_bridges_use_custom_textbox) self.tor_bridges_use_custom_textbox_options = QtWidgets.QWidget() self.tor_bridges_use_custom_textbox_options.setLayout( tor_bridges_use_custom_textbox_options_layout) self.tor_bridges_use_custom_textbox_options.hide() # Bridges layout/widget bridges_layout = QtWidgets.QVBoxLayout() bridges_layout.addWidget(self.tor_bridges_no_bridges_radio) bridges_layout.addWidget(self.tor_bridges_use_obfs4_radio) bridges_layout.addWidget(self.tor_bridges_use_custom_radio) bridges_layout.addWidget(self.tor_bridges_use_custom_textbox_options) self.bridges = QtWidgets.QWidget() self.bridges.setLayout(bridges_layout) # Automatic self.connection_type_automatic_radio = QtWidgets.QRadioButton( strings._('gui_settings_connection_type_automatic_option', True)) self.connection_type_automatic_radio.toggled.connect( self.connection_type_automatic_toggled) # Control port self.connection_type_control_port_radio = QtWidgets.QRadioButton( strings._('gui_settings_connection_type_control_port_option', True)) self.connection_type_control_port_radio.toggled.connect( self.connection_type_control_port_toggled) connection_type_control_port_extras_label = QtWidgets.QLabel( strings._('gui_settings_control_port_label', True)) self.connection_type_control_port_extras_address = QtWidgets.QLineEdit( ) self.connection_type_control_port_extras_port = QtWidgets.QLineEdit() connection_type_control_port_extras_layout = QtWidgets.QHBoxLayout() connection_type_control_port_extras_layout.addWidget( connection_type_control_port_extras_label) connection_type_control_port_extras_layout.addWidget( self.connection_type_control_port_extras_address) connection_type_control_port_extras_layout.addWidget( self.connection_type_control_port_extras_port) self.connection_type_control_port_extras = QtWidgets.QWidget() self.connection_type_control_port_extras.setLayout( connection_type_control_port_extras_layout) self.connection_type_control_port_extras.hide() # Socket file self.connection_type_socket_file_radio = QtWidgets.QRadioButton( strings._('gui_settings_connection_type_socket_file_option', True)) self.connection_type_socket_file_radio.toggled.connect( self.connection_type_socket_file_toggled) connection_type_socket_file_extras_label = QtWidgets.QLabel( strings._('gui_settings_socket_file_label', True)) self.connection_type_socket_file_extras_path = QtWidgets.QLineEdit() connection_type_socket_file_extras_layout = QtWidgets.QHBoxLayout() connection_type_socket_file_extras_layout.addWidget( connection_type_socket_file_extras_label) connection_type_socket_file_extras_layout.addWidget( self.connection_type_socket_file_extras_path) self.connection_type_socket_file_extras = QtWidgets.QWidget() self.connection_type_socket_file_extras.setLayout( connection_type_socket_file_extras_layout) self.connection_type_socket_file_extras.hide() # Tor SOCKS address and port gui_settings_socks_label = QtWidgets.QLabel( strings._('gui_settings_socks_label', True)) self.connection_type_socks_address = QtWidgets.QLineEdit() self.connection_type_socks_port = QtWidgets.QLineEdit() connection_type_socks_layout = QtWidgets.QHBoxLayout() connection_type_socks_layout.addWidget(gui_settings_socks_label) connection_type_socks_layout.addWidget( self.connection_type_socks_address) connection_type_socks_layout.addWidget(self.connection_type_socks_port) self.connection_type_socks = QtWidgets.QWidget() self.connection_type_socks.setLayout(connection_type_socks_layout) self.connection_type_socks.hide() # Authentication options # No authentication self.authenticate_no_auth_radio = QtWidgets.QRadioButton( strings._('gui_settings_authenticate_no_auth_option', True)) self.authenticate_no_auth_radio.toggled.connect( self.authenticate_no_auth_toggled) # Password self.authenticate_password_radio = QtWidgets.QRadioButton( strings._('gui_settings_authenticate_password_option', True)) self.authenticate_password_radio.toggled.connect( self.authenticate_password_toggled) authenticate_password_extras_label = QtWidgets.QLabel( strings._('gui_settings_password_label', True)) self.authenticate_password_extras_password = QtWidgets.QLineEdit('') authenticate_password_extras_layout = QtWidgets.QHBoxLayout() authenticate_password_extras_layout.addWidget( authenticate_password_extras_label) authenticate_password_extras_layout.addWidget( self.authenticate_password_extras_password) self.authenticate_password_extras = QtWidgets.QWidget() self.authenticate_password_extras.setLayout( authenticate_password_extras_layout) self.authenticate_password_extras.hide() # Authentication options layout authenticate_group_layout = QtWidgets.QVBoxLayout() authenticate_group_layout.addWidget(self.authenticate_no_auth_radio) authenticate_group_layout.addWidget(self.authenticate_password_radio) authenticate_group_layout.addWidget(self.authenticate_password_extras) self.authenticate_group = QtWidgets.QGroupBox( strings._("gui_settings_authenticate_label", True)) self.authenticate_group.setLayout(authenticate_group_layout) # Test tor settings button self.connection_type_test_button = QtWidgets.QPushButton( strings._('gui_settings_connection_type_test_button', True)) self.connection_type_test_button.clicked.connect(self.test_tor_clicked) # Put the radios into their own group so they are exclusive connection_type_radio_group_layout = QtWidgets.QVBoxLayout() connection_type_radio_group_layout.addWidget( self.connection_type_bundled_radio) connection_type_radio_group_layout.addWidget( self.connection_type_automatic_radio) connection_type_radio_group_layout.addWidget( self.connection_type_control_port_radio) connection_type_radio_group_layout.addWidget( self.connection_type_socket_file_radio) connection_type_radio_group = QtWidgets.QGroupBox( strings._("gui_settings_connection_type_label", True)) connection_type_radio_group.setLayout( connection_type_radio_group_layout) # Connection type layout connection_type_group_layout = QtWidgets.QVBoxLayout() connection_type_group_layout.addWidget( self.connection_type_control_port_extras) connection_type_group_layout.addWidget( self.connection_type_socket_file_extras) connection_type_group_layout.addWidget(self.connection_type_socks) connection_type_group_layout.addWidget(self.authenticate_group) connection_type_group_layout.addWidget( self.connection_type_test_button) connection_type_group = QtWidgets.QGroupBox() connection_type_group.setLayout(connection_type_group_layout) # The Bridges options are not exclusive (enabling Bridges offers obfs4 or custom bridges) connection_type_bridges_radio_group_layout = QtWidgets.QVBoxLayout() connection_type_bridges_radio_group_layout.addWidget(self.bridges) self.connection_type_bridges_radio_group = QtWidgets.QGroupBox( strings._("gui_settings_tor_bridges", True)) self.connection_type_bridges_radio_group.setLayout( connection_type_bridges_radio_group_layout) self.connection_type_bridges_radio_group.hide() # Buttons self.save_button = QtWidgets.QPushButton( strings._('gui_settings_button_save', True)) self.save_button.clicked.connect(self.save_clicked) self.cancel_button = QtWidgets.QPushButton( strings._('gui_settings_button_cancel', True)) self.cancel_button.clicked.connect(self.cancel_clicked) self.help_button = QtWidgets.QPushButton( strings._('gui_settings_button_help', True)) self.help_button.clicked.connect(self.help_clicked) buttons_layout = QtWidgets.QHBoxLayout() buttons_layout.addWidget(self.help_button) buttons_layout.addStretch() buttons_layout.addWidget(self.save_button) buttons_layout.addWidget(self.cancel_button) # Tor network connection status self.tor_status = QtWidgets.QLabel() self.tor_status.setStyleSheet( 'background-color: #ffffff; color: #000000; padding: 10px') self.tor_status.hide() # Layout left_col_layout = QtWidgets.QVBoxLayout() left_col_layout.addWidget(sharing_group) left_col_layout.addWidget(stealth_group) left_col_layout.addWidget(autoupdate_group) left_col_layout.addStretch() right_col_layout = QtWidgets.QVBoxLayout() right_col_layout.addWidget(connection_type_radio_group) right_col_layout.addWidget(connection_type_group) right_col_layout.addWidget(self.connection_type_bridges_radio_group) right_col_layout.addWidget(self.tor_status) right_col_layout.addStretch() col_layout = QtWidgets.QHBoxLayout() col_layout.addLayout(left_col_layout) col_layout.addLayout(right_col_layout) layout = QtWidgets.QVBoxLayout() layout.addLayout(col_layout) layout.addLayout(buttons_layout) self.setLayout(layout) self.cancel_button.setFocus() # Load settings, and fill them in self.old_settings = Settings(self.config) self.old_settings.load() close_after_first_download = self.old_settings.get( 'close_after_first_download') if close_after_first_download: self.close_after_first_download_checkbox.setCheckState( QtCore.Qt.Checked) else: self.close_after_first_download_checkbox.setCheckState( QtCore.Qt.Unchecked) systray_notifications = self.old_settings.get('systray_notifications') if systray_notifications: self.systray_notifications_checkbox.setCheckState( QtCore.Qt.Checked) else: self.systray_notifications_checkbox.setCheckState( QtCore.Qt.Unchecked) save_private_key = self.old_settings.get('save_private_key') if save_private_key: self.save_private_key_checkbox.setCheckState(QtCore.Qt.Checked) else: self.save_private_key_checkbox.setCheckState(QtCore.Qt.Unchecked) use_stealth = self.old_settings.get('use_stealth') if use_stealth: self.stealth_checkbox.setCheckState(QtCore.Qt.Checked) if save_private_key: hidservauth_details.show() self.hidservauth_copy_button.show() else: self.stealth_checkbox.setCheckState(QtCore.Qt.Unchecked) use_autoupdate = self.old_settings.get('use_autoupdate') if use_autoupdate: self.autoupdate_checkbox.setCheckState(QtCore.Qt.Checked) else: self.autoupdate_checkbox.setCheckState(QtCore.Qt.Unchecked) autoupdate_timestamp = self.old_settings.get('autoupdate_timestamp') self._update_autoupdate_timestamp(autoupdate_timestamp) connection_type = self.old_settings.get('connection_type') if connection_type == 'bundled': if self.connection_type_bundled_radio.isEnabled(): self.connection_type_bundled_radio.setChecked(True) else: # If bundled tor is disabled, fallback to automatic self.connection_type_automatic_radio.setChecked(True) elif connection_type == 'automatic': self.connection_type_automatic_radio.setChecked(True) elif connection_type == 'control_port': self.connection_type_control_port_radio.setChecked(True) elif connection_type == 'socket_file': self.connection_type_socket_file_radio.setChecked(True) self.connection_type_control_port_extras_address.setText( self.old_settings.get('control_port_address')) self.connection_type_control_port_extras_port.setText( str(self.old_settings.get('control_port_port'))) self.connection_type_socket_file_extras_path.setText( self.old_settings.get('socket_file_path')) self.connection_type_socks_address.setText( self.old_settings.get('socks_address')) self.connection_type_socks_port.setText( str(self.old_settings.get('socks_port'))) auth_type = self.old_settings.get('auth_type') if auth_type == 'no_auth': self.authenticate_no_auth_radio.setChecked(True) elif auth_type == 'password': self.authenticate_password_radio.setChecked(True) self.authenticate_password_extras_password.setText( self.old_settings.get('auth_password')) if self.old_settings.get('no_bridges'): self.tor_bridges_no_bridges_radio.setChecked(True) self.tor_bridges_use_obfs4_radio.setChecked(False) self.tor_bridges_use_custom_radio.setChecked(False) else: self.tor_bridges_no_bridges_radio.setChecked(False) self.tor_bridges_use_obfs4_radio.setChecked( self.old_settings.get('tor_bridges_use_obfs4')) if self.old_settings.get('tor_bridges_use_custom_bridges'): self.tor_bridges_use_custom_radio.setChecked(True) # Remove the 'Bridge' lines at the start of each bridge. # They are added automatically to provide compatibility with # copying/pasting bridges provided from https://bridges.torproject.org new_bridges = [] bridges = self.old_settings.get( 'tor_bridges_use_custom_bridges').split('Bridge ') for bridge in bridges: new_bridges.append(bridge) new_bridges = ''.join(new_bridges) self.tor_bridges_use_custom_textbox.setPlainText(new_bridges)