mirror of
https://github.com/onionshare/onionshare.git
synced 2025-01-10 03:37:28 -03:00
Initial work on supporting the option to automatically attempt to fetch bridges based on the user's location if Tor fails to connect (censorship circumvention)
This commit is contained in:
parent
d88005d550
commit
b727a9651f
5 changed files with 54 additions and 5 deletions
|
@ -113,6 +113,7 @@ class Settings(object):
|
|||
"persistent_tabs": [],
|
||||
"locale": None, # this gets defined in fill_in_defaults()
|
||||
"theme": 0,
|
||||
"censorship_circumvention": False,
|
||||
}
|
||||
self._settings = {}
|
||||
self.fill_in_defaults()
|
||||
|
|
|
@ -36,6 +36,7 @@ class TestSettings:
|
|||
"bridges_custom": "",
|
||||
"persistent_tabs": [],
|
||||
"theme": 0,
|
||||
"censorship_circumvention": False,
|
||||
}
|
||||
for key in settings_obj._settings:
|
||||
# Skip locale, it will not always default to the same thing
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
"gui_settings_tor_bridges": "Connect using a Tor bridge?",
|
||||
"gui_settings_tor_bridges_label": "Bridges help you access the Tor Network in places where Tor is blocked. Depending on where you are, one bridge may work better than another.",
|
||||
"gui_settings_bridge_use_checkbox": "Use a bridge",
|
||||
"gui_settings_censorship_circumvention_checkbox": "Attempt to automatically find a bridge based on your country if Tor fails to connect",
|
||||
"gui_settings_bridge_radio_builtin": "Select a built-in bridge",
|
||||
"gui_settings_bridge_none_radio_option": "Don't use a bridge",
|
||||
"gui_settings_meek_lite_expensive_warning": "Warning: The meek-azure bridges are very costly for the Tor Project to run.<br><br>Only use them if unable to connect to Tor directly, via obfs4 transports, or other normal bridges.",
|
||||
|
|
|
@ -41,7 +41,7 @@ from onionshare_cli.onion import (
|
|||
from . import strings
|
||||
from .gui_common import GuiCommon
|
||||
from .widgets import Alert
|
||||
|
||||
from onionshare_cli.censorship import CensorshipCircumvention
|
||||
|
||||
class TorConnectionDialog(QtWidgets.QProgressDialog):
|
||||
"""
|
||||
|
@ -165,7 +165,7 @@ class TorConnectionWidget(QtWidgets.QWidget):
|
|||
success = QtCore.Signal()
|
||||
fail = QtCore.Signal(str)
|
||||
|
||||
def __init__(self, common, status_bar):
|
||||
def __init__(self, common, status_bar, meek):
|
||||
super(TorConnectionWidget, self).__init__(None)
|
||||
self.common = common
|
||||
self.common.log("TorConnectionWidget", "__init__")
|
||||
|
@ -181,6 +181,8 @@ class TorConnectionWidget(QtWidgets.QWidget):
|
|||
)
|
||||
self.cancel_button.clicked.connect(self.cancel_clicked)
|
||||
|
||||
self.meek = meek
|
||||
|
||||
progress_layout = QtWidgets.QHBoxLayout()
|
||||
progress_layout.addWidget(self.progress)
|
||||
progress_layout.addWidget(self.cancel_button)
|
||||
|
@ -263,7 +265,30 @@ class TorConnectionWidget(QtWidgets.QWidget):
|
|||
def _error_connecting_to_tor(self, msg):
|
||||
self.common.log("TorConnectionWidget", "_error_connecting_to_tor")
|
||||
self.active = False
|
||||
self.fail.emit(msg)
|
||||
# If we are allowed to try automatically resolving connection issues
|
||||
# (e.g possible censorship) by obtaining bridges for the user, do so
|
||||
if self.settings.get("censorship_circumvention"):
|
||||
# Automatically try to obtain bridges from the Censorship Circumvention API
|
||||
self.common.log("TorConnectionWidget", "_error_connecting_to_tor", "Trying to automatically obtain bridges")
|
||||
self.meek.start()
|
||||
self.censorship_circumvention = CensorshipCircumvention(self.common, self.meek)
|
||||
request_bridges = self.censorship_circumvention.request_settings(country="cn")
|
||||
if request_bridges:
|
||||
# @TODO there might be several bridges
|
||||
bridges = request_bridges["settings"][0]["bridges"]["bridge_strings"][0]
|
||||
self.common.log("TorConnectionWidget", "_error_connecting_to_tor", f"Obtained bridges: {bridges}")
|
||||
self.settings.set("bridges_enabled", True)
|
||||
self.settings.set("bridges_type", "custom")
|
||||
# @TODO there might be several bridges
|
||||
self.settings.set("bridges_custom", bridges)
|
||||
self.common.log("TorConnectionWidget", "_error_connecting_to_tor", "Starting Tor again")
|
||||
self.settings.save()
|
||||
# Now try and connect again
|
||||
self.start()
|
||||
else:
|
||||
self.fail.emit()
|
||||
else:
|
||||
self.fail.emit()
|
||||
|
||||
|
||||
class TorConnectionThread(QtCore.QThread):
|
||||
|
|
|
@ -91,6 +91,12 @@ class TorSettingsTab(QtWidgets.QWidget):
|
|||
self.bridge_use_checkbox.stateChanged.connect(
|
||||
self.bridge_use_checkbox_state_changed
|
||||
)
|
||||
self.censorship_circumvention_checkbox = QtWidgets.QCheckBox(
|
||||
strings._("gui_settings_censorship_circumvention_checkbox")
|
||||
)
|
||||
self.censorship_circumvention_checkbox.stateChanged.connect(
|
||||
self.censorship_circumvention_checkbox_state_changed
|
||||
)
|
||||
|
||||
# Built-in bridge
|
||||
self.bridge_builtin_radio = QtWidgets.QRadioButton(
|
||||
|
@ -164,6 +170,7 @@ class TorSettingsTab(QtWidgets.QWidget):
|
|||
bridges_layout = QtWidgets.QVBoxLayout()
|
||||
bridges_layout.addWidget(bridges_label)
|
||||
bridges_layout.addWidget(self.bridge_use_checkbox)
|
||||
bridges_layout.addWidget(self.censorship_circumvention_checkbox)
|
||||
bridges_layout.addWidget(self.bridge_settings)
|
||||
|
||||
self.bridges = QtWidgets.QWidget()
|
||||
|
@ -330,7 +337,7 @@ class TorSettingsTab(QtWidgets.QWidget):
|
|||
columns_wrapper.setLayout(columns_layout)
|
||||
|
||||
# Tor connection widget
|
||||
self.tor_con = TorConnectionWidget(self.common, self.status_bar)
|
||||
self.tor_con = TorConnectionWidget(self.common, self.status_bar, self.meek)
|
||||
self.tor_con.success.connect(self.tor_con_success)
|
||||
self.tor_con.fail.connect(self.tor_con_fail)
|
||||
self.tor_con.hide()
|
||||
|
@ -430,6 +437,7 @@ class TorSettingsTab(QtWidgets.QWidget):
|
|||
|
||||
if self.old_settings.get("bridges_enabled"):
|
||||
self.bridge_use_checkbox.setCheckState(QtCore.Qt.Checked)
|
||||
self.censorship_circumvention_checkbox.setCheckState(QtCore.Qt.Checked)
|
||||
self.bridge_settings.show()
|
||||
|
||||
bridges_type = self.old_settings.get("bridges_type")
|
||||
|
@ -506,6 +514,16 @@ class TorSettingsTab(QtWidgets.QWidget):
|
|||
else:
|
||||
self.bridge_settings.hide()
|
||||
|
||||
def censorship_circumvention_checkbox_state_changed(self, state):
|
||||
"""
|
||||
'Allow censorship circumvention (automatic bridges)' checkbox changed
|
||||
"""
|
||||
# Turning on censorship circumvention through the act of
|
||||
# automatic bridge selection, implicitly means enabling
|
||||
# bridges.
|
||||
if state == QtCore.Qt.Checked:
|
||||
self.bridge_use_checkbox.setCheckState(QtCore.Qt.Checked)
|
||||
|
||||
def bridge_builtin_radio_toggled(self, checked):
|
||||
"""
|
||||
'Select a built-in bridge' radio button toggled
|
||||
|
@ -812,6 +830,9 @@ class TorSettingsTab(QtWidgets.QWidget):
|
|||
if self.bridge_use_checkbox.checkState() == QtCore.Qt.Checked:
|
||||
settings.set("bridges_enabled", True)
|
||||
|
||||
if self.censorship_circumvention_checkbox.checkState() == QtCore.Qt.Checked:
|
||||
settings.set("censorship_circumvention", True)
|
||||
|
||||
if self.bridge_builtin_radio.isChecked():
|
||||
settings.set("bridges_type", "built-in")
|
||||
|
||||
|
|
Loading…
Reference in a new issue