File disk-encryption-tool-1+git20240826.c956112.obscpio of Package disk-encryption-tool

07070100000000000081A400000000000000000000000166CC462400000026000000000000000000000000000000000000003A00000000disk-encryption-tool-1+git20240826.c956112/.dir-locals.el((sh-mode . ((sh-basic-offset . 8))))
07070100000001000081A400000000000000000000000166CC46240000013B000000000000000000000000000000000000003900000000disk-encryption-tool-1+git20240826.c956112/.editorconfig# EditorConfig configuration for sdbootutil
# http://EditorConfig.org

# Top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file, utf-8 charset
[*]
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
charset = utf-8
indent_style = tab
indent_size = 8
07070100000002000041ED00000000000000000000000266CC462400000000000000000000000000000000000000000000003300000000disk-encryption-tool-1+git20240826.c956112/.github07070100000003000041ED00000000000000000000000266CC462400000000000000000000000000000000000000000000003D00000000disk-encryption-tool-1+git20240826.c956112/.github/workflows07070100000004000081A400000000000000000000000166CC46240000026B000000000000000000000000000000000000004600000000disk-encryption-tool-1+git20240826.c956112/.github/workflows/test.ymlname: MicroOS in QEMU
on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - name: Install dependencies
      run: |
        sudo apt update
        sudo apt install -y qemu-system-x86 ovmf
        # Normally setfacl -m u:$USER:rw /dev/kvm should work, but for some
        # reason this only sticks around for a single QEMU run. udev?
        sudo usermod -a -G kvm "$USER"
    - name: Test
      run: |
        # Needed to activate the new kvm group membership
        sudo -u "$USER" bash test/test.sh
07070100000005000081A400000000000000000000000166CC46240000042E000000000000000000000000000000000000003300000000disk-encryption-tool-1+git20240826.c956112/LICENSEMIT License

Copyright (c) 2023 Ludwig Nussel

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
07070100000006000081A400000000000000000000000166CC4624000006DC000000000000000000000000000000000000003500000000disk-encryption-tool-1+git20240826.c956112/README.mdTool to turn a plain text image into one using LUKS full disk
encryption. There are three modes:

* Directly encrypt a disk image on a host system. The image can then
  be deployed somewhere else
* Prime a disk image by adding code to the initrd of the image that
  encrypts the image on first boot
* Include the initrd code already when building an image. The image
  would then encrypt itself on first boot.

