/usr/lib/dracut/modules.d/90crypt/crypt-lib.sh is in dracut-core 047-2.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | #!/bin/sh
command -v getarg >/dev/null || . /lib/dracut-lib.sh
# check if the crypttab contains an entry for a LUKS UUID
crypttab_contains() {
local luks="$1"
local dev="$2"
local l d rest
if [ -f /etc/crypttab ]; then
while read l d rest || [ -n "$l" ]; do
strstr "${l##luks-}" "${luks##luks-}" && return 0
strstr "$d" "${luks##luks-}" && return 0
if [ -n "$dev" ]; then
for _dev in "$(devnames $d)"; do
[ "$dev" -ef "$_dev" ] && return 0
done
fi
if [ -e /etc/block_uuid.map ]; then
# search for line starting with $d
_line=$(sed -n "\,^$d .*$,{p}" /etc/block_uuid.map)
[ -z "$_line" ] && continue
# get second column with uuid
_uuid="$(echo $_line | sed 's,^.* \(.*$\),\1,')"
strstr "$_uuid" "${luks##luks-}" && return 0
fi
done < /etc/crypttab
fi
return 1
}
# ask_for_password
#
# Wraps around plymouth ask-for-password and adds fallback to tty password ask
# if plymouth is not present.
#
# --cmd command
# Command to execute. Required.
# --prompt prompt
# Password prompt. Note that function already adds ':' at the end.
# Recommended.
# --tries n
# How many times repeat command on its failure. Default is 3.
# --ply-[cmd|prompt|tries]
# Command/prompt/tries specific for plymouth password ask only.
# --tty-[cmd|prompt|tries]
# Command/prompt/tries specific for tty password ask only.
# --tty-echo-off
# Turn off input echo before tty command is executed and turn on after.
# It's useful when password is read from stdin.
ask_for_password() {
local cmd; local prompt; local tries=3
local ply_cmd; local ply_prompt; local ply_tries=3
local tty_cmd; local tty_prompt; local tty_tries=3
local ret
while [ $# -gt 0 ]; do
case "$1" in
--cmd) ply_cmd="$2"; tty_cmd="$2"; shift;;
--ply-cmd) ply_cmd="$2"; shift;;
--tty-cmd) tty_cmd="$2"; shift;;
--prompt) ply_prompt="$2"; tty_prompt="$2"; shift;;
--ply-prompt) ply_prompt="$2"; shift;;
--tty-prompt) tty_prompt="$2"; shift;;
--tries) ply_tries="$2"; tty_tries="$2"; shift;;
--ply-tries) ply_tries="$2"; shift;;
--tty-tries) tty_tries="$2"; shift;;
--tty-echo-off) tty_echo_off=yes;;
esac
shift
done
{ flock -s 9;
# Prompt for password with plymouth, if installed and running.
if type plymouth >/dev/null 2>&1 && plymouth --ping 2>/dev/null; then
plymouth ask-for-password \
--prompt "$ply_prompt" --number-of-tries=$ply_tries \
--command="$ply_cmd"
ret=$?
else
if [ "$tty_echo_off" = yes ]; then
stty_orig="$(stty -g)"
stty -echo
fi
local i=1
while [ $i -le $tty_tries ]; do
[ -n "$tty_prompt" ] && \
printf "$tty_prompt [$i/$tty_tries]:" >&2
eval "$tty_cmd" && ret=0 && break
ret=$?
i=$(($i+1))
[ -n "$tty_prompt" ] && printf '\n' >&2
done
[ "$tty_echo_off" = yes ] && stty $stty_orig
fi
} 9>/.console_lock
[ $ret -ne 0 ] && echo "Wrong password" >&2
return $ret
}
# Try to mount specified device (by path, by UUID or by label) and check
# the path with 'test'.
#
# example:
# test_dev -f LABEL="nice label" /some/file1
test_dev() {
local test_op=$1; local dev="$2"; local f="$3"
local ret=1; local mount_point=$(mkuniqdir /mnt testdev)
local path
[ -n "$dev" -a -n "$*" ] || return 1
[ -d "$mount_point" ] || die 'Mount point does not exist!'
if mount -r "$dev" "$mount_point" >/dev/null 2>&1; then
test $test_op "${mount_point}/${f}"
ret=$?
umount "$mount_point"
fi
rmdir "$mount_point"
return $ret
}
# match_dev devpattern dev
#
# Returns true if 'dev' matches 'devpattern'. Both 'devpattern' and 'dev' are
# expanded to kernel names and then compared. If name of 'dev' is on list of
# names of devices matching 'devpattern', the test is positive. 'dev' and
# 'devpattern' may be anything which function 'devnames' recognizes.
#
# If 'devpattern' is empty or '*' then function just returns true.
#
# Example:
# match_dev UUID=123 /dev/dm-1
# Returns true if /dev/dm-1 UUID starts with "123".
match_dev() {
[ -z "$1" -o "$1" = '*' ] && return 0
local devlist; local dev
devlist="$(devnames "$1")" || return 255
dev="$(devnames "$2")" || return 255
strstr "
$devlist
" "
$dev
"
}
# getkey keysfile for_dev
#
# Reads file <keysfile> produced by probe-keydev and looks for first line to
# which device <for_dev> matches. The successful result is printed in format
# "<keydev>:<keypath>". When nothing found, just false is returned.
#
# Example:
# getkey /tmp/luks.keys /dev/sdb1
# May print:
# /dev/sdc1:/keys/some.key
getkey() {
local keys_file="$1"; local for_dev="$2"
local luks_dev; local key_dev; local key_path
[ -z "$keys_file" -o -z "$for_dev" ] && die 'getkey: wrong usage!'
[ -f "$keys_file" ] || return 1
local IFS=:
while read luks_dev key_dev key_path || [ -n "$luks_dev" ]; do
if match_dev "$luks_dev" "$for_dev"; then
echo "${key_dev}:${key_path}"
return 0
fi
done < "$keys_file"
return 1
}
# readkey keypath keydev device
#
# Mounts <keydev>, reads key from file <keypath>, optionally processes it (e.g.
# if encrypted with GPG) and prints to standard output which is supposed to be
# read by cryptsetup. <device> is just passed to helper function for
# informational purpose.
readkey() {
local keypath="$1"
local keydev="$2"
local device="$3"
# No mounting needed if the keyfile resides inside the initrd
if [ "/" == "$keydev" ]; then
local mntp=/
else
# This creates a unique single mountpoint for *, or several for explicitly
# given LUKS devices. It accomplishes unlocking multiple LUKS devices with
# a single password entry.
local mntp="/mnt/$(str_replace "keydev-$keydev-$keypath" '/' '-')"
if [ ! -d "$mntp" ]; then
mkdir "$mntp"
mount -r "$keydev" "$mntp" || die 'Mounting rem. dev. failed!'
fi
fi
case "${keypath##*.}" in
gpg)
if [ -f /lib/dracut-crypt-gpg-lib.sh ]; then
. /lib/dracut-crypt-gpg-lib.sh
gpg_decrypt "$mntp" "$keypath" "$keydev" "$device"
else
die "No GPG support to decrypt '$keypath' on '$keydev'."
fi
;;
img)
if [ -f /lib/dracut-crypt-loop-lib.sh ]; then
. /lib/dracut-crypt-loop-lib.sh
loop_decrypt "$mntp" "$keypath" "$keydev" "$device"
printf "%s\n" "umount \"$mntp\"; rmdir \"$mntp\";" > ${hookdir}/cleanup/"crypt-loop-cleanup-99-${mntp##*/}".sh
return 0
else
die "No loop file support to decrypt '$keypath' on '$keydev'."
fi
;;
*) cat "$mntp/$keypath" ;;
esac
# No unmounting if the keyfile resides inside the initrd
if [ "/" != "$keydev" ]; then
# General unmounting mechanism, modules doing custom cleanup should return earlier
# and install a pre-pivot cleanup hook
umount "$mntp"
rmdir "$mntp"
fi
}
|