Merge pull request #27912 from mrc0mmand/cryptsetup-tests
test: add a couple more tests for systemd-cryptsetup
This commit is contained in:
@@ -234,7 +234,7 @@ static int parse_one_option(const char *option) {
|
||||
return log_oom();
|
||||
|
||||
} else if ((val = startswith(option, "header="))) {
|
||||
if (!STR_IN_SET(arg_type, ANY_LUKS, CRYPT_LUKS1, CRYPT_LUKS2, CRYPT_TCRYPT))
|
||||
if (!arg_type || !STR_IN_SET(arg_type, ANY_LUKS, CRYPT_LUKS1, CRYPT_LUKS2, CRYPT_TCRYPT))
|
||||
arg_type = ANY_LUKS;
|
||||
|
||||
if (!path_is_absolute(val))
|
||||
|
||||
@@ -18,7 +18,7 @@ if ! get_bool "${TEST_PREFER_NSPAWN:=}"; then
|
||||
TEST_NO_NSPAWN=1
|
||||
fi
|
||||
|
||||
command -v dfuzzer >/dev/null || exit 0
|
||||
test_require_bin dfuzzer
|
||||
|
||||
if ! get_bool "$IS_BUILT_WITH_ASAN"; then
|
||||
echo "systemd is built without ASan, skipping..."
|
||||
|
||||
@@ -4,6 +4,7 @@ set -e
|
||||
|
||||
TEST_DESCRIPTION="cryptsetup systemd setup"
|
||||
IMAGE_NAME="cryptsetup"
|
||||
IMAGE_ADDITIONAL_DATA_SIZE=100
|
||||
TEST_NO_NSPAWN=1
|
||||
TEST_FORCE_NEWIMAGE=1
|
||||
|
||||
@@ -12,28 +13,29 @@ TEST_FORCE_NEWIMAGE=1
|
||||
|
||||
PART_UUID="deadbeef-dead-dead-beef-000000000000"
|
||||
DM_NAME="test24_varcrypt"
|
||||
KERNEL_APPEND+=" rd.luks=1 luks.name=$PART_UUID=$DM_NAME luks.key=$PART_UUID=/keyfile:LABEL=varcrypt_keydev"
|
||||
KERNEL_OPTIONS=(
|
||||
"rd.luks=1"
|
||||
"luks.name=$PART_UUID=$DM_NAME"
|
||||
"luks.key=$PART_UUID=/keyfile:LABEL=varcrypt_keydev"
|
||||
"luks.options=$PART_UUID=x-initrd.attach"
|
||||
)
|
||||
KERNEL_APPEND+=" ${KERNEL_OPTIONS[*]}"
|
||||
QEMU_OPTIONS+=" -drive format=raw,cache=unsafe,file=${STATEDIR:?}/keydev.img"
|
||||
|
||||
check_result_qemu() {
|
||||
local ret=1
|
||||
local ret
|
||||
|
||||
mount_initdir
|
||||
[[ -e "${initdir:?}/testok" ]] && ret=0
|
||||
[[ -f "$initdir/failed" ]] && cp -a "$initdir/failed" "${TESTDIR:?}"
|
||||
|
||||
cryptsetup luksOpen "${LOOPDEV:?}p2" "${DM_NAME:?}" <"$TESTDIR/keyfile"
|
||||
mount "/dev/mapper/$DM_NAME" "$initdir/var"
|
||||
save_journal "$initdir/var/log/journal"
|
||||
check_coverage_reports "${initdir:?}" || ret=5
|
||||
|
||||
check_result_common "${initdir:?}" && ret=0 || ret=$?
|
||||
|
||||
_umount_dir "$initdir/var"
|
||||
_umount_dir "$initdir"
|
||||
cryptsetup luksClose "/dev/mapper/$DM_NAME"
|
||||
|
||||
[[ -f "$TESTDIR/failed" ]] && cat "$TESTDIR/failed"
|
||||
echo "${JOURNAL_LIST:-No journals were saved}"
|
||||
|
||||
test -s "$TESTDIR/failed" && ret=1
|
||||
return $ret
|
||||
}
|
||||
|
||||
@@ -61,6 +63,7 @@ test_create_image() {
|
||||
mkdir -p "$STATEDIR/keydev"
|
||||
mount "$STATEDIR/keydev.img" "$STATEDIR/keydev"
|
||||
echo -n test >"$STATEDIR/keydev/keyfile"
|
||||
sync "$STATEDIR/keydev"
|
||||
umount "$STATEDIR/keydev"
|
||||
|
||||
cat >>"$initdir/etc/fstab" <<EOF
|
||||
@@ -97,9 +100,9 @@ EOF
|
||||
}
|
||||
|
||||
cleanup_root_var() {
|
||||
ddebug "umount ${initdir:?}/var"
|
||||
mountpoint "$initdir/var" && umount "$initdir/var"
|
||||
mountpoint -q "$initdir/var" && umount "$initdir/var"
|
||||
[[ -b "/dev/mapper/${DM_NAME:?}" ]] && cryptsetup luksClose "/dev/mapper/$DM_NAME"
|
||||
mountpoint -q "${STATEDIR:?}/keydev" && umount "$STATEDIR/keydev"
|
||||
}
|
||||
|
||||
test_cleanup() {
|
||||
|
||||
@@ -9,7 +9,7 @@ IMAGE_NAME="private-users"
|
||||
. "${TEST_BASE_DIR:?}/test-functions"
|
||||
|
||||
has_user_dbus_socket || exit 0
|
||||
command -v mksquashfs >/dev/null 2>&1 || exit 0
|
||||
test_require_bin mksquashfs
|
||||
|
||||
test_append_files() {
|
||||
inst_binary unsquashfs
|
||||
|
||||
@@ -11,10 +11,7 @@ TEST_DESCRIPTION="testing homed"
|
||||
. "${TEST_BASE_DIR:?}/test-functions"
|
||||
|
||||
get_bool "${NO_BUILD:-}" && HOMECTL_BIN="homectl" || HOMECTL_BIN="${BUILD_DIR:?}/homectl"
|
||||
if ! command -v "$HOMECTL_BIN" >/dev/null; then
|
||||
echo "Built without systemd-homed, skipping the test"
|
||||
exit 0
|
||||
fi
|
||||
test_require_bin "$HOMECTL_BIN"
|
||||
|
||||
# Need loop devices for mounting images
|
||||
test_append_files() {
|
||||
|
||||
@@ -12,9 +12,7 @@ TEST_INSTALL_VERITY_MINIMAL=1
|
||||
# shellcheck source=test/test-functions
|
||||
. "${TEST_BASE_DIR:?}/test-functions"
|
||||
|
||||
command -v mksquashfs >/dev/null 2>&1 || exit 0
|
||||
command -v veritysetup >/dev/null 2>&1 || exit 0
|
||||
command -v sfdisk >/dev/null 2>&1 || exit 0
|
||||
test_require_bin mksquashfs veritysetup sfdisk
|
||||
|
||||
test_append_files() {
|
||||
instmods squashfs =squashfs
|
||||
|
||||
@@ -4,6 +4,7 @@ set -e
|
||||
|
||||
TEST_DESCRIPTION="test systemd-repart"
|
||||
IMAGE_NAME="repart"
|
||||
IMAGE_ADDITIONAL_ROOT_SIZE=1000
|
||||
TEST_FORCE_NEWIMAGE=1
|
||||
|
||||
# shellcheck source=test/test-functions
|
||||
|
||||
@@ -5,41 +5,23 @@ set -e
|
||||
TEST_DESCRIPTION="cryptenroll/cryptsetup with TPM2 devices"
|
||||
IMAGE_NAME="tpm2"
|
||||
TEST_NO_NSPAWN=1
|
||||
TEST_SETUP_SWTPM=1
|
||||
TEST_REQUIRE_INSTALL_TESTS=0
|
||||
|
||||
# shellcheck source=test/test-functions
|
||||
. "${TEST_BASE_DIR:?}/test-functions"
|
||||
|
||||
command -v swtpm >/dev/null 2>&1 || exit 0
|
||||
command -v tpm2_pcrextend >/dev/null 2>&1 || exit 0
|
||||
test_require_bin swtpm tpm2_pcrextend
|
||||
|
||||
test_append_files() {
|
||||
local workspace="${1:?}"
|
||||
local workspace="${1:?}"
|
||||
|
||||
instmods tpm tpm_tis tpm_ibmvtpm
|
||||
install_dmevent
|
||||
generate_module_dependencies
|
||||
inst_binary tpm2_pcrextend
|
||||
inst_binary tpm2_pcrread
|
||||
inst_binary openssl
|
||||
instmods tpm tpm_tis tpm_ibmvtpm
|
||||
install_dmevent
|
||||
generate_module_dependencies
|
||||
inst_binary tpm2_pcrextend
|
||||
inst_binary tpm2_pcrread
|
||||
inst_binary openssl
|
||||
}
|
||||
|
||||
TEST_70_TPM_DEVICE="tpm-tis"
|
||||
if [[ "$(uname -m)" == "ppc64le" ]]; then
|
||||
# tpm-spapr support was introduced in qemu 5.0.0. Skip test for old qemu versions.
|
||||
qemu_min_version "5.0.0" || exit 0
|
||||
TEST_70_TPM_DEVICE="tpm-spapr"
|
||||
fi
|
||||
|
||||
TEST_70_at_exit() {
|
||||
[[ -n "${TEST_70_SWTPM_PID:-}" ]] && kill "$TEST_70_SWTPM_PID" &>/dev/null
|
||||
[[ -n "${TEST_70_TPM_STATE:-}" ]] && rm -rf "$TEST_70_TPM_STATE"
|
||||
}
|
||||
|
||||
TEST_70_TPM_STATE="$(mktemp -d)"
|
||||
swtpm socket --tpm2 --tpmstate dir="$TEST_70_TPM_STATE" --ctrl type=unixio,path="$TEST_70_TPM_STATE/sock" &
|
||||
TEST_70_SWTPM_PID=$!
|
||||
add_at_exit_handler TEST_70_at_exit
|
||||
QEMU_OPTIONS+=" -chardev socket,id=chrtpm,path=$TEST_70_TPM_STATE/sock -tpmdev emulator,id=tpm0,chardev=chrtpm -device $TEST_70_TPM_DEVICE,tpmdev=tpm0"
|
||||
|
||||
do_test "$@"
|
||||
|
||||
@@ -9,10 +9,7 @@ NSPAWN_ARGUMENTS="--private-network"
|
||||
# shellcheck source=test/test-functions
|
||||
. "${TEST_BASE_DIR:?}/test-functions"
|
||||
|
||||
if ! command -v knotd >/dev/null; then
|
||||
echo "This test requires Knot DNS server, skipping..."
|
||||
exit 0
|
||||
fi
|
||||
test_require_bin knotd
|
||||
|
||||
# We need at least Knot 3.0 which support (among others) the ds-push directive
|
||||
if ! knotc -c "${TEST_BASE_DIR:?}/knot-data/knot.conf" conf-check; then
|
||||
|
||||
+72
-21
@@ -69,21 +69,14 @@ _at_exit() {
|
||||
# Run the EXIT handlers in reverse order
|
||||
for ((i = ${#_AT_EXIT_HANDLERS[@]} - 1; i >= 0; i--)); do
|
||||
ddebug "Running EXIT handler '${_AT_EXIT_HANDLERS[$i]}'"
|
||||
"${_AT_EXIT_HANDLERS[$i]}"
|
||||
eval "${_AT_EXIT_HANDLERS[$i]}"
|
||||
done
|
||||
}
|
||||
|
||||
trap _at_exit EXIT
|
||||
|
||||
add_at_exit_handler() {
|
||||
local handler="${1?}"
|
||||
|
||||
if [[ "$(type -t "$handler")" != "function" ]]; then
|
||||
dfatal "'$handler' is not a function"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
_AT_EXIT_HANDLERS+=("$handler")
|
||||
_AT_EXIT_HANDLERS+=("${1:?}")
|
||||
}
|
||||
|
||||
# Decide if we can (and want to) run qemu with KVM acceleration.
|
||||
@@ -333,6 +326,17 @@ if get_bool "$IS_BUILT_WITH_ASAN"; then
|
||||
echo "Detected ASan RT '$ASAN_RT_NAME' located at '$ASAN_RT_PATH'"
|
||||
fi
|
||||
|
||||
test_require_bin() {
|
||||
local bin
|
||||
|
||||
for bin in "$@"; do
|
||||
if ! command -v "$bin" >/dev/null; then
|
||||
echo "Required binary $bin not available, skipping the test"
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
find_qemu_bin() {
|
||||
QEMU_BIN="${QEMU_BIN:-""}"
|
||||
# SUSE and Red Hat call the binary qemu-kvm. Debian and Gentoo call it kvm.
|
||||
@@ -364,6 +368,48 @@ find_qemu_bin() {
|
||||
fi
|
||||
}
|
||||
|
||||
qemu_setup_swtpm_socket() {
|
||||
local pid state_dir tpm_device
|
||||
|
||||
if ! tpm_device="$(qemu_get_tpm_device)"; then
|
||||
dinfo "Found QEMU version is too old for TPM2 on ppc64le"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
state_dir="$(mktemp -d)"
|
||||
swtpm socket --tpm2 --tpmstate dir="$state_dir" --ctrl type=unixio,path="$state_dir/sock" &
|
||||
pid=$!
|
||||
if ! kill -0 "$pid"; then
|
||||
echo >&2 "Failed to setup swtpm socket"
|
||||
return 1
|
||||
fi
|
||||
|
||||
dinfo "Started swtpm as PID $pid with state dir $state_dir"
|
||||
|
||||
add_at_exit_handler "kill -TERM $pid 2>/dev/null; rm -rf '$state_dir'"
|
||||
|
||||
QEMU_OPTIONS+=" -chardev socket,id=chrtpm,path=$state_dir/sock -tpmdev emulator,id=tpm0,chardev=chrtpm -device $tpm_device,tpmdev=tpm0"
|
||||
dinfo "Configured emulated TPM2 device $tpm_device"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
qemu_get_tpm_device() {
|
||||
local tpm_device="tpm-tis"
|
||||
|
||||
if [[ "$(uname -m)" == "ppc64le" ]]; then
|
||||
# tpm-spapr support was introduced in qemu 5.0.0
|
||||
if ! qemu_min_version "5.0.0"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
tpm_device="tpm-spapr"
|
||||
fi
|
||||
|
||||
echo "$tpm_device"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Compares argument #1=X.Y.Z (X&Y&Z = numeric) to the version of the installed qemu
|
||||
# returns 0 if newer or equal
|
||||
# returns 1 if older
|
||||
@@ -454,6 +500,10 @@ run_qemu() {
|
||||
|
||||
find_qemu_bin || return 1
|
||||
|
||||
if get_bool "${TEST_SETUP_SWTPM:-}"; then
|
||||
qemu_setup_swtpm_socket || return 1
|
||||
fi
|
||||
|
||||
# Umount initdir to avoid concurrent access to the filesystem
|
||||
_umount_dir "$initdir"
|
||||
|
||||
@@ -1373,7 +1423,7 @@ cleanup_loopdev() {
|
||||
add_at_exit_handler cleanup_loopdev
|
||||
|
||||
create_empty_image() {
|
||||
if [ -z "${IMAGE_NAME:=}" ]; then
|
||||
if [[ -z "${IMAGE_NAME:=}" ]]; then
|
||||
echo "create_empty_image: \$IMAGE_NAME not set"
|
||||
exit 1
|
||||
fi
|
||||
@@ -1383,21 +1433,24 @@ create_empty_image() {
|
||||
local data_size=100
|
||||
if ! get_bool "$NO_BUILD"; then
|
||||
if meson configure "${BUILD_DIR:?}" | grep 'static-lib\|standalone-binaries' | awk '{ print $2 }' | grep -q 'true'; then
|
||||
root_size=$((root_size+=200))
|
||||
root_size=$((root_size + 200))
|
||||
fi
|
||||
if meson configure "${BUILD_DIR:?}" | grep 'link-.*-shared' | awk '{ print $2 }' | grep -q 'false'; then
|
||||
root_size=$((root_size+=200))
|
||||
root_size=$((root_size + 200))
|
||||
fi
|
||||
if get_bool "$IS_BUILT_WITH_COVERAGE"; then
|
||||
root_size=$((root_size+=250))
|
||||
root_size=$((root_size + 250))
|
||||
fi
|
||||
if get_bool "$IS_BUILT_WITH_ASAN"; then
|
||||
root_size=$((root_size * 2))
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$IMAGE_NAME" = "repart" ]; then
|
||||
root_size=$((root_size+=1000))
|
||||
if [[ "${IMAGE_ADDITIONAL_ROOT_SIZE:-0}" -gt 0 ]]; then
|
||||
root_size=$((root_size + IMAGE_ADDITIONAL_ROOT_SIZE))
|
||||
fi
|
||||
if [[ "${IMAGE_ADDITIONAL_DATA_SIZE:-0}" -gt 0 ]]; then
|
||||
data_size=$((data_size + IMAGE_ADDITIONAL_DATA_SIZE))
|
||||
fi
|
||||
|
||||
echo "Setting up ${IMAGE_PUBLIC:?} (${root_size} MB)"
|
||||
@@ -1406,8 +1459,8 @@ create_empty_image() {
|
||||
# Create the blank file to use as a root filesystem
|
||||
truncate -s "${root_size}M" "$IMAGE_PUBLIC"
|
||||
|
||||
LOOPDEV=$(losetup --show -P -f "$IMAGE_PUBLIC")
|
||||
[ -b "$LOOPDEV" ] || return 1
|
||||
LOOPDEV="$(losetup --show -P -f "$IMAGE_PUBLIC")"
|
||||
[[ -b "$LOOPDEV" ]] || return 1
|
||||
# Create two partitions - a root one and a data one (utilized by some tests)
|
||||
sfdisk "$LOOPDEV" <<EOF
|
||||
label: gpt
|
||||
@@ -1662,8 +1715,7 @@ check_result_nspawn() {
|
||||
fi
|
||||
fi
|
||||
|
||||
check_result_common "${workspace}"
|
||||
ret=$?
|
||||
check_result_common "${workspace}" && ret=0 || ret=$?
|
||||
|
||||
_umount_dir "${initdir:?}"
|
||||
|
||||
@@ -1683,8 +1735,7 @@ check_result_qemu() {
|
||||
fi
|
||||
fi
|
||||
|
||||
check_result_common "${initdir:?}"
|
||||
ret=$?
|
||||
check_result_common "${initdir:?}" && ret=0 || ret=$?
|
||||
|
||||
_umount_dir "${initdir:?}"
|
||||
|
||||
|
||||
@@ -5,5 +5,5 @@ After=multi-user.target
|
||||
|
||||
[Service]
|
||||
ExecStartPre=rm -f /failed /testok
|
||||
ExecStart=sh -x -e -c 'mountpoint /var; systemctl --state=failed --no-legend --no-pager >/failed; echo OK >/testok'
|
||||
ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh
|
||||
Type=oneshot
|
||||
|
||||
Executable
+216
@@ -0,0 +1,216 @@
|
||||
#!/usr/bin/env bash
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
set -eux
|
||||
set -o pipefail
|
||||
|
||||
# TODO:
|
||||
# - /proc/cmdline parsing
|
||||
# - figure out token support (apart from TPM2, as that's covered by TEST-70-TPM2)
|
||||
# - this might help https://www.qemu.org/docs/master/system/devices/ccid.html
|
||||
# - expect + interactive auth?
|
||||
|
||||
# We set up an encrypted /var partition which should get mounted automatically
|
||||
# on boot
|
||||
mountpoint /var
|
||||
|
||||
systemctl --state=failed --no-legend --no-pager | tee /failed
|
||||
if [[ -s /failed ]]; then
|
||||
echo >&2 "Found units in failed state"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
at_exit() {
|
||||
set +e
|
||||
|
||||
mountpoint -q /proc/cmdline && umount /proc/cmdline
|
||||
rm -f /etc/crypttab
|
||||
[[ -e /tmp/crypttab.bak ]] && cp -fv /tmp/crypttab.bak /etc/crypttab
|
||||
[[ -n "${STORE_LOOP:-}" ]] && losetup -d "$STORE_LOOP"
|
||||
[[ -n "${WORKDIR:-}" ]] && rm -rf "$WORKDIR"
|
||||
|
||||
systemctl daemon-reload
|
||||
}
|
||||
|
||||
trap at_exit EXIT
|
||||
|
||||
cryptsetup_start_and_check() {
|
||||
local expect_fail=0
|
||||
local ec volume unit
|
||||
|
||||
if [[ "${1:?}" == "-f" ]]; then
|
||||
expect_fail=1
|
||||
shift
|
||||
fi
|
||||
|
||||
for volume in "$@"; do
|
||||
unit="systemd-cryptsetup@$volume.service"
|
||||
|
||||
# The unit existence check should always pass
|
||||
[[ "$(systemctl show -P LoadState "$unit")" == loaded ]]
|
||||
systemctl list-unit-files "$unit"
|
||||
|
||||
systemctl start "$unit" && ec=0 || ec=$?
|
||||
if [[ "$expect_fail" -ne 0 ]]; then
|
||||
if [[ "$ec" -eq 0 ]]; then
|
||||
echo >&2 "Unexpected pass when starting $unit"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ "$ec" -ne 0 ]]; then
|
||||
echo >&2 "Unexpected fail when starting $unit"
|
||||
return 1
|
||||
fi
|
||||
|
||||
systemctl status "$unit"
|
||||
test -e "/dev/mapper/$volume"
|
||||
systemctl stop "$unit"
|
||||
test ! -e "/dev/mapper/$volume"
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Note: some stuff (especially TPM-related) is already tested by TEST-70-TPM2,
|
||||
# so focus more on other areas instead
|
||||
|
||||
# Use a common workdir to make the cleanup easier
|
||||
WORKDIR="$(mktemp -d)"
|
||||
|
||||
# Prepare a couple of LUKS2-encrypted disk images
|
||||
#
|
||||
# 1) Image with an empty password
|
||||
IMAGE_EMPTY="$WORKDIR/empty.img)"
|
||||
IMAGE_EMPTY_KEYFILE="$WORKDIR/empty.keyfile"
|
||||
IMAGE_EMPTY_KEYFILE_ERASE="$WORKDIR/empty-erase.keyfile"
|
||||
IMAGE_EMPTY_KEYFILE_ERASE_FAIL="$WORKDIR/empty-erase-fail.keyfile)"
|
||||
truncate -s 32M "$IMAGE_EMPTY"
|
||||
echo -n passphrase >"$IMAGE_EMPTY_KEYFILE"
|
||||
chmod 0600 "$IMAGE_EMPTY_KEYFILE"
|
||||
cryptsetup luksFormat --batch-mode \
|
||||
--pbkdf pbkdf2 \
|
||||
--pbkdf-force-iterations 1000 \
|
||||
--use-urandom \
|
||||
"$IMAGE_EMPTY" "$IMAGE_EMPTY_KEYFILE"
|
||||
PASSWORD=passphrase NEWPASSWORD="" systemd-cryptenroll --password "$IMAGE_EMPTY"
|
||||
# Duplicate the key file to test keyfile-erase as well
|
||||
cp -v "$IMAGE_EMPTY_KEYFILE" "$IMAGE_EMPTY_KEYFILE_ERASE"
|
||||
# The key should get erased even on a failed attempt, so test that too
|
||||
cp -v "$IMAGE_EMPTY_KEYFILE" "$IMAGE_EMPTY_KEYFILE_ERASE_FAIL"
|
||||
|
||||
# 2) Image with a detached header and a key file offset + size
|
||||
IMAGE_DETACHED="$WORKDIR/detached.img"
|
||||
IMAGE_DETACHED_KEYFILE="$WORKDIR/detached.keyfile"
|
||||
IMAGE_DETACHED_KEYFILE2="$WORKDIR/detached.keyfile2"
|
||||
IMAGE_DETACHED_HEADER="$WORKDIR/detached.header"
|
||||
truncate -s 32M "$IMAGE_DETACHED"
|
||||
dd if=/dev/urandom of="$IMAGE_DETACHED_KEYFILE" count=64 bs=1
|
||||
dd if=/dev/urandom of="$IMAGE_DETACHED_KEYFILE2" count=32 bs=1
|
||||
chmod 0600 "$IMAGE_DETACHED_KEYFILE" "$IMAGE_DETACHED_KEYFILE2"
|
||||
cryptsetup luksFormat --batch-mode \
|
||||
--pbkdf pbkdf2 \
|
||||
--pbkdf-force-iterations 1000 \
|
||||
--use-urandom \
|
||||
--header "$IMAGE_DETACHED_HEADER" \
|
||||
--keyfile-offset 32 \
|
||||
--keyfile-size 16 \
|
||||
"$IMAGE_DETACHED" "$IMAGE_DETACHED_KEYFILE"
|
||||
# Also, add a second key file to key slot 8
|
||||
# Note: --key-slot= behaves as --new-key-slot= when used alone for backwards compatibility
|
||||
cryptsetup luksAddKey --batch-mode \
|
||||
--header "$IMAGE_DETACHED_HEADER" \
|
||||
--key-file "$IMAGE_DETACHED_KEYFILE" \
|
||||
--keyfile-offset 32 \
|
||||
--keyfile-size 16 \
|
||||
--key-slot 8 \
|
||||
"$IMAGE_DETACHED" "$IMAGE_DETACHED_KEYFILE2"
|
||||
|
||||
# Prepare a couple of dummy devices we'll store a copy of the detached header
|
||||
# and one of the keys on to test if systemd-cryptsetup correctly mounts them
|
||||
# when necessary
|
||||
STORE_IMAGE="$WORKDIR/store.img"
|
||||
truncate -s 64M "$STORE_IMAGE"
|
||||
STORE_LOOP="$(losetup --show --find --partscan "$STORE_IMAGE")"
|
||||
sfdisk "$STORE_LOOP" <<EOF
|
||||
label: gpt
|
||||
type=0FC63DAF-8483-4772-8E79-3D69D8477DE4 name=header_store size=32M
|
||||
type=0FC63DAF-8483-4772-8E79-3D69D8477DE4 name=keyfile_store
|
||||
EOF
|
||||
udevadm settle --timeout=30
|
||||
mkdir -p /mnt
|
||||
mkfs.ext4 -L header_store "/dev/disk/by-partlabel/header_store"
|
||||
mount "/dev/disk/by-partlabel/header_store" /mnt
|
||||
cp "$IMAGE_DETACHED_HEADER" /mnt/header
|
||||
umount /mnt
|
||||
mkfs.ext4 -L keyfile_store "/dev/disk/by-partlabel/keyfile_store"
|
||||
mount "/dev/disk/by-partlabel/keyfile_store" /mnt
|
||||
cp "$IMAGE_DETACHED_KEYFILE2" /mnt/keyfile
|
||||
umount /mnt
|
||||
udevadm settle --timeout=30
|
||||
|
||||
# Prepare our test crypttab
|
||||
[[ -e /etc/crypttab ]] && cp -fv /etc/crypttab /tmp/crypttab.bak
|
||||
cat >/etc/crypttab <<EOF
|
||||
# headless should translate to headless=1
|
||||
empty_key $IMAGE_EMPTY $IMAGE_EMPTY_KEYFILE headless,x-systemd.device-timeout=1m
|
||||
empty_key_erase $IMAGE_EMPTY $IMAGE_EMPTY_KEYFILE_ERASE headless=1,keyfile-erase=1
|
||||
empty_key_erase_fail $IMAGE_EMPTY $IMAGE_EMPTY_KEYFILE_ERASE_FAIL headless=1,keyfile-erase=1,keyfile-offset=4
|
||||
# Empty passphrase without try-empty-password(=yes) shouldn't work
|
||||
empty_fail0 $IMAGE_EMPTY - headless=1
|
||||
empty_fail1 $IMAGE_EMPTY - headless=1,try-empty-password=0
|
||||
empty0 $IMAGE_EMPTY - headless=1,try-empty-password
|
||||
empty1 $IMAGE_EMPTY - headless=1,try-empty-password=1
|
||||
# This one expects the key to be under /{etc,run}/cryptsetup-keys.d/empty_nokey.key
|
||||
empty_nokey $IMAGE_EMPTY - headless=1
|
||||
|
||||
detached $IMAGE_DETACHED $IMAGE_DETACHED_KEYFILE headless=1,header=$IMAGE_DETACHED_HEADER,keyfile-offset=32,keyfile-size=16
|
||||
detached_store0 $IMAGE_DETACHED $IMAGE_DETACHED_KEYFILE headless=1,header=/header:LABEL=header_store,keyfile-offset=32,keyfile-size=16
|
||||
detached_store1 $IMAGE_DETACHED /keyfile:LABEL=keyfile_store headless=1,header=$IMAGE_DETACHED_HEADER
|
||||
detached_store2 $IMAGE_DETACHED /keyfile:LABEL=keyfile_store headless=1,header=/header:LABEL=header_store
|
||||
detached_fail0 $IMAGE_DETACHED $IMAGE_DETACHED_KEYFILE headless=1,header=$IMAGE_DETACHED_HEADER,keyfile-offset=32
|
||||
detached_fail1 $IMAGE_DETACHED $IMAGE_DETACHED_KEYFILE headless=1,header=$IMAGE_DETACHED_HEADER
|
||||
detached_fail2 $IMAGE_DETACHED $IMAGE_DETACHED_KEYFILE headless=1
|
||||
detached_fail3 $IMAGE_DETACHED $IMAGE_DETACHED_KEYFILE headless=1,header=$IMAGE_DETACHED_HEADER,keyfile-offset=16,keyfile-size=16
|
||||
detached_fail4 $IMAGE_DETACHED $IMAGE_DETACHED_KEYFILE headless=1,header=$IMAGE_DETACHED_HEADER,keyfile-offset=32,keyfile-size=8
|
||||
detached_slot0 $IMAGE_DETACHED $IMAGE_DETACHED_KEYFILE2 headless=1,header=$IMAGE_DETACHED_HEADER
|
||||
detached_slot1 $IMAGE_DETACHED $IMAGE_DETACHED_KEYFILE2 headless=1,header=$IMAGE_DETACHED_HEADER,key-slot=8
|
||||
detached_slot_fail $IMAGE_DETACHED $IMAGE_DETACHED_KEYFILE2 headless=1,header=$IMAGE_DETACHED_HEADER,key-slot=0
|
||||
EOF
|
||||
|
||||
# Temporarily drop luks.name=/luks.uuid= from the kernel command line, as it makes
|
||||
# systemd-cryptsetup-generator ignore mounts from /etc/crypttab that are not also
|
||||
# specified on the kernel command line
|
||||
sed -r 's/luks.(name|uuid)=[^[:space:]+]//' /proc/cmdline >/tmp/cmdline.tmp
|
||||
mount --bind /tmp/cmdline.tmp /proc/cmdline
|
||||
# Run the systemd-cryptsetup-generator once explicitly, to collect coverage,
|
||||
# as during daemon-reload we run generators in a sandbox
|
||||
mkdir -p /tmp/systemd-cryptsetup-generator.out
|
||||
/usr/lib/systemd/system-generators/systemd-cryptsetup-generator /tmp/systemd-cryptsetup-generator.out/
|
||||
systemctl daemon-reload
|
||||
systemctl list-unit-files "systemd-cryptsetup@*"
|
||||
|
||||
cryptsetup_start_and_check empty_key
|
||||
test -e "$IMAGE_EMPTY_KEYFILE_ERASE"
|
||||
cryptsetup_start_and_check empty_key_erase
|
||||
test ! -e "$IMAGE_EMPTY_KEYFILE_ERASE"
|
||||
test -e "$IMAGE_EMPTY_KEYFILE_ERASE_FAIL"
|
||||
cryptsetup_start_and_check -f empty_key_erase_fail
|
||||
test ! -e "$IMAGE_EMPTY_KEYFILE_ERASE_FAIL"
|
||||
cryptsetup_start_and_check -f empty_fail{0..1}
|
||||
cryptsetup_start_and_check empty{0..1}
|
||||
# First, check if we correctly fail without any key
|
||||
cryptsetup_start_and_check -f empty_nokey
|
||||
# And now provide the key via /{etc,run}/cryptsetup-keys.d/
|
||||
mkdir -p /run/cryptsetup-keys.d
|
||||
cp "$IMAGE_EMPTY_KEYFILE" /run/cryptsetup-keys.d/empty_nokey.key
|
||||
cryptsetup_start_and_check empty_nokey
|
||||
|
||||
cryptsetup_start_and_check detached
|
||||
cryptsetup_start_and_check detached_store{0..2}
|
||||
cryptsetup_start_and_check -f detached_fail{0..4}
|
||||
cryptsetup_start_and_check detached_slot{0..1}
|
||||
cryptsetup_start_and_check -f detached_slot_fail
|
||||
|
||||
echo OK >/testok
|
||||
Reference in New Issue
Block a user