In general the tool is developed with [kiwi](https://github.com/OSInside/kiwi)
in mind. It assumes that the image contains a single root fs using btrfs in the
third partition. Both grub2 and systemd-boot are supported. The tool generates
a

Example to directly encrypt an image:

    disk-encryption-tool -v SLE-Micro.x86_64-5.4.0-Default-GM.raw

Example to prime a plain text image to encrypt on first boot:

    disk-encryption-tool -v --prime SLE-Micro.x86_64-5.4.0-Default-GM.raw


When run on first boot the tool integrates with
[jeos-firstboot](https://github.com/openSUSE/jeos-firstboot/). The encryption
in initrd deploys an automatically generated recovery key, compatible with
[systemd-cryptenroll](https://www.freedesktop.org/software/systemd/man/latest/systemd-cryptenroll.html).
Later in the real root a jeos-firsboot module then offers to deploy
either the root password or another custom passphrase as well.

Parameters for cryptsetup-reencrypt(8) can be passed via
`/etc/encrypt_options`. One option per line, e.g.

   --type=luks1
   --iter-time=2000

It's also possible to integrate with combustion. The combustion
script would have to look like this:

    #!/bin/bash
    # combustion: prepare
    if [ "$1" = "--prepare" ]; then
        echo 12345 | disk-encryption-tool -v
    else
        echo root:12345 | chpasswd
    fi
07070100000007000081ED00000000000000000000000166CC462400002EC2000000000000000000000000000000000000004000000000disk-encryption-tool-1+git20240826.c956112/disk-encryption-tool#!/bin/bash
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: Copyright 2023 SUSE LLC
set -e
shopt -s nullglob

unset "${!LC_@}"
LANG="C.utf8"
export LANG

verbose=
prime=
gen_key=

switched_rw=
cr_name='cr_root'
cr_dev=
blkdev=
blkpart=
partno=
mp=
mounted=
tmpdir=$(mktemp -d -t disk-encryption-tool.XXXXXX)
cleanup()
{
	set +e
	if [ -n "$mp" ]; then
		while read -r i; do
			[ "$i" != "$mp" ] || make_ro
			umount "$i"
		done < <(findmnt -o TARGET -Rn --list "$mp" | tac)
	fi
	if [ -n "$mounted" ]; then
		if [ -e "$tmpdir/mounts" ]; then
			# restore previous mounts
			while read -r line; do
				eval "$line"
				mapfile -td, options < <(echo -n "$OPTIONS")
				if [ -n "$cr_dev" ] && [ "$SOURCE" = "$blkpart" ]; then
					SOURCE="$cr_dev"
				fi
				mount "$SOURCE" "$TARGET" -t "$FSTYPE" -o "$OPTIONS"
			done < "$tmpdir/mounts"
		fi
	else
		[ -e "$cr_dev" ] && cryptsetup close "${cr_dev##*/}"
		case "$blkdev" in
			/dev/nbd*) qemu-nbd -d "$blkdev" ;;
			/dev/loop*) losetup -d "$blkdev" ;;
		esac
	fi
	[ -d "$tmpdir" ] && ! mountpoint -q "$tmpdir/mnt" && rm -rf "$tmpdir"
}
trap cleanup EXIT

helpandquit()
{
	cat <<-EOF
		Usage: $0 [OPTIONS] IMAGE|BLOCKDEV

		Encrypt IMAGE or BLOCKDEV

		OPTIONS:
		  --verbose       verbose
		  --prime         add hook scripts to initrd to encrypt on first boot
		  --partno=N      partition number (default 3)
		  --gen-key       generate random recovery key
		  -h              help screen

	EOF
	exit 0
}

log_info()
{
	[ "${verbose:-0}" -gt 0 ] || return 0
	echo "$@"
}

err()
{
	echo "Error: $*" >&2
	exit 1
}

warn()
{
	echo "Warning: $*" >&2
}

isdigits()
{
       local v="${1:?}"
       [ -z "${v//[0-9]*/}" ]
}

settle_umount_events()
{
        # Manual umount confuses systemd sometimes because it's async and the
        # .mount unit might still be active when the "start" is queued, making
        # it a noop, which ultimately leaves /sysroot unmounted
        # (https://github.com/systemd/systemd/issues/20329). To avoid that,
        # wait until systemd processed the umount events. In a chroot (or with
        # SYSTEMD_OFFLINE=1) systemctl always succeeds, so avoid an infinite loop.
	if [ "$mounted" = "/sysroot" ] && ! systemctl --quiet is-active does-not-exist.mount; then
		while systemctl --quiet is-active sysroot.mount; do sleep 0.5; done
	fi
}

read_password()
{
	local password2
	[ -z "$password" ] || return 0
	if ! [ -t 0 ]; then
		read -r -s password
		return "$?"
	fi
        while true; do
                read -r -s -p "Enter encryption passphrase: " password
		echo
		if type -p pwscore &>/dev/null; then
			echo "$password" | pwscore || continue
		fi
                read -r -s -p "Confirm encryption passphrase: " password2
		echo
                if [ "$password" != "$password2" ]; then
                        echo "Entered passwords don't match"
                        continue
                fi
                [ -n "$password" ] || err "No password, no encryption"
                break
        done
}

encrypt()
{
	local encrypt_options=(\
		--reduce-device-size 32m \
		--progress-frequency=1 \
	)
	if [ -e "${ENCRYPTION_CONFIG:-/etc/encrypt_options}" ]; then
		while read -r op; do
			[ "${op//#}" = "$op" ] || continue
			encrypt_options+=("$op")
		done < "${ENCRYPTION_CONFIG:-/etc/encrypt_options}"
	fi
	# sle 15 compat code
	if type -p cryptsetup-reencrypt &> /dev/null; then
		read_password

		echo "$password" | cryptsetup-reencrypt --new --type luks1 "${encrypt_options[@]}" "$@" "${blkpart}"

		log_info "Encryption done"

		log_info "open encrypted image"
		echo "$password" | cryptsetup open "${blkpart}" "$cr_name"
	else
		log_info "encrypt with options ${encrypt_options[*]}"
		if [ -n "$password" ]; then
			# XXX: hopefully we can use the kernel keyring in the future here
			cryptsetup reencrypt --force-password --verbose --encrypt "${encrypt_options[@]}" "$@" "${blkpart}" "$cr_name" <<<"$password"
			[ -z "$gen_key" ] ||  echo '{"type":"systemd-recovery","keyslots":["0"]}' | cryptsetup token import "${blkpart}"
		else
			cryptsetup reencrypt --batch-mode --verify-passphrase --force-password --verbose --encrypt "${encrypt_options[@]}" "$@" "${blkpart}" "$cr_name"
		fi
	fi
	cr_dev="/dev/mapper/$cr_name"
}

call_dracut()
{
	if [ -L "$mp/boot/initrd" ]; then
		local initrd kv
		initrd="$(readlink "$mp/boot/initrd")"
		kv="${initrd#initrd-}"
		log_info "create initrd for $kv"
		chroot "$mp" dracut --add-drivers dm_crypt -q -f "/boot/$initrd" "$kv" "$@"
	elif [ -e "$mp/etc/kernel/entry-token" ]; then
		local token kernel kv
		read -r token < "$mp/etc/kernel/entry-token"
		log_info "token $token"
		for initrd in "$mp/boot/efi/$token"/*/initrd-*; do
			kv="${initrd%/*}"
			kv="${kv##*/}"
			initrd="${initrd#"$mp"}"
			log_info "create $initrd for $kv"
			hostonly_l=no chroot "$mp" dracut -q --reproducible -f "$initrd" "$kv" "$@"
		done
	else
		err "Unsupported boot loader or fs layout"
	fi
}

mountstuff()
{
	mount -t tmpfs -o size=10m tmpfs "$mp/run"
	for i in proc dev sys; do
		mount --bind "/$i" "$mp/$i"
	done

	for i in /.snapshots /boot/efi /boot/writable /var; do
		grep -q "\s$i\s" "$mp/etc/fstab" || continue
		[ -d "$mp/$i" ] || continue
		mountpoint -q "$mp/$i" && continue
		mount -T "$mp"/etc/fstab --target-prefix="$mp" "/$i"
	done
}

make_rw()
{
	local prop
	read -r prop < <(btrfs prop get -t s "$mp" ro)
	[ "$prop" = "ro=true" ] || return 0
	log_info "switch to rw"
	btrfs prop set -t s "$mp" ro false
	switched_rw=1
}

make_ro()
{
	[ -n "$switched_rw" ] || return 0
	unset switched_rw
	log_info "set ro again"
	btrfs prop set -t s "$mp" ro true
}

####### main #######

getopttmp=$(getopt -o hv --long help,verbose,prime,partno:,gen-key -n "${0##*/}" -- "$@")
eval set -- "$getopttmp"

while true ; do
        case "$1" in
                -h|--help) helpandquit ;;
		-v|--verbose) verbose=$((++verbose)); shift ;;
		--prime) prime="1"; shift ;;
		--partno) partno="$2"; shift 2;;
		--gen-key) gen_key="1"; shift;;
                --) shift ; break ;;
                *) echo "Internal error!" ; exit 1 ;;
        esac
done

[ -z "$1" ] && [ -e /etc/initrd-release ] && set -- /sysroot

[ -n "$1" ] || helpandquit

[ -z "$prime" ] && [ -e "/dev/mapper/$cr_name" ] && err "$cr_name exists. Exit."

