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