Blame SOURCES/Use-one-clevis-luks-askpass-per-device.patch

ef20f4
From 523f1361c759d5af0952b0137d4dbd51be1e7b3d Mon Sep 17 00:00:00 2001
ef20f4
From: Sergio Correia <scorreia@redhat.com>
ef20f4
Date: Sun, 22 Dec 2019 17:01:09 -0500
ef20f4
Subject: [PATCH] Use one clevis-luks-askpass per device
ef20f4
ef20f4
This should improve the reliability of the boot unlocking, especially
ef20f4
when unlocking multiple devices upon boot.
ef20f4
ef20f4
It also greatly simplifies the configuration, as three is no need to
ef20f4
enable any systemd units manually nor add _netdev to either fstab or
ef20f4
crypttab.
ef20f4
---
ef20f4
 src/luks/clevis-luks-unlockers.7.adoc         | 16 +++----------
ef20f4
 src/luks/systemd/clevis-luks-askpass          |  7 +++++-
ef20f4
 src/luks/systemd/clevis-luks-askpass.path     | 10 --------
ef20f4
 .../systemd/clevis-luks-askpass.service.in    |  8 -------
ef20f4
 src/luks/systemd/clevis-luks-askpass@.path    | 12 ++++++++++
ef20f4
 .../systemd/clevis-luks-askpass@.service.in   |  9 +++++++
ef20f4
 src/luks/systemd/dracut/module-setup.sh.in    | 24 +++++++++++++++++++
ef20f4
 src/luks/systemd/meson.build                  |  8 +++----
ef20f4
 8 files changed, 58 insertions(+), 36 deletions(-)
ef20f4
 delete mode 100644 src/luks/systemd/clevis-luks-askpass.path
ef20f4
 delete mode 100644 src/luks/systemd/clevis-luks-askpass.service.in
ef20f4
 create mode 100644 src/luks/systemd/clevis-luks-askpass@.path
ef20f4
 create mode 100644 src/luks/systemd/clevis-luks-askpass@.service.in
ef20f4
ef20f4
diff --git a/src/luks/clevis-luks-unlockers.7.adoc b/src/luks/clevis-luks-unlockers.7.adoc
ef20f4
index 161b73a..e8d47ba 100644
ef20f4
--- a/src/luks/clevis-luks-unlockers.7.adoc
ef20f4
+++ b/src/luks/clevis-luks-unlockers.7.adoc
ef20f4
@@ -26,7 +26,7 @@ You can unlock a LUKS volume manually using the following command:
ef20f4
 
ef20f4
 For more information, see link:clevis-luks-unlock.1.adoc[*clevis-luks-unlock*(1)].
ef20f4
 
ef20f4
-== EARLY BOOT UNLOCKING
ef20f4
+== BOOT UNLOCKING
ef20f4
 
ef20f4
 If Clevis integration does not already ship in your initramfs, you may need to
ef20f4
 rebuild your initramfs with this command:
ef20f4
@@ -34,23 +34,13 @@ rebuild your initramfs with this command:
ef20f4
     $ sudo dracut -f
ef20f4
 
ef20f4
 Once Clevis is integrated into your initramfs, a simple reboot should unlock
ef20f4
-your root volume. Note, however, that early boot integration only works for the
ef20f4
-root volume. Non-root volumes should use the late boot unlocker.
ef20f4
+your clevis-bound volumes. Root volumes will be unlocked in early-boot, while the
ef20f4
+remaining volumes will be unlocked after dracut switch-root.
ef20f4
 
ef20f4
 Dracut will bring up your network using DHCP by default. If you need to specify
ef20f4
 additional network parameters, such as static IP configuration, please consult
ef20f4
 the dracut documentation.
ef20f4
 
ef20f4
-== LATE BOOT UNLOCKING
ef20f4
-
ef20f4
-You can enable late boot unlocking by executing the following command:
ef20f4
-
ef20f4
-    $ sudo systemctl enable clevis-luks-askpass.path
ef20f4
-
ef20f4
-After a reboot, Clevis will attempt to unlock all *_netdev* devices listed in
ef20f4
-*/etc/crypttab* when systemd prompts for their passwords. This implies that
ef20f4
-systemd support for *_netdev* is required.
ef20f4
-
ef20f4
 == DESKTOP UNLOCKING
ef20f4
 
ef20f4
 When the udisks2 unlocker is installed, your GNOME desktop session should
ef20f4
diff --git a/src/luks/systemd/clevis-luks-askpass b/src/luks/systemd/clevis-luks-askpass
ef20f4
index b01d93a..feebb1a 100755
ef20f4
--- a/src/luks/systemd/clevis-luks-askpass
ef20f4
+++ b/src/luks/systemd/clevis-luks-askpass
ef20f4
@@ -24,15 +24,17 @@ UUID=cb6e8904-81ff-40da-a84a-07ab9ab5715e
ef20f4
 shopt -s nullglob
ef20f4
 
ef20f4
 path=/run/systemd/ask-password
ef20f4
-while getopts ":lp:" o; do
ef20f4
+while getopts ":lpu:" o; do
ef20f4
     case "$o" in
ef20f4
     l) loop=true;;
ef20f4
     p) path=$OPTARG;;
ef20f4
+    u) device_uuid=$OPTARG;;
ef20f4
     esac
ef20f4
 done
ef20f4
 
ef20f4
 while true; do
ef20f4
     todo=0
ef20f4
+    [ -n "${device_uuid}" ] && todo=1 && loop=true
ef20f4
 
ef20f4
     for question in $path/ask.*; do
ef20f4
         metadata=false
ef20f4
@@ -48,6 +50,8 @@ while true; do
ef20f4
         done < "$question"
ef20f4
 
ef20f4
         [ -z "$d" -o -z "$s" ] && continue
ef20f4
+        [[ -n "${device_uuid}" ]] && [[ "${d}" != *"${device_uuid}"* ]] \
ef20f4
+            && continue
ef20f4
 
ef20f4
         if cryptsetup isLuks --type luks1 "$d"; then
ef20f4
             # If the device is not initialized, sliently skip it.
ef20f4
@@ -79,6 +83,7 @@ while true; do
ef20f4
             done
ef20f4
         fi
ef20f4
 
ef20f4
+        [ -n "${device_uuid}" ] && [ "${unlocked}" == true ] && todo=0 && break
ef20f4
         [ $metadata == true ] || continue
ef20f4
         [ $unlocked == true ] && continue
ef20f4
         todo=$((todo + 1))
ef20f4
diff --git a/src/luks/systemd/clevis-luks-askpass.path b/src/luks/systemd/clevis-luks-askpass.path
ef20f4
deleted file mode 100644
ef20f4
index a4d01ba..0000000
ef20f4
--- a/src/luks/systemd/clevis-luks-askpass.path
ef20f4
+++ /dev/null
ef20f4
@@ -1,10 +0,0 @@
ef20f4
-[Unit]
ef20f4
-Description=Clevis systemd-ask-password Watcher
ef20f4
-Before=remote-fs-pre.target
ef20f4
-Wants=remote-fs-pre.target
ef20f4
-
ef20f4
-[Path]
ef20f4
-PathChanged=/run/systemd/ask-password
ef20f4
-
ef20f4
-[Install]
ef20f4
-WantedBy=remote-fs.target
ef20f4
diff --git a/src/luks/systemd/clevis-luks-askpass.service.in b/src/luks/systemd/clevis-luks-askpass.service.in
ef20f4
deleted file mode 100644
ef20f4
index 2c6bbed..0000000
ef20f4
--- a/src/luks/systemd/clevis-luks-askpass.service.in
ef20f4
+++ /dev/null
ef20f4
@@ -1,8 +0,0 @@
ef20f4
-[Unit]
ef20f4
-Description=Clevis LUKS systemd-ask-password Responder
ef20f4
-Requires=network-online.target
ef20f4
-After=network-online.target
ef20f4
-
ef20f4
-[Service]
ef20f4
-Type=oneshot
ef20f4
-ExecStart=@libexecdir@/clevis-luks-askpass -l
ef20f4
diff --git a/src/luks/systemd/clevis-luks-askpass@.path b/src/luks/systemd/clevis-luks-askpass@.path
ef20f4
new file mode 100644
ef20f4
index 0000000..3f23665
ef20f4
--- /dev/null
ef20f4
+++ b/src/luks/systemd/clevis-luks-askpass@.path
ef20f4
@@ -0,0 +1,12 @@
ef20f4
+[Unit]
ef20f4
+Description=Clevis systemd-ask-password Watcher for %i
ef20f4
+DefaultDependencies=no
ef20f4
+Conflicts=shutdown.target
ef20f4
+Before=basic.target shutdown.target
ef20f4
+
ef20f4
+[Path]
ef20f4
+DirectoryNotEmpty=/run/systemd/ask-password
ef20f4
+MakeDirectory=yes
ef20f4
+
ef20f4
+[Install]
ef20f4
+WantedBy=basic.target
ef20f4
diff --git a/src/luks/systemd/clevis-luks-askpass@.service.in b/src/luks/systemd/clevis-luks-askpass@.service.in
ef20f4
new file mode 100644
ef20f4
index 0000000..cd26eb2
ef20f4
--- /dev/null
ef20f4
+++ b/src/luks/systemd/clevis-luks-askpass@.service.in
ef20f4
@@ -0,0 +1,9 @@
ef20f4
+[Unit]
ef20f4
+Description=Clevis LUKS systemd-ask-password Responder for luks-%i
ef20f4
+DefaultDependencies=no
ef20f4
+Conflicts=shutdown.target
ef20f4
+Before=shutdown.target
ef20f4
+
ef20f4
+[Service]
ef20f4
+Type=oneshot
ef20f4
+ExecStart=@libexecdir@/clevis-luks-askpass -u %i
ef20f4
diff --git a/src/luks/systemd/dracut/module-setup.sh.in b/src/luks/systemd/dracut/module-setup.sh.in
ef20f4
index 841f7a8..1877715 100755
ef20f4
--- a/src/luks/systemd/dracut/module-setup.sh.in
ef20f4
+++ b/src/luks/systemd/dracut/module-setup.sh.in
ef20f4
@@ -29,6 +29,29 @@ is_bound_to_tang() {
ef20f4
     return 1
ef20f4
 }
ef20f4
 
ef20f4
+configure_passwd_watchers() {
ef20f4
+    if ! command -v systemctl >/dev/null; then
ef20f4
+        return 1
ef20f4
+    fi
ef20f4
+
ef20f4
+    local proc_cmdline
ef20f4
+    proc_cmdline=$(
ef20f4
+
ef20f4
+    local luks_uuid
ef20f4
+    local cfg
ef20f4
+    for dev in $(lsblk -p -n -s -r \
ef20f4
+                 | awk '$6 == "crypt" { getline; print $1 }' | sort -u); do
ef20f4
+        luks_uuid=$(cryptsetup luksUUID "${dev}")
ef20f4
+        [[ "${proc_cmdline}" == *"rd.luks.uuid=luks-${luks_uuid}"* ]] && continue
ef20f4
+
ef20f4
+        if cfg=$(clevis luks list -d "${dev}" 2>/dev/null); then
ef20f4
+            local action=enable
ef20f4
+            [ -z "${cfg}" ] && action=disable
ef20f4
+            systemctl "${action}" "clevis-luks-askpass@${luks_uuid}.path" 2>/dev/null
ef20f4
+        fi
ef20f4
+    done
ef20f4
+}
ef20f4
+
ef20f4
 depends() {
ef20f4
     local depends="crypt systemd"
ef20f4
     if is_bound_to_tang; then
ef20f4
@@ -84,6 +107,7 @@ install() {
ef20f4
 	inst_libdir_file "libtss2-tcti-device.so*"
ef20f4
     fi
ef20f4
 
ef20f4
+    configure_passwd_watchers
ef20f4
     dracut_need_initqueue
ef20f4
 }
ef20f4
 
ef20f4
diff --git a/src/luks/systemd/meson.build b/src/luks/systemd/meson.build
ef20f4
index 108e9d8..334e84c 100644
ef20f4
--- a/src/luks/systemd/meson.build
ef20f4
+++ b/src/luks/systemd/meson.build
ef20f4
@@ -6,14 +6,14 @@ if systemd.found()
ef20f4
   unitdir = systemd.get_pkgconfig_variable('systemdsystemunitdir')
ef20f4
 
ef20f4
   configure_file(
ef20f4
-    input: 'clevis-luks-askpass.service.in',
ef20f4
-    output: 'clevis-luks-askpass.service',
ef20f4
+    input: 'clevis-luks-askpass@.service.in',
ef20f4
+    output: 'clevis-luks-askpass@.service',
ef20f4
     install_dir: unitdir,
ef20f4
     configuration: data,
ef20f4
   )
ef20f4
 
ef20f4
-  install_data('clevis-luks-askpass.path', install_dir: unitdir)
ef20f4
+  install_data('clevis-luks-askpass@.path', install_dir: unitdir)
ef20f4
   install_data('clevis-luks-askpass', install_dir: libexecdir)
ef20f4
 else
ef20f4
   warning('Will not install systemd support due to missing dependencies!')
ef20f4
-endif
ef20f4
\ No newline at end of file
ef20f4
+endif
ef20f4
-- 
ef20f4
2.18.1
ef20f4