]> git.pld-linux.org Git - packages/cryptsetup-luks.git/blob - cryptsetup-luks-initramfs-root-local-top
- package python binding (as python-pycryptsetup)
[packages/cryptsetup-luks.git] / cryptsetup-luks-initramfs-root-local-top
1 #!/bin/sh
2
3 #
4 # Standard initramfs preamble
5 #
6 prereqs()
7 {
8         # Make sure that cryptroot is run last in local-top
9         for req in /scripts/local-top/*; do
10                 script=${req##*/}
11                 if [ $script != cryptroot ]; then
12                         echo $script
13                 fi
14         done
15 }
16
17 case $1 in
18 prereqs)
19         prereqs
20         exit 0
21         ;;
22 esac
23
24
25 #
26 # Helper functions
27 #
28 message()
29 {
30         if [ -p /dev/.initramfs/usplash_outfifo ] && [ -x /sbin/usplash_write ]; then
31                 usplash_write "TEXT-URGENT $@"
32         else
33                 echo "$@" >&2
34         fi
35         return 0
36 }
37
38 parse_options()
39 {
40         local cryptopts
41         cryptopts="$1"
42
43         if [ -z "$cryptopts" ]; then
44                 return 1
45         fi
46
47         # Defaults
48         cryptcipher=aes-cbc-essiv:sha256
49         cryptsize=256
50         crypthash=ripemd160
51         crypttarget=cryptroot
52         cryptsource=""
53         cryptlvm=""
54         cryptkeyscript=""
55         cryptkey="" # This is only used as an argument to an eventual keyscript
56         crypttries=3
57
58         local IFS=" ,"
59         for x in $cryptopts; do
60                 case $x in
61                 hash=*)
62                         crypthash=${x#hash=}
63                         ;;
64                 size=*)
65                         cryptsize=${x#size=}
66                         ;;
67                 cipher=*)
68                         cryptcipher=${x#cipher=}
69                         ;;
70                 target=*)
71                         crypttarget=${x#target=}
72                         ;;
73                 source=*)
74                         cryptsource=${x#source=}
75                         if [ ${cryptsource#UUID=} != $cryptsource ]; then
76                                 cryptsource="/dev/disk/by-uuid/${cryptsource#UUID=}"
77                         elif [ ${cryptsource#LABEL=} != $cryptsource ]; then
78                                 cryptsource="/dev/disk/by-label/${cryptsource#LABEL=}"
79                         fi
80                         ;;
81                 lvm=*)
82                         cryptlvm=${x#lvm=}
83                         ;;
84                 keyscript=*)
85                         cryptkeyscript=${x#keyscript=}
86                         ;;
87                 key=*)
88                         if [ "${x#key=}" != "none" ]; then
89                                 cryptkey=${x#key=}
90                         fi
91                         ;;
92                 tries=*)
93                         crypttries="${x#tries=}"
94                         case "$crypttries" in
95                           *[![:digit:].]*)
96                                 crypttries=3
97                                 ;;
98                         esac
99                         ;;
100                 esac
101         done
102
103         if [ -z "$cryptsource" ]; then
104                 message "cryptsetup: source parameter missing"
105                 return 1
106         fi
107         return 0
108 }
109
110 activate_vg()
111 {
112         local vg
113         vg="${1#/dev/mapper/}"
114
115         # Sanity checks
116         if [ ! -x /sbin/lvm ] || [ "$vg" = "$1" ]; then
117                 return 1
118         fi
119
120         # Make sure that the device contains at least one dash
121         if [ "${vg%%-*}" = "$vg" ]; then
122                 return 1
123         fi
124
125         # Split volume group from logical volume.
126         vg=$(echo ${vg} | sed -e 's#\(.*\)\([^-]\)-[^-].*#\1\2#')
127
128         # Reduce padded --'s to -'s
129         vg=$(echo ${vg} | sed -e 's#--#-#g')
130
131         lvm vgchange -ay ${vg}
132         return $?
133 }
134
135 activate_evms()
136 {
137         local dev module
138         dev="${1#/dev/evms/}"
139
140         # Sanity checks
141         if [ ! -x /sbin/evms_activate ] || [ "$dev" = "$1" ]; then
142                 return 1
143         fi
144
145         # Load modules used by evms
146         for module in dm-mod linear raid0 raid1 raid10 raid5 raid6; do
147                 /sbin/modprobe -q $module
148         done
149
150         # Activate it
151         /sbin/evms_activate
152         return $?
153 }
154
155 setup_mapping()
156 {
157         local opts count cryptcreate cryptremove NEWROOT
158         opts="$1"
159
160         if [ -z "$opts" ]; then
161                 return 0
162         fi
163
164         parse_options "$opts" || return 1
165
166         if [ -n "$cryptkeyscript" ] && [ ! -x "$cryptkeyscript" ]; then
167                 message "cryptsetup: error - script \"$cryptkeyscript\" missing"
168                 return 1
169         fi
170
171         # The same target can be specified multiple times
172         # e.g. root and resume lvs-on-lvm-on-crypto
173         if [ -e "/dev/mapper/$crypttarget" ]; then
174                 return 0
175         fi
176
177         /sbin/modprobe -q dm_crypt
178
179         # Make sure the cryptsource device is available
180         if [ ! -e $cryptsource ]; then
181                 activate_vg $cryptsource
182                 activate_evms $cryptsource
183         fi
184
185         /sbin/udevadm settle --timeout=30
186
187         if [ ! -e $cryptsource ]; then
188                 message "cryptsetup: source device $cryptsource not found"
189                 return 1
190         fi
191
192         # Prepare commands
193         if /sbin/cryptsetup isLuks $cryptsource > /dev/null 2>&1; then
194                 cryptcreate="/sbin/cryptsetup -T 1 luksOpen $cryptsource $crypttarget"
195         else
196                 cryptcreate="/sbin/cryptsetup -T 1 -c $cryptcipher -s $cryptsize -h $crypthash create $crypttarget $cryptsource"
197         fi
198         cryptremove="/sbin/cryptsetup remove $crypttarget"
199         NEWROOT="/dev/mapper/$crypttarget"
200
201         # Try to get a satisfactory password $crypttries times
202         count=0
203         while [ $crypttries -le 0 ] || [ $count -lt $crypttries ]; do
204                 count=$(( $count + 1 ))
205
206                 if [ $count -gt 1 ]; then
207                         sleep 3
208                 fi
209
210                 if [ $crypttries -gt 0 ] && [ $count -gt $crypttries ]; then
211                         message "cryptsetup: maximum number of tries exceeded for $crypttarget"
212                         return 1
213                 fi
214
215                 if [ -z "$cryptkeyscript" ]; then
216                         cryptkeyscript="/lib/cryptsetup/askpass"
217                         cryptkey="Enter passphrase to unlock the disk $cryptsource ($crypttarget): "
218                 fi
219
220
221                 if ! crypttarget="$crypttarget" cryptsource="$cryptsource" \
222                      $cryptkeyscript "$cryptkey" | $cryptcreate --key-file=- ; then
223                         message "cryptsetup: cryptsetup failed, bad password or options?"
224                         continue
225                 fi
226
227                 if [ ! -e "$NEWROOT" ]; then
228                         message "cryptsetup: unknown error setting up device mapping"
229                         return 1
230                 fi
231
232                 FSTYPE=''
233                 eval $(fstype < "$NEWROOT")
234
235                 # See if we need to setup lvm on the crypto device
236                 if [ "$FSTYPE" = "lvm" ] || [ "$FSTYPE" = "lvm2" ]; then
237                         if [ -z "$cryptlvm" ]; then
238                                 message "cryptsetup: lvm fs found but no lvm configured"
239                                 return 1
240                         elif ! activate_vg "/dev/mapper/$cryptlvm"; then
241                                 message "cryptsetup: failed to setup lvm device"
242                                 return 1
243                         fi
244
245                         NEWROOT="/dev/mapper/$cryptlvm"
246                         eval $(fstype < "$NEWROOT")
247                 fi
248
249                 if [ -z "$FSTYPE" ] || [ "$FSTYPE" = "unknown" ]; then
250                         message "cryptsetup: unknown fstype, bad password or options?"
251                         $cryptremove
252                         continue
253                 fi
254
255                 message "cryptsetup: $crypttarget setup successfully"
256                 break
257         done
258
259         /sbin/udevadm settle --timeout=30
260         return 0
261 }
262
263 #
264 # Begin real processing
265 #
266
267 # Do we have any kernel boot arguments?
268 found=''
269 for opt in $(cat /proc/cmdline); do
270         case $opt in
271         cryptopts=*)
272                 found=yes
273                 setup_mapping "${opt#cryptopts=}"
274                 ;;
275         esac
276 done
277
278 if [ -n "$found" ]; then
279         exit 0
280 fi
281
282 # Do we have any settings from the /conf/conf.d/cryptroot file?
283 if [ -r /conf/conf.d/cryptroot ]; then
284         while read mapping <&3; do
285                 setup_mapping "$mapping"
286         done 3< /conf/conf.d/cryptroot
287 fi
288
289 exit 0
This page took 0.050571 seconds and 3 git commands to generate.