#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-06-17; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.installer.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 2024-2025; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-FileType: SOURCE
# SPDX-License-Identifier: EUPL-1.2 OR LicenseRef-CCLA-1.0
# SPDX-LicenseComment: This file is part of the CISS.debian.installer.secure framework.
# SPDX-PackageName: CISS.debian.installer
# SPDX-Security-Contact: security@coresecret.eu

### Contributions so far see ./docs/CREDITS.md

# TODO: Move this command later than 4131_installation_systemd.sh
### Set the X11 keyboard layout (for graphical environments).
#do_in_target "${TARGET}" localectl set-x11-keymap "${locale_keyboard_xkb_keymap}"
# TODO: Update preseed.yaml for pgp signing key AND / OR implementation of presigned unlock_wrapper.sh
# TODO: Implement Clang Build Chain and Secure Boot PK CISS.ROOT.CA Signing Workflow
# TODO: Update preseed.yaml for pgp signing key OR implementation of presigned unlock_wrapper.sh
# TODO: Implement Console Login Deactivation and 2fa as advertised in preseed.yaml Refactor 4500_installation_accounts.sh
# TODO: Check Packages for installation. Refactor preseed.yaml, 4130_installation_toolset.sh, 4700_setup_packages.sh
# TODO: What do we need for CISS environment?
# TODO: Hardening Scripts Integration
# TODO: SSH 2fa integration
# TODO: Recovery Partition Integration
# TODO: Grub Boot Menu Update for Recovery Integration
# TODO: update-grub Post Hook Clang, Recovery, Signing PK
# TODO: Copying Log Files to final System
# TODO: Integrate CISS.debian.installer calling arguments and preseed.yaml into CISS.debian.live.builder build chain?
# TODO: Reboot function for Autoinstall
# TODO: 0105_arg_nuke_converter.sh - implement HashRounds as argument
# TODO: Implement loop_pass() for other passwords 0105_arg_nuke_converter.sh
# TODO: Implement / Integrate IP, Port validation CDI_1200

### WHY BASH?
# Ease of installation. No compiling or installing gems, CPAN modules, pip packages, etc. Simple to use and read. Clear syntax
# and straightforward output interpretation. Built-in power. Pattern matching, line processing, and regular expression support
# are available natively, no external binaries required. Cross-platform consistency. '/bin/bash' is the default shell on most
# Linux distributions, ensuring scripts run unmodified across systems. macOS compatibility. Since macOS Catalina (10.15), the
# default login shell has been zsh, but bash remains available at '/bin/bash'. Windows support. You can use bash via WSL, MSYS2,
# or Cygwin on Windows systems.

### CATCH ARGUMENTS AND DECLARE BASIC VARIABLES.
# shellcheck disable=SC2155
declare -girx VAR_START_TIME="${SECONDS}"                                # Start time of script execution.
declare -grx  VAR_PARAM_COUNT="$#"                                       # Arguments passed to script.
declare -grx  VAR_PARAM_STRNG="$*"                                       # Arguments passed to script as string.
declare -ag   ARY_PARAM_ARRAY=("$@")                                     # Arguments passed to script as an array.
declare -grx  VAR_SETUP_FILE="${0##*/}"                                  # 'setup.sh'
declare -grx  VAR_SETUP_PATH="$(cd "$(dirname "${0}")" && pwd)"          # '/opt/git/CISS.debian.installer'
declare -grx  VAR_SETUP_FULL="$(cd "$(dirname "${0}")" && pwd)/${0##*/}" # '/opt/git/CISS.debian.installer/setup.sh'

### PRELIMINARY CHECKS.
### No ash, dash, ksh, sh.
# shellcheck disable=2292
[ -z "${BASH_VERSINFO[0]}" ] && {
  . ./meta_loader_early.sh
  printf "%b❌ Please make sure you are using 'bash'! Bye... %b%b" "${RED}" "${RES}" "${NL}" >&2
  exit "${ERR_UNSUPPORTED_BASH}"
}

### No zsh.
[[ -n "${ZSH_VERSION:-}" ]] && {
  . ./meta_loader_early.sh
  printf "%b❌ Please make sure you are using 'bash'! Bye... %b%b" "${RED}" "${RES}" "${NL}" >&2
  exit "${ERR_UNSUPPORTED_BASH}"
}

### Not root.
[[ ${EUID} -ne 0 ]] && {
  . ./meta_loader_early.sh
  printf "%b❌ Please make sure you are 'root'! Bye... %b%b" "${RED}" "${RES}" "${NL}" >&2
  exit "${ERR_USER_IS_NOT_ROOT}"
}

