]>
Commit | Line | Data |
---|---|---|
8d07ddab | 1 | #!/bin/sh |
c34c6a69 | 2 | LUKS_RCSID='$Revision$ $Date:: $' |
05c474b5 | 3 | |
8d07ddab | 4 | # geninitrd mod: cryptsetup luks |
6e49b0b1 | 5 | USE_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 | |
9 | have_luks=no | |
10 | ||
8d07ddab | 11 | # device to use for name for cryptsetup luks |
704c497d | 12 | LUKSNAME="" |
8d07ddab | 13 | |
c124d0cf ER |
14 | # setup geninitrd module |
15 | # @access public | |
16 | setup_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 | |
27 | is_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 | ||
a5b35f50 | 35 | local dev dm_name=${node#/dev/mapper/} |
8d07ddab ER |
36 | if [ "$node" = "$dm_name" ]; then |
37 | debug "is_luks: $node is not device mapper name" | |
38 | return 1 | |
39 | fi | |
b892656c ER |
40 | |
41 | dev=$(awk -vdm_name="$dm_name" '$1 == dm_name { print $2 }' /etc/crypttab) | |
1d96f045 ER |
42 | if [ "$dev" ]; then |
43 | /sbin/cryptsetup isLuks $dev | |
44 | rc=$? | |
45 | else | |
a5b35f50 | 46 | rc=1 |
1d96f045 | 47 | fi |
8d07ddab ER |
48 | |
49 | if [ $rc = 0 ]; then | |
50 | debug "is_luks: $node is cryptsetup luks" | |
51 | else | |
52 | debug "is_luks: $node is not cryptsetup luks" | |
53 | fi | |
54 | return $rc | |
55 | } | |
56 | ||
57 | # find modules for $devpath | |
58 | # @param $devpath device to be examined | |
59 | # @access public | |
60 | find_modules_luks() { | |
61 | local devpath="$1" | |
704c497d | 62 | local dev="" |
f4dd815d | 63 | |
704c497d | 64 | LUKSNAME=${devpath#/dev/mapper/} |
8d07ddab | 65 | |
b02a6b13 | 66 | find_module "dm-crypt" |
8d07ddab ER |
67 | |
68 | # TODO: autodetect | |
b02a6b13 ER |
69 | find_module "aes" |
70 | find_module "cbc" | |
8d07ddab | 71 | |
8d07ddab | 72 | # recurse |
b892656c ER |
73 | dev=$(awk -vLUKSNAME="$LUKSNAME" '$1 == LUKSNAME { print $2 }' /etc/crypttab) |
74 | if [ -n "$dev" ]; then | |
704c497d JK |
75 | find_modules_for_devpath $dev |
76 | have_luks=yes | |
77 | else | |
78 | die "Cannot find '$LUKSNAME' in /etc/crypttab" | |
79 | fi | |
8d07ddab ER |
80 | } |
81 | ||
82 | ||
83 | # generate initrd fragment for cryptsetup luks init | |
84 | # @access public | |
85 | initrd_gen_luks() { | |
1b481849 ER |
86 | if ! is_yes "$have_luks"; then |
87 | return | |
88 | fi | |
89 | ||
8d07ddab | 90 | inst_d /bin |
684d5d2a | 91 | inst_exec $cryptsetup /bin/cryptsetup |
8d07ddab ER |
92 | |
93 | mount_dev | |
94 | mount_sys | |
95 | initrd_gen_devices | |
96 | # TODO: 'udevadm settle' is called by lukssetup, is udev optional? | |
97 | ||
704c497d JK |
98 | debug "luks: process /etc/crypttab $LUKSNAME" |
99 | luks_crypttab $LUKSNAME | |
8d07ddab ER |
100 | } |
101 | ||
102 | ||
103 | # PRIVATE METHODS | |
104 | key_is_random() { | |
105 | [ "$1" = "/dev/urandom" -o "$1" = "/dev/hw_random" -o "$1" = "/dev/random" ] | |
106 | } | |
107 | ||
108 | # produce cryptsetup from $name from /etc/crypttab | |
109 | luks_crypttab() { | |
704c497d | 110 | local LUKSNAME="$1" |
8d07ddab ER |
111 | |
112 | # copy from /etc/rc.d/init.d/cryptsetup | |
113 | local dst src key opt mode owner | |
114 | ||
115 | while read dst src key opt; do | |
704c497d | 116 | [ "$dst" != "$LUKSNAME" ] && continue |
8d07ddab ER |
117 | |
118 | if [ -n "$key" -a "x$key" != "xnone" ]; then | |
119 | if test -e "$key" ; then | |
120 | mode=$(LC_ALL=C ls -l "$key" | cut -c 5-10) | |
121 | owner=$(LC_ALL=C ls -l $key | awk '{ print $3 }') | |
122 | if [ "$mode" != "------" ] && ! key_is_random "$key"; then | |
123 | die "INSECURE MODE FOR $key" | |
124 | fi | |
125 | if [ "$owner" != root ]; then | |
126 | die "INSECURE OWNER FOR $key" | |
127 | fi | |
128 | else | |
129 | die "Key file for $dst not found" | |
130 | fi | |
131 | else | |
132 | key="" | |
133 | fi | |
134 | ||
135 | if /sbin/cryptsetup isLuks "$src" 2>/dev/null; then | |
136 | if key_is_random "$key"; then | |
137 | die "$dst: LUKS requires non-random key, skipping" | |
138 | fi | |
139 | if [ -n "$opt" ]; then | |
140 | warn "$dst: options are invalid for LUKS partitions, ignoring them" | |
141 | fi | |
142 | if [ "$key" ]; then | |
143 | keyfile=/etc/.$dst.key | |
144 | inst $key $keyfile | |
145 | fi | |
146 | ||
147 | debug "+ cryptsetup ${keyfile:+-d $keyfile} luksOpen '$src' '$dst'" | |
148 | add_linuxrc <<-EOF | |
2fcb6fc5 AM |
149 | # cryptsetup can be called twice and in case on crypt on lvm only second |
150 | # will succeed because there will be no src device in first cryptsetup call | |
151 | # this can be called multiple times, before lvm and after lvm. | |
cb006694 AF |
152 | luksdev='$src' |
153 | if [ \${luksdev##/dev/disk/by-uuid/} != \${luksdev} ]; then | |
154 | src_uuid=\${luksdev##/dev/disk/by-uuid/} | |
155 | while read x y z name; do | |
156 | found_uuid=\$(cryptsetup luksUUID /dev/\${name} 2>/dev/null) | |
157 | if [ "\$found_uuid" = "\$src_uuid" ]; then | |
158 | luksdev=/dev/\$name | |
159 | break | |
160 | fi | |
161 | done < /proc/partitions | |
162 | fi | |
163 | ||
164 | if [ -e "\$luksdev" ]; then | |
2fcb6fc5 AM |
165 | crypt_status=\$(cryptsetup status '$dst') |
166 | if [ "\${crypt_status%%is inactive.}" != "\$crypt_status" ]; then | |
167 | # is inactive | |
cb006694 | 168 | cryptsetup ${keyfile:+-d $keyfile} luksOpen "\$luksdev" '$dst' <&1 |
2fcb6fc5 | 169 | fi |
abce1a7f | 170 | fi |
8d07ddab ER |
171 | |
172 | debugshell | |
173 | EOF | |
174 | else | |
175 | die "$dst: only LUKS encryption supported" | |
176 | fi | |
177 | done < /etc/crypttab | |
178 | } |