Files
CISS.debian.live.builder/config/includes.chroot/preseed/.iso/preseed_hash_generator.sh
Marc S. Weidner 2e50dd9535
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
V8.13.768.2025.12.06
Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
2025-12-06 03:52:15 +01:00

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