import clevis-15-1.el8

This commit is contained in:
CentOS Sources 2021-05-18 02:44:16 -04:00 committed by Andrew Lukoshko
parent b2e84aface
commit dbe4f9bd04
14 changed files with 276 additions and 4863 deletions

View File

@ -1 +1 @@
83aebcbe5792b43bf281b442f379cea08d7c43b0 SOURCES/clevis-13.tar.xz
ce825a10c5aa885e001c963be4cc4a8dea2137b0 SOURCES/clevis-15.tar.xz

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/clevis-13.tar.xz
SOURCES/clevis-15.tar.xz

View File

@ -1,84 +0,0 @@
From 27a27befed2257c2156ed8b94d679951b9b1a4d5 Mon Sep 17 00:00:00 2001
From: Sergio Correia <scorreia@redhat.com>
Date: Wed, 13 May 2020 23:51:04 -0300
Subject: [PATCH 1/8] Adjust pin-tang test to account for newer tang without
tangd-update
---
src/luks/tests/unbind-unbound-slot-luks2 | 1 +
src/pins/tang/meson.build | 8 +-------
src/pins/tang/pin-tang | 11 ++++++++---
3 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/luks/tests/unbind-unbound-slot-luks2 b/src/luks/tests/unbind-unbound-slot-luks2
index 6a2aca5..6d814ad 100755
--- a/src/luks/tests/unbind-unbound-slot-luks2
+++ b/src/luks/tests/unbind-unbound-slot-luks2
@@ -36,6 +36,7 @@ TMP="$(mktemp -d)"
DEV="${TMP}/luks2-device"
new_device "luks2" "${DEV}"
+SLT=2
if clevis luks unbind -d "${DEV}" -s "${SLT}"; then
error "${TEST}: Unbind is expected to fail for device ${DEV} and slot ${SLT}" >&2
fi
diff --git a/src/pins/tang/meson.build b/src/pins/tang/meson.build
index 74a3442..9b9a3db 100644
--- a/src/pins/tang/meson.build
+++ b/src/pins/tang/meson.build
@@ -9,12 +9,6 @@ kgen = find_program(
'/usr/lib/x86_64-linux-gnu/tangd-keygen',
required: false
)
-updt = find_program(
- join_paths(libexecdir, 'tangd-update'),
- '/usr/libexec/tangd-update',
- '/usr/lib/x86_64-linux-gnu/tangd-update',
- required: false
-)
tang = find_program(
join_paths(libexecdir, 'tangd'),
'/usr/libexec/tangd',
@@ -28,7 +22,7 @@ if curl.found()
bins += join_paths(meson.current_source_dir(), 'clevis-encrypt-tang')
mans += join_paths(meson.current_source_dir(), 'clevis-encrypt-tang.1')
- if actv.found() and kgen.found() and updt.found() and tang.found()
+ if actv.found() and kgen.found() and tang.found()
env = environment()
env.set('SD_ACTIVATE', actv.path())
env.append('PATH',
diff --git a/src/pins/tang/pin-tang b/src/pins/tang/pin-tang
index 1720d3d..8190f3d 100755
--- a/src/pins/tang/pin-tang
+++ b/src/pins/tang/pin-tang
@@ -31,18 +31,23 @@ mkdir -p "$TMP"/db
mkdir -p "$TMP"/cache
# Generate the server keys
+KEYS="$TMP"/db
tangd-keygen "$TMP"/db sig exc
-tangd-update "$TMP"/db "$TMP"/cache
+if which tangd-update; then
+ tangd-update "$TMP"/db "$TMP"/cache
+ KEYS=$TMP/cache
+fi
# Start the server
port="$(shuf -i 1024-65536 -n 1)"
-$SD_ACTIVATE --inetd -l 127.0.0.1:$port -a tangd "$TMP"/cache &
+$SD_ACTIVATE --inetd -l 127.0.0.1:$port -a tangd "$KEYS" &
PID=$!
sleep 0.25
thp="$(jose jwk thp -i "$TMP/db/sig.jwk")"
-adv="$TMP/cache/default.jws"
url="http://localhost:${port}"
+adv="$TMP/adv"
+curl "$url/adv" -o $adv
cfg="$(printf '{"url":"%s","adv":"%s"}' "$url" "$adv")"
enc="$(echo -n "hi" | clevis encrypt tang "$cfg")"
--
2.18.4

View File

@ -0,0 +1,176 @@
From 16f667d9f3d649e33ca762afa1a8a7f909b953a8 Mon Sep 17 00:00:00 2001
From: Sergio Correia <scorreia@redhat.com>
Date: Sun, 25 Oct 2020 11:15:46 -0300
Subject: [PATCH] Fixes for dealing with newer tang without tangd-update
---
src/luks/tests/meson.build | 11 +----------
src/luks/tests/tests-common-functions.in | 19 +++++++++++--------
src/pins/tang/meson.build | 11 +----------
src/pins/tang/pin-tang | 11 ++++++++---
4 files changed, 21 insertions(+), 31 deletions(-)
diff --git a/src/luks/tests/meson.build b/src/luks/tests/meson.build
index ba5f6a2..c0f9dc3 100644
--- a/src/luks/tests/meson.build
+++ b/src/luks/tests/meson.build
@@ -17,14 +17,6 @@ kgen = find_program(
join_paths('/', 'usr', get_option('libexecdir'), 'tangd-keygen'),
required: false
)
-updt = find_program(
- join_paths(libexecdir, 'tangd-update'),
- join_paths(get_option('prefix'), get_option('libdir'), 'tangd-update'),
- join_paths(get_option('prefix'), get_option('libexecdir'), 'tangd-update'),
- join_paths('/', 'usr', get_option('libdir'), 'tangd-update'),
- join_paths('/', 'usr', get_option('libexecdir'), 'tangd-update'),
- required: false
-)
tang = find_program(
join_paths(libexecdir, 'tangd'),
join_paths(get_option('prefix'), get_option('libdir'), 'tangd'),
@@ -58,11 +50,10 @@ env.prepend('PATH',
)
has_tang = false
-if actv.found() and kgen.found() and updt.found() and tang.found()
+if actv.found() and kgen.found() and tang.found()
has_tang = true
env.set('SD_ACTIVATE', actv.path())
env.set('TANGD_KEYGEN', kgen.path())
- env.set('TANGD_UPDATE', updt.path())
env.set('TANGD', tang.path())
endif
diff --git a/src/luks/tests/tests-common-functions.in b/src/luks/tests/tests-common-functions.in
index 8520715..318d007 100755
--- a/src/luks/tests/tests-common-functions.in
+++ b/src/luks/tests/tests-common-functions.in
@@ -251,18 +251,19 @@ tang_remove_rotated_keys() {
return 1
fi
- [ -z "${TANGD_UPDATE}" ] && skip_test "WARNING: TANGD_UPDATE is not defined."
-
local db="${basedir}/db"
- local cache="${basedir}/cache"
mkdir -p "${db}"
- mkdir -p "${cache}"
+
+ if [ -n "${TANGD_UPDATE}" ]; then
+ local cache="${basedir}/cache"
+ mkdir -p "${cache}"
+ fi
pushd "${db}"
find . -name ".*.jwk" -exec rm -f {} \;
popd
- "${TANGD_UPDATE}" "${db}" "${cache}"
+ [ -n "${TANGD_UPDATE}" ] && "${TANGD_UPDATE}" "${db}" "${cache}"
return 0
}
@@ -277,12 +278,12 @@ tang_new_keys() {
fi
[ -z "${TANGD_KEYGEN}" ] && skip_test "WARNING: TANGD_KEYGEN is not defined."
- [ -z "${TANGD_UPDATE}" ] && skip_test "WARNING: TANGD_UPDATE is not defined."
local db="${basedir}/db"
- local cache="${basedir}/cache"
mkdir -p "${db}"
+ [ -n "${TANGD_UPDATE}" ] && local cache="${basedir}/cache"
+
if [ -n "${rotate}" ]; then
pushd "${db}"
local k
@@ -296,7 +297,7 @@ tang_new_keys() {
fi
"${TANGD_KEYGEN}" "${db}"
- "${TANGD_UPDATE}" "${db}" "${cache}"
+ [ -n "${TANGD_UPDATE}" ] && "${TANGD_UPDATE}" "${db}" "${cache}"
return 0
}
@@ -322,6 +323,8 @@ tang_run() {
fi
local KEYS="${basedir}/cache"
+ [ -z "${TANGD_UPDATE}" ] && KEYS="${basedir}/db"
+
local inetd='--inetd'
[ "${SD_ACTIVATE##*/}" = "systemd-activate" ] && inetd=
diff --git a/src/pins/tang/meson.build b/src/pins/tang/meson.build
index f7d8226..ebcdd4a 100644
--- a/src/pins/tang/meson.build
+++ b/src/pins/tang/meson.build
@@ -12,14 +12,6 @@ kgen = find_program(
join_paths('/', 'usr', get_option('libexecdir'), 'tangd-keygen'),
required: false
)
-updt = find_program(
- join_paths(libexecdir, 'tangd-update'),
- join_paths(get_option('prefix'), get_option('libdir'), 'tangd-update'),
- join_paths(get_option('prefix'), get_option('libexecdir'), 'tangd-update'),
- join_paths('/', 'usr', get_option('libdir'), 'tangd-update'),
- join_paths('/', 'usr', get_option('libexecdir'), 'tangd-update'),
- required: false
-)
tang = find_program(
join_paths(libexecdir, 'tangd'),
join_paths(get_option('prefix'), get_option('libdir'), 'tangd'),
@@ -35,11 +27,10 @@ if curl.found()
bins += join_paths(meson.current_source_dir(), 'clevis-encrypt-tang')
mans += join_paths(meson.current_source_dir(), 'clevis-encrypt-tang.1')
- if actv.found() and kgen.found() and updt.found() and tang.found()
+ if actv.found() and kgen.found() and tang.found()
env = environment()
env.set('SD_ACTIVATE', actv.path())
env.set('TANGD_KEYGEN', kgen.path())
- env.set('TANGD_UPDATE', updt.path())
env.set('TANGD', tang.path())
env.prepend('PATH',
join_paths(meson.source_root(), 'src'),
diff --git a/src/pins/tang/pin-tang b/src/pins/tang/pin-tang
index 98e5e4d..a63d0a2 100755
--- a/src/pins/tang/pin-tang
+++ b/src/pins/tang/pin-tang
@@ -31,8 +31,12 @@ mkdir -p "$TMP"/db
mkdir -p "$TMP"/cache
# Generate the server keys
+KEYS="$TMP"/db
"${TANGD_KEYGEN}" "$TMP"/db sig exc
-"${TANGD_UPDATE}" "$TMP"/db "$TMP"/cache
+if which tangd-update; then
+ tangd-update "$TMP"/db "$TMP"/cache
+ KEYS="$TMP"/cache
+fi
# Start the server
port="$(shuf -i 1024-65536 -n 1)"
@@ -40,13 +44,14 @@ port="$(shuf -i 1024-65536 -n 1)"
inetd='--inetd'
[ "${SD_ACTIVATE##*/}" = "systemd-activate" ] && inetd=
-"$SD_ACTIVATE" $inetd -l 127.0.0.1:"$port" -a "$TANGD" "$TMP"/cache &
+"$SD_ACTIVATE" $inetd -l 127.0.0.1:"$port" -a "$TANGD" "$KEYS" &
PID=$!
sleep 0.25
thp="$(jose jwk thp -i "$TMP/db/sig.jwk")"
-adv="$TMP/cache/default.jws"
url="http://localhost:${port}"
+adv="$TMP/adv"
+curl "$url/adv" -o "$adv"
cfg="$(printf '{"url":"%s","adv":"%s"}' "$url" "$adv")"
enc="$(echo -n "hi" | clevis encrypt tang "$cfg")"
--
2.18.4

View File

@ -1,7 +1,7 @@
From e3641a7193adac1cea525c093f39679c2cfa22c9 Mon Sep 17 00:00:00 2001
From: Sergio Correia <scorreia@redhat.com>
Date: Wed, 13 May 2020 23:53:38 -0300
Subject: [PATCH 5/8] Add the option to extract luks passphrase used for
From aa52396c35e76aabd085a819b08167d559042a20 Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Tue, 3 Nov 2020 08:42:48 -0300
Subject: [PATCH 2/2] Add the option to extract luks passphrase used for
binding
Usage:
@ -9,13 +9,13 @@ Usage:
clevis luks pass -d /dev/sda1 -s 1
<passphrase here>
---
src/luks/clevis-luks-pass | 69 +++++++++++++++++++++++++++++
src/luks/clevis-luks-pass.1.adoc | 43 ++++++++++++++++++
src/luks/clevis-luks-pass | 64 ++++++++++++++++++++++++++++++++
src/luks/clevis-luks-pass.1.adoc | 43 +++++++++++++++++++++
src/luks/meson.build | 3 ++
src/luks/tests/meson.build | 11 +++++
src/luks/tests/pass-tang-luks1 | 75 ++++++++++++++++++++++++++++++++
src/luks/tests/pass-tang-luks2 | 75 ++++++++++++++++++++++++++++++++
6 files changed, 276 insertions(+)
src/luks/tests/meson.build | 2 +
src/luks/tests/pass-tang-luks1 | 59 +++++++++++++++++++++++++++++
src/luks/tests/pass-tang-luks2 | 59 +++++++++++++++++++++++++++++
6 files changed, 230 insertions(+)
create mode 100755 src/luks/clevis-luks-pass
create mode 100644 src/luks/clevis-luks-pass.1.adoc
create mode 100755 src/luks/tests/pass-tang-luks1
@ -23,12 +23,12 @@ clevis luks pass -d /dev/sda1 -s 1
diff --git a/src/luks/clevis-luks-pass b/src/luks/clevis-luks-pass
new file mode 100755
index 0000000..1ce8c4c
index 0000000..1f59b39
--- /dev/null
+++ b/src/luks/clevis-luks-pass
@@ -0,0 +1,69 @@
@@ -0,0 +1,64 @@
+#!/bin/bash -e
+# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
+# vim: set ts=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
+#
+# Copyright (c) 2019 Red Hat, Inc.
+# Author: Sergio Correia <scorreia@redhat.com> - LUKS2 support.
@ -51,16 +51,16 @@ index 0000000..1ce8c4c
+
+SUMMARY="Returns the LUKS passphrase used for binding a particular slot."
+
+function usage() {
+ echo >&2
+ echo "Usage: clevis luks pass -d DEV -s SLT" >&2
+ echo >&2
+ echo "$SUMMARY": >&2
+ echo >&2
+ echo " -d DEV The LUKS device to extract the LUKS passphrase used for binding" >&2
+ echo >&2
+ echo " -s SLOT The slot number to extract the LUKS passphrase" >&2
+ echo >&2
+usage() {
+ exec >&2
+ echo "Usage: clevis luks pass -d DEV -s SLT"
+ echo
+ echo "$SUMMARY"
+ echo
+ echo " -d DEV The LUKS device to extract the LUKS passphrase used for binding"
+ echo
+ echo " -s SLOT The slot number to extract the LUKS passphrase"
+ echo
+ exit 1
+}
+
@ -87,13 +87,8 @@ index 0000000..1ce8c4c
+ usage
+fi
+
+if ! jwe=$(clevis_luks_read_slot "${DEV}" "${SLT}" 2>/dev/null); then
+ echo "It was not possible to read slot ${SLT} from ${DEV}!" >&2
+ exit 1
+fi
+
+if ! clevis decrypt < <(echo -n "${jwe}"); then
+ echo "It was not possible to decrypt the passphrase associated to slot ${SLT} in {DEV}!" >&2
+if ! clevis_luks_unlock_device_by_slot "${DEV}" "${SLT}"; then
+ echo "It was not possible to decrypt the passphrase associated to slot ${SLT} in ${DEV}!" >&2
+ exit 1
+fi
diff --git a/src/luks/clevis-luks-pass.1.adoc b/src/luks/clevis-luks-pass.1.adoc
@ -146,13 +141,13 @@ index 0000000..fa9526a
+
+link:clevis-luks-unlock.1.adoc[*clevis-luks-unlock*(1)],
diff --git a/src/luks/meson.build b/src/luks/meson.build
index 0d24f8d..fda2ca8 100644
index 12f5a0d..008736e 100644
--- a/src/luks/meson.build
+++ b/src/luks/meson.build
@@ -41,6 +41,9 @@ if libcryptsetup.found() and luksmeta.found() and pwmake.found()
@@ -50,6 +50,9 @@ if libcryptsetup.found() and luksmeta.found() and pwmake.found()
bins += join_paths(meson.current_source_dir(), 'clevis-luks-unlock')
mans += join_paths(meson.current_source_dir(), 'clevis-luks-unlock.1')
bins += join_paths(meson.current_source_dir(), 'clevis-luks-edit')
mans += join_paths(meson.current_source_dir(), 'clevis-luks-edit.1')
+
+ bins += join_paths(meson.current_source_dir(), 'clevis-luks-pass')
+ mans += join_paths(meson.current_source_dir(), 'clevis-luks-pass.1')
@ -160,51 +155,31 @@ index 0d24f8d..fda2ca8 100644
warning('Will not install LUKS support due to missing dependencies!')
endif
diff --git a/src/luks/tests/meson.build b/src/luks/tests/meson.build
index 9a16b42..4757c4b 100644
index c22a069..f4584aa 100644
--- a/src/luks/tests/meson.build
+++ b/src/luks/tests/meson.build
@@ -1,3 +1,9 @@
+actv = find_program(
+ 'systemd-socket-activate',
+ 'systemd-activate',
+ required: false
+)
+
# We use jq for comparing the pin config in the clevis luks list tests.
jq = find_program('jq', required: false)
@@ -45,8 +51,11 @@ env.prepend('PATH',
join_paths(meson.build_root(), 'src', 'pins', 'sss'),
join_paths(meson.build_root(), 'src', 'pins', 'tang'),
join_paths(meson.build_root(), 'src', 'pins', 'tpm2'),
+ libexecdir,
+ '/usr/libexec',
separator: ':'
)
+env.set('SD_ACTIVATE', actv.path())
has_tang = false
if actv.found() and kgen.found() and tang.found()
@@ -77,6 +86,7 @@ endif
if has_tang
test('unlock-tang-luks1', find_program('unlock-tang-luks1'), env: env, timeout: 90)
@@ -84,6 +84,7 @@ if has_tang
test('report-tang-luks1', find_program('report-tang-luks1'), env: env, timeout: 90)
test('report-sss-luks1', find_program('report-sss-luks1'), env: env, timeout: 90)
test('edit-tang-luks1', find_program('edit-tang-luks1'), env: env, timeout: 150)
+ test('pass-tang-luks1', find_program('pass-tang-luks1'), env: env, timeout: 60)
endif
+test('pass-tang-luks1', find_program('pass-tang-luks1'), env: env)
# LUKS2 tests go here, and they get included if we get support for it, based
# on the cryptsetup version.
@@ -96,4 +106,5 @@ if luksmeta_data.get('OLD_CRYPTSETUP') == '0'
if has_tang
test('unlock-tang-luks2', find_program('unlock-tang-luks2'), env: env, timeout: 120)
test('backup-restore-luks1', find_program('backup-restore-luks1'), env: env, timeout: 60)
@@ -111,6 +112,7 @@ if luksmeta_data.get('OLD_CRYPTSETUP') == '0'
test('report-tang-luks2', find_program('report-tang-luks2'), env: env, timeout: 120)
test('report-sss-luks2', find_program('report-sss-luks2'), env: env, timeout: 120)
test('edit-tang-luks2', find_program('edit-tang-luks2'), env: env, timeout: 210)
+ test('pass-tang-luks2', find_program('pass-tang-luks2'), env: env, timeout: 60)
endif
+ test('pass-tang-luks2', find_program('pass-tang-luks2'), env: env, timeout: 60)
endif
test('backup-restore-luks2', find_program('backup-restore-luks2'), env: env, timeout: 120)
diff --git a/src/luks/tests/pass-tang-luks1 b/src/luks/tests/pass-tang-luks1
new file mode 100755
index 0000000..05cdb3e
index 0000000..0d91e6c
--- /dev/null
+++ b/src/luks/tests/pass-tang-luks1
@@ -0,0 +1,75 @@
@@ -0,0 +1,59 @@
+#!/bin/bash -x
+# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
+#
@ -227,36 +202,25 @@ index 0000000..05cdb3e
+
+TEST="${0}"
+. tests-common-functions
+. clevis-luks-common-functions
+
+function on_exit() {
+ if [ "$PID" ]; then kill $PID; wait $PID || true; fi
+ [ -d "$TMP" ] && rm -rf $TMP
+ [ ! -d "${TMP}" ] && return 0
+ tang_stop "${TMP}"
+ rm -rf "${TMP}"
+}
+
+trap 'on_exit' EXIT
+trap 'exit' ERR
+
+export TMP=$(mktemp -d)
+mkdir -p "${TMP}/db"
+TMP=$(mktemp -d)
+
+# Generate the server keys
+KEYS="$TMP/db"
+tangd-keygen $TMP/db sig exc
+if which tangd-update; then
+ mkdir -p "${TMP}/cache"
+ tangd-update "${TMP}/db" "${TMP}/cache"
+ KEYS="${TMP}/cache"
+fi
+
+# Start the server.
+port=$(shuf -i 1024-65536 -n 1)
+"${SD_ACTIVATE}" --inetd -l 127.0.0.1:"${port}" -a tangd "${KEYS}" &
+export PID=$!
+sleep 0.25
+port=$(get_random_port)
+tang_run "${TMP}" "${port}" &
+tang_wait_until_ready "${port}"
+
+url="http://localhost:${port}"
+adv="${TMP}/adv"
+curl "${url}/adv" -o "${adv}"
+tang_get_adv "${port}" "${adv}"
+
+cfg=$(printf '{"url":"%s","adv":"%s"}' "$url" "$adv")
+
@ -268,24 +232,19 @@ index 0000000..05cdb3e
+ error "${TEST}: Bind should have succeeded."
+fi
+
+#Now let's test the passphrase.
+# Now let's test the passphrase.
+SLT=1
+PASS=$(clevis luks pass -d "${DEV}" -s "${SLT}")
+echo $PASS >&2
+if ! cryptsetup luksOpen --test-passphrase ""${DEV} \
+ --key-file <(clevis luks pass -d "${DEV}" -s "${SLT}"); then
+if ! clevis_luks_check_valid_key_or_keyfile "${DEV}" "${PASS}" "" "${SLT}"; then
+ error "Passphrase obtained from clevis luks pass failed."
+fi
+
+kill -9 "${PID}"
+! wait "${PID}"
+unset PID
diff --git a/src/luks/tests/pass-tang-luks2 b/src/luks/tests/pass-tang-luks2
new file mode 100755
index 0000000..9123aa0
index 0000000..2d50413
--- /dev/null
+++ b/src/luks/tests/pass-tang-luks2
@@ -0,0 +1,75 @@
@@ -0,0 +1,59 @@
+#!/bin/bash -x
+# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
+#
@ -308,36 +267,25 @@ index 0000000..9123aa0
+
+TEST="${0}"
+. tests-common-functions
+. clevis-luks-common-functions
+
+function on_exit() {
+ if [ "$PID" ]; then kill $PID; wait $PID || true; fi
+ [ -d "$TMP" ] && rm -rf $TMP
+ [ ! -d "${TMP}" ] && return 0
+ tang_stop "${TMP}"
+ rm -rf "${TMP}"
+}
+
+trap 'on_exit' EXIT
+trap 'exit' ERR
+
+export TMP=$(mktemp -d)
+mkdir -p "${TMP}/db"
+TMP=$(mktemp -d)
+
+# Generate the server keys
+KEYS="$TMP/db"
+tangd-keygen $TMP/db sig exc
+if which tangd-update; then
+ mkdir -p "${TMP}/cache"
+ tangd-update "${TMP}/db" "${TMP}/cache"
+ KEYS="${TMP}/cache"
+fi
+
+# Start the server.
+port=$(shuf -i 1024-65536 -n 1)
+"${SD_ACTIVATE}" --inetd -l 127.0.0.1:"${port}" -a tangd "${KEYS}" &
+export PID=$!
+sleep 0.25
+port=$(get_random_port)
+tang_run "${TMP}" "${port}" &
+tang_wait_until_ready "${port}"
+
+url="http://localhost:${port}"
+adv="${TMP}/adv"
+curl "${url}/adv" -o "${adv}"
+tang_get_adv "${port}" "${adv}"
+
+cfg=$(printf '{"url":"%s","adv":"%s"}' "$url" "$adv")
+
@ -349,18 +297,13 @@ index 0000000..9123aa0
+ error "${TEST}: Bind should have succeeded."
+fi
+
+#Now let's test the passphrase.
+# Now let's test the passphrase.
+SLT=1
+PASS=$(clevis luks pass -d "${DEV}" -s "${SLT}")
+echo $PASS >&2
+if ! cryptsetup luksOpen --test-passphrase ""${DEV} \
+ --key-file <(clevis luks pass -d "${DEV}" -s "${SLT}"); then
+if ! clevis_luks_check_valid_key_or_keyfile "${DEV}" "${PASS}" "" "${SLT}"; then
+ error "Passphrase obtained from clevis luks pass failed."
+fi
+
+kill -9 "${PID}"
+! wait "${PID}"
+unset PID
--
2.18.4
2.29.2

View File

@ -1,732 +0,0 @@
From e5f6d87d5c71f3faf0c0dbe38534fd3eab30f43e Mon Sep 17 00:00:00 2001
From: Sergio Correia <scorreia@redhat.com>
Date: Wed, 13 May 2020 23:51:04 -0300
Subject: [PATCH 2/8] Fix clevis luks unlock and add related tests
---
src/luks/clevis-luks-common-functions | 35 ++++++
src/luks/clevis-luks-unlock | 68 ++++++++++++
src/luks/clevis-luks-unlock.in | 130 ----------------------
src/luks/meson.build | 10 +-
src/luks/tests/meson.build | 40 +++++++
src/luks/tests/tests-common-functions.in | 134 +++++++++++++++++++++--
src/luks/tests/unlock-tang-luks1 | 83 ++++++++++++++
src/luks/tests/unlock-tang-luks2 | 83 ++++++++++++++
8 files changed, 439 insertions(+), 144 deletions(-)
create mode 100755 src/luks/clevis-luks-unlock
delete mode 100755 src/luks/clevis-luks-unlock.in
create mode 100755 src/luks/tests/unlock-tang-luks1
create mode 100755 src/luks/tests/unlock-tang-luks2
diff --git a/src/luks/clevis-luks-common-functions b/src/luks/clevis-luks-common-functions
index e27c444..d04fdb5 100644
--- a/src/luks/clevis-luks-common-functions
+++ b/src/luks/clevis-luks-common-functions
@@ -281,3 +281,38 @@ clevis_luks_read_pins_from_slot() {
fi
printf "%s: %s\n" "${SLOT}" "${cfg}"
}
+
+# clevis_luks_unlock_device() does the unlock of the device passed as
+# parameter and returns the decoded passphrase.
+clevis_luks_unlock_device() {
+ local DEV="${1}"
+ [ -z "${DEV}" ] && return 1
+
+ local used_slots
+ if ! used_slots=$(clevis_luks_used_slots "${DEV}") \
+ || [ -z "${used_slots}" ]; then
+ return 1
+ fi
+
+ local slt jwe passphrase
+ for slt in ${used_slots}; do
+ if ! jwe="$(clevis_luks_read_slot "${DEV}" "${slt}" 2>/dev/null)" \
+ || [ -z "${jwe}" ]; then
+ continue
+ fi
+
+ if ! passphrase="$(clevis decrypt < <(echo -n "${jwe}"))" \
+ || [ -z "${passphrase}" ]; then
+ continue
+ fi
+
+ if ! cryptsetup luksOpen --test-passphrase "${DEV}" \
+ --key-file <(echo -n "${passphrase}"); then
+ continue
+ fi
+ echo -n "${passphrase}"
+ return 0
+ done
+
+ return 1
+}
diff --git a/src/luks/clevis-luks-unlock b/src/luks/clevis-luks-unlock
new file mode 100755
index 0000000..580fde8
--- /dev/null
+++ b/src/luks/clevis-luks-unlock
@@ -0,0 +1,68 @@
+#!/bin/bash -e
+# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
+#
+# Copyright (c) 2016 Red Hat, Inc.
+# Author: Nathaniel McCallum <npmccallum@redhat.com>
+#
+# 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 <http://www.gnu.org/licenses/>.
+#
+. clevis-luks-common-functions
+
+SUMMARY="Unlocks a LUKS volume"
+
+function usage() {
+ exec >&2
+ echo
+ echo "Usage: clevis luks unlock -d DEV [-n NAME]"
+ echo
+ echo "$SUMMARY":
+ echo
+ echo " -d DEV The LUKS device on which to perform unlocking"
+ echo
+ echo " -n NAME The name of the unlocked device node"
+ echo
+ exit 2
+}
+
+if [ $# -eq 1 ] && [ "$1" == "--summary" ]; then
+ echo "$SUMMARY"
+ exit 0
+fi
+
+while getopts ":d:n:" o; do
+ case "$o" in
+ d) DEV="$OPTARG";;
+ n) NAME="$OPTARG";;
+ *) usage;;
+ esac
+done
+
+if [ -z "$DEV" ]; then
+ echo "Did not specify a device!" >&2
+ usage
+fi
+
+if ! cryptsetup isLuks "$DEV"; then
+ echo "$DEV is not a LUKS device!" >&2
+ exit 1
+fi
+
+NAME="${NAME:-luks-"$(cryptsetup luksUUID "$DEV")"}"
+
+if ! pt=$(clevis_luks_unlock_device "${DEV}"); then
+ echo "${DEV} could not be opened." >&2
+ exit 1
+fi
+
+cryptsetup open -d- "${DEV}" "${NAME}" < <(echo -n "${pt}")
diff --git a/src/luks/clevis-luks-unlock.in b/src/luks/clevis-luks-unlock.in
deleted file mode 100755
index aa3134b..0000000
--- a/src/luks/clevis-luks-unlock.in
+++ /dev/null
@@ -1,130 +0,0 @@
-#!/bin/bash -e
-# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
-#
-# Copyright (c) 2016 Red Hat, Inc.
-# Author: Nathaniel McCallum <npmccallum@redhat.com>
-#
-# 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 <http://www.gnu.org/licenses/>.
-#
-
-SUMMARY="Unlocks a LUKS volume"
-UUID=cb6e8904-81ff-40da-a84a-07ab9ab5715e
-
-# We require cryptsetup >= 2.0.4 to fully support LUKSv2.
-# Support is determined at build time.
-function luks2_supported() {
- return @OLD_CRYPTSETUP@
-}
-
-function usage() {
- exec >&2
- echo
- echo "Usage: clevis luks unlock -d DEV [-n NAME]"
- echo
- echo "$SUMMARY":
- echo
- echo " -d DEV The LUKS device on which to perform unlocking"
- echo
- echo " -n NAME The name of the unlocked device node"
- echo
- exit 2
-}
-
-if [ $# -eq 1 ] && [ "$1" == "--summary" ]; then
- echo "$SUMMARY"
- exit 0
-fi
-
-while getopts ":d:n:" o; do
- case "$o" in
- d) DEV="$OPTARG";;
- n) NAME="$OPTARG";;
- *) usage;;
- esac
-done
-
-if [ -z "$DEV" ]; then
- echo "Did not specify a device!" >&2
- usage
-fi
-
-if ! cryptsetup isLuks "$DEV"; then
- echo "$DEV is not a LUKS device!" >&2
- exit 1
-fi
-
-if luks2_supported; then
- if cryptsetup isLuks --type luks1 "$DEV"; then
- luks_type="luks1"
- elif cryptsetup isLuks --type luks2 "$DEV";then
- luks_type="luks2"
- else
- echo "$DEV is not a supported LUKS device!" >&2
- exit 1
- fi
-else
- luks_type="luks1"
-fi
-NAME="${NAME:-luks-"$(cryptsetup luksUUID "$DEV")"}"
-
-luks1_decrypt() {
- luksmeta load "$@" \
- | clevis decrypt
-
- local rc
- for rc in "${PIPESTATUS[@]}"; do
- [ $rc -eq 0 ] || return $rc
- done
- return 0
-}
-
-luks2_decrypt() {
- # jose jwe fmt -c outputs extra \n, so clean it up
- cryptsetup token export "$@" \
- | jose fmt -j- -Og jwe -o- \
- | jose jwe fmt -i- -c \
- | tr -d '\n' \
- | clevis decrypt
-
- local rc
- for rc in "${PIPESTATUS[@]}"; do
- [ $rc -eq 0 ] || return $rc
- done
- return 0
-}
-
-if [ "$luks_type" == "luks1" ]; then
- while read -r slot state uuid; do
- [ "$state" == "active" ] || continue
- [ "$uuid" == "$UUID" ] || continue
-
- pt="$(luks1_decrypt -d $DEV -s $slot -u $UUID)" \
- || continue
- exec cryptsetup open -d- "$DEV" "$NAME" < <(
- echo -n "$pt"
- )
- done < <(luksmeta show -d "$DEV")
-
-elif [ "$luks_type" == "luks2" ]; then
- while read -r id; do
- pt="$(luks2_decrypt --token-id "$id" "$DEV")" \
- || continue
- exec cryptsetup open -d- "$DEV" "$NAME" < <(
- echo -n "$pt"
- )
- done < <(cryptsetup luksDump "$DEV" | sed -rn 's|^\s+([0-9]+): clevis|\1|p')
-fi
-
-echo "$DEV could not be opened." >&2
-exit 1
diff --git a/src/luks/meson.build b/src/luks/meson.build
index bbba63f..0d24f8d 100644
--- a/src/luks/meson.build
+++ b/src/luks/meson.build
@@ -21,9 +21,7 @@ clevis_luks_bind = configure_file(input: 'clevis-luks-bind.in',
clevis_luks_unbind = configure_file(input: 'clevis-luks-unbind.in',
output: 'clevis-luks-unbind',
configuration: luksmeta_data)
-clevis_luks_unlock = configure_file(input: 'clevis-luks-unlock.in',
- output: 'clevis-luks-unlock',
- configuration: luksmeta_data)
+
if libcryptsetup.found() and luksmeta.found() and pwmake.found()
subdir('systemd')
subdir('udisks2')
@@ -31,18 +29,18 @@ if libcryptsetup.found() and luksmeta.found() and pwmake.found()
bins += clevis_luks_unbind
mans += join_paths(meson.current_source_dir(), 'clevis-luks-unbind.1')
- bins += clevis_luks_unlock
- mans += join_paths(meson.current_source_dir(), 'clevis-luks-unlock.1')
-
bins += clevis_luks_bind
mans += join_paths(meson.current_source_dir(), 'clevis-luks-bind.1')
mans += join_paths(meson.current_source_dir(), 'clevis-luks-unlockers.7')
bins += join_paths(meson.current_source_dir(), 'clevis-luks-common-functions')
+
bins += join_paths(meson.current_source_dir(), 'clevis-luks-list')
mans += join_paths(meson.current_source_dir(), 'clevis-luks-list.1')
+ bins += join_paths(meson.current_source_dir(), 'clevis-luks-unlock')
+ mans += join_paths(meson.current_source_dir(), 'clevis-luks-unlock.1')
else
warning('Will not install LUKS support due to missing dependencies!')
endif
diff --git a/src/luks/tests/meson.build b/src/luks/tests/meson.build
index 2e0fb92..9a16b42 100644
--- a/src/luks/tests/meson.build
+++ b/src/luks/tests/meson.build
@@ -1,6 +1,30 @@
# We use jq for comparing the pin config in the clevis luks list tests.
jq = find_program('jq', required: false)
+# we use systemd-socket-activate for running test tang servers.
+actv = find_program(
+ 'systemd-socket-activate',
+ 'systemd-activate',
+ required: false
+)
+
+kgen = find_program(
+ join_paths(libexecdir, 'tangd-keygen'),
+ join_paths(get_option('prefix'), get_option('libdir'), 'tangd-keygen'),
+ join_paths(get_option('prefix'), get_option('libexecdir'), 'tangd-keygen'),
+ join_paths('/', 'usr', get_option('libdir'), 'tangd-keygen'),
+ join_paths('/', 'usr', get_option('libexecdir'), 'tangd-keygen'),
+ required: false
+)
+tang = find_program(
+ join_paths(libexecdir, 'tangd'),
+ join_paths(get_option('prefix'), get_option('libdir'), 'tangd'),
+ join_paths(get_option('prefix'), get_option('libexecdir'), 'tangd'),
+ join_paths('/', 'usr', get_option('libdir'), 'tangd'),
+ join_paths('/', 'usr', get_option('libexecdir'), 'tangd'),
+ required: false
+)
+
common_functions = configure_file(input: 'tests-common-functions.in',
output: 'tests-common-functions',
configuration: luksmeta_data,
@@ -24,6 +48,14 @@ env.prepend('PATH',
separator: ':'
)
+has_tang = false
+if actv.found() and kgen.found() and tang.found()
+ has_tang = true
+ env.set('SD_ACTIVATE', actv.path())
+ env.set('TANGD_KEYGEN', kgen.path())
+ env.set('TANGD', tang.path())
+endif
+
test('bind-wrong-pass-luks1', find_program('bind-wrong-pass-luks1'), env: env)
test('bind-luks1', find_program('bind-luks1'), env: env)
test('unbind-unbound-slot-luks1', find_program('unbind-unbound-slot-luks1'), env: env)
@@ -42,6 +74,10 @@ else
warning('Will not run "clevis luks list" tests due to missing jq dependency')
endif
+if has_tang
+ test('unlock-tang-luks1', find_program('unlock-tang-luks1'), env: env, timeout: 90)
+endif
+
# LUKS2 tests go here, and they get included if we get support for it, based
# on the cryptsetup version.
# Binding LUKS2 takes longer, so timeout is increased for a few tests.
@@ -56,4 +92,8 @@ if luksmeta_data.get('OLD_CRYPTSETUP') == '0'
test('list-tang-luks2', find_program('list-tang-luks2'), env: env, timeout: 60)
test('list-sss-tang-luks2', find_program('list-sss-tang-luks2'), env: env, timeout: 60)
endif
+
+ if has_tang
+ test('unlock-tang-luks2', find_program('unlock-tang-luks2'), env: env, timeout: 120)
+ endif
endif
diff --git a/src/luks/tests/tests-common-functions.in b/src/luks/tests/tests-common-functions.in
index 90420d1..7b3fdad 100755
--- a/src/luks/tests/tests-common-functions.in
+++ b/src/luks/tests/tests-common-functions.in
@@ -56,7 +56,7 @@ new_device() {
# Some builders fail if the cryptsetup steps are not ran as root, so let's
# skip the test now if not running as root.
- if [ $(id -u) != 0 ]; then
+ if [ "$(id -u)" != 0 ]; then
skip_test "WARNING: You must be root to run this test; test skipped."
fi
@@ -74,9 +74,9 @@ new_device() {
return 0
fi
- fallocate -l16M "${DEV}"
- local extra_options='--pbkdf pbkdf2 --pbkdf-force-iterations 1000'
- cryptsetup luksFormat --type "${LUKS}" ${extra_options} --batch-mode \
+ fallocate -l64M "${DEV}"
+ cryptsetup luksFormat --type "${LUKS}" --pbkdf pbkdf2 \
+ --pbkdf-force-iterations 1000 --batch-mode \
--force-password "${DEV}" <<< "${PASS}"
# Caching the just-formatted device for possible reuse.
cp -f "${DEV}" "${DEV_CACHED}"
@@ -90,7 +90,7 @@ new_device_keyfile() {
# Some builders fail if the cryptsetup steps are not ran as root, so let's
# skip the test now if not running as root.
- if [ $(id -u) != 0 ]; then
+ if [ "$(id -u)" != 0 ]; then
skip_test "WARNING: You must be root to run this test; test skipped."
fi
@@ -98,9 +98,9 @@ new_device_keyfile() {
error "Invalid keyfile (${KEYFILE})."
fi
- fallocate -l16M "${DEV}"
- local extra_options='--pbkdf pbkdf2 --pbkdf-force-iterations 1000'
- cryptsetup luksFormat --type "${LUKS}" ${extra_options} --batch-mode \
+ fallocate -l64M "${DEV}"
+ cryptsetup luksFormat --type "${LUKS}" --pbkdf pbkdf2 \
+ --pbkdf-force-iterations 1000 --batch-mode \
"${DEV}" "${KEYFILE}"
}
@@ -112,4 +112,122 @@ pin_cfg_equal() {
<(jq -S . < <(echo -n "${cfg2}"))
}
+# Get a random port to be used with a test tang server.
+get_random_port() {
+ shuf -i 1024-65535 -n 1
+}
+
+# Removes tang rotated keys from the test server.
+tang_remove_rotated_keys() {
+ local basedir="${1}"
+
+ if [ -z "${basedir}" ]; then
+ echo "Please pass a valid base directory for tang"
+ return 1
+ fi
+
+ local db="${basedir}/db"
+ mkdir -p "${db}"
+
+ pushd "${db}"
+ find . -name ".*.jwk" -exec rm -f {} \;
+ popd
+}
+
+# Creates new keys for the test tang server.
+tang_new_keys() {
+ local basedir="${1}"
+ local rotate="${2}"
+
+ if [ -z "${basedir}" ]; then
+ echo "Please pass a valid base directory for tang"
+ return 1
+ fi
+
+ [ -z "${TANGD_KEYGEN}" ] && skip_test "WARNING: TANGD_KEYGEN is not defined."
+
+ local db="${basedir}/db"
+ mkdir -p "${db}"
+
+ if [ -n "${rotate}" ]; then
+ pushd "${db}"
+ local k
+ k=$(find . -name "*.jwk" | wc -l)
+ if [ "${k}" -gt 0 ]; then
+ for k in *.jwk; do
+ mv -f -- "${k}" ".${k}"
+ done
+ fi
+ popd
+ fi
+
+ "${TANGD_KEYGEN}" "${db}"
+
+ return 0
+}
+
+# Start a test tang server.
+tang_run() {
+ local basedir="${1}"
+ local port="${2}"
+
+ if [ -z "${basedir}" ]; then
+ echo "Please pass a valid base directory for tang" >&2
+ return 1
+ fi
+
+ if [ -z "${port}" ]; then
+ echo "Please pass a valid port for tang" >&2
+ return 1
+ fi
+
+ if ! tang_new_keys "${basedir}"; then
+ echo "Error creating new keys for tang server" >&2
+ return 1
+ fi
+
+ local KEYS="${basedir}/db"
+
+ local inetd='--inetd'
+ [ "${SD_ACTIVATE##*/}" = "systemd-activate" ] && inetd=
+
+ local pid pidfile
+ pidfile="${basedir}/tang.pid"
+
+ "${SD_ACTIVATE}" ${inetd} -l "${TANG_HOST}":"${port}" \
+ -a "${TANGD}" "${KEYS}" &
+ pid=$!
+ echo "${pid}" > "${pidfile}"
+}
+
+# Stop tang server.
+tang_stop() {
+ local basedir="${1}"
+ local pidfile="${basedir}/tang.pid"
+ [ -f "${pidfile}" ] || return 0
+
+ local pid
+ pid=$(<"${pidfile}")
+ kill "${pid}"
+}
+
+# Wait for the tang server to be operational.
+tang_wait_until_ready() {
+ local port="${1}"
+ while ! curl --output /dev/null --silent --fail \
+ http://"${TANG_HOST}":"${port}"/adv; do
+ sleep 0.1
+ echo -n . >&2
+ done
+}
+
+# Get tang advertisement.
+tang_get_adv() {
+ local port="${1}"
+ local adv="${2}"
+
+ curl -o "${adv}" http://"${TANG_HOST}":"${port}"/adv
+}
+
+export TANG_HOST=127.0.0.1
export DEFAULT_PASS='just-some-test-password-here'
diff --git a/src/luks/tests/unlock-tang-luks1 b/src/luks/tests/unlock-tang-luks1
new file mode 100755
index 0000000..841ba01
--- /dev/null
+++ b/src/luks/tests/unlock-tang-luks1
@@ -0,0 +1,83 @@
+#!/bin/bash -ex
+# vim: set ts=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
+#
+# Copyright (c) 2020 Red Hat, Inc.
+# Author: Sergio Correia <scorreia@redhat.com>
+#
+# 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 <http://www.gnu.org/licenses/>.
+
+TEST=$(basename "${0}")
+. tests-common-functions
+
+. clevis-luks-common-functions
+
+on_exit() {
+ [ ! -d "${TMP}" ] && return 0
+ tang_stop "${TMP}"
+ rm -rf "${TMP}"
+}
+
+trap 'on_exit' EXIT
+trap 'on_exit' ERR
+
+TMP="$(mktemp -d)"
+
+port=$(get_random_port)
+tang_run "${TMP}" "${port}" &
+tang_wait_until_ready "${port}"
+
+url="http://${TANG_HOST}:${port}"
+adv="${TMP}/adv"
+tang_get_adv "${port}" "${adv}"
+
+cfg=$(printf '{"url":"%s","adv":"%s"}' "$url" "$adv")
+
+# LUKS1.
+DEV="${TMP}/luks1-device"
+new_device "luks1" "${DEV}"
+
+if ! clevis luks bind -f -d "${DEV}" tang "${cfg}" <<< "${DEFAULT_PASS}"; then
+ error "${TEST}: Bind should have succeeded."
+fi
+
+if ! clevis_luks_unlock_device "${DEV}"; then
+ error "${TEST}: we were unable to unlock ${DEV}."
+fi
+
+# Let's rotate the tang keys and add another binding with the new key.
+tang_new_keys "${TMP}" "rotate-keys"
+
+# Unlock should still work now.
+if ! clevis_luks_unlock_device "${DEV}"; then
+ error "${TEST}: we should still be able to unlock ${DEV}"
+fi
+
+# Now let's remove the rotated keys.
+tang_remove_rotated_keys "${TMP}"
+
+# Unlock should not work anymore.
+if clevis_luks_unlock_device "${DEV}"; then
+ error "${TEST}: we should not be able to unlock ${DEV}"
+fi
+
+# Now let's add another binding with the new keys.
+tang_get_adv "${port}" "${adv}" # Updating the advertisement.
+if ! clevis luks bind -f -d "${DEV}" tang "${cfg}" <<< "${DEFAULT_PASS}"; then
+ error "${TEST}: Bind should have succeeded."
+fi
+
+# Unlock should work again, using the new keys.
+if ! clevis_luks_unlock_device "${DEV}"; then
+ error "${TEST}: we should be able to unlock ${DEV} with the new keys"
+fi
diff --git a/src/luks/tests/unlock-tang-luks2 b/src/luks/tests/unlock-tang-luks2
new file mode 100755
index 0000000..81822fb
--- /dev/null
+++ b/src/luks/tests/unlock-tang-luks2
@@ -0,0 +1,83 @@
+#!/bin/bash -ex
+# vim: set ts=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
+#
+# Copyright (c) 2020 Red Hat, Inc.
+# Author: Sergio Correia <scorreia@redhat.com>
+#
+# 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 <http://www.gnu.org/licenses/>.
+
+TEST=$(basename "${0}")
+. tests-common-functions
+
+. clevis-luks-common-functions
+
+on_exit() {
+ [ ! -d "${TMP}" ] && return 0
+ tang_stop "${TMP}"
+ rm -rf "${TMP}"
+}
+
+trap 'on_exit' EXIT
+trap 'on_exit' ERR
+
+TMP="$(mktemp -d)"
+
+port=$(get_random_port)
+tang_run "${TMP}" "${port}" &
+tang_wait_until_ready "${port}"
+
+url="http://${TANG_HOST}:${port}"
+adv="${TMP}/adv"
+tang_get_adv "${port}" "${adv}"
+
+cfg=$(printf '{"url":"%s","adv":"%s"}' "$url" "$adv")
+
+# LUKS2.
+DEV="${TMP}/luks2-device"
+new_device "luks2" "${DEV}"
+
+if ! clevis luks bind -f -d "${DEV}" tang "${cfg}" <<< "${DEFAULT_PASS}"; then
+ error "${TEST}: Bind should have succeeded."
+fi
+
+if ! clevis_luks_unlock_device "${DEV}"; then
+ error "${TEST}: we were unable to unlock ${DEV}."
+fi
+
+# Let's rotate the tang keys and add another binding with the new key.
+tang_new_keys "${TMP}" "rotate-keys"
+
+# Unlock should still work now.
+if ! clevis_luks_unlock_device "${DEV}"; then
+ error "${TEST}: we should still be able to unlock ${DEV}"
+fi
+
+# Now let's remove the rotated keys.
+tang_remove_rotated_keys "${TMP}"
+
+# Unlock should not work anymore.
+if clevis_luks_unlock_device "${DEV}"; then
+ error "${TEST}: we should not be able to unlock ${DEV}"
+fi
+
+# Now let's add another binding with the new keys.
+tang_get_adv "${port}" "${adv}" # Updating the advertisement.
+if ! clevis luks bind -f -d "${DEV}" tang "${cfg}" <<< "${DEFAULT_PASS}"; then
+ error "${TEST}: Bind should have succeeded."
+fi
+
+# Unlock should work again, using the new keys.
+if ! clevis_luks_unlock_device "${DEV}"; then
+ error "${TEST}: we should be able to unlock ${DEV} with the new keys"
+fi
--
2.18.4

View File

@ -1,57 +0,0 @@
From d393fbc256e22cc8019d18214e4d140d58f3302a Mon Sep 17 00:00:00 2001
From: Sergio Correia <scorreia@redhat.com>
Date: Wed, 13 May 2020 23:51:04 -0300
Subject: [PATCH 3/8] Improve error message when bind is given an invalid PIN
---
src/luks/clevis-luks-bind.in | 6 ++++++
src/luks/clevis-luks-common-functions | 9 +++++++++
2 files changed, 15 insertions(+)
diff --git a/src/luks/clevis-luks-bind.in b/src/luks/clevis-luks-bind.in
index a5d3c5f..89a5e22 100755
--- a/src/luks/clevis-luks-bind.in
+++ b/src/luks/clevis-luks-bind.in
@@ -19,6 +19,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
+. clevis-luks-common-functions
+
SUMMARY="Binds a LUKS device using the specified policy"
UUID=cb6e8904-81ff-40da-a84a-07ab9ab5715e
@@ -76,6 +78,10 @@ fi
if ! PIN="${@:$((OPTIND++)):1}" || [ -z "$PIN" ]; then
echo "Did not specify a pin!" >&2
usage
+elif ! EXE=$(findexe clevis-encrypt-"${PIN}") \
+ || [ -z "${EXE}" ]; then
+ echo "'$PIN' is not a valid pin!" >&2
+ usage
fi
if ! CFG="${@:$((OPTIND++)):1}" || [ -z "$CFG" ]; then
diff --git a/src/luks/clevis-luks-common-functions b/src/luks/clevis-luks-common-functions
index d04fdb5..36f0bfd 100644
--- a/src/luks/clevis-luks-common-functions
+++ b/src/luks/clevis-luks-common-functions
@@ -108,6 +108,15 @@ clevis_luks_read_slot() {
echo "${DATA_CODED}"
}
+# findexe() finds an executable.
+findexe() {
+ while read -r -d: path; do
+ [ -f "${path}/${1}" ] && [ -x "${path}/${1}" ] && \
+ echo "${path}/${1}" && return 0
+ done <<< "${PATH}:"
+ return 1
+}
+
# clevis_luks_used_slots() will return the list of used slots for a given LUKS
# device.
clevis_luks_used_slots() {
--
2.18.4

View File

@ -1,53 +0,0 @@
From fc0cc6f159857e463aacababdc0735b0972d103c Mon Sep 17 00:00:00 2001
From: Sergio Correia <scorreia@redhat.com>
Date: Wed, 13 May 2020 23:51:04 -0300
Subject: [PATCH 4/8] Add rd.neednet=1 to cmdline only if there are devices
bound to tang
---
.../dracut/clevis-pin-tang/module-setup.sh.in | 21 +++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/src/luks/systemd/dracut/clevis-pin-tang/module-setup.sh.in b/src/luks/systemd/dracut/clevis-pin-tang/module-setup.sh.in
index 1bb2ead..a4984dc 100755
--- a/src/luks/systemd/dracut/clevis-pin-tang/module-setup.sh.in
+++ b/src/luks/systemd/dracut/clevis-pin-tang/module-setup.sh.in
@@ -18,8 +18,23 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
+has_devices_bound_to_tang() {
+ local dev
+ for dev in $(lsblk -p -n -s -r \
+ | awk '$6 == "crypt" { getline; print $1 }' | sort -u); do
+ if clevis luks list -d "${dev}" 2>/dev/null | grep -q tang; then
+ return 0
+ fi
+ done
+ return 1
+}
+
depends() {
- echo clevis network
+ local deps="clevis"
+ if has_devices_bound_to_tang; then
+ deps=$(printf "%s network" "${deps}")
+ fi
+ echo "${deps}"
return 0
}
@@ -28,7 +43,9 @@ cmdline() {
}
install() {
- cmdline > "${initdir}/etc/cmdline.d/99clevis-pin-tang.conf"
+ if has_devices_bound_to_tang; then
+ cmdline > "${initdir}/etc/cmdline.d/99clevis-pin-tang.conf"
+ fi
inst_multiple \
clevis-decrypt-tang \
--
2.18.4

File diff suppressed because it is too large Load Diff

View File

@ -1,464 +0,0 @@
From a85f50f789d69d9ca0a4096a64ac912f5967f97f Mon Sep 17 00:00:00 2001
From: Sergio Correia <scorreia@redhat.com>
Date: Sun, 10 May 2020 15:32:50 -0300
Subject: [PATCH 7/8] Add clevis luks report
---
src/luks/clevis-luks-report | 95 +++++++++++++++++++++++++++++
src/luks/clevis-luks-report-compare | 71 +++++++++++++++++++++
src/luks/clevis-luks-report-decode | 59 ++++++++++++++++++
src/luks/clevis-luks-report-sss | 53 ++++++++++++++++
src/luks/clevis-luks-report-tang | 67 ++++++++++++++++++++
src/luks/clevis-luks-report.1.adoc | 41 +++++++++++++
src/luks/meson.build | 7 +++
7 files changed, 393 insertions(+)
create mode 100755 src/luks/clevis-luks-report
create mode 100755 src/luks/clevis-luks-report-compare
create mode 100755 src/luks/clevis-luks-report-decode
create mode 100755 src/luks/clevis-luks-report-sss
create mode 100755 src/luks/clevis-luks-report-tang
create mode 100644 src/luks/clevis-luks-report.1.adoc
diff --git a/src/luks/clevis-luks-report b/src/luks/clevis-luks-report
new file mode 100755
index 0000000..f047256
--- /dev/null
+++ b/src/luks/clevis-luks-report
@@ -0,0 +1,95 @@
+#!/usr/bin/bash -e
+# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
+#
+# Copyright (c) 2018 Red Hat, Inc.
+# Author: Radovan Sroka <rsroka@redhat.com>
+#
+# 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 <http://www.gnu.org/licenses/>.
+#
+
+. clevis-luks-common-functions
+
+SUMMARY="Report any key rotation on the server side"
+
+if [ "$1" == "--summary" ]; then
+ echo "$SUMMARY"
+ exit 0
+fi
+
+function usage_and_exit () {
+ echo >&2
+ echo "Usage: clevis luks report [-qr] -d DEV -s SLOT" >&2
+ echo >&2
+ echo -e " -q\t Quiet mode" >&2
+ echo -e " -r\t Regenerate luks metadata with \"clevis luks regen -d DEV -s SLOT\"" >&2
+ echo >&2
+ echo "$SUMMARY" >&2
+ echo >&2
+ exit "$1"
+}
+
+while getopts "hd:s:rq" o; do
+ case "$o" in
+ d) DEV="$OPTARG";;
+ h) usage_and_exit 0;;
+ r) ROPT="regen";;
+ s) SLT="$OPTARG";;
+ q) QOPT="quiet";;
+ *) usage_and_exit 1;;
+ esac
+done
+
+### get luks metadata
+
+if [ -z "$DEV" ]; then
+ echo "Did not specify a device!" >&2
+ exit 1
+fi
+
+if [ -z "$SLT" ]; then
+ echo "Did not specify a slot!" >&2
+ exit 1
+fi
+
+if ! DATA_CODED=$(clevis_luks_read_slot "${DEV}" "${SLT}"); then
+ # Error message was already displayed by clevis_luks_read_slot(),
+ # at this point.
+ exit 1
+fi
+
+EXE="$(findexe clevis-luks-report-decode)"
+RESULT="$($EXE "${DATA_CODED}")"
+
+if [ -n "$RESULT" ]; then
+ echo "$RESULT"
+ echo "Report detected that some keys were rotated."
+ if [ -z "$QOPT" ]; then
+ if [ -z "$ROPT" ]; then
+ read -r -p "Do you want to regenerate luks metadata with \"clevis luks regen -d $DEV -s $SLT\"? [ynYN] " ans < /dev/tty
+ [[ "$ans" =~ ^[yY]$ ]] && ROPT="regen"
+ fi
+ fi
+else
+ exit 0
+fi
+
+if [ "$ROPT" = "regen" ]; then
+ EXE="$(findexe clevis-luks-regen)"
+ exec "$EXE" -d "$DEV" -s "$SLT"
+else
+ if [ -n "${RESULT}" ]; then
+ # Keys were rotated.
+ exit 1
+ fi
+fi
diff --git a/src/luks/clevis-luks-report-compare b/src/luks/clevis-luks-report-compare
new file mode 100755
index 0000000..2ba5132
--- /dev/null
+++ b/src/luks/clevis-luks-report-compare
@@ -0,0 +1,71 @@
+#!/usr/bin/bash -e
+# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
+#
+# Copyright (c) 2018 Red Hat, Inc.
+# Author: Radovan Sroka <rsroka@redhat.com>
+#
+# 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 <http://www.gnu.org/licenses/>.
+#
+
+SUMMARY="Compare two sets of keys"
+
+if [ "$1" == "--summary" ]; then
+ echo "$SUMMARY"
+ exit 1
+fi
+
+if [ -z "$1" ]; then
+ echo "$0 missing the first argument!"
+ exit 1
+fi
+
+if [ -z "$2" ]; then
+ echo "$0 missing the second argument!"
+ exit 1
+fi
+
+ADV_KEYS="$1" # keys from advertisement
+LUKS_KEYS="$2" # keys from luks metadata
+
+### iterate over adv keys and make thumbprints
+CNT=0
+declare -a ADV_KEYS_ARRAY
+while res="$(jose fmt -j- -g keys -g"$CNT" -o- <<< "$ADV_KEYS")"; do
+ thp="$(echo "$res" | jose jwk thp -i-)"
+ ADV_KEYS_ARRAY["$CNT"]="$thp"
+ CNT=$(( CNT + 1 ))
+done
+
+CNT=0
+while key="$(jose fmt -j- -g keys -g"$CNT" -o- <<< "$LUKS_KEYS")"; do
+ thp="$(echo "$key" | jose jwk thp -i-)"
+
+ FOUND=0
+ for k in "${ADV_KEYS_ARRAY[@]}"
+ do
+ if [ "$k" = "$thp" ]; then
+ FOUND=1
+ break
+ fi
+ done
+
+ if [ "$FOUND" -eq "0" ]; then
+ echo "Key \"$thp\" is not in the advertisement and was probably rotated!"
+ echo "$key"
+ echo
+ fi
+ CNT=$(( CNT + 1 ))
+done
+
+exit 0
diff --git a/src/luks/clevis-luks-report-decode b/src/luks/clevis-luks-report-decode
new file mode 100755
index 0000000..f39d1e9
--- /dev/null
+++ b/src/luks/clevis-luks-report-decode
@@ -0,0 +1,59 @@
+#!/usr/bin/bash -e
+# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
+#
+# Copyright (c) 2018 Red Hat, Inc.
+# Author: Radovan Sroka <rsroka@redhat.com>
+#
+# 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 <http://www.gnu.org/licenses/>.
+#
+
+. clevis-luks-common-functions
+
+SUMMARY="Decode luks header"
+
+if [ "$1" == "--summary" ]; then
+ echo "$SUMMARY"
+ exit 1
+fi
+
+if [ -z "$1" ]; then
+ echo "$0 missing the first argument!"
+ exit 1
+fi
+
+DATA_CODED="$1"
+
+if DATA_CODED="$(jose jwe fmt -i- <<< "$DATA_CODED")"; then
+ DATA_CODED="$(jose fmt -j- -g protected -u- <<< "$DATA_CODED")"
+ DATA_DECODED="$(jose b64 dec -i- <<< "$DATA_CODED")"
+else
+ echo "Error decoding JWE protected header!" >&2
+ exit 1
+fi
+
+### get pin and url
+
+if ! PIN="$(jose fmt -j- -g clevis -g pin -u- <<< "$DATA_DECODED")" || [ -z "$PIN" ]; then
+ echo "Pin wasn't found in luks metadata!" >&2
+ exit 1
+fi
+
+if ! CONTENT="$(jose fmt -j- -g clevis -g "$PIN" -o- <<< "$DATA_DECODED")" || [ -z "$CONTENT" ]; then
+ echo "Content wasn't found!" >&2
+ exit 1
+fi
+
+EXE="$(findexe clevis-luks-report-"$PIN")"
+
+exec "$EXE" "$CONTENT"
diff --git a/src/luks/clevis-luks-report-sss b/src/luks/clevis-luks-report-sss
new file mode 100755
index 0000000..1dba4c1
--- /dev/null
+++ b/src/luks/clevis-luks-report-sss
@@ -0,0 +1,53 @@
+#!/bin/bash -e
+# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
+#
+# Copyright (c) 2018 Red Hat, Inc.
+# Author: Radovan Sroka <rsroka@redhat.com>
+#
+# 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 <http://www.gnu.org/licenses/>.
+#
+
+. clevis-luks-common-functions
+
+SUMMARY="SSS report plugin"
+
+if [ "$1" == "--summary" ]; then
+ echo "$SUMMARY"
+ exit 1
+fi
+
+if [ -z "$1" ]; then
+ echo "$0 missing the first argument!" >&2
+ exit 1
+fi
+
+CONTENT="$1" # sss content
+
+CNT=0
+while DATA_CODED="$(jose fmt -j- -g jwe -g"$CNT" -u- <<< "$CONTENT")"; do
+ if [ -z "$DATA_CODED" ]; then
+ CNT=$(( CNT + 1 ))
+ continue # in some cases it can be empty string
+ fi
+
+ EXE="$(findexe clevis-luks-report-decode)"
+ if ! $EXE "$DATA_CODED"; then
+ echo "Failed" >&2
+ exit 1
+ fi
+
+ CNT=$(( CNT + 1 ))
+done
+
+exit 0
diff --git a/src/luks/clevis-luks-report-tang b/src/luks/clevis-luks-report-tang
new file mode 100755
index 0000000..07f2a72
--- /dev/null
+++ b/src/luks/clevis-luks-report-tang
@@ -0,0 +1,67 @@
+#!/usr/bin/bash -e
+# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
+#
+# Copyright (c) 2018 Red Hat, Inc.
+# Author: Radovan Sroka <rsroka@redhat.com>
+#
+# 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 <http://www.gnu.org/licenses/>.
+#
+
+. clevis-luks-common-functions
+
+SUMMARY="Tang report plugin"
+
+if [ "$1" == "--summary" ]; then
+ echo "$SUMMARY"
+ exit 1
+fi
+
+if [ -z "$1" ]; then
+ echo "$0 missing the first argument!"
+ exit 1
+fi
+
+CONTENT="$1"
+
+### Get the advertisement
+if ! URL="$(jose fmt -j- -g url -u- <<< "$CONTENT")" || [ -z "$URL" ]; then
+ echo "URL was not found!" >&2
+ exit 1
+fi
+
+if ! jws="$(curl -sfg "$URL/adv")"; then
+ echo "Unable to fetch advertisement: $URL/adv!" >&2
+ exit 1
+fi
+
+if ! TANG_KEYS="$(jose fmt -j- -Og payload -SyOg keys -AUo- <<< "$jws")"; then
+ echo "Advertisement is malformed!" >&2
+ exit 1
+fi
+
+### Check advertisement validity
+ver="$(jose jwk use -i- -r -u verify -o- <<< "$TANG_KEYS")"
+if ! jose jws ver -i "$jws" -k- -a <<< "$ver"; then
+ echo "Advertisement is missing signatures!" >&2
+ exit 1
+fi
+
+if ! LUKS_KEYS="$(jose fmt -j- -g adv -o- <<< "$CONTENT")" || [ -z "$LUKS_KEYS" ]; then
+ echo "LUKS keys from LUKS metadata were not found!" >&2
+ exit 1
+fi
+
+EXE="$(findexe clevis-luks-report-compare)"
+
+exec "$EXE" "$TANG_KEYS" "$LUKS_KEYS"
diff --git a/src/luks/clevis-luks-report.1.adoc b/src/luks/clevis-luks-report.1.adoc
new file mode 100644
index 0000000..cf42afe
--- /dev/null
+++ b/src/luks/clevis-luks-report.1.adoc
@@ -0,0 +1,41 @@
+CLEVIS-LUKS-REPORT(1)
+=====================
+:doctype: manpage
+
+
+== NAME
+
+clevis-luks-report - Reports whether a pin bound to a LUKS1 or LUKS2 volume has been rotated
+
+== SYNOPSIS
+
+*clevis luks report* -d DEV -s SLT
+
+== OVERVIEW
+
+The *clevis luks report* command checks a given slot of a LUKS device and reports whether the pin bound to it
+-- if any -- has been rotated.
+
+== OPTIONS
+
+* *-d* _DEV_ :
+ The bound LUKS device
+
+* *-s* _SLT_ :
+ The slot or key slot number for the pin to be verified
+
+* *-q* :
+ Quiet mode. If used, we will not prompt whether to regenerate data with *clevis luks regen*
+
+* *-r* :
+ Regenerates LUKS metadata with *clevis luks regen -d DEV -s SLOT*
+
+== EXAMPLE
+
+ Check whether the pin bound to slot 1 in /dev/sda1 has been rotated:
+
+ # clevis luks report -d /dev/sda1 -s 1
+
+== SEE ALSO
+
+link:clevis-luks-regen.1.adoc[*clevis-luks-regen*(1)]
diff --git a/src/luks/meson.build b/src/luks/meson.build
index f21388d..ee588c3 100644
--- a/src/luks/meson.build
+++ b/src/luks/meson.build
@@ -47,6 +47,13 @@ if libcryptsetup.found() and luksmeta.found() and pwmake.found()
bins += join_paths(meson.current_source_dir(), 'clevis-luks-regen')
mans += join_paths(meson.current_source_dir(), 'clevis-luks-regen.1')
+
+ bins += join_paths(meson.current_source_dir(), 'clevis-luks-report')
+ bins += join_paths(meson.current_source_dir(), 'clevis-luks-report-compare')
+ bins += join_paths(meson.current_source_dir(), 'clevis-luks-report-decode')
+ bins += join_paths(meson.current_source_dir(), 'clevis-luks-report-sss')
+ bins += join_paths(meson.current_source_dir(), 'clevis-luks-report-tang')
+ mans += join_paths(meson.current_source_dir(), 'clevis-luks-report.1')
else
warning('Will not install LUKS support due to missing dependencies!')
endif
--
2.18.4

View File

@ -1,339 +0,0 @@
From 3250784e99016d9f920892dbb1438b9e76fb210b Mon Sep 17 00:00:00 2001
From: Sergio Correia <scorreia@redhat.com>
Date: Sun, 10 May 2020 15:57:23 -0300
Subject: [PATCH 8/8] Use one clevis-luks-askpass per device
This should improve the reliability of the boot unlocking, especially
when unlocking multiple devices upon boot.
It also greatly simplifies the configuration, as there is no need to
enable any systemd units manually nor add _netdev to either fstab or
crypttab.
---
src/luks/clevis-luks-common-functions | 8 ++
src/luks/clevis-luks-unlockers.7.adoc | 16 +---
src/luks/systemd/clevis-luks-askpass | 81 ++++++-------------
src/luks/systemd/clevis-luks-askpass.path | 10 ---
.../systemd/clevis-luks-askpass.service.in | 8 --
src/luks/systemd/clevis-luks-askpass@.path | 12 +++
.../systemd/clevis-luks-askpass@.service.in | 8 ++
.../systemd/dracut/clevis/module-setup.sh.in | 23 ++++++
src/luks/systemd/meson.build | 6 +-
9 files changed, 80 insertions(+), 92 deletions(-)
delete mode 100644 src/luks/systemd/clevis-luks-askpass.path
delete mode 100644 src/luks/systemd/clevis-luks-askpass.service.in
create mode 100644 src/luks/systemd/clevis-luks-askpass@.path
create mode 100644 src/luks/systemd/clevis-luks-askpass@.service.in
diff --git a/src/luks/clevis-luks-common-functions b/src/luks/clevis-luks-common-functions
index 5b515ad..c9d712a 100644
--- a/src/luks/clevis-luks-common-functions
+++ b/src/luks/clevis-luks-common-functions
@@ -555,3 +555,11 @@ clevis_luks_restore_dev() {
fi
return 0
}
+
+# clevis_is_luks_device_by_uuid_open() checks whether the LUKS device with
+# given UUID is open.
+clevis_is_luks_device_by_uuid_open() {
+ local LUKS_UUID="${1}"
+ [ -z "${LUKS_UUID}" ] && return 1
+ test -b /dev/disk/by-id/dm-uuid-*"${LUKS_UUID//-/}"*
+}
diff --git a/src/luks/clevis-luks-unlockers.7.adoc b/src/luks/clevis-luks-unlockers.7.adoc
index 161b73a..e8d47ba 100644
--- a/src/luks/clevis-luks-unlockers.7.adoc
+++ b/src/luks/clevis-luks-unlockers.7.adoc
@@ -26,7 +26,7 @@ You can unlock a LUKS volume manually using the following command:
For more information, see link:clevis-luks-unlock.1.adoc[*clevis-luks-unlock*(1)].
-== EARLY BOOT UNLOCKING
+== BOOT UNLOCKING
If Clevis integration does not already ship in your initramfs, you may need to
rebuild your initramfs with this command:
@@ -34,23 +34,13 @@ rebuild your initramfs with this command:
$ sudo dracut -f
Once Clevis is integrated into your initramfs, a simple reboot should unlock
-your root volume. Note, however, that early boot integration only works for the
-root volume. Non-root volumes should use the late boot unlocker.
+your clevis-bound volumes. Root volumes will be unlocked in early-boot, while the
+remaining volumes will be unlocked after dracut switch-root.
Dracut will bring up your network using DHCP by default. If you need to specify
additional network parameters, such as static IP configuration, please consult
the dracut documentation.
-== LATE BOOT UNLOCKING
-
-You can enable late boot unlocking by executing the following command:
-
- $ sudo systemctl enable clevis-luks-askpass.path
-
-After a reboot, Clevis will attempt to unlock all *_netdev* devices listed in
-*/etc/crypttab* when systemd prompts for their passwords. This implies that
-systemd support for *_netdev* is required.
-
== DESKTOP UNLOCKING
When the udisks2 unlocker is installed, your GNOME desktop session should
diff --git a/src/luks/systemd/clevis-luks-askpass b/src/luks/systemd/clevis-luks-askpass
index 9fea6aa..20294e5 100755
--- a/src/luks/systemd/clevis-luks-askpass
+++ b/src/luks/systemd/clevis-luks-askpass
@@ -19,96 +19,61 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-UUID=cb6e8904-81ff-40da-a84a-07ab9ab5715e
+. clevis-luks-common-functions
shopt -s nullglob
path=/run/systemd/ask-password
-while getopts ":lp:" o; do
+while getopts ":lp:u:" o; do
case "$o" in
l) loop=true;;
p) path="$OPTARG";;
+ u) device_uuid=$OPTARG;;
+ *) ;;
esac
done
-luks1_decrypt() {
- luksmeta load "$@" \
- | clevis decrypt
-
- local rc
- for rc in "${PIPESTATUS[@]}"; do
- [ $rc -eq 0 ] || return $rc
- done
- return 0
-}
-
-luks2_jwe() {
- # jose jwe fmt -c outputs extra \n, so clean it up
- cryptsetup token export "$@" \
- | jose fmt -j- -Og jwe -o- \
- | jose jwe fmt -i- -c \
- | tr -d '\n'
-
- local rc
- for rc in "${PIPESTATUS[@]}"; do
- [ $rc -eq 0 ] || return $rc
- done
- return 0
-}
-
while true; do
todo=0
for question in "$path"/ask.*; do
- metadata=false
unlocked=false
d=
s=
- while read line; do
+ while read -r line; do
case "$line" in
Id=cryptsetup:*) d="${line##Id=cryptsetup:}";;
Socket=*) s="${line##Socket=}";;
esac
done < "$question"
- [ "$d" ] && [ "$s" ] || continue
+ [ -b "${d}" ] || continue
+ [ -S "${s}" ] || continue
- if cryptsetup isLuks --type luks1 "$d"; then
- # If the device is not initialized, sliently skip it.
- luksmeta test -d "$d" || continue
-
- while read -r slot state uuid; do
- [ "$state" == "active" ] || continue
- [ "$uuid" == "$UUID" ] || continue
- metadata=true
-
- if pt="$(luks1_decrypt -d "$d" -s "$slot" -u "$UUID")"; then
- echo -n "+$pt" | ncat -U -u --send-only "$s"
- unlocked=true
- break
- fi
- done < <(luksmeta show -d "$d")
- elif cryptsetup isLuks --type luks2 "$d"; then
- while read -r id; do
- jwe="$(luks2_jwe --token-id "$id" "$d")" \
- || continue
- metadata=true
+ if [ -n "${device_uuid}" ]; then
+ uuid="$(cryptsetup luksUUID "${d}")"
+ [ "${uuid}" != "${device_uuid}" ] && todo=1 && continue
+ fi
- if pt="$(echo -n "$jwe" | clevis decrypt)"; then
- echo -n "+$pt" | ncat -U -u --send-only "$s"
- unlocked=true
- break
- fi
- done < <(cryptsetup luksDump "$d" | sed -rn 's|^\s+([0-9]+): clevis|\1|p')
+ if pt="$(clevis_luks_unlock_device "${d}")"; then
+ echo -n "+$pt" | ncat -U -u --send-only "$s"
+ unlocked=true
fi
- [ "$metadata" == true ] || continue
+ [ -n "${device_uuid}" ] && [ "${unlocked}" == true ] && break
[ "$unlocked" == true ] && continue
((todo++))
done
- if [ $todo -eq 0 ] || [ "$loop" != true ]; then
+ if [ -n "${device_uuid}" ]; then
+ [ ! -b /dev/disk/by-uuid/"${device_uuid}" ] && break
+ if clevis_is_luks_device_by_uuid_open "${device_uuid}"; then
+ break
+ fi
+ fi
+
+ if [ "$todo" -eq 0 ] || [ "$loop" != true ]; then
break;
fi
diff --git a/src/luks/systemd/clevis-luks-askpass.path b/src/luks/systemd/clevis-luks-askpass.path
deleted file mode 100644
index a4d01ba..0000000
--- a/src/luks/systemd/clevis-luks-askpass.path
+++ /dev/null
@@ -1,10 +0,0 @@
-[Unit]
-Description=Clevis systemd-ask-password Watcher
-Before=remote-fs-pre.target
-Wants=remote-fs-pre.target
-
-[Path]
-PathChanged=/run/systemd/ask-password
-
-[Install]
-WantedBy=remote-fs.target
diff --git a/src/luks/systemd/clevis-luks-askpass.service.in b/src/luks/systemd/clevis-luks-askpass.service.in
deleted file mode 100644
index 2c6bbed..0000000
--- a/src/luks/systemd/clevis-luks-askpass.service.in
+++ /dev/null
@@ -1,8 +0,0 @@
-[Unit]
-Description=Clevis LUKS systemd-ask-password Responder
-Requires=network-online.target
-After=network-online.target
-
-[Service]
-Type=oneshot
-ExecStart=@libexecdir@/clevis-luks-askpass -l
diff --git a/src/luks/systemd/clevis-luks-askpass@.path b/src/luks/systemd/clevis-luks-askpass@.path
new file mode 100644
index 0000000..3f23665
--- /dev/null
+++ b/src/luks/systemd/clevis-luks-askpass@.path
@@ -0,0 +1,12 @@
+[Unit]
+Description=Clevis systemd-ask-password Watcher for %i
+DefaultDependencies=no
+Conflicts=shutdown.target
+Before=basic.target shutdown.target
+
+[Path]
+DirectoryNotEmpty=/run/systemd/ask-password
+MakeDirectory=yes
+
+[Install]
+WantedBy=basic.target
diff --git a/src/luks/systemd/clevis-luks-askpass@.service.in b/src/luks/systemd/clevis-luks-askpass@.service.in
new file mode 100644
index 0000000..4165ec5
--- /dev/null
+++ b/src/luks/systemd/clevis-luks-askpass@.service.in
@@ -0,0 +1,8 @@
+[Unit]
+Description=Clevis LUKS systemd-ask-password Responder for luks-%i
+DefaultDependencies=no
+Conflicts=shutdown.target
+Before=shutdown.target
+
+[Service]
+ExecStart=@libexecdir@/clevis-luks-askpass -u %i
diff --git a/src/luks/systemd/dracut/clevis/module-setup.sh.in b/src/luks/systemd/dracut/clevis/module-setup.sh.in
index abc79b3..1a0d6f7 100755
--- a/src/luks/systemd/dracut/clevis/module-setup.sh.in
+++ b/src/luks/systemd/dracut/clevis/module-setup.sh.in
@@ -23,6 +23,24 @@ depends() {
return 255
}
+configure_passwd_watchers() {
+ if ! command -v systemctl >/dev/null; then
+ return 1
+ fi
+
+ find /etc/systemd/system/ -name "clevis-luks-askpass*" -exec rm -f {} \;
+
+ local uuid
+ for dev in $(lsblk -p -n -s -r \
+ | awk '$6 == "crypt" { getline; print $1 }' | sort -u); do
+ uuid=$(cryptsetup luksUUID "${dev}")
+
+ if clevis luks list -d "${dev}" >/dev/null 2>/dev/null; then
+ systemctl enable "clevis-luks-askpass@${uuid}.path" 2>/dev/null
+ fi
+ done
+}
+
install() {
inst_hook initqueue/online 60 "$moddir/clevis-hook.sh"
inst_hook initqueue/settled 60 "$moddir/clevis-hook.sh"
@@ -30,6 +48,10 @@ install() {
inst_multiple \
/etc/services \
@libexecdir@/clevis-luks-askpass \
+ clevis-luks-common-functions \
+ head \
+ grep \
+ sed \
clevis-decrypt \
cryptsetup \
luksmeta \
@@ -38,5 +60,6 @@ install() {
jose \
ncat
+ configure_passwd_watchers
dracut_need_initqueue
}
diff --git a/src/luks/systemd/meson.build b/src/luks/systemd/meson.build
index 369e7f7..334e84c 100644
--- a/src/luks/systemd/meson.build
+++ b/src/luks/systemd/meson.build
@@ -6,13 +6,13 @@ if systemd.found()
unitdir = systemd.get_pkgconfig_variable('systemdsystemunitdir')
configure_file(
- input: 'clevis-luks-askpass.service.in',
- output: 'clevis-luks-askpass.service',
+ input: 'clevis-luks-askpass@.service.in',
+ output: 'clevis-luks-askpass@.service',
install_dir: unitdir,
configuration: data,
)
- install_data('clevis-luks-askpass.path', install_dir: unitdir)
+ 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!')
--
2.18.4

View File

@ -1,555 +0,0 @@
From 7b1639b2194a8bfbb0daedf1cbdfc4ebef5f6b31 Mon Sep 17 00:00:00 2001
From: Sergio Correia <scorreia@redhat.com>
Date: Mon, 18 May 2020 08:36:17 -0300
Subject: [PATCH] Introduce -y (assume yes) argument to clevis luks bind
In order to simplify automated operations with e.g. ansible,
it would be helpful to have a way to automate the creation of
bindings with clevis.
In simple scenarios, it's possible to download the advertisement
from a tang server and pass it in the binding configuration, to
do the binding offline, in the following way:
curl -sfg http://tang.server/adv -o adv.jws
clevis luks bind -d /dev/sda2 tang '{"url":"http://tang.server", "adv":"adv.jws}'
However, for more complex scenarios using multiple servers with
the sss pin, it becomes a lot more complicated to do the same
thing and do the binding in an automated fashion. An alternative
would be to use expect (tcl), but it can also be complicated.
In this commit we introduce -y as a parameter to clevis luks bind,
meanining _assume yes_. Essentially, this would make it so that
the user would not have to manually trust tang key(s) by typing
y/yes.
Security-wise, it would be similar to downloading the advertisement
manually and passing it to tang as the "adv" configuration option,
something already supported.
We already have a -f parameter, so we picked something different,
not to change existing behavior and possibly break existing scripts.
---
src/luks/clevis-luks-bind.1.adoc | 7 +-
src/luks/clevis-luks-bind.in | 11 +++-
src/luks/clevis-luks-regen | 4 +-
src/luks/tests/assume-yes-luks1 | 81 ++++++++++++++++++++++++
src/luks/tests/assume-yes-luks2 | 81 ++++++++++++++++++++++++
src/luks/tests/meson.build | 2 +
src/pins/sss/clevis-encrypt-sss.1.adoc | 14 +++-
src/pins/sss/clevis-encrypt-sss.c | 30 ++++++---
src/pins/tang/clevis-encrypt-tang | 35 ++++++----
src/pins/tang/clevis-encrypt-tang.1.adoc | 11 +++-
10 files changed, 246 insertions(+), 30 deletions(-)
create mode 100755 src/luks/tests/assume-yes-luks1
create mode 100755 src/luks/tests/assume-yes-luks2
diff --git a/src/luks/clevis-luks-bind.1.adoc b/src/luks/clevis-luks-bind.1.adoc
index 336c0f4..438e517 100644
--- a/src/luks/clevis-luks-bind.1.adoc
+++ b/src/luks/clevis-luks-bind.1.adoc
@@ -9,7 +9,7 @@ clevis-luks-bind - Bind a LUKS device using the specified policy
== SYNOPSIS
-*clevis luks bind* [-f] -d DEV [-s SLT] [-k KEY] PIN CFG
+*clevis luks bind* [-f] [-y] -d DEV [-s SLT] [-k KEY] PIN CFG
== OVERVIEW
@@ -34,6 +34,11 @@ Clevis LUKS unlockers. See link:clevis-luks-unlockers.7.adoc[*clevis-luks-unlock
* *-f* :
Do not prompt for LUKSMeta initialization
+* *-y* :
+ Automatically answer yes for all questions. When using _tang_, it
+ causes the advertisement trust check to be skipped, which can be
+ useful in automated deployments
+
* *-d* _DEV_ :
The LUKS device on which to perform binding
diff --git a/src/luks/clevis-luks-bind.in b/src/luks/clevis-luks-bind.in
index 89a5e22..8b8b5ee 100755
--- a/src/luks/clevis-luks-bind.in
+++ b/src/luks/clevis-luks-bind.in
@@ -33,12 +33,14 @@ function luks2_supported() {
function usage() {
exec >&2
echo
- echo "Usage: clevis luks bind [-f] [-s SLT] [-k KEY] -d DEV PIN CFG"
+ echo "Usage: clevis luks bind [-f] [-y] [-s SLT] [-k KEY] -d DEV PIN CFG"
echo
echo "$SUMMARY":
echo
echo " -f Do not prompt for LUKSMeta initialization"
echo
+ echo " -y Automatically answer yes for all questions"
+ echo
echo " -d DEV The LUKS device on which to perform binding"
echo
echo " -s SLT The LUKS slot to use"
@@ -55,12 +57,15 @@ if [ $# -eq 1 ] && [ "$1" == "--summary" ]; then
fi
FRC=()
-while getopts ":hfd:s:k:" o; do
+YES=()
+while getopts ":fyd:s:k:" o; do
case "$o" in
f) FRC+=(-f);;
d) DEV="$OPTARG";;
s) SLT="$OPTARG";;
k) KEY="$OPTARG";;
+ y) FRC+=(-f)
+ YES+=(-y);;
*) usage;;
esac
done
@@ -139,7 +144,7 @@ cryptsetup luksDump "$DEV" \
)")"
# Encrypt the new key
-jwe="$(echo -n "$key" | clevis encrypt "$PIN" "$CFG")"
+jwe="$(echo -n "$key" | clevis encrypt "$PIN" "$CFG" "${YES}")"
# If necessary, initialize the LUKS volume
if [ "$luks_type" == "luks1" ] && ! luksmeta test -d "$DEV"; then
diff --git a/src/luks/clevis-luks-regen b/src/luks/clevis-luks-regen
index 44fd673..6071d85 100755
--- a/src/luks/clevis-luks-regen
+++ b/src/luks/clevis-luks-regen
@@ -110,7 +110,7 @@ if ! new_passphrase=$(generate_key "${DEV}"); then
fi
# Reencrypt the new password.
-if ! jwe=$(clevis encrypt "${PIN}" "${CFG}" <<< "${new_passphrase}"); then
+if ! jwe="$(clevis encrypt "${PIN}" "${CFG}" <<< "${new_passphrase}")"; then
echo "Error using pin '${PIN}' with config '${CFG}'" >&2
exit 1
fi
@@ -176,7 +176,7 @@ fi
# Now make sure that we can unlock this device after the change.
# If we can't, undo the changes.
if ! cryptsetup open --test-passphrase --key-slot "${SLT}" "${DEV}" 2>/dev/null \
- <<< $(clevis luks pass -d "${DEV}" -s "${SLT}" 2>/dev/null); then
+ <<< "$(clevis luks pass -d "${DEV}" -s "${SLT}" 2>/dev/null)"; then
echo "Invalid configuration detected after rebinding. Reverting changes."
restore_device "${DEV}" "${TMP}"
exit 1
diff --git a/src/luks/tests/assume-yes-luks1 b/src/luks/tests/assume-yes-luks1
new file mode 100755
index 0000000..ad9dea4
--- /dev/null
+++ b/src/luks/tests/assume-yes-luks1
@@ -0,0 +1,81 @@
+#!/bin/bash -ex
+# vim: set ts=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
+#
+# Copyright (c) 2020 Red Hat, Inc.
+# Author: Sergio Correia <scorreia@redhat.com>
+#
+# 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 <http://www.gnu.org/licenses/>.
+
+TEST=$(basename "${0}")
+. tests-common-functions
+
+. clevis-luks-common-functions
+
+on_exit() {
+ local d
+ for d in "${TMP}" "${TMP2}"; do
+ [ ! -d "${d}" ] && continue
+ tang_stop "${d}"
+ rm -rf "${d}"
+ done
+}
+
+trap 'on_exit' EXIT
+trap 'on_exit' ERR
+
+TMP="$(mktemp -d)"
+
+port=$(get_random_port)
+tang_run "${TMP}" "${port}" &
+tang_wait_until_ready "${port}"
+
+url="http://${TANG_HOST}:${port}"
+
+cfg=$(printf '{"url":"%s"}' "$url")
+
+# LUKS1.
+DEV="${TMP}/luks1-device"
+new_device "luks1" "${DEV}"
+
+if ! clevis luks bind -y -d "${DEV}" tang "${cfg}" <<< "${DEFAULT_PASS}"; then
+ error "${TEST}: Bind should have succeeded."
+fi
+
+if ! clevis_luks_unlock_device "${DEV}"; then
+ error "${TEST}: we were unable to unlock ${DEV}."
+fi
+
+# Let's use a second tang server to test the sss pin.
+TMP2="$(mktemp -d)"
+
+port2=$(get_random_port)
+tang_run "${TMP2}" "${port2}" &
+tang_wait_until_ready "${port2}"
+
+url2="http://${TANG_HOST}:${port2}"
+
+cfg2=$(printf '{"t":1,"pins":{"tang":[{"url":"%s"},{"url":"%s"}]}}' \
+ "${url1}" "${url2}")
+
+# LUKS1.
+new_device "luks1" "${DEV}"
+# Now let's test the sss pin with the two test tang servers we deployed.
+if ! clevis luks bind -y -d "${DEV}" sss "${cfg2}" <<< "${DEFAULT_PASS}"; then
+ error "${TEST}: Bind should have succeeded."
+fi
+
+# Unlock should still work now.
+if ! clevis_luks_unlock_device "${DEV}"; then
+ error "${TEST}: we should still be able to unlock ${DEV}"
+fi
diff --git a/src/luks/tests/assume-yes-luks2 b/src/luks/tests/assume-yes-luks2
new file mode 100755
index 0000000..5c0edc3
--- /dev/null
+++ b/src/luks/tests/assume-yes-luks2
@@ -0,0 +1,81 @@
+#!/bin/bash -ex
+# vim: set ts=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
+#
+# Copyright (c) 2020 Red Hat, Inc.
+# Author: Sergio Correia <scorreia@redhat.com>
+#
+# 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 <http://www.gnu.org/licenses/>.
+
+TEST=$(basename "${0}")
+. tests-common-functions
+
+. clevis-luks-common-functions
+
+on_exit() {
+ local d
+ for d in "${TMP}" "${TMP2}"; do
+ [ ! -d "${d}" ] && continue
+ tang_stop "${d}"
+ rm -rf "${d}"
+ done
+}
+
+trap 'on_exit' EXIT
+trap 'on_exit' ERR
+
+TMP="$(mktemp -d)"
+
+port=$(get_random_port)
+tang_run "${TMP}" "${port}" &
+tang_wait_until_ready "${port}"
+
+url="http://${TANG_HOST}:${port}"
+
+cfg=$(printf '{"url":"%s"}' "$url")
+
+# LUKS2.
+DEV="${TMP}/luks2-device"
+new_device "luks2" "${DEV}"
+
+if ! clevis luks bind -y -d "${DEV}" tang "${cfg}" <<< "${DEFAULT_PASS}"; then
+ error "${TEST}: Bind should have succeeded."
+fi
+
+if ! clevis_luks_unlock_device "${DEV}"; then
+ error "${TEST}: we were unable to unlock ${DEV}."
+fi
+
+# Let's use a second tang server to test the sss pin.
+TMP2="$(mktemp -d)"
+
+port2=$(get_random_port)
+tang_run "${TMP2}" "${port2}" &
+tang_wait_until_ready "${port2}"
+
+url2="http://${TANG_HOST}:${port2}"
+
+cfg2=$(printf '{"t":1,"pins":{"tang":[{"url":"%s"},{"url":"%s"}]}}' \
+ "${url1}" "${url2}")
+
+# LUKS2.
+new_device "luks2" "${DEV}"
+# Now let's test the sss pin with the two test tang servers we deployed.
+if ! clevis luks bind -y -d "${DEV}" sss "${cfg2}" <<< "${DEFAULT_PASS}"; then
+ error "${TEST}: Bind should have succeeded."
+fi
+
+# Unlock should still work now.
+if ! clevis_luks_unlock_device "${DEV}"; then
+ error "${TEST}: we should still be able to unlock ${DEV}"
+fi
diff --git a/src/luks/tests/meson.build b/src/luks/tests/meson.build
index dbef9bf..4795488 100644
--- a/src/luks/tests/meson.build
+++ b/src/luks/tests/meson.build
@@ -85,6 +85,7 @@ endif
if has_tang
test('unlock-tang-luks1', find_program('unlock-tang-luks1'), env: env, timeout: 90)
+ test('assume-yes-luks1', find_program('assume-yes-luks1'), env: env)
endif
test('pass-tang-luks1', find_program('pass-tang-luks1'), env: env)
test('backup-restore-luks1', find_program('backup-restore-luks1'), env: env)
@@ -108,6 +109,7 @@ if luksmeta_data.get('OLD_CRYPTSETUP') == '0'
if has_tang
test('unlock-tang-luks2', find_program('unlock-tang-luks2'), env: env, timeout: 120)
+ test('assume-yes-luks2', find_program('assume-yes-luks2'), env: env, timeout: 60)
endif
test('pass-tang-luks2', find_program('pass-tang-luks2'), env: env, timeout: 60)
test('backup-restore-luks2', find_program('backup-restore-luks2'), env:env, timeout: 90)
diff --git a/src/pins/sss/clevis-encrypt-sss.1.adoc b/src/pins/sss/clevis-encrypt-sss.1.adoc
index 7144e7e..7152144 100644
--- a/src/pins/sss/clevis-encrypt-sss.1.adoc
+++ b/src/pins/sss/clevis-encrypt-sss.1.adoc
@@ -5,11 +5,11 @@ CLEVIS-ENCRYPT-SSS(1)
== NAME
-clevis-encrypt-sss - Encrypts using a Shamir's Secret Sharing policy
+clevis-encrypt-sss - Encrypts using a Shamir's Secret Sharing policy
== SYNOPSIS
-*clevis encrypt sss* CONFIG < PT > JWE
+*clevis encrypt sss* CONFIG [-y] < PT > JWE
== OVERVIEW
@@ -52,6 +52,16 @@ The format of the *pins* property is as follows:
When the list version of the format is used, multiple pins of that type will
receive key fragments.
+== OPTIONS
+
+* *-y* :
+ Automatically answer yes for all questions. For the _tang_ pin, it will
+ skip the advertisement trust check, which can be useful in automated
+ deployments:
+
+ $ cfg='{"t":1,"pins":{"tang":[{"url":...},{"url":...}]}}'
+ $ clevis encrypt sss "$cfg" -y < PT > JWE
+
== SEE ALSO
link:clevis-encrypt-tang.1.adoc[*clevis-encrypt-tang*(1)],
diff --git a/src/pins/sss/clevis-encrypt-sss.c b/src/pins/sss/clevis-encrypt-sss.c
index d6f2c2c..531e918 100644
--- a/src/pins/sss/clevis-encrypt-sss.c
+++ b/src/pins/sss/clevis-encrypt-sss.c
@@ -86,9 +86,9 @@ npins(json_t *pins)
}
static json_t *
-encrypt_frag(json_t *sss, const char *pin, const json_t *cfg)
+encrypt_frag(json_t *sss, const char *pin, const json_t *cfg, int assume_yes)
{
- char *args[] = { "clevis", "encrypt", (char *) pin, NULL, NULL };
+ char *args[] = { "clevis", "encrypt", (char *) pin, NULL, NULL, NULL };
json_auto_t *jwe = json_string("");
str_auto_t *str = NULL;
uint8_t *pnt = NULL;
@@ -100,6 +100,10 @@ encrypt_frag(json_t *sss, const char *pin, const json_t *cfg)
if (!str)
return NULL;
+ if (assume_yes) {
+ args[4] = "-y";
+ }
+
pnt = sss_point(sss, &pntl);
if (!pnt)
return NULL;
@@ -137,7 +141,7 @@ encrypt_frag(json_t *sss, const char *pin, const json_t *cfg)
}
static json_t *
-encrypt_frags(json_int_t t, json_t *pins)
+encrypt_frags(json_int_t t, json_t *pins, int assume_yes)
{
const char *pname = NULL;
json_auto_t *sss = NULL;
@@ -172,7 +176,7 @@ encrypt_frags(json_int_t t, json_t *pins)
json_array_foreach(pcfgs, i, pcfg) {
json_auto_t *jwe = NULL;
- jwe = encrypt_frag(sss, pname, pcfg);
+ jwe = encrypt_frag(sss, pname, pcfg, assume_yes);
if (!jwe)
return NULL;
@@ -201,14 +205,24 @@ main(int argc, char *argv[])
const char *iv = NULL;
json_t *pins = NULL;
json_int_t t = 1;
+ int assume_yes = 0;
if (argc == 2 && strcmp(argv[1], "--summary") == 0) {
fprintf(stdout, "%s\n", SUMMARY);
return EXIT_SUCCESS;
}
- if (isatty(STDIN_FILENO) || argc != 2)
- goto usage;
+ if (isatty(STDIN_FILENO) || argc != 2) {
+ if (argc != 3) {
+ goto usage;
+ }
+
+ if (strcmp(argv[2], "-y") == 0) {
+ assume_yes = 1;
+ } else if (strlen(argv[2]) > 0) {
+ goto usage;
+ }
+ }
/* Parse configuration. */
cfg = json_loads(argv[1], 0, NULL);
@@ -228,7 +242,7 @@ main(int argc, char *argv[])
return EXIT_FAILURE;
}
- sss = encrypt_frags(t, pins);
+ sss = encrypt_frags(t, pins, assume_yes);
if (!sss)
return EXIT_FAILURE;
@@ -287,7 +301,7 @@ main(int argc, char *argv[])
usage:
fprintf(stderr, "\n");
- fprintf(stderr, "Usage: clevis encrypt sss CONFIG < PLAINTEXT > JWE\n");
+ fprintf(stderr, "Usage: clevis encrypt sss CONFIG [-y] < PLAINTEXT > JWE\n");
fprintf(stderr, "\n");
fprintf(stderr, "%s\n", SUMMARY);
fprintf(stderr, "\n");
diff --git a/src/pins/tang/clevis-encrypt-tang b/src/pins/tang/clevis-encrypt-tang
index 378b25d..4a43f1f 100755
--- a/src/pins/tang/clevis-encrypt-tang
+++ b/src/pins/tang/clevis-encrypt-tang
@@ -28,10 +28,14 @@ fi
if [ -t 0 ]; then
exec >&2
echo
- echo "Usage: clevis encrypt tang CONFIG < PLAINTEXT > JWE"
+ echo "Usage: clevis encrypt tang CONFIG [-y] < PLAINTEXT > JWE"
echo
echo "$SUMMARY"
echo
+ echo " -y Use this option for skipping the advertisement"
+ echo " trust check. This can be useful in automated"
+ echo " deployments"
+ echo
echo "This command uses the following configuration properties:"
echo
echo " url: <string> The base URL of the Tang server (REQUIRED)"
@@ -60,6 +64,9 @@ if ! cfg="$(jose fmt -j- -Oo- <<< "$1" 2>/dev/null)"; then
exit 1
fi
+trust=
+[ -n "${2}" ] && [ "${2}" == "-y" ] && trust=yes
+
if ! url="$(jose fmt -j- -Og url -u- <<< "$cfg")"; then
echo "Missing the required 'url' property!" >&2
exit 1
@@ -100,18 +107,20 @@ if ! jose jws ver -i "$jws" -k- -a <<< "$ver"; then
fi
### Check advertisement trust
-if [ -z "$thp" ]; then
- echo "The advertisement contains the following signing keys:" >&2
- echo >&2
- jose jwk thp -i- <<< "$ver" >&2
- echo >&2
- read -r -p "Do you wish to trust these keys? [ynYN] " ans < /dev/tty
- [[ "$ans" =~ ^[yY]$ ]] || exit 1
-
-elif [ "$thp" != "any" ] && \
- ! jose jwk thp -i- -f "$thp" -o /dev/null <<< "$ver"; then
- echo "Trusted JWK '$thp' did not sign the advertisement!" >&2
- exit 1
+if [ -z "${trust}" ]; then
+ if [ -z "$thp" ]; then
+ echo "The advertisement contains the following signing keys:" >&2
+ echo >&2
+ jose jwk thp -i- <<< "$ver" >&2
+ echo >&2
+ read -r -p "Do you wish to trust these keys? [ynYN] " ans < /dev/tty
+ [[ "$ans" =~ ^[yY]$ ]] || exit 1
+
+ elif [ "$thp" != "any" ] && \
+ ! jose jwk thp -i- -f "$thp" -o /dev/null <<< "$ver"; then
+ echo "Trusted JWK '$thp' did not sign the advertisement!" >&2
+ exit 1
+ fi
fi
### Perform encryption
diff --git a/src/pins/tang/clevis-encrypt-tang.1.adoc b/src/pins/tang/clevis-encrypt-tang.1.adoc
index 276575f..c34d109 100644
--- a/src/pins/tang/clevis-encrypt-tang.1.adoc
+++ b/src/pins/tang/clevis-encrypt-tang.1.adoc
@@ -9,7 +9,7 @@ clevis-encrypt-tang - Encrypts using a Tang binding server policy
== SYNOPSIS
-*clevis encrypt tang* CONFIG < PT > JWE
+*clevis encrypt tang* CONFIG [-y] < PT > JWE
== OVERVIEW
@@ -76,6 +76,15 @@ This command uses the following configuration properties:
* *adv* (object) :
A trusted advertisement (raw JSON)
+== OPTIONS
+
+* *-y* :
+ Automatically answer yes for all questions. Use this option for skipping
+ the advertisement trust check. This can be useful in automated deployments:
+
+ $ clevis encrypt tang '{"url":...}' -y < PT > JWE
+
+
== SEE ALSO
link:clevis-decrypt.1.adoc[*clevis-decrypt*(1)]
--
2.18.4

File diff suppressed because it is too large Load Diff

View File

@ -1,25 +1,18 @@
%global _hardened_build 1
Name: clevis
Version: 13
Release: 3%{?dist}
Version: 15
Release: 1%{?dist}
Summary: Automated decryption framework
License: GPLv3+
URL: https://github.com/latchset/%{name}
Source0: https://github.com/latchset/%{name}/releases/download/v%{version}/%{name}-%{version}.tar.xz
Patch0001: 0001-Adjust-pin-tang-test-to-account-for-newer-tang-witho.patch
Patch0002: 0002-Fix-clevis-luks-unlock-and-add-related-tests.patch
Patch0003: 0003-Improve-error-message-when-bind-is-given-an-invalid-.patch
Patch0004: 0004-Add-rd.neednet-1-to-cmdline-only-if-there-are-device.patch
Patch0005: 0005-Add-the-option-to-extract-luks-passphrase-used-for-b.patch
Patch0006: 0006-Add-clevis-luks-regen-command.patch
Patch0007: 0007-Add-clevis-luks-report.patch
Patch0008: 0008-Use-one-clevis-luks-askpass-per-device.patch
Patch0009: 0009-Introduce-y-assume-yes-argument-to-clevis-luks-bind.patch
Patch0010: 0010-Add-clevis-luks-edit-command.patch
Patch0001: 0001-Fixes-for-dealing-with-newer-tang-without-tangd-upda.patch
Patch0002: 0002-Add-the-option-to-extract-luks-passphrase-used-for-b.patch
BuildRequires: git
BuildRequires: gcc
BuildRequires: meson
BuildRequires: asciidoc
@ -129,19 +122,25 @@ desktop-file-validate \
%meson_test
%pre
getent group %{name} >/dev/null || groupadd -r %{name}
getent group %{name} >/dev/null || groupadd -r %{name} &>/dev/null
getent passwd %{name} >/dev/null || \
useradd -r -g %{name} -d %{_localstatedir}/cache/%{name} -s /sbin/nologin \
-c "Clevis Decryption Framework unprivileged user" %{name}
-c "Clevis Decryption Framework unprivileged user" %{name} &>/dev/null
# 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
%pre systemd
if [ $1 -ge 0 ]; then
# clevis-systemd < 11-8 shipped with clevis-luks-askpass.path unit.
# Make sure it's gone.
[ -e /usr/lib/systemd/system/clevis-luks-askpass.path ] && \
systemctl disable clevis-luks-askpass.path
fi
%posttrans
# In case clevis-luks-askpass is enabled, make sure it's using the
# correct target, which changed in v14.
[ "$(find /etc/systemd/system/ -name "clevis-luks-askpass*")" ] || exit 0
find /etc/systemd/system/ -name "clevis-luks-askpass*" \
| grep -q cryptsetup.target.wants && exit 0
find /etc/systemd/system/ -name "clevis-luks-askpass*" -exec rm {} +
systemctl enable clevis-luks-askpass.path >/dev/null 2>&1 || :
exit 0
%files
@ -179,16 +178,12 @@ exit 0
%{_bindir}/%{name}-luks-pass
%{_bindir}/%{name}-luks-regen
%{_bindir}/%{name}-luks-report
%{_bindir}/%{name}-luks-report-compare
%{_bindir}/%{name}-luks-report-decode
%{_bindir}/%{name}-luks-report-sss
%{_bindir}/%{name}-luks-report-tang
%{_bindir}/%{name}-luks-edit
%files systemd
%{_libexecdir}/%{name}-luks-askpass
%{_unitdir}/%{name}-luks-askpass@.path
%{_unitdir}/%{name}-luks-askpass@.service
%{_unitdir}/%{name}-luks-askpass.path
%{_unitdir}/%{name}-luks-askpass.service
%files dracut
%{_prefix}/lib/dracut/modules.d/60%{name}
@ -201,6 +196,12 @@ exit 0
%attr(4755, root, root) %{_libexecdir}/%{name}-luks-udisks2
%changelog
* Mon Oct 26 2020 Sergio Correia <scorreia@redhat.com> - 15-1
- Update to latest upstream release, v15
Resolves: rhbz#1887836
Resolves: rhbz#1853651
Resolves: rhbz#1874460
* Wed May 20 2020 Sergio Correia <scorreia@redhat.com> - 13-3
- Add clevis luks edit command
Resolves: rhbz#1436735