#!/bin/bash
# shellcheck disable=SC2001,SC2064

# 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, is only use once during the first start-up.
# The purpose is to configure some important settings before or TorBox is
# connecting the tor network (for example OBFS4, Tor Automatic Counteractions...)
#
# SYNTAX
# ./first_use <NUMBER> <SOURCE_SCRIPT>
#
# Following NUMBERs are supported:
# 0 - Not a fresh installation - does nothing
# 1 - Will install and configure the OpenVPN server in a TorBox on a cloud installation (currently: 1 -> 3)
# 2 - Will generate new unique SSH server keys (currently: 2 -> 3)
# 3 - Will ask the source of the Internet, if OBFS4 bridges should be aktivated (and then unmask) and if TACA be activated (currently: 3 -> 0)
#
# If SOURCE_SCRIPT is empty, the default is then the script was started from the shell or at the beginning --> starts menu at the end
#
##### SET VARIABLES ######
#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_10=10

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

# Identify the Operating System
CHECK_OS="$(lsb_release -si)"
CHECK_OS="$(echo "$CHECK_OS" | tail -n1)"
if [ "$CHECK_OS" == "Debian" ] && [ -f /etc/rpi-issue ] ; then CHECK_OS="Raspbian" ; fi

# Other variables
TORRC="/etc/tor/torrc"
TORBOX_PATH="/home/torbox/torbox"
RUNFILE="$TORBOX_PATH/run/torbox.run"
TXT_DIR="$TORBOX_PATH/text"
FRESHINSTALLED=$1
[ ! -z $2 ] && SOURCE_SCRIPT=$2 || SOURCE_SCRIPT=menu

#Check if this installation is on a cloud
ON_A_CLOUD=$(grep "^ON_A_CLOUD=.*" ${RUNFILE} | sed "s/.*=//g")

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

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

# This function is used for the step 1 as a trap for q
# Syntax finish_bridge_start2
# Used predefined variables: RED, NOCOLOR, TORRC
finish_bridge_start2()
{
  # Did tor with bridge-support start up?
	REPLY=""
	while true
	do
		read -r -p $'\e[1;91mDid you see \"Bootstrapped 100%: Done\" [Y/n]? -> \e[0m'
		# The following line is for the prompt to appear on a new line.
		if [[ $REPLY =~ ^[YyNn]$ ]] ; then
			echo
			echo
			break
		fi
	done
	if [[ $REPLY =~ ^[Yy]$ ]] ; then
		echo -e "${RED}[+] DONE! TorBox is ready to work! Be careful with using it!${NOCOLOR}"
		echo
		echo
		sleep 5
		exit 0
	else
		clear
		whiptail --textbox $TXT_DIR/first_use-not_working-text $MENU_HEIGHT_15 $MENU_WIDTH
		CHECK=$(grep "^#ReachableAddresses" ${TORRC})
		if [ -z ${CHECK} ] ; then
			sudo sed -i "s/^ReachableAddresses /#ReachableAddresses /g" ${TORRC}
		else
			sudo sed -i "s/^#ReachableAddresses /ReachableAddresses /g" ${TORRC}
		fi
		clear
		trap "bash menu-bridges; trap; exit 0" EXIT
		exit 0
	fi
}

