mirror of
https://github.com/onionshare/onionshare.git
synced 2025-01-10 03:37:28 -03:00
Merge branch 'develop' of github.com:onionshare/onionshare into windows-tweaks
This commit is contained in:
commit
ca5d173790
5 changed files with 93 additions and 80 deletions
|
@ -19,8 +19,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
"""
|
"""
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from .meek import MeekNotRunning
|
|
||||||
|
|
||||||
|
|
||||||
class CensorshipCircumventionError(Exception):
|
class CensorshipCircumventionError(Exception):
|
||||||
"""
|
"""
|
||||||
|
@ -47,15 +45,12 @@ class CensorshipCircumvention(object):
|
||||||
self.api_proxies = {}
|
self.api_proxies = {}
|
||||||
if meek:
|
if meek:
|
||||||
self.meek = meek
|
self.meek = meek
|
||||||
if not self.meek.meek_proxies:
|
self.common.log(
|
||||||
raise MeekNotRunning()
|
"CensorshipCircumvention",
|
||||||
else:
|
"__init__",
|
||||||
self.common.log(
|
"Using Meek with CensorshipCircumvention API",
|
||||||
"CensorshipCircumvention",
|
)
|
||||||
"__init__",
|
self.api_proxies = self.meek.meek_proxies
|
||||||
"Using Meek with CensorshipCircumvention API",
|
|
||||||
)
|
|
||||||
self.api_proxies = self.meek.meek_proxies
|
|
||||||
if onion:
|
if onion:
|
||||||
self.onion = onion
|
self.onion = onion
|
||||||
if not self.onion.is_authenticated:
|
if not self.onion.is_authenticated:
|
||||||
|
@ -100,7 +95,7 @@ class CensorshipCircumvention(object):
|
||||||
if r.status_code != 200:
|
if r.status_code != 200:
|
||||||
self.common.log(
|
self.common.log(
|
||||||
"CensorshipCircumvention",
|
"CensorshipCircumvention",
|
||||||
"censorship_obtain_map",
|
"request_map",
|
||||||
f"status_code={r.status_code}",
|
f"status_code={r.status_code}",
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
|
@ -110,7 +105,7 @@ class CensorshipCircumvention(object):
|
||||||
if "errors" in result:
|
if "errors" in result:
|
||||||
self.common.log(
|
self.common.log(
|
||||||
"CensorshipCircumvention",
|
"CensorshipCircumvention",
|
||||||
"censorship_obtain_map",
|
"request_map",
|
||||||
f"errors={result['errors']}",
|
f"errors={result['errors']}",
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
|
@ -138,7 +133,7 @@ class CensorshipCircumvention(object):
|
||||||
if country:
|
if country:
|
||||||
self.common.log(
|
self.common.log(
|
||||||
"CensorshipCircumvention",
|
"CensorshipCircumvention",
|
||||||
"censorship_obtain_settings",
|
"request_settings",
|
||||||
f"Trying to obtain bridges for country={country}",
|
f"Trying to obtain bridges for country={country}",
|
||||||
)
|
)
|
||||||
data = {"country": country}
|
data = {"country": country}
|
||||||
|
@ -154,7 +149,7 @@ class CensorshipCircumvention(object):
|
||||||
if r.status_code != 200:
|
if r.status_code != 200:
|
||||||
self.common.log(
|
self.common.log(
|
||||||
"CensorshipCircumvention",
|
"CensorshipCircumvention",
|
||||||
"censorship_obtain_settings",
|
"request_settings",
|
||||||
f"status_code={r.status_code}",
|
f"status_code={r.status_code}",
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
|
@ -164,7 +159,7 @@ class CensorshipCircumvention(object):
|
||||||
if "errors" in result:
|
if "errors" in result:
|
||||||
self.common.log(
|
self.common.log(
|
||||||
"CensorshipCircumvention",
|
"CensorshipCircumvention",
|
||||||
"censorship_obtain_settings",
|
"request_settings",
|
||||||
f"errors={result['errors']}",
|
f"errors={result['errors']}",
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
|
@ -175,7 +170,7 @@ class CensorshipCircumvention(object):
|
||||||
if not "settings" in result:
|
if not "settings" in result:
|
||||||
self.common.log(
|
self.common.log(
|
||||||
"CensorshipCircumvention",
|
"CensorshipCircumvention",
|
||||||
"censorship_obtain_settings",
|
"request_settings",
|
||||||
"No settings found for this country",
|
"No settings found for this country",
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
|
@ -200,7 +195,7 @@ class CensorshipCircumvention(object):
|
||||||
if r.status_code != 200:
|
if r.status_code != 200:
|
||||||
self.common.log(
|
self.common.log(
|
||||||
"CensorshipCircumvention",
|
"CensorshipCircumvention",
|
||||||
"censorship_obtain_builtin_bridges",
|
"request_builtin_bridges",
|
||||||
f"status_code={r.status_code}",
|
f"status_code={r.status_code}",
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
|
@ -210,7 +205,7 @@ class CensorshipCircumvention(object):
|
||||||
if "errors" in result:
|
if "errors" in result:
|
||||||
self.common.log(
|
self.common.log(
|
||||||
"CensorshipCircumvention",
|
"CensorshipCircumvention",
|
||||||
"censorship_obtain_builtin_bridges",
|
"request_builtin_bridges",
|
||||||
f"errors={result['errors']}",
|
f"errors={result['errors']}",
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
|
@ -237,42 +232,15 @@ class CensorshipCircumvention(object):
|
||||||
f"Obtained bridges: {bridges}",
|
f"Obtained bridges: {bridges}",
|
||||||
)
|
)
|
||||||
bridge_strings = bridges["bridge_strings"]
|
bridge_strings = bridges["bridge_strings"]
|
||||||
bridge_type = bridges["type"]
|
|
||||||
bridge_source = bridges["source"]
|
|
||||||
|
|
||||||
# If the recommended bridge source is to use the built-in
|
self.settings.set("bridges_type", "custom")
|
||||||
# bridges, set that in our settings, as if the user had
|
|
||||||
# selected the built-in bridges for a specific PT themselves.
|
# Sanity check the bridges provided from the Tor API before saving
|
||||||
#
|
bridges_checked = self.common.check_bridges_valid(bridge_strings)
|
||||||
if bridge_source == "builtin":
|
|
||||||
self.common.log(
|
if bridges_checked:
|
||||||
"CensorshipCircumvention",
|
self.settings.set("bridges_custom", "\n".join(bridges_checked))
|
||||||
"save_settings",
|
|
||||||
"Will be using built-in bridges",
|
|
||||||
)
|
|
||||||
self.settings.set("bridges_type", "built-in")
|
|
||||||
if bridge_type == "obfs4":
|
|
||||||
self.settings.set("bridges_builtin_pt", "obfs4")
|
|
||||||
if bridge_type == "snowflake":
|
|
||||||
self.settings.set("bridges_builtin_pt", "snowflake")
|
|
||||||
if bridge_type == "meek":
|
|
||||||
self.settings.set("bridges_builtin_pt", "meek-azure")
|
|
||||||
bridges_ok = True
|
bridges_ok = True
|
||||||
else:
|
|
||||||
self.common.log(
|
|
||||||
"CensorshipCircumvention",
|
|
||||||
"save_settings",
|
|
||||||
"Will be using custom bridges",
|
|
||||||
)
|
|
||||||
# Any other type of bridge we can treat as custom.
|
|
||||||
self.settings.set("bridges_type", "custom")
|
|
||||||
|
|
||||||
# Sanity check the bridges provided from the Tor API before saving
|
|
||||||
bridges_checked = self.common.check_bridges_valid(bridge_strings)
|
|
||||||
|
|
||||||
if bridges_checked:
|
|
||||||
self.settings.set("bridges_custom", "\n".join(bridges_checked))
|
|
||||||
bridges_ok = True
|
|
||||||
|
|
||||||
# If we got any good bridges, save them to settings and return.
|
# If we got any good bridges, save them to settings and return.
|
||||||
if bridges_ok:
|
if bridges_ok:
|
||||||
|
@ -291,3 +259,42 @@ class CensorshipCircumvention(object):
|
||||||
"Could not use any of the obtained bridges.",
|
"Could not use any of the obtained bridges.",
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def request_default_bridges(self):
|
||||||
|
"""
|
||||||
|
Retrieves the list of default fall-back bridges from the Tor Project.
|
||||||
|
|
||||||
|
These are intended for when no censorship settings were found for a
|
||||||
|
specific country, but maybe there was some connection issue anyway.
|
||||||
|
"""
|
||||||
|
if not self.api_proxies:
|
||||||
|
return False
|
||||||
|
endpoint = "https://bridges.torproject.org/moat/circumvention/defaults"
|
||||||
|
try:
|
||||||
|
r = requests.get(
|
||||||
|
endpoint,
|
||||||
|
headers={"Content-Type": "application/vnd.api+json"},
|
||||||
|
proxies=self.api_proxies,
|
||||||
|
)
|
||||||
|
if r.status_code != 200:
|
||||||
|
self.common.log(
|
||||||
|
"CensorshipCircumvention",
|
||||||
|
"request_default_bridges",
|
||||||
|
f"status_code={r.status_code}",
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
|
||||||
|
result = r.json()
|
||||||
|
|
||||||
|
if "errors" in result:
|
||||||
|
self.common.log(
|
||||||
|
"CensorshipCircumvention",
|
||||||
|
"request_default_bridges",
|
||||||
|
f"errors={result['errors']}",
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
|
||||||
|
return result
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
raise CensorshipCircumventionError(e)
|
||||||
|
|
|
@ -69,7 +69,7 @@ class Meek(object):
|
||||||
if self.meek_client_file_path is None or not os.path.exists(
|
if self.meek_client_file_path is None or not os.path.exists(
|
||||||
self.meek_client_file_path
|
self.meek_client_file_path
|
||||||
):
|
):
|
||||||
raise MeekNotFound()
|
raise MeekNotFound(self.common)
|
||||||
|
|
||||||
# Start the Meek Client as a subprocess.
|
# Start the Meek Client as a subprocess.
|
||||||
self.common.log("Meek", "start", "Starting meek client")
|
self.common.log("Meek", "start", "Starting meek client")
|
||||||
|
@ -128,7 +128,7 @@ class Meek(object):
|
||||||
|
|
||||||
if "CMETHOD-ERROR" in line:
|
if "CMETHOD-ERROR" in line:
|
||||||
self.cleanup()
|
self.cleanup()
|
||||||
raise MeekNotRunning()
|
raise MeekNotRunning(self.common, line)
|
||||||
break
|
break
|
||||||
|
|
||||||
if self.meek_port:
|
if self.meek_port:
|
||||||
|
@ -137,9 +137,8 @@ class Meek(object):
|
||||||
"https": f"socks5h://{self.meek_host}:{self.meek_port}",
|
"https": f"socks5h://{self.meek_host}:{self.meek_port}",
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
self.common.log("Meek", "start", "Could not obtain the meek port")
|
|
||||||
self.cleanup()
|
self.cleanup()
|
||||||
raise MeekNotRunning()
|
raise MeekNotRunning(self.common, "Could not obtain the meek port")
|
||||||
|
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
"""
|
"""
|
||||||
|
@ -182,8 +181,19 @@ class MeekNotRunning(Exception):
|
||||||
number it started on, in order to do domain fronting.
|
number it started on, in order to do domain fronting.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def __init__(self, common, info=None):
|
||||||
|
self.common = common
|
||||||
|
msg = "Meek experienced an error starting up"
|
||||||
|
if info:
|
||||||
|
msg = msg + f": {info}"
|
||||||
|
self.common.log("MeekNotRunning", "__init__", msg)
|
||||||
|
|
||||||
|
|
||||||
class MeekNotFound(Exception):
|
class MeekNotFound(Exception):
|
||||||
"""
|
"""
|
||||||
We were unable to find the Meek Client binary.
|
We were unable to find the Meek Client binary.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def __init__(self, common):
|
||||||
|
self.common = common
|
||||||
|
self.common.log("MeekNotFound", "__init__", "Could not find the meek binary")
|
||||||
|
|
|
@ -954,20 +954,6 @@ class Onion(object):
|
||||||
"update_builtin_bridges",
|
"update_builtin_bridges",
|
||||||
f"Obtained bridges: {builtin_bridges}",
|
f"Obtained bridges: {builtin_bridges}",
|
||||||
)
|
)
|
||||||
if builtin_bridges["meek"]:
|
|
||||||
# Meek bridge needs to be defined as "meek_lite", not "meek",
|
|
||||||
# for it to work with obfs4proxy.
|
|
||||||
# We also refer to this bridge type as 'meek-azure' in our settings.
|
|
||||||
# So first, rename the key in the dict
|
|
||||||
builtin_bridges["meek-azure"] = builtin_bridges.pop("meek")
|
|
||||||
new_meek_bridges = []
|
|
||||||
# Now replace the values. They also need the url/front params appended
|
|
||||||
for item in builtin_bridges["meek-azure"]:
|
|
||||||
newline = item.replace("meek", "meek_lite")
|
|
||||||
new_meek_bridges.append(
|
|
||||||
f"{newline} url=https://meek.azureedge.net/ front=ajax.aspnetcdn.com"
|
|
||||||
)
|
|
||||||
builtin_bridges["meek-azure"] = new_meek_bridges
|
|
||||||
# Save the new settings
|
# Save the new settings
|
||||||
self.settings.set("bridges_builtin", builtin_bridges)
|
self.settings.set("bridges_builtin", builtin_bridges)
|
||||||
self.settings.save()
|
self.settings.save()
|
||||||
|
|
|
@ -181,7 +181,9 @@ class AutoConnectTab(QtWidgets.QWidget):
|
||||||
self.tor_con.start(self.curr_settings)
|
self.tor_con.start(self.curr_settings)
|
||||||
|
|
||||||
def _got_no_bridges(self):
|
def _got_no_bridges(self):
|
||||||
# If we got no bridges, try connecting again using built-in obfs4 bridges
|
# If we got no bridges, even after trying the default bridges
|
||||||
|
# provided by the Censorship API, try connecting again using
|
||||||
|
# our built-in obfs4 bridges
|
||||||
self.curr_settings.set("bridges_type", "built-in")
|
self.curr_settings.set("bridges_type", "built-in")
|
||||||
self.curr_settings.set("bridges_builtin_pt", "obfs4")
|
self.curr_settings.set("bridges_builtin_pt", "obfs4")
|
||||||
self.curr_settings.set("bridges_enabled", True)
|
self.curr_settings.set("bridges_enabled", True)
|
||||||
|
@ -244,6 +246,18 @@ class AutoConnectTab(QtWidgets.QWidget):
|
||||||
bridge_settings = self.censorship_circumvention.request_settings(
|
bridge_settings = self.censorship_circumvention.request_settings(
|
||||||
country=country
|
country=country
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if not bridge_settings:
|
||||||
|
# Fall back to trying the default bridges from the API
|
||||||
|
self.common.log(
|
||||||
|
"AutoConnectTab",
|
||||||
|
"use_bridge_connect_clicked",
|
||||||
|
"Falling back to trying default bridges provided by the Censorship Circumvention API",
|
||||||
|
)
|
||||||
|
bridge_settings = (
|
||||||
|
self.censorship_circumvention.request_default_bridges()
|
||||||
|
)
|
||||||
|
|
||||||
self.common.gui.meek.cleanup()
|
self.common.gui.meek.cleanup()
|
||||||
|
|
||||||
if bridge_settings and self.censorship_circumvention.save_settings(
|
if bridge_settings and self.censorship_circumvention.save_settings(
|
||||||
|
|
|
@ -236,14 +236,10 @@ class MoatThread(QtCore.QThread):
|
||||||
# Start Meek so that we can do domain fronting
|
# Start Meek so that we can do domain fronting
|
||||||
try:
|
try:
|
||||||
self.meek.start()
|
self.meek.start()
|
||||||
except MeekNotFound:
|
except (
|
||||||
self.common.log("MoatThread", "run", f"Could not find meek-client")
|
MeekNotFound,
|
||||||
self.bridgedb_error.emit()
|
MeekNotRunning,
|
||||||
return
|
):
|
||||||
except MeekNotRunning:
|
|
||||||
self.common.log(
|
|
||||||
"MoatThread", "run", f"Ran meek-client, but there was an error"
|
|
||||||
)
|
|
||||||
self.bridgedb_error.emit()
|
self.bridgedb_error.emit()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue