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
19 if [ -e /etc
/block_uuid.map
]; then
20 # search for line starting with $d
21 _line
=$
(sed -n "\,^$d .*$,{p}" /etc
/block_uuid.map
)
22 [ -z "$_line" ] && continue
23 # get second column with uuid
24 _uuid
="$(echo $_line | sed 's,^.* \(.*$\),\1,')"
25 strstr
"$_uuid" "${luks##luks-}" && return 0
34 # Wraps around plymouth ask-for-password and adds fallback to tty password ask
35 # if plymouth is not present.
38 # Command to execute. Required.
40 # Password prompt. Note that function already adds ':' at the end.
43 # How many times repeat command on its failure. Default is 3.
44 # --ply-[cmd|prompt|tries]
45 # Command/prompt/tries specific for plymouth password ask only.
46 # --tty-[cmd|prompt|tries]
47 # Command/prompt/tries specific for tty password ask only.
49 # Turn off input echo before tty command is executed and turn on after.
50 # It's useful when password is read from stdin.
52 local cmd
; local prompt
; local tries
=3
53 local ply_cmd
; local ply_prompt
; local ply_tries
=3
54 local tty_cmd
; local tty_prompt
; local tty_tries
=3
57 while [ $# -gt 0 ]; do
59 --cmd) ply_cmd
="$2"; tty_cmd
="$2"; shift;;
60 --ply-cmd) ply_cmd
="$2"; shift;;
61 --tty-cmd) tty_cmd
="$2"; shift;;
62 --prompt) ply_prompt
="$2"; tty_prompt
="$2"; shift;;
63 --ply-prompt) ply_prompt
="$2"; shift;;
64 --tty-prompt) tty_prompt
="$2"; shift;;
65 --tries) ply_tries
="$2"; tty_tries
="$2"; shift;;
66 --ply-tries) ply_tries
="$2"; shift;;
67 --tty-tries) tty_tries
="$2"; shift;;
68 --tty-echo-off) tty_echo_off
=yes;;
74 # Prompt for password with plymouth, if installed and running.
75 if type plymouth
>/dev
/null
2>&1 && plymouth
--ping 2>/dev
/null
; then
76 plymouth ask-for-password \
77 --prompt "$ply_prompt" --number-of-tries=$ply_tries \
81 if [ "$tty_echo_off" = yes ]; then
82 stty_orig
="$(stty -g)"
87 while [ $i -le $tty_tries ]; do
88 [ -n "$tty_prompt" ] && \
89 printf "$tty_prompt [$i/$tty_tries]:" >&2
90 eval "$tty_cmd" && ret
=0 && break
93 [ -n "$tty_prompt" ] && printf '\n' >&2
96 [ "$tty_echo_off" = yes ] && stty
$stty_orig
100 [ $ret -ne 0 ] && echo "Wrong password" >&2
104 # Try to mount specified device (by path, by UUID or by label) and check
105 # the path with 'test'.
108 # test_dev -f LABEL="nice label" /some/file1
110 local test_op
=$1; local dev
="$2"; local f
="$3"
111 local ret
=1; local mount_point
=$
(mkuniqdir
/mnt testdev
)
114 [ -n "$dev" -a -n "$*" ] ||
return 1
115 [ -d "$mount_point" ] || die
'Mount point does not exist!'
117 if mount
-r "$dev" "$mount_point" >/dev
/null
2>&1; then
118 test $test_op "${mount_point}/${f}"
120 umount
"$mount_point"
128 # match_dev devpattern dev
130 # Returns true if 'dev' matches 'devpattern'. Both 'devpattern' and 'dev' are
131 # expanded to kernel names and then compared. If name of 'dev' is on list of
132 # names of devices matching 'devpattern', the test is positive. 'dev' and
133 # 'devpattern' may be anything which function 'devnames' recognizes.
135 # If 'devpattern' is empty or '*' then function just returns true.
138 # match_dev UUID=123 /dev/dm-1
139 # Returns true if /dev/dm-1 UUID starts with "123".
141 [ -z "$1" -o "$1" = '*' ] && return 0
142 local devlist
; local dev
144 devlist
="$(devnames "$1")" ||
return 255
145 dev
="$(devnames "$2")" ||
return 255
154 # getkey keysfile for_dev
156 # Reads file <keysfile> produced by probe-keydev and looks for first line to
157 # which device <for_dev> matches. The successful result is printed in format
158 # "<keydev>:<keypath>". When nothing found, just false is returned.
161 # getkey /tmp/luks.keys /dev/sdb1
163 # /dev/sdc1:/keys/some.key
165 local keys_file
="$1"; local for_dev
="$2"
166 local luks_dev
; local key_dev
; local key_path
168 [ -z "$keys_file" -o -z "$for_dev" ] && die
'getkey: wrong usage!'
169 [ -f "$keys_file" ] ||
return 1
172 while read luks_dev key_dev key_path ||
[ -n "$luks_dev" ]; do
173 if match_dev
"$luks_dev" "$for_dev"; then
174 echo "${key_dev}:${key_path}"
182 # readkey keypath keydev device
184 # Mounts <keydev>, reads key from file <keypath>, optionally processes it (e.g.
185 # if encrypted with GPG) and prints to standard output which is supposed to be
186 # read by cryptsetup. <device> is just passed to helper function for
187 # informational purpose.
193 # No mounting needed if the keyfile resides inside the initrd
194 if [ "/" = "$keydev" ]; then
197 # This creates a unique single mountpoint for *, or several for explicitly
198 # given LUKS devices. It accomplishes unlocking multiple LUKS devices with
199 # a single password entry.
200 local mntp
="/mnt/$(str_replace "keydev-
$keydev-$keypath" '/' '-')"
202 if [ ! -d "$mntp" ]; then
204 mount
-r "$keydev" "$mntp" || die
'Mounting rem. dev. failed!'
208 case "${keypath##*.}" in
210 if [ -f /lib
/dracut-crypt-gpg-lib.sh
]; then
211 .
/lib
/dracut-crypt-gpg-lib.sh
212 gpg_decrypt
"$mntp" "$keypath" "$keydev" "$device"
214 die
"No GPG support to decrypt '$keypath' on '$keydev'."
218 if [ -f /lib
/dracut-crypt-loop-lib.sh
]; then
219 .
/lib
/dracut-crypt-loop-lib.sh
220 loop_decrypt
"$mntp" "$keypath" "$keydev" "$device"
221 printf "%s\n" "umount \"$mntp\"; rmdir \"$mntp\";" > ${hookdir}/cleanup
/"crypt-loop-cleanup-99-${mntp##*/}".sh
224 die
"No loop file support to decrypt '$keypath' on '$keydev'."
227 *) cat "$mntp/$keypath" ;;
230 # No unmounting if the keyfile resides inside the initrd
231 if [ "/" != "$keydev" ]; then
232 # General unmounting mechanism, modules doing custom cleanup should return earlier
233 # and install a pre-pivot cleanup hook