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