]>
Commit | Line | Data |
---|---|---|
d2741bb5 AM |
1 | diff -urN util-linux-2.12q.org/mount/cryptsetup.c util-linux-2.12q/mount/cryptsetup.c |
2 | --- util-linux-2.12q.org/mount/cryptsetup.c 1970-01-01 01:00:00.000000000 +0100 | |
3 | +++ util-linux-2.12q/mount/cryptsetup.c 2005-02-27 19:26:34.000000000 +0100 | |
72cdbcb5 | 4 | @@ -0,0 +1,214 @@ |
d740abeb | 5 | +/* |
6 | + * cryptsetup.c - setup and control encrypted devices | |
7 | + */ | |
8 | + | |
9 | +#include <stdio.h> | |
10 | +#include <string.h> | |
11 | +#include <stdlib.h> | |
12 | + | |
13 | +#include <libcryptsetup.h> | |
14 | + | |
15 | +#include "cryptsetup.h" | |
16 | +#include "nls.h" | |
17 | + | |
18 | +extern int verbose; | |
19 | +extern char *xstrdup (const char *s); /* not: #include "sundries.h" */ | |
20 | +extern void *xmalloc (size_t size); /* idem */ | |
21 | +extern void error (const char *fmt, ...); /* idem */ | |
22 | + | |
23 | +#ifdef CRYPT_FLAG_READONLY | |
24 | + | |
25 | +#define BUFFER_SIZE 128 | |
26 | +#define DEFAULT_HASH "ripemd160" | |
27 | +#define DEFAULT_KEYSIZE 256 | |
28 | + | |
29 | +static char * | |
30 | +xstrtok(char *s, char delim) { | |
31 | + static char *p; | |
32 | + | |
33 | + if (!s) | |
34 | + s = p; | |
35 | + if (s) { | |
36 | + p = strchr(s, delim); | |
37 | + if (p) | |
38 | + *p++ = '\0'; | |
39 | + } | |
40 | + return s; | |
41 | +} | |
42 | + | |
43 | +int | |
44 | +set_crypt(char **cryptdev, const char *realdev, int offset, | |
45 | + char **encryption, int pfd, int *cryptro) { | |
46 | + struct crypt_options options; | |
47 | + char buffer[BUFFER_SIZE]; | |
48 | + const char *dir = crypt_get_dir(); | |
49 | + const char *name = NULL; | |
50 | + char *p, *q; | |
51 | + int ret; | |
52 | + | |
53 | + if (!dir) { | |
54 | + error(_("mount: crypt engine not ready")); | |
55 | + return 1; | |
56 | + } | |
57 | + | |
58 | + if (**encryption == '@') { | |
59 | + int len = strlen(dir); | |
60 | + p = *encryption + 1; | |
61 | + if (strncmp(dir, p, len) == 0 && p[len] == '/') | |
62 | + p += len + 1; | |
63 | + q = strchr(p, ':'); | |
64 | + if (q) | |
65 | + *q++ = '\0'; | |
66 | + else | |
67 | + q = p + strlen(p); | |
68 | + | |
69 | + name = p; | |
70 | + *encryption = q; | |
71 | + } | |
72 | + | |
73 | + if (!name) { | |
74 | + p = (char *)realdev; | |
75 | + if (*p == '/') | |
76 | + p++; | |
77 | + if (strncmp(p, "dev/", 4) == 0) | |
78 | + p += 4; | |
79 | + for(q = buffer; *p && q < &buffer[BUFFER_SIZE - 2]; p++) | |
80 | + switch(*p) { | |
81 | + case ':': | |
82 | + case '/': | |
83 | + *q++ = '-'; | |
84 | + break; | |
85 | + case '-': | |
86 | + *q++ = '-'; | |
87 | + *q++ = '-'; | |
88 | + break; | |
89 | + default: | |
90 | + *q++ = *p; | |
91 | + } | |
92 | + strncpy(q, "-crypt", BUFFER_SIZE - (q - buffer)); | |
93 | + buffer[BUFFER_SIZE - 1] = '\0'; | |
94 | + name = buffer; | |
95 | + } | |
96 | + | |
97 | + p = xstrdup(*encryption); | |
98 | + | |
99 | + memset(&options, 0, sizeof options); | |
100 | + options.name = name; | |
101 | + options.device = realdev; | |
102 | + options.cipher = xstrtok(p, ':'); | |
103 | + q = xstrtok(NULL, ':'); | |
104 | + options.key_size = q ? strtoul(q, NULL, 0) : 0; | |
105 | + if (!options.key_size) | |
106 | + options.key_size = DEFAULT_KEYSIZE; | |
107 | + options.hash = xstrtok(NULL, ':'); | |
108 | + if (!(options.hash && *options.hash)) | |
109 | + options.hash = DEFAULT_HASH; | |
110 | + options.key_file = xstrtok(NULL, ':'); | |
111 | + if (!(options.key_file && *options.key_file)) | |
112 | + options.key_file = NULL; | |
113 | + options.passphrase_fd = (pfd >= 0) ? pfd : 0; | |
114 | + options.flags = 0; | |
d740abeb | 115 | + if (*cryptro) |
116 | + options.flags |= CRYPT_FLAG_READONLY; | |
117 | + options.offset = offset; | |
118 | + | |
119 | + if (options.offset % 512) { | |
120 | + error(_("mount: offset must be a multiple of 512 bytes")); | |
121 | + return 1; | |
122 | + } | |
123 | + options.offset >>= 9; | |
124 | + | |
125 | + if (options.key_size % 8) { | |
126 | + error(_("mount: key size must be a multiple of 8 bits")); | |
127 | + return 1; | |
128 | + } | |
129 | + options.key_size /= 8; | |
130 | + | |
131 | + ret = crypt_create_device(&options); | |
132 | + | |
133 | + free(p); | |
134 | + | |
135 | + if (ret < 0) { | |
136 | + /* use dev as buffer */ | |
137 | + char *errorstr = buffer; | |
138 | + crypt_get_error(errorstr, BUFFER_SIZE); | |
139 | + if (!verbose) | |
140 | + errorstr = strerror(-ret); | |
141 | + | |
142 | + error(_("mount: cryptsetup failed with: %s"), errorstr); | |
143 | + return 1; | |
144 | + } | |
145 | + | |
146 | + *cryptdev = (char *)xmalloc(strlen(dir) + strlen(name) + 2); | |
147 | + sprintf(*cryptdev, "%s/%s", dir, name); | |
148 | + | |
149 | + if (options.flags & CRYPT_FLAG_READONLY) | |
150 | + *cryptro = 1; | |
151 | + | |
152 | + return 0; | |
153 | +} | |
154 | + | |
155 | +int | |
156 | +del_crypt (const char *device) { | |
157 | + struct crypt_options options; | |
158 | + const char *dir = crypt_get_dir(); | |
159 | + int len = strlen(dir); | |
160 | + int ret; | |
161 | + | |
162 | + if (!dir) { | |
163 | + error(_("mount: crypt engine not ready")); | |
164 | + return 1; | |
165 | + } | |
166 | + | |
167 | + if (*device == '@') { | |
168 | + char *p; | |
169 | + device++; | |
170 | + p = strchr(device, ':'); | |
171 | + if (p) | |
172 | + *p = '\0'; | |
173 | + } | |
174 | + | |
175 | + if (strncmp(dir, device, len) == 0 && device[len] == '/') | |
176 | + device += len + 1; | |
177 | + | |
178 | + memset(&options, 0, sizeof options); | |
179 | + options.name = device; | |
180 | + | |
181 | + ret = crypt_remove_device(&options); | |
182 | + if (ret < 0) { | |
183 | + char buffer[BUFFER_SIZE]; | |
184 | + char *errorstr = buffer; | |
185 | + crypt_get_error(errorstr, BUFFER_SIZE); | |
186 | + if (!verbose) | |
187 | + errorstr = strerror(-ret); | |
188 | + | |
189 | + error(_("mount: cryptsetup failed with: %s"), errorstr); | |
190 | + return 1; | |
191 | + } | |
192 | + | |
193 | + return 0; | |
194 | +} | |
195 | + | |
196 | +#else /* without CRYPT_FLAG_READONLY */ | |
197 | + | |
198 | +static void | |
199 | +mutter(void) { | |
200 | + fprintf(stderr, | |
201 | + _("This mount was compiled without cryptsetup support. " | |
202 | + "Please recompile.\n")); | |
203 | +} | |
204 | + | |
205 | +int | |
206 | +set_crypt(char **cryptdev, const char *realdev, int offset, | |
207 | + char **encryption, int pfd, int *cryptro) { | |
208 | + mutter(); | |
209 | + return 1; | |
210 | +} | |
211 | + | |
212 | +int | |
213 | +del_crypt (const char *device) { | |
214 | + mutter(); | |
215 | + return 1; | |
216 | +} | |
217 | + | |
218 | +#endif | |
d2741bb5 AM |
219 | diff -urN util-linux-2.12q.org/mount/cryptsetup.h util-linux-2.12q/mount/cryptsetup.h |
220 | --- util-linux-2.12q.org/mount/cryptsetup.h 1970-01-01 01:00:00.000000000 +0100 | |
221 | +++ util-linux-2.12q/mount/cryptsetup.h 2005-02-27 19:26:34.000000000 +0100 | |
d740abeb | 222 | @@ -0,0 +1,4 @@ |
223 | +extern int verbose; | |
224 | +extern int set_crypt(char **, const char *, int, char **, | |
225 | + int, int *); | |
226 | +extern int del_crypt(const char *); | |
bbf03782 JR |
227 | diff -urN util-linux-2.12q.org/mount/Makefile.am util-linux-2.12q/mount/Makefile.am |
228 | --- util-linux-2.12q.org/mount/Makefile.am 2005-02-27 19:25:37.000000000 +0100 | |
229 | +++ util-linux-2.12q/mount/Makefile.am 2005-02-27 19:27:21.000000000 +0100 | |
230 | @@ -9,17 +9,17 @@ | |
d740abeb | 231 | |
bbf03782 JR |
232 | mount_SOURCES = mount.c fstab.c sundries.c xmalloc.c realpath.c mntent.c \ |
233 | get_label_uuid.c mount_by_label.c mount_blkid.c mount_guess_fstype.c \ | |
234 | - getusername.c \ | |
235 | + getusername.c cryptsetup.c \ | |
236 | nfsmount.c nfsmount_xdr.c nfsmount_clnt.c \ | |
237 | lomount.c | |
d740abeb | 238 | |
bbf03782 JR |
239 | -mount_LDADD = $(top_srcdir)/lib/libenv.a $(top_srcdir)/lib/libsetproctitle.a |
240 | +mount_LDADD = $(top_srcdir)/lib/libenv.a $(top_srcdir)/lib/libsetproctitle.a -lcryptsetup | |
d740abeb | 241 | |
bbf03782 JR |
242 | umount_SOURCES = umount.c fstab.c sundries.c xmalloc.c realpath.c mntent.c \ |
243 | getusername.c get_label_uuid.c mount_by_label.c mount_blkid.c \ | |
244 | - lomount.c | |
245 | + lomount.c cryptsetup.c | |
d740abeb | 246 | |
bbf03782 JR |
247 | -umount_LDADD = $(top_srcdir)/lib/libenv.a |
248 | +umount_LDADD = $(top_srcdir)/lib/libenv.a -lcryptsetup | |
d740abeb | 249 | |
bbf03782 JR |
250 | swapon_SOURCES = swapon.c xmalloc.c \ |
251 | get_label_uuid.c mount_by_label.c mount_blkid.c | |
d2741bb5 AM |
252 | diff -urN util-linux-2.12q.org/mount/mount.c util-linux-2.12q/mount/mount.c |
253 | --- util-linux-2.12q.org/mount/mount.c 2004-12-21 23:00:36.000000000 +0100 | |
254 | +++ util-linux-2.12q/mount/mount.c 2005-02-27 19:29:40.000000000 +0100 | |
255 | @@ -28,6 +28,7 @@ | |
d740abeb | 256 | #include "mntent.h" |
257 | #include "fstab.h" | |
258 | #include "lomount.h" | |
259 | +#include "cryptsetup.h" | |
260 | #include "loop.h" | |
261 | #include "linux_fs.h" /* for BLKGETSIZE */ | |
262 | #include "mount_guess_rootdev.h" | |
d2741bb5 | 263 | @@ -98,6 +99,7 @@ |
d740abeb | 264 | #define MS_USER 0x20000000 |
265 | #define MS_OWNER 0x10000000 | |
d2741bb5 AM |
266 | #define MS_GROUP 0x08000000 |
267 | +#define MS_CRYPT 0x00040000 | |
268 | #define MS_COMMENT 0x00020000 | |
d740abeb | 269 | #define MS_LOOP 0x00010000 |
270 | ||
d2741bb5 | 271 | @@ -607,7 +609,7 @@ |
d740abeb | 272 | *type = opt_vfstype; |
273 | } | |
274 | ||
275 | - *loop = ((*flags & MS_LOOP) || *loopdev || opt_offset || opt_encryption); | |
276 | + *loop = ((*flags & MS_LOOP) || *loopdev || (opt_offset && !opt_encryption)); | |
277 | *loopfile = *spec; | |
278 | ||
279 | if (*loop) { | |
d2741bb5 | 280 | @@ -626,7 +628,7 @@ |
d740abeb | 281 | printf(_("mount: going to use the loop device %s\n"), *loopdev); |
d2741bb5 | 282 | offset = opt_offset ? strtoull(opt_offset, NULL, 0) : 0; |
d740abeb | 283 | if (set_loop(*loopdev, *loopfile, offset, |
284 | - opt_encryption, pfd, &loopro)) { | |
285 | + NULL /* opt_encryption */, pfd, &loopro)) { | |
286 | if (verbose) | |
287 | printf(_("mount: failed setting up loop device\n")); | |
288 | return EX_FAIL; | |
d2741bb5 | 289 | @@ -636,6 +638,42 @@ |
d740abeb | 290 | *spec = *loopdev; |
291 | if (loopro) | |
292 | *flags |= MS_RDONLY; | |
293 | + /* set offset to 0 so that crypto setup doesn't add an offset too */ | |
294 | + opt_offset = 0; | |
295 | + } | |
296 | + } | |
297 | + | |
298 | + return 0; | |
299 | +} | |
300 | + | |
301 | +static int | |
302 | +crypt_check(char **spec, char **type, int *flags, | |
303 | + int *crypt, char **cryptdev, char **realdev) { | |
304 | + int offset; | |
305 | + | |
306 | + *crypt = ((*flags & MS_CRYPT) || opt_encryption); | |
307 | + *realdev = *spec; | |
308 | + | |
309 | + if (*crypt) { | |
310 | + *flags |= MS_CRYPT; | |
311 | + if (fake) { | |
312 | + if (verbose) | |
313 | + printf(_("mount: skipping the setup of an encrypted device\n")); | |
314 | + } else { | |
315 | + int cryptro = (*flags & MS_RDONLY); | |
316 | + | |
317 | + offset = opt_offset ? strtoul(opt_offset, NULL, 0) : 0; | |
318 | + if (set_crypt(cryptdev, *realdev, offset, | |
319 | + &opt_encryption, pfd, &cryptro)) { | |
320 | + if (verbose) | |
321 | + printf(_("mount: failed setting up encrypted device\n")); | |
322 | + return EX_FAIL; | |
323 | + } | |
324 | + if (verbose > 1) | |
325 | + printf(_("mount: setup crypt device successfully\n")); | |
326 | + *spec = *cryptdev; | |
327 | + if (cryptro) | |
328 | + *flags |= MS_RDONLY; | |
329 | } | |
330 | } | |
331 | ||
d2741bb5 AM |
332 | @@ -788,7 +826,9 @@ |
333 | const char *opts, *spec, *node, *types; | |
d740abeb | 334 | char *user = 0; |
335 | int loop = 0; | |
336 | + int crypt = 0; | |
d2741bb5 | 337 | const char *loopdev = 0, *loopfile = 0; |
d740abeb | 338 | + char *cryptdev = 0, *realdev = 0; |
339 | struct stat statbuf; | |
340 | int nfs_mount_version = 0; /* any version */ | |
341 | ||
d2741bb5 | 342 | @@ -823,6 +863,10 @@ |
d740abeb | 343 | res = loop_check(&spec, &types, &flags, &loop, &loopdev, &loopfile); |
344 | if (res) | |
d2741bb5 | 345 | goto out; |
d740abeb | 346 | + |
347 | + res = crypt_check(&spec, &types, &flags, &crypt, &cryptdev, &realdev); | |
348 | + if (res) | |
d2741bb5 | 349 | + goto out; |
d740abeb | 350 | } |
351 | ||
352 | /* | |
d2741bb5 | 353 | @@ -863,8 +907,13 @@ |
d740abeb | 354 | /* Mount succeeded, report this (if verbose) and write mtab entry. */ |
355 | if (loop) | |
356 | opt_loopdev = loopdev; | |
357 | + if (crypt) { | |
358 | + char *tmp = xmalloc(strlen(cryptdev) + strlen(opt_encryption) + 3); | |
359 | + sprintf(tmp, "@%s:%s", cryptdev, opt_encryption); | |
360 | + opt_encryption = tmp; | |
361 | + } | |
362 | ||
363 | - update_mtab_entry(loop ? loopfile : spec, | |
364 | + update_mtab_entry(loop ? loopfile : crypt ? realdev : spec, | |
365 | node, | |
366 | types ? types : "unknown", | |
367 | fix_opts_string (flags & ~MS_NOMTAB, extra_opts, user), | |
d2741bb5 | 368 | @@ -879,6 +928,8 @@ |
d740abeb | 369 | |
370 | mnt_err = errno; | |
371 | ||
372 | + if (crypt) | |
373 | + del_crypt(spec); | |
374 | if (loop) | |
375 | del_loop(spec); | |
376 | ||
d2741bb5 AM |
377 | diff -urN util-linux-2.12q.org/mount/umount.c util-linux-2.12q/mount/umount.c |
378 | --- util-linux-2.12q.org/mount/umount.c 2004-12-20 23:03:45.000000000 +0100 | |
379 | +++ util-linux-2.12q/mount/umount.c 2005-02-27 19:26:34.000000000 +0100 | |
380 | @@ -15,6 +15,7 @@ | |
d740abeb | 381 | #include "sundries.h" |
382 | #include "getusername.h" | |
383 | #include "lomount.h" | |
384 | +#include "cryptsetup.h" | |
385 | #include "loop.h" | |
386 | #include "fstab.h" | |
387 | #include "env.h" | |
d2741bb5 | 388 | @@ -274,6 +275,7 @@ |
d740abeb | 389 | int res; |
d2741bb5 | 390 | int status; |
d740abeb | 391 | const char *loopdev; |
392 | + const char *cryptdev; | |
393 | ||
394 | /* Special case for root. As of 0.99pl10 we can (almost) unmount root; | |
395 | the kernel will remount it readonly so that we can carry on running | |
d2741bb5 | 396 | @@ -365,12 +367,33 @@ |
d740abeb | 397 | } |
398 | } | |
399 | ||
400 | - loopdev = 0; | |
401 | if (res >= 0) { | |
402 | /* Umount succeeded */ | |
403 | if (verbose) | |
404 | printf (_("%s umounted\n"), spec); | |
405 | + } | |
406 | + | |
407 | + cryptdev = 0; | |
408 | + if (res >= 0) { | |
409 | + /* Free any encrypted devices that we allocated ourselves */ | |
410 | + if (mc) { | |
411 | + char *optl; | |
412 | + | |
413 | + optl = mc->m.mnt_opts ? xstrdup(mc->m.mnt_opts) : ""; | |
414 | + for (optl = strtok (optl, ","); optl; | |
415 | + optl = strtok (NULL, ",")) { | |
416 | + if (!strncmp(optl, "encryption=", 11)) { | |
417 | + cryptdev = optl+11; | |
418 | + break; | |
419 | + } | |
420 | + } | |
421 | + } | |
422 | + } | |
423 | + if (cryptdev) | |
424 | + del_crypt(cryptdev); | |
425 | ||
426 | + loopdev = 0; | |
427 | + if (res >= 0) { | |
428 | /* Free any loop devices that we allocated ourselves */ | |
429 | if (mc) { | |
430 | char *optl; |