summaryrefslogtreecommitdiffstats
path: root/libmount/src
diff options
context:
space:
mode:
authorKarel Zak2012-01-11 16:16:00 +0100
committerKarel Zak2012-01-11 16:16:00 +0100
commit1a7a421ed74bc8502cdd9d1de46bc78c62b71b7d (patch)
tree1eb7fc58b8ec2f414246c52d0350fa7b04c01d51 /libmount/src
parentlosetup: add note about non-root users to losetup.8 (diff)
downloadkernel-qcow2-util-linux-1a7a421ed74bc8502cdd9d1de46bc78c62b71b7d.tar.gz
kernel-qcow2-util-linux-1a7a421ed74bc8502cdd9d1de46bc78c62b71b7d.tar.xz
kernel-qcow2-util-linux-1a7a421ed74bc8502cdd9d1de46bc78c62b71b7d.zip
libmount: add support for encrypted loopdevs
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libmount/src')
-rw-r--r--libmount/src/context.c20
-rw-r--r--libmount/src/context_loopdev.c26
-rw-r--r--libmount/src/libmount.h.in5
-rw-r--r--libmount/src/libmount.sym1
-rw-r--r--libmount/src/mountP.h3
-rw-r--r--libmount/src/optmap.c1
6 files changed, 54 insertions, 2 deletions
diff --git a/libmount/src/context.c b/libmount/src/context.c
index 19954096b..d67f692a1 100644
--- a/libmount/src/context.c
+++ b/libmount/src/context.c
@@ -897,6 +897,26 @@ struct libmnt_cache *mnt_context_get_cache(struct libmnt_context *cxt)
}
/**
+ * mnt_context_set_passwd_cb:
+ * @cxt: mount context
+ *
+ * Sets callbacks for encryption password.
+ *
+ * Returns: 0 on success, negative number in case of error.
+ */
+int mnt_context_set_passwd_cb(struct libmnt_context *cxt,
+ char *(*get)(struct libmnt_context *),
+ void (*release)(struct libmnt_context *, char *))
+{
+ if (!cxt)
+ return -EINVAL;
+
+ cxt->pwd_get_cb = get;
+ cxt->pwd_release_cb = release;
+ return 0;
+}
+
+/**
* mnt_context_get_lock:
* @cxt: mount context
*
diff --git a/libmount/src/context_loopdev.c b/libmount/src/context_loopdev.c
index 6221166ff..d32e70966 100644
--- a/libmount/src/context_loopdev.c
+++ b/libmount/src/context_loopdev.c
@@ -34,7 +34,8 @@ int mnt_context_is_loopdev(struct libmnt_context *cxt)
if (cxt->user_mountflags & (MNT_MS_LOOP |
MNT_MS_OFFSET |
- MNT_MS_SIZELIMIT))
+ MNT_MS_SIZELIMIT |
+ MNT_MS_ENCRYPTION))
return 1;
if (cxt->mountflags & (MS_BIND | MS_MOVE | MS_PROPAGATION))
@@ -64,7 +65,7 @@ int mnt_context_is_loopdev(struct libmnt_context *cxt)
int mnt_context_setup_loopdev(struct libmnt_context *cxt)
{
const char *backing_file, *optstr, *loopdev = NULL;
- char *val = NULL;
+ char *val = NULL, *enc = NULL, *pwd = NULL;
size_t len;
struct loopdev_cxt lc;
int rc = 0, lo_flags = 0;
@@ -125,6 +126,20 @@ int mnt_context_setup_loopdev(struct libmnt_context *cxt)
DBG(CXT, mnt_debug_h(cxt, "failed to parse sizelimit="));
}
+ /*
+ * encryption=
+ */
+ if (rc == 0 && (cxt->user_mountflags & MNT_MS_ENCRYPTION) &&
+ mnt_optstr_get_option(optstr, "encryption", &val, &len) == 0) {
+ enc = strndup(val, len);
+ if (val && !enc)
+ rc = -ENOMEM;
+ if (enc && cxt->pwd_get_cb) {
+ DBG(CXT, mnt_debug_h(cxt, "asking for pass"));
+ pwd = cxt->pwd_get_cb(cxt);
+ }
+ }
+
if (rc)
goto done;
@@ -156,6 +171,8 @@ int mnt_context_setup_loopdev(struct libmnt_context *cxt)
rc = loopcxt_set_offset(&lc, offset);
if (!rc && sizelimit)
rc = loopcxt_set_sizelimit(&lc, sizelimit);
+ if (!rc && enc && pwd)
+ loopcxt_set_encryption(&lc, enc, pwd);
if (!rc)
loopcxt_set_flags(&lc, lo_flags);
if (rc) {
@@ -208,6 +225,11 @@ int mnt_context_setup_loopdev(struct libmnt_context *cxt)
loopcxt_set_fd(&lc, -1, 0);
}
done:
+ free(enc);
+ if (pwd && cxt->pwd_release_cb) {
+ DBG(CXT, mnt_debug_h(cxt, "release pass"));
+ cxt->pwd_release_cb(cxt, pwd);
+ }
loopcxt_deinit(&lc);
return rc;
}
diff --git a/libmount/src/libmount.h.in b/libmount/src/libmount.h.in
index 9e1a65fca..5409ed515 100644
--- a/libmount/src/libmount.h.in
+++ b/libmount/src/libmount.h.in
@@ -431,6 +431,10 @@ extern int mnt_context_set_fstype_pattern(struct libmnt_context *cxt,
extern int mnt_context_set_options_pattern(struct libmnt_context *cxt,
const char *pattern);
+extern int mnt_context_set_passwd_cb(struct libmnt_context *cxt,
+ char *(*get)(struct libmnt_context *),
+ void (*release)(struct libmnt_context *, char *));
+
extern int mnt_context_set_tables_errcb(struct libmnt_context *cxt,
int (*cb)(struct libmnt_table *tb, const char *filename, int line));
extern int mnt_context_set_fstab(struct libmnt_context *cxt,
@@ -498,6 +502,7 @@ extern int mnt_context_set_syscall_status(struct libmnt_context *cxt, int status
#define MNT_MS_XCOMMENT (1 << 13)
#define MNT_MS_OFFSET (1 << 14)
#define MNT_MS_SIZELIMIT (1 << 15)
+#define MNT_MS_ENCRYPTION (1 << 16)
/*
* mount(2) MS_* masks (MNT_MAP_LINUX map)
diff --git a/libmount/src/libmount.sym b/libmount/src/libmount.sym
index 0740db8e1..563ae7a0c 100644
--- a/libmount/src/libmount.sym
+++ b/libmount/src/libmount.sym
@@ -213,6 +213,7 @@ global:
mnt_context_is_fork;
mnt_context_is_parent;
mnt_context_next_umount;
+ mnt_context_set_passwd_cb;
mnt_context_wait_for_children;
mnt_fs_is_netfs;
mnt_fs_is_pseudofs;
diff --git a/libmount/src/mountP.h b/libmount/src/mountP.h
index c82a97999..fa0567877 100644
--- a/libmount/src/mountP.h
+++ b/libmount/src/mountP.h
@@ -276,6 +276,9 @@ struct libmnt_context
int (*table_errcb)(struct libmnt_table *tb, /* callback for libmnt_table structs */
const char *filename, int line);
+ char *(*pwd_get_cb)(struct libmnt_context *); /* get encryption password */
+ void (*pwd_release_cb)(struct libmnt_context *, char *); /* release password */
+
int optsmode; /* fstab optstr mode MNT_OPTSMODE_{AUTO,FORCE,IGNORE} */
int loopdev_fd; /* open loopdev */
diff --git a/libmount/src/optmap.c b/libmount/src/optmap.c
index 2f57334db..7bd4da736 100644
--- a/libmount/src/optmap.c
+++ b/libmount/src/optmap.c
@@ -147,6 +147,7 @@ static const struct libmnt_optmap userspace_opts_map[] =
{ "loop[=]", MNT_MS_LOOP }, /* use the loop device */
{ "offset=", MNT_MS_OFFSET, MNT_NOMTAB }, /* loop device offset */
{ "sizelimit=", MNT_MS_SIZELIMIT, MNT_NOMTAB }, /* loop device size limit */
+ { "encryption=", MNT_MS_ENCRYPTION, MNT_NOMTAB }, /* loop device encryption */
{ "nofail", MNT_MS_NOFAIL, MNT_NOMTAB }, /* Do not fail if ENOENT on dev */