Some checks failed
🛡️ Retrieve DNSSEC status of coresecret.dev. / 🛡️ Retrieve DNSSEC status of coresecret.dev. (push) Successful in 1m13s
🛡️ Shell Script Linting / 🛡️ Shell Script Linting (push) Successful in 56s
🔐 Generating a Private Live ISO TRIXIE. / 🔐 Generating a Private Live ISO TRIXIE. (push) Successful in 51m3s
💙 Generating a PUBLIC Live ISO. / 💙 Generating a PUBLIC Live ISO. (push) Failing after 1m33s
Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
239 lines
9.7 KiB
Bash
239 lines
9.7 KiB
Bash
#!/bin/bash
|
|
# SPDX-Version: 3.0
|
|
# SPDX-CreationInfo: 2025-05-05; WEIDNER, Marc S.; <msw@coresecret.dev>
|
|
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.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: LicenseRef-CNCL-1.1 OR LicenseRef-CCLA-1.1
|
|
# SPDX-LicenseComment: This file is part of the CISS.debian.installer.secure framework.
|
|
# SPDX-PackageName: CISS.debian.live.builder
|
|
# SPDX-Security-Contact: security@coresecret.eu
|
|
|
|
declare -gr VERSION="Master V8.13.768.2025.12.06"
|
|
|
|
### VERY EARLY CHECK FOR DEBUGGING
|
|
if [[ $* == *" --debug "* ]]; then
|
|
declare -gr EARLY_DEBUG=true
|
|
# Set a verbose PS4 prompt including timestamp, source, line, exit status and function name
|
|
declare -gr PS4='\e[97m+\e[0m\e[96m$(date +%T.%4N)\e[0m\e[97m:\e[0m\e[92m[${BASH_SOURCE[0]}:${LINENO}]\e[0m\e[97m|\e[0m\e[93m$?\e[0m\e[97m>\e[0m\e[95m${FUNCNAME[0]:-main}()\e[0m \e[97m>>\e[0m '
|
|
# shellcheck disable=SC2155
|
|
declare -gr DEBUG_LOG="/tmp/ciss_live_builder_$$.log"
|
|
# Generates empty DEBUG_LOG
|
|
touch "${DEBUG_LOG}" && chmod 0600 "${DEBUG_LOG}"
|
|
# Open file descriptor 42 for writing to the debug log
|
|
exec 42>| "${DEBUG_LOG}"
|
|
# Write Debug Log Header https://www.gnu.org/software/bash/manual/html_node/Bash-Variables
|
|
{
|
|
printf "\e[97m+\e[0m\e[92m%s: CISS.debian.live.builder Debug Log \e[0m\n" "$(date +%T.%4N)"
|
|
printf "\e[97m+\e[0m\e[92m%s: Version : %s \e[0m\n" "$(date +%T.%4N)" "${VERSION}"
|
|
printf "\e[97m+\e[0m\e[92m%s: Epoch : %s \e[0m\n" "$(date +%T.%4N)" "${EPOCHREALTIME}"
|
|
printf "\e[97m+\e[0m\e[92m%s: Bash MAJ Release : %s \e[0m\n" "$(date +%T.%4N)" "${BASH_VERSINFO[0]}"
|
|
printf "\e[97m+\e[0m\e[92m%s: Bash MIN Version : %s \e[0m\n" "$(date +%T.%4N)" "${BASH_VERSINFO[1]}"
|
|
printf "\e[97m+\e[0m\e[92m%s: Bash Patch Level : %s \e[0m\n" "$(date +%T.%4N)" "${BASH_VERSINFO[2]}"
|
|
printf "\e[97m+\e[0m\e[92m%s: Bash Build Version : %s \e[0m\n" "$(date +%T.%4N)" "${BASH_VERSINFO[3]}"
|
|
printf "\e[97m+\e[0m\e[92m%s: Bash Release : %s \e[0m\n" "$(date +%T.%4N)" "${BASH_VERSINFO[4]}"
|
|
printf "\e[97m+\e[0m\e[92m%s: UID : %s \e[0m\n" "$(date +%T.%4N)" "${UID}"
|
|
printf "\e[97m+\e[0m\e[92m%s: EUID : %s \e[0m\n" "$(date +%T.%4N)" "${EUID}"
|
|
printf "\e[97m+\e[0m\e[92m%s: Hostname : %s \e[0m\n" "$(date +%T.%4N)" "${HOSTNAME}"
|
|
printf "\e[97m+\e[0m\e[92m%s: Script name : %s \e[0m\n" "$(date +%T.%4N)" "$0"
|
|
printf "\e[97m+\e[0m\e[92m%s: Argument counter : %s \e[0m\n" "$(date +%T.%4N)" "$#"
|
|
printf "\e[97m+\e[0m\e[92m%s: Argument string : %s \e[0m\n" "$(date +%T.%4N)" "$*"
|
|
printf "\e[97m+\e[0m\e[92m%s: Script PID : %s \e[0m\n" "$(date +%T.%4N)" "$$"
|
|
printf "\e[97m+\e[0m\e[92m%s: Script Parent PID : %s \e[0m\n" "$(date +%T.%4N)" "${PPID}"
|
|
printf "\e[97m+\e[0m\e[92m%s: Script work DIR : %s \e[0m\n" "$(date +%T.%4N)" "${PWD}"
|
|
printf "\e[97m+\e[0m\e[92m%s: Shell Options : %s \e[0m\n" "$(date +%T.%4N)" "$-"
|
|
printf "\e[97m+\e[0m\e[92m%s: BASHOPTS : %s \e[0m\n" "$(date +%T.%4N)" "${BASHOPTS}"
|
|
printf "\e[97m+\e[0m\e[92m%s: === Debug Log === : \e[0m\n" "$(date +%T.%4N)"
|
|
} >&42
|
|
# Tell Bash to send xtrace output to FD 42
|
|
export BASH_XTRACEFD=42
|
|
# Enable inheritable shell options
|
|
export SHELLOPTS
|
|
# Turn on xtrace
|
|
set -x
|
|
else
|
|
declare -gr EARLY_DEBUG=false
|
|
fi
|
|
|
|
### Definition of error codes
|
|
declare -gir ERR_NOT_USER_0=128
|
|
declare -gir ERR_UNSPPTBASH=255
|
|
|
|
### Definition of error trap vars
|
|
# declare -g errcode="" # = $? = $1 = ERRCODE
|
|
# declare -g errscrt="" # = ${BASH_SOURCE[0]} = $2 = ERRSCRT
|
|
# declare -g errline="" # = ${LINENO} = $3 = ERRLINE
|
|
# declare -g errfunc="" # = ${FUNCNAME[0]:-main} = $4 = ERRFUNC
|
|
# declare -g errcmmd="" # = ${$BASH_COMMAND} = $5 = ERRCMMD
|
|
|
|
### Preliminary vars declaration
|
|
declare -gr argument_count="$#"
|
|
declare -gr argument_string="$*"
|
|
|
|
### Preliminary checks
|
|
[[ ${EUID} -ne 0 ]] \
|
|
&& printf "\e[91m❌ Please make sure you are 'root'! Bye... \e[0m\n" >&2 && exit "${ERR_NOT_USER_0}"
|
|
[[ -z ${BASH_VERSINFO[0]} ]] \
|
|
&& printf "\e[91m❌ Please make sure you are using 'bash'! Bye... \e[0m\n" >&2 && exit "${ERR_UNSPPTBASH}"
|
|
[[ $(kill -l | grep -c SIG) -eq 0 ]] \
|
|
&& printf "\e[91m❌ Please make sure you are calling the script without leading 'sh'! Bye... \e[0m\n" >&2 && exit "${ERR_UNSPPTBASH}"
|
|
[[ ${BASH_VERSINFO[0]} -lt 5 ]] \
|
|
&& printf "\e[91m❌ Minimum requirement is bash 5.1. You are using '%s'! Bye... \e[0m\n" "${BASH_VERSION}" >&2 && exit "${ERR_UNSPPTBASH}"
|
|
[[ ${BASH_VERSINFO[0]} -le 5 ]] && [[ ${BASH_VERSINFO[1]} -le 1 ]] \
|
|
&& printf "\e[91m❌ Minimum requirement is bash 5.1. You are using '%s'! Bye... \e[0m\n" "${BASH_VERSION}" >&2 && exit "${ERR_UNSPPTBASH}"
|
|
|
|
### For all options see https://www.gnu.org/software/bash/manual/bash.html#The-Set-Builtin
|
|
set -o errexit # Exit script when a command exits with non-zero status, the same as "set -e".
|
|
set -o nounset # Exit script on use of an undefined variable, the same as "set -u".
|
|
set -o pipefail # Makes pipelines return the exit status of the last command in the pipe that failed.
|
|
set -o noclobber # Prevent overwriting, the same as "set -C".
|
|
|
|
#######################################
|
|
# Trap function to be called on 'ERR'.
|
|
# Globals:
|
|
# DEBUG_LOG
|
|
# EARLY_DEBUG
|
|
# VERSION
|
|
# argument_count
|
|
# argument_string
|
|
# Arguments:
|
|
# $1: $?
|
|
# $2: ${BASH_SOURCE[0]}
|
|
# $3: ${LINENO}
|
|
# $4: ${FUNCNAME[0]:-main}
|
|
# $5: ${BASH_COMMAND}
|
|
#######################################
|
|
# shellcheck disable=SC2317
|
|
trap_on_err() {
|
|
declare -r errcode="$1"
|
|
declare -r errscrt="$2"
|
|
declare -r errline="$3"
|
|
declare -r errfunc="$4"
|
|
declare -r errcmmd="$5"
|
|
trap - ERR
|
|
if [[ "${errcode}" -ne 127 ]]; then
|
|
printf "\e[91m❌ Hash Generation Process failed.\e[0m\n" >&2
|
|
printf "\e[91m❌ Version : '%s' \e[0m\n" "${VERSION}" >&2
|
|
printf "\e[91m❌ Error : '%s' \e[0m\n" "${errcode}" >&2
|
|
printf "\e[91m❌ Line : '%s' \e[0m\n" "${errline}" >&2
|
|
printf "\e[91m❌ Script : '%s' \e[0m\n" "${errscrt}" >&2
|
|
printf "\e[91m❌ Function : '%s' \e[0m\n" "${errfunc}" >&2
|
|
printf "\e[91m❌ Command : '%s' \e[0m\n" "${errcmmd}" >&2
|
|
printf "\e[91m❌ Arguments # : '%s' \e[0m\n" "${argument_count}" >&2
|
|
printf "\e[91m❌ Arguments : '%s' \e[0m\n" "${argument_string}" >&2
|
|
if "${EARLY_DEBUG}"; then
|
|
printf "\e[91m❌ Debug Log : '%s' \e[0m\n" "${DEBUG_LOG}" >&2
|
|
printf "\e[91m❌ cat %s \e[0m\n" "${DEBUG_LOG}" >&2
|
|
fi
|
|
printf "\n"
|
|
fi
|
|
}
|
|
|
|
trap 'trap_on_err "$?" "${BASH_SOURCE[0]}" "${LINENO}" "${FUNCNAME[0]:-main}" "${BASH_COMMAND}"' ERR
|
|
|
|
### Initialization
|
|
# shellcheck disable=SC2155
|
|
declare -gr SCRIPT_FULLPATH="$(readlink -f "${BASH_SOURCE[0]:-$0}")"
|
|
# shellcheck disable=SC2155
|
|
declare -gr WORK_DIR="$(dirname "${SCRIPT_FULLPATH}")"
|
|
declare -gr BASE_DIR="${WORK_DIR%/.iso}"
|
|
declare -gr CFG_DIR="${BASE_DIR}/.cfg"
|
|
declare -gr PRES_FILE="${BASE_DIR}/preseed.cfg"
|
|
declare -gr HASH_FILE="${CFG_DIR}/md5sum.txt"
|
|
declare -ga hashes=()
|
|
|
|
# shellcheck disable=SC2188
|
|
>| "${HASH_FILE}"
|
|
|
|
#######################################
|
|
# Generator for md5 Hashes
|
|
# Globals:
|
|
# CFG_DIR
|
|
# HASH_FILE
|
|
# hash
|
|
# hashes
|
|
# Arguments:
|
|
# None
|
|
#######################################
|
|
gen_hash() {
|
|
# Enable nullglob so that non-matching patterns expand to nothing
|
|
shopt -s nullglob
|
|
declare file
|
|
declare filename
|
|
# Loop over all *.cfg files in CFG_DIR
|
|
for file in "${CFG_DIR}"/*.cfg; do
|
|
# Only process if it's a regular file
|
|
if [[ -f "${file}" ]]; then
|
|
# Calculate md5 hash (only the hash value)
|
|
hash=$(md5sum "${file}" | awk '{ print $1 }')
|
|
# Extract the filename without a path
|
|
filename=${file##*/}
|
|
# Append "hash filename" to HASH_FILE
|
|
echo "${hash} ${filename}" >> "${HASH_FILE}"
|
|
# Add hash to array
|
|
hashes+=("${hash}")
|
|
fi
|
|
done
|
|
}
|
|
|
|
gen_hash
|
|
|
|
{
|
|
declare in_hash_block=false
|
|
declare outer_line
|
|
declare hash
|
|
while IFS= read -r outer_line; do
|
|
# Check if a line contains "#BOH" and start the hash insertion block
|
|
if [[ ${outer_line} == "#BOH" ]]; then
|
|
echo "${outer_line}"
|
|
# shellcheck disable=SC1003
|
|
echo 'd-i preseed/include/checksum string \'
|
|
|
|
# Add all new hashes from the array "hashes" except the last one
|
|
for ((i = 0; i < ${#hashes[@]} - 1; i++)); do
|
|
hash="${hashes[i]}"
|
|
echo "${hash} \\"
|
|
done
|
|
|
|
# Output the last hash without the trailing backslash.
|
|
echo "${hashes[@]: -1}"
|
|
|
|
# Set the flag for the hash block to "true".
|
|
in_hash_block=true
|
|
continue
|
|
fi
|
|
|
|
# Check if the line "#EOH" has been reached to end the hash block.
|
|
if [[ ${outer_line} == "#EOH" && ${in_hash_block} == true ]]; then
|
|
echo "${outer_line}"
|
|
in_hash_block=false
|
|
continue
|
|
fi
|
|
|
|
# Skip lines within the hash block (old hashes and d-i line).
|
|
if [[ ${in_hash_block} == true ]]; then
|
|
# Skip the line "d-i preseed/include/checksum string".
|
|
if [[ ${outer_line} =~ ^d-i\ preseed/include/checksum\ string ]]; then
|
|
continue
|
|
fi
|
|
# Skip lines with old hashes.
|
|
if [[ ${outer_line} =~ [a-f0-9]{32} ]]; then
|
|
continue
|
|
fi
|
|
fi
|
|
|
|
# Leave all other rows unchanged.
|
|
echo "${outer_line}"
|
|
|
|
done < "${PRES_FILE}"
|
|
} >| "${PRES_FILE}.tmp"
|
|
|
|
mv -f "${PRES_FILE}.tmp" "${PRES_FILE}"
|
|
sed -i ':a;N;/\n#EOH/!ba;s/\(\n\)\+\(#EOH\)/\n#EOH/' "${PRES_FILE}"
|
|
sed -i '$d' "$PRES_FILE"
|
|
echo "# Written by: $0 Version: ${VERSION} at: $(date +%T.%4N)" >> "${PRES_FILE}"
|
|
printf "\e[92m✅ '%s' Process successful.\e[0m\n" "${0}"
|
|
exit 0
|
|
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh
|