]>
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 | |
d740abeb | 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 | |
d2741bb5 AM |
221 | diff -urN util-linux-2.12q.org/mount/cryptsetup.h util-linux-2.12q/mount/cryptsetup.h |
222 | --- util-linux-2.12q.org/mount/cryptsetup.h 1970-01-01 01:00:00.000000000 +0100 | |
223 | +++ util-linux-2.12q/mount/cryptsetup.h 2005-02-27 19:26:34.000000000 +0100 | |
d740abeb | 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 *); | |
d2741bb5 AM |
229 | diff -urN util-linux-2.12q.org/mount/Makefile util-linux-2.12q/mount/Makefile |
230 | --- util-linux-2.12q.org/mount/Makefile 2005-02-27 19:25:37.000000000 +0100 | |
231 | +++ util-linux-2.12q/mount/Makefile 2005-02-27 19:27:21.000000000 +0100 | |
232 | @@ -30,6 +30,7 @@ | |
d740abeb | 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 | ||
d2741bb5 | 240 | @@ -49,12 +50,12 @@ |
d740abeb | 241 | |
d2741bb5 AM |
242 | mount: mount.o fstab.o sundries.o xmalloc.o realpath.o mntent.o version.o \ |
243 | get_label_uuid.o mount_by_label.o mount_blkid.o mount_guess_fstype.o \ | |
244 | - getusername.o $(LIB)/setproctitle.o $(LIB)/env.o $(NFS_OBJS) $(LO_OBJS) | |
245 | + getusername.o $(LIB)/setproctitle.o $(LIB)/env.o $(NFS_OBJS) $(LO_OBJS) $(CRYPT_OBJS) | |
246 | $(LINK) $^ -o $@ $(BLKID_LIB) | |
d740abeb | 247 | |
d2741bb5 AM |
248 | umount: umount.o fstab.o sundries.o xmalloc.o realpath.o mntent.o \ |
249 | getusername.o get_label_uuid.o mount_by_label.o mount_blkid.o \ | |
250 | - version.o $(LIB)/env.o $(LO_OBJS) | |
251 | + version.o $(LIB)/env.o $(LO_OBJS) $(CRYPT_OBJS) | |
252 | $(LINK) $^ -o $@ $(BLKID_LIB) | |
d740abeb | 253 | |
d2741bb5 AM |
254 | swapon: swapon.o version.o xmalloc.o \ |
255 | diff -urN util-linux-2.12q.org/mount/mount.c util-linux-2.12q/mount/mount.c | |
256 | --- util-linux-2.12q.org/mount/mount.c 2004-12-21 23:00:36.000000000 +0100 | |
257 | +++ util-linux-2.12q/mount/mount.c 2005-02-27 19:29:40.000000000 +0100 | |
258 | @@ -28,6 +28,7 @@ | |
d740abeb | 259 | #include "mntent.h" |
260 | #include "fstab.h" | |
261 | #include "lomount.h" | |
262 | +#include "cryptsetup.h" | |
263 | #include "loop.h" | |
264 | #include "linux_fs.h" /* for BLKGETSIZE */ | |
265 | #include "mount_guess_rootdev.h" | |
d2741bb5 | 266 | @@ -98,6 +99,7 @@ |
d740abeb | 267 | #define MS_USER 0x20000000 |
268 | #define MS_OWNER 0x10000000 | |
d2741bb5 AM |
269 | #define MS_GROUP 0x08000000 |
270 | +#define MS_CRYPT 0x00040000 | |
271 | #define MS_COMMENT 0x00020000 | |
d740abeb | 272 | #define MS_LOOP 0x00010000 |
273 | ||
d2741bb5 | 274 | @@ -607,7 +609,7 @@ |
d740abeb | 275 | *type = opt_vfstype; |
276 | } | |
277 | ||
278 | - *loop = ((*flags & MS_LOOP) || *loopdev || opt_offset || opt_encryption); | |
279 | + *loop = ((*flags & MS_LOOP) || *loopdev || (opt_offset && !opt_encryption)); | |
280 | *loopfile = *spec; | |
281 | ||
282 | if (*loop) { | |
d2741bb5 | 283 | @@ -626,7 +628,7 @@ |
d740abeb | 284 | printf(_("mount: going to use the loop device %s\n"), *loopdev); |
d2741bb5 | 285 | offset = opt_offset ? strtoull(opt_offset, NULL, 0) : 0; |
d740abeb | 286 | if (set_loop(*loopdev, *loopfile, offset, |
287 | - opt_encryption, pfd, &loopro)) { | |
288 | + NULL /* opt_encryption */, pfd, &loopro)) { | |
289 | if (verbose) | |
290 | printf(_("mount: failed setting up loop device\n")); | |
291 | return EX_FAIL; | |
d2741bb5 | 292 | @@ -636,6 +638,42 @@ |
d740abeb | 293 | *spec = *loopdev; |
294 | if (loopro) | |
295 | *flags |= MS_RDONLY; | |
296 | + /* set offset to 0 so that crypto setup doesn't add an offset too */ | |
297 | + opt_offset = 0; | |
298 | + } | |
299 | + } | |
300 | + | |
301 | + return 0; | |
302 | +} | |
303 | + | |
304 | +static int | |
305 | +crypt_check(char **spec, char **type, int *flags, | |
306 | + int *crypt, char **cryptdev, char **realdev) { | |
307 | + int offset; | |
308 | + | |
309 | + *crypt = ((*flags & MS_CRYPT) || opt_encryption); | |
310 | + *realdev = *spec; | |
311 | + | |
312 | + if (*crypt) { | |
313 | + *flags |= MS_CRYPT; | |
314 | + if (fake) { | |
315 | + if (verbose) | |
316 | + printf(_("mount: skipping the setup of an encrypted device\n")); | |
317 | + } else { | |
318 | + int cryptro = (*flags & MS_RDONLY); | |
319 | + | |
320 | + offset = opt_offset ? strtoul(opt_offset, NULL, 0) : 0; | |
321 | + if (set_crypt(cryptdev, *realdev, offset, | |
322 | + &opt_encryption, pfd, &cryptro)) { | |
323 | + if (verbose) | |
324 | + printf(_("mount: failed setting up encrypted device\n")); | |
325 | + return EX_FAIL; | |
326 | + } | |
327 | + if (verbose > 1) | |
328 | + printf(_("mount: setup crypt device successfully\n")); | |
329 | + *spec = *cryptdev; | |
330 | + if (cryptro) | |
331 | + *flags |= MS_RDONLY; | |
332 | } | |
333 | } | |
334 | ||
d2741bb5 AM |
335 | @@ -788,7 +826,9 @@ |
336 | const char *opts, *spec, *node, *types; | |
d740abeb | 337 | char *user = 0; |
338 | int loop = 0; | |
339 | + int crypt = 0; | |
d2741bb5 | 340 | const char *loopdev = 0, *loopfile = 0; |
d740abeb | 341 | + char *cryptdev = 0, *realdev = 0; |
342 | struct stat statbuf; | |
343 | int nfs_mount_version = 0; /* any version */ | |
344 | ||
d2741bb5 | 345 | @@ -823,6 +863,10 @@ |
d740abeb | 346 | res = loop_check(&spec, &types, &flags, &loop, &loopdev, &loopfile); |
347 | if (res) | |
d2741bb5 | 348 | goto out; |
d740abeb | 349 | + |
350 | + res = crypt_check(&spec, &types, &flags, &crypt, &cryptdev, &realdev); | |
351 | + if (res) | |
d2741bb5 | 352 | + goto out; |
d740abeb | 353 | } |
354 | ||
355 | /* | |
d2741bb5 | 356 | @@ -863,8 +907,13 @@ |
d740abeb | 357 | /* Mount succeeded, report this (if verbose) and write mtab entry. */ |
358 | if (loop) | |
359 | opt_loopdev = loopdev; | |
360 | + if (crypt) { | |
361 | + char *tmp = xmalloc(strlen(cryptdev) + strlen(opt_encryption) + 3); | |
362 | + sprintf(tmp, "@%s:%s", cryptdev, opt_encryption); | |
363 | + opt_encryption = tmp; | |
364 | + } | |
365 | ||
366 | - update_mtab_entry(loop ? loopfile : spec, | |
367 | + update_mtab_entry(loop ? loopfile : crypt ? realdev : spec, | |
368 | node, | |
369 | types ? types : "unknown", | |
370 | fix_opts_string (flags & ~MS_NOMTAB, extra_opts, user), | |
d2741bb5 | 371 | @@ -879,6 +928,8 @@ |
d740abeb | 372 | |
373 | mnt_err = errno; | |
374 | ||
375 | + if (crypt) | |
376 | + del_crypt(spec); | |
377 | if (loop) | |
378 | del_loop(spec); | |
379 | ||
d2741bb5 AM |
380 | diff -urN util-linux-2.12q.org/mount/umount.c util-linux-2.12q/mount/umount.c |
381 | --- util-linux-2.12q.org/mount/umount.c 2004-12-20 23:03:45.000000000 +0100 | |
382 | +++ util-linux-2.12q/mount/umount.c 2005-02-27 19:26:34.000000000 +0100 | |
383 | @@ -15,6 +15,7 @@ | |
d740abeb | 384 | #include "sundries.h" |
385 | #include "getusername.h" | |
386 | #include "lomount.h" | |
387 | +#include "cryptsetup.h" | |
388 | #include "loop.h" | |
389 | #include "fstab.h" | |
390 | #include "env.h" | |
d2741bb5 | 391 | @@ -274,6 +275,7 @@ |
d740abeb | 392 | int res; |
d2741bb5 | 393 | int status; |
d740abeb | 394 | const char *loopdev; |
395 | + const char *cryptdev; | |
396 | ||
397 | /* Special case for root. As of 0.99pl10 we can (almost) unmount root; | |
398 | the kernel will remount it readonly so that we can carry on running | |
d2741bb5 | 399 | @@ -365,12 +367,33 @@ |
d740abeb | 400 | } |
401 | } | |
402 | ||
403 | - loopdev = 0; | |
404 | if (res >= 0) { | |
405 | /* Umount succeeded */ | |
406 | if (verbose) | |
407 | printf (_("%s umounted\n"), spec); | |
408 | + } | |
409 | + | |
410 | + cryptdev = 0; | |
411 | + if (res >= 0) { | |
412 | + /* Free any encrypted devices that we allocated ourselves */ | |
413 | + if (mc) { | |
414 | + char *optl; | |
415 | + | |
416 | + optl = mc->m.mnt_opts ? xstrdup(mc->m.mnt_opts) : ""; | |
417 | + for (optl = strtok (optl, ","); optl; | |
418 | + optl = strtok (NULL, ",")) { | |
419 | + if (!strncmp(optl, "encryption=", 11)) { | |
420 | + cryptdev = optl+11; | |
421 | + break; | |
422 | + } | |
423 | + } | |
424 | + } | |
425 | + } | |
426 | + if (cryptdev) | |
427 | + del_crypt(cryptdev); | |
428 | ||
429 | + loopdev = 0; | |
430 | + if (res >= 0) { | |
431 | /* Free any loop devices that we allocated ourselves */ | |
432 | if (mc) { | |
433 | char *optl; |