3 command -v getarg
>/dev
/null || .
/lib
/dracut-lib.sh
5 # check if the crypttab contains an entry for a LUKS UUID
10 if [ -f /etc
/crypttab
]; then
11 while read l d rest ||
[ -n "$l" ]; do
12 strstr
"${l##luks-}" "${luks##luks-}" && return 0
13 strstr
"$d" "${luks##luks-}" && return 0
14 if [ -n "$dev" ]; then
15 for _dev
in "$(devnames $d)"; do
16 [ "$dev" -ef "$_dev" ] && return 0
26 # Wraps around plymouth ask-for-password and adds fallback to tty password ask
27 # if plymouth is not present.
30 # Command to execute. Required.
32 # Password prompt. Note that function already adds ':' at the end.
35 # How many times repeat command on its failure. Default is 3.
36 # --ply-[cmd|prompt|tries]
37 # Command/prompt/tries specific for plymouth password ask only.
38 # --tty-[cmd|prompt|tries]
39 # Command/prompt/tries specific for tty password ask only.
41 # Turn off input echo before tty command is executed and turn on after.
42 # It's useful when password is read from stdin.
44 local cmd
; local prompt
; local tries
=3
45 local ply_cmd
; local ply_prompt
; local ply_tries
=3
46 local tty_cmd
; local tty_prompt
; local tty_tries
=3
49 while [ $# -gt 0 ]; do
51 --cmd) ply_cmd
="$2"; tty_cmd
="$2"; shift;;
52 --ply-cmd) ply_cmd
="$2"; shift;;
53 --tty-cmd) tty_cmd
="$2"; shift;;
54 --prompt) ply_prompt
="$2"; tty_prompt
="$2"; shift;;
55 --ply-prompt) ply_prompt
="$2"; shift;;
56 --tty-prompt) tty_prompt
="$2"; shift;;
57 --tries) ply_tries
="$2"; tty_tries
="$2"; shift;;
58 --ply-tries) ply_tries
="$2"; shift;;
59 --tty-tries) tty_tries
="$2"; shift;;
60 --tty-echo-off) tty_echo_off
=yes;;
66 # Prompt for password with plymouth, if installed and running.
67 if type plymouth
>/dev
/null
2>&1 && plymouth
--ping 2>/dev
/null
; then
68 plymouth ask-for-password \
69 --prompt "$ply_prompt" --number-of-tries=$ply_tries \
73 if [ "$tty_echo_off" = yes ]; then
74 stty_orig
="$(stty -g)"
79 while [ $i -le $tty_tries ]; do
80 [ -n "$tty_prompt" ] && \
81 printf "$tty_prompt [$i/$tty_tries]:" >&2
82 eval "$tty_cmd" && ret
=0 && break
85 [ -n "$tty_prompt" ] && printf '\n' >&2
88 [ "$tty_echo_off" = yes ] && stty
$stty_orig
92 [ $ret -ne 0 ] && echo "Wrong password" >&2
96 # Try to mount specified device (by path, by UUID or by label) and check
97 # the path with 'test'.
100 # test_dev -f LABEL="nice label" /some/file1
102 local test_op
=$1; local dev
="$2"; local f
="$3"
103 local ret
=1; local mount_point
=$
(mkuniqdir
/mnt testdev
)
106 [ -n "$dev" -a -n "$*" ] ||
return 1
107 [ -d "$mount_point" ] || die
'Mount point does not exist!'
109 if mount
-r "$dev" "$mount_point" >/dev
/null
2>&1; then
110 test $test_op "${mount_point}/${f}"
112 umount
"$mount_point"
120 # match_dev devpattern dev
122 # Returns true if 'dev' matches 'devpattern'. Both 'devpattern' and 'dev' are
123 # expanded to kernel names and then compared. If name of 'dev' is on list of
124 # names of devices matching 'devpattern', the test is positive. 'dev' and
125 # 'devpattern' may be anything which function 'devnames' recognizes.
127 # If 'devpattern' is empty or '*' then function just returns true.
130 # match_dev UUID=123 /dev/dm-1
131 # Returns true if /dev/dm-1 UUID starts with "123".
133 [ -z "$1" -o "$1" = '*' ] && return 0
134 local devlist
; local dev
136 devlist
="$(devnames "$1")" ||
return 255
137 dev
="$(devnames "$2")" ||
return 255
146 # getkey keysfile for_dev
148 # Reads file <keysfile> produced by probe-keydev and looks for first line to
149 # which device <for_dev> matches. The successful result is printed in format
150 # "<keydev>:<keypath>". When nothing found, just false is returned.
153 # getkey /tmp/luks.keys /dev/sdb1
155 # /dev/sdc1:/keys/some.key
157 local keys_file
="$1"; local for_dev
="$2"
158 local luks_dev
; local key_dev
; local key_path
160 [ -z "$keys_file" -o -z "$for_dev" ] && die
'getkey: wrong usage!'
161 [ -f "$keys_file" ] ||
return 1
164 while read luks_dev key_dev key_path ||
[ -n "$luks_dev" ]; do
165 if match_dev
"$luks_dev" "$for_dev"; then
166 echo "${key_dev}:${key_path}"
174 # readkey keypath keydev device
176 # Mounts <keydev>, reads key from file <keypath>, optionally processes it (e.g.
177 # if encrypted with GPG) and prints to standard output which is supposed to be
178 # read by cryptsetup. <device> is just passed to helper function for
179 # informational purpose.
185 # This creates a unique single mountpoint for *, or several for explicitly
186 # given LUKS devices. It accomplishes unlocking multiple LUKS devices with
187 # a single password entry.
188 local mntp
="/mnt/$(str_replace "keydev-
$keydev-$keypath" '/' '-')"
190 if [ ! -d "$mntp" ]; then
192 mount
-r "$keydev" "$mntp" || die
'Mounting rem. dev. failed!'
195 case "${keypath##*.}" in
197 if [ -f /lib
/dracut-crypt-gpg-lib.sh
]; then
198 .
/lib
/dracut-crypt-gpg-lib.sh
199 gpg_decrypt
"$mntp" "$keypath" "$keydev" "$device"
201 die
"No GPG support to decrypt '$keypath' on '$keydev'."
205 if [ -f /lib
/dracut-crypt-loop-lib.sh
]; then
206 .
/lib
/dracut-crypt-loop-lib.sh
207 loop_decrypt
"$mntp" "$keypath" "$keydev" "$device"
208 initqueue
--onetime --finished --unique --name "crypt-loop-cleanup-99-${mntp##*/}" \
209 $
(command -v umount
) "$mntp; " $
(command -v rmdir) "$mntp"
212 die
"No loop file support to decrypt '$keypath' on '$keydev'."
215 *) cat "$mntp/$keypath" ;;
218 # General unmounting mechanism, modules doing custom cleanup should return earlier
219 # and install a pre-pivot cleanup hook