Version 1.0.4 terminalphone.sh

This commit is contained in:
Here ForAwhile 2026-02-19 12:51:09 +00:00
parent ca94542464
commit 616768a364

View file

@ -9,7 +9,7 @@ set -euo pipefail
# CONFIGURATION
#=============================================================================
APP_NAME="TerminalPhone"
VERSION="1.0.3"
VERSION="1.0.4"
BASE_DIR="$(dirname "$(readlink -f "$0")")"
DATA_DIR="$BASE_DIR/.terminalphone"
TOR_DIR="$DATA_DIR/tor_data"
@ -25,6 +25,7 @@ RECV_PIPE="$DATA_DIR/run/recv_$$"
SEND_PIPE="$DATA_DIR/run/send_$$"
CIPHER_RUNTIME_FILE="$DATA_DIR/run/cipher_$$"
# Defaults
LISTEN_PORT=7777
TOR_SOCKS_PORT=9050
@ -34,6 +35,7 @@ SAMPLE_RATE=8000 # Hz
PTT_KEY=" " # spacebar
CHUNK_DURATION=1 # seconds per audio chunk
CIPHER="aes-256-cbc" # OpenSSL cipher for encryption
SNOWFLAKE_ENABLED=0 # Snowflake bridge (off by default)
# ANSI Colors
RED='\033[0;31m'
@ -59,6 +61,7 @@ fi
# State
TOR_PID=""
CALL_ACTIVE=0
ORIGINAL_STTY=""
@ -107,6 +110,7 @@ kill_bg_processes() {
if [ -n "$TOR_PID" ] && kill -0 "$TOR_PID" 2>/dev/null; then
kill "$TOR_PID" 2>/dev/null || true
fi
}
save_pid() {
@ -155,6 +159,7 @@ OPUS_BITRATE=$OPUS_BITRATE
OPUS_FRAMESIZE=$OPUS_FRAMESIZE
PTT_KEY="$PTT_KEY"
CIPHER="$CIPHER"
SNOWFLAKE_ENABLED=$SNOWFLAKE_ENABLED
EOF
}
@ -269,15 +274,71 @@ HiddenServiceDir $TOR_DIR/hidden_service
HiddenServicePort $LISTEN_PORT 127.0.0.1:$LISTEN_PORT
Log notice file $TOR_DIR/tor.log
EOF
# Append snowflake bridge config if enabled
if [ "$SNOWFLAKE_ENABLED" -eq 1 ] && check_dep snowflake-client; then
local sf_bin
sf_bin=$(command -v snowflake-client)
cat >> "$TOR_CONF" << EOF
UseBridges 1
ClientTransportPlugin snowflake exec $sf_bin
Bridge snowflake 192.0.2.3:80 2B280B23E1107BB62ABFC40DDCC8824814F80A72 fingerprint=2B280B23E1107BB62ABFC40DDCC8824814F80A72 url=https://snowflake-broker.torproject.net/ ice=stun:stun.l.google.com:19302,stun:stun.voip.blackberry.com:3478
EOF
log_info "Snowflake bridge enabled in torrc"
elif [ "$SNOWFLAKE_ENABLED" -eq 1 ]; then
log_warn "Snowflake enabled but snowflake-client not found — skipping bridge"
fi
chmod 600 "$TOR_CONF"
}
install_snowflake() {
if check_dep snowflake-client; then
log_ok "snowflake-client already installed"
return 0
fi
log_info "Installing snowflake-client..."
local SUDO="sudo"
if [ $IS_TERMUX -eq 1 ]; then
SUDO=""
elif ! check_dep sudo; then
SUDO=""
fi
if [ $IS_TERMUX -eq 1 ]; then
pkg install -y snowflake-client
elif check_dep apt-get; then
$SUDO apt-get update -qq
$SUDO apt-get install -y snowflake-client
elif check_dep dnf; then
$SUDO dnf install -y snowflake-client
elif check_dep pacman; then
$SUDO pacman -S --noconfirm snowflake-pt-client
else
log_err "No supported package manager found. Install snowflake-client manually."
return 1
fi
if check_dep snowflake-client; then
log_ok "snowflake-client installed successfully"
else
log_err "snowflake-client installation failed"
return 1
fi
}
start_tor() {
if [ -n "$TOR_PID" ] && kill -0 "$TOR_PID" 2>/dev/null; then
log_info "Tor is already running (PID $TOR_PID)"
return 0
fi
setup_tor
# Clear old log so we only see fresh output
@ -285,6 +346,9 @@ start_tor() {
> "$tor_log"
log_info "Starting Tor..."
if [ "$SNOWFLAKE_ENABLED" -eq 1 ]; then
echo -e " ${DIM}Snowflake bridge enabled — this may take longer than usual, please be patient.${NC}"
fi
tor -f "$TOR_CONF" &>/dev/null &
TOR_PID=$!
save_pid "tor" "$TOR_PID"
@ -361,6 +425,7 @@ stop_tor() {
TOR_PID=""
log_ok "Tor stopped"
fi
}
get_onion() {
@ -766,6 +831,42 @@ draw_call_header() {
echo -e " ${GREEN}${NC} Local cipher: ${WHITE}${cipher_upper}${NC}" >&2
echo -e " ${DIM}${NC} Remote cipher: ${DIM}waiting...${NC}" >&2
fi
# Show Snowflake bridge info if enabled
if [ "$SNOWFLAKE_ENABLED" -eq 1 ]; then
local tor_log="$TOR_DIR/tor.log"
echo "" >&2
echo -e " ${TOR_PURPLE}${NC} ${BOLD}Snowflake bridge${NC}" >&2
if [ -f "$tor_log" ]; then
# Parse bridge descriptor: "new bridge descriptor 'NAME' (fresh): $FINGERPRINT"
local bridge_line=""
bridge_line=$(grep "new bridge descriptor" "$tor_log" 2>/dev/null | tail -1 || true)
if [ -n "$bridge_line" ]; then
local bridge_name=""
bridge_name=$(echo "$bridge_line" | sed -n "s/.*new bridge descriptor '\([^']*\)'.*/\1/p" || true)
local bridge_fp=""
bridge_fp=$(echo "$bridge_line" | sed -n 's/.*(\(fresh\|stale\)): \(.*\)/\2/p' || true)
if [ -n "$bridge_name" ]; then
# Truncate fingerprint to fit terminal
local fp_display="$bridge_fp"
if [ ${#fp_display} -gt 40 ]; then
fp_display="${fp_display:0:40}..."
fi
echo -e " ${DIM}descriptor:${NC} ${WHITE}${bridge_name}${NC} ${DIM}${fp_display}${NC}" >&2
fi
fi
# Show managed proxy status
local proxy_line=""
proxy_line=$(grep 'Managed proxy.*snowflake' "$tor_log" 2>/dev/null | tail -1 || true)
if [ -n "$proxy_line" ]; then
if echo "$proxy_line" | grep -q "connected"; then
echo -e " ${DIM}transport:${NC} ${GREEN}connected${NC}" >&2
else
echo -e " ${DIM}transport:${NC} ${YELLOW}connecting...${NC}" >&2
fi
fi
fi
fi
echo "" >&2
echo -e " ${BOLD}Controls:${NC}" >&2
@ -1181,6 +1282,17 @@ show_status() {
echo -e " ${RED}${NC} Audio dependencies missing"
fi
# Snowflake
if [ "$SNOWFLAKE_ENABLED" -eq 1 ]; then
if check_dep snowflake-client; then
echo -e " ${GREEN}${NC} Snowflake bridge enabled"
else
echo -e " ${YELLOW}${NC} Snowflake enabled (client not installed)"
fi
else
echo -e " ${DIM}${NC} Snowflake bridge disabled"
fi
# Config
echo -e "\n ${DIM}Listen port: $LISTEN_PORT${NC}"
echo -e " ${DIM}SOCKS port: $TOR_SOCKS_PORT${NC}"
@ -1201,10 +1313,17 @@ settings_menu() {
echo -e "\n${BOLD}${CYAN}═══ Settings ═══${NC}\n"
echo -e " ${DIM}Current cipher: ${NC}${WHITE}${CIPHER}${NC}"
echo -e " ${DIM}Current Opus bitrate: ${NC}${WHITE}${OPUS_BITRATE} kbps${NC}"
echo -e " ${DIM}Current Opus frame: ${NC}${WHITE}${OPUS_FRAMESIZE} ms${NC}\n"
echo -e " ${DIM}Current Opus frame: ${NC}${WHITE}${OPUS_FRAMESIZE} ms${NC}"
local sf_label="${RED}disabled${NC}"
if [ "$SNOWFLAKE_ENABLED" -eq 1 ]; then
sf_label="${GREEN}enabled${NC}"
fi
echo -e " ${DIM}Snowflake bridge: ${NC}${sf_label}\n"
echo -e " ${BOLD}${WHITE}1${NC} ${CYAN}${NC} Change encryption cipher"
echo -e " ${BOLD}${WHITE}2${NC} ${CYAN}${NC} Change Opus encoding quality"
echo -e " ${BOLD}${WHITE}3${NC} ${CYAN}${NC} Snowflake bridge (censorship circumvention)"
echo -e " ${BOLD}${WHITE}0${NC} ${CYAN}${NC} ${DIM}Back to main menu${NC}"
echo ""
echo -ne " ${BOLD}Select: ${NC}"
@ -1213,6 +1332,7 @@ settings_menu() {
case "$schoice" in
1) settings_cipher ;;
2) settings_opus ;;
3) settings_snowflake ;;
0|q|Q) return ;;
*)
echo -e "\n ${RED}Invalid choice${NC}"
@ -1384,6 +1504,79 @@ settings_opus() {
read -r
}
settings_snowflake() {
clear
echo -e "\n${BOLD}${CYAN}═══ Snowflake Bridge ═══${NC}\n"
echo -e " ${DIM}Snowflake uses WebRTC proxies to help bypass Tor censorship.${NC}"
echo -e " ${DIM}Enable this if Tor is blocked in your region.${NC}\n"
if [ "$SNOWFLAKE_ENABLED" -eq 1 ]; then
echo -e " Status: ${GREEN}${BOLD}ENABLED${NC}"
else
echo -e " Status: ${RED}${BOLD}DISABLED${NC}"
fi
if check_dep snowflake-client; then
echo -e " Binary: ${GREEN}${NC} snowflake-client installed"
else
echo -e " Binary: ${RED}${NC} snowflake-client not installed"
fi
echo -e " ${DIM}Tor manages snowflake-client as a pluggable transport.${NC}"
echo ""
if [ "$SNOWFLAKE_ENABLED" -eq 1 ]; then
echo -e " ${BOLD}${WHITE}1${NC} ${CYAN}${NC} Disable Snowflake"
else
echo -e " ${BOLD}${WHITE}1${NC} ${CYAN}${NC} Enable Snowflake"
fi
echo -e " ${BOLD}${WHITE}0${NC} ${CYAN}${NC} ${DIM}Back${NC}"
echo ""
echo -ne " ${BOLD}Select: ${NC}"
read -r sf_choice
case "$sf_choice" in
1)
if [ "$SNOWFLAKE_ENABLED" -eq 1 ]; then
SNOWFLAKE_ENABLED=0
save_config
echo -e "\n ${YELLOW}${BOLD}${NC} Snowflake disabled"
echo -e " ${DIM}Restart Tor for changes to take effect.${NC}"
else
# Install if not present
if ! check_dep snowflake-client; then
echo ""
echo -ne " ${BOLD}snowflake-client not installed. Install now? [Y/n]: ${NC}"
read -r install_confirm
if [ "$install_confirm" != "n" ] && [ "$install_confirm" != "N" ]; then
install_snowflake || {
echo -ne " ${DIM}Press Enter to continue...${NC}"
read -r
return
}
else
echo -e "\n ${YELLOW}Snowflake not enabled (client not installed)${NC}"
echo -ne " ${DIM}Press Enter to continue...${NC}"
read -r
return
fi
fi
SNOWFLAKE_ENABLED=1
save_config
echo -e "\n ${GREEN}${BOLD}${NC} Snowflake enabled"
echo -e " ${DIM}Restart Tor for changes to take effect.${NC}"
fi
;;
0|q|Q) return ;;
*)
echo -e "\n ${RED}Invalid choice${NC}"
;;
esac
echo -ne " ${DIM}Press Enter to continue...${NC}"
read -r
}
#=============================================================================
# MAIN MENU
#=============================================================================
@ -1415,8 +1608,12 @@ main_menu() {
if [ -n "$SHARED_SECRET" ]; then
secret_status="${GREEN}${NC}"
fi
local sf_status="${RED}${NC}"
if [ "$SNOWFLAKE_ENABLED" -eq 1 ]; then
sf_status="${GREEN}${NC}"
fi
echo -e " ${DIM}Tor:${NC} $tor_status ${DIM}Secret:${NC} $secret_status ${DIM}PTT:${NC} ${GREEN}[SPACE]${NC}\n"
echo -e " ${DIM}Tor:${NC} $tor_status ${DIM}Secret:${NC} $secret_status ${DIM}SF:${NC} $sf_status ${DIM}PTT:${NC} ${GREEN}[SPACE]${NC}\n"
echo -e " ${BOLD}${WHITE}1${NC} ${CYAN}${NC} Listen for calls"
echo -e " ${BOLD}${WHITE}2${NC} ${CYAN}${NC} Call an onion address"