]>
Commit | Line | Data |
---|---|---|
d740abeb | 1 | diff -Nur util-linux-2.12.orig/mount/cryptsetup.c util-linux-2.12/mount/cryptsetup.c |
2 | --- util-linux-2.12.orig/mount/cryptsetup.c 1970-01-01 01:00:00.000000000 +0100 | |
3 | +++ util-linux-2.12/mount/cryptsetup.c 2004-03-10 00:54:10.977381704 +0100 | |
4 | @@ -0,0 +1,216 @@ | |
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; | |
115 | + if (!options.key_file) | |
116 | + options.flags |= CRYPT_FLAG_PASSPHRASE; | |
117 | + if (*cryptro) | |
118 | + options.flags |= CRYPT_FLAG_READONLY; | |
119 | + options.offset = offset; | |
120 | + | |
121 | + if (options.offset % 512) { | |
122 | + error(_("mount: offset must be a multiple of 512 bytes")); | |
123 | + return 1; | |
124 | + } | |
125 | + options.offset >>= 9; | |
126 | + | |
127 | + if (options.key_size % 8) { | |
128 | + error(_("mount: key size must be a multiple of 8 bits")); | |
129 | + return 1; | |
130 | + } | |
131 | + options.key_size /= 8; | |
132 | + | |
133 | + ret = crypt_create_device(&options); | |
134 | + | |
135 | + free(p); | |
136 | + | |
137 | + if (ret < 0) { | |
138 | + /* use dev as buffer */ | |
139 | + char *errorstr = buffer; | |
140 | + crypt_get_error(errorstr, BUFFER_SIZE); | |
141 | + if (!verbose) | |
142 | + errorstr = strerror(-ret); | |
143 | + | |
144 | + error(_("mount: cryptsetup failed with: %s"), errorstr); | |
145 | + return 1; | |
146 | + } | |
147 | + | |
148 | + *cryptdev = (char *)xmalloc(strlen(dir) + strlen(name) + 2); | |
149 | + sprintf(*cryptdev, "%s/%s", dir, name); | |
150 | + | |
151 | + if (options.flags & CRYPT_FLAG_READONLY) | |
152 | + *cryptro = 1; | |
153 | + | |
154 | + return 0; | |
155 | +} | |
156 | + | |
157 | +int | |
158 | +del_crypt (const char *device) { | |
159 | + struct crypt_options options; | |
160 | + const char *dir = crypt_get_dir(); | |
161 | + int len = strlen(dir); | |
162 | + int ret; | |
163 | + | |
164 | + if (!dir) { | |
165 | + error(_("mount: crypt engine not ready")); | |
166 | + return 1; | |
167 | + } | |
168 | + | |
169 | + if (*device == '@') { | |
170 | + char *p; | |
171 | + device++; | |
172 | + p = strchr(device, ':'); | |
173 | + if (p) | |
174 | + *p = '\0'; | |
175 | + } | |
176 | + | |
177 | + if (strncmp(dir, device, len) == 0 && device[len] == '/') | |
178 | + device += len + 1; | |
179 | + | |
180 | + memset(&options, 0, sizeof options); | |
181 | + options.name = device; | |
182 | + | |
183 | + ret = crypt_remove_device(&options); | |
184 | + if (ret < 0) { | |
185 | + char buffer[BUFFER_SIZE]; | |
186 | + char *errorstr = buffer; | |
187 | + crypt_get_error(errorstr, BUFFER_SIZE); | |
188 | + if (!verbose) | |
189 | + errorstr = strerror(-ret); | |
190 | + | |
191 | + error(_("mount: cryptsetup failed with: %s"), errorstr); | |
192 | + return 1; | |
193 | + } | |
194 | + | |
195 | + return 0; | |
196 | +} | |
197 | + | |
198 | +#else /* without CRYPT_FLAG_READONLY */ | |
199 | + | |
200 | +static void | |
201 | +mutter(void) { | |
202 | + fprintf(stderr, | |
203 | + _("This mount was compiled without cryptsetup support. " | |
204 | + "Please recompile.\n")); | |
205 | +} | |
206 | + | |
207 | +int | |
208 | +set_crypt(char **cryptdev, const char *realdev, int offset, | |
209 | + char **encryption, int pfd, int *cryptro) { | |
210 | + mutter(); | |
211 | + return 1; | |
212 | +} | |
213 | + | |
214 | +int | |
215 | +del_crypt (const char *device) { | |
216 | + mutter(); | |
217 | + return 1; | |
218 | +} | |
219 | + | |
220 | +#endif | |
221 | diff -Nur util-linux-2.12.orig/mount/cryptsetup.h util-linux-2.12/mount/cryptsetup.h | |
222 | --- util-linux-2.12.orig/mount/cryptsetup.h 1970-01-01 01:00:00.000000000 +0100 | |
223 | +++ util-linux-2.12/mount/cryptsetup.h 2004-03-10 00:07:48.000000000 +0100 | |
224 | @@ -0,0 +1,4 @@ | |
225 | +extern int verbose; | |
226 | +extern int set_crypt(char **, const char *, int, char **, | |
227 | + int, int *); | |
228 | +extern int del_crypt(const char *); | |
229 | diff -Nur util-linux-2.12.orig/mount/Makefile util-linux-2.12/mount/Makefile | |
230 | --- util-linux-2.12.orig/mount/Makefile 2003-07-16 22:07:27.000000000 +0200 | |
231 | +++ util-linux-2.12/mount/Makefile 2004-03-10 00:07:48.000000000 +0100 | |
232 | @@ -25,6 +25,7 @@ | |
233 | MAYBE = pivot_root swapoff | |
234 | ||
235 | LO_OBJS = lomount.o $(LIB)/xstrncpy.o | |
236 | +CRYPT_OBJS = cryptsetup.o -lcryptsetup | |
237 | NFS_OBJS = nfsmount.o nfsmount_xdr.o nfsmount_clnt.o | |
238 | GEN_FILES = nfsmount.h nfsmount_xdr.c nfsmount_clnt.c | |
239 | ||
240 | @@ -44,11 +45,11 @@ | |
241 | ||
242 | mount: mount.o fstab.o sundries.o realpath.o mntent.o version.o \ | |
243 | mount_guess_fstype.o get_label_uuid.o mount_by_label.o getusername.o \ | |
244 | - $(LIB)/setproctitle.o $(LIB)/env.o $(NFS_OBJS) $(LO_OBJS) | |
245 | + $(LIB)/setproctitle.o $(LIB)/env.o $(NFS_OBJS) $(LO_OBJS) $(CRYPT_OBJS) | |
246 | $(LINK) $^ -o $@ | |
247 | ||
248 | umount: umount.o fstab.o sundries.o realpath.o mntent.o getusername.o \ | |
249 | - get_label_uuid.o version.o $(LIB)/env.o $(LO_OBJS) | |
250 | + get_label_uuid.o version.o $(LIB)/env.o $(LO_OBJS) $(CRYPT_OBJS) | |
251 | $(LINK) $^ -o $@ | |
252 | ||
253 | swapon: swapon.o version.o | |
254 | diff -Nur util-linux-2.12.orig/mount/mount.c util-linux-2.12/mount/mount.c | |
255 | --- util-linux-2.12.orig/mount/mount.c 2003-07-15 23:38:48.000000000 +0200 | |
256 | +++ util-linux-2.12/mount/mount.c 2004-03-10 00:28:34.619477080 +0100 | |
257 | @@ -62,6 +62,7 @@ | |
258 | #include "mntent.h" | |
259 | #include "fstab.h" | |
260 | #include "lomount.h" | |
261 | +#include "cryptsetup.h" | |
262 | #include "loop.h" | |
263 | #include "linux_fs.h" /* for BLKGETSIZE */ | |
264 | #include "mount_guess_rootdev.h" | |
265 | @@ -130,6 +131,7 @@ | |
266 | #define MS_USERS 0x40000000 | |
267 | #define MS_USER 0x20000000 | |
268 | #define MS_OWNER 0x10000000 | |
269 | +#define MS_CRYPT 0x00040000 | |
270 | #define MS_NETDEV 0x00020000 | |
271 | #define MS_LOOP 0x00010000 | |
272 | ||
273 | @@ -206,7 +208,7 @@ | |
274 | { "vfs=", 1, &opt_vfstype }, | |
275 | { "offset=", 0, &opt_offset }, | |
276 | { "encryption=", 0, &opt_encryption }, | |
277 | - { "speed=", 0, &opt_speed }, | |
278 | + { "speed=", 0, &opt_speed }, | |
279 | { NULL, 0, NULL } | |
280 | }; | |
281 | ||
282 | @@ -586,7 +588,7 @@ | |
283 | *type = opt_vfstype; | |
284 | } | |
285 | ||
286 | - *loop = ((*flags & MS_LOOP) || *loopdev || opt_offset || opt_encryption); | |
287 | + *loop = ((*flags & MS_LOOP) || *loopdev || (opt_offset && !opt_encryption)); | |
288 | *loopfile = *spec; | |
289 | ||
290 | if (*loop) { | |
291 | @@ -605,7 +607,7 @@ | |
292 | printf(_("mount: going to use the loop device %s\n"), *loopdev); | |
293 | offset = opt_offset ? strtoul(opt_offset, NULL, 0) : 0; | |
294 | if (set_loop(*loopdev, *loopfile, offset, | |
295 | - opt_encryption, pfd, &loopro)) { | |
296 | + NULL /* opt_encryption */, pfd, &loopro)) { | |
297 | if (verbose) | |
298 | printf(_("mount: failed setting up loop device\n")); | |
299 | return EX_FAIL; | |
300 | @@ -615,6 +617,42 @@ | |
301 | *spec = *loopdev; | |
302 | if (loopro) | |
303 | *flags |= MS_RDONLY; | |
304 | + /* set offset to 0 so that crypto setup doesn't add an offset too */ | |
305 | + opt_offset = 0; | |
306 | + } | |
307 | + } | |
308 | + | |
309 | + return 0; | |
310 | +} | |
311 | + | |
312 | +static int | |
313 | +crypt_check(char **spec, char **type, int *flags, | |
314 | + int *crypt, char **cryptdev, char **realdev) { | |
315 | + int offset; | |
316 | + | |
317 | + *crypt = ((*flags & MS_CRYPT) || opt_encryption); | |
318 | + *realdev = *spec; | |
319 | + | |
320 | + if (*crypt) { | |
321 | + *flags |= MS_CRYPT; | |
322 | + if (fake) { | |
323 | + if (verbose) | |
324 | + printf(_("mount: skipping the setup of an encrypted device\n")); | |
325 | + } else { | |
326 | + int cryptro = (*flags & MS_RDONLY); | |
327 | + | |
328 | + offset = opt_offset ? strtoul(opt_offset, NULL, 0) : 0; | |
329 | + if (set_crypt(cryptdev, *realdev, offset, | |
330 | + &opt_encryption, pfd, &cryptro)) { | |
331 | + if (verbose) | |
332 | + printf(_("mount: failed setting up encrypted device\n")); | |
333 | + return EX_FAIL; | |
334 | + } | |
335 | + if (verbose > 1) | |
336 | + printf(_("mount: setup crypt device successfully\n")); | |
337 | + *spec = *cryptdev; | |
338 | + if (cryptro) | |
339 | + *flags |= MS_RDONLY; | |
340 | } | |
341 | } | |
342 | ||
343 | @@ -765,7 +803,9 @@ | |
344 | char *spec, *node, *types; | |
345 | char *user = 0; | |
346 | int loop = 0; | |
347 | + int crypt = 0; | |
348 | char *loopdev = 0, *loopfile = 0; | |
349 | + char *cryptdev = 0, *realdev = 0; | |
350 | struct stat statbuf; | |
351 | int nfs_mount_version = 0; /* any version */ | |
352 | ||
353 | @@ -796,6 +836,10 @@ | |
354 | res = loop_check(&spec, &types, &flags, &loop, &loopdev, &loopfile); | |
355 | if (res) | |
356 | return res; | |
357 | + | |
358 | + res = crypt_check(&spec, &types, &flags, &crypt, &cryptdev, &realdev); | |
359 | + if (res) | |
360 | + return res; | |
361 | } | |
362 | ||
363 | /* | |
364 | @@ -832,8 +876,13 @@ | |
365 | /* Mount succeeded, report this (if verbose) and write mtab entry. */ | |
366 | if (loop) | |
367 | opt_loopdev = loopdev; | |
368 | + if (crypt) { | |
369 | + char *tmp = xmalloc(strlen(cryptdev) + strlen(opt_encryption) + 3); | |
370 | + sprintf(tmp, "@%s:%s", cryptdev, opt_encryption); | |
371 | + opt_encryption = tmp; | |
372 | + } | |
373 | ||
374 | - update_mtab_entry(loop ? loopfile : spec, | |
375 | + update_mtab_entry(loop ? loopfile : crypt ? realdev : spec, | |
376 | node, | |
377 | types ? types : "unknown", | |
378 | fix_opts_string (flags & ~MS_NOMTAB, extra_opts, user), | |
379 | @@ -847,6 +896,8 @@ | |
380 | ||
381 | mnt_err = errno; | |
382 | ||
383 | + if (crypt) | |
384 | + del_crypt(spec); | |
385 | if (loop) | |
386 | del_loop(spec); | |
387 | ||
388 | diff -Nur util-linux-2.12.orig/mount/umount.c util-linux-2.12/mount/umount.c | |
389 | --- util-linux-2.12.orig/mount/umount.c 2003-07-15 23:19:22.000000000 +0200 | |
390 | +++ util-linux-2.12/mount/umount.c 2004-03-10 00:07:48.000000000 +0100 | |
391 | @@ -41,6 +41,7 @@ | |
392 | #include "sundries.h" | |
393 | #include "getusername.h" | |
394 | #include "lomount.h" | |
395 | +#include "cryptsetup.h" | |
396 | #include "loop.h" | |
397 | #include "fstab.h" | |
398 | #include "env.h" | |
399 | @@ -249,6 +250,7 @@ | |
400 | int isroot; | |
401 | int res; | |
402 | const char *loopdev; | |
403 | + const char *cryptdev; | |
404 | ||
405 | /* Special case for root. As of 0.99pl10 we can (almost) unmount root; | |
406 | the kernel will remount it readonly so that we can carry on running | |
407 | @@ -331,12 +333,33 @@ | |
408 | } | |
409 | } | |
410 | ||
411 | - loopdev = 0; | |
412 | if (res >= 0) { | |
413 | /* Umount succeeded */ | |
414 | if (verbose) | |
415 | printf (_("%s umounted\n"), spec); | |
416 | + } | |
417 | + | |
418 | + cryptdev = 0; | |
419 | + if (res >= 0) { | |
420 | + /* Free any encrypted devices that we allocated ourselves */ | |
421 | + if (mc) { | |
422 | + char *optl; | |
423 | + | |
424 | + optl = mc->m.mnt_opts ? xstrdup(mc->m.mnt_opts) : ""; | |
425 | + for (optl = strtok (optl, ","); optl; | |
426 | + optl = strtok (NULL, ",")) { | |
427 | + if (!strncmp(optl, "encryption=", 11)) { | |
428 | + cryptdev = optl+11; | |
429 | + break; | |
430 | + } | |
431 | + } | |
432 | + } | |
433 | + } | |
434 | + if (cryptdev) | |
435 | + del_crypt(cryptdev); | |
436 | ||
437 | + loopdev = 0; | |
438 | + if (res >= 0) { | |
439 | /* Free any loop devices that we allocated ourselves */ | |
440 | if (mc) { | |
441 | char *optl; | |
442 |