From 148e0d0a36b1c787d8c0d550283312d37315e94f Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Sat, 21 Jun 2025 19:18:28 -0400 Subject: [PATCH] Add Tor placeholders instructions and fallback --- README.md | 10 ++++++++++ docs/troubleshooting.md | 8 ++++++++ gui/electron/main.js | 8 +++++++- gui/electron/tor.js | 32 +++++++++++++++++++++++++++---- scripts/download_tor.sh | 42 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 95 insertions(+), 5 deletions(-) create mode 100755 scripts/download_tor.sh diff --git a/README.md b/README.md index 9c9abd5..0e6780a 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,16 @@ node, javascript-obfuscator, html-minifier-terser Run `voxvera check` to see missing dependencies. +### Placeholder Tor files + +The `voxvera/resources/tor/*` folders only contain small text files named +`placeholder`. VoxVera expects real `tor` and `obfs4proxy` binaries in those +locations when running `voxvera serve` or the Electron GUI. Install the tools +manually (for example with `apt install tor obfs4proxy`) and set the +environment variables `TOR_SOCKS_PORT` and `TOR_CONTROL_PORT` before launching. +You may also run `scripts/download_tor.sh` to fetch prebuilt binaries and +replace the placeholders. + --- ## 🎮 GUI (Electron) diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index edc5b26..6a3754a 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -6,6 +6,14 @@ This page collects common issues encountered when hosting or accessing flyers. - Ensure Tor is allowed through your firewall. On systems using `ufw` you may need to run `sudo ufw allow tor`. - Some networks block Tor entirely. If you cannot reach onion services, try connecting over a different network or use a Tor bridge. +### Placeholder binaries + +The files in `voxvera/resources/tor/*` are not real executables. Install `tor` +and `obfs4proxy` yourself (e.g. `apt install tor obfs4proxy`) then set +`TOR_SOCKS_PORT` and `TOR_CONTROL_PORT` before running `voxvera serve` or the +Electron GUI. Running `scripts/download_tor.sh` can also populate the missing +files automatically. + ## Firewall rules - If `voxvera serve` fails to start OnionShare, verify that outbound connections on ports 9001 and 80 are permitted. - Corporate or university firewalls can block the hidden service ports required by Tor. diff --git a/gui/electron/main.js b/gui/electron/main.js index fb11606..9f9d238 100644 --- a/gui/electron/main.js +++ b/gui/electron/main.js @@ -46,7 +46,13 @@ function startOnionShare() { } async function runServe (retry = false) { - const { torProc, socksPort, controlPort } = await launchTor(); + let torProc, socksPort, controlPort; + try { + ({ torProc, socksPort, controlPort } = await launchTor()); + } catch (err) { + dialog.showErrorBox('Tor error', err.message); + return; + } const env = { ...process.env, TOR_SOCKS_PORT: socksPort.toString(), diff --git a/gui/electron/tor.js b/gui/electron/tor.js index c8a9cdf..e863819 100644 --- a/gui/electron/tor.js +++ b/gui/electron/tor.js @@ -1,15 +1,39 @@ const { spawn } = require('child_process'); const path = require('path'); +const fs = require('fs'); +const which = require('which'); const getPort = (...args) => import('get-port').then(m => m.default(...args)); async function launchTor() { const socks = await getPort(); const control = await getPort(); const torBase = path.join(__dirname, '..', '..', 'voxvera', 'resources', 'tor'); - const exe = path.join(torBase, process.platform, - process.platform === 'win32' ? 'tor.exe' : 'tor'); - const obfs4 = path.join(torBase, process.platform, - process.platform === 'win32' ? 'obfs4proxy.exe' : 'obfs4proxy'); + let exe = path.join(torBase, process.platform, + process.platform === 'win32' ? 'tor.exe' : 'tor'); + let obfs4 = path.join(torBase, process.platform, + process.platform === 'win32' ? 'obfs4proxy.exe' : 'obfs4proxy'); + + const missing = p => { + try { + const data = fs.readFileSync(p, 'utf8'); + return data.includes('placeholder'); + } catch (e) { + return true; + } + }; + + if (missing(exe)) { + const sysTor = which.sync('tor', { nothrow: true }); + if (sysTor) exe = sysTor; + } + if (missing(obfs4)) { + const sysObfs = which.sync('obfs4proxy', { nothrow: true }); + if (sysObfs) obfs4 = sysObfs; + } + + if (missing(exe) || missing(obfs4)) { + throw new Error('Tor or obfs4proxy not found; install them first.'); + } const args = [ 'SocksPort', socks, diff --git a/scripts/download_tor.sh b/scripts/download_tor.sh new file mode 100755 index 0000000..cbd12bf --- /dev/null +++ b/scripts/download_tor.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +set -euo pipefail + +VERSION="${VERSION:-13.5.18}" +BASE_URL="https://www.torproject.org/dist/torbrowser" + +case "$(uname -s)" in + Linux*) PLATFORM=linux; ARCHIVE="tor-expert-bundle-linux-x86_64-${VERSION}.tar.gz"; EXE=tor;; + Darwin*) PLATFORM=mac; ARCHIVE="tor-expert-bundle-macos-x86_64-${VERSION}.tar.gz"; EXE=tor;; + MINGW*|MSYS*|CYGWIN*) PLATFORM=win; ARCHIVE="tor-expert-bundle-windows-x86_64-${VERSION}.tar.gz"; EXE=tor.exe;; + *) echo "Unsupported OS" >&2; exit 1;; +esac + +TMPDIR=$(mktemp -d) +trap 'rm -rf "$TMPDIR"' EXIT + +URL="$BASE_URL/${VERSION}/${ARCHIVE}" + +echo "Downloading $URL" +curl -L "$URL" -o "$TMPDIR/$ARCHIVE" + +echo "Extracting..." +tar -xf "$TMPDIR/$ARCHIVE" -C "$TMPDIR" + +DEST="$(dirname "$0")/../voxvera/resources/tor/$PLATFORM" +mkdir -p "$DEST" + +TOR_BIN=$(find "$TMPDIR" -type f -name "$EXE" | head -n 1) +OBFS_BIN=$(find "$TMPDIR" -type f -name "obfs4proxy*" | head -n 1) + +if [[ -z "$TOR_BIN" || -z "$OBFS_BIN" ]]; then + echo "Failed to locate tor or obfs4proxy in archive" >&2 + exit 1 +fi + +cp "$TOR_BIN" "$DEST/$(basename "$EXE")" +cp "$OBFS_BIN" "$DEST/$(basename "$OBFS_BIN")" + +chmod +x "$DEST/$(basename "$EXE")" "$DEST/$(basename "$OBFS_BIN")" + +echo "Installed binaries to $DEST" +