#!/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 script backups TorBox's configuration
#
# SYNTAX
# ./backup
#
#
##### SET VARIABLES ######
#
#Set the the variables for the menu
MENU_WIDTH=80
MENU_HEIGHT_25=25
MENU_HEIGHT_20=20

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

#Generating the filename for the backup
BACKUP_DIR="/home/torbox/backup"
OS_BK_TAR="$BACKUP_DIR/torbox_backup-$(date +%Y-%m-%d-%H'h'-%M'm').tgz"

#Other variables
TORRC="/etc/tor/torrc"
TOR_USER="debian-tor"
DATA_DIR_ROOT="/var/lib"
DATA_DIR="${DATA_DIR_ROOT}/tor"
DATA_DIR_OS="${DATA_DIR}/services"
CLIENT_ONION_AUTH_DIR="${DATA_DIR}/onion_auth"
HASHED_FINGERPRINT_DIR="${DATA_DIR}/hashed-fingerprint"
WEBSITE_DIR="/var/www"
NGINX_DIR="/etc/nginx"
RUNDIR="/home/torbox/torbox/run"
TXT_DIR="/home/torbox/torbox/text"


###### MAIN ######
clear
INPUT=$(cat "${TXT_DIR}/backup-text")
if (whiptail --title "TorBox - INFO (scroll down!)" --scrolltext --yesno "$INPUT" $MENU_HEIGHT_25 $MENU_WIDTH); then
	exitstatus=$?
	if [ "$exitstatus" = "0" ]; then

		# OBFS4 Bridge Relay data exist?
		if sudo -u "${TOR_USER}" [ ! -f "${HASHED_FINGERPRINT_DIR}" ]; then
			OBFS4RELAY=0
		else
			OBFS4RELAY=1
		fi

		# Onion Services available?
		SERVICE_NAME_LIST=$(sudo -u "${TOR_USER}" ls "${DATA_DIR_OS}")
		if [ -z "${SERVICE_NAME_LIST}" ]; then
			ONIONSERVICES=0
		else
			ONIONSERVICES=1
		fi

		# Onion Client Authorization used?
		ONION_AUTH_LIST=$(sudo -u "${TOR_USER}" ls "${CLIENT_ONION_AUTH_DIR}")
		if [ -z "${ONION_AUTH_LIST}" ]; then
			ONIONAUTH=0
		else
			ONIONAUTH=1
		fi

		# Please, choose with SPACE which data you want to includ
		if [ "$OBFS4RELAY" == "1" ] || [ "$ONIONSERVICES" == "1" ] || [ "$ONIONAUTH" == "1" ] ; then
			WHIPTAIL_LINE="whiptail --nocancel --title \"TorBox v.0.5.5 - BACKUP SELECTION\" --checklist --separate-output \"\nAdditionally to the TorBox configuration, we have found OBFS4 Bridge Relay and/or Onion Services data, which can be included in the backup. \n\nPlease, choose with SPACE which data you want to includ and press ENTER \n(ESC -> go back)\n\" $MENU_HEIGHT_20 $MENU_WIDTH 3"
			i=0
			n=0
			if [ "$OBFS4RELAY" == "1" ]; then
				i=$((i+1))
				n=1
				WHIPTAIL_LINE="$WHIPTAIL_LINE \"$i\" \"Backup the OBFS4 Bridge Relay data\" ON"
			fi
			if [ "$ONIONSERVICES" == "1" ]; then
				n=$((2+n))
				i=$((i+1))
				WHIPTAIL_LINE="$WHIPTAIL_LINE \"$i\" \"Backup the Onion Services data\" ON"
				i=$((i+1))
				WHIPTAIL_LINE="$WHIPTAIL_LINE \"$i\" \"Backup all shared folders\" ON"
			fi
			if [ "$ONIONAUTH" == "1" ]; then
				i=$((i+1))
				n=$((4+n))
				WHIPTAIL_LINE="$WHIPTAIL_LINE \"$i\" \"Backup all server access authorization\" ON"
			fi
			WHIPTAIL_LINE="$WHIPTAIL_LINE 3>&1 1>&2 2>&3"
			CHOICE=$(eval $WHIPTAIL_LINE)
			exitstatus=$?
			# exitstatus == 1 means that the ESC key was pressed
			[ "$exitstatus" == "1" ] && exit 1
			OBFS4RELAY=0
			ONIONSERVICES=0
			SHAREDFOLDERS=0
			ONIONAUTH=0
			if [ ! -z "$CHOICE" ]; then mapfile -t CHOICE <<< "$CHOICE"
				if [ "$n" == "1" ] && [ "${CHOICE[0]}" == "1" ]; then OBFS4RELAY=1; fi
				if [ "$n" == "2" ] && [ "${CHOICE[0]}" == "1" ]; then ONIONSERVICES=1; fi
				if [ "$n" == "2" ] && [ "${CHOICE[0]}" == "2" ]; then SHAREDFOLDERS=1; fi
				if [ "$n" == "2" ] && [ "${CHOICE[1]}" == "2" ]; then SHAREDFOLDERS=1; fi
				if [ "$n" == "3" ] && [ "${CHOICE[0]}" == "1" ]; then OBFS4RELAY=1; fi
				if [ "$n" == "3" ] && [ "${CHOICE[0]}" == "2" ]; then ONIONSERVICES=1; fi
				if [ "$n" == "3" ] && [ "${CHOICE[0]}" == "3" ]; then SHAREDFOLDERS=1; fi
				if [ "$n" == "3" ] && [ "${CHOICE[1]}" == "2" ]; then ONIONSERVICES=1; fi
				if [ "$n" == "3" ] && [ "${CHOICE[1]}" == "3" ]; then SHAREDFOLDERS=1; fi
				if [ "$n" == "3" ] && [ "${CHOICE[2]}" == "3" ]; then SHAREDFOLDERS=1; fi
				if [ "$n" == "4" ] && [ "${CHOICE[0]}" == "1" ]; then ONIONAUTH=1; fi
				if [ "$n" == "5" ] && [ "${CHOICE[0]}" == "1" ]; then OBFS4RELAY=1; fi
				if [ "$n" == "5" ] && [ "${CHOICE[0]}" == "2" ]; then ONIONAUTH=1; fi
				if [ "$n" == "5" ] && [ "${CHOICE[1]}" == "2" ]; then ONIONAUTH=1; fi
				if [ "$n" == "6" ] && [ "${CHOICE[0]}" == "1" ]; then ONIONSERVICES=1; fi
				if [ "$n" == "6" ] && [ "${CHOICE[0]}" == "2" ]; then SHAREDFOLDERS=1; fi
				if [ "$n" == "6" ] && [ "${CHOICE[0]}" == "3" ]; then ONIONAUTH=1; fi
				if [ "$n" == "6" ] && [ "${CHOICE[1]}" == "2" ]; then SHAREDFOLDERS=1; fi
				if [ "$n" == "6" ] && [ "${CHOICE[1]}" == "3" ]; then ONIONAUTH=1; fi
				if [ "$n" == "6" ] && [ "${CHOICE[2]}" == "3" ]; then ONIONAUTH=1; fi
				if [ "$n" == "7" ] && [ "${CHOICE[0]}" == "1" ]; then OBFS4RELAY=1; fi
				if [ "$n" == "7" ] && [ "${CHOICE[0]}" == "2" ]; then ONIONSERVICES=1; fi
				if [ "$n" == "7" ] && [ "${CHOICE[0]}" == "3" ]; then SHAREDFOLDERS=1; fi
				if [ "$n" == "7" ] && [ "${CHOICE[0]}" == "4" ]; then ONIONAUTH=1; fi
				if [ "$n" == "7" ] && [ "${CHOICE[1]}" == "2" ]; then ONIONSERVICES=1; fi
				if [ "$n" == "7" ] && [ "${CHOICE[1]}" == "3" ]; then SHAREDFOLDERS=1; fi
				if [ "$n" == "7" ] && [ "${CHOICE[1]}" == "4" ]; then ONIONAUTH=1; fi
				if [ "$n" == "7" ] && [ "${CHOICE[2]}" == "3" ]; then SHAREDFOLDERS=1; fi
				if [ "$n" == "7" ] && [ "${CHOICE[2]}" == "4" ]; then ONIONAUTH=1; fi
				if [ "$n" == "7" ] && [ "${CHOICE[3]}" == "4" ]; then ONIONAUTH=1; fi
			fi
		fi
		BACKUPSTRING="${TORRC} ${RUNDIR} ${NGINX_DIR}"
		if [ "$OBFS4RELAY" == "1" ]; then BACKUPSTRING="$BACKUPSTRING ${DATA_DIR}/fingerprint ${DATA_DIR}/hashed-fingerprint ${DATA_DIR}/keys ${DATA_DIR}/pt_state"; fi
		if [ "$ONIONSERVICES" == "1" ]; then BACKUPSTRING="$BACKUPSTRING ${DATA_DIR_OS}" ; fi
		if [ "$ONIONAUTH" == "1" ]; then BACKUPSTRING="$BACKUPSTRING ${CLIENT_ONION_AUTH_DIR}"; fi
		if [ "$SHAREDFOLDERS" == "1" ]; then
			BACKUPSTRING="$BACKUPSTRING ${WEBSITE_DIR}";
		else
			sudo find "$WEBSITE_DIR" -type d >${RUNDIR}/directories_list.txt
		fi
		clear
		echo -e "${RED}[+] Start backup...${NOCOLOR}"
		echo -e "${RED}[+] Calculating size...${NOCOLOR}"
		NEEDED_SIZE=$(sudo tar -cz --absolute-names ${BACKUPSTRING} | wc -c)

		# Useful, if we will implement the mounting of an USB drive under BACKUP_DIR
		AVAILABLE_SIZE=$(df -a | grep "$BACKUP_DIR" | awk '{print $4}')
		if [ -z "$AVAILABLE_SIZE" ]; then AVAILABLE_SIZE=$(df -k / | tail -1 | awk '{print $4}'); fi
		AVAILABLE_SIZE=$((AVAILABLE_SIZE*1024))
		if [ $NEEDED_SIZE -lt $AVAILABLE_SIZE ]; then

			echo -e "${RED}[+] Backup in progress...${NOCOLOR}"
			if [ ! -d "$BACKUP_DIR" ]; then
				mkdir $BACKUP_DIR
			fi
			(sudo tar -cpzf "$OS_BK_TAR" --absolute-names ${BACKUPSTRING}) 2>/dev/null
			sudo rm "${RUNDIR}/directories_list.txt"
			LINK_EXIST=$(ls -L "$BACKUP_DIR/shared_folders" 2>/dev/null)
			if [ -z "$LINK_EXIST" ]; then
				echo -e "${RED}[+] Creating a link to the shared folders.${NOCOLOR}"
				(sudo ln -sf "${WEBSITE_DIR}" "${BACKUP_DIR}/shared_folders") 2>/dev/null
			fi
			echo ""
			echo -e "${YELLOW}[+] Backup is done!${NOCOLOR}"
			echo -e "${RED}[+] You will find it here: ${YELLOW}${OS_BK_TAR}"
			echo " "
			read -n 1 -s -r -p $'\e[1;31mPlease press any key to continue... \e[0m'
			clear
		else
			clear
			echo -e "${YELLOW}[!] ABORT! NOT ENOUGH SPACE!${NOCOLOR}"
			echo -e "${YELLOW}[+] Did you include shared folders? Please, try again without them!${NOCOLOR}"
			echo " "
			read -n 1 -s -r -p $'\e[1;31mPlease press any key to continue... \e[0m'
			clear
			exit 1
		fi
	fi
fi
