|
@@ -1,4 +1,4 @@
|
|
-#!/bin/bash -e
|
|
|
|
|
|
+#!/bin/bash
|
|
#
|
|
#
|
|
# Copyright (c) 2017 Red Hat, Inc.
|
|
# Copyright (c) 2017 Red Hat, Inc.
|
|
# Copyright (c) 2017 Shawn Rose
|
|
# Copyright (c) 2017 Shawn Rose
|
|
@@ -24,64 +24,91 @@
|
|
#
|
|
#
|
|
|
|
|
|
case $1 in
|
|
case $1 in
|
|
-prereqs) exit 0;;
|
|
|
|
|
|
+prereqs) exit 0 ;;
|
|
esac
|
|
esac
|
|
|
|
|
|
-# Return 0 if $pid has a file descriptor pointing to $name, 1 otherwise
|
|
|
|
-in_fds() {
|
|
|
|
- local pid="$1" name="$2" fd
|
|
|
|
|
|
+# Return fifo path or nothing if not found
|
|
|
|
+get_fifo_path() {
|
|
|
|
+ local pid="$1"
|
|
for fd in /proc/$pid/fd/*; do
|
|
for fd in /proc/$pid/fd/*; do
|
|
if [ -e "$fd" ]; then
|
|
if [ -e "$fd" ]; then
|
|
- [ "$(readlink -f "$fd")" != "$name" ] || return 0
|
|
|
|
|
|
+ if [[ $(readlink -f "${fd}") == *"/cryptsetup/passfifo" ]]; then
|
|
|
|
+ readlink -f "${fd}"
|
|
|
|
+ fi
|
|
fi
|
|
fi
|
|
done
|
|
done
|
|
- return 1
|
|
|
|
}
|
|
}
|
|
|
|
|
|
-# Print the PID of the askpass process with a file descriptor opened to
|
|
|
|
-# /lib/cryptsetup/passfifo if there is one.
|
|
|
|
|
|
+# Print the PID of the askpass process and fifo path with a file descriptor opened to
|
|
get_askpass_pid() {
|
|
get_askpass_pid() {
|
|
psinfo=$(ps) # Doing this so I don't end up matching myself
|
|
psinfo=$(ps) # Doing this so I don't end up matching myself
|
|
echo "$psinfo" | awk "/$cryptkeyscript/ { print \$1 }" | while read -r pid; do
|
|
echo "$psinfo" | awk "/$cryptkeyscript/ { print \$1 }" | while read -r pid; do
|
|
- if in_fds "$pid" "$PASSFIFO"; then
|
|
|
|
- echo "$pid"
|
|
|
|
|
|
+ pf=$(get_fifo_path "${pid}")
|
|
|
|
+ if [[ $pf != "" ]]; then
|
|
|
|
+ echo "${pid} ${pf}"
|
|
break
|
|
break
|
|
fi
|
|
fi
|
|
done
|
|
done
|
|
}
|
|
}
|
|
|
|
|
|
luks1_decrypt() {
|
|
luks1_decrypt() {
|
|
- luksmeta load "$@" \
|
|
|
|
- | clevis decrypt
|
|
|
|
|
|
+ local CRYPTTAB_SOURCE=$1
|
|
|
|
+ local PASSFIFO=$2
|
|
|
|
+ UUID=cb6e8904-81ff-40da-a84a-07ab9ab5715e
|
|
|
|
+ luksmeta show -d "$CRYPTTAB_SOURCE" | while read -r slot state uuid; do
|
|
|
|
+ [ "$state" == "active" ] || continue
|
|
|
|
+ [ "$uuid" == "$UUID" ] || continue
|
|
|
|
+
|
|
|
|
+ lml=$(luksmeta load -d "${CRYPTTAB_SOURCE}" -s "${slot}" -u "${UUID}")
|
|
|
|
+ [ $? -eq 0 ] || continue
|
|
|
|
+
|
|
|
|
+ decrypted=$(echo -n "${lml}" | clevis decrypt 2>/dev/null)
|
|
|
|
+ [ $? -eq 0 ] || continue
|
|
|
|
|
|
- local rc
|
|
|
|
- for rc in "${PIPESTATUS[@]}"; do
|
|
|
|
- [ $rc -eq 0 ] || return $rc
|
|
|
|
|
|
+ # Fail safe
|
|
|
|
+ [ "$decrypted" != "" ] || continue
|
|
|
|
+
|
|
|
|
+ echo -n "${decrypted}" >"$PASSFIFO"
|
|
|
|
+ return 0
|
|
done
|
|
done
|
|
- return 0
|
|
|
|
|
|
+
|
|
|
|
+ return 1
|
|
}
|
|
}
|
|
|
|
|
|
-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'
|
|
|
|
|
|
+luks2_decrypt() {
|
|
|
|
+ local CRYPTTAB_SOURCE=$1
|
|
|
|
+ local PASSFIFO=$2
|
|
|
|
+ cryptsetup luksDump "$CRYPTTAB_SOURCE" | sed -rn 's|^\s+([0-9]+): clevis|\1|p' | while read -r id; do
|
|
|
|
+ # jose jwe fmt -c outputs extra \n, so clean it up
|
|
|
|
+ cte=$(cryptsetup token export --token-id "$id" "$CRYPTTAB_SOURCE")
|
|
|
|
+ [ $? -eq 0 ] || continue
|
|
|
|
|
|
- local rc
|
|
|
|
- for rc in "${PIPESTATUS[@]}"; do
|
|
|
|
- [ $rc -eq 0 ] || return $rc
|
|
|
|
|
|
+ josefmt=$(echo "${cte}" | jose fmt -j- -Og jwe -o-)
|
|
|
|
+ [ $? -eq 0 ] || continue
|
|
|
|
+
|
|
|
|
+ josejwe=$(echo "${josefmt}" | jose jwe fmt -i- -c)
|
|
|
|
+ [ $? -eq 0 ] || continue
|
|
|
|
+
|
|
|
|
+ jwe=$(echo "${josejwe}" | tr -d '\n')
|
|
|
|
+ [ $? -eq 0 ] || continue
|
|
|
|
+
|
|
|
|
+ decrypted=$(echo -n "${jwe}" | clevis decrypt 2>/dev/null)
|
|
|
|
+ [ $? -eq 0 ] || continue
|
|
|
|
+
|
|
|
|
+ # Fail safe
|
|
|
|
+ [ "$decrypted" != "" ] || continue
|
|
|
|
+
|
|
|
|
+ echo -n "${decrypted}" >"$PASSFIFO"
|
|
|
|
+ return 0
|
|
done
|
|
done
|
|
- return 0
|
|
|
|
|
|
+
|
|
|
|
+ return 1
|
|
}
|
|
}
|
|
|
|
|
|
# Wait for askpass, and then try and decrypt immediately. Just in case
|
|
# Wait for askpass, and then try and decrypt immediately. Just in case
|
|
# there are multiple devices that need decrypting, this will loop
|
|
# there are multiple devices that need decrypting, this will loop
|
|
# infinitely (The local-bottom script will kill this after decryption)
|
|
# infinitely (The local-bottom script will kill this after decryption)
|
|
-clevisloop()
|
|
|
|
-{
|
|
|
|
- set -e
|
|
|
|
-
|
|
|
|
|
|
+clevisloop() {
|
|
# Set the path how we want it (Probably not all needed)
|
|
# Set the path how we want it (Probably not all needed)
|
|
PATH="/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin"
|
|
PATH="/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin"
|
|
|
|
|
|
@@ -92,54 +119,47 @@ clevisloop()
|
|
cryptkeyscript='\/lib\/cryptsetup\/askpass'
|
|
cryptkeyscript='\/lib\/cryptsetup\/askpass'
|
|
fi
|
|
fi
|
|
|
|
|
|
- PASSFIFO='/usr/lib/cryptsetup/passfifo'
|
|
|
|
-
|
|
|
|
OLD_CRYPTTAB_SOURCE=""
|
|
OLD_CRYPTTAB_SOURCE=""
|
|
|
|
|
|
while true; do
|
|
while true; do
|
|
|
|
|
|
- pid=$(get_askpass_pid)
|
|
|
|
-
|
|
|
|
until [ "$pid" ] && [ -p "$PASSFIFO" ]; do
|
|
until [ "$pid" ] && [ -p "$PASSFIFO" ]; do
|
|
sleep .1
|
|
sleep .1
|
|
- pid=$(get_askpass_pid)
|
|
|
|
|
|
+ pid_fifo=$(get_askpass_pid)
|
|
|
|
+ pid=$(echo "${pid_fifo}" | cut -d' ' -f1)
|
|
|
|
+ PASSFIFO=$(echo "${pid_fifo}" | cut -d' ' -f2-)
|
|
done
|
|
done
|
|
|
|
|
|
# Import CRYPTTAB_SOURCE from the askpass process.
|
|
# Import CRYPTTAB_SOURCE from the askpass process.
|
|
- local "$(grep '^CRYPTTAB_SOURCE=' /proc/"$pid"/environ)"
|
|
|
|
|
|
+ local CRYPTTAB_SOURCE="$(cat /proc/${pid}/environ 2> /dev/null | \
|
|
|
|
+ tr '\0' '\n' | grep '^CRYPTTAB_SOURCE=' | cut -d= -f2)"
|
|
|
|
+ [ -n "$CRYPTTAB_SOURCE" ] || continue
|
|
|
|
|
|
# Make sure that CRYPTTAB_SOURCE is actually a block device
|
|
# Make sure that CRYPTTAB_SOURCE is actually a block device
|
|
[ ! -b "$CRYPTTAB_SOURCE" ] && continue
|
|
[ ! -b "$CRYPTTAB_SOURCE" ] && continue
|
|
|
|
|
|
|
|
+ sleep .1
|
|
# Make the source has changed if needed
|
|
# Make the source has changed if needed
|
|
[ "$CRYPTTAB_SOURCE" = "$OLD_CRYPTTAB_SOURCE" ] && continue
|
|
[ "$CRYPTTAB_SOURCE" = "$OLD_CRYPTTAB_SOURCE" ] && continue
|
|
-
|
|
|
|
OLD_CRYPTTAB_SOURCE="$CRYPTTAB_SOURCE"
|
|
OLD_CRYPTTAB_SOURCE="$CRYPTTAB_SOURCE"
|
|
|
|
|
|
- UUID=cb6e8904-81ff-40da-a84a-07ab9ab5715e
|
|
|
|
if cryptsetup isLuks --type luks1 "$CRYPTTAB_SOURCE"; then
|
|
if cryptsetup isLuks --type luks1 "$CRYPTTAB_SOURCE"; then
|
|
# If the device is not initialized, sliently skip it.
|
|
# If the device is not initialized, sliently skip it.
|
|
luksmeta test -d "$CRYPTTAB_SOURCE" || continue
|
|
luksmeta test -d "$CRYPTTAB_SOURCE" || continue
|
|
|
|
|
|
- luksmeta show -d "$CRYPTTAB_SOURCE" | while read -r slot state uuid; do
|
|
|
|
- [ "$state" == "active" ] || continue
|
|
|
|
- [ "$uuid" == "$UUID" ] || continue
|
|
|
|
-
|
|
|
|
- if pt="$(luks1_decrypt -d "$CRYPTTAB_SOURCE" -s "$slot" -u "$UUID")"; then
|
|
|
|
- echo -n "$pt" > "$PASSFIFO"
|
|
|
|
- break
|
|
|
|
- fi
|
|
|
|
- done
|
|
|
|
|
|
+ if luks1_decrypt "${CRYPTTAB_SOURCE}" "${PASSFIFO}"; then
|
|
|
|
+ echo "Unlocked ${CRYPTTAB_SOURCE} with clevis"
|
|
|
|
+ else
|
|
|
|
+ OLD_CRYPTTAB_SOURCE=""
|
|
|
|
+ sleep 5
|
|
|
|
+ fi
|
|
elif cryptsetup isLuks --type luks2 "$CRYPTTAB_SOURCE"; then
|
|
elif cryptsetup isLuks --type luks2 "$CRYPTTAB_SOURCE"; then
|
|
- cryptsetup luksDump "$CRYPTTAB_SOURCE" | sed -rn 's|^\s+([0-9]+): clevis|\1|p' | while read -r id; do
|
|
|
|
- jwe="$(luks2_jwe --token-id "$id" "$CRYPTTAB_SOURCE")" \
|
|
|
|
- || continue
|
|
|
|
-
|
|
|
|
- if pt="$(echo -n "$jwe" | clevis decrypt)"; then
|
|
|
|
- echo -n "$pt" > "$PASSFIFO"
|
|
|
|
- break
|
|
|
|
- fi
|
|
|
|
- done
|
|
|
|
|
|
+ if luks2_decrypt "${CRYPTTAB_SOURCE}" "${PASSFIFO}"; then
|
|
|
|
+ echo "Unlocked ${CRYPTTAB_SOURCE} with clevis"
|
|
|
|
+ else
|
|
|
|
+ OLD_CRYPTTAB_SOURCE=""
|
|
|
|
+ sleep 5
|
|
|
|
+ fi
|
|
fi
|
|
fi
|
|
# Now that the current device has its password, let's sleep a
|
|
# Now that the current device has its password, let's sleep a
|
|
# bit. This gives cryptsetup time to actually decrypt the
|
|
# bit. This gives cryptsetup time to actually decrypt the
|
|
@@ -150,35 +170,34 @@ clevisloop()
|
|
|
|
|
|
. /scripts/functions
|
|
. /scripts/functions
|
|
|
|
|
|
-
|
|
|
|
# This is a copy of 'all_netbootable_devices/all_non_enslaved_devices' for
|
|
# This is a copy of 'all_netbootable_devices/all_non_enslaved_devices' for
|
|
# platforms that might not provide it.
|
|
# platforms that might not provide it.
|
|
clevis_all_netbootable_devices() {
|
|
clevis_all_netbootable_devices() {
|
|
- for device in /sys/class/net/* ; do
|
|
|
|
- if [ ! -e "$device/flags" ]; then
|
|
|
|
- continue
|
|
|
|
- fi
|
|
|
|
|
|
+ for device in /sys/class/net/*; do
|
|
|
|
+ if [ ! -e "$device/flags" ]; then
|
|
|
|
+ continue
|
|
|
|
+ fi
|
|
|
|
|
|
- loop=$(($(cat "$device/flags") & 0x8 && 1 || 0))
|
|
|
|
- bc=$(($(cat "$device/flags") & 0x2 && 1 || 0))
|
|
|
|
- ptp=$(($(cat "$device/flags") & 0x10 && 1 || 0))
|
|
|
|
|
|
+ loop=$(($(cat "$device/flags") & 0x8 && 1 || 0))
|
|
|
|
+ bc=$(($(cat "$device/flags") & 0x2 && 1 || 0))
|
|
|
|
+ ptp=$(($(cat "$device/flags") & 0x10 && 1 || 0))
|
|
|
|
|
|
- # Skip any device that is a loopback
|
|
|
|
- if [ $loop = 1 ]; then
|
|
|
|
- continue
|
|
|
|
- fi
|
|
|
|
|
|
+ # Skip any device that is a loopback
|
|
|
|
+ if [ $loop = 1 ]; then
|
|
|
|
+ continue
|
|
|
|
+ fi
|
|
|
|
|
|
- # Skip any device that isn't a broadcast
|
|
|
|
- # or point-to-point.
|
|
|
|
- if [ $bc = 0 ] && [ $ptp = 0 ]; then
|
|
|
|
- continue
|
|
|
|
- fi
|
|
|
|
|
|
+ # Skip any device that isn't a broadcast
|
|
|
|
+ # or point-to-point.
|
|
|
|
+ if [ $bc = 0 ] && [ $ptp = 0 ]; then
|
|
|
|
+ continue
|
|
|
|
+ fi
|
|
|
|
|
|
- # Skip any enslaved device (has "master" link
|
|
|
|
- # attribute on it)
|
|
|
|
- device=$(basename "$device")
|
|
|
|
- ip -o link show "$device" | grep -q -w master && continue
|
|
|
|
- DEVICE="$DEVICE $device"
|
|
|
|
|
|
+ # Skip any enslaved device (has "master" link
|
|
|
|
+ # attribute on it)
|
|
|
|
+ device=$(basename "$device")
|
|
|
|
+ ip -o link show "$device" | grep -q -w master && continue
|
|
|
|
+ DEVICE="$DEVICE $device"
|
|
done
|
|
done
|
|
echo "$DEVICE"
|
|
echo "$DEVICE"
|
|
}
|
|
}
|
|
@@ -202,4 +221,4 @@ if eth_check; then
|
|
fi
|
|
fi
|
|
|
|
|
|
clevisloop &
|
|
clevisloop &
|
|
-echo $! > /run/clevis.pid
|
|
|
|
|
|
+echo $! >/run/clevis.pid
|