mirror of
https://github.com/onionshare/onionshare.git
synced 2025-01-23 05:01:24 -05:00
Combine all get-tor scripts into a single get-tor.py
This commit is contained in:
parent
ee9a5269bb
commit
3fd96cd472
@ -9,62 +9,42 @@ git clone https://github.com/onionshare/onionshare.git
|
|||||||
cd onionshare/desktop
|
cd onionshare/desktop
|
||||||
```
|
```
|
||||||
|
|
||||||
Make sure you have Python 3 installed. If you're using Windows or macOS, install version 3.9.9 [from python.org](https://www.python.org/downloads/release/python-3912/). For Windows, make sure to install the 32-bit (x86) version, and to check the box to add python to the path on the first page of the installer.
|
Make sure you have Python 3 installed. If you're using Windows or macOS, install version 3.9.12 [from python.org](https://www.python.org/downloads/release/python-3912/). For Windows, make sure to check the box to add python to the path on the first page of the installer.
|
||||||
|
|
||||||
Make sure you have [poetry installed](https://python-poetry.org/docs/#installation), and then install the dependencies:
|
Make sure you have [poetry](https://python-poetry.org/) installed:
|
||||||
|
|
||||||
|
```
|
||||||
|
pip3 install poetry
|
||||||
|
```
|
||||||
|
|
||||||
|
And install the poetry dependencies:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
poetry install
|
poetry install
|
||||||
```
|
```
|
||||||
|
|
||||||
In Windows, you may need to install [Microsoft C++ Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/), making sure to check "Desktop development with C++", before `poetry install` will work properly.
|
**Windows users:** You may need to install [Microsoft C++ Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/), making sure to check "Desktop development with C++", before `poetry install` will work properly.
|
||||||
|
|
||||||
### Install platform-specific dependencies
|
### Get Tor
|
||||||
|
|
||||||
#### Linux
|
**Linux users:** In Ubuntu 20.04 you need the `libxcb-xinerama0` package installed.
|
||||||
|
|
||||||
In Ubuntu 20.04 you need the `libxcb-xinerama0` package installed.
|
**Windows users:** Download and install 7-Zip from https://7-zip.org/download.html. [Add](https://medium.com/@kevinmarkvi/how-to-add-executables-to-your-path-in-windows-5ffa4ce61a53) `C:\Program Files (x86)\7-Zip` to your path.
|
||||||
|
|
||||||
Download Tor Browser and extract the binaries:
|
Download Tor Browser and extract the binaries:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
poetry run ./scripts/get-tor-linux.py
|
poetry run python ./scripts/get-tor.py
|
||||||
```
|
|
||||||
|
|
||||||
#### macOS
|
|
||||||
|
|
||||||
Download Tor Browser and extract the binaries:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
poetry run ./scripts/get-tor-osx.py
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Windows
|
|
||||||
|
|
||||||
These instructions include adding folders to the path in Windows. To do this, go to Start and type "advanced system settings", and open "View advanced system settings" in the Control Panel. Click Environment Variables. Under "System variables" double-click on Path. From there you can add and remove folders that are available in the PATH.
|
|
||||||
|
|
||||||
Download and install 7-Zip from https://7-zip.org/download.html. I downloaded `7z1900.exe`. Add `C:\Program Files (x86)\7-Zip` to your path.
|
|
||||||
|
|
||||||
Download Tor Browser and extract the binaries:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
poetry run python scripts\get-tor-windows.py
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Compile dependencies
|
### Compile dependencies
|
||||||
|
|
||||||
Install Go. The simplest way to make sure everything works is to install Go by following [these instructions](https://golang.org/doc/install). (In Windows, make sure to install the 32-bit version of Go, such as `go1.17.5.windows-386.msi`.)
|
Install Go. The simplest way to make sure everything works is to install Go by following [these instructions](https://golang.org/doc/install).
|
||||||
|
|
||||||
Download and compile `meek-client`:
|
Download and compile `meek-client`:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./scripts/build-meek-client.py
|
poetry run python ./scripts/build-meek-client.py
|
||||||
```
|
|
||||||
|
|
||||||
Or in Windows:
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
python .\scripts\build-meek-client.py
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Running OnionShare from the source code tree
|
### Running OnionShare from the source code tree
|
||||||
|
@ -1,74 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
|
||||||
OnionShare | https://onionshare.org/
|
|
||||||
|
|
||||||
Copyright (C) 2014-2022 Micah Lee, et al. <micah@micahflee.com>
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import os
|
|
||||||
import requests
|
|
||||||
|
|
||||||
|
|
||||||
class UpdateTorBridges:
|
|
||||||
"""
|
|
||||||
Update the built-in Tor Bridges in OnionShare's torrc templates.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, root_path):
|
|
||||||
self.root_path = root_path
|
|
||||||
torrc_template_dir = os.path.join(
|
|
||||||
self.root_path, os.pardir, "cli/onionshare_cli/resources"
|
|
||||||
)
|
|
||||||
endpoint = "https://bridges.torproject.org/moat/circumvention/builtin"
|
|
||||||
r = requests.post(
|
|
||||||
endpoint,
|
|
||||||
headers={"Content-Type": "application/vnd.api+json"},
|
|
||||||
)
|
|
||||||
if r.status_code != 200:
|
|
||||||
print(
|
|
||||||
f"There was a problem fetching the latest built-in bridges: status_code={r.status_code}"
|
|
||||||
)
|
|
||||||
return False
|
|
||||||
|
|
||||||
result = r.json()
|
|
||||||
|
|
||||||
if "errors" in result:
|
|
||||||
print(
|
|
||||||
f"There was a problem fetching the latest built-in bridges: errors={result['errors']}"
|
|
||||||
)
|
|
||||||
return False
|
|
||||||
|
|
||||||
for bridge_type in ["meek-azure", "obfs4", "snowflake"]:
|
|
||||||
if result[bridge_type]:
|
|
||||||
if bridge_type == "meek-azure":
|
|
||||||
torrc_template_extension = "meek_lite_azure"
|
|
||||||
else:
|
|
||||||
torrc_template_extension = bridge_type
|
|
||||||
torrc_template = os.path.join(
|
|
||||||
self.root_path,
|
|
||||||
torrc_template_dir,
|
|
||||||
f"torrc_template-{torrc_template_extension}",
|
|
||||||
)
|
|
||||||
|
|
||||||
with open(torrc_template, "w") as f:
|
|
||||||
f.write(f"# Enable built-in {bridge_type} bridge\n")
|
|
||||||
bridges = result[bridge_type]
|
|
||||||
# Sorts the bridges numerically by IP, since they come back in
|
|
||||||
# random order from the API each time, and create noisy git diff.
|
|
||||||
bridges.sort(key=lambda s: s.split()[1])
|
|
||||||
for item in bridges:
|
|
||||||
f.write(f"Bridge {item}\n")
|
|
@ -1,135 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
|
||||||
OnionShare | https://onionshare.org/
|
|
||||||
|
|
||||||
Copyright (C) 2014-2022 Micah Lee, et al. <micah@micahflee.com>
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
"""
|
|
||||||
|
|
||||||
"""
|
|
||||||
This script downloads a pre-built tor binary to bundle with OnionShare.
|
|
||||||
In order to avoid a Mac gnupg dependency, I manually verify the signature
|
|
||||||
and hard-code the sha256 hash.
|
|
||||||
"""
|
|
||||||
import inspect
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import hashlib
|
|
||||||
import shutil
|
|
||||||
import subprocess
|
|
||||||
import requests
|
|
||||||
from bridges import UpdateTorBridges
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
tarball_url = "https://dist.torproject.org/torbrowser/11.0.9/tor-browser-linux64-11.0.9_en-US.tar.xz"
|
|
||||||
tarball_filename = "tor-browser-linux64-11.0.9_en-US.tar.xz"
|
|
||||||
expected_tarball_sha256 = (
|
|
||||||
"baa5ccafb5c68f1c46f9ae983b9b0a0419f66d41e0483ba5aacb3462fa0a8032"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Build paths
|
|
||||||
root_path = os.path.dirname(
|
|
||||||
os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
|
|
||||||
)
|
|
||||||
working_path = os.path.join(root_path, "build", "tor")
|
|
||||||
tarball_path = os.path.join(working_path, tarball_filename)
|
|
||||||
dist_path = os.path.join(root_path, "onionshare", "resources", "tor")
|
|
||||||
|
|
||||||
# Make sure dirs exist
|
|
||||||
if not os.path.exists(working_path):
|
|
||||||
os.makedirs(working_path, exist_ok=True)
|
|
||||||
|
|
||||||
if not os.path.exists(dist_path):
|
|
||||||
os.makedirs(dist_path, exist_ok=True)
|
|
||||||
|
|
||||||
# Make sure the tarball is downloaded
|
|
||||||
if not os.path.exists(tarball_path):
|
|
||||||
print("Downloading {}".format(tarball_url))
|
|
||||||
r = requests.get(tarball_url)
|
|
||||||
open(tarball_path, "wb").write(r.content)
|
|
||||||
tarball_sha256 = hashlib.sha256(r.content).hexdigest()
|
|
||||||
else:
|
|
||||||
tarball_data = open(tarball_path, "rb").read()
|
|
||||||
tarball_sha256 = hashlib.sha256(tarball_data).hexdigest()
|
|
||||||
|
|
||||||
# Compare the hash
|
|
||||||
if tarball_sha256 != expected_tarball_sha256:
|
|
||||||
print("ERROR! The sha256 doesn't match:")
|
|
||||||
print("expected: {}".format(expected_tarball_sha256))
|
|
||||||
print(" actual: {}".format(tarball_sha256))
|
|
||||||
sys.exit(-1)
|
|
||||||
|
|
||||||
# Delete extracted tarball, if it's there
|
|
||||||
shutil.rmtree(os.path.join(working_path, "tor-browser_en-US"), ignore_errors=True)
|
|
||||||
|
|
||||||
# Extract the tarball
|
|
||||||
subprocess.call(["tar", "-xvf", tarball_path], cwd=working_path)
|
|
||||||
tarball_tor_path = os.path.join(
|
|
||||||
working_path, "tor-browser_en-US", "Browser", "TorBrowser"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Copy into dist
|
|
||||||
shutil.copyfile(
|
|
||||||
os.path.join(tarball_tor_path, "Data", "Tor", "geoip"),
|
|
||||||
os.path.join(dist_path, "geoip"),
|
|
||||||
)
|
|
||||||
shutil.copyfile(
|
|
||||||
os.path.join(tarball_tor_path, "Data", "Tor", "geoip6"),
|
|
||||||
os.path.join(dist_path, "geoip6"),
|
|
||||||
)
|
|
||||||
shutil.copyfile(
|
|
||||||
os.path.join(tarball_tor_path, "Tor", "tor"),
|
|
||||||
os.path.join(dist_path, "tor"),
|
|
||||||
)
|
|
||||||
os.chmod(os.path.join(dist_path, "tor"), 0o755)
|
|
||||||
shutil.copyfile(
|
|
||||||
os.path.join(tarball_tor_path, "Tor", "libcrypto.so.1.1"),
|
|
||||||
os.path.join(dist_path, "libcrypto.so.1.1"),
|
|
||||||
)
|
|
||||||
shutil.copyfile(
|
|
||||||
os.path.join(tarball_tor_path, "Tor", "libevent-2.1.so.7"),
|
|
||||||
os.path.join(dist_path, "libevent-2.1.so.7"),
|
|
||||||
)
|
|
||||||
shutil.copyfile(
|
|
||||||
os.path.join(tarball_tor_path, "Tor", "libssl.so.1.1"),
|
|
||||||
os.path.join(dist_path, "libssl.so.1.1"),
|
|
||||||
)
|
|
||||||
shutil.copyfile(
|
|
||||||
os.path.join(tarball_tor_path, "Tor", "libstdc++", "libstdc++.so.6"),
|
|
||||||
os.path.join(dist_path, "libstdc++.so.6"),
|
|
||||||
)
|
|
||||||
shutil.copyfile(
|
|
||||||
os.path.join(tarball_tor_path, "Tor", "PluggableTransports", "obfs4proxy"),
|
|
||||||
os.path.join(dist_path, "obfs4proxy"),
|
|
||||||
)
|
|
||||||
os.chmod(os.path.join(dist_path, "obfs4proxy"), 0o755)
|
|
||||||
shutil.copyfile(
|
|
||||||
os.path.join(
|
|
||||||
tarball_tor_path, "Tor", "PluggableTransports", "snowflake-client"
|
|
||||||
),
|
|
||||||
os.path.join(dist_path, "snowflake-client"),
|
|
||||||
)
|
|
||||||
os.chmod(os.path.join(dist_path, "snowflake-client"), 0o755)
|
|
||||||
|
|
||||||
print(f"Tor binaries extracted to: {dist_path}")
|
|
||||||
|
|
||||||
# Fetch the built-in bridges
|
|
||||||
UpdateTorBridges(root_path)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
@ -1,123 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
|
||||||
OnionShare | https://onionshare.org/
|
|
||||||
|
|
||||||
Copyright (C) 2014-2022 Micah Lee, et al. <micah@micahflee.com>
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
"""
|
|
||||||
|
|
||||||
"""
|
|
||||||
This script downloads a pre-built tor binary to bundle with OnionShare.
|
|
||||||
In order to avoid a Mac gnupg dependency, I manually verify the signature
|
|
||||||
and hard-code the sha256 hash.
|
|
||||||
"""
|
|
||||||
import inspect
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import hashlib
|
|
||||||
import shutil
|
|
||||||
import subprocess
|
|
||||||
import requests
|
|
||||||
|
|
||||||
from bridges import UpdateTorBridges
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
dmg_url = "https://dist.torproject.org/torbrowser/11.0.9/TorBrowser-11.0.9-osx64_en-US.dmg"
|
|
||||||
dmg_filename = "TorBrowser-11.0.9-osx64_en-US.dmg"
|
|
||||||
expected_dmg_sha256 = (
|
|
||||||
"e34629a178a92983924a5a89c7a988285d2d27f21832413a7f7e33af7871c8d6"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Build paths
|
|
||||||
root_path = os.path.dirname(
|
|
||||||
os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
|
|
||||||
)
|
|
||||||
working_path = os.path.join(root_path, "build", "tor")
|
|
||||||
dmg_tor_path = os.path.join(
|
|
||||||
"/Volumes", "Tor Browser", "Tor Browser.app", "Contents"
|
|
||||||
)
|
|
||||||
dmg_path = os.path.join(working_path, dmg_filename)
|
|
||||||
dist_path = os.path.join(root_path, "onionshare", "resources", "tor")
|
|
||||||
if not os.path.exists(dist_path):
|
|
||||||
os.makedirs(dist_path, exist_ok=True)
|
|
||||||
|
|
||||||
# Make sure the working folder exists
|
|
||||||
if not os.path.exists(working_path):
|
|
||||||
os.makedirs(working_path)
|
|
||||||
|
|
||||||
# Make sure the zip is downloaded
|
|
||||||
if not os.path.exists(dmg_path):
|
|
||||||
print("Downloading {}".format(dmg_url))
|
|
||||||
r = requests.get(dmg_url)
|
|
||||||
open(dmg_path, "wb").write(r.content)
|
|
||||||
dmg_sha256 = hashlib.sha256(r.content).hexdigest()
|
|
||||||
else:
|
|
||||||
dmg_data = open(dmg_path, "rb").read()
|
|
||||||
dmg_sha256 = hashlib.sha256(dmg_data).hexdigest()
|
|
||||||
|
|
||||||
# Compare the hash
|
|
||||||
if dmg_sha256 != expected_dmg_sha256:
|
|
||||||
print("ERROR! The sha256 doesn't match:")
|
|
||||||
print("expected: {}".format(expected_dmg_sha256))
|
|
||||||
print(" actual: {}".format(dmg_sha256))
|
|
||||||
sys.exit(-1)
|
|
||||||
|
|
||||||
# Mount the dmg, copy data to the working path
|
|
||||||
subprocess.call(["hdiutil", "attach", dmg_path])
|
|
||||||
|
|
||||||
# Copy into dist
|
|
||||||
shutil.copyfile(
|
|
||||||
os.path.join(dmg_tor_path, "Resources", "TorBrowser", "Tor", "geoip"),
|
|
||||||
os.path.join(dist_path, "geoip"),
|
|
||||||
)
|
|
||||||
shutil.copyfile(
|
|
||||||
os.path.join(dmg_tor_path, "Resources", "TorBrowser", "Tor", "geoip6"),
|
|
||||||
os.path.join(dist_path, "geoip6"),
|
|
||||||
)
|
|
||||||
shutil.copyfile(
|
|
||||||
os.path.join(dmg_tor_path, "MacOS", "Tor", "tor.real"),
|
|
||||||
os.path.join(dist_path, "tor"),
|
|
||||||
)
|
|
||||||
os.chmod(os.path.join(dist_path, "tor"), 0o755)
|
|
||||||
shutil.copyfile(
|
|
||||||
os.path.join(dmg_tor_path, "MacOS", "Tor", "libevent-2.1.7.dylib"),
|
|
||||||
os.path.join(dist_path, "libevent-2.1.7.dylib"),
|
|
||||||
)
|
|
||||||
# obfs4proxy binary
|
|
||||||
shutil.copyfile(
|
|
||||||
os.path.join(dmg_tor_path, "MacOS", "Tor", "PluggableTransports", "obfs4proxy"),
|
|
||||||
os.path.join(dist_path, "obfs4proxy"),
|
|
||||||
)
|
|
||||||
os.chmod(os.path.join(dist_path, "obfs4proxy"), 0o755)
|
|
||||||
# snowflake-client binary
|
|
||||||
shutil.copyfile(
|
|
||||||
os.path.join(
|
|
||||||
dmg_tor_path, "MacOS", "Tor", "PluggableTransports", "snowflake-client"
|
|
||||||
),
|
|
||||||
os.path.join(dist_path, "snowflake-client"),
|
|
||||||
)
|
|
||||||
os.chmod(os.path.join(dist_path, "snowflake-client"), 0o755)
|
|
||||||
|
|
||||||
# Eject dmg
|
|
||||||
subprocess.call(["diskutil", "eject", "/Volumes/Tor Browser"])
|
|
||||||
|
|
||||||
# Fetch the built-in bridges
|
|
||||||
UpdateTorBridges(root_path)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
@ -1,108 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
|
||||||
OnionShare | https://onionshare.org/
|
|
||||||
|
|
||||||
Copyright (C) 2014-2022 Micah Lee, et al. <micah@micahflee.com>
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
"""
|
|
||||||
|
|
||||||
"""
|
|
||||||
This script downloads a pre-built tor binary to bundle with OnionShare.
|
|
||||||
In order to avoid a Windows gnupg dependency, I manually verify the signature
|
|
||||||
and hard-code the sha256 hash.
|
|
||||||
"""
|
|
||||||
import inspect
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import hashlib
|
|
||||||
import shutil
|
|
||||||
import subprocess
|
|
||||||
import requests
|
|
||||||
|
|
||||||
from bridges import UpdateTorBridges
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
exe_url = "https://dist.torproject.org/torbrowser/11.0.9/torbrowser-install-11.0.9_en-US.exe"
|
|
||||||
exe_filename = "torbrowser-install-11.0.9_en-US.exe"
|
|
||||||
expected_exe_sha256 = (
|
|
||||||
"e938433028b6ffb5d312db6268b19e419626b071f08209684c8e5b9f3d3df2bc"
|
|
||||||
)
|
|
||||||
# Build paths
|
|
||||||
root_path = os.path.dirname(
|
|
||||||
os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
|
|
||||||
)
|
|
||||||
working_path = os.path.join(root_path, "build", "tor")
|
|
||||||
exe_path = os.path.join(working_path, exe_filename)
|
|
||||||
dist_path = os.path.join(root_path, "onionshare", "resources", "tor")
|
|
||||||
|
|
||||||
# Make sure the working folder exists
|
|
||||||
if not os.path.exists(working_path):
|
|
||||||
os.makedirs(working_path)
|
|
||||||
|
|
||||||
# Make sure Tor Browser is downloaded
|
|
||||||
if not os.path.exists(exe_path):
|
|
||||||
print("Downloading {}".format(exe_url))
|
|
||||||
r = requests.get(exe_url)
|
|
||||||
open(exe_path, "wb").write(r.content)
|
|
||||||
exe_sha256 = hashlib.sha256(r.content).hexdigest()
|
|
||||||
else:
|
|
||||||
exe_data = open(exe_path, "rb").read()
|
|
||||||
exe_sha256 = hashlib.sha256(exe_data).hexdigest()
|
|
||||||
|
|
||||||
# Compare the hash
|
|
||||||
if exe_sha256 != expected_exe_sha256:
|
|
||||||
print("ERROR! The sha256 doesn't match:")
|
|
||||||
print("expected: {}".format(expected_exe_sha256))
|
|
||||||
print(" actual: {}".format(exe_sha256))
|
|
||||||
sys.exit(-1)
|
|
||||||
|
|
||||||
# Extract the bits we need from the exe
|
|
||||||
subprocess.Popen(
|
|
||||||
[
|
|
||||||
"7z",
|
|
||||||
"e",
|
|
||||||
"-y",
|
|
||||||
exe_path,
|
|
||||||
"Browser\\TorBrowser\\Tor",
|
|
||||||
"-o%s" % os.path.join(working_path, "Tor"),
|
|
||||||
]
|
|
||||||
).wait()
|
|
||||||
subprocess.Popen(
|
|
||||||
[
|
|
||||||
"7z",
|
|
||||||
"e",
|
|
||||||
"-y",
|
|
||||||
exe_path,
|
|
||||||
"Browser\\TorBrowser\\Data\\Tor\\geoip*",
|
|
||||||
"-o%s" % os.path.join(working_path, "Data"),
|
|
||||||
]
|
|
||||||
).wait()
|
|
||||||
|
|
||||||
# Copy into the onionshare resources
|
|
||||||
if os.path.exists(dist_path):
|
|
||||||
shutil.rmtree(dist_path)
|
|
||||||
os.makedirs(dist_path)
|
|
||||||
shutil.copytree(os.path.join(working_path, "Tor"), os.path.join(dist_path, "Tor"))
|
|
||||||
shutil.copytree(
|
|
||||||
os.path.join(working_path, "Data"), os.path.join(dist_path, "Data", "Tor")
|
|
||||||
)
|
|
||||||
|
|
||||||
# Fetch the built-in bridges
|
|
||||||
UpdateTorBridges(root_path)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
326
desktop/scripts/get-tor.py
Normal file
326
desktop/scripts/get-tor.py
Normal file
@ -0,0 +1,326 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import platform
|
||||||
|
import inspect
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import hashlib
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import requests
|
||||||
|
|
||||||
|
# Windows
|
||||||
|
exe_url = (
|
||||||
|
"https://dist.torproject.org/torbrowser/11.0.9/torbrowser-install-11.0.9_en-US.exe"
|
||||||
|
)
|
||||||
|
exe_filename = "torbrowser-install-11.0.9_en-US.exe"
|
||||||
|
expected_exe_sha256 = "e938433028b6ffb5d312db6268b19e419626b071f08209684c8e5b9f3d3df2bc"
|
||||||
|
|
||||||
|
# macOS
|
||||||
|
dmg_url = (
|
||||||
|
"https://dist.torproject.org/torbrowser/11.0.9/TorBrowser-11.0.9-osx64_en-US.dmg"
|
||||||
|
)
|
||||||
|
dmg_filename = "TorBrowser-11.0.9-osx64_en-US.dmg"
|
||||||
|
expected_dmg_sha256 = "e34629a178a92983924a5a89c7a988285d2d27f21832413a7f7e33af7871c8d6"
|
||||||
|
|
||||||
|
# Linux
|
||||||
|
tarball_url = "https://dist.torproject.org/torbrowser/11.0.9/tor-browser-linux64-11.0.9_en-US.tar.xz"
|
||||||
|
tarball_filename = "tor-browser-linux64-11.0.9_en-US.tar.xz"
|
||||||
|
expected_tarball_sha256 = (
|
||||||
|
"baa5ccafb5c68f1c46f9ae983b9b0a0419f66d41e0483ba5aacb3462fa0a8032"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Common paths
|
||||||
|
root_path = os.path.dirname(
|
||||||
|
os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
|
||||||
|
)
|
||||||
|
working_path = os.path.join(root_path, "build", "tor")
|
||||||
|
|
||||||
|
|
||||||
|
def get_tor_windows():
|
||||||
|
# Build paths
|
||||||
|
exe_path = os.path.join(working_path, exe_filename)
|
||||||
|
dist_path = os.path.join(root_path, "onionshare", "resources", "tor")
|
||||||
|
|
||||||
|
# Make sure the working folder exists
|
||||||
|
if not os.path.exists(working_path):
|
||||||
|
os.makedirs(working_path)
|
||||||
|
|
||||||
|
# Make sure Tor Browser is downloaded
|
||||||
|
if not os.path.exists(exe_path):
|
||||||
|
print("Downloading {}".format(exe_url))
|
||||||
|
r = requests.get(exe_url)
|
||||||
|
open(exe_path, "wb").write(r.content)
|
||||||
|
exe_sha256 = hashlib.sha256(r.content).hexdigest()
|
||||||
|
else:
|
||||||
|
exe_data = open(exe_path, "rb").read()
|
||||||
|
exe_sha256 = hashlib.sha256(exe_data).hexdigest()
|
||||||
|
|
||||||
|
# Compare the hash
|
||||||
|
if exe_sha256 != expected_exe_sha256:
|
||||||
|
print("ERROR! The sha256 doesn't match:")
|
||||||
|
print("expected: {}".format(expected_exe_sha256))
|
||||||
|
print(" actual: {}".format(exe_sha256))
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
# Extract the bits we need from the exe
|
||||||
|
subprocess.Popen(
|
||||||
|
[
|
||||||
|
"7z",
|
||||||
|
"e",
|
||||||
|
"-y",
|
||||||
|
exe_path,
|
||||||
|
"Browser\\TorBrowser\\Tor",
|
||||||
|
"-o%s" % os.path.join(working_path, "Tor"),
|
||||||
|
]
|
||||||
|
).wait()
|
||||||
|
subprocess.Popen(
|
||||||
|
[
|
||||||
|
"7z",
|
||||||
|
"e",
|
||||||
|
"-y",
|
||||||
|
exe_path,
|
||||||
|
"Browser\\TorBrowser\\Data\\Tor\\geoip*",
|
||||||
|
"-o%s" % os.path.join(working_path, "Data"),
|
||||||
|
]
|
||||||
|
).wait()
|
||||||
|
|
||||||
|
# Copy into the onionshare resources
|
||||||
|
if os.path.exists(dist_path):
|
||||||
|
shutil.rmtree(dist_path)
|
||||||
|
os.makedirs(dist_path)
|
||||||
|
shutil.copytree(os.path.join(working_path, "Tor"), os.path.join(dist_path, "Tor"))
|
||||||
|
shutil.copytree(
|
||||||
|
os.path.join(working_path, "Data"), os.path.join(dist_path, "Data", "Tor")
|
||||||
|
)
|
||||||
|
|
||||||
|
# Fetch the built-in bridges
|
||||||
|
update_tor_bridges()
|
||||||
|
|
||||||
|
|
||||||
|
def get_tor_macos():
|
||||||
|
# Build paths
|
||||||
|
dmg_tor_path = os.path.join(
|
||||||
|
"/Volumes", "Tor Browser", "Tor Browser.app", "Contents"
|
||||||
|
)
|
||||||
|
dmg_path = os.path.join(working_path, dmg_filename)
|
||||||
|
dist_path = os.path.join(root_path, "onionshare", "resources", "tor")
|
||||||
|
if not os.path.exists(dist_path):
|
||||||
|
os.makedirs(dist_path, exist_ok=True)
|
||||||
|
|
||||||
|
# Make sure the working folder exists
|
||||||
|
if not os.path.exists(working_path):
|
||||||
|
os.makedirs(working_path)
|
||||||
|
|
||||||
|
# Make sure the zip is downloaded
|
||||||
|
if not os.path.exists(dmg_path):
|
||||||
|
print("Downloading {}".format(dmg_url))
|
||||||
|
r = requests.get(dmg_url)
|
||||||
|
open(dmg_path, "wb").write(r.content)
|
||||||
|
dmg_sha256 = hashlib.sha256(r.content).hexdigest()
|
||||||
|
else:
|
||||||
|
dmg_data = open(dmg_path, "rb").read()
|
||||||
|
dmg_sha256 = hashlib.sha256(dmg_data).hexdigest()
|
||||||
|
|
||||||
|
# Compare the hash
|
||||||
|
if dmg_sha256 != expected_dmg_sha256:
|
||||||
|
print("ERROR! The sha256 doesn't match:")
|
||||||
|
print("expected: {}".format(expected_dmg_sha256))
|
||||||
|
print(" actual: {}".format(dmg_sha256))
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
# Mount the dmg, copy data to the working path
|
||||||
|
subprocess.call(["hdiutil", "attach", dmg_path])
|
||||||
|
|
||||||
|
# Copy into dist
|
||||||
|
shutil.copyfile(
|
||||||
|
os.path.join(dmg_tor_path, "Resources", "TorBrowser", "Tor", "geoip"),
|
||||||
|
os.path.join(dist_path, "geoip"),
|
||||||
|
)
|
||||||
|
shutil.copyfile(
|
||||||
|
os.path.join(dmg_tor_path, "Resources", "TorBrowser", "Tor", "geoip6"),
|
||||||
|
os.path.join(dist_path, "geoip6"),
|
||||||
|
)
|
||||||
|
shutil.copyfile(
|
||||||
|
os.path.join(dmg_tor_path, "MacOS", "Tor", "tor.real"),
|
||||||
|
os.path.join(dist_path, "tor"),
|
||||||
|
)
|
||||||
|
os.chmod(os.path.join(dist_path, "tor"), 0o755)
|
||||||
|
shutil.copyfile(
|
||||||
|
os.path.join(dmg_tor_path, "MacOS", "Tor", "libevent-2.1.7.dylib"),
|
||||||
|
os.path.join(dist_path, "libevent-2.1.7.dylib"),
|
||||||
|
)
|
||||||
|
# obfs4proxy binary
|
||||||
|
shutil.copyfile(
|
||||||
|
os.path.join(dmg_tor_path, "MacOS", "Tor", "PluggableTransports", "obfs4proxy"),
|
||||||
|
os.path.join(dist_path, "obfs4proxy"),
|
||||||
|
)
|
||||||
|
os.chmod(os.path.join(dist_path, "obfs4proxy"), 0o755)
|
||||||
|
# snowflake-client binary
|
||||||
|
shutil.copyfile(
|
||||||
|
os.path.join(
|
||||||
|
dmg_tor_path, "MacOS", "Tor", "PluggableTransports", "snowflake-client"
|
||||||
|
),
|
||||||
|
os.path.join(dist_path, "snowflake-client"),
|
||||||
|
)
|
||||||
|
os.chmod(os.path.join(dist_path, "snowflake-client"), 0o755)
|
||||||
|
|
||||||
|
# Eject dmg
|
||||||
|
subprocess.call(["diskutil", "eject", "/Volumes/Tor Browser"])
|
||||||
|
|
||||||
|
# Fetch the built-in bridges
|
||||||
|
update_tor_bridges()
|
||||||
|
|
||||||
|
|
||||||
|
def get_tor_linux():
|
||||||
|
# Build paths
|
||||||
|
tarball_path = os.path.join(working_path, tarball_filename)
|
||||||
|
dist_path = os.path.join(root_path, "onionshare", "resources", "tor")
|
||||||
|
|
||||||
|
# Make sure dirs exist
|
||||||
|
if not os.path.exists(working_path):
|
||||||
|
os.makedirs(working_path, exist_ok=True)
|
||||||
|
|
||||||
|
if not os.path.exists(dist_path):
|
||||||
|
os.makedirs(dist_path, exist_ok=True)
|
||||||
|
|
||||||
|
# Make sure the tarball is downloaded
|
||||||
|
if not os.path.exists(tarball_path):
|
||||||
|
print("Downloading {}".format(tarball_url))
|
||||||
|
r = requests.get(tarball_url)
|
||||||
|
open(tarball_path, "wb").write(r.content)
|
||||||
|
tarball_sha256 = hashlib.sha256(r.content).hexdigest()
|
||||||
|
else:
|
||||||
|
tarball_data = open(tarball_path, "rb").read()
|
||||||
|
tarball_sha256 = hashlib.sha256(tarball_data).hexdigest()
|
||||||
|
|
||||||
|
# Compare the hash
|
||||||
|
if tarball_sha256 != expected_tarball_sha256:
|
||||||
|
print("ERROR! The sha256 doesn't match:")
|
||||||
|
print("expected: {}".format(expected_tarball_sha256))
|
||||||
|
print(" actual: {}".format(tarball_sha256))
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
# Delete extracted tarball, if it's there
|
||||||
|
shutil.rmtree(os.path.join(working_path, "tor-browser_en-US"), ignore_errors=True)
|
||||||
|
|
||||||
|
# Extract the tarball
|
||||||
|
subprocess.call(["tar", "-xvf", tarball_path], cwd=working_path)
|
||||||
|
tarball_tor_path = os.path.join(
|
||||||
|
working_path, "tor-browser_en-US", "Browser", "TorBrowser"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Copy into dist
|
||||||
|
shutil.copyfile(
|
||||||
|
os.path.join(tarball_tor_path, "Data", "Tor", "geoip"),
|
||||||
|
os.path.join(dist_path, "geoip"),
|
||||||
|
)
|
||||||
|
shutil.copyfile(
|
||||||
|
os.path.join(tarball_tor_path, "Data", "Tor", "geoip6"),
|
||||||
|
os.path.join(dist_path, "geoip6"),
|
||||||
|
)
|
||||||
|
shutil.copyfile(
|
||||||
|
os.path.join(tarball_tor_path, "Tor", "tor"),
|
||||||
|
os.path.join(dist_path, "tor"),
|
||||||
|
)
|
||||||
|
os.chmod(os.path.join(dist_path, "tor"), 0o755)
|
||||||
|
shutil.copyfile(
|
||||||
|
os.path.join(tarball_tor_path, "Tor", "libcrypto.so.1.1"),
|
||||||
|
os.path.join(dist_path, "libcrypto.so.1.1"),
|
||||||
|
)
|
||||||
|
shutil.copyfile(
|
||||||
|
os.path.join(tarball_tor_path, "Tor", "libevent-2.1.so.7"),
|
||||||
|
os.path.join(dist_path, "libevent-2.1.so.7"),
|
||||||
|
)
|
||||||
|
shutil.copyfile(
|
||||||
|
os.path.join(tarball_tor_path, "Tor", "libssl.so.1.1"),
|
||||||
|
os.path.join(dist_path, "libssl.so.1.1"),
|
||||||
|
)
|
||||||
|
shutil.copyfile(
|
||||||
|
os.path.join(tarball_tor_path, "Tor", "libstdc++", "libstdc++.so.6"),
|
||||||
|
os.path.join(dist_path, "libstdc++.so.6"),
|
||||||
|
)
|
||||||
|
shutil.copyfile(
|
||||||
|
os.path.join(tarball_tor_path, "Tor", "PluggableTransports", "obfs4proxy"),
|
||||||
|
os.path.join(dist_path, "obfs4proxy"),
|
||||||
|
)
|
||||||
|
os.chmod(os.path.join(dist_path, "obfs4proxy"), 0o755)
|
||||||
|
shutil.copyfile(
|
||||||
|
os.path.join(
|
||||||
|
tarball_tor_path, "Tor", "PluggableTransports", "snowflake-client"
|
||||||
|
),
|
||||||
|
os.path.join(dist_path, "snowflake-client"),
|
||||||
|
)
|
||||||
|
os.chmod(os.path.join(dist_path, "snowflake-client"), 0o755)
|
||||||
|
|
||||||
|
print(f"Tor binaries extracted to: {dist_path}")
|
||||||
|
|
||||||
|
# Fetch the built-in bridges
|
||||||
|
update_tor_bridges()
|
||||||
|
|
||||||
|
|
||||||
|
def update_tor_bridges():
|
||||||
|
"""
|
||||||
|
Update the built-in Tor Bridges in OnionShare's torrc templates.
|
||||||
|
"""
|
||||||
|
torrc_template_dir = os.path.join(
|
||||||
|
root_path, os.pardir, "cli/onionshare_cli/resources"
|
||||||
|
)
|
||||||
|
endpoint = "https://bridges.torproject.org/moat/circumvention/builtin"
|
||||||
|
r = requests.post(
|
||||||
|
endpoint,
|
||||||
|
headers={"Content-Type": "application/vnd.api+json"},
|
||||||
|
)
|
||||||
|
if r.status_code != 200:
|
||||||
|
print(
|
||||||
|
f"There was a problem fetching the latest built-in bridges: status_code={r.status_code}"
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
|
||||||
|
result = r.json()
|
||||||
|
|
||||||
|
if "errors" in result:
|
||||||
|
print(
|
||||||
|
f"There was a problem fetching the latest built-in bridges: errors={result['errors']}"
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
|
||||||
|
for bridge_type in ["meek-azure", "obfs4", "snowflake"]:
|
||||||
|
if result[bridge_type]:
|
||||||
|
if bridge_type == "meek-azure":
|
||||||
|
torrc_template_extension = "meek_lite_azure"
|
||||||
|
else:
|
||||||
|
torrc_template_extension = bridge_type
|
||||||
|
torrc_template = os.path.join(
|
||||||
|
root_path,
|
||||||
|
torrc_template_dir,
|
||||||
|
f"torrc_template-{torrc_template_extension}",
|
||||||
|
)
|
||||||
|
|
||||||
|
with open(torrc_template, "w") as f:
|
||||||
|
f.write(f"# Enable built-in {bridge_type} bridge\n")
|
||||||
|
bridges = result[bridge_type]
|
||||||
|
# Sorts the bridges numerically by IP, since they come back in
|
||||||
|
# random order from the API each time, and create noisy git diff.
|
||||||
|
bridges.sort(key=lambda s: s.split()[1])
|
||||||
|
for item in bridges:
|
||||||
|
f.write(f"Bridge {item}\n")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""
|
||||||
|
Download Tor Browser and extract tor binaries
|
||||||
|
"""
|
||||||
|
system = platform.system()
|
||||||
|
if system == "Windows":
|
||||||
|
get_tor_windows()
|
||||||
|
elif system == "Darwin":
|
||||||
|
get_tor_macos()
|
||||||
|
elif system == "Linux":
|
||||||
|
get_tor_linux()
|
||||||
|
else:
|
||||||
|
print("Platform not supported")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
Loading…
Reference in New Issue
Block a user