]> git.ipfire.org Git - thirdparty/dracut.git/blob - modules.d/90crypt/cryptroot-ask.sh
ask for a password on readkey failure
[thirdparty/dracut.git] / modules.d / 90crypt / cryptroot-ask.sh
1 #!/bin/sh
2
3 PATH=/usr/sbin:/usr/bin:/sbin:/bin
4 NEWROOT=${NEWROOT:-"/sysroot"}
5
6 # do not ask, if we already have root
7 [ -f $NEWROOT/proc ] && exit 0
8
9 . /lib/dracut-lib.sh
10
11 # if device name is /dev/dm-X, convert to /dev/mapper/name
12 if [ "${1##/dev/dm-}" != "$1" ]; then
13 device="/dev/mapper/$(dmsetup info -c --noheadings -o name "$1")"
14 else
15 device="$1"
16 fi
17
18 # default luksname - luks-UUID
19 luksname=$2
20
21 # number of tries
22 numtries=${3:-10}
23
24 # TODO: improve to support what cmdline does
25 if [ -f /etc/crypttab ] && getargbool 1 rd.luks.crypttab -d -n rd_NO_CRYPTTAB; then
26 while read name dev luksfile luksoptions || [ -n "$name" ]; do
27 # ignore blank lines and comments
28 if [ -z "$name" -o "${name#\#}" != "$name" ]; then
29 continue
30 fi
31
32 # PARTUUID used in crypttab
33 if [ "${dev%%=*}" = "PARTUUID" ]; then
34 if [ "luks-${dev##PARTUUID=}" = "$luksname" ]; then
35 luksname="$name"
36 break
37 fi
38
39 # UUID used in crypttab
40 elif [ "${dev%%=*}" = "UUID" ]; then
41 if [ "luks-${dev##UUID=}" = "$luksname" ]; then
42 luksname="$name"
43 break
44 fi
45
46 # ID used in crypttab
47 elif [ "${dev%%=*}" = "ID" ]; then
48 if [ "luks-${dev##ID=}" = "$luksname" ]; then
49 luksname="$name"
50 break
51 fi
52
53 # path used in crypttab
54 else
55 cdev=$(readlink -f $dev)
56 mdev=$(readlink -f $device)
57 if [ "$cdev" = "$mdev" ]; then
58 luksname="$name"
59 break
60 fi
61 fi
62 done < /etc/crypttab
63 unset name dev
64 fi
65
66 # check if destination already exists
67 [ -b /dev/mapper/$luksname ] && exit 0
68
69 # we already asked for this device
70 asked_file=/tmp/cryptroot-asked-$luksname
71 [ -f $asked_file ] && exit 0
72
73 # load dm_crypt if it is not already loaded
74 [ -d /sys/module/dm_crypt ] || modprobe dm_crypt
75
76 . /lib/dracut-crypt-lib.sh
77
78 #
79 # Open LUKS device
80 #
81
82 info "luksOpen $device $luksname $luksfile $luksoptions"
83
84 OLD_IFS="$IFS"
85 IFS=,
86 set -- $luksoptions
87 IFS="$OLD_IFS"
88
89 while [ $# -gt 0 ]; do
90 case $1 in
91 noauto)
92 # skip this
93 exit 0
94 ;;
95 swap)
96 # skip this
97 exit 0
98 ;;
99 tmp)
100 # skip this
101 exit 0
102 ;;
103 allow-discards)
104 allowdiscards="--allow-discards"
105 ;;
106 header=*)
107 cryptsetupopts="${cryptsetupopts} --${1}"
108 ;;
109 esac
110 shift
111 done
112
113 # parse for allow-discards
114 if strstr "$(cryptsetup --help)" "allow-discards"; then
115 if discarduuids=$(getargs "rd.luks.allow-discards"); then
116 discarduuids=$(str_replace "$discarduuids" 'luks-' '')
117 if strstr " $discarduuids " " ${luksdev##luks-}"; then
118 allowdiscards="--allow-discards"
119 fi
120 elif getargbool 0 rd.luks.allow-discards; then
121 allowdiscards="--allow-discards"
122 fi
123 fi
124
125 if strstr "$(cryptsetup --help)" "allow-discards"; then
126 cryptsetupopts="$cryptsetupopts $allowdiscards"
127 fi
128
129 unset allowdiscards
130
131 # fallback to passphrase
132 ask_passphrase=1
133
134 if [ -n "$luksfile" -a "$luksfile" != "none" -a -e "$luksfile" ]; then
135 if cryptsetup --key-file "$luksfile" $cryptsetupopts luksOpen "$device" "$luksname"; then
136 ask_passphrase=0
137 fi
138 else
139 while [ -n "$(getarg rd.luks.key)" ]; do
140 if tmp=$(getkey /tmp/luks.keys $device); then
141 keydev="${tmp%%:*}"
142 keypath="${tmp#*:}"
143 else
144 if [ $numtries -eq 0 ]; then
145 warn "No key found for $device. Fallback to passphrase mode."
146 break
147 fi
148 sleep 1
149 info "No key found for $device. Will try $numtries time(s) more later."
150 initqueue --unique --onetime --settled \
151 --name cryptroot-ask-$luksname \
152 $(command -v cryptroot-ask) "$device" "$luksname" "$(($numtries-1))"
153 exit 0
154 fi
155 unset tmp
156
157 info "Using '$keypath' on '$keydev'"
158 readkey "$keypath" "$keydev" "$device" \
159 | cryptsetup -d - $cryptsetupopts luksOpen "$device" "$luksname" \
160 && ask_passphrase=0
161 unset keypath keydev
162 break
163 done
164 fi
165
166 if [ $ask_passphrase -ne 0 ]; then
167 luks_open="$(command -v cryptsetup) $cryptsetupopts luksOpen"
168 _timeout=$(getargs "rd.luks.timeout")
169 _timeout=${_timeout:-0}
170 ask_for_password --ply-tries 5 \
171 --ply-cmd "$luks_open -T1 $device $luksname" \
172 --ply-prompt "Password ($device)" \
173 --tty-tries 1 \
174 --tty-cmd "$luks_open -T5 -t $_timeout $device $luksname"
175 unset luks_open
176 unset _timeout
177 fi
178
179 unset device luksname luksfile
180
181 # mark device as asked
182 >> $asked_file
183
184 need_shutdown
185 udevsettle
186
187 exit 0