]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - libexec/rc/rc.d/geli
cdn-patch: offer option to mount /etc/keys before attaching geli devices
[FreeBSD/FreeBSD.git] / libexec / rc / rc.d / geli
1 #!/bin/sh
2 #
3 # Copyright (c) 2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
4 # All rights reserved.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 # 1. Redistributions of source code must retain the above copyright
10 #    notice, this list of conditions and the following disclaimer.
11 # 2. Redistributions in binary form must reproduce the above copyright
12 #    notice, this list of conditions and the following disclaimer in the
13 #    documentation and/or other materials provided with the distribution.
14 #
15 # THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
16 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 # ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
19 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 # SUCH DAMAGE.
26 #
27 # $FreeBSD$
28 #
29
30 # PROVIDE: disks
31 # KEYWORD: nojail
32
33 . /etc/rc.subr
34
35 name="geli"
36 desc="GELI disk encryption"
37 start_precmd="geli_prestart"
38 start_cmd="geli_start"
39 stop_cmd="geli_stop"
40 required_modules="geom_eli:g_eli"
41
42 : ${geli_mount_keys_first:=NO}
43
44 geli_prestart()
45 {
46         if checkyesno geli_mount_keys_first
47         then
48                 if ! mount | grep -q "on /etc/keys ("
49                 then
50                         mount -r /etc/keys
51                 fi
52         fi
53
54         [ -n "$(geli_make_list)" -o -n "${geli_groups}" ]
55         return $?
56 }
57
58
59 # Takes provider
60 # Reads key from EFIvar
61 # Returns tempfile pathname containing key
62 geli_efi()
63 {
64         local provider="${1}"
65         local provider_=`ltr ${provider} '/-' '_'`
66         local guid="65537263-7465-654b-4f79-44666f6f216d"
67
68         eval "efi=\${geli_${provider_}_efi:-NO}"
69
70         if checkyesno efi
71         then
72                 efivar="$(printf "%s-%s" "${guid}" "$(echo -n "${provider}" | sha256)")"
73                 tmpkey="$(mktemp "/tmp/efikey_${provider_}")"
74                 efivar --binary --no-name "${efivar}" > "${tmpkey}"
75                 if [ -s "${tmpkey}" ]
76                 then
77                         echo "${tmpkey}"
78                 fi
79         fi
80 }
81
82 geli_efi_init()
83 {
84         mount -t tmpfs tmpfs /tmp
85 }
86
87 geli_efi_fini()
88 {
89         umount -t tmpfs /tmp
90 }
91
92 geli_start()
93 {
94         devices=`geli_make_list`
95
96         if [ -z "${geli_tries}" ]; then
97                 if [ -n "${geli_attach_attempts}" ]; then
98                         # Compatibility with rc.d/gbde.
99                         geli_tries=${geli_attach_attempts}
100                 else
101                         geli_tries=`${SYSCTL_N} kern.geom.eli.tries`
102                 fi
103         fi
104
105         geli_efi_init
106
107         for provider in ${devices}; do
108                 provider_=`ltr ${provider} '/-' '_'`
109
110                 eval "flags=\${geli_${provider_}_flags}"
111                 if [ -z "${flags}" ]; then
112                         flags=${geli_default_flags}
113                 fi
114
115                 efikey="$(geli_efi "${provider}")"
116                 if [ -s "${efikey}" ]
117                 then
118                         echo "Acquired key for ${provider} from EFI."
119                         flags="${flags} -p -k ${efikey}"
120                 fi
121
122                 if [ -e "/dev/${provider}" -a ! -e "/dev/${provider}.eli" ]; then
123                         echo "Configuring Disk Encryption for ${provider}."
124                         count=1
125                         while [ ${count} -le ${geli_tries} ]; do
126                                 geli attach ${flags} ${provider}
127                                 if [ -e "/dev/${provider}.eli" ]; then
128                                         break
129                                 fi
130                                 echo "Attach failed; attempt ${count} of ${geli_tries}."
131                                 count=$((count+1))
132                         done
133                 fi
134         done
135
136         for group in ${geli_groups}; do
137                 group_=`ltr ${group} '/-' '_'`
138
139                 eval "flags=\${geli_${group_}_flags}"
140                 if [ -z "${flags}" ]; then
141                         flags=${geli_default_flags}
142                 fi
143
144                 eval "providers=\${geli_${group_}_devices}"
145                 if [ -z "${providers}" ]; then
146                         echo "No devices listed in geli group ${group}."
147                         continue
148                 fi
149
150                 efikey="$(geli_efi "${group}")"
151                 if [ -s "${efikey}" ]
152                 then
153                         echo "Acquired key for ${group} from EFI."
154                         flags="${flags} -p -k ${efikey}"
155                 fi
156
157                 if [ -e "/dev/${providers%% *}" -a ! -e "/dev/${providers%% *}.eli" ]; then
158                         echo "Configuring Disk Encryption for geli group ${group}, containing ${providers}."
159                         count=1
160                         while [ ${count} -le ${geli_tries} ]; do
161                                 geli attach ${flags} ${providers}
162                                 if [ -e "/dev/${providers%% *}.eli" ]; then
163                                         break
164                                 fi
165                                 echo "Attach failed; attempt ${count} of ${geli_tries}."
166                                 count=$((count+1))
167                         done
168                 fi
169         done
170
171         geli_efi_fini
172 }
173
174 geli_stop()
175 {
176         devices=`geli_make_list`
177
178         for group in ${geli_groups}; do
179                 group_=`ltr ${group} '/-' '_'`
180
181                 eval "providers=\${geli_${group_}_devices}"
182
183                 devices="${devices} ${providers}"
184         done
185
186         for provider in ${devices}; do
187                 if [ -e "/dev/${provider}.eli" ]; then
188                         umount "/dev/${provider}.eli" 2>/dev/null
189                         geli detach "${provider}"
190                 fi
191         done
192 }
193
194 load_rc_config $name
195 run_rc_command "$1"