if [ -d "$1" ] || [ -b "$1" ]; then
	if [ -b "$1" ]; then
		blkpart="$1"
	else
		mountpoint -q "$1" || err "$1 is not a valid mountpoint"
		mp="$1"
		mounted="$1"
		blkpart="$(findmnt -nvo SOURCE "$mp")"
	fi
	[ -L "/sys/class/block/${blkpart##*/}" ] || err "$blkpart is not a partition"
	blkdev="$(readlink -f "/sys/class/block/${blkpart##*/}")"
	blkdev="${blkdev%/*}"
	blkdev="/dev/${blkdev##*/}"
	read -r partno < "/sys/class/block/${blkpart##*/}"/partition
else
	[ -n "$partno" ] || warn "--partno not specified, assuming 3"
	: "${partno:=3}"
	case "${1##*/}" in
		*.raw )
			log_info "setting up loop device"
			blkdev="$(losetup --show -fP "$1")"
			log_info "loop device $blkdev"
			;;
		*.qcow2)
			[ -e "/dev/nbd0" ] || modprobe nbd
			blkdev=/dev/nbd0
			qemu-nbd -c "$blkdev" "$1"
			udevadm settle
			;;
		*) err "Unsupported image" ;;
	esac
	blkpart="${blkdev}p${partno}"
fi
shift

eval "$(blkid -c /dev/null -o export "$blkpart"|sed 's/^/loop_/')"

[ "$loop_TYPE" != crypto_LUKS ] || { echo "Already encrypted"; exit 0; }
[ "$loop_TYPE" = btrfs ] || err "File system is ${loop_TYPE:-unknown} but only btrfs is supported"

if [ -z "$mounted" ]; then
	log_info "mounting fs"
	mkdir -p "$tmpdir/mnt"
	mount -t btrfs -o rw "${blkpart}" "$tmpdir/mnt"
	mp="$tmpdir/mnt"
else
	mountpoint -q "$mp" || err "$mp is not mounted"
	findmnt -o SOURCE,TARGET,FSTYPE,OPTIONS -Rvn --pairs "$mp" > "$tmpdir/mounts"
	mount -o remount,rw "$mp"
fi

if [ -n "$prime" ]; then
	mkdir -p "$tmpdir/overlay-w"
	dst="$tmpdir/overlay/95disk-encryption-tool"
	mkdir -p "$dst"
	for i in disk-encryption-tool disk-encryption-tool-dracut module-setup.sh \
			disk-encryption-tool-dracut.service generate-recovery-key; do
		cp "${0%/*}/$i" "$dst/$i"
	done
	if [ -e "${ENCRYPTION_CONFIG:-/etc/encrypt_options}" ]; then
		cp "${ENCRYPTION_CONFIG:-/etc/encrypt_options}" "$dst/encrypt_options"
		export ENCRYPTION_CONFIG="/usr/lib/dracut/modules.d/95disk-encryption-tool/encrypt_options"
	fi

	make_rw

	mountstuff

	# dirty
	if [ -d "$mp/usr/share/jeos-firstboot/modules" ]; then
		install -D -m 644 "${0%/*}/jeos-firstboot-diskencrypt-override.conf" "$mp/usr/lib/systemd/system/jeos-firstboot.service.d/jeos-firstboot-diskencrypt-override.conf"
		cp "${0%/*}/jeos-firstboot-enroll" "$mp/usr/share/jeos-firstboot/modules/enroll"
	fi

	mount -t overlay overlay \
		-o lowerdir="$mp/usr/lib/dracut/modules.d/,upperdir=$tmpdir/overlay,workdir=$tmpdir/overlay-w" \
		"$mp/usr/lib/dracut/modules.d/"

	call_dracut

	exit 0
fi

read -r minsize bytes _rest < <(btrfs inspect-internal min-dev-size "$mp")
isdigits "$minsize" || err "Failed to read minimum btrfs size"
[ "$bytes" = 'bytes' ] || err "Failed to read minimum btrfs size"

log_info "resizing fs"
btrfs filesystem resize "$minsize" "$mp"

if [ -e "$tmpdir/mounts" ]; then
	# subshell intentional here
	tac "$tmpdir/mounts" | while read -r line; do
		eval "$line"
		umount "$TARGET"
	done
else
	umount "$mp"
fi
unset mp

settle_umount_events

# shrink partition to a minimum so reencryption doesn't write everything
log_info "resizing partition"
echo "size=$((minsize/1024+32*1024))KiB" | sfdisk -q -N "$partno" "$blkdev"
udevadm settle

if [ -n "$gen_key" ]; then
	read -r password < <(generate-recovery-key)
	echo -e "Recovery key: \e[1m$password\e[m"
	if [ -e /etc/initrd-release ]; then
		read -r key_id < <(echo -n "$password" | keyctl padd user cryptenroll @u)
	fi
fi

echo "Encrypting..."
encrypt "$@"

log_info "grow partition again"
echo ", +" | sfdisk --no-reread -q -N "$partno" "$blkdev" &> /dev/null
if [ -e /etc/initrd-release ]; then
	# seems to be the only way to tell the kernel about a specific partition change
	partx -u --nr "$partno" "$blkdev" || :
	cryptsetup resize "$cr_name" <<<"$password"
fi

if [ -z "$mounted" ]; then
	mount -o rw "$cr_dev" "/mnt"
	mp="/mnt"
