#!/bin/bash

# This file is part of TorBox, an easy to use anonymizing router based on Raspberry Pi.
# Copyright (C) 2026 radio_24
# Contact: anonym@torbox.ch
# Website: https://www.torbox.ch
# Github:  https://github.com/radio24/TorBox
#
# 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 is 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/>.
#
# DESCRIPTION
# This file displays the Bridge Relay menu and executes all relevant scripts.
#
# SYNTAX
# ./menu-server
#
#
###### SET VARIABLES ######
#
# SIZE OF THE MENU
#
# How many items do you have in the main menu?
NO_ITEMS=8
#
# How many lines are only for decoration and spaces?
NO_SPACER=3
#
#Set the the variables for the menu
MENU_WIDTH=80
MENU_WIDTH_REDUX=60
MENU_HEIGHT_25=25
MENU_HEIGHT_20=20
MENU_HEIGHT_15=15
# MENU_HEIGHT should not exceed 26
MENU_HEIGHT=$((8+NO_ITEMS+NO_SPACER))
MENU_LIST_HEIGHT=$((NO_ITEMS+NO_SPACER))

#Colors
RED='\033[1;31m'
YELLOW='\033[1;93m'
NOCOLOR='\033[0m'

#Other variables
TORRC="/etc/tor/torrc"
BAK="/etc/tor/torrc.bak"

##############################
######## FUNCTIONS ########

# include lib
.  /home/torbox/torbox/lib/torbox.lib

# This function imports the configuration and makes some preparations
# TOGGLE07 / TOGGLE08 represents the status of the Bridge Relay mode
read_config()
{
MODE_BR=$(grep "^BridgeRelay" ${TORRC})
MODE_BRIDGES=$(grep "^UseBridges" ${TORRC})
if [ "$MODE_BR" = "BridgeRelay 1" ]; then
    TOGGLE07="Bridge relay ON!"
    TOGGLE07b="ON"
    TOGGLE08b="OFF"
    ACTIVATED="Bridge Relay Mode is ACTIVATED"
    ORPORT=$(grep "^ORPort" ${TORRC})
    OBFS4PORT=$(grep "^ServerTransportListenAddr" ${TORRC})
    CONTACT=$(grep "^ContactInfo" ${TORRC})
    NICK=$(grep "^Nickname" ${TORRC})
    BRIDGEDISTRIBUTION=$(grep "BridgeDistribution" ${TORRC})
else
    TOGGLE07="Bridge relay OFF!"
    TOGGLE07b="OFF"
    TOGGLE08b="ON"
    ACTIVATED="Bridge Relay Mode is DEACTIVATED"
    ORPORT=$(grep "^#ORPort" ${TORRC})
    OBFS4PORT=$(grep "^#ServerTransportListenAddr" ${TORRC})
    CONTACT=$(grep "^#ContactInfo" ${TORRC})
    NICK=$(grep "^#Nickname" ${TORRC})
    BRIDGEDISTRIBUTION=$(grep "#BridgeDistribution" ${TORRC})
fi
sORPORT=$(cut -d ' ' -f2 <<< $ORPORT)
sOBFS4PORT=$(cut -d ':' -f2 <<< $OBFS4PORT)
sCONTACT=$(cut -d ' ' -f2 <<< $CONTACT)
sNICK=$(cut -d ' ' -f2 <<< $NICK)
sBRIDGEDISTRIBUTION=$(cut -d ' ' -f2 <<< $BRIDGEDISTRIBUTION)
}

# This function changes the configuration and, if necessary, restarts tor
change_config()
{
if [ "$MODE_BR" != "BridgeRelay 1" ]; then
  sudo sed -i "s/^$ORPORT/#ORPort $nORPORT/" ${TORRC}
  sudo sed -i "s/^$OBFS4PORT/#ServerTransportListenAddr obfs4 0.0.0.0:$nOBFS4PORT/" ${TORRC}
  sudo sed -i "s/^$CONTACT/#ContactInfo $nCONTACT/" ${TORRC}
  sudo sed -i "s/^$NICK/#Nickname $nNICK/" ${TORRC}
  sudo sed -i "s/^$BRIDGEDISTRIBUTION/#BridgeDistribution $nBRIDGEDISTRIBUTION/" ${TORRC}
else
  sudo sed -i "s/^$ORPORT/ORPort $nORPORT/" ${TORRC}
  sudo sed -i "s/^$OBFS4PORT/ServerTransportListenAddr obfs4 0.0.0.0:$nOBFS4PORT/" ${TORRC}
  sudo sed -i "s/^$CONTACT/ContactInfo $nCONTACT/" ${TORRC}
  sudo sed -i "s/^$NICK/Nickname $nNICK/" ${TORRC}
  sudo sed -i "s/^$BRIDGEDISTRIBUTION/BridgeDistribution $nBRIDGEDISTRIBUTION/" ${TORRC}
  INPUT=$(cat text/restart-bridge_server-text)
  if (whiptail --title "TorBox - INFO (scroll down!)" --scrolltext --defaultno --no-button "NO - DON'T RESTART" --yes-button "YES - RESTART" --yesno "$INPUT" $MENU_HEIGHT_25 $MENU_WIDTH); then
    clear
    restarting_tor menu-server
  fi
fi
}