# This function is used for the main program as a trap for q
# Syntax finish_bridge_start1
# Used predefined variables: RED, NOCOLOR, TORRC
finish_bridge_start1()
{
  # Did tor with bridge-support start up?
 	while true
 	do
 		read -r -p $'\e[1;91mDid you see \"Bootstrapped 100%: Done\" [Y/n]? -> \e[0m'
 		# The following line is for the prompt to appear on a new line.
 		if [[ $REPLY =~ ^[YyNn]$ ]] ; then
 			echo
 			echo
 			break
 		fi
 	done
 	if [[ $REPLY =~ ^[Yy]$ ]] ; then
 		echo -e "${RED}[+] DONE! TorBox is ready to work! Be careful with using it!${NOCOLOR}"
 		echo
 		echo
 		sleep 5
 		exit 0
 	else
    INPUT=$(cat $TXT_DIR/first_use-anti-firewall-text)
		if (whiptail --title "TorBox - FIRST START UP!" --no-button "SUB-MENU" --yes-button "CHANGE ANTI-FIREWALL" --yesno "$INPUT" $MENU_HEIGHT_20 $MENU_WIDTH); then
			CHECK=$(grep "^#ReachableAddresses" ${TORRC})
			if [ -z ${CHECK} ] ; then
				sudo sed -i "s/^ReachableAddresses /#ReachableAddresses /g" ${TORRC}
			else
				sudo sed -i "s/^#ReachableAddresses /ReachableAddresses /g" ${TORRC}
			fi
      clear
			echo -e "${RED}[+] DONE! Checking progress - please be patient!${NOCOLOR}"
		  echo -e "    Ignore any error messages; this can take a while; please wait..."
		  echo -e "    Finally, you should see \"${YELLOW}Bootstrapped 100%: Done${NOCOLOR}\"."
		  echo -e "    You can leave the progress report by pressing q."
		  echo ""
			stty intr q
			# shellcheck disable=SC2064
			trap "finish_bridge_start2" SIGINT
      sudo systemctl restart tor &
			sudo tail -f -n 0 /var/log/tor/notices.log | sed -u 's#.*Bootstrapped 100% (done): Done#\x1b[93m&\x1b[0m#' | sed -u 's#Bootstrapped 100% (done): Done#Bootstrapped 100% (done): Done -- YOU CAN PRESS NOW Q!#' | grep -v -e "Rejecting ill-formed reverse lookup" -e "Missing mapping for virtual address" -e "You configured a non-loopback address" -e "opening log file" -e "Application request when we haven't" -e "Giving up. (waiting for circuit)" -e "New control connection opened from" -e "While fetching directory info, no running dirservers known"
			stty intr ^c
		else
			clear
			echo -e "${RED}[+] We are starting now the Countermeasure sub-menu${NOCOLOR}"
			echo -e "${RED}[+] For more information see here: https://www.torbox.ch/?page_id=797${NOCOLOR}"
			echo
			echo
			read -n 1 -s -r -p "Press any key to continue"
			sudo sed -i "s/^FRESH_INSTALLED=.*/FRESH_INSTALLED=0/" ${RUNFILE}
			trap "bash menu-bridges; trap; exit 0" EXIT
			exit 0
		fi
	fi
}

######## PREPARATIONS ########
# Resetting
clear
sleep 1
shopt -s checkwinsize
[ -f nohup.out ] && sudo rm nohup.out
stty intr ^c
trap
clear
sleep 1

# Probabaly only under Ubuntu shell output line separator fails to get reset: https://superuser.com/questions/1650758/how-does-the-shell-output-line-separator-fail-to-get-reset
if [ "$CHECK_OS" == "Ubuntu" ]; then stty sane; fi
if [ -z "$FRESHINSTALLED" ]; then FRESHINSTALLED=$(grep "^FRESH_INSTALLED=.*" ${RUNFILE} | sed "s/.*=//g"); fi