else
	read -r line < "$tmpdir/mounts"
	eval "$line"
	mapfile -td, options < <(echo -n "$OPTIONS")
	for ((i=0;i<${#options};++i)); do [ "${options[i]}" = ro ] && options[i]=rw; done
	OPTIONS="$(IFS=, eval echo '"${options[*]}"')"
	[ "$SOURCE" = "$blkpart" ] && SOURCE="$cr_dev"
	mount "$cr_dev" "$TARGET" -t "$FSTYPE" -o "$OPTIONS"
	mp="$TARGET"
fi

log_info "resizing fs to max again"
btrfs filesystem resize max "$mp"

make_rw

declare loop_UUID
eval "$(blkid -c /dev/null -o export "$blkpart"|sed 's/^/loop_/')"
if [ -n "$loop_UUID" ]; then
	echo "$cr_name /dev/disk/by-uuid/$loop_UUID none x-initrd.attach" > "$mp"/etc/crypttab
else
	warn "Can't determine device UUID. Can't generate crypttab"
fi

mountstuff

if grep -q "LOADER_TYPE.*grub2" "$mp"/etc/sysconfig/bootloader; then
	log_info "Update bootloader"

	echo GRUB_ENABLE_CRYPTODISK=y >> "$mp"/etc/default/grub

	sed -i -e 's/^LOADER_TYPE=.*/LOADER_TYPE="grub2"/' "$mp"/etc/sysconfig/bootloader
	chroot "$mp" update-bootloader --reinit
	sed -i -e 's/^LOADER_TYPE=.*/LOADER_TYPE="grub2-efi"/' "$mp"/etc/sysconfig/bootloader
	chroot "$mp" update-bootloader --reinit
	mv "$mp/boot/grub2/grub.cfg" "$mp/boot/grub2/grub.cfg.bak"
	cat > "$mp/boot/grub2/grub.cfg" <<-'EOF'
	set linux=linux
	set initrd=initrd
	if [ "${grub_cpu}" = "x86_64" -o "${grub_cpu}" = "i386" ]; then
	    if [ "${grub_platform}" = "efi" ]; then
		set linux=linuxefi
		set initrd=initrdefi
	    fi
	fi
	export linux initrd
	EOF
	sed -e 's/linuxefi/$linux/;s/initrdefi/$initrd/' < "$mp/boot/grub2/grub.cfg.bak" >> "$mp/boot/grub2/grub.cfg"
	rm "$mp/boot/grub2/grub.cfg.bak"
elif [ -e "$mp/etc/kernel/entry-token" ]; then
	: # sd-boot
else
	log_info "unsupported boot loader"
	grep LOADER_TYPE "$mp"/etc/sysconfig/bootloader
fi

# A new initrd is created as side effect of the enrolment
# (jeos-firtboot module), as this calls sdbootutil

make_ro

echo "Image encryption completed"
07070100000008000081ED00000000000000000000000166CC4624000004EA000000000000000000000000000000000000004700000000disk-encryption-tool-1+git20240826.c956112/disk-encryption-tool-dracut#!/bin/sh

exec < /dev/console >/dev/console 2>&1
type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh

# get systemd credential
# https://systemd.io/CREDENTIALS/
get_credential()
{
	local var="${1:?}"
	local name="${2:?}"
	[ -n "$CREDENTIALS_DIRECTORY" ] || return 1
	[ -e "$CREDENTIALS_DIRECTORY/$name" ] || return 1
	read -r "$var" < "$CREDENTIALS_DIRECTORY/$name" || [ -n "${!var}" ]
}

encrypt=
if get_credential encrypt disk-encryption-tool-dracut.encrypt && [ "$encrypt" = "no" ]; then
	exit 0
fi

# check whether encryption was explicitly turned off
if ! getargbool 1 rd.encrypt; then
	exit 0
fi

# XXX: this is so dirty
systemctl start sysroot.mount
mount --target-prefix /sysroot --fstab /sysroot/etc/fstab /var
if [ ! -e /sysroot/var/lib/YaST2/reconfig_system ] && [ "$encrypt" != "force" ]; then
	echo "system already configured, no encryption"
	umount /sysroot/var
	exit 0
fi
umount /sysroot/var

# silence systemd
kill -SIGRTMIN+21 1
inhibitor=
if [ "$encrypt" != "force" ]; then
	echo -ne '\n\n\a'
	read -n1 -s -r -t 10 -p "*** Press ESC to prevent encrypting the disk" inhibitor
	echo
fi
if [ "$inhibitor" != $'\e' ]; then
	/usr/bin/disk-encryption-tool -v --gen-key || die "Encryption failed"
fi
# turn messages on again
kill -SIGRTMIN+20 1
07070100000009000081A400000000000000000000000166CC462400000355000000000000000000000000000000000000004F00000000disk-encryption-tool-1+git20240826.c956112/disk-encryption-tool-dracut.service[Unit]
Description=Encrypt root disk
DefaultDependencies=false

# /sysroot needs to be available, but it's temporarily stopped
# for remounting so a direct requirement is not possible
Requires=initrd-root-device.target
After=initrd-root-device.target

After=combustion.service

# After ignition completed its stuff
After=ignition-complete.target

# So that /etc/fstab's x-initrd.mount entries are read (again) later
Before=initrd-parse-etc.service

Conflicts=initrd-switch-root.target umount.target
Conflicts=dracut-emergency.service emergency.service emergency.target

# Without this it goes into an endless loop on failure
OnFailure=emergency.target
OnFailureJobMode=isolate

[Service]
Type=oneshot
KeyringMode=shared
ExecStart=/usr/bin/disk-encryption-tool-dracut
ImportCredential=disk-encryption-tool-dracut.*

[Install]
RequiredBy=firstboot.target
0707010000000A000081ED00000000000000000000000166CC462400000895000000000000000000000000000000000000004700000000disk-encryption-tool-1+git20240826.c956112/disk-encryption-tool-enroll#!/bin/bash

get_credential() {
	local var="${1:?}"
	local name="${2:?}"
	local keyid
	keyid="$(keyctl id %user:"$name" 2> /dev/null)" || true

	if [ -e "$CREDENTIALS_DIRECTORY/$name" ]; then
		read -r "$var" < "$CREDENTIALS_DIRECTORY/$name"
	elif [ -n "$keyid" ]; then
		read -r "$var" <<< "$(keyctl pipe "$keyid")"
	fi
}

have_luks2() {
	lsblk --noheadings -o PATH,FSTYPE | grep -q crypto_LUKS
}

write_issue_file() {
	if [ -e '/usr/sbin/issue-generator' ]; then
		mkdir -p "/run/issue.d/"
		issuefile="/run/issue.d/90-diskencrypt.conf"
	else
		issuefile='/dev/stdout'
	fi

	echo -ne "Encryption recovery key:\n  " > "$issuefile"
	keyctl pipe "$crypt_keyid" >> "$issuefile"
	echo -e "\n" >> "$issuefile"
	if [ -x /usr/bin/qrencode ]; then
		echo "You can also scan it with your mobile phone:" >> "$issuefile"
		keyctl pipe "$crypt_keyid" | qrencode -t utf8i >> "$issuefile"
	fi

	issue-generator
}


[ ! -e "/var/lib/YaST2/reconfig_system" ] || exit 0
have_luks2 || exit 0
crypt_keyid="$(keyctl id %user:cryptenroll 2> /dev/null)" || exit 0
[ -n "$crypt_keyid" ] || {
	echo "Recovery key not registered in the keyring. Aborting" > /dev/stderr
	exit 1
}

write_issue_file

# Proceed with the enrollment

pw=
get_credential pw "disk-encryption-tool-enroll.pw"

tpm2_pin=
get_credential tpm2_pin "disk-encryption-tool-enroll.tpm2+pin"

tpm2=
get_credential tpm2 "disk-encryption-tool-enroll.tpm2"

fido2=
get_credential fido2 "disk-encryption-tool-enroll.fido2"

[ -z "$pw" ] || {
	echo "Enrolling password"
	# Note that if --no-reuse-initrd is used, then a new initrd
	# will be created and will break the measurement of the
	# initial components if later the TPM2 enrollment is called
	extra=
	if [ -z "$tpm2_pin" ] && [ -z "$tpm2" ] && [ -z "$fido2" ]; then
		extra="--no-reuse-initrd"
	fi
	PW="$pw" sdbootutil enroll --method=password "$extra"
}

if [ -n "$tpm2_pin" ]; then
	echo "Enrolling TPM2 with PIN"
	SDB_ADD_INITIAL_COMPONENT=1 PIN="$crypt_tpm_pin" sdbootutil enroll --method=tpm2+pin
elif [ -n "$tpm2" ]; then
	echo "Enrolling TPM2"
	SDB_ADD_INITIAL_COMPONENT=1 sdbootutil enroll --method=tpm2
fi

[ -z "$fido2" ] || {
	echo "Enrolling a FIDO2 key"
	sdbootutil enroll --method=fido2
}
0707010000000B000081A400000000000000000000000166CC462400000158000000000000000000000000000000000000004F00000000disk-encryption-tool-1+git20240826.c956112/disk-encryption-tool-enroll.service[Unit]
Description=Enroll encrypted root disk 
DefaultDependencies=false

After=jeos-firstboot.service
#ConditionPathExists=/var/lib/YaST2/enroll_system

[Service]
Type=oneshot
RemainAfterExit=yes
KeyringMode=shared
ExecStart=/usr/bin/disk-encryption-tool-enroll
ImportCredential=disk-encryption-tool-enroll.*

[Install]
WantedBy=default.target0707010000000C000081A400000000000000000000000166CC462400000E7C000000000000000000000000000000000000004500000000disk-encryption-tool-1+git20240826.c956112/disk-encryption-tool.spec#
# spec file for package disk-encryption-tool
#
# Copyright (c) 2024 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.

# Please submit bugfixes or comments via https://bugs.opensuse.org/
#
# icecream 0

%if 0%{?_build_in_place}
%define git_version %(git log '-n1' '--date=format:%Y%m%d' '--no-show-signature' "--pretty=format:+git%cd.%h")
BuildRequires:  git-core
%else
# this is required for obs' source validator. It's
# 20-files-present-and-referenced ignores all conditionals. So the
# definition of git_version actually happens always.
%define git_version %{nil}
%endif

Name:           disk-encryption-tool
Version:        84.87%{git_version}
Release:        0
Summary:        Tool to reencrypt kiwi raw images
License:        MIT
URL:            https://github.com/lnussel/disk-encryption-tool
Source:         disk-encryption-tool-%{version}.tar
BuildRequires:  systemd-rpm-macros
Requires:       cryptsetup
Requires:       keyutils
Requires:       pcr-oracle
# something needs to require it. Can be us.
Requires:       tpm2.0-tools
Requires:       qrencode
ExclusiveArch:  aarch64 ppc64le riscv64 x86_64
BuildArch:      noarch
%{?systemd_requires}

%description
Convert a plain text kiwi image into one with LUKS full disk
encryption. Supports both raw and qcow2 images. It assumes that the
third partition is the root fs using btrfs.
After encrypting the disk, the fs is mounted and a new initrd
created as well as the grub2 config adjusted.

%prep
%setup -q

%build

%install
mkdir -p %buildroot/usr/lib/dracut/modules.d/95disk-encryption-tool
for i in disk-encryption-tool{,-dracut,-dracut.service} module-setup.sh generate-recovery-key; do
  cp "$i" %buildroot/usr/lib/dracut/modules.d/95disk-encryption-tool/"$i"
done
mkdir -p %buildroot/usr/bin
ln -s ../lib/dracut/modules.d/95disk-encryption-tool/disk-encryption-tool %buildroot/usr/bin
ln -s ../lib/dracut/modules.d/95disk-encryption-tool/generate-recovery-key %buildroot/usr/bin
install -D -m 644 jeos-firstboot-diskencrypt-override.conf \
	%{buildroot}/usr/lib/systemd/system/jeos-firstboot.service.d/jeos-firstboot-diskencrypt-override.conf
install -D -m 644 jeos-firstboot-enroll %buildroot/usr/share/jeos-firstboot/modules/enroll
install -m 755 disk-encryption-tool-enroll %buildroot/usr/bin/disk-encryption-tool-enroll
install -D -m 644 disk-encryption-tool-enroll.service %buildroot/%{_unitdir}/disk-encryption-tool-enroll.service

%preun
%service_del_preun disk-encryption-tool-enroll.service

%postun
%service_del_postun disk-encryption-tool-enroll.service

%pre
%service_add_pre disk-encryption-tool-enroll.service

%post
%service_add_post disk-encryption-tool-enroll.service

%files
%license LICENSE
/usr/bin/disk-encryption-tool
/usr/bin/disk-encryption-tool-enroll
/usr/bin/generate-recovery-key
%dir /usr/lib/dracut
%dir /usr/lib/dracut/modules.d
/usr/lib/dracut/modules.d/95disk-encryption-tool
%dir /usr/share/jeos-firstboot
%dir /usr/share/jeos-firstboot/modules
/usr/share/jeos-firstboot/modules/enroll
%dir /usr/lib/systemd/system/jeos-firstboot.service.d
/usr/lib/systemd/system/jeos-firstboot.service.d/jeos-firstboot-diskencrypt-override.conf
%{_unitdir}/disk-encryption-tool-enroll.service

%changelog

0707010000000D000081ED00000000000000000000000166CC4624000001C9000000000000000000000000000000000000004100000000disk-encryption-tool-1+git20240826.c956112/generate-recovery-key#!/bin/bash
set -e
modhex=('c' 'b' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'n' 'r' 't' 'u' 'v')
mapfile -t raw_key < <(hexdump -v --format '1/1 "%u\n"' -n 32 /dev/random)
[ "${#raw_key[@]}" = 32 ]
key=""
for ((i=0;i<"${#raw_key[@]}";++i)); do
	[ "$i" -gt 0 ] && [ "$((i%4))" -eq 0 ] && key="$key-"
	c="${raw_key[i]}"
	key="$key${modhex[$((c>>4))]}${modhex[$((c&15))]}"
done
[ -x /usr/bin/qrencode ] && [ -t 1 ] && echo -n "$key" | qrencode -t utf8i
echo "$key"
0707010000000E000081A400000000000000000000000166CC46240000001D000000000000000000000000000000000000005400000000disk-encryption-tool-1+git20240826.c956112/jeos-firstboot-diskencrypt-override.conf[Service]
KeyringMode=shared
0707010000000F000081A400000000000000000000000166CC462400001170000000000000000000000000000000000000004100000000disk-encryption-tool-1+git20240826.c956112/jeos-firstboot-enroll#!/bin/bash

crypt_keyid=""
crypt_pw=""
crypt_tpm_pin=""
# for pin
cryptenroll_tpm_extra_args=()

with_fido2=
with_tpm2=

luks2_devices=()


have_luks2() {
	lsblk --noheadings -o PATH,FSTYPE | grep -q crypto_LUKS
}

# exit early without defining any helper functions if there are no luks devices
have_luks2 || return 0

enroll_systemd_firstboot() {
	[ -e /usr/bin/systemd-cryptenroll ] || return 0
	crypt_keyid="$(keyctl id %user:cryptenroll 2> /dev/null)" || return 0
	[ -n "$crypt_keyid" ] || return 0

	welcome_screen_with_console_switch

	local has_fido2=${JEOS_HAS_FIDO2:-}
	local has_tpm2=

	[ -z "$(systemd-cryptenroll --fido2-device=list 2>/dev/null)" ] || has_fido2=1
	[ ! -e '/sys/class/tpm/tpm0' ] || has_tpm2=lock

	while true; do
		local list=()

		if [ -z "$with_fido2" ] && [ -z "$with_tpm2" ] && [ -n "$has_fido2" ]; then
			list+=('FIDO2' $'Enroll FIDO2 token')
		fi
		if [ -z "$with_tpm2" ] && [ -z "$with_fido2" ] && [ -n "$has_tpm2" ]; then
			list+=('TPM2' $'Enroll TPM2 based token' 'TPM2_interactive' 'Enroll TPM2 based token with PIN')
		fi
		if [ -z "$crypt_pw" ]; then
			if [ -n "$password" ]; then
				list+=('root' $'Enroll root password')
			fi
			list+=('password' $'Enroll extra password')
		fi
		[ -n "$list" ] || break

		list+=('done' $'Done')

		d --no-tags --default-item "${list[0]}" --menu $"Disk Encryption" 0 0 "$(menuheight ${#list[@]})" "${list[@]}"
		if [ "$result" = 'done' ]; then
			if [ -z "$crypt_pw" ] && [ -z "$with_fido2" ] && [ -z "$with_tpm2" ] && [ -z "$is_jeos_config" ]; then
				d_styled --yesno $"Neither password, TPM2 nor FIDO2 entrolled. Unlocking disk will only work with recovery key. Is this intended?" 0 0 || continue
			fi
			break;
		elif [ "$result" = 'FIDO2' ]; then
			with_fido2=1
		elif [ "$result" = 'TPM2' ]; then
			with_tpm2="$has_tpm2"
		elif [ "$result" = 'TPM2_interactive' ]; then
			while true; do
				d --insecure --passwordbox  $"Enter new PIN (actually just passphrase)" 0 0
				if [ -z "$result" ]; then
					d_styled --yesno $"Retry?" 0 0 || break
					continue
				fi
				crypt_tpm_pin="$result"
				d --insecure --passwordbox  $"Confirm PIN" 0 0
				[ "$crypt_tpm_pin" != "$result" ] || { with_tpm2="$has_tpm2"; break; }
				d --msgbox $"PINs don't match. Try again" 0 0
			done

		elif [ "$result" = 'root' ]; then
			crypt_pw="$password"
		elif [ "$result" = 'password' ]; then
			while true; do
				d --insecure --passwordbox  $"Enter encryption password" 0 0
				if [ -z "$result" ]; then
					d --aspect 29 --msgbox $"No encryption password set. You can add more keys manually using systemd-cryptenroll." 0 0
					break
				fi
				crypt_pw="$result"
				d --insecure --passwordbox  $"Confirm encryption password" 0 0
				[ "$crypt_pw" != "$result" ] || break
				d --msgbox $"Passwords don't match. Try again" 0 0
			done
		else
			d --msgbox "Error: $result" 0 0
		fi
	done

	return 0
}

write_issue_file() {
	if [ -e '/usr/sbin/issue-generator' ] && [ -z "$dry" ]; then
		mkdir -p "/run/issue.d/"
		issuefile="/run/issue.d/90-diskencrypt.conf"
	else
		issuefile='/dev/stdout'
	fi

	echo -ne "Encryption recovery key:\n  " > "$issuefile"
	keyctl pipe "$crypt_keyid" >> "$issuefile"
	echo -e "\n" >> "$issuefile"
	if [ -x /usr/bin/qrencode ]; then
		echo "You can also scan it with your mobile phone:" >> "$issuefile"
		keyctl pipe "$crypt_keyid" | qrencode -t utf8i >> "$issuefile"
	fi

	run issue-generator
}

enroll_post() {
	[ -e /usr/bin/systemd-cryptenroll ] || return 0
	[ -n "$crypt_keyid" ] || return 0

	write_issue_file
	do_enroll
}

do_enroll() {
	[ -z "$crypt_pw" ] || {
		# Note that if --no-reuse-initrd is used, then a new
		# initrd will be created and will break the
		# measurement of the initial components if later the
		# TPM2 enrollment is called
		extra=
		if [ -z "$with_tpm2" ] && [ -z "$with_fido2" ]; then
			extra="--no-reuse-initrd"
		fi
		PW="$crypt_pw" run sdbootutil enroll --method=password "$extra"
	}

	if [ -n "$with_tpm2" ]; then
		if [ -n "$crypt_tpm_pin" ]; then
			SDB_ADD_INITIAL_COMPONENT=1 PIN="$crypt_tpm_pin" run sdbootutil enroll --method=tpm2+pin
		else
			SDB_ADD_INITIAL_COMPONENT=1 run sdbootutil enroll --method=tpm2
		fi
	fi

	[ -z "$with_fido2" ] || run sdbootutil enroll --method=fido2
}

enroll_jeos_config() {
	is_jeos_config=1
	d --insecure --passwordbox  $"Enter decryption password" 0 0
	[ -n "$result" ] || return 0
	echo -n "$result" | keyctl padd user cryptenroll @u

	enroll_systemd_firstboot
	do_enroll
}
07070100000010000081ED00000000000000000000000166CC4624000003F5000000000000000000000000000000000000003B00000000disk-encryption-tool-1+git20240826.c956112/module-setup.sh#!/bin/bash

# called by dracut
check() {
	require_any_binary cryptsetup || return 1
	return 0
}

# called by dracut
depends() {
	echo "crypt"
	return 0
}

# called by dracut
install() {
	instmods dmi_sysfs # for systemd credentials via smbios
	inst_multiple -o cryptsetup-reencrypt
	inst_multiple cryptsetup btrfs mktemp getopt mountpoint findmnt sfdisk tac sed hexdump keyctl partx

	inst_script "$moddir"/disk-encryption-tool /usr/bin/disk-encryption-tool
	inst_script "$moddir"/disk-encryption-tool-dracut /usr/bin/disk-encryption-tool-dracut
	inst_script "$moddir"/generate-recovery-key /usr/bin/generate-recovery-key

	for service in "disk-encryption-tool-dracut.service"; do
		inst_simple "${moddir}/$service" "${systemdsystemunitdir}/$service"
		$SYSTEMCTL -q --root "$initdir" enable "$service"
		#$SYSTEMCTL -q --root "$initdir" enable "debug-shell.service"
	done

	: "${ENCRYPTION_CONFIG:=/etc/encrypt_options}"
	[ -e "$ENCRYPTION_CONFIG" ] && inst_simple "$ENCRYPTION_CONFIG" "/etc/encrypt_options"
}
07070100000011000041ED00000000000000000000000266CC462400000000000000000000000000000000000000000000003000000000disk-encryption-tool-1+git20240826.c956112/test07070100000012000081A400000000000000000000000166CC46240000029D000000000000000000000000000000000000003B00000000disk-encryption-tool-1+git20240826.c956112/test/config.ign{
  "ignition": {
    "version": "3.2.0"
  },
  "passwd": {
    "users": [
      {
        "name": "root",
        "passwordHash": "$2a$10$IGzLVVX6jfMoe4Qoog2v.e24woQJiys9Doe8.taWrqdDkZyrXiGZu"
      }
    ]
  },
  "storage": {
    "filesystems": [
      {
        "device": "/dev/disk/by-label/ROOT",
        "format": "btrfs",
        "mountOptions": [
          "subvol=/@/home"
        ],
        "path": "/home",
        "wipeFilesystem": false
      }
    ],
    "files": [
      {
        "path": "/etc/locale.conf",
        "mode": 420,
        "overwrite": true,
        "contents": {
          "source": "data:,LANG=en_US.UTF-8"
        }
      }
    ]
  }
}
07070100000013000081ED00000000000000000000000166CC46240000104B000000000000000000000000000000000000003800000000disk-encryption-tool-1+git20240826.c956112/test/test.sh#!/bin/bash
set -euxo pipefail

# Some basic combustion testing:
# 1. Download the latest MicroOS image
# 2. Use its combustion to install the disk-encryption-tool to test and transfer kernel + initrd to the host using 9pfs
# 3. Revert the image to the original state and perform tests using the generated kernel + initrd

# Skip the generation of a new initrd with the changed disk-encryption-tool.
# Only useful when iterating this test script.
reuseinitrd=
if [ "${1-}" = "--reuseinitrd" ]; then
	reuseinitrd=1
	shift
fi

# Working dir which is also exposed to the VM through 9pfs.
# If not specified, create a temporary directory which is deleted on exit.
if [ -n "${1-}" ]; then
	tmpdir="$(realpath "$1")"
else
	tmpdir="$(mktemp -d)"
	cleanup() {
		rm -rf "$tmpdir"
	}
	trap cleanup EXIT
fi

QEMU_BASEARGS=(
	# -accel tcg was here after -accel kvm but the fallback hid a weird bug
	# that in GH actions only the first instance of QEMU was able to access /dev/kvm.
	-accel kvm -cpu host -nographic -m 1024
	# Reading from stdin doesn't work, configure serial and monitor appropriately.
	-chardev null,id=serial,logfile=/dev/stdout,logappend=on -serial chardev:serial -monitor none
	-virtfs "local,path=${tmpdir},mount_tag=tmpdir,security_model=none")

if [ -e /usr/share/qemu/ovmf-x86_64-code.bin ]; then
	QEMU_BASEARGS+=(-bios /usr/share/qemu/ovmf-x86_64-code.bin)
elif [ -e /usr/share/qemu/OVMF.fd ]; then
	QEMU_BASEARGS+=(-bios /usr/share/qemu/OVMF.fd)
else
	echo "No OVMF found"
	exit 1
fi

# Prepare the temporary dir: Install disk-encryption-tool and copy resources.
testdir="$(dirname "$0")"
# TODO: Use a Makefile for this and in the .spec file.
mkdir -p "${tmpdir}/install/usr/lib/dracut/modules.d/95disk-encryption-tool"
for i in disk-encryption-tool{,-dracut,-dracut.service} module-setup.sh generate-recovery-key; do
	cp "${testdir}/../${i}" "${tmpdir}/install/usr/lib/dracut/modules.d/95disk-encryption-tool/${i}"
done
cp "${testdir}/"{testscript,config.ign} "${tmpdir}"
cd "$tmpdir"

# Download latest MicroOS image
if ! [ -f openSUSE-MicroOS.x86_64-kvm-and-xen-sdboot.qcow2 ]; then
	wget --progress=bar:force:noscroll https://download.opensuse.org/tumbleweed/appliances/openSUSE-MicroOS.x86_64-kvm-and-xen-sdboot.qcow2
	qemu-img snapshot -c initial openSUSE-MicroOS.x86_64-kvm-and-xen-sdboot.qcow2
else
	qemu-img snapshot -a initial openSUSE-MicroOS.x86_64-kvm-and-xen-sdboot.qcow2
fi

# First step: Use combustion in the downloaded image to generate an initrd with the new disk-encryption-tool.
if ! [ -n "${reuseinitrd}" ] || ! [ -e "${tmpdir}/vmlinuz" ] || ! [ -e "${tmpdir}/initrd" ]; then
	rm -f "${tmpdir}/done"
	cat >create-initrd <<'EOF'
#!/bin/bash
set -euxo pipefail
exec &>/dev/ttyS0
trap '[ $? -eq 0 ] || poweroff -f' EXIT
mount -t 9p -o trans=virtio tmpdir /mnt
# Install new disk-encryption-tool, make sure the old remnants are gone
rpm -e --nodeps --noscripts disk-encryption-tool
cp -av /mnt/install/usr /
cp /usr/lib/modules/$(uname -r)/vmlinuz /mnt/vmlinuz
dracut -f --no-hostonly /mnt/initrd
touch /mnt/done
umount /mnt
SYSTEMD_IGNORE_CHROOT=1 poweroff -f
EOF

	timeout 300 qemu-system-x86_64 "${QEMU_BASEARGS[@]}" -drive if=virtio,file=openSUSE-MicroOS.x86_64-kvm-and-xen-sdboot.qcow2 \
		-fw_cfg name=opt/org.opensuse.combustion/script,file=create-initrd

	if ! [ -e "${tmpdir}/done" ]; then
		echo "Initrd generation failed"
		exit 1
	fi
fi

# Test using a config drive
rm -f "${tmpdir}/done"
qemu-img snapshot -a initial openSUSE-MicroOS.x86_64-kvm-and-xen-sdboot.qcow2

rm -rf configdrv
mkdir -p configdrv/combustion/
cp testscript configdrv/combustion/script
mkdir -p configdrv/ignition/
cp config.ign configdrv/ignition/config.ign
/sbin/mkfs.ext4 -F -d configdrv -L ignition combustion.raw 16M

timeout 300 qemu-system-x86_64 "${QEMU_BASEARGS[@]}" -drive if=virtio,file=openSUSE-MicroOS.x86_64-kvm-and-xen-sdboot.qcow2 \
	-kernel vmlinuz -initrd initrd -append "root=LABEL=ROOT console=ttyS0 quiet systemd.show_status=1 systemd.log_target=console systemd.journald.forward_to_console=1 rd.emergency=poweroff rd.shell=0" \
	-drive if=virtio,file=combustion.raw

if ! [ -e "${tmpdir}/done" ]; then
	echo "Test failed"
	exit 1
fi
07070100000014000081A400000000000000000000000166CC462400000A86000000000000000000000000000000000000003B00000000disk-encryption-tool-1+git20240826.c956112/test/testscript#!/bin/bash
# combustion: prepare
set -euxo pipefail
exec &>/dev/ttyS0

# Poweroff immediately on any failure to avoid unnecessary waiting.
trap '[ $? -eq 0 ] || poweroff -f' EXIT

if [ "${1-}" = "--prepare" ]; then
	# We set disk-encryption-tool-dracut.encryption credential to
	# "force".  This will make disk-encryption-tool-dracut force the
	# encryption, ignoring that Combusion configured the system, and
	# will skip the permission countdown
	#
	# After the encryption the recovery key is registered in the
	# kernel keyring %user:cryptenroll
	mkdir -p /run/credstore
	echo "force" > /run/credstore/disk-encryption-tool-dracut.encrypt
	exit 0
fi

# Create a valid machine-id, as this will be required to create later
# the host secret
systemd-machine-id-setup

# We want to persist the host secret key created via systemd-cred
# (/var/lib/systemd/credential.secret)
mount /var

mkdir -p /etc/credstore.encrypted
credential="$(mktemp disk-encryption-tool.XXXXXXXXXX)"

# Enroll extra password
# echo "SECRET_PASSWORD" > "$credential"
echo "linux" > "$credential"
systemd-creds encrypt --name=disk-encryption-tool-enroll.pw "$credential" \
	      /etc/credstore.encrypted/disk-encryption-tool-enroll.pw

# # Enroll TPM2 with secret PIN
# echo "SECRET_PIN" > "$credential"
# systemd-creds encrypt --name=disk-encryption-tool-enroll.tpm2+pin "$credential" \
# 	      /etc/credstore.encrypted/disk-encryption-tool-enroll.tpm2+pin

# # Enroll TPM2
# echo "1" > "$credential"
# systemd-creds encrypt --name=disk-encryption-tool-enroll.tpm2 "$credential" \
# 	      /etc/credstore.encrypted/disk-encryption-tool-enroll.tpm2

# # Enroll FIDO2
# echo "1" > "$credential"
# systemd-creds encrypt --name=disk-encryption-tool-enroll.fido2 "$credential" \
# 	      /etc/credstore.encrypted/disk-encryption-tool-enroll.fido2

shred -u "$credential"

# Umount back /var to not confuse tukit later
umount /var

# Keyboard
systemd-firstboot --force --keymap=es

# Make sure that the system comes up good, leave a marker in the shared FS
# and power off the VM.
cat >>/usr/bin/combustion-validate <<'EOF'
#!/bin/bash
set -euxo pipefail
exec &>/dev/ttyS0
trap '[ $? -eq 0 ] || poweroff -f' EXIT
findmnt
lsblk
if [ "$(findmnt -nrvo SOURCE /)" != "/dev/mapper/cr_root" ]; then
	echo "Not encrypted?"
	exit 1
fi
mount -t 9p -o trans=virtio tmpdir /mnt
touch /mnt/done
umount /mnt
poweroff -f
EOF
chmod a+x /usr/bin/combustion-validate

cat >>/etc/systemd/system/combustion-validate.service <<'EOF'
[Service]
ExecStart=/usr/bin/combustion-validate
[Install]
RequiredBy=default.target
EOF
systemctl enable combustion-validate.service

# Leave a marker
echo "Configured with combustion" > /etc/issue.d/combustion
07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!81 blocks
openSUSE Build Service is sponsored by