V8.00.000.2025.06.17

Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
This commit is contained in:
2025-07-23 08:50:22 +02:00
parent 328e346c95
commit 080e04efa3
52 changed files with 35 additions and 37 deletions

View File

@@ -0,0 +1,43 @@
#!/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
guard_sourcing
#######################################
# Specify the network interface card (NIC) interactively for setup.
# Globals:
# DIR_TMP
# Arguments:
# None
# Returns:
# 0: on success
#######################################
check_nic() {
ip -o link show | awk -F': ' '{print $2}' | sed 's!lo!!' | sed '/^$/d' | awk '{$1=$1};1' >| "${DIR_TMP}nic.tmp"
declare var_counter=1
declare var_line=""
declare var_nic=""
declare var_radiolist=""
while IFS= read -r var_line; do
var_radiolist="${var_radiolist} ${var_line} ${var_counter} on "
((var_counter++))
done < "${DIR_TMP}nic.tmp"
# shellcheck disable=SC2086 disable=SC2248
var_nic=$(dialog --ascii-lines --clear --backtitle "Specify the NIC for setup" --radiolist "NIC available" 0 0 ${var_counter} ${var_radiolist} 3>&1 1>&2 2>&3)
clear
do_log "info" "true" "You have selected: '${var_nic}' - proceeding with setup."
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,111 @@
#!/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
guard_sourcing
#######################################
# Use do_in_target() for:
# simple commands (e.g., dpkg, ln, mkdir, apt, etc.)
# Use do_in_target_script() for:
# all shell scripts, redirects, pipes, conditions, loops, or subshells
#######################################
#######################################
# Wrapper for executing commands in the desired chroot environment.
# Globals:
# ERR_CHRT_COMMAND
# TERM
# Arguments:
# 1: Target of the chroot environment.
# 2: Commands and options and parameters to be executed in chroot.
# Returns:
# 0: on success
# ERR_CHRT_COMMAND: on failure
#######################################
do_in_target() {
declare var_chroot_target="$1"
shift
declare -a ary_chroot_command=("$@")
if (( ${#ary_chroot_command[@]} == 0 )); then
do_log "emergency" "true" "Empty command passed to 'do_in_target()'."
return "${ERR_CHRT_COMMAND}"
fi
if chroot "${var_chroot_target}" /usr/bin/env -i \
HOME=/root \
PATH=/usr/sbin:/usr/bin:/sbin:/bin \
TERM="${TERM}" \
"${ary_chroot_command[@]}"
then
do_log "info" "true" "Success: chroot '${var_chroot_target}': '${ary_chroot_command[*]}'."
return 0
else
do_log "emergency" "true" "Failed: chroot '${var_chroot_target}': '${ary_chroot_command[*]}'."
return "${ERR_CHRT_COMMAND}"
fi
}
#######################################
# Execute a full shell script line inside the chroot via bash -c.
# Supports interactive debug shell on error.
# Globals:
# ERR_CHRT_COMMAND
# TERM
# DEBUG_INTERACTIVE (optional boolean)
# Arguments:
# 1: Target of the chroot environment
# 2: Command string to execute inside a shell (quoted)
# Returns:
# 0: on success
# ERR_CHRT_COMMAND: on failure
#######################################
do_in_target_script() {
declare var_chroot_target="$1"
shift
declare var_chroot_script="$1"
if [[ -z "${var_chroot_script}" ]]; then
do_log "emergency" "true" "Empty command passed to 'do_in_target_script()'."
return "${ERR_CHRT_COMMAND}"
fi
do_log "debug" "true" "Evaluating chroot script in '${var_chroot_target}': '${var_chroot_script}'."
if chroot "${var_chroot_target}" /usr/bin/env -i \
HOME=/root \
PATH=/usr/sbin:/usr/bin:/sbin:/bin \
TERM="${TERM}" \
/bin/bash -c "${var_chroot_script}"
then
do_log "info" "true" "Success: chroot '${var_chroot_target}': '${var_chroot_script}'."
return 0
else
declare -i var_chroot_rc="${?}"
do_log "emergency" "true" "Failure: chroot '${var_chroot_target}': '${var_chroot_script}'."
do_log "debug" "true" "Return code: '${var_chroot_rc}'."
# TODO: Test with Dialog Wrapper in interactive mode.
#if [[ "${DEBUG_INTERACTIVE}" == "true" ]]; then
# do_log "warning" "true" "Launching interactive debug shell in chroot: '${var_chroot_target}'."
# chroot "${var_chroot_target}" /bin/bash -l
#fi
return "${ERR_CHRT_COMMAND}"
fi
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,58 @@
#!/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
### Options in "GRUB_CMDLINE_LINUX" are always effective.
### Options in "GRUB_CMDLINE_LINUX_DEFAULT" are effective ONLY during normal boot (NOT during recovery mode).
guard_sourcing
#######################################
# Helper module to extract the current GRUB CMDLINE strings.
# Globals:
# TARGET
# VAR_GRUB_CMDLINE_LINUX
# VAR_GRUB_CMDLINE_LINUX_DEFAULT
# VAR_ORIG_GRUB_CMDLINE_LINUX
# VAR_ORIG_GRUB_CMDLINE_LINUX_DEFAULT
# Arguments:
# None
#######################################
grub_extract_current_string() {
# shellcheck disable=SC2155
declare -gx VAR_ORIG_GRUB_CMDLINE_LINUX=$(grep -E 'GRUB_CMDLINE_LINUX=' "${TARGET}/etc/default/grub")
# shellcheck disable=SC2155
declare -gx VAR_ORIG_GRUB_CMDLINE_LINUX_DEFAULT=$(grep -E 'GRUB_CMDLINE_LINUX_DEFAULT=' "${TARGET}/etc/default/grub")
# shellcheck disable=SC2155
declare -gx VAR_GRUB_CMDLINE_LINUX=$(grep -E 'GRUB_CMDLINE_LINUX=' "${TARGET}/etc/default/grub" | sed 's/.$//')
# shellcheck disable=SC2155
declare -gx VAR_GRUB_CMDLINE_LINUX_DEFAULT=$(grep -E 'GRUB_CMDLINE_LINUX_DEFAULT=' "${TARGET}/etc/default/grub" | sed 's/.$//')
}
#######################################
# Helper module to finish the modified GRUB CMDLINE strings.
# Globals:
# TARGET
# VAR_GRUB_CMDLINE_LINUX
# VAR_GRUB_CMDLINE_LINUX_DEFAULT
# VAR_H
# VAR_ORIG_GRUB_CMDLINE_LINUX
# VAR_ORIG_GRUB_CMDLINE_LINUX_DEFAULT
# Arguments:
# None
#######################################
grub_finalize_string() {
VAR_GRUB_CMDLINE_LINUX="${VAR_GRUB_CMDLINE_LINUX}${VAR_H}"
VAR_GRUB_CMDLINE_LINUX_DEFAULT="${VAR_GRUB_CMDLINE_LINUX_DEFAULT}${VAR_H}"
sed -i "s/${VAR_ORIG_GRUB_CMDLINE_LINUX}/${VAR_GRUB_CMDLINE_LINUX}/" "${TARGET}/etc/default/grub"
sed -i "s/${VAR_ORIG_GRUB_CMDLINE_LINUX_DEFAULT}/${VAR_GRUB_CMDLINE_LINUX_DEFAULT}/" "${TARGET}/etc/default/grub"
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,49 @@
#!/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
guard_sourcing
#######################################
# Helper Module to generate a Subnet Mask out of an IP in CCDIR Notation.
# Arguments:
# 1: IPv4 in CCDIR Notation, e.g.,: 192.168.128.128/24
# Returns:
# 0: on success
#######################################
generate_subnetmask() {
declare var_arg="$1"
declare var_prefix="${var_arg#*/}"
declare var_mask_int=""
declare var_has_ipv4_subnet=""
var_mask_int=$((0xFFFFFFFF << (32 - var_prefix) & 0xFFFFFFFF))
var_has_ipv4_subnet=$(printf "%d.%d.%d.%d" \
$(((var_mask_int >> 24) & 0xFF)) \
$(((var_mask_int >> 16) & 0xFF)) \
$(((var_mask_int >> 8) & 0xFF)) \
$((var_mask_int & 0xFF)))
printf '%s' "${var_has_ipv4_subnet}"
return 0
}
#######################################
# Helper module for update, full dist-upgrade, autoclean, autopurge and autoremove.
# Arguments:
# None
#######################################
update_upgrade() {
apt-get update -y
apt-get dist-upgrade -y
apt-get autoclean -y
apt-get autopurge -y
apt-get autoremove -y
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,50 @@
#!/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
guard_sourcing
#######################################
# Wrapper around 'printf' for clean code.
# Globals:
# RES
# Arguments:
# 1: One of "${BLA}" | "${RED}" | "${GRE}" | "${YEL}" | "${BLU}" | "${MAG}" | "${CYA}" | "${WHI}"
# 2: Text string to print on terminal.
#######################################
do_print_color() {
printf "%s\n" "${1}${2}${RES}"
}
#######################################
# Wrapper around 'printf' for clean, uniform terminal output and line fold for long text strings for better readability.
# Globals:
# RES
# Arguments:
# 1: One of "${BLA}" | "${RED}" | "${GRE}" | "${YEL}" | "${BLU}" | "${MAG}" | "${CYA}" | "${WHI}"
# 2: Text string to print on terminal.
#######################################
do_print_fold() {
declare var_color="$1"; shift
declare var_msg_string="$*"
declare var_formatted_string="${var_color}${var_msg_string}${RES}"
printf "%b\n" "${var_formatted_string}" | fold -s -w 76 | sed '1! s/^/ /'
}
#######################################
# Wrapper around 'printf' for logfile redirect.
# Arguments:
# 1: Text string to redirect to a log file.
#######################################
do_print_log() {
printf "%s\n" "${1}"
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,49 @@
#!/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
guard_sourcing
#######################################
# Remove any leading or trailing whitespace.
# Arguments:
# 1: String to clean.
#######################################
remove_whitespace() {
# shellcheck disable=SC2155
declare var_out=$(printf "%s" "$1" | xargs)
printf '%s' "${var_out}"
}
#######################################
# Function to escape all shell metacharacters
# Arguments:
# 1: String to Sanitize
#######################################
sanitize_input() {
declare input="$1"
### %q quotes the string so that the shell re-reads it as the original literal
printf '%q' "${input}"
}
#######################################
# Function to remove any character not in the allowed set
# Arguments:
# 1: String to Sanitize
#######################################
sanitize_string() {
declare input="$1"
### Define allowed characters:
### letters, digits, dot, underscore, slash, equals, [, ], colon, double-quote, hyphen, space.
declare allowed='a-zA-Z0-9._/=\[\]:"\-+ '
printf '%s' "${input}" | tr -cd "${allowed}"
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,76 @@
#!/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
guard_sourcing
#######################################
# Wrapper for secure curl.
# Globals:
# ERR_DOWNLOAD_FAILED
# ERR_NO_DOWNLOAD_ARG
# Arguments:
# 1: URL from which to download a specific file.
# 2: /path/to/file to be saved to.
# Returns:
# ERR_DOWNLOAD_FAILED: Download failed.
# ERR_NO_DOWNLOAD_ARG: No arguments specified.
#######################################
scurl() {
if [[ $# -ne 2 ]]; then
do_log "error" "true" "Usage: scurl <URL> <path/to/file>"
return "${ERR_NO_DOWNLOAD_ARG}"
fi
declare url="$1"
declare output_path="$2"
if ! curl --doh-url "https://dns01.eddns.eu/dns-query" \
--doh-cert-status \
--tlsv1.3 \
-sSf \
-o "${output_path}" \
"${url}"
then
do_log "error" "true" "Download failed for URL: '${1}'."
return "${ERR_DOWNLOAD_FAILED}"
fi
}
#######################################
# Wrapper for secure wget.
# Globals:
# ERR_DOWNLOAD_FAILED
# ERR_NO_DOWNLOAD_ARG
# Arguments:
# 1: URL from which to download a specific file.
# 2: /path/to/file to be saved to.
# Returns:
# ERR_DOWNLOAD_FAILED: Download failed.
# ERR_NO_DOWNLOAD_ARG: No arguments specified.
#######################################
swget() {
if [[ $# -ne 2 ]]; then
do_log "error" "true" "Usage: swget <URL> <path/to/file>"
return "${ERR_NO_DOWNLOAD_ARG}"
fi
declare url="$1"
declare output_path="$2"
if ! wget --show-progress \
--no-clobber \
--https-only \
--secure-protocol=TLSv1_3 \
-qO "${output_path}" \
"${url}"
then
do_log "error" "true" "Download failed for URL: '${1}'."
return "${ERR_DOWNLOAD_FAILED}"
fi
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,26 @@
#!/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
guard_sourcing
#######################################
# yq_val <YQ expression> <file> - Returns value, converts null to ""
# Arguments:
# 1: Key String to evaluate
# 2: YAML File
#######################################
yq_val() {
declare var_h; var_h=$(yq e "$1" "$2")
[[ "${var_h}" == null ]] && var_h=""
printf '%s' "${var_h}"
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,130 @@
#!/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
guard_sourcing
#######################################
# Log level values for comparison.
# Arguments:
# 1: "${LOG_LEVEL}" one of: "debug" | "info" | "notice" | "warn" | "error" | "critical" | "fatal" | "emergency"
#######################################
log_level_value() {
case "${1,,}" in
debug) printf '%d' 7 ;;
info) printf '%d' 6 ;;
notice) printf '%d' 5 ;;
warn) printf '%d' 4 ;;
error) printf '%d' 3 ;;
critical) printf '%d' 2 ;;
fatal) printf '%d' 1 ;;
emergency) printf '%d' 0 ;;
esac
}
#######################################
# Filter and compare log levels.
# Globals:
# DEFAULT_LOG_LEVEL
# Arguments:
# 1: "${LOG_LEVEL}" one of: "debug" | "info" | "notice" | "warn" | "error" | "critical" | "fatal" | "emergency"
#######################################
do_should_log() {
# shellcheck disable=SC2155
declare -i var_desired_log_value=$(log_level_value "$1") # Desired log level
# shellcheck disable=SC2155
declare -i var_default_log_value=$(log_level_value "${DEFAULT_LOG_LEVEL}") # Current threshold
### Return true if a message should be logged.
[[ $var_desired_log_value -le $var_default_log_value ]]
}
#######################################
# Log level color retriever.
# Globals:
# BLU
# C_GRN
# MAG
# RED
# WHI
# YEL
# Arguments:
# 1: "${LOG_LEVEL}" one of: "debug" | "info" | "notice" | "warn" | "error" | "critical" | "fatal" | "emergency"
#######################################
do_get_log_color() {
case "${1,,}" in
debug) echo "${WHI}" ;;
info) echo "${C_GRN}" ;;
notice) echo "${YEL}" ;;
warn | error | critical) echo "${RED}" ;;
fatal | emergency) echo "${MAG}" ;;
*) echo "${BLU}" ;;
esac
}
#######################################
# Main logger wrapper.
# Globals:
# LOG_ERR
# LOG_INS
# Arguments:
# 1: "${LOG_LEVEL}" one of: "debug" | "info" | "notice" | "warn" | "error" | "critical" | "fatal" | "emergency"
# 2: "${LOG_ONLY}" boolean "true" | "false"
# @: "${MESSAGE[*]}" arbitrary text string to log.
#######################################
do_log() {
declare var_log_level="$1"; shift
declare var_log_only="$2"; shift
declare ary_message=("$@")
declare var_msg_string="${ary_message[*]}"
declare var_color; var_color=$(do_get_log_color "${var_log_level}")
declare var_ts; var_ts="$(date -u '+%Y-%m-%dT%H:%M:%S.%4N%z')"
declare var_log_entry=("${var_ts} [${var_log_level}]: ${ary_message[*]}")
if do_should_log "${var_log_level}"; then
if [[ "${var_log_only,,}" == "true" ]]; then
case "${var_log_level,,}" in
debug | info | notice) do_print_log "${var_log_entry[*]}" >> "${LOG_INS}" ;;
warn | error | critical | fatal | emergency ) do_print_log "${var_log_entry[*]}" >> "${LOG_ERR}" ;;
esac
elif [[ "${var_log_only,,}" == "false" ]]; then
case "${var_log_level,,}" in
debug | info | notice)
if [[ ${#var_msg_string} -le 76 ]]; then
do_print_color "${var_color}" "${var_log_entry[*]}"
do_print_log "${var_log_entry[*]}" >> "${LOG_INS}"
else
do_print_fold "${var_color}" "${var_log_entry[*]}"
do_print_log "${var_log_entry[*]}" >> "${LOG_INS}"
fi
;;
warn | error | critical | fatal | emergency)
if [[ ${#var_msg_string} -le 76 ]]; then
do_print_color "${var_color}" "${var_log_entry[*]}"
do_print_log "${var_log_entry[*]}" >> "${LOG_ERR}"
else
do_print_fold "${var_color}" "${var_log_entry[*]}"
do_print_log "${var_log_entry[*]}" >> "${LOG_ERR}"
fi
;;
*)
if [[ ${#var_msg_string} -le 76 ]]; then
do_print_color "${var_color}" "${var_log_entry[*]}"
do_print_log "${var_log_entry[*]}" >> "${LOG_INS}"
else
do_print_fold "${var_color}" "${var_log_entry[*]}"
do_print_log "${var_log_entry[*]}" >> "${LOG_INS}"
fi
;;
esac
fi
fi
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,34 @@
#!/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
guard_sourcing
#######################################
# Checks if a search pattern / string / value is present in an array.
# Arguments:
# 1: String to check against:
# 2: "$@" Array
# Returns:
# 0: If String is present in Array.
# 1: If String is NOT present in Array.
#######################################
validation_array() {
declare var_element
declare var_string=$1; shift
for var_element in "$@"; do
if [[ "${var_element}" == "${var_string}" ]]; then
return 0
fi
done
return 1
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,110 @@
#!/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
guard_sourcing
#######################################
# IPv4 validation.
# Globals:
# ERR_INVALID_IPV4
# Arguments:
# 1: IPv4 to validate.
# Returns:
# ERR_INVALID_IPV4
#######################################
validation_ipv4() {
declare var_ip="$1"
### Single-pass check: 4 octets, each 0-255, no leading zeros (unless the octet is exactly "0")
if [[ "${var_ip}" =~ ^((25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})\.){3}(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})$ ]]; then
do_log "info" "true" "'${var_ip}' seems to be a valid IPv4."
else
return "${ERR_INVALID_IPV4}"
fi
}
#######################################
# IPv6 validation, including
# - Standard IPv6 notation with eight groups such as 2001:0db8:85a3:0000:0000:8a2e:0370:7334
# - Shortened notation with :: like 2001:db8::1
# - Addresses with embedded IPv4 addresses like ::ffff:192.0.2.128
# - Link-local addresses like fe80::1%eth0
# Globals:
# ERR_INVALID_IPV6
# Arguments:
# 1: IPv6 address
# Returns:
# ERR_INVALID_IPV6
#######################################
validation_ipv6() {
### Original input (may include %zone).
declare var_ip="$1"
### Strip optional zone id, e.g. fe80::1%eth0 -> fe80::1
declare var_addr="${var_ip%%\%*}"
declare var_has_double_colon=0
### Step 1 - IPv4-mapped / -embedded addresses (::ffff:192.0.2.1)
if [[ "${var_addr}" == *.* ]]; then
declare var_ipv4_part="${var_addr##*:}"
validation_ipv4 "${var_ipv4_part}" || return "${ERR_INVALID_IPV6}"
### Replace IPv4 part by a placeholder, so we can count hextets later
var_addr="${var_addr%:*}:0:0"
fi
### Step 2 - Detect forbidden multiple '::'
if [[ "${var_addr}" == *::* ]]; then
var_has_double_colon=1
### Remove first '::' and check there is no second one.
[[ ${var_addr#*::*} == *::* ]] && return "${ERR_INVALID_IPV6}"
fi
### Step 3 - Split into hextets and validate format.
declare var_hextet
declare -a var_segments
IFS=':' read -ra var_segments <<< "${var_addr}"
declare seg_count=${#var_segments[@]}
for var_hextet in "${var_segments[@]}"; do
### Empty part of '::' compression
[[ -z "${var_hextet}" ]] && continue
[[ "${var_hextet}" =~ ^[0-9a-fA-F]{1,4}$ ]] || return "${ERR_INVALID_IPV6}"
done
### Step 4 - Check total hextet count.
if (( var_has_double_colon )); then
(( seg_count <= 8 )) || return "${ERR_INVALID_IPV6}"
else
(( seg_count == 8 )) || return "${ERR_INVALID_IPV6}"
fi
### Success
do_log "info" "true" "'${var_ip}' seems to be a valid IPv6."
}
#######################################
# Port validation.
# Globals:
# ERR_INVALID_PORT
# Arguments:
# 1: Port number
# Returns:
# ERR_INVALID_PORT
#######################################
validation_port() {
declare var_port="$1"
if [[ "${var_port}" =~ ^[0-9]+$ ]] && (( var_port >= 1 && var_port <= 65535 )); then
do_log "info" "true" "'${var_port}' seems to be a valid port."
else
do_log "error" "false" "'${var_port}' seems to be NOT a valid port."
return "${ERR_INVALID_PORT}"
fi
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,63 @@
#!/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
guard_sourcing
#######################################
# Validate all preseed network variables (IPv4 & IPv6)
# Arguments:
# None
#######################################
validation_preseed() {
declare var value
### --- IPv4 variables ------------------------------------------------------
declare -a ipv4_vars=(
network_static_ipv4nameserver_0
network_static_ipv4nameserver_1
network_static_ipv4nameserver_fallback_0
network_static_ipv4nameserver_fallback_1
network_static_ipv4address
network_static_ipv4gateway
)
### --- IPv6 variables ------------------------------------------------------
declare -a ipv6_vars=(
network_static_ipv6nameserver_0
network_static_ipv6nameserver_1
network_static_ipv6nameserver_fallback_0
network_static_ipv6nameserver_fallback_1
network_static_ipv6address
)
### --- loop over both groups ----------------------------------------------
for var in "${ipv4_vars[@]}"; do
value="${!var}"
if [[ -n "${value}" ]]; then
validation_ipv4 "${value}"
else
do_log "info" "true" "'${var}' is not set."
fi
done
for var in "${ipv6_vars[@]}"; do
value="${!var}"
if [[ -n "${value}" ]]; then
validation_ipv6 "${value}"
else
do_log "info" "false" "'${var}' is not set."
fi
done
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,71 @@
#!/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
guard_sourcing
#######################################
# Parsing './.preseed/preseed.yaml' and './.preseed/partitioning.yaml'.
# Globals:
# ARY_BOOTPARAM
# ARY_NTPSRVR
# ARY_PACKAGES
# DIR_CNF
# DIR_TMP
# VAR_PRESEED
# Arguments:
# None
# Returns:
# 0: on success
#######################################
yaml_parser() {
cat "${DIR_CNF}/preseed.yaml" "${DIR_CNF}/partitioning.yaml" >| "${DIR_TMP}/combined.yaml"
yq -o=shell "${DIR_TMP}/combined.yaml" >| "${VAR_PRESEED}"
# shellcheck disable=SC2034
declare -ag ARY_BOOTPARAM=() ARY_NTPSRVR=() ARY_PACKAGES=()
declare -gix VAR_USER_MAX=0
declare var_index var_key var_value
### Generate Arrays for Grub Parameter, NTPSec Server FQDN, Software Packages
while IFS='=' read -r var_key var_value; do
var_value=${var_value#\'}
var_value=${var_value%\'}
case "${var_key}" in
grub_parameter_[0-9]*) ARY_BOOTPARAM+=("${var_value}") ;;
ntp_server_[0-9]*) ARY_NTPSRVR+=("${var_value}") ;;
software_[0-9]*) ARY_PACKAGES+=("${var_value}") ;;
esac
done < "${VAR_PRESEED}"
### Search all set variables for user_userN_name patterns.
# shellcheck disable=SC2312
while IFS='=' read -r var_index; do
if [[ "${var_index}" =~ ^user_user([0-9]+)_name$ ]]; then
var_index="${BASH_REMATCH[1]}"
(( var_index > VAR_USER_MAX )) && VAR_USER_MAX="${var_index}"
fi
done < <(compgen -v)
### Delete the respective 'key:value'-variables in the global variable set.
sed -i '/^grub_parameter_[0-9]\+=/d' "${VAR_PRESEED}"
sed -i '/^ntp_server_[0-9]\+=/d' "${VAR_PRESEED}"
sed -i '/^software_[0-9]\+=/d' "${VAR_PRESEED}"
### Substitute all key= by key=""
sed -i -E 's/^(.*)=\s*$/\1=""/' "${VAR_PRESEED}"
### Wrap each key=value by '' e.g., key='value'
sed -i -E "s/^(.*)=([^'\"]+)$/\1='\2'/" "${VAR_PRESEED}"
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh

View File

@@ -0,0 +1,150 @@
#!/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
guard_sourcing
#######################################
# Reading and extracting variables from "${PRESEED}".
# Globals:
# ERR_NO_VALID_RECIPE
# HMP_RECIPE_DEV_PARTITIONS
# VAR_PRESEED
# VAR_RECIPE_DEV_COUNTER
# VAR_RECIPE_FIRMWARE
# VAR_RECIPE_STRING
# VAR_RECIPE_TABLE
# Arguments:
# None
# Returns:
# 0: on success
#######################################
yaml_reader() {
### Declare and substitute input files
declare -r var_if="${VAR_PRESEED}"
### Search pattern for variables (recipe_<string>_active='true')
declare -r var_search_pattern="^recipe_.*_active='true'"
declare var_line=""
declare var_middle_part=""
### Read "${var_if}" line by line
while IFS= read -r var_line; do
### Check, if line matches the search pattern
if [[ "${var_line}" =~ ${var_search_pattern} ]]; then
### Extract the middle part or second position
var_middle_part=$(echo "${var_line}" | sed -E "s/^recipe_([^_]+)_active='true'/\1/")
declare -gx VAR_RECIPE_STRING="${var_middle_part}"
### Exit after first occurrence
break
fi
done < "${var_if}"
if [[ -n "${VAR_RECIPE_STRING}" ]]; then
do_log "info" "true" "Found active recipe string: '${VAR_RECIPE_STRING}'."
else
do_log "fatal" "true" "Found NO active recipe string: '${VAR_RECIPE_STRING}'." >&2
exit "${ERR_NO_VALID_RECIPE}"
fi
### Variable for highest device count e.g., /dev/sdf = "f"
declare var_highest_dev
### Search "${var_if}" for matching recipe_${VAR_RECIPE_STRING}_dev_* entries and find the highest dev letter
var_highest_dev=$(grep -E "^recipe_${VAR_RECIPE_STRING}_dev_" "${var_if}" | awk -F'_' '
{
if (NF >= 4) {
### Extract 4th position (e.g., "recipe_${VAR_RECIPE_STRING}_dev_sda" or "recipe_${VAR_RECIPE_STRING}_dev_vda")
device_field = $4
### Check, if field is at least 3 char wide and last char contains a letter
if (length(device_field) >= 3) {
last_char = substr(device_field, length(device_field), 1) ### Extract last letter of respective field
if (last_char ~ /^[a-z]$/ && last_char > max) {
max = last_char
}
}
}
}
END { print max }
')
### Save the result in VAR_RECIPE_DEV_COUNTER
declare -gx VAR_RECIPE_DEV_COUNTER="${var_highest_dev}"
if [[ -n ${VAR_RECIPE_DEV_COUNTER} ]]; then
do_log "info" "true" "Found highest recipe device: '${VAR_RECIPE_DEV_COUNTER}'."
else
do_log "fatal" "true" "Found NO highest recipe device: '${VAR_RECIPE_DEV_COUNTER}'." >&2
exit "${ERR_NO_VALID_RECIPE}"
fi
declare var_device="" var_fields="" var_line="" var_partition=""
declare -Agx HMP_RECIPE_DEV_PARTITIONS=()
### Read var_if and iterate through all matching entries without executing in a subshell
while read -r var_line; do
### Extract fields of line
IFS='_' read -ra var_fields <<< "${var_line}"
### Check that enough fields are available
if [[ "${#var_fields[@]}" -ge 5 ]]; then
var_device="${var_fields[3]}" ### The fourth position includes the device (e.g., sda, vda, xvda)
var_partition="${var_fields[4]}" ### The fifth position includes the partition (e.g., 13)
### Check, if the partition is a number and higher than the current value
if [[ "${var_partition}" =~ ^[0-9]+$ ]]; then
if [[ -z "${HMP_RECIPE_DEV_PARTITIONS[${var_device}]}" || "${var_partition}" -gt ${HMP_RECIPE_DEV_PARTITIONS[${var_device}]} ]]; then
# shellcheck disable=SC2004
HMP_RECIPE_DEV_PARTITIONS[${var_device}]="${var_partition}"
fi
fi
fi
done < <(grep -E "^recipe_${VAR_RECIPE_STRING}_dev_" "${var_if}")
for var_device in "${!HMP_RECIPE_DEV_PARTITIONS[@]}"; do
do_log "info" "false" "Highest number of partitions for ${var_device}: ${HMP_RECIPE_DEV_PARTITIONS[${var_device}]}"
done
### Extract the chosen Nuke mechanism
declare recipe_nuke_var="recipe_${VAR_RECIPE_STRING}_control_nuke"
declare -gx VAR_NUKE="${!recipe_nuke_var}"
### Extract chosen partition table
declare recipe_table_var="recipe_${VAR_RECIPE_STRING}_control_table"
declare -gx VAR_RECIPE_TABLE="${!recipe_table_var}"
### Extract chosen firmware
declare recipe_firmware_var="recipe_${VAR_RECIPE_STRING}_control_firmware"
declare -gx VAR_RECIPE_FIRMWARE="${!recipe_firmware_var}"
if [[ "${VAR_RECIPE_TABLE,,}" == "gpt" && "${VAR_RECIPE_FIRMWARE,,}" == "uefi" ]]; then
do_log "info" "false" "Partition table: '${VAR_RECIPE_TABLE}' and firmware: '${VAR_RECIPE_FIRMWARE}' > ESP 'EF00' necessary."
elif [[ "${VAR_RECIPE_TABLE,,}" == "gpt" && "${VAR_RECIPE_FIRMWARE,,}" == "bios" ]]; then
do_log "info" "false" "Partition table: '${VAR_RECIPE_TABLE}' and firmware: '${VAR_RECIPE_FIRMWARE}' > BIOS Boot Partition 'EF02' necessary."
elif [[ "${VAR_RECIPE_TABLE,,}" == "msdos" && "${VAR_RECIPE_FIRMWARE,,}" == "uefi" ]]; then
do_log "info" "false" "Partition table: '${VAR_RECIPE_TABLE}' and firmware: '${VAR_RECIPE_FIRMWARE}' > ESP on MBR needs partition type '0xEF'."
elif [[ "${VAR_RECIPE_TABLE,,}" == "msdos" && "${VAR_RECIPE_FIRMWARE,,}" == "bios" ]]; then
do_log "info" "false" "Partition table: '${VAR_RECIPE_TABLE}' and firmware: '${VAR_RECIPE_FIRMWARE}' > No special firmware partition necessary."
fi
return 0
}
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh