From 009335577f970e240fe06b50d1d647091acb5b5817f6930a3cf4f2291eaf71ec Mon Sep 17 00:00:00 2001 From: "Marc S. Weidner" Date: Sun, 23 Nov 2025 19:25:48 +0000 Subject: [PATCH] V8.13.440.2025.11.19 Signed-off-by: Marc S. Weidner --- .archive/0024-ciss-crypt-squash | 364 ++++++++++++++++++ .../usr/lib/live/boot/0024-ciss-crypt-squash | 98 ++--- .../usr/lib/live/boot/9990-main.sh | 5 +- .../usr/lib/live/boot/9990-overlay.sh | 2 +- 4 files changed, 399 insertions(+), 70 deletions(-) create mode 100644 .archive/0024-ciss-crypt-squash diff --git a/.archive/0024-ciss-crypt-squash b/.archive/0024-ciss-crypt-squash new file mode 100644 index 0000000..73cd534 --- /dev/null +++ b/.archive/0024-ciss-crypt-squash @@ -0,0 +1,364 @@ +#!/bin/sh +# bashsupport disable=BP5007 +# shellcheck disable=SC2249 +# shellcheck shell=sh + +# SPDX-Version: 3.0 +# SPDX-CreationInfo: 2025-11-12; WEIDNER, Marc S.; +# 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.; +# 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 + +# Purpose: Open /live/ciss_rootfs.crypt (LUKS) for final processing in '9990-overlay.sh' +# Phase : premount (executed by live-boot inside the initramfs) + +_SAVED_SET_OPTS="$(set +o)" + +set -eu + +printf "\e[95m[INFO] Starting : [/usr/lib/live/boot/0024-ciss-crypt-squash] \n\e[0m" + +####################################### +# Ask for a passphrase on /dev/console, mask input with '*'. +# Globals: +# None +# Arguments: +# None +# Returns: +# 0: on success +# 1: on failure / empty +####################################### +ask_pass_console() { + PASSPHRASE="" + SAVED_STTY="" + + ### Save current console settings. + SAVED_STTY=$(stty -g /dev/null || printf '') + + ### Non-canonical mode, no echo, 1 byte at a time. + stty -echo -icanon time 0 min 1 /dev/null || return 1 + + printf '\e[93m[INFO] Enter LUKS passphrase: \n\e[0m' > /dev/console + + cr=$(printf '\r') + bs=$(printf '\b') + del=$(printf '\177') + + while :; do + + ### Read exactly one byte from the console. + c=$(dd bs=1 count=1 2>/dev/null /dev/console + break + + fi + + ### If nothing read (race), loop again. + [ -z "${c}" ] && continue + + case "${c}" in + + "${cr}") + ### Enter: finish input. + printf '\n' > /dev/console + break + ;; + + "${bs}"|"${del}") + ### Backspace, delete: delete one character, if available. + if [ -n "${PASSPHRASE}" ]; then + + PASSPHRASE=${PASSPHRASE%?} + printf '\b \b' > /dev/console + + fi + ;; + + *) + ### Normal character: append and mask output. + PASSPHRASE="${PASSPHRASE}${c}" + printf '*' > /dev/console + ;; + + esac + + done + + [ -n "${SAVED_STTY}" ] && stty "${SAVED_STTY}" /dev/null || : + + printf '%s' "${PASSPHRASE}" + + return 0 +} + +####################################### +# Premount logging helper. +# Globals: +# None +# Arguments: +# *: String to log. +####################################### +log() { + msg="$*" + if [ -w /dev/kmsg ]; then + printf '<6>%s: %s\n' '0024-ciss-crypt-squash' "${msg}" > /dev/kmsg + else + printf '%s: %s\n' '0024-ciss-crypt-squash' "${msg}" + fi +} + +### Declare variables. --------------------------------------------------------------------------------------------------------- +export CDLB_ISO_LABEL="CISS.debian.live" +export CDLB_LUKS_FS="/live/ciss_rootfs.crypt" +export CDLB_MAPPER_NAME="crypt_liveiso" +export CDLB_MAPPER_DEV="/dev/mapper/${CDLB_MAPPER_NAME}" +CDLB_REMOTE_WAIT_SECS="${CDLB_REMOTE_WAIT_SECS:-3600}" +MNT_MEDIUM="/run/live/medium" +MNT_ROOTFS="/run/live/rootfs" +_PARAMETER="" +_dev="" + +### Read the kernel cmdline once. ---------------------------------------------------------------------------------------------- +CMDLINE="$(cat /proc/cmdline 2>/dev/null || printf '')" + +for _PARAMETER in ${CMDLINE}; do + + case "${_PARAMETER}" in + + ciss_crypt_path=*) export CDLB_LUKS_FS="${_PARAMETER#ciss_crypt_path=}";; + ciss_iso_label=* ) export CDLB_ISO_LABEL="${_PARAMETER#ciss_iso_label=}";; + + esac + +done + +printf "\e[92m[INFO] CDLB_LUKS_FS : [%s] \n\e[0m" "${CDLB_LUKS_FS}" +printf "\e[92m[INFO] CDLB_ISO_LABEL : [%s] \n\e[0m" "${CDLB_ISO_LABEL}" + +mkdir -p "${MNT_MEDIUM}" "${MNT_ROOTFS}" + +### Mount the live medium (ISO) read-only, unless already mounted. ------------------------------------------------------------- +if ! mountpoint -q "${MNT_MEDIUM}"; then + + if [ -n "${CDLB_ISO_LABEL}" ] && [ -e "/dev/disk/by-label/${CDLB_ISO_LABEL}" ]; then + + mount -r -t iso9660 "/dev/disk/by-label/${CDLB_ISO_LABEL}" "${MNT_MEDIUM}" 2>/dev/null \ + || mount -r -t udf "/dev/disk/by-label/${CDLB_ISO_LABEL}" "${MNT_MEDIUM}" 2>/dev/null \ + || log "could not mount label=${CDLB_ISO_LABEL} (iso9660/udf)" + + fi + +fi + +if ! mountpoint -q "${MNT_MEDIUM}"; then + + ### Fallback scan (covers SR drives and loop-mounted ISOs that udev exposed). + for _dev in /dev/sr* /dev/cdrom /dev/disk/by-label/*; do + + ### Skip non-block entries early. + [ -b "${_dev}" ] || continue + + ### Try ISO9660 first, then UDF; only unmount on failure. + if mount -r -t iso9660 "${_dev}" "${MNT_MEDIUM}" 2>/dev/null || mount -r -t udf "${_dev}" "${MNT_MEDIUM}" 2>/dev/null; then + + mountpoint -q "${MNT_MEDIUM}" 2>/dev/null && break + + else + + umount "${MNT_MEDIUM}" 2>/dev/null || true + + fi + + done + +fi + +if ! mountpoint -q "${MNT_MEDIUM}"; then + + log "No live medium mounted, defer to default live-boot path." + printf "\e[91m[FATAL] Boot failure : No live medium mounted, defer to default live-boot path. \n\e[0m" + exit 42 + +fi + +printf "\e[92m[INFO] MNT_MEDIUM : [%s] \n\e[0m" "${MNT_MEDIUM}" + +### Locate the encrypted root container on the medium. ------------------------------------------------------------------------- +if [ ! -f "${MNT_MEDIUM}${CDLB_LUKS_FS}" ]; then + + log "Encrypted root not found at: [${MNT_MEDIUM}${CDLB_LUKS_FS}]" + printf "\e[91m[FATAL] Boot failure : Encrypted root not found at: [%s%s] \n\e[0m" "${MNT_MEDIUM}" "${CDLB_LUKS_FS}" + exit 42 + +fi + +printf "\e[92m[INFO] CISS LUKS FS : [%s%s] \n\e[0m" "${MNT_MEDIUM}" "${CDLB_LUKS_FS}" + +### Attach a loop device read-only to the encrypted file. ---------------------------------------------------------------------- +LOOP="$(losetup -f --show -r "${MNT_MEDIUM}${CDLB_LUKS_FS}")" || { log "losetup failed"; exit 42; } + +printf "\e[92m[INFO] Loop device : [%s] \n\e[0m" "${LOOP}" + +### Expose the loop device for unlock-wrapper.sh, dropbear forced-command. ----------------------------------------------------- +mkdir -p /run 2>/dev/null || true + +echo "${LOOP}" > /run/ciss-loopdev 2>/dev/null || true + +chmod 0600 /run/ciss-loopdev 2>/dev/null || true + +printf "\e[92m[INFO] Exposed LOOP : [/run/ciss-loopdev] -> [%s]\n\e[0m" "${LOOP}" + +### Prepare fifo for passphrase. ----------------------------------------------------------------------------------------------- +mkdir -p /lib/cryptsetup 2>/dev/null || true + +if [ -p /lib/cryptsetup/passfifo ]; then + + rm -f /lib/cryptsetup/passfifo 2>/dev/null || true + +fi + +if ! mkfifo /lib/cryptsetup/passfifo 2>/dev/null; then + + printf "\e[92m[WARN] Boot failure : Failed to create /lib/cryptsetup/passfifo \n\e[0m" + exit 42 + +fi + +chmod 0600 /lib/cryptsetup/passfifo 2>/dev/null || true + +### Background broker: read FIFO, try cryptsetup per line. --------------------------------------------------------------------- +( + set +e + + PASS="" + + while :; do + + if [ -b "${CDLB_MAPPER_DEV}" ]; then + + break + + fi + + if ! IFS= read -r PASS < /lib/cryptsetup/passfifo; then + + sleep 1 + continue + + fi + + [ -n "${PASS}" ] || continue + + printf "\e[93m[INFO] CISS LUKS decryption : LUKS mapper [%s] trying to unlock via cryptsetup ... \n\e[0m" "${CDLB_MAPPER_DEV}" >/dev/console 2>/dev/null || true + + KEYLEN=${#PASS} + + printf '%s' "${PASS}" | cryptsetup open --tries 1 \ + --type luks \ + --keyfile-size="${KEYLEN}" \ + --readonly "${LOOP}" "${CDLB_MAPPER_NAME}" --key-file - 2>/dev/console + + if [ -b "${CDLB_MAPPER_DEV}" ]; then + + printf "\e[92m[INFO] CISS LUKS decryption : LUKS mapper [%s] successfully opened. \n\e[0m" "${CDLB_MAPPER_DEV}" >/dev/console 2>/dev/null || true + break + + fi + + done +) & +PID_BROKER="$!" + +### Background process console-prompt feed passphrases into FIFO. -------------------------------------------------------------- +( + set +e + + PASS="" + + while :; do + + if [ -b "${CDLB_MAPPER_DEV}" ]; then + + break + + fi + + # shellcheck disable=SC2310 + PASS="$(ask_pass_console)" || continue + + printf '%s\n' "${PASS}" >| /lib/cryptsetup/passfifo 2>/dev/null || : + + done +) & +PID_PROMPT="$!" + +### Main process: wait bounded time for the mapper to appear. ------------------------------------------------------------------ +REMAINING="${CDLB_REMOTE_WAIT_SECS}" + +if [ ! -b "${CDLB_MAPPER_DEV}" ]; then + + printf "\e[93m[INFO] CISS LUKS decryption : Waiting up to %s seconds for [%s] to be unlocked ... \n\e[0m" "${REMAINING}" "${CDLB_MAPPER_DEV}" + +fi + +while [ "${REMAINING}" -gt 0 ]; do + + if [ -b "${CDLB_MAPPER_DEV}" ]; then + + break + + fi + + sleep 1 + + REMAINING=$((REMAINING - 1)) + +done + +if [ ! -b "${CDLB_MAPPER_DEV}" ]; then + + printf "\e[91m[WARN] CISS LUKS decryption : Timeout LUKS mapper [%s] not present after %s seconds. \n\e[0m" "${CDLB_MAPPER_DEV}" "${CDLB_REMOTE_WAIT_SECS}" + kill "${PID_PROMPT}" 2>/dev/null || true + kill "${PID_BROKER}" 2>/dev/null || true + rm -f /lib/cryptsetup/passfifo 2>/dev/null || true + exit 42 + +fi + +kill "${PID_PROMPT}" 2>/dev/null || true +wait "${PID_BROKER}" 2>/dev/null || true +rm -f /lib/cryptsetup/passfifo 2>/dev/null || true + +printf "\e[92m[INFO] LUKS mapper : [%s] is now present.\n\e[0m" "${CDLB_MAPPER_DEV}" + +### Expose the decrypted root device for live-boot overlay. The live-boot components will pick this up in '9990-overlay.sh'. --- +echo "${CDLB_MAPPER_DEV}" >| /run/ciss-rootdev +chmod 0644 /run/ciss-rootdev 2>/dev/null || true +export CISS_ROOT_DEV="${CDLB_MAPPER_DEV}" +export CISS_ROOT_DIR="" + +log "Decrypted root device exposed at [/run/ciss-rootdev] -> [${CDLB_MAPPER_DEV}]" +printf "\e[92m[INFO] CISS LUKS decryption : Decrypted root device exposed at: [/run/ciss-rootdev] -> [%s] \n\e[0m" "${CDLB_MAPPER_DEV}" + +### Final sanity check. -------------------------------------------------------------------------------------------------------- +if [ ! -b "${CDLB_MAPPER_DEV}" ]; then + + log "Failed to unlock encrypted root [${CDLB_LUKS_FS}] via dropbear and console." + printf "\e[91m[WARN] Failed unlock : [%s] via dropbear and console. \n\e[0m" "${CDLB_LUKS_FS}" + exit 42 + +fi + +eval "${_SAVED_SET_OPTS}" + +printf "\e[92m[INFO] Successfully applied : [/usr/lib/live/boot/0024-ciss-crypt-squash] \n\e[0m" + +# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh diff --git a/config/includes.chroot/usr/lib/live/boot/0024-ciss-crypt-squash b/config/includes.chroot/usr/lib/live/boot/0024-ciss-crypt-squash index c6cd87e..68cd726 100644 --- a/config/includes.chroot/usr/lib/live/boot/0024-ciss-crypt-squash +++ b/config/includes.chroot/usr/lib/live/boot/0024-ciss-crypt-squash @@ -43,8 +43,6 @@ ask_pass_console() { ### Non-canonical mode, no echo, 1 byte at a time. stty -echo -icanon time 0 min 1 /dev/null || return 1 - printf '\e[93m[INFO] Enter LUKS passphrase: \n\e[0m' > /dev/console - cr=$(printf '\r') bs=$(printf '\b') del=$(printf '\177') @@ -67,13 +65,13 @@ ask_pass_console() { case "${c}" in "${cr}") - ### Enter: finish input. + ### Enter: finish input. printf '\n' > /dev/console break ;; "${bs}"|"${del}") - ### Backspace, delete: delete one character, if available. + ### Backspace, delete: delete one character, if available. if [ -n "${PASSPHRASE}" ]; then PASSPHRASE=${PASSPHRASE%?} @@ -83,7 +81,7 @@ ask_pass_console() { ;; *) - ### Normal character: append and mask output. + ### Normal character: append and mask output. PASSPHRASE="${PASSPHRASE}${c}" printf '*' > /dev/console ;; @@ -99,60 +97,6 @@ ask_pass_console() { return 0 } -####################################### -# Ask for a passphrase on /dev/console, mask input with '*'. -# Globals: -# None -# Arguments: -# None -# Returns: -# 0: on success -# 1: on failure / empty -####################################### -ask_pass_console_old() { - PASSPHRASE="" - SAVED_STTY="" - - if command -v stty >/dev/null 2>&1; then - - SAVED_STTY="$(stty -g /dev/null || printf '')" - stty -echo /dev/console 2>/dev/null || SAVED_STTY="" - - fi - - printf "\e[93m[INFO] Enter LUKS passphrase: \n\e[0m" >/dev/console 2>/dev/null || return 1 - - while :; do - - C="$(dd if=/dev/console bs=1 count=1 2>/dev/null | tr -d '\r\n')" - - [ -z "${C}" ] && break - - PASSPHRASE="${PASSPHRASE}${C}" - - printf "*" >/dev/console 2>/dev/null || : - - done - - if [ -n "${SAVED_STTY}" ]; then - - stty "${SAVED_STTY}" /dev/console 2>/dev/null || : - - else - - stty echo /dev/console 2>/dev/null || : - - fi - - printf "\n" >/dev/console 2>/dev/null || : - - [ -n "${PASSPHRASE}" ] || return 1 - - printf '%s\n' "${PASSPHRASE}" - - return 0 -} - ####################################### # Premount logging helper. # Globals: @@ -336,6 +280,8 @@ PID_BROKER="$!" set +e PASS="" + PASS_SENT=0 + WAIT_LOOP=0 while :; do @@ -345,22 +291,38 @@ PID_BROKER="$!" fi - #printf "\e[93m[INFO] Enter LUKS passphrase on console: \n\e[0m" >/dev/console 2>/dev/null || break + if [ "${PASS_SENT}" -eq 0 ]; then - #if ! IFS= read -r PASS /dev/null; then + printf '\e[93m[INFO] Enter LUKS passphrase: \n\e[0m' > /dev/console - # break + # shellcheck disable=SC2310 + PASS="$(ask_pass_console)" || continue - #fi + printf '%s\n' "${PASS}" >| /lib/cryptsetup/passfifo 2>/dev/null || : - #[ -n "${PASS}" ] || continue + PASS_SENT=1 + WAIT_LOOP=0 - # shellcheck disable=SC2310 - PASS="$(ask_pass_console)" || continue + else - printf '%s\n' "${PASS}" >| /lib/cryptsetup/passfifo 2>/dev/null || : + WAIT_LOOP=$((WAIT_LOOP + 1)) + + if [ "${WAIT_LOOP}" -ge 160 ]; then + + printf '\e[91m[WARN] Please try again : \n\e[0m' > /dev/console + + PASS_SENT=0 + WAIT_LOOP=0 + + fi + + fi + + sleep 0.1 done + + return 0 ) & PID_PROMPT="$!" @@ -401,7 +363,7 @@ kill "${PID_PROMPT}" 2>/dev/null || true wait "${PID_BROKER}" 2>/dev/null || true rm -f /lib/cryptsetup/passfifo 2>/dev/null || true -printf "\e[92m[INFO] LUKS mapper : [%s] is now present.\n\e[0m" "${CDLB_MAPPER_DEV}" +printf "\e[92m[INFO] CISS LUKS decryption : [%s] is now present.\n\e[0m" "${CDLB_MAPPER_DEV}" ### Expose the decrypted root device for live-boot overlay. The live-boot components will pick this up in '9990-overlay.sh'. --- echo "${CDLB_MAPPER_DEV}" >| /run/ciss-rootdev diff --git a/config/includes.chroot/usr/lib/live/boot/9990-main.sh b/config/includes.chroot/usr/lib/live/boot/9990-main.sh index 6a259e1..5cf59b1 100644 --- a/config/includes.chroot/usr/lib/live/boot/9990-main.sh +++ b/config/includes.chroot/usr/lib/live/boot/9990-main.sh @@ -77,8 +77,9 @@ Live () printf "\e[93m[DEBUG] live(): Do a local boot from hd [livefs_root=%s] \e[0m\n" "${ROOT?}" livefs_root=${ROOT} else - printf "\e[93m[DEBUG] live(): [Setup_Memdisk] \e[0m\n" + printf "\e[93m[DEBUG] live(): [Setup_Memdisk] starting ... \e[0m\n" Setup_Memdisk + printf "\e[93m[DEBUG] live(): [Setup_Memdisk] finished. \e[0m\n" # If the live media location is given via command line and access to it # involves LVM volumes, the corresponding volumes need to be activated. @@ -86,6 +87,7 @@ Live () # shellcheck disable=SC2116 for dev in $(echo "${LIVE_MEDIA}") do + printf "\e[93m[DEBUG] live(): [%s] -> dev \e[0m\n" "${dev}" case "${dev}" in /dev/mapper/*) # shellcheck disable=SC2046,SC2312 @@ -125,6 +127,7 @@ Live () fi fi + printf "\e[93m[DEBUG] live(): [%s] -> livefs_root. \e[0m\n" "${livefs_root}" if [ -z "${livefs_root}" ] then panic "Unable to find a medium containing a live file system" diff --git a/config/includes.chroot/usr/lib/live/boot/9990-overlay.sh b/config/includes.chroot/usr/lib/live/boot/9990-overlay.sh index 707d86d..f336d4b 100644 --- a/config/includes.chroot/usr/lib/live/boot/9990-overlay.sh +++ b/config/includes.chroot/usr/lib/live/boot/9990-overlay.sh @@ -20,7 +20,7 @@ #set -e -printf "\e[95m[INFO] Sourcing : [/usr/lib/live/boot/9990-overlay.sh] \n\e[0m" +printf "\e[95m[INFO] Sourcing : [/usr/lib/live/boot/9990-overlay.sh] \n\e[0m" setup_unionfs () {