### Not called by sh.
# shellcheck disable=2312
[[ $(kill -l | grep -c SIG) -eq 0 ]] && {
  . ./meta_loader_early.sh
  printf "%b❌ Please make sure you are calling the script without leading 'sh'! Bye... %b%b" "${RED}" "${RES}" "${NL}" >&2
  exit "${ERR_UNSUPPORTED_BASH}"
}

### Not sourced.
[[ "${BASH_SOURCE[0]}" != "$0" ]] && {
  . ./meta_loader_early.sh
  printf "%b❌ This script must be executed, not sourced. Please run './setup.sh' directly. %b%b" "${RED}" "${RES}" "${NL}" >&2
  exit "${ERR_UNSUPPORTED_BASH}"
}

### Minimum Bash version 5.
[[ ${BASH_VERSINFO[0]} -lt 5 ]] && {
  . ./meta_loader_early.sh
  printf "%b❌ Minimum requirement is bash 5.1. You are using '%s'! Bye... %b%b" "${RED}" "${BASH_VERSION}" "${RES}" "${NL}" >&2
  exit "${ERR_UNSUPPORTED_BASH}"
}

### Minimum Bash version 5.1.
[[ ${BASH_VERSINFO[0]} -le 5 ]] && [[ ${BASH_VERSINFO[1]} -le 1 ]] && {
  . ./meta_loader_early.sh
  printf "%b❌ Minimum requirement is bash 5.1. You are using '%s'! Bye... %b%b" "${RED}" "${BASH_VERSION}" "${RES}" "${NL}" >&2
  exit "${ERR_UNSUPPORTED_BASH}"
}

### No arguments.
[[ ${#} -eq 0 ]] && {
  . ./meta_loader_early.sh
  usage >&2
  exit 1
}

### CHECK FOR CONTACT, HELP, AND VERSION STRING.
for arg in "$@"; do case "${arg,,}" in -c|--contact) . ./meta_loader_cuv.sh; contact; exit 0;; esac; done
for arg in "$@"; do case "${arg,,}" in -h|--help)    . ./meta_loader_cuv.sh; usage  ; exit 0;; esac; done
for arg in "$@"; do case "${arg,,}" in -v|--version) . ./meta_loader_cuv.sh; version; exit 0;; esac; done

### SOURCING MUST SET EARLY VARIABLES. SOURCING COLOR_ECHO() AND GUARD_SOURCING().
. ./lib/cdi_0005_guard/0005_guard_sourcing.sh # The function guard_sourcing MUST be present in each file to source.
. ./lib/cdi_0005_guard/0006_source_guard.sh   # Wrapper for sourcing modules, libraries, variables.
source_guard "./var/color.var.sh"
source_guard "./var/early.var.sh"
source_guard "./lib/cdi_0010_basic/0010_color_echo.sh"
clear

### ALL CHECKS DONE. READY TO START THE SCRIPT.
# shellcheck disable=SC2155
declare -grx VAR_DIALOG=$(mktemp var_dialog.XXXXXXXX)
color_echo "${GRE}" "CISS.DEBIAN.INSTALLER PREPARATION: ALL CHECKS DONE. READY TO START THE SCRIPT ..."
declare -grx VAR_SETUP="true"
umask 0022

### SOURCING FUNCTIONS, LIBRARIES, VARIABLES.
if [[ "${VAR_SETUP}" == "true" ]]; then
  ### SOURCING VARIABLES
  color_echo "${GRE}" "CISS.DEBIAN.INSTALLER PREPARATION: SOURCING VARIABLES ..."
  . ./meta_loader_var.sh
  ### SOURCING FUNCTIONS
  color_echo "${GRE}" "CISS.DEBIAN.INSTALLER PREPARATION: SOURCING FUNCTIONS ..."
  . ./meta_loader_func.sh
  ### SOURCING LIBRARIES
  color_echo "${GRE}" "CISS.DEBIAN.INSTALLER PREPARATION: SOURCING LIBRARIES ..."
  . ./meta_loader_lib.sh
fi

### PREPARING DIRECTORIES AND FILES.
color_echo "${GRE}" "CISS.DEBIAN.INSTALLER PREPARATION: PREPARING DIRECTORIES AND FILES ..."
gen_dir_files

### CHECKING REQUIRED PACKAGES.
color_echo "${GRE}" "CISS.DEBIAN.INSTALLER PREPARATION: CHECKING REQUIRED PACKAGES ..."
check_pkgs
color_echo "${GRE}" "CISS.DEBIAN.INSTALLER PREPARATION: CHECKING GIT VARIABLES ..."
check_git

### ADVISORY LOCK.
color_echo "${GRE}" "CISS.DEBIAN.INSTALLER PREPARATION: ADVISORY LOCK ..."
exec 127>/var/lock/ciss_debian_installer.lock || {
  printf "%b❌ Cannot open lockfile for writing! Bye... %b%b" "${RED}" "${RES}" "${NL}" >&2
  exit "${ERR_FLOCK_PROTECTED}"
}

if ! flock -x -n 127; then
  printf "%b❌ Another instance is running! Bye...%b%b" "${RED}" "${RES}" "${NL}" >&2
  exit "${ERR_FLOCK_COLLISION}"
fi

### SCAN FOR DEBUG MODE.
color_echo "${GRE}" "CISS.DEBIAN.INSTALLER PREPARATION: SCAN FOR DEBUG MODE ..."
pre_scan_debug "$@"

### CHECK FOR AUTO INSTALL MODE.
color_echo "${GRE}" "CISS.DEBIAN.INSTALLER PREPARATION: CHECK FOR AUTO INSTALL MODE ..."
for arg in "$@"; do case "${arg,,}" in -a|--autoinstall) declare -gx VAR_AUTO_INSTALL="true";; esac; done; unset arg

### ACTIVATING TRAPS.
color_echo "${GRE}" "CISS.DEBIAN.INSTALLER PREPARATION: ACTIVATING TRAPS ..."
trap 'trap_exit "$?" "${BASH_SOURCE[0]}" "${LINENO}" "${FUNCNAME[0]:-main}" "${BASH_COMMAND}"' EXIT
trap 'trap_err  "$?" "${BASH_SOURCE[0]}" "${LINENO}" "${FUNCNAME[0]:-main}" "${BASH_COMMAND}"' ERR
trap 'trap_int' INT TERM

### INTERACTIVE MODE NOTES AND KERNEL SELECTION.
if ! "${VAR_AUTO_INSTALL}"; then dialog_kernel; fi
if ! "${VAR_AUTO_INSTALL}"; then dialog_notes; fi

### Dialog Output for Initialization START.
color_echo "${GRE}" "CISS.DEBIAN.INSTALLER PREPARATION: CHECK DIALOG WRAPPER ..."
if ! "${VAR_AUTO_INSTALL}"; then . ./lib/cdi_0200_dialog/0200_dialog_helper.sh && dialog_box; fi

### ARGUMENT CHECKS.
echo "MAIN PROGRAM SEQUENCE: 0101_arg_sanitizer.sh ..."
arg_check "$@"
declare -ar ARY_ARG_SANITIZED=("$@")
declare -grx VAR_ARG_SANITIZED="${ARY_ARG_SANITIZED[*]}"

### ARGUMENT PARSING.
echo "MAIN PROGRAM SEQUENCE: 0102_arg_parser.sh ..."
arg_parser "$@"

### PRIORITY UPDATES.
echo "MAIN PROGRAM SEQUENCE: 0103_arg_priority_check.sh ..."
arg_priority_check

### HASHING PASSWORDS.
echo "MAIN PROGRAM SEQUENCE: 0105_arg_nuke_converter.sh ..."
nuke_passphrase

### CDI_1200

### CDI_1250
echo "MAIN PROGRAM SEQUENCE: 1250_yaml_parser.sh ..."
yaml_parser
echo "MAIN PROGRAM SEQUENCE: 1251_yaml_reader.sh ..."
yaml_reader
echo "MAIN PROGRAM SEQUENCE: 1252_yaml_validator.sh ..."
yaml_validator

### CDI_3200
echo "MAIN PROGRAM SEQUENCE: 3200_partitioning.sh ..."
partitioning
echo "MAIN PROGRAM SEQUENCE: 3210_benchmarking_encryption.sh ..."
benchmarking_encryption
echo "MAIN PROGRAM SEQUENCE: 3220_partition_encryption.sh ..."
partition_encryption
echo "MAIN PROGRAM SEQUENCE: 3240_partition_formatting.sh ..."
partition_formatting
echo "MAIN PROGRAM SEQUENCE: 3280_mount_partition.sh ..."
mount_partition
echo "MAIN PROGRAM SEQUENCE: 3290_uuid_logger.sh ..."
uuid_logger

### CDI_4000
echo "MAIN PROGRAM SEQUENCE: 4000_debootstrap.sh ..."
func_debootstrap
echo "MAIN PROGRAM SEQUENCE: 4010_prepare_mounts.sh ..."
prepare_mounts
echo "MAIN PROGRAM SEQUENCE: 4020_remove_x509.sh ..."
remove_x509
echo "MAIN PROGRAM SEQUENCE: 4030_setup_hostname.sh ..."
setup_hostname
echo "MAIN PROGRAM SEQUENCE: 4035_setup_resolv.sh ..."
setup_resolv
echo "MAIN PROGRAM SEQUENCE: 4040_setup_timezone.sh ..."
setup_timezone
echo "MAIN PROGRAM SEQUENCE: 4050_setup_locales.sh ..."
setup_locales

### CDI_4100
echo "MAIN PROGRAM SEQUENCE: 4100_generate_sources.sh ..."
generate_sources
echo "MAIN PROGRAM SEQUENCE: 4110_update_sources.sh ..."
update_sources
echo "MAIN PROGRAM SEQUENCE: 4120_installation_kernel.sh ..."
installation_kernel
echo "MAIN PROGRAM SEQUENCE: 4130_installation_toolset.sh ..."
installation_toolset
echo "MAIN PROGRAM SEQUENCE: 4131_installation_systemd.sh ..."
installation_systemd
echo "MAIN PROGRAM SEQUENCE: 4132_installation_machineid.sh ..."
installation_machineid
echo "MAIN PROGRAM SEQUENCE: 4133_installation_masking.sh ..."
installation_masking
echo "MAIN PROGRAM SEQUENCE: 4140_installation_microcode.sh ..."
installation_microcode
echo "MAIN PROGRAM SEQUENCE: 4150_installation_chrony.sh ..."
installation_chrony

### CDI_4200
echo "MAIN PROGRAM SEQUENCE: 4200_generate_fstab.sh ..."
generate_fstab
echo "MAIN PROGRAM SEQUENCE: 4210_generate_crypttab.sh ..."
generate_crypttab
echo "MAIN PROGRAM SEQUENCE: 4220_installation_cryptsetup.sh ..."
installation_cryptsetup
echo "MAIN PROGRAM SEQUENCE: 4230_installation_grub.sh ..."
installation_grub
echo "MAIN PROGRAM SEQUENCE: 4240_update_grub_password.sh ..."
update_grub_password
echo "MAIN PROGRAM SEQUENCE: 4250_update_grub_bootparameter.sh ..."
update_grub_bootparameter

### CDI_4300
echo "MAIN PROGRAM SEQUENCE: 4300_installation_network.sh ..."
installation_network
echo "MAIN PROGRAM SEQUENCE: 4310_dropbear_build.sh ..."
dropbear_build
echo "MAIN PROGRAM SEQUENCE: 4311_dropbear_initramfs.sh ..."
dropbear_initramfs
echo "MAIN PROGRAM SEQUENCE: 4312_dropbear_setup.sh ..."
dropbear_setup
echo "MAIN PROGRAM SEQUENCE: 4320_update_initramfs.sh ..."
update_initramfs

### CDI_4400
echo "MAIN PROGRAM SEQUENCE: 4400_kernel_modules.sh ..."
kernel_modules && kernel_modprobe
echo "MAIN PROGRAM SEQUENCE: 4410_kernel_sysctl.sh ..."
kernel_sysctl
echo "MAIN PROGRAM SEQUENCE: 4420_installation_ssh.sh ..."
installation_ssh
echo "MAIN PROGRAM SEQUENCE: 4430_installation_skel.sh ..."
installation_skel
echo "MAIN PROGRAM SEQUENCE: 4440_hardening_files.sh ..."
hardening_files

### CDI_4500
echo "MAIN PROGRAM SEQUENCE: 4500_installation_accounts.sh ..."
installation_accounts

### CDI_4600
#echo "MAIN PROGRAM SEQUENCE: 4600_minimal_checks.sh ..."

#echo "MAIN PROGRAM SEQUENCE: 4610_finalize_system.sh ..."

#echo "MAIN PROGRAM SEQUENCE: 4670_verify_system.sh ..."

#echo "MAIN PROGRAM SEQUENCE: 4680_check_sshd_config_integrity.sh ..."

#echo "MAIN PROGRAM SEQUENCE: 4690_check_grub_cmdline.sh ..."

### CDI_4700
echo "MAIN PROGRAM SEQUENCE: 4799_exiting_chroot_system.sh ..."
exiting_chroot_system

### CDI_5000
if [[ "${VAR_RECOVERY}" == "true" ]]; then
  wrapper_recovery
fi

### Dialog Output for Initialization END
if ! "${VAR_AUTO_INSTALL}"; then . ./lib/cdi_0200_dialog/0200_dialog_helper.sh && dialog_box_cleaner; fi

declare -gx VAR_SCRIPT_SUCCESS="true"

exit 0
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh
