diff --git a/0001-PKCS-11-pin-fix-dracut-for-unconfigured-device.patch b/0001-PKCS-11-pin-fix-dracut-for-unconfigured-device.patch new file mode 100644 index 0000000000000000000000000000000000000000..a80fe03b085f53b8eec202c7b636f3fcf57f4302 --- /dev/null +++ b/0001-PKCS-11-pin-fix-dracut-for-unconfigured-device.patch @@ -0,0 +1,288 @@ +From 691b4136d6077ed7b079a38459b6844dbc584776 Mon Sep 17 00:00:00 2001 +From: Sergio Arroutbi +Date: Mon, 30 Sep 2024 11:27:57 +0200 +Subject: [PATCH] PKCS#11 pin: fix dracut for unconfigured device + +Signed-off-by: Sergio Arroutbi +--- + .../clevis-pin-pkcs11/module-setup.sh.in | 2 +- + src/luks/systemd/clevis-luks-pkcs11-askpin.in | 72 +++++-------------- + .../clevis-pkcs11-afunix-socket-unlock.c | 9 ++- + src/pins/pkcs11/clevis-pkcs11-common | 52 +++++++++++++- + 4 files changed, 74 insertions(+), 61 deletions(-) + +diff --git a/src/luks/dracut/clevis-pin-pkcs11/module-setup.sh.in b/src/luks/dracut/clevis-pin-pkcs11/module-setup.sh.in +index 39d06a0..a7a6d6b 100755 +--- a/src/luks/dracut/clevis-pin-pkcs11/module-setup.sh.in ++++ b/src/luks/dracut/clevis-pin-pkcs11/module-setup.sh.in +@@ -23,7 +23,7 @@ depends() { + } + + install() { +- inst_hook initqueue 60 "${moddir}/clevis-pkcs11-prehook.sh" ++ inst_hook pre-trigger 60 "${moddir}/clevis-pkcs11-prehook.sh" + inst_hook initqueue/settled 60 "${moddir}/clevis-pkcs11-hook.sh" + inst_hook initqueue/online 60 "${moddir}/clevis-pkcs11-hook.sh" + +diff --git a/src/luks/systemd/clevis-luks-pkcs11-askpin.in b/src/luks/systemd/clevis-luks-pkcs11-askpin.in +index 8f4092f..b860efa 100755 +--- a/src/luks/systemd/clevis-luks-pkcs11-askpin.in ++++ b/src/luks/systemd/clevis-luks-pkcs11-askpin.in +@@ -52,6 +52,7 @@ get_pkcs11_error() { + return 0 + } + ++ + if command -v pcscd; then + echo "clevis-pkcs11: starting pcscd if not available ..." + PCSCD_PID=$(ps auxf | grep "[p]cscd") +@@ -72,51 +73,6 @@ if [ "${dracut_mode}" != true ]; then + pkcs11-tool -L + fi + +-if ! pkcs11_device=$(pkcs11-tool -L 2>/dev/null | grep "Slot" | head -1 | \ +- awk -F ":" '{print $2}' | sed -e 's@^ *@@g'); then +- echo "No PKCS11 device detected (without module option) / pkcs11-tool error" +- exit 1 +-fi +- +-if ! pkcs11-tool -O 2>/dev/null 1>/dev/null; then +- pkcs11_device="" +- echo "No objects in PKCS11 device detected" +-fi +- +-while [ -z "${pkcs11_device}" ]; do +- if [ "${dracut_mode}" != true ]; then +- module_paths=$(clevis_get_module_path_from_pkcs11_config "/etc/crypttab") +- if [ -n "${module_paths}" ]; then +- modules=$(echo ${module_paths} | tr ";" "\n") +- for module in $modules; do +- pkcs11_device=$(pkcs11-tool -L --module ${module} | grep "Slot" \ +- | head -1 | awk -F ":" '{print $2}' | sed -e 's@^ *@@g') +- if [ -n "${pkcs11_device}" ]; then +- break; +- fi +- done +- fi +- fi +- if [ -z "${pkcs11_device}" ]; then +- if [ "${retry_mode}" == true ]; then +- option=$(systemd-ask-password --echo "Detected no PKCS#11 device, retry PKCS#11 detection? [yY/nN]") +- if [ "${option}" == "N" ] || [ "${option}" == "n" ] ; then +- echo "Won't continue PKCS11 device detection" +- exit 0 +- fi +- pkcs11_device=$(pkcs11-tool -L | grep "Slot" \ +- | head -1 | awk -F ":" '{print $2}' | sed -e 's@^ *@@g') +- if ! pkcs11-tool -O 2>/dev/null; then +- pkcs11_device="" +- echo "No objects in PKCS11 device detected" +- fi +- else +- exit 0 +- fi +- fi +-done +-echo "Detected PKCS11 device:${pkcs11_device}" +- + devices_array=() + # Let's analyze all entries from /etc/crypttab that contain clevis-pkcs11.sock entries + while read -r line; +@@ -126,6 +82,8 @@ do + next_device=0 + errors=0 + msg="" ++ # Store passphrases to send to control socket ++ systemd_device=$(echo "${line}" | awk '{print $1}') + while [ ${next_device} -ne 1 ]; do + uuid=$(echo "${line}" | awk '{print $2}') + if ! mapped_device=$(clevis_map_device "${uuid}"); then +@@ -141,15 +99,23 @@ do + fi + # If no PKCS#11 configuration, advance to next device + if ! clevis luks list -d "${mapped_device}" | grep pkcs11 >/dev/null 2>&1; then +- echo "Device:${mapped_device} does not contain PKCS#11 configuration" ++ echo "Device:${mapped_device} does not contain PKCS#11 configuration" >&2 ++ # Send a wrong passphrase ++ echo -n "${systemd_device},NOPASSWORDFOR${systemd_device}" | socat UNIX-CONNECT:/run/systemd/clevis-pkcs11.control.sock - + next_device=1 + continue + fi ++ if ! pkcs11_device=$(clevis_detect_pkcs11_device "${dracut_mode}" "${retry_mode}"); then ++ echo "No PKCS11 device detected" >&2 ++ exit 0 ++ else ++ echo "Detected PKCS11 device:${pkcs11_device}" >&2 ++ fi + # Get configuration PKCS#11 URI + uri=$(clevis luks list -d "${mapped_device}" | awk -F '"uri":' '{print $2}' | awk -F '"' '{print $2}' | awk -F '"' '{print $1}') + slot_opt="" + if ! slot=$(clevis_get_pkcs11_final_slot_from_uri "${uri}"); then +- echo "Could not find slot for uri:${uri}" ++ echo "Could not find slot for uri:${uri}" >&2 + else + slot_opt="--slot-index ${slot}" + fi +@@ -159,8 +125,9 @@ do + module_opt="--module ${module}" + fi + echo "Device:${mapped_device}, slot_opt:${slot_opt}, module_opt:${module_opt}" +- if ! pkcs11-tool -O ${module_opt} ${slot_opt}; then +- echo "No objects on slot:${slot}, module_opt:${module_opt}" ++ if ! pkcs11-tool -O ${module_opt} ${slot_opt} 2>/dev/null 1>/dev/null; then ++ echo "No objects on slot:${slot}, module_opt:${module_opt}" >&2 ++ echo -n "${systemd_device},NOPASSWORDFOR${systemd_device}" | socat UNIX-CONNECT:/run/systemd/clevis-pkcs11.control.sock - + next_device=1 + continue + fi +@@ -175,22 +142,21 @@ do + # Get key from PKCS11 pin here and feed AF_UNIX socket program + echo "${pin}" > /run/systemd/clevis-pkcs11.pin + if ! passphrase=$(clevis_luks_unlock_device "${mapped_device}") || [ -z "${passphrase}" ]; then +- echo "Could not unlock device:${mapped_device}" ++ echo "Could not unlock device:${mapped_device}" >&2 + msg="$(get_pkcs11_error)" + ((errors++)) + if [ ${errors} -eq ${too_many_errors} ]; then +- echo "Too many errors !!!" 1>&2 ++ echo "Too many errors !!!" >&2 + next_device=1 + fi + continue + fi + next_device=1 +- echo "Device:${mapped_device} unlocked successfully by clevis" ++ echo "Device:${mapped_device} unlocked successfully by clevis" >&2 + if [ "${dracut_mode}" == true ]; then + echo "${mapped_device}" >> /run/systemd/clevis-pkcs11-dracut.devices + fi + # Store passphrases to send to control socket +- systemd_device=$(echo "${line}" | awk '{print $1}') + devices_array+=("${systemd_device},${passphrase}") + done + fi +diff --git a/src/pins/pkcs11/clevis-pkcs11-afunix-socket-unlock.c b/src/pins/pkcs11/clevis-pkcs11-afunix-socket-unlock.c +index a6ecc63..24bad83 100644 +--- a/src/pins/pkcs11/clevis-pkcs11-afunix-socket-unlock.c ++++ b/src/pins/pkcs11/clevis-pkcs11-afunix-socket-unlock.c +@@ -146,7 +146,6 @@ static void* control_thread(void *targ) { + } + char* t = control_msg; + int is_device = 1; +- fprintf(logfile, "Received control message:[%s]\n", t); + while((t = strtok(t, ","))) { + if (is_device) { + fprintf(logfile, "Adding device:%s\n", t); +@@ -185,7 +184,7 @@ static void dump_wide_version(void) { + + static void int_handler(int s) { + if(logfile) { +- fprintf(logfile, "Closing, signal:[%d]\n", s); ++ fprintf(logfile, "Closing, received signal:[%d]\n", s); + fclose(logfile); + } + exit(EXIT_FAILURE); +@@ -222,6 +221,7 @@ int main(int argc, char* argv[]) { + break; + case 'f': + strncpy(sock_file, optarg, MAX_PATH - 1); ++ unlink(sock_file); + break; + case 'k': + strncpy(key, optarg, MAX_KEY - 1); +@@ -275,7 +275,6 @@ int main(int argc, char* argv[]) { + memset(&sock_addr, 0, sizeof(sock_addr)); + sock_addr.sun_family = AF_UNIX; + strncpy(sock_addr.sun_path, sock_file, sizeof(sock_addr.sun_path)-1); +- unlink(sock_file); + s = socket(AF_UNIX, SOCK_STREAM, 0); + if (s == -1) { + perror("socket"); +@@ -346,8 +345,8 @@ int main(int argc, char* argv[]) { + perror("key entry send error"); + goto efailure; + } +- fprintf(logfile, "Sending:[%s] to device:[%s]\n", +- entry_key, unlocking_device); ++ fprintf(logfile, "Sending passphrase to device:[%s]\n", ++ unlocking_device); + } else { + fprintf(logfile, "Device not found: [%s]\n", unlocking_device); + } +diff --git a/src/pins/pkcs11/clevis-pkcs11-common b/src/pins/pkcs11/clevis-pkcs11-common +index 4c0629c..571a2be 100755 +--- a/src/pins/pkcs11/clevis-pkcs11-common ++++ b/src/pins/pkcs11/clevis-pkcs11-common +@@ -27,6 +27,56 @@ serial_devices_array="" + URI_EXPECTED_FORMAT="pkcs11:" + DEFAULT_CRYPTTAB_FILE="/etc/crypttab" + ++clevis_detect_pkcs11_device() { ++ dracut_mode="${1:false}" ++ retry_mode="${2:false}" ++ if ! pkcs11_device=$(pkcs11-tool -L 2>/dev/null | grep "Slot" | head -1 | \ ++ awk -F ":" '{print $2}' | sed -e 's@^ *@@g'); then ++ echo "" ++ return 1 ++ fi ++ ++ if ! pkcs11-tool -O 2>/dev/null 1>/dev/null; then ++ pkcs11_device="" ++ echo "No objects in PKCS11 device detected" >&2 ++ fi ++ ++ while [ -z "${pkcs11_device}" ]; do ++ if [ "${dracut_mode}" != true ]; then ++ module_paths=$(clevis_get_module_path_from_pkcs11_config "/etc/crypttab") ++ if [ -n "${module_paths}" ]; then ++ modules=$(echo ${module_paths} | tr ";" "\n") ++ for module in $modules; do ++ pkcs11_device=$(pkcs11-tool -L --module ${module} | grep "Slot" \ ++ | head -1 | awk -F ":" '{print $2}' | sed -e 's@^ *@@g') ++ if [ -n "${pkcs11_device}" ]; then ++ break; ++ fi ++ done ++ fi ++ fi ++ if [ -z "${pkcs11_device}" ]; then ++ if [ "${retry_mode}" == true ]; then ++ option=$(systemd-ask-password --echo "Detected no PKCS#11 device, retry PKCS#11 detection? [yY/nN]") ++ if [ "${option}" == "N" ] || [ "${option}" == "n" ] ; then ++ echo "" ++ # Straight Forward Mode ++ return 0 ++ fi ++ pkcs11_device=$(pkcs11-tool -L | grep "Slot" \ ++ | head -1 | awk -F ":" '{print $2}' | sed -e 's@^ *@@g') ++ if ! pkcs11-tool -O 2>/dev/null 1>/dev/null; then ++ pkcs11_device="" ++ echo "No objects in PKCS11 device detected" >&2 ++ fi ++ else ++ echo "${pkcs11_device}" ++ return 0 ++ fi ++ fi ++ done ++} ++ + clevis_parse_devices_array() { + INPUT_ARRAY=$(pkcs11-tool -L | grep Slot) + counter=0 +@@ -64,12 +114,10 @@ clevis_get_module_path_from_pkcs11_config() { + while read -r line; do + uuid=$(echo "${line}" | awk '{print $2}') + if ! mapped_device=$(clevis_map_device "${uuid}"); then +- echo "Could not check mapped device for UID:${uuid}" + continue + fi + # If no PKCS#11 configuration, advance to next device + if ! clevis luks list -d "${mapped_device}" | grep pkcs11 >/dev/null 2>&1; then +- echo "Device:${mapped_device} does not contain PKCS#11 configuration" + continue + fi + # Get configuration PKCS#11 URI +-- +2.46.2 + diff --git a/clevis-18.tar.xz b/clevis-18.tar.xz deleted file mode 100644 index 001fcbca967fd5e8ecadd60460569170327850da..0000000000000000000000000000000000000000 Binary files a/clevis-18.tar.xz and /dev/null differ diff --git a/clevis-21.tar.xz b/clevis-21.tar.xz new file mode 100644 index 0000000000000000000000000000000000000000..9fd107decb62f798eb394874c4c680f6b933fdbf Binary files /dev/null and b/clevis-21.tar.xz differ diff --git a/clevis.spec b/clevis.spec index 54195c2c286dd6f4f432ee65683a814663e7153f..b6da51d17ca070aa5df7ac963c6cbb9a69b137c4 100644 --- a/clevis.spec +++ b/clevis.spec @@ -1,19 +1,48 @@ Name: clevis -Version: 18 -Release: 2 +Version: 21 +Release: 1 Summary: A plugable framework for automated decryption -License: GPLv3+ +License: GPL-3.0-or-later URL: https://github.com/latchset/%{name} Source0: https://github.com/latchset/%{name}/releases/download/v%{version}/%{name}-%{version}.tar.xz +Source1: clevis.sysusers + +Patch0001: 0001-PKCS-11-pin-fix-dracut-for-unconfigured-device.patch + +BuildRequires: meson +BuildRequires: pkgconfig(audit) >= 2.7.8 +BuildRequires: pkgconfig(bash-completion) +BuildRequires: pkgconfig(dracut) +BuildRequires: pkgconfig(gio-2.0) +BuildRequires: pkgconfig(jansson) >= 2.10 +BuildRequires: pkgconfig(jose) >= 8 +BuildRequires: pkgconfig(libcrypto) +BuildRequires: pkgconfig(libcryptsetup) >= 2.0.2 +BuildRequires: pkgconfig(luksmeta) >= 8 +BuildRequires: pkgconfig(systemd) +BuildRequires: pkgconfig(udisks2) +BuildRequires: /usr/bin/a2x +BuildRequires: /usr/bin/curl +BuildRequires: /usr/bin/git +BuildRequires: /usr/bin/jq +BuildRequires: /usr/bin/keyctl +BuildRequires: /usr/bin/pkcs11-tool +BuildRequires: /usr/bin/tpm2_create +BuildRequires: /usr/bin/tpm2_createpolicy +BuildRequires: /usr/bin/tpm2_createprimary +BuildRequires: /usr/bin/tpm2_flushcontext +BuildRequires: /usr/bin/tpm2_load +BuildRequires: /usr/bin/tpm2_pcrread +BuildRequires: /usr/bin/tpm2_unseal +BuildRequires: /usr/sbin/cryptsetup +BuildRequires: /usr/sbin/pcscd +BuildRequires: desktop-file-utils -BuildRequires: meson cmake jansson jose pkgconfig libjose-devel asciidoc gcc compat-openssl11-devel -BuildRequires: desktop-file-utils libudisks2-devel audit-libs-devel tang dracut pkgconfig -BuildRequires: bash-completion tpm2-tools luksmeta libluksmeta-devel ninja-build systemd curl -BuildRequires: cracklib-dicts diffutils jq Requires: tpm2-tools jose curl coreutils cryptsetup luksmeta -Provides: clevis-luks -Obsoletes: clevis-luks +Provides: clevis-luks = %{version}-%{release} +Obsoletes: clevis-luks < %{version}-%{release} +Requires(pre): shadow-utils %description Clevis is a plugable framework for automated decryption. It can be used @@ -48,6 +77,20 @@ Requires: %{name}%{?_isa} = %{version}-%{release} The udisks2 unlocker attempts to automatically unlock volumes in desktop environments that use UDisks2 or storaged (like GNOME). +%package pin-pkcs11 +Summary: PKCS#11 for clevis +Requires: %{name}-systemd%{?_isa} = %{version}-%{release} +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: %{name}-dracut%{?_isa} = %{version}-%{release} +Conflicts: %{name} < 21 +Conflicts: %{name}-systemd < 21 +Conflicts: %{name}-dracut < 21 +Requires: pcsc-lite +Requires: opensc + +%description pin-pkcs11 +Automatically unlocks LUKS block devices through a PKCS#11 device. + %package_help %prep @@ -59,6 +102,7 @@ that use UDisks2 or storaged (like GNOME). %install %meson_install +install -p -D -m 0644 %{S:1} %{buildroot}%{_sysusersdir}/clevis.conf %check # add test for clevis-luks-udisks2.desktop: validates the clevis-luks-udisks2.desktop @@ -66,37 +110,83 @@ that use UDisks2 or storaged (like GNOME). desktop-file-validate %{buildroot}%{_sysconfdir}/xdg/autostart/%{name}-luks-udisks2.desktop %meson_test +%pre +%sysusers_create_compat %{S:1} +# Add clevis user to tss group. +if getent group tss >/dev/null && ! groups %{name} | grep -q "\btss\b"; then + usermod -a -G tss %{name} &>/dev/null +fi +exit 0 + %files -%defattr(-,root,root) %license COPYING* -%{_datadir}/bash-completion/ -%{_bindir}/clevis -%{_bindir}/clevis-decrypt* -%{_bindir}/clevis-encrypt* -%{_bindir}/%{name}-luks* +%{_datadir}/bash-completion/* +%{_bindir}/%{name}-decrypt-tang +%{_bindir}/%{name}-decrypt-tpm2 +%{_bindir}/%{name}-decrypt-sss +%{_bindir}/%{name}-decrypt-null +%{_bindir}/%{name}-decrypt +%{_bindir}/%{name}-encrypt-tang +%{_bindir}/%{name}-encrypt-tpm2 +%{_bindir}/%{name}-encrypt-sss +%{_bindir}/%{name}-encrypt-null +%{_bindir}/%{name} +%{_bindir}/%{name}-luks-unlock +%{_bindir}/%{name}-luks-unbind +%{_bindir}/%{name}-luks-bind +%{_bindir}/%{name}-luks-common-functions +%{_bindir}/%{name}-luks-list +%{_bindir}/%{name}-luks-edit +%{_bindir}/%{name}-luks-regen +%{_bindir}/%{name}-luks-report +%{_bindir}/%{name}-luks-pass +%{_sysusersdir}/clevis.conf %files systemd -%defattr(-,root,root) -%{_unitdir}/clevis-luks-askpass* -%{_libexecdir}/clevis-luks-askpass +%{_libexecdir}/%{name}-luks-askpass +%{_libexecdir}/%{name}-luks-unlocker +%{_unitdir}/%{name}-luks-askpass.path +%{_unitdir}/%{name}-luks-askpass.service %files dracut -%defattr(-,root,root) -%{_prefix}/lib/dracut/modules.d/60clevis/* -%{_prefix}/lib/dracut/modules.d/60clevis-pin-sss/module-setup.sh -%{_prefix}/lib/dracut/modules.d/60clevis-pin-tang/module-setup.sh -%{_prefix}/lib/dracut/modules.d/60clevis-pin-tpm2/module-setup.sh +%dir %{_prefix}/lib/dracut/modules.d/60%{name} +%{_prefix}/lib/dracut/modules.d/60%{name}/clevis-hook.sh +%{_prefix}/lib/dracut/modules.d/60%{name}/module-setup.sh +%dir %{_prefix}/lib/dracut/modules.d/60%{name}-pin-null +%{_prefix}/lib/dracut/modules.d/60%{name}-pin-null/module-setup.sh +%dir %{_prefix}/lib/dracut/modules.d/60%{name}-pin-sss +%{_prefix}/lib/dracut/modules.d/60%{name}-pin-sss/module-setup.sh +%dir %{_prefix}/lib/dracut/modules.d/60%{name}-pin-tang +%{_prefix}/lib/dracut/modules.d/60%{name}-pin-tang/module-setup.sh +%dir %{_prefix}/lib/dracut/modules.d/60%{name}-pin-tpm2 +%{_prefix}/lib/dracut/modules.d/60%{name}-pin-tpm2/module-setup.sh %files udisks2 -%defattr(-,root,root) %{_sysconfdir}/xdg/autostart/clevis-luks-udisks2.desktop %attr(4755, root, root) %{_libexecdir}/clevis-luks-udisks2 +%files pin-pkcs11 +%{_libexecdir}/%{name}-luks-pkcs11-askpass +%{_libexecdir}/%{name}-luks-pkcs11-askpin +%{_bindir}/%{name}-decrypt-pkcs11 +%{_bindir}/%{name}-encrypt-pkcs11 +%{_bindir}/%{name}-pkcs11-afunix-socket-unlock +%{_bindir}/%{name}-pkcs11-common +%{_unitdir}/%{name}-luks-pkcs11-askpass.service +%{_unitdir}/%{name}-luks-pkcs11-askpass.socket +%dir %{_prefix}/lib/dracut/modules.d/60%{name}-pin-pkcs11 +%{_prefix}/lib/dracut/modules.d/60%{name}-pin-pkcs11/module-setup.sh +%{_prefix}/lib/dracut/modules.d/60%{name}-pin-pkcs11/%{name}-pkcs11-hook.sh +%{_prefix}/lib/dracut/modules.d/60%{name}-pin-pkcs11/%{name}-pkcs11-prehook.sh + %files help -%defattr(-,root,root) -%{_mandir}/man* +%{_mandir}/man?/* %changelog +* Tue Dec 16 2025 dillon chen - 21-1 +- 2404LTS branch update to 21 +- create user and group in pre section + * Wed Feb 8 2023 dillon chen - 18-2 - buildlrequires compat-openssl11 after openeel upgrade to 3.0 diff --git a/clevis.sysusers b/clevis.sysusers new file mode 100644 index 0000000000000000000000000000000000000000..daad762fb3a2b3776a6ea5563abaac65927c0798 --- /dev/null +++ b/clevis.sysusers @@ -0,0 +1 @@ +u clevis - "Clevis Decryption Framework unprivileged user" /var/cache/clevis -