]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: add support for encrypted loopdevs
authorKarel Zak <kzak@redhat.com>
Wed, 11 Jan 2012 15:16:00 +0000 (16:16 +0100)
committerKarel Zak <kzak@redhat.com>
Wed, 11 Jan 2012 15:16:00 +0000 (16:16 +0100)
Signed-off-by: Karel Zak <kzak@redhat.com>
libmount/src/context.c
libmount/src/context_loopdev.c
libmount/src/libmount.h.in
libmount/src/libmount.sym
libmount/src/mountP.h
libmount/src/optmap.c

index 19954096b508bfb3811ed92d414b62da0a4276a4..d67f692a17ea5ccc4b6d68a563c1b70ec326a4ce 100644 (file)
@@ -896,6 +896,26 @@ struct libmnt_cache *mnt_context_get_cache(struct libmnt_context *cxt)
        return cxt->cache;
 }
 
+/**
+ * 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
index 6221166ff7faafe8b8c7506560d8c63f4695bd19..d32e7096620ec2c4467236fd8f5f50fb2e754ced 100644 (file)
@@ -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;
 }
index 9e1a65fcaaf7bd99138aff2af9daa5833d01e540..5409ed5158dcb213177ab874e184c3397ce0d24e 100644 (file)
@@ -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)
index 0740db8e123989f8c828def23d107c202099780c..563ae7a0c53d217a003c1f8ab26c544c3ee6a94b 100644 (file)
@@ -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;
index c82a9799988473b1944694f79ffce25a084fee6d..fa0567877cba166f08e14d90a9f5600ec28ae887 100644 (file)
@@ -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 */
 
index 2f57334db03650c2a21a1b855e38a5f5fd542b40..7bd4da736c3f93ef3090b7ad0e79b08db7a340e8 100644 (file)
@@ -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 */