]> git.pld-linux.org Git - projects/geninitrd.git/blame - mod-luks.sh
Fallback detection if device is crypted.
[projects/geninitrd.git] / mod-luks.sh
CommitLineData
8d07ddab 1#!/bin/sh
c34c6a69 2LUKS_RCSID='$Revision$ $Date:: $'
05c474b5 3
8d07ddab 4# geninitrd mod: cryptsetup luks
6e49b0b1 5USE_LUKS=${USE_LUKS:-yes}
8d07ddab
ER
6
7# true if root device is crypted with cryptsetup luks
8# and we should init cryptsetup luks at boot
9have_luks=no
10
8d07ddab
ER
11# device to use for name for cryptsetup luks
12LUKSDEV=""
13
c124d0cf
ER
14# setup geninitrd module
15# @access public
16setup_mod_luks() {
17 cryptsetup=$(find_tool $initrd_dir/cryptsetup /sbin/cryptsetup-initrd)
6e49b0b1
ER
18
19 if [ ! -x /sbin/cryptsetup ] || [ ! -x "$cryptsetup" ]; then
c124d0cf
ER
20 USE_LUKS=no
21 fi
22}
23
8d07ddab
ER
24# return true if node is cryptsetup luks encrypted
25# @param string $node device node to be examined
26# @access public
27is_luks() {
28 local node="$1"
f7385874
ER
29
30 # luks not wanted
31 if is_no "$USE_LUKS"; then
32 return 1
33 fi
34
8d07ddab
ER
35 if [ ! -e "$node" ]; then
36 warn "is_luks(): node $node doesn't exist!"
37 return 1
38 fi
39
d5848229 40 local dev dm_status dm_name=${node#/dev/mapper/}
8d07ddab
ER
41 if [ "$node" = "$dm_name" ]; then
42 debug "is_luks: $node is not device mapper name"
43 return 1
44 fi
45
378e5f2b 46 dev=$(/sbin/cryptsetup status $dm_name 2>/dev/null | awk '/device:/{print $2}')
1d96f045
ER
47 if [ "$dev" ]; then
48 /sbin/cryptsetup isLuks $dev
49 rc=$?
50 else
d5848229
AM
51 # If luks partition was activated using old cryptsetup (at initrd level)
52 # then "device:" report could be missing from cryptsetup status above.
53 # Fallback to dmsetup report in such case.
54 dm_status=$(/sbin/dmsetup status --target crypt $dm_name 2>/dev/null)
55 if [ -n "$dm_status" ]; then
56 rc=0
57 else
58 rc=1
59 fi
1d96f045 60 fi
8d07ddab
ER
61
62 if [ $rc = 0 ]; then
63 debug "is_luks: $node is cryptsetup luks"
64 else
65 debug "is_luks: $node is not cryptsetup luks"
66 fi
67 return $rc
68}
69
70# find modules for $devpath
71# @param $devpath device to be examined
72# @access public
73find_modules_luks() {
74 local devpath="$1"
75 local dev
76
77 local name=${devpath#/dev/mapper/}
f7385874 78 LUKSDEV=$(/sbin/cryptsetup status $name 2>/dev/null | awk '/device:/{print $2}')
8d07ddab
ER
79 if [ -z "$LUKSDEV" ]; then
80 die "Lost cryptsetup device meanwhile?"
81 fi
82
b02a6b13 83 find_module "dm-crypt"
8d07ddab
ER
84
85 # TODO: autodetect
b02a6b13
ER
86 find_module "aes"
87 find_module "cbc"
8d07ddab
ER
88
89 have_luks=yes
90
91 # recurse
92 find_modules_for_devpath $LUKSDEV
93}
94
95
96# generate initrd fragment for cryptsetup luks init
97# @access public
98initrd_gen_luks() {
1b481849
ER
99 if ! is_yes "$have_luks"; then
100 return
101 fi
102
8d07ddab 103 inst_d /bin
684d5d2a 104 inst_exec $cryptsetup /bin/cryptsetup
8d07ddab
ER
105
106 mount_dev
107 mount_sys
108 initrd_gen_devices
109 # TODO: 'udevadm settle' is called by lukssetup, is udev optional?
110
111 debug "luks: process /etc/crypttab $LUKSDEV"
112 luks_crypttab $LUKSDEV
113}
114
115
116# PRIVATE METHODS
117key_is_random() {
118 [ "$1" = "/dev/urandom" -o "$1" = "/dev/hw_random" -o "$1" = "/dev/random" ]
119}
120
121# produce cryptsetup from $name from /etc/crypttab
122luks_crypttab() {
123 local LUKSDEV="$1"
124
125 # copy from /etc/rc.d/init.d/cryptsetup
126 local dst src key opt mode owner
127
128 while read dst src key opt; do
129 [ -z "$dst" -o "${dst#\#}" != "$dst" ] && continue
cb006694 130 [ "$src" != "$LUKSDEV" ] && [ "$(readlink -f $src)" != "$LUKSDEV" ] && continue
8d07ddab
ER
131
132 if [ -n "$key" -a "x$key" != "xnone" ]; then
133 if test -e "$key" ; then
134 mode=$(LC_ALL=C ls -l "$key" | cut -c 5-10)
135 owner=$(LC_ALL=C ls -l $key | awk '{ print $3 }')
136 if [ "$mode" != "------" ] && ! key_is_random "$key"; then
137 die "INSECURE MODE FOR $key"
138 fi
139 if [ "$owner" != root ]; then
140 die "INSECURE OWNER FOR $key"
141 fi
142 else
143 die "Key file for $dst not found"
144 fi
145 else
146 key=""
147 fi
148
149 if /sbin/cryptsetup isLuks "$src" 2>/dev/null; then
150 if key_is_random "$key"; then
151 die "$dst: LUKS requires non-random key, skipping"
152 fi
153 if [ -n "$opt" ]; then
154 warn "$dst: options are invalid for LUKS partitions, ignoring them"
155 fi
156 if [ "$key" ]; then
157 keyfile=/etc/.$dst.key
158 inst $key $keyfile
159 fi
160
161 debug "+ cryptsetup ${keyfile:+-d $keyfile} luksOpen '$src' '$dst'"
162 add_linuxrc <<-EOF
2fcb6fc5
AM
163 # cryptsetup can be called twice and in case on crypt on lvm only second
164 # will succeed because there will be no src device in first cryptsetup call
165 # this can be called multiple times, before lvm and after lvm.
cb006694
AF
166 luksdev='$src'
167 if [ \${luksdev##/dev/disk/by-uuid/} != \${luksdev} ]; then
168 src_uuid=\${luksdev##/dev/disk/by-uuid/}
169 while read x y z name; do
170 found_uuid=\$(cryptsetup luksUUID /dev/\${name} 2>/dev/null)
171 if [ "\$found_uuid" = "\$src_uuid" ]; then
172 luksdev=/dev/\$name
173 break
174 fi
175 done < /proc/partitions
176 fi
177
178 if [ -e "\$luksdev" ]; then
2fcb6fc5
AM
179 crypt_status=\$(cryptsetup status '$dst')
180 if [ "\${crypt_status%%is inactive.}" != "\$crypt_status" ]; then
181 # is inactive
cb006694 182 cryptsetup ${keyfile:+-d $keyfile} luksOpen "\$luksdev" '$dst' <&1
2fcb6fc5 183 fi
abce1a7f 184 fi
8d07ddab
ER
185
186 debugshell
187 EOF
188 else
189 die "$dst: only LUKS encryption supported"
190 fi
191 done < /etc/crypttab
192}
This page took 0.04763 seconds and 4 git commands to generate.