######## PREPARATIONS ########
read_config
clear

# Resetting
cd "$(dirname "$0")" || exit 1
shopt -s checkwinsize
[ -f nohup.out ] && sudo rm nohup.out
stty intr ^c
trap

###### DISPLAY THE MENU ######
clear

CHOICE=$(whiptail --cancel-button "Back" --title "TorBox v.0.5.5 - OBFS4 BRIDGE RELAY" --menu "Choose an option (ESC -> back to the main menu)            ${TOGGLE07}" $MENU_HEIGHT $MENU_WIDTH $MENU_LIST_HEIGHT \
"==" "=============================================[Informational]===" \
" 1" "RUN AN OBFS4 BRIDGE RELAY - READ ME FIRST"  \
"==" "=======================================[OBFS4 bridges relay]==="  \
" 2" "Toggle OBFS4 Bridge Relay Mode from $TOGGLE07b to $TOGGLE08b"  \
" 3" "Check and/or change the configuration"  \
" 4" "Reset configuration to default"  \
" 5" "Show me my personal OBFS4 bridge address"  \
" 6" "Enter the advanced tor configuration editor"  \
" 7" "Restart Tor - check if it is working (press q to quit)"  \
"==" "================================================[Dangerous!]===" \
" 8" "Remove permanently OBFS4 Bridge Relay data" \
3>&1 1>&2 2>&3)
exitstatus=$?
# exitstatus == 255 means that the ESC key was pressed
[ "$exitstatus" == "255" ] && exit 0

CHOICE=$(echo "$CHOICE" | tr -d ' ')
case "$CHOICE" in

  # Displays the read.me
	1)
    INPUT=$(cat text/help-bridge_server-text)
    whiptail --title "TorBox - INFO (scroll down!)" --msgbox --scrolltext "$INPUT" $MENU_HEIGHT_25 $MENU_WIDTH
  ;;

  # Toggle Bridge Relay Mode ON or OFF
  2)
    if [ "$MODE_BR" != "BridgeRelay 1" ]; then
			if [ "$MODE_BRIDGES" != "UseBridges 1" ]; then
				if grep "^ReachableAddresses" ${TORRC} ; then
					INPUT=$(cat text/no_antifirewall-please-text)
					if (whiptail --title "TorBox - INFO" --yesno "$INPUT" $MENU_HEIGHT_15 $MENU_WIDTH); then
						sudo sed -i "s/^ReachableAddresses /#ReachableAddresses /g" ${TORRC}
					fi
				fi
        clear
        INPUT=$(cat text/activate-bridge_server-text)
        if (whiptail --title "TorBox - INFO" --defaultno --no-button "DON'T CHANGE" --yes-button "ACTIVATE" --yesno "$INPUT" $MENU_HEIGHT_25 $MENU_WIDTH); then
          sudo sed -i "s/^#BridgeRelay/BridgeRelay/g" ${TORRC}
          sudo sed -i "s/^#ORPort/ORPort/g" ${TORRC}
          sudo sed -i "s/^#ExtORPort/ExtORPort/g" ${TORRC}
          sudo sed -i "s/^#ServerTransportPlugin/ServerTransportPlugin/g" ${TORRC}
          sudo sed -i "s/^#ServerTransportListenAddr/ServerTransportListenAddr/g" ${TORRC}
          sudo sed -i "s/^#ContactInfo/ContactInfo/g" ${TORRC}
          sudo sed -i "s/^#Nickname/Nickname/g" ${TORRC}
          sudo sed -i "s/^#BridgeDistribution/BridgeDistribution/g" ${TORRC}
          (sudo iptables -C INPUT -p tcp --dport $sORPORT -j ACCEPT) 2>/dev/null
          RULE_CHECK=$?
          if [ $RULE_CHECK = 1 ]; then
            sudo iptables -A INPUT -p tcp --dport $sORPORT -j ACCEPT
            sudo iptables -A INPUT -p tcp --dport $sOBFS4PORT -j ACCEPT
          fi
					INPUT=$(cat text/restart-tor-text)
		      if (whiptail --title "TorBox - INFO" --defaultno --no-button "NO - DON'T (RE)START" --yes-button "YES - (RE)START" --yesno "$INPUT" $MENU_HEIGHT_15 $MENU_WIDTH); then
		        clear
		        restarting_tor menu-server
		      fi
        fi
      else
        INPUT="\n\nTo activate the OBFS4 Bridge Relay Mode, you have first to DEACTIVATE the Bridge Mode. You can not run both settings simultaneously!"
        whiptail --title "TorBox - INFO" --msgbox "$INPUT" $MENU_HEIGHT_15 $MENU_WIDTH
      fi
    else
      INPUT=$(cat text/deactivate-bridge_server-text)
      if (whiptail --title "TorBox - INFO" --defaultno --no-button "DON'T CHANGE" --yes-button "DEACTIVATE" --yesno "$INPUT" $MENU_HEIGHT_15 $MENU_WIDTH); then
        clear
        deactivating_bridge_relay
        sleep 2
        restarting_tor menu-server
      fi
    fi
    read_config
  ;;

  # Check and/or change the configuration
  3)
    INPUT="\nThis is the configuration of your Bridge Relay (default values in brackets):\n\n$ACTIVATED\nORPort is set to (4235): $sORPORT\nOBSF4Port is set to (443): $sOBFS4PORT\nYour contact email is set to: $sCONTACT\nYour nickname is set to: $sNICK\nThe distribution method is set to: $sBRIDGEDISTRIBUTION\n\nWould you like to change the configuration?"
    if (whiptail --defaultno --yesno "$INPUT" $MENU_HEIGHT_20 $MENU_WIDTH); then
      nORPORT=$(whiptail --title "Changing the configuration of the Bridge Relay -- Port number of ORPort" --inputbox "\n\nThis port must be externally reachable. Avoid port 9001 because it's commonly associated with Tor and censors may be scanning the Internet for this port.\n\nEnter the port number of the ORPort (ENTER -> $sORPORT):" $MENU_HEIGHT_20 $MENU_WIDTH_REDUX 3>&1 1>&2 2>&3)
      [ -z "$nORPORT" ] && nORPORT=$sORPORT
			is_integer "${nORPORT}"
			exitstatus=$?
			# exitstatus == 1 means that $nORPORT is not an integer
			if [ "$exitstatus" = "1" ]; then
				clear
				echo -e "${YELLOW}[!] WRONG INPUT - THIS IS NOT AN INTEGER!${NOCOLOR}"
				echo -e "${RED}[+] I asked you for a number and you gave me... what??? ${NOCOLOR}"
				sleep 5
				clear
				trap "bash menu-server; exit 0" EXIT
				exit 1
			fi
      nOBFS4PORT=$(whiptail --title "Changing the configuration of the Bridge Relay -- Port number of OBFS4" --inputbox "\n\nThis port must be externally reachable. Avoid port 9001 because it's commonly associated with Tor and censors may be scanning the Internet for this port. It have to differ from the port number of ORPort\n\nEnter the port number of the OBFS4 (ENTER -> $sOBFS4PORT):" 20 $MENU_WIDTH_REDUX 3>&1 1>&2 2>&3)
      [ -z "$nOBFS4PORT" ] && nOBFS4PORT=$sOBFS4PORT
			is_integer "${nOBFS4PORT}"
			exitstatus=$?
			# exitstatus == 1 means that $nOBFS4PORT is not an integer
			if [ "$exitstatus" = "1" ]; then
				clear
				echo -e "${YELLOW}[!] WRONG INPUT - THIS IS NOT AN INTEGER!${NOCOLOR}"
				echo -e "${RED}[+] I asked you for a number and you gave me... what??? ${NOCOLOR}"
				sleep 5
				clear
				trap "bash menu-server; exit 0" EXIT
				exit 1
			fi
      nCONTACT=$(whiptail --title "Changing the configuration of the Bridge Relay -- Contact Email" --inputbox "\n\nAdd your contact email address so we can contact you if there are problems with your bridge.\n\nEnter your contact email address\n(ENTER -> $sCONTACT):" $MENU_HEIGHT_20 $MENU_WIDTH_REDUX 3>&1 1>&2 2>&3)
      [ -z "$nCONTACT" ] && nCONTACT=$sCONTACT
			# # NEW v.0.5.4
			# Nickname: A handle for your relay, so people don't have to refer to it by key. Nicknames must be between 1 and 19 characters inclusive, and must contain only the characters [a-zA-Z0-9]. If not set, "Unnamed" will be used.
			# See here: https://github.com/Ilshidur/tor-relay-docker/blob/master/torrc.bridge.default
      nNICK=$(whiptail --title "Changing the configuration of the Bridge Relay -- Nickname" --inputbox "\n\nAdd your nickname (optional; only letters and numbers; not more than 19 characters).\n\nEnter your nickname:" $MENU_HEIGHT_20 $MENU_WIDTH_REDUX 3>&1 1>&2 2>&3)
			clear
			if [ ! -z "$nNICK" ]; then
				if [[ $nNICK != *[0123456789ABCDEFGHIJKLMNOPQRSTUVWXZYabcdefghijklmnopqrstuvwxzy-]* ]]; then
					clear
					echo " "
					echo -e "${YELLOW}[!] Only letters (upper and lower case) and numbers are allowed.${NOCOLOR}"
					echo -e "${YELLOW}[!] We didn't set a Nickname,yet. You can change the configuration later.${NOCOLOR}"
					nNICK=""
					sleep 5
				elif ${#nNICK} -gt 19 ; then
					clear
					echo " "
					echo -e "${YELLOW}[!] The Nickname must not exceed 19 charcters!${NOCOLOR}"
					echo -e "${YELLOW}[!] We didn't set a Nickname,yet. You can change the configuration later.${NOCOLOR}"
					nNICK=""
					sleep 5
				fi
			fi
			#
      nBRIDGEDISTRIBUTION=$(whiptail --title "Changing the configuration of the Bridge Relay -- Distribution Method" --radiolist "Choose with SPACE and then press ENTER (ESC -> go back)" $MENU_HEIGHT $MENU_WIDTH 6 \
"ANY" "Let BridgeDB decide about the distribution method (default)" ON \
"HTTPS" "Distributed through the bridge website" OFF \
"MOAT" "Directly fetched and used by the Torbrowser" OFF \
"EMAIL" "Distributed by email (bridges@torproject.org)" OFF \
"NONE" "Avoid distributing the bridge address" OFF \
3>&1 1>&2 2>&3)
      nBRIDGEDISTRIBUTION=${nBRIDGEDISTRIBUTION,,}
      [ -z "$nBRIDGEDISTRIBUTION" ] && nBRIDGEDISTRIBUTION="sBRIDGEDISTRIBUTION"
      change_config
      read_config
    fi
  ;;

  # Reset configuration to default
  4)
    INPUT="\nThis is the configuration of your Bridge Relay:\n\n$ACTIVATED\nORPort is set to (4235): $sORPORT\nOBSF4Port is set to (443): $sOBFS4PORT\nYour contact email is set to: $sCONTACT\nYour nickname is set to: $sNICK\nThe distribution method is set to: $sBRIDGEDISTRIBUTION\n\nWould you like to reset the configuration to the default values?"
    if (whiptail --defaultno --yesno "$INPUT" $MENU_HEIGHT_20 $MENU_WIDTH); then
      nORPORT="4235"
      nOBFS4PORT="443"
      nCONTACT="<address@email.com>"
      nNICK="TorBox055"
      nBRIDGEDISTRIBUTION="any"
      change_config
      read_config
    fi
  ;;

  # Display the personal bridge address
  5)
    if [ "$MODE_BR" = "BridgeRelay 1" ]; then
      read_config
      PRIVATE_IP_SPACE=""
      PRIVATE_IP_SPACE=$(ip route get 1.1.1.1 | grep -oP 'src \K\S+' | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')
      if [ -z "$PRIVATE_IP_SPACE" ]; then
        MYIP=$(ip route get 1.1.1.1 | grep -oP 'src \K\S+')
      else
        MYIP=$(curl -s http://ifconfig.me)
      fi
      FINGERPRINT=$(sudo cat /var/lib/tor/fingerprint)
			if [ -z "$FINGERPRINT" ]; then
				clear
				echo -e "${YELLOW}[!] ERROR DISPLAYING YOUR PERSONAL OBFS4 BRIDGE ADDRESS!!${NOCOLOR}"
				echo -e "${RED}[+] Did you forget to restart tor? Please use entry 7.${NOCOLOR}"
				echo " "
				read -n 1 -s -r -p "Press any key to continue"
				exit 1
			fi
      FINGERPRINT=$(cut -d ' ' -f2 <<< $FINGERPRINT)
      CERT=$(sudo grep -oP "cert=.*" /var/lib/tor/pt_state/obfs4_bridgeline.txt)
      BRIDGELINE="$MYIP:$sOBFS4PORT $FINGERPRINT $CERT"
      echo -e "${RED}[+] ACTIVATED BRIDGE RELAY${NOCOLOR}"
      echo -e "${RED}[+] Below is your personal bridge address, which you can use with another TorBox or with the Tor Browser.${NOCOLOR}"
      echo -e "${RED}[+] Format: obfs4 <IP>:<Port> <Fingerprint> cert=<Certificate> iat-mode=0${NOCOLOR}"
      echo ""
      echo -e "${YELLOW}[!] obfs4 $BRIDGELINE"
      echo ""
      echo -e "${RED}[+] Would you like to check the validity of the bridge?${NOCOLOR}"
      echo -e "${RED}[+] Go to https://metrics.torproject.org/rs.html and search for the fingerprint${NOCOLOR}"
      echo -e "${RED}[+] Or go to https://bridges.torproject.org/scan/ for a TCP reachability test${NOCOLOR}"
      echo " "
    else
      echo -e "${YELLOW}[!] DEACTIVATED BRIDGE RELAY!!${NOCOLOR}"
      echo -e "${RED}[+] There is no personal bridge address, yet. You have to activate the Bridge Relay first (menu entry 2).${NOCOLOR}"
      echo " "
    fi
    read -n 1 -s -r -p "Press any key to continue"
  ;;

  # Enter the advanced configuration editor
  6)
    INPUT=$(cat text/advanced-bridges-text)
    if (whiptail --title "TorBox - INFO" --defaultno --no-button "DON'T CHANGE" --yes-button "CHANGE NOW" --yesno "$INPUT" $MENU_HEIGHT_20 $MENU_WIDTH); then
      sudo cp ${TORRC} ${BAK}
      bin/vitor
      INPUT=$(cat text/restart-tor-text)
      if (whiptail --title "TorBox - INFO" --defaultno --no-button "NO - DON'T (RE)START" --yes-button "YES - (RE)START" --yesno "$INPUT" $MENU_HEIGHT_15 $MENU_WIDTH); then
        clear
        restarting_tor menu-server
      fi
    fi
  ;;

  # Open the ports, restart Tor and check the progress
  7)
    INPUT=$(cat text/restart-bridge_server-text)
    if (whiptail --title "TorBox - INFO (scroll down!)" --scrolltext --defaultno --no-button "NO - DON'T RESTART" --yes-button "YES - RESTART" --yesno "$INPUT" $MENU_HEIGHT_25 $MENU_WIDTH); then
      clear
      echo -e "${RED}[+] Reading configuration...${NOCOLOR}"
      read_config
      sleep 2
      if [ "$MODE_BR" = "BridgeRelay 1" ]; then
        echo -e "${RED}[+] Opening port ORPort $sORPORT and OBFS4Port $sOBFS4PORT${NOCOLOR}"
        (sudo iptables -C INPUT -p tcp --dport $sORPORT -j ACCEPT) 2>/dev/null
        RULE_CHECK=$?
        if [ $RULE_CHECK = 1 ]; then
          sudo iptables -A INPUT -p tcp --dport $sORPORT -j ACCEPT
          sudo iptables -A INPUT -p tcp --dport $sOBFS4PORT -j ACCEPT
        fi
      fi
      sleep 2
			echo ""
      restarting_tor menu-server
    fi
  ;;

	#This permanently removes Bridge Relay data
	8)
	   INPUT=$(cat text/remove-brdata-text)
		 if (whiptail --title "TorBox - INFO" --defaultno  --yesno "$INPUT" 18 $MENU_WIDTH); then
		 	clear
		 	echo -e "${RED}[+] Deactivating Bridge mode or Bridge Relay...${NOCOLOR}"
		 	deactivating_bridge_relay
		 	echo -e "${RED}[+] Removing Bridge Relay data${NOCOLOR}"
		 	(sudo rm -r /var/lib/tor/keys) 2>/dev/null
		 	(sudo rm /var/lib/tor/fingerprint) 2>/dev/null
		 	(sudo rm /var/lib/tor/hashed-fingerprint) 2>/dev/null
		 	(sudo rm -r /var/lib/tor/pt_state) 2>/dev/null
		 	echo -e "${YELLOW}[+] DONE!${NOCOLOR}"
		 	sleep 4
		 	restarting_tor menu-server
		 fi
  ;;

  *)
    clear
    exit 0
esac
bash menu-server
