--- Begin Message ---
Package: mount
Version: 2.12p-2
Severity: wishlist
Tags: patch
I have added support for using cryptsetup to mount devices over the dmcrypt
API present in kernels >= 2.6.4. It works like loopback encryption, but
whenever the user passes the option 'dmname=xxx' this switches to dmcrypt.
I choose to invoke /sbin/cryptsetup rather than link it in like losetup
because I don't think mount should depend on cryptographic libraries. This
way, if the user needs it, he is told to install it.
I've tested in in conjunction with loopback (ie: fs over dmcrypt over loop)
and by itself on block devices and it seems to work. It also works well with
automounting encrypted DVD/CDs. ;-)
Let me know what you think!
PS. There is one more thing I would like to change, but in a later patch to
keep things small and separate: when mount fails, it doesn't release
loopback devices (and now also device mapper devices). Since the user can
typo a passphrase, this should be handled more gracefully than it is now.
-- System Information:
Debian Release: 3.1
APT prefers testing
APT policy: (500, 'testing')
Architecture: i386 (i686)
Kernel: Linux 2.6.8-1-686
Locale: LANG=en_CA.UTF-8, LC_CTYPE=en_CA.UTF-8 (charmap=UTF-8)
Versions of packages mount depends on:
ii libblkid1 1.35-6 Block device id library
ii libc6 2.3.2.ds1-20 GNU C Library: Shared libraries
an
ii libuuid1 1.35-6 Universally unique id library
-- no debconf information
#! /bin/sh /usr/share/dpatch/dpatch-run
## 20cryptsetup.dpatch by Wesley W. Terpstra <[email protected]>
##
## All lines beginning with ## DP:' are a description of the patch.
## DP: Add cryptsetup support for mounting dmcrypt'd block devices
@DPATCH@
diff -ru util-linux-2.12p.orig/mount/lomount.c util-linux-2.12p/mount/lomount.c
--- util-linux-2.12p.orig/mount/lomount.c 2005-01-13 16:01:04.000000000
+0100
+++ util-linux-2.12p/mount/lomount.c 2005-01-13 16:02:18.000000000 +0100
@@ -17,6 +17,7 @@
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/sysmacros.h>
+#include <sys/wait.h>
#include "loop.h"
#include "lomount.h"
@@ -29,6 +30,8 @@
extern char *xstrdup (const char *s); /* not: #include "sundries.h" */
extern void error (const char *fmt, ...); /* idem */
+static const char cryptsetup[] = "/sbin/cryptsetup";
+
#ifdef LOOP_SET_FD
#include <getopt.h>
@@ -506,6 +509,65 @@
return 1;
}
+static int
+reap_dmcrypt (pid_t p) {
+ int st;
+
+ if (waitpid(p, &st, 0) != p) {
+ fprintf(stderr, _("mount: could not reap cryptsetup\n"));
+ return 1;
+ }
+
+ if (WIFEXITED(st) && WEXITSTATUS(st) == 0)
+ return 0;
+
+ fprintf(stderr, _("mount: cryptsetup did not succeed\n"));
+ return 1;
+}
+
+static int
+check_cryptsetup(void) {
+ if (access(cryptsetup, X_OK) != 0) {
+ fprintf(stderr, _("mount: cryptsetup not installed?\n"));
+ fprintf(stderr, _("failed to (de)configure dmcrypt\n"));
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+set_dmcrypt(char* args[]) {
+ pid_t p;
+
+ if (check_cryptsetup() != 0)
+ return 1;
+
+ if ((p = fork()) == 0) {
+ execv(cryptsetup, args);
+ fprintf(stderr, _("mount: cryptsetup exec failed\n"));
+ exit(1);
+ }
+
+ return reap_dmcrypt(p);
+}
+
+int
+del_dmcrypt(const char* dmname) {
+ pid_t p;
+
+ if (check_cryptsetup() != 0)
+ return 1;
+
+ if ((p = fork()) == 0) {
+ execl(cryptsetup, cryptsetup, "remove", dmname, 0);
+ fprintf(stderr, _("mount: cryptsetup exec failed\n"));
+ exit(1);
+ }
+
+ return reap_dmcrypt(p);
+}
+
int
del_loop (const char *device) {
int fd;
diff -ru util-linux-2.12p.orig/mount/lomount.h util-linux-2.12p/mount/lomount.h
--- util-linux-2.12p.orig/mount/lomount.h 2005-01-13 16:01:04.000000000
+0100
+++ util-linux-2.12p/mount/lomount.h 2005-01-13 16:02:18.000000000 +0100
@@ -2,5 +2,7 @@
extern int set_loop(const char *, const char *, unsigned long long,
const char *, int, int, int *, int);
extern int del_loop(const char *);
+extern int set_dmcrypt(char* args[]);
+extern int del_dmcrypt(const char* dmname);
extern int is_loop_device(const char *);
extern char * find_unused_loop_device(void);
diff -ru util-linux-2.12p.orig/mount/mount.c util-linux-2.12p/mount/mount.c
--- util-linux-2.12p.orig/mount/mount.c 2005-01-13 16:01:04.000000000 +0100
+++ util-linux-2.12p/mount/mount.c 2005-01-13 16:02:18.000000000 +0100
@@ -174,7 +174,8 @@
};
static const char *opt_loopdev, *opt_vfstype, *opt_offset, *opt_encryption,
- *opt_keybits, *opt_nohashpass, *opt_speed, *opt_comment;
+ *opt_keybits, *opt_keyhash, *opt_keyfile, *opt_nohashpass, *opt_dmname,
+ *opt_speed, *opt_comment;
static struct string_opt_map {
char *tag;
@@ -184,8 +185,11 @@
{ "loop=", 0, &opt_loopdev },
{ "vfs=", 1, &opt_vfstype },
{ "offset=", 0, &opt_offset },
+ { "dmname=", 0, &opt_dmname },
{ "encryption=", 0, &opt_encryption },
{ "keybits=", 0, &opt_keybits },
+ { "keyhash=", 0, &opt_keyhash },
+ { "keyfile=", 0, &opt_keyfile },
{ "nohashpass", 0, &opt_nohashpass },
{ "speed=", 0, &opt_speed },
{ "comment=", 1, &opt_comment },
@@ -615,8 +619,8 @@
*type = opt_vfstype;
}
- *loop = ((*flags & MS_LOOP) || *loopdev || opt_offset || opt_encryption ||
- opt_keybits);
+ *loop = ((*flags & MS_LOOP) || *loopdev || opt_offset ||
+ ((opt_encryption || opt_keybits) && !opt_dmname));
*loopfile = *spec;
if (*loop) {
@@ -655,6 +659,66 @@
return 0;
}
+static int
+dmcrypt_check(const char **spec, int* flags,
+ int* dmcrypt, const char **dmdev) {
+ const char* args[30];
+ char* mapper;
+ int i = 0;
+ *dmcrypt = opt_dmname?1:0;
+
+ if (*dmcrypt) {
+ *dmdev = *spec;
+ *spec = mapper = malloc(strlen(opt_dmname) + 30);
+ sprintf(mapper, "/dev/mapper/%s", opt_dmname);
+
+ args[i++] = "cryptsetup";
+
+ if (*flags & MS_RDONLY) {
+ args[i++] = "-r";
+ }
+ if (opt_keyfile) {
+ args[i++] = "--key-file";
+ args[i++] = opt_keyfile;
+ }
+ if (opt_keybits) {
+ args[i++] = "--key-size";
+ args[i++] = opt_keybits;
+ }
+ if (opt_keyhash) {
+ args[i++] = "--hash";
+ args[i++] = opt_keyhash;
+ }
+ if (opt_encryption) {
+ args[i++] = "--cipher";
+ args[i++] = opt_encryption;
+ }
+
+ args[i++] = "create";
+ args[i++] = opt_dmname;
+ args[i++] = *dmdev;
+ args[i] = 0;
+
+ if (verbose) {
+ int j;
+ printf("mount:");
+ for (j = 0; j < i; ++j)
+ printf(" %s", args[j]);
+ printf("\n");
+ }
+
+ if (set_dmcrypt((char**)args) != 0)
+ return EX_FAIL;
+ } else {
+ if (opt_keyhash)
+ fprintf(stderr, _("mount: keyhash only supported with
cryptsetup; set dmname\n"));
+ if (opt_keyfile)
+ fprintf(stderr, _("mount: keyfile only supported with
cryptsetup; set dmname\n"));
+ }
+
+ return 0;
+}
+
static void
update_mtab_entry(const char *spec, const char *node, const char *type,
const char *opts, int flags, int freq, int pass) {
@@ -800,8 +864,8 @@
char *mount_opts; /* actually used on system call */
const char *opts, *spec, *node, *types;
char *user = 0;
- int loop = 0;
- const char *loopdev = 0, *loopfile = 0;
+ int loop = 0, dmcrypt = 0;
+ const char *loopdev = 0, *loopfile = 0, *dmdev = 0;
struct stat statbuf;
int nfs_mount_version = 0; /* any version */
@@ -836,6 +890,10 @@
res = loop_check(&spec, &types, &flags, &loop, &loopdev, &loopfile);
if (res)
goto out;
+
+ res = dmcrypt_check(&spec, &flags, &dmcrypt, &dmdev);
+ if (res)
+ goto out;
}
/*
@@ -877,7 +945,7 @@
if (loop)
opt_loopdev = loopdev;
- update_mtab_entry(loop ? loopfile : spec,
+ update_mtab_entry(loop ? loopfile : (dmcrypt ? dmdev : spec),
node,
types ? types : "unknown",
fix_opts_string (flags & ~MS_NOMTAB, extra_opts, user),
@@ -892,6 +960,8 @@
mnt_err = errno;
+ if (dmcrypt)
+ del_dmcrypt(opt_dmname);
if (loop)
del_loop(spec);
diff -ru util-linux-2.12p.orig/mount/umount.c util-linux-2.12p/mount/umount.c
--- util-linux-2.12p.orig/mount/umount.c 2004-12-20 23:03:45.000000000
+0100
+++ util-linux-2.12p/mount/umount.c 2005-01-13 16:02:19.000000000 +0100
@@ -274,6 +274,7 @@
int res;
int status;
const char *loopdev;
+ const char *dmname;
/* Special case for root. As of 0.99pl10 we can (almost) unmount root;
the kernel will remount it readonly so that we can carry on running
@@ -366,11 +367,28 @@
}
loopdev = 0;
+ dmname = 0;
if (res >= 0) {
/* Umount succeeded */
if (verbose)
printf (_("%s umounted\n"), spec);
+ /* Remove the crypted device first */
+ if (mc) {
+ char *optl;
+
+ /* new style mtab line? */
+ optl = mc->m.mnt_opts ? xstrdup(mc->m.mnt_opts) : "";
+ for (optl = strtok (optl, ","); optl;
+ optl = strtok (NULL, ",")) {
+ if (!strncmp(optl, "dmname=", 7)) {
+ dmname = optl+7;
+ }
+ }
+
+ if (dmname) del_dmcrypt(dmname);
+ }
+
/* Free any loop devices that we allocated ourselves */
if (mc) {
char *optl;
signature.asc
Description: Digital signature
--- End Message ---