Subject: Systemd: drop ncat dependency Origin: v15-5-g9cdd041 Upstream-Author: Sergio Correia Date: Wed Dec 2 20:53:48 2020 -0300 When using systemd, i.e., clevis-luks-askpass, we use ncat to send the decrypted password to the systemd socket as per systemd's password agents specification [1]. However, systemd itself has a utility that does exactly that, systemd-reply-password. In this commit we drop the ncat dependency and instead use systemd-reply-password in clevis-luks-askpass. [1] https://systemd.io/PASSWORD_AGENTS/ -- Extra adjustment needed to build on pre-usrmerge chroots. --- a/INSTALL.md +++ b/INSTALL.md @@ -22,7 +22,6 @@ * [tang](https://github.com/latchset/tang) * [curl](https://github.com/curl/curl) * [tpm2-tools](https://github.com/tpm2-software/tpm2-tools) -* [ncat](https://nmap.org/ncat/) (for clevis-luks-askpass) ### Fedora --- a/src/luks/systemd/clevis-luks-askpass +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/bash -set -eu -# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: -# -# Copyright (c) 2016 Red Hat, Inc. -# Author: Harald Hoyer -# Author: Nathaniel McCallum -# -# 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= -path=/run/systemd/ask-password -while getopts ":lp:" o; do - case "${o}" in - l) loop=true;; - p) path="${OPTARG}";; - *) ;; - esac -done - -while true; do - for question in "${path}"/ask.*; do - # question will expand to itself, in case no files match, so we verify - # whether it actually exists, before proceeding. - [ ! -e "${question}" ] && continue - - d= - s= - while read -r line; do - case "$line" in - Id=cryptsetup:*) d="${line##Id=cryptsetup:}";; - Socket=*) s="${line##Socket=}";; - esac - done < "$question" - - [ -b "${d}" ] || continue - [ -S "${s}" ] || continue - - if ! pt="$(clevis_luks_unlock_device "${d}")" || [ -z "${pt}" ]; then - continue - fi - - uuid="$(cryptsetup luksUUID "${d}")" - if ! printf '+%s' "${pt}" | ncat -U -u --send-only "${s}"; then - echo "Unable to unlock ${d} (UUID=${uuid}) with recovered passphrase" >&2 - continue - fi - - echo "Unlocked ${d} (UUID=${uuid}) successfully" >&2 - done - - [ "${loop}" != true ] && break - # Checking for pending devices to be unlocked. - if remaining=$(clevis_devices_to_unlock) && [ -z "${remaining}" ]; then - break; - fi - - sleep 0.5 -done --- /dev/null +++ b/src/luks/systemd/clevis-luks-askpass.in @@ -0,0 +1,76 @@ +#!/bin/bash +set -eu +# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: +# +# Copyright (c) 2016 Red Hat, Inc. +# Author: Harald Hoyer +# Author: Nathaniel McCallum +# +# 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= +path=/run/systemd/ask-password +while getopts ":lp:" o; do + case "${o}" in + l) loop=true;; + p) path="${OPTARG}";; + *) ;; + esac +done + +while true; do + for question in "${path}"/ask.*; do + # question will expand to itself, in case no files match, so we verify + # whether it actually exists, before proceeding. + [ ! -e "${question}" ] && continue + + d= + s= + while read -r line; do + case "$line" in + Id=cryptsetup:*) d="${line##Id=cryptsetup:}";; + Socket=*) s="${line##Socket=}";; + esac + done < "$question" + + [ -b "${d}" ] || continue + [ -S "${s}" ] || continue + + if ! pt="$(clevis_luks_unlock_device "${d}")" || [ -z "${pt}" ]; then + continue + fi + + uuid="$(cryptsetup luksUUID "${d}")" + if ! printf '%s' "${pt}" | @SYSTEMD_REPLY_PASS@ 1 "${s}"; then + echo "Unable to unlock ${d} (UUID=${uuid}) with recovered passphrase" >&2 + continue + fi + + echo "Unlocked ${d} (UUID=${uuid}) successfully" >&2 + done + + [ "${loop}" != true ] && break + # Checking for pending devices to be unlocked. + if remaining=$(clevis_devices_to_unlock) && [ -z "${remaining}" ]; then + break; + fi + + sleep 0.5 +done --- a/src/luks/systemd/dracut/clevis/module-setup.sh.in +++ b/src/luks/systemd/dracut/clevis/module-setup.sh.in @@ -36,6 +36,7 @@ inst_multiple \ /etc/services \ + @SYSTEMD_REPLY_PASS@ \ @libexecdir@/clevis-luks-askpass \ clevis-luks-common-functions \ grep sed cut \ @@ -45,8 +46,7 @@ luksmeta \ clevis \ mktemp \ - jose \ - ncat + jose dracut_need_initqueue } --- a/src/luks/systemd/meson.build +++ b/src/luks/systemd/meson.build @@ -1,6 +1,16 @@ systemd = dependency('systemd', required: false) -if systemd.found() +sd_reply_pass = find_program( + join_paths(get_option('prefix'), get_option('libdir'), 'systemd', 'systemd-reply-password'), + join_paths(get_option('prefix'), 'lib', 'systemd', 'systemd-reply-password'), + join_paths('/', 'usr', get_option('libdir'), 'systemd', 'systemd-reply-password'), + join_paths('/', 'usr', 'lib', 'systemd', 'systemd-reply-password'), + join_paths('/', 'lib', 'systemd', 'systemd-reply-password'), + required: false +) + +if systemd.found() and sd_reply_pass.found() + data.set('SYSTEMD_REPLY_PASS', sd_reply_pass.path()) subdir('dracut') unitdir = systemd.get_pkgconfig_variable('systemdsystemunitdir') @@ -12,8 +22,14 @@ configuration: data, ) + configure_file( + input: 'clevis-luks-askpass.in', + output: 'clevis-luks-askpass', + install_dir: libexecdir, + configuration: data + ) + install_data('clevis-luks-askpass.path', install_dir: unitdir) - install_data('clevis-luks-askpass', install_dir: libexecdir) else warning('Will not install systemd support due to missing dependencies!') endif