Merge pull request #1238 from micahflee/1237_finding_tor

Find tor correctly
This commit is contained in:
Micah Lee 2020-11-29 16:36:51 -08:00 committed by GitHub
commit b0b552931a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 94 additions and 35 deletions

View File

@ -22,7 +22,7 @@ import os, sys, time, argparse, threading
from datetime import datetime
from datetime import timedelta
from .common import Common
from .common import Common, CannotFindTor
from .web import Web
from .onion import *
from .onionshare import OnionShare
@ -320,7 +320,15 @@ def main(cwd=None):
web = Web(common, False, mode_settings, mode)
# Start the Onion object
onion = Onion(common, use_tmp_dir=True)
try:
onion = Onion(common, use_tmp_dir=True)
except CannotFindTor:
print("You must install tor to use OnionShare from the command line")
if common.platform == "Darwin":
print("In macOS, you can do this with Homebrew (https://brew.sh):")
print(" brew install tor")
sys.exit()
try:
onion.connect(
custom_settings=False,

View File

@ -34,6 +34,12 @@ from pkg_resources import resource_filename
from .settings import Settings
class CannotFindTor(Exception):
"""
OnionShare can't find a tor binary
"""
class Common:
"""
The Common object is shared amongst all parts of OnionShare.
@ -82,6 +88,8 @@ class Common:
def get_tor_paths(self):
if self.platform == "Linux":
tor_path = shutil.which("tor")
if not tor_path:
raise CannotFindTor()
obfs4proxy_file_path = shutil.which("obfs4proxy")
prefix = os.path.dirname(os.path.dirname(tor_path))
tor_geo_ip_file_path = os.path.join(prefix, "share/tor/geoip")
@ -94,6 +102,8 @@ class Common:
tor_geo_ipv6_file_path = os.path.join(base_path, "Data", "Tor", "geoip6")
elif self.platform == "Darwin":
tor_path = shutil.which("tor")
if not tor_path:
raise CannotFindTor()
obfs4proxy_file_path = shutil.which("obfs4proxy")
prefix = os.path.dirname(os.path.dirname(tor_path))
tor_geo_ip_file_path = os.path.join(prefix, "share/tor/geoip")

View File

@ -32,7 +32,6 @@ import getpass
import psutil
from distutils.version import LooseVersion as Version
from . import common
from .settings import Settings
# TODO: Figure out how to localize this for the GUI
@ -44,40 +43,30 @@ class TorErrorAutomatic(Exception):
using automatic settings that should work with Tor Browser.
"""
pass
class TorErrorInvalidSetting(Exception):
"""
This exception is raised if the settings just don't make sense.
"""
pass
class TorErrorSocketPort(Exception):
"""
OnionShare can't connect to the Tor controller using the supplied address and port.
"""
pass
class TorErrorSocketFile(Exception):
"""
OnionShare can't connect to the Tor controller using the supplied socket file.
"""
pass
class TorErrorMissingPassword(Exception):
"""
OnionShare connected to the Tor controller, but it requires a password.
"""
pass
class TorErrorUnreadableCookieFile(Exception):
"""
@ -85,8 +74,6 @@ class TorErrorUnreadableCookieFile(Exception):
to access the cookie file.
"""
pass
class TorErrorAuthError(Exception):
"""
@ -94,8 +81,6 @@ class TorErrorAuthError(Exception):
that a Tor controller isn't listening on this port.
"""
pass
class TorErrorProtocolError(Exception):
"""
@ -103,8 +88,6 @@ class TorErrorProtocolError(Exception):
isn't acting like a Tor controller (such as in Whonix).
"""
pass
class TorTooOld(Exception):
"""
@ -113,8 +96,6 @@ class TorTooOld(Exception):
is too old.
"""
pass
class BundledTorTimeout(Exception):
"""

View File

@ -51,7 +51,7 @@ Download Tor Browser and extract the binaries:
python scripts\get-tor-windows.py
```
### Prepare the code
### Prepare the virtual environment
OnionShare uses [Briefcase](https://briefcase.readthedocs.io/en/latest/).
@ -79,15 +79,27 @@ pip install briefcase
In order to work with the desktop app, you'll need to build a wheel of the CLI package first, and copy it into the `desktop` folder. You'll need to re-run this script each time you change the CLI code.
```sh
./scripts/rebuild-cli.sh
python scripts/rebuild-cli.py
```
Run OnionShare from the source tree like this:
### Running OnionShare from the source code tree
Inside the virtual environment, run OnionShare like this to install all of the dependencies:
```
briefcase dev -d
```
Once you have the dependencies installed, you can run it using the `dev.sh` script, which lets you use command line arguments, such as to `--verbose` or `--local-only`:
```
./scripts/dev.sh --help
./scripts/dev.sh -v
./scripts/dev.sh -v --local-only
```
Windows uses `scripts\dev.bat` instead.
## Running tests
Install these packages inside your virtual environment:

3
desktop/scripts/dev.bat Normal file
View File

@ -0,0 +1,3 @@
cd src
python -c "import onionshare; onionshare.main()" %*
cd ..

9
desktop/scripts/dev.sh Executable file
View File

@ -0,0 +1,9 @@
#!/bin/bash
# Run OnionShare desktop, allowing you to use command-line arguments
SCRIPTS_DIR="$( cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd )"
cd $SCRIPTS_DIR
cd ../src
python -c "import onionshare; onionshare.main()" $@

45
desktop/scripts/rebuild-cli.py Executable file
View File

@ -0,0 +1,45 @@
#!/usr/bin/env python3
"""
This script builds the CLI python wheel, copies it to the desktop folder,
and installs it in the virtual environment.
"""
import inspect
import os
import sys
import glob
import subprocess
import shutil
def main():
# Build paths
root_path = os.path.dirname(
os.path.dirname(
os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
)
)
cli_path = os.path.join(root_path, "cli")
desktop_path = os.path.join(root_path, "desktop")
# Delete old wheels
for filename in glob.glob(os.path.join(cli_path, "dist", "*.whl")):
os.remove(filename)
# Build new wheel
subprocess.call(["poetry", "install"], cwd=cli_path)
subprocess.call(["poetry", "build"], cwd=cli_path)
wheel_filename = glob.glob(os.path.join(cli_path, "dist", "*.whl"))[0]
wheel_basename = os.path.basename(wheel_filename)
shutil.copyfile(
wheel_filename,
os.path.join(desktop_path, wheel_basename),
)
# Reinstall the new wheel
subprocess.call(["pip", "uninstall", "onionshare-cli", "-y"])
subprocess.call(["pip", "install", os.path.join(desktop_path, wheel_basename)])
if __name__ == "__main__":
main()

View File

@ -1,9 +0,0 @@
#!/bin/bash
# Build the CLI python wheel and copy it to the desktop folder
SCRIPTS_DIR="$( cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd )"
cd $SCRIPTS_DIR
cd ../../cli
poetry build
cp dist/*.whl ../desktop

View File

@ -142,7 +142,7 @@ class SettingsDialog(QtWidgets.QDialog):
self.tor_geo_ip_file_path,
self.tor_geo_ipv6_file_path,
self.obfs4proxy_file_path,
) = self.common.get_tor_paths()
) = self.common.gui.get_tor_paths()
if not self.obfs4proxy_file_path or not os.path.isfile(
self.obfs4proxy_file_path
):
@ -165,7 +165,7 @@ class SettingsDialog(QtWidgets.QDialog):
self.tor_geo_ip_file_path,
self.tor_geo_ipv6_file_path,
self.obfs4proxy_file_path,
) = self.common.get_tor_paths()
) = self.common.gui.get_tor_paths()
if not self.obfs4proxy_file_path or not os.path.isfile(
self.obfs4proxy_file_path
):