From 9cb110f64530aaa7ee81e48926094684b8282b4b Mon Sep 17 00:00:00 2001 From: Sergio Correia Date: Tue, 16 Jan 2024 16:26:56 +0000 Subject: [PATCH] luks: decouple dracut from systemd unlocker Add an unlocker that does not require systemd. --- src/luks/dracut/clevis/clevis-hook.sh.in | 24 ++++++- src/luks/dracut/clevis/clevis-luks-unlocker | 72 +++++++++++++++++++++ src/luks/dracut/clevis/meson.build | 2 + src/luks/dracut/clevis/module-setup.sh.in | 10 ++- 4 files changed, 105 insertions(+), 3 deletions(-) create mode 100755 src/luks/dracut/clevis/clevis-luks-unlocker diff --git a/src/luks/dracut/clevis/clevis-hook.sh.in b/src/luks/dracut/clevis/clevis-hook.sh.in index cb257c99..78921a5d 100755 --- a/src/luks/dracut/clevis/clevis-hook.sh.in +++ b/src/luks/dracut/clevis/clevis-hook.sh.in @@ -1,2 +1,22 @@ -#!/bin/bash -@libexecdir@/clevis-luks-askpass +#!/bin/sh +set -eu +# vim: set ts=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: +# +# Copyright (c) 2020-2024 Red Hat, Inc. +# Author: Sergio Correia +# +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +@libexecdir@/clevis-luks-unlocker -l diff --git a/src/luks/dracut/clevis/clevis-luks-unlocker b/src/luks/dracut/clevis/clevis-luks-unlocker new file mode 100755 index 00000000..83063206 --- /dev/null +++ b/src/luks/dracut/clevis/clevis-luks-unlocker @@ -0,0 +1,72 @@ +#!/bin/sh +set -eu +# vim: set ts=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: +# +# Copyright (c) 2020-2024 Red Hat, Inc. +# Author: Sergio Correia +# +# Non-systemd clevis unlocker +# Modifications sponsored by PMGA Tech LLP +# +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +. clevis-luks-common-functions + +# Make sure to exit cleanly if SIGTERM is received. +trap 'echo "Exiting due to SIGTERM" && exit 0' TERM + +loop= +while getopts ":l" o; do + case "${o}" in + l) loop=true;; + *) ;; + esac +done + +to_unlock() { + _devices='' + for _d in $(blkid -t TYPE=crypto_LUKS -o device); do + if ! bindings="$(clevis luks list -d "${_d}" 2>/dev/null)" \ + || [ -z "${bindings}" ]; then + continue + fi + _uuid="$(cryptsetup luksUUID "${_d}")" + if clevis_is_luks_device_by_uuid_open "${_uuid}"; then + continue + fi + _devices="$(printf '%s\n%s' "${_devices}" "${_d}")" + done + echo "${_devices}" | sed -e 's/^\n$//' +} + +while true; do + for d in $(to_unlock); do + uuid="$(cryptsetup luksUUID "${d}")" + if ! clevis luks unlock -d "${d}"; then + echo "Unable to unlock ${d} (UUID=${uuid})" >&2 + continue + fi + echo "Unlocked ${d} (UUID=${uuid}) successfully" >&2 + done + + [ "${loop}" != true ] && break + # Checking for pending devices to be unlocked. + if remaining=$(to_unlock) && [ -z "${remaining}" ]; then + break; + fi + + sleep 0.5 +done diff --git a/src/luks/dracut/clevis/meson.build b/src/luks/dracut/clevis/meson.build index 167e708a..b05bc101 100644 --- a/src/luks/dracut/clevis/meson.build +++ b/src/luks/dracut/clevis/meson.build @@ -16,6 +16,8 @@ if dracut.found() install_dir: dracutdir, configuration: data, ) + + install_data('clevis-luks-unlocker', install_dir: libexecdir) else warning('Will not install dracut module due to missing dependencies!') endif diff --git a/src/luks/dracut/clevis/module-setup.sh.in b/src/luks/dracut/clevis/module-setup.sh.in index b69e534a..50547a52 100755 --- a/src/luks/dracut/clevis/module-setup.sh.in +++ b/src/luks/dracut/clevis/module-setup.sh.in @@ -19,7 +19,11 @@ # depends() { - echo crypt systemd + local __depends=crypt + if dracut_module_included "systemd"; then + __depends=$(printf '%s systemd' "${__depends}") + fi + echo "${__depends}" return 255 } @@ -35,6 +39,10 @@ install() { else inst_hook initqueue/online 60 "$moddir/clevis-hook.sh" inst_hook initqueue/settled 60 "$moddir/clevis-hook.sh" + inst_multiple \ + @libexecdir@/clevis-luks-unlocker \ + clevis-luks-unlock \ + blkid fi inst_multiple \