]> git.ipfire.org Git - thirdparty/dracut.git/blame - modules.d/90crypt/cryptroot-ask.sh
ask for a password on readkey failure
[thirdparty/dracut.git] / modules.d / 90crypt / cryptroot-ask.sh
CommitLineData
ab83e0a6
HH
1#!/bin/sh
2
fb59f4c9 3PATH=/usr/sbin:/usr/bin:/sbin:/bin
8234b92d 4NEWROOT=${NEWROOT:-"/sysroot"}
fb59f4c9 5
5966b1b1 6# do not ask, if we already have root
8234b92d 7[ -f $NEWROOT/proc ] && exit 0
5966b1b1 8
e3469d76 9. /lib/dracut-lib.sh
c70f6415 10
bb2200ff
HH
11# if device name is /dev/dm-X, convert to /dev/mapper/name
12if [ "${1##/dev/dm-}" != "$1" ]; then
13 device="/dev/mapper/$(dmsetup info -c --noheadings -o name "$1")"
14else
15 device="$1"
16fi
17
e3469d76
CG
18# default luksname - luks-UUID
19luksname=$2
20
5ad3803d
HH
21# number of tries
22numtries=${3:-10}
23
8844cd6b 24# TODO: improve to support what cmdline does
68e7661c 25if [ -f /etc/crypttab ] && getargbool 1 rd.luks.crypttab -d -n rd_NO_CRYPTTAB; then
6d58fa27 26 while read name dev luksfile luksoptions || [ -n "$name" ]; do
2926b5b3
27 # ignore blank lines and comments
28 if [ -z "$name" -o "${name#\#}" != "$name" ]; then
29 continue
30 fi
31
b7058d0c 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
2926b5b3 39 # UUID used in crypttab
b7058d0c 40 elif [ "${dev%%=*}" = "UUID" ]; then
9b5e2e85 41 if [ "luks-${dev##UUID=}" = "$luksname" ]; then
2926b5b3
42 luksname="$name"
43 break
44 fi
3b403b32 45
b7058d0c 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
2926b5b3
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
349bac42 62 done < /etc/crypttab
5ad3803d 63 unset name dev
349bac42
HH
64fi
65
e3469d76
CG
66# check if destination already exists
67[ -b /dev/mapper/$luksname ] && exit 0
68
69# we already asked for this device
9835859f
TM
70asked_file=/tmp/cryptroot-asked-$luksname
71[ -f $asked_file ] && exit 0
e3469d76
CG
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
2926b5b3
78#
79# Open LUKS device
80#
81
5ad3803d
HH
82info "luksOpen $device $luksname $luksfile $luksoptions"
83
84OLD_IFS="$IFS"
85IFS=,
86set -- $luksoptions
87IFS="$OLD_IFS"
88
89while [ $# -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"
b7058d0c 105 ;;
106 header=*)
107 cryptsetupopts="${cryptsetupopts} --${1}"
108 ;;
5ad3803d
HH
109 esac
110 shift
111done
112
113# parse for allow-discards
114if strstr "$(cryptsetup --help)" "allow-discards"; then
115 if discarduuids=$(getargs "rd.luks.allow-discards"); then
329bbd79
HH
116 discarduuids=$(str_replace "$discarduuids" 'luks-' '')
117 if strstr " $discarduuids " " ${luksdev##luks-}"; then
5ad3803d
HH
118 allowdiscards="--allow-discards"
119 fi
329bbd79 120 elif getargbool 0 rd.luks.allow-discards; then
5ad3803d
HH
121 allowdiscards="--allow-discards"
122 fi
123fi
124
125if strstr "$(cryptsetup --help)" "allow-discards"; then
126 cryptsetupopts="$cryptsetupopts $allowdiscards"
127fi
128
129unset allowdiscards
2926b5b3 130
e3469d76
CG
131# fallback to passphrase
132ask_passphrase=1
133
4e05cb40 134if [ -n "$luksfile" -a "$luksfile" != "none" -a -e "$luksfile" ]; then
5ad3803d 135 if cryptsetup --key-file "$luksfile" $cryptsetupopts luksOpen "$device" "$luksname"; then
4e05cb40
HH
136 ask_passphrase=0
137 fi
138else
139 while [ -n "$(getarg rd.luks.key)" ]; do
140 if tmp=$(getkey /tmp/luks.keys $device); then
141 keydev="${tmp%%:*}"
142 keypath="${tmp#*:}"
c70f6415 143 else
5ad3803d
HH
144 if [ $numtries -eq 0 ]; then
145 warn "No key found for $device. Fallback to passphrase mode."
146 break
4e05cb40 147 fi
5ad3803d
HH
148 sleep 1
149 info "No key found for $device. Will try $numtries time(s) more later."
4e05cb40
HH
150 initqueue --unique --onetime --settled \
151 --name cryptroot-ask-$luksname \
5ad3803d 152 $(command -v cryptroot-ask) "$device" "$luksname" "$(($numtries-1))"
4e05cb40 153 exit 0
c70f6415 154 fi
4e05cb40
HH
155 unset tmp
156
157 info "Using '$keypath' on '$keydev'"
158 readkey "$keypath" "$keydev" "$device" \
705eb4ee
MR
159 | cryptsetup -d - $cryptsetupopts luksOpen "$device" "$luksname" \
160 && ask_passphrase=0
4e05cb40 161 unset keypath keydev
4e05cb40
HH
162 break
163 done
164fi
165
c70f6415 166if [ $ask_passphrase -ne 0 ]; then
5ad3803d 167 luks_open="$(command -v cryptsetup) $cryptsetupopts luksOpen"
c1688560
NP
168 _timeout=$(getargs "rd.luks.timeout")
169 _timeout=${_timeout:-0}
3909d7ed
170 ask_for_password --ply-tries 5 \
171 --ply-cmd "$luks_open -T1 $device $luksname" \
172 --ply-prompt "Password ($device)" \
173 --tty-tries 1 \
c1688560 174 --tty-cmd "$luks_open -T5 -t $_timeout $device $luksname"
3909d7ed 175 unset luks_open
c1688560 176 unset _timeout
2926b5b3 177fi
ab83e0a6 178
4e05cb40 179unset device luksname luksfile
7254c24a 180
5966b1b1 181# mark device as asked
9b5e2e85 182>> $asked_file
5966b1b1 183
fb67e4aa 184need_shutdown
7254c24a
MS
185udevsettle
186
ed2de829 187exit 0