######## MAIN ########
while [ $FRESHINSTALLED -gt 0 ]; do
  case $FRESHINSTALLED in

		# NEW v.0.5.4: Only executed if installed with --on_a_cloud
    1)
      clear
			sudo sed -i "s/^FRESH_INSTALLED=.*/FRESH_INSTALLED=3/" ${RUNFILE}
			FRESHINSTALLED=3
			if [[ ! -e /etc/openvpn/server.conf ]]; then sudo bash $TORBOX_PATH/install/openvpn-install.sh on_a_cloud; fi
			./menu 5
    ;;

    # This will generate new unique SSH server keys (only for images)
    2)
      clear
      sudo sed -i "s/^FRESH_INSTALLED=.*/FRESH_INSTALLED=3/" ${RUNFILE}
      echo -e "${BRED}[+] First time starting your TorBox!${NOCOLOR}"
      echo -e "${BRED}[+] Generating new unique SSH server keys for your TorBox installation!${NOCOLOR}"
      (sudo rm -r /etc/ssh/ssh_host_*) 2>/dev/null
      sudo ssh-keygen -A
      echo ""
      echo -e "${BRED}[+] To take effect, you have to close and reopen all your SSH sessions.${NOCOLOR}"
      FRESHINSTALLED=3
      sleep 10
    ;;

    # This will ask the source of the Internet, if OBFS4 bridges should be aktivated (and then unmask) and if TACA should be activated.
    3)
			# If there is still a home directory / user called "ubuntu", then we will remove it.
			if [ -d "/home/ubuntu" ]; then
				(sudo userdel -r ubuntu) 2>/dev/null
			fi

			# Welcome screen and asking if the user wants to configure the new installed TorBox
      clear
      INPUT=$(cat $TXT_DIR/first_use-welcome-text)
      if (whiptail --title "TorBox - FIRST START UP (scroll down!)" --scrolltext --yesno "$INPUT" $MENU_HEIGHT_25 $MENU_WIDTH); then
        sleep 1
      else
        sudo sed -i "s/^FRESH_INSTALLED=.*/FRESH_INSTALLED=0/" ${RUNFILE}
        exit 0
      fi

			# Implementation of optional randomization of the hostname to prevent ISPs to see the default
			INPUT=$(cat $TXT_DIR/randomize_hostname-text)
			HOSTNAME=$(hostname)
			INPUT=$(sed "s/HOSTNAMEANKER/$HOSTNAME/g" <<< "$INPUT")
			if (whiptail --title "TorBox Installation on Raspberry Pi OS" --defaultno --yes-button "CHANGE!" --yesno "$INPUT" $MENU_HEIGHT_20 $MENU_WIDTH); then
				exitstatus=$?
				# exitstatus == 255 means that the ESC key was pressed
				if [ "$exitstatus" != "255" ]; then
					if (whiptail --title "TorBox Installation on Raspberry Pi OS" --no-button "SET HOSTNAME" --yes-button "RANDOMIZE HOSTNAME" --yesno "You can set a specific hostname or use a randomized one. Please choose..." $MENU_HEIGHT_10 $MENU_WIDTH); then
						# shellcheck disable=SC2002
						HOSTNAME=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 10 | head -n 1)
					else
						exitstatus=$?
						# exitstatus == 255 means that the ESC key was pressed
						if [ "$exitstatus" != "255" ]; then
							HOSTNAME=$(whiptail --title "TorBox Installation on Raspberry Pi OS" --inputbox "\nEnter the hostname:" $MENU_HEIGHT_10 $MENU_WIDTH_REDUX 3>&1 1>&2 2>&3)
							if [[ $HOSTNAME != *[0123456789ABCDEFGHIJKLMNOPQRSTUVWXZYabcdefghijklmnopqrstuvwxzy-]* ]]; then
								HOSTNAME=$(tr -dc 'a-zA-Z0-9' <<<$HOSTNAME)
							fi
							if ${#HOSTNAME} -gt 64 ; then
								HOSTNAME=$(head -c 64 <<<$HOSTNAME)
							fi
						fi
					fi
				fi
				# exitstatus == 255 means that the ESC key was pressed
				if [ "$exitstatus" != "255" ] && [ "$HOSTNAME" != "" ]; then
					clear
					echo -e "${RED}[+] Setting up the hostname...${NOCOLOR}"
					sleep 1
					(sudo hostnamectl set-hostname "$HOSTNAME") 2>/dev/null
					clear
					sudo systemctl restart systemd-hostnamed
					if grep "127.0.1.1.*" /etc/hosts ; then
						(sudo sed -i "s/127.0.1.1.*/127.0.1.1\t$HOSTNAME/g" /etc/hosts) 2>/dev/null
						clear
					else
						(sudo sed -i "s/^::1/127.0.1.1\t$HOSTNAME\n::1/g" /etc/hosts) 2>/dev/null
						clear
					fi
					whiptail --title "TorBox - INFO" --msgbox "TorBox's hostname is now changed to $HOSTNAME\n\nYou have to log out and again log into your console to see the change." $MENU_HEIGHT_10 $MENU_WIDTH_REDUX
				fi
			fi

			# Will the user keep using the default configured firewall circumvention?
			INPUT=$(cat $TXT_DIR/first_use-firewall-text)
			if (whiptail --title "TorBox - FIRST START UP!" --defaultno --yesno "$INPUT" $MENU_HEIGHT_25 $MENU_WIDTH); then
				sudo sed -i "s/^#ReachableAddresses /ReachableAddresses /g" ${TORRC}
			else
				sudo sed -i "s/^ReachableAddresses /#ReachableAddresses /g" ${TORRC}
			fi

			# Configuring the source of the Internet (not on a cloud)
			if [ "$ON_A_CLOUD" -eq "0" ]; then
				check_interface_with_internet
    		CHOICE=$(whiptail --nocancel --title "TorBox v.0.5.5 - FIRST START UP!" --menu "From where is the Internet coming? (ESC -> don't change)" 16 $MENU_WIDTH 8 \
    		"==" "===============================================================" \
    		" 1" "Ethernet cable (eth0) or TorBox on a cloud (tun1)          "$FLASH_ETH0 \
    		" 2" "Wireless network (USB adapter; wlan1)                      "$FLASH_WLAN1 \
    		" 3" "Wireless network or TorBox mini (onboard chip; wlan0)      "$FLASH_WLAN0 \
    		" 4" "Cellular, USB dongle or Tethering (Android) (ppp0; usb0)   "$FLASH_USB0 \
    		" 5" "USB ethernet adapter or Tethering (iOS) (eth1)             "$FLASH_ETH1 \
    		" 6" "Over a VPN connection (tun0)                               "$FLASH_TUN0 \
    		"==" "===============================================================" \
    		3>&1 1>&2 2>&3)

      	# This will configure the origin of the Internet.
      	CHOICE=$(echo "$CHOICE" | tr -d ' ')
      	if [ ! -z "$CHOICE" ]; then
        	if [[ $CHOICE -gt 0  && $CHOICE -lt 7 ]]; then
          	CHOICE=$((CHOICE+4))
						# NEW v.0.5.4-post
						# If something gets wrong, we want to be shure that tor is unmasked and that the first use dialogue is not started again
						(sudo systemctl unmask tor) 2>/dev/null
						(sudo systemctl unmask tor@default.service) 2>/dev/null
						echo -e "${RED}[+] Unmasking Tor...${NOCOLOR}"
						echo -e "${RED}[+] Enable Tor...${NOCOLOR}"
						(sudo systemctl enable tor) 2>/dev/null
						sudo sed -i "s/^FRESH_INSTALLED=.*/FRESH_INSTALLED=0/" ${RUNFILE}
						./menu $CHOICE
        	fi
      	fi
				# Ask for TACA support (not on a cloud)
      	clear
      	INPUT=$(cat $TXT_DIR/first_use-TACA-text)
				if (whiptail --title "TorBox - FIRST START UP!" --yesno "$INPUT" $MENU_HEIGHT_15 $MENU_WIDTH); then
					clear
					# To start TACA, notices.log has to be present
					(sudo -u debian-tor touch /var/log/tor/notices.log) 2>/dev/null
					(sudo chmod -R go-rwx /var/log/tor/notices.log) 2>/dev/null
					if [ ! -f $TORBOX_PATH/log_check_config.py ]; then
						clear
						for ARGUMENT in $(seq 1 6) ; do
							echo -e "${RED}[+] Activating TorBox's automatic countermeasure - protection number $ARGUMENT${NOCOLOR}"
							sleep 1
							LOOP_NUMBER=$((LOOP_NUMBER+1))
							[ $LOOP_NUMBER = 1 ] && (cp $TORBOX_PATH/install/log_check_config/header $TORBOX_PATH/log_check_config.py) &>/dev/null
							[[ "$ARGUMENT" =~ [1-6] ]] && (cat $TORBOX_PATH/install/log_check_config/00"${ARGUMENT}" >> $TORBOX_PATH/log_check_config.py) &>/dev/null
						done
						(cat $TORBOX_PATH/install/log_check_config/footer >> $TORBOX_PATH/log_check_config.py) &>/dev/null
					fi
					(sudo sed -i "s/^LOGCHECK=.*/LOGCHECK=1/" $RUNFILE) &>/dev/null
					sudo pkill -f "log_check.py"
					sudo $TORBOX_PATH/log_check.py &
					echo -e "${RED}[+] TorBox's automatic countermeasure feature is activated!${NOCOLOR}"
					sleep 2
				else
					clear
					sudo pkill -f "log_check.py"
	     		(sudo rm $TORBOX_PATH/log_check_config.py) &>/dev/null
	     		(sudo find /var/log/tor/ | grep "automat" | xargs -d"\n" sudo rm) &>/dev/null
	     		(sudo sed -i "s/^LOGCHECK=.*/LOGCHECK=0/" $RUNFILE) &>/dev/null
      		sleep 1
    		fi
			fi

			# Synchronize time to avoid problems with bridges
			clear
			sudo timedatectl set-timezone UTC
			if [ "$CHECK_OS" == "Ubuntu" ]; then stty sane; fi
			settime
			# Ask for bridge support
			clear
      DEFAULT_BRIDGE_SUPPORT=0
      INPUT=$(cat $TXT_DIR/first_use-add-bridges-text)
			if (whiptail --title "TorBox - FIRST START UP" --defaultno --yesno "$INPUT" $MENU_HEIGHT_25 $MENU_WIDTH); then
				if grep "^ReachableAddresses" ${TORRC} ; then
					INPUT=$(cat $TXT_DIR/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
				if (whiptail --title "TorBox - INFO" --no-button "SNOWFLAKE" --yes-button "OBFS4" --yesno "Do you want to use OBFS4 or SNOWFLAKE bridges?" $MENU_HEIGHT_10 $MENU_WIDTH_REDUX); then
					sudo sed -i "s/^#UseBridges/UseBridges/g" ${TORRC}
					sudo sed -i "s/^#UpdateBridgesFromAuthority/UpdateBridgesFromAuthority/g" ${TORRC}
					sudo sed -i "s/^#ClientTransportPlugin meek_lite,obfs4/ClientTransportPlugin meek_lite,obfs4/g" ${TORRC}
					sudo sed -i "s/^ClientTransportPlugin snowflake /#ClientTransportPlugin snowflake /g" ${TORRC}
					sudo sed -i "s/^#Bridge obfs4 /Bridge obfs4 /g" ${TORRC}
					sudo sed -i "s/^Bridge snowflake /#Bridge snowflake /g" ${TORRC}
					sudo sed -i "s/^Bridge meek_lite /#Bridge meek_lite /g" ${TORRC}
				else
					sudo sed -i "s/^#UseBridges/UseBridges/g" ${TORRC}
					sudo sed -i "s/^#UpdateBridgesFromAuthority/UpdateBridgesFromAuthority/g" ${TORRC}
					sudo sed -i "s/^ClientTransportPlugin meek_lite,obfs4/#ClientTransportPlugin meek_lite,obfs4/g" ${TORRC}
					sudo sed -i "s/^#ClientTransportPlugin snowflake /ClientTransportPlugin snowflake /g" ${TORRC}
					sudo sed -i "s/^Bridge obfs4 /#Bridge obfs4 /g" ${TORRC}
					sudo sed -i "s/^Bridge meek_lite /#Bridge meek_lite /g" ${TORRC}
					clear
					sudo bash bin/bridges_activate_snowflake norestart
				fi
	      DEFAULT_BRIDGE_SUPPORT=1
				clear
        echo -e "${RED}[+] Starting Tor ${YELLOW}WITH${RED} bridge support...${NOCOLOR}"
        sleep 1
			else
				sudo sed -i "s/^UseBridges/#UseBridges/g" ${TORRC}
				sudo sed -i "s/^UpdateBridgesFromAuthority/#UpdateBridgesFromAuthority/g" ${TORRC}
				sudo sed -i "s/^ClientTransportPlugin meek_lite,obfs4/#ClientTransportPlugin meek_lite,obfs4/g" ${TORRC}
				sudo sed -i "s/^ClientTransportPlugin snowflake /#ClientTransportPlugin snowflake /g" ${TORRC}
				sudo sed -i "s/^Bridge obfs4 /#Bridge obfs4 /g" ${TORRC}
				sudo sed -i "s/^Bridge snowflake /#Bridge snowflake /g" ${TORRC}
				sudo sed -i "s/^Bridge meek_lite /#Bridge meek_lite /g" ${TORRC}
				DEFAULT_BRIDGE_SUPPORT=0
				clear
				echo -e "${RED}[+] Starting Tor ${YELLOW}WITHOUT${RED} OBFS4 bridge support...${NOCOLOR}"
				sleep 1
			fi
      (sudo systemctl unmask tor) 2>/dev/null
			(sudo systemctl unmask tor@default.service) 2>/dev/null
      echo -e "${RED}[+] Unmasking Tor...${NOCOLOR}"
      echo -e "${RED}[+] Enable Tor...${NOCOLOR}"
      (sudo systemctl enable tor) 2>/dev/null
      sudo sed -i "s/^FRESH_INSTALLED=.*/FRESH_INSTALLED=0/" ${RUNFILE}
			sleep 1
			clear
			echo -e "${RED}[+] DONE! Checking progress - please be patient!${NOCOLOR}"
		  echo -e "    Ignore any error messages; this can take a while; please wait..."
		  echo -e "    Finally, you should see \"${YELLOW}Bootstrapped 100%: Done${NOCOLOR}\"."
		  echo -e "    You can leave the progress report by pressing q."
		  echo ""
			stty intr q
			# shellcheck disable=SC2064
      if [ "$DEFAULT_BRIDGE_SUPPORT" == "1" ]; then
				trap "finish_bridge_start1" SIGINT;
			else
				trap "bash $SOURCE_SCRIPT; exit 0" SIGINT;
			fi
      sudo systemctl restart tor &
			sudo tail -f -n 0 /var/log/tor/notices.log | sed -u 's#.*Bootstrapped 100% (done): Done#\x1b[93m&\x1b[0m#' | sed -u 's#Bootstrapped 100% (done): Done#Bootstrapped 100% (done): Done -- YOU CAN PRESS NOW Q!#' | grep -v -e "Rejecting ill-formed reverse lookup" -e "Missing mapping for virtual address" -e "You configured a non-loopback address" -e "opening log file" -e "Application request when we haven't" -e "Giving up. (waiting for circuit)" -e "New control connection opened from" -e "While fetching directory info, no running dirservers known"
			stty intr ^c
    ;;

    *) exit 1
  esac
done
