#!/bin/bash
NF="\e[0m"
FB="\e[1m"
CG="\e[38;5;40m"
CR="\e[38;5;9m"
CY="\033[38;5;226m"

### BEGIN FUNCTION BLOCK

verifydefaultconfigpresence(){
if [ "$config" = "/opt/autoremakessh/client/defaultconfig" ]; then
    if  [ ! -f /opt/autoremakessh/client/defaultconfig ]; then
    echo -e ${CR}No default config found! Use -h argument for help.${NF}
    return 1
    fi
fi
}

verifyconfigvalidity(){
if [ ! -f $config ]; then
echo -e ${CR}Invalid config file location or permissions${NF}
return 1
fi
source $config
if [ "$server" = "" ]; then
    echo -e "${CR}[!] 'server' value cannot be empty! Exiting!"
    return 1
fi
if [ "$privkey" = "" ]; then
    echo -e "${CR}[!] 'privkey' value cannot be empty! Exiting!"
    return 1
fi
if [ "$pubkey" = "" ]; then
    echo -e "${CR}[!] 'pubkey' value cannot be empty! Exiting!"
    return 1
fi
if [ "$checksumdir" = "" ]; then
    echo -e "${CR}[!] 'checksumdir' value cannot be empty! Exiting!"
    return 1
fi
if [[ "$disablechecksums" != "0" && "$disablechecksums" != "1" ]]; then
    echo -e "${CR}[!] Invalid value for option 'disablechecksums'. Exiting!"
    return 1
fi
if [[ "$insecure" != "0" && "$insecure" != "1" ]]; then
    echo -e "${CR}[!] Invalid value for option 'insecure'. Exiting!"
    return 1
fi
}

guardband() {
if [ $? -ne 0 ]; then
echo ''
echo -e "${CR}Script Exited with an error.${NF}"
exit 1
fi
}

ipguardband() {
if [ $? -ne 0 ]; then
securitywarning
fi
}

verifyserver(){
if ! wget --spider "$server" 2>/dev/null; then
    echo -e "${CR}Error: Cannot reach provisioning server${NF}"
    echo -e "${CR}URL in config: $server ${NF}"
    return 1
    else
    echo -e "${CG}Server OK!${NF}"
    echo -e "${CG}URL in config: $server ${NF}"

    sleep 1
fi
}

checksums(){
if  [ "$disablechecksums" = "0" ]; then
    serversidePUB=$(wget $server/$checksumdir/$priv -q -O -)
    serversidePRIV=$(wget $server/$checksumdir/$pub -q -O -)
    else
    echo -e ${CY}Skipping checksum verification${NF}
fi
}

verifyconfigsecureIP(){
if [ "$insecure" = "1" ]; then
return 0
fi
    local host_part=$(echo "$server" | sed -E 's|^[a-zA-Z0-9]+://([^/]+).*|\1|')

    if [[ $host_part =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        ip="$host_part"
    else
        ip=""
        if command -v host >/dev/null 2>&1; then
            output=$(host "$host_part")
            if [[ $output =~ has\ address ]]; then
                ip=$(echo "$output" | awk '{print $4}')
            fi
        elif command -v nslookup >/dev/null 2>&1; then
            output=$(nslookup "$host_part")
            if [[ $output =~ Name: ]]; then
                ip=$(echo "$output" | awk '{print $2}')
            fi
        elif command -v dig >/dev/null 2>&1; then
            output=$(dig +short "$host_part")
            ip="$output"
        else
            output=$(getent ahosts "$host_part")
            if [[ $output =~ [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+ ]]; then
                ip=$(echo "$output" | awk '{print $1}')
            fi
        fi

        if [[ -z "$ip" ]]; then
            echo -e ${CR}"[!] Unable to resolve IP address for host '$host_part'."${NF}
            return 1
        fi
    fi

local oct1=$(echo "$ip" | cut -d. -f1)
local oct2=$(echo "$ip" | cut -d. -f2)

if [[ -n $oct1 && $oct1 =~ ^[0-9]+$ ]] && [[ -n $oct2 && $oct2 =~ ^[0-9]+$ ]]; then
    if [[ $oct1 -eq 10 ]]; then
        return 0
    fi
    if [[ $oct1 -eq 172 ]] && [[ $oct2 -ge 16 ]] && [[ $oct2 -le 31 ]]; then
        return 0
    fi
    if [[ $oct1 -eq 192 ]] && [[ $oct2 -eq 168 ]]; then
        return 0
    fi
fi
    return 1
}

securitywarning(){
echo ''
echo -e "${CR}${FB}@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@${NF}"
echo -e "${CR}${FB}@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@${NF}"
echo -e "${CR}${FB}@@@                                                                      @@@${NF}"
echo -e "${CR}${FB}@@@                                                                      @@@${NF}"
echo -e "${CR}${FB}@@@    WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!    @@@${NF}"
echo -e "${CR}${FB}@@@                                                                      @@@${NF}"
echo -e "${CR}${FB}@@@                                                                      @@@${NF}"
echo -e "${CR}${FB}@@@     Security Check has reported a fail - Either config is using      @@@${NF}"
echo -e "${CR}${FB}@@@     a public IP as a target server for provisioning, or hostname     @@@${NF}"
echo -e "${CR}${FB}@@@                        couldn't be resolved.                         @@@${NF}"
echo -e "${CR}${FB}@@@                                                                      @@@${NF}"
echo -e "${CR}${FB}@@@        Assuming by default that the target server is publicly        @@@${NF}"
echo -e "${CR}${FB}@@@       reachable, this is an incredibly bad idea as it exposes        @@@${NF}"
echo -e "${CR}${FB}@@@       your keys on the internet, which is the same as leaving        @@@${NF}"
echo -e "${CR}${FB}@@@             your machine passwordless over the internet.             @@@${NF}"
echo -e "${CR}${FB}@@@                                                                      @@@${NF}"
echo -e "${CR}${FB}@@@      Please consider using a local server that isn't exposed to      @@@${NF}"
echo -e "${CR}${FB}@@@     the internet unless you accept the risks or know what you're     @@@${NF}"
echo -e "${CR}${FB}@@@                                doing.                                @@@${NF}"
echo -e "${CR}${FB}@@@                                                                      @@@${NF}"
echo -e "${CR}${FB}@@@      If you have already generated new keys using the publicly       @@@${NF}"
echo -e "${CR}${FB}@@@     exposed server, it is strongly recommended to reset your keys    @@@${NF}"
echo -e "${CR}${FB}@@@                             IMMEDIATELY!                             @@@${NF}"
echo -e "${CR}${FB}@@@                                                                      @@@${NF}"
echo -e "${CR}${FB}@@@                                                                      @@@${NF}"
echo -e "${CR}${FB}@@@        You can override this warning by setting 'insecure' to 1      @@@${NF}"
echo -e "${CR}${FB}@@@       in the active config file. Refer to docs for more details.     @@@${NF}"
echo -e "${CR}${FB}@@@                                                                      @@@${NF}"
echo -e "${CR}${FB}@@@                                                                      @@@${NF}"
echo -e "${CR}${FB}@@@    WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!    @@@${NF}"
echo -e "${CR}${FB}@@@                                                                      @@@${NF}"
echo -e "${CR}${FB}@@@                                                                      @@@${NF}"
echo -e "${CR}${FB}@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@${NF}"
echo -e "${CR}${FB}@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@${NF}"
sleep 30
exit 1
}

usage() {
  echo ""
    echo "Usage:"
    echo "autoremakessh [MODE] [OPTIONS]"
    echo ""
    echo "Possible modes:"
    echo "Default - Client mode"
    echo "-s - Server mode"
    echo ""
    echo "Possible Options:"
    echo "-c [FILE] - Configuration file to use (Default /opt/autoremakessh/client/defaultconfig)"
    echo "-h - Display this message"
    exit 0
}

### END FUNCTION BLOCK

config="/opt/autoremakessh/client/defaultconfig"
srvmode=0

echo ""
echo "AutoremakeSSH Version 20260410-0"
echo "© 2026 Franscobec - AGPLv3 License"
echo "https://git.franscorack.com/Franscobec/AutoremakeSSH/src/branch/main/"
echo ""

while getopts ":c:sh" opt; do
  case ${opt} in
    c )
      config=$OPTARG
      ;;
    s )
      srvmode=1
      ;;
    h )
      usage
      ;;
    \? )
      echo "Invalid option: -$OPTARG" 1>&2
      exit 1
      ;;
    : )
      echo "Invalid option: -$OPTARG requires an argument" 1>&2
      exit 1
      ;;
  esac
done

shift $((OPTIND -1))
if [ -z "$config" ]; then
  echo "No custom config file specified. Using default: $config"
fi

if [ "$srvmode" -eq 1 ]; then
  echo "Server mode is not yet implemented"
  exit 1
fi

verifydefaultconfigpresence
guardband
verifyconfigvalidity
guardband
verifyserver
guardband
verifyconfigsecureIP
ipguardband
    verifydefaultconfigpresence
    guardband
    verifyconfigvalidity
    guardband
    verifyserver

fi
