Files
CISS.debian.live.builder/config/includes.chroot/preseed/.iso/preseed_hash_generator.sh
2025-06-03 00:24:36 +02:00

239 lines
9.7 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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: 20242025; 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.live.builder
# SPDX-Security-Contact: security@coresecret.eu
declare -gr VERSION="Master V8.03.384.2025.06.03"
### 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