Note that cryptsetup-reencrypt is a separate package on Fedora, but is
already part of the appliance on Debian/Ubuntu.
---
appliance/packagelist.in | 1 +
daemon/luks.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
generator/actions.ml | 18 ++++++++++++++++++
gobject/Makefile.inc | 2 ++
src/MAX_PROC_NR | 2 +-
5 files changed, 68 insertions(+), 1 deletion(-)
diff --git a/appliance/packagelist.in b/appliance/packagelist.in
index bbbe4b2..485e9cd 100644
--- a/appliance/packagelist.in
+++ b/appliance/packagelist.in
@@ -26,6 +26,7 @@ ifelse(REDHAT,1,
augeas-libs
cryptsetup
cryptsetup-luks dnl old name used before Fedora 17
+ cryptsetup-reencrypt
dhclient
genisoimage
gfs-utils
diff --git a/daemon/luks.c b/daemon/luks.c
index 53bb820..440caa2 100644
--- a/daemon/luks.c
+++ b/daemon/luks.c
@@ -29,6 +29,7 @@
#define MAX_ARGS 64
GUESTFSD_EXT_CMD(str_cryptsetup, cryptsetup);
+GUESTFSD_EXT_CMD(str_cryptsetup_reencrypt, cryptsetup_reencrypt);
int
optgroup_luks_available (void)
@@ -294,3 +295,48 @@ do_luks_kill_slot (const char *device, const char *key, int keyslot)
return 0;
}
+
+int
+optgroup_luksreencrypt_available (void)
+{
+ return prog_exists (str_cryptsetup_reencrypt);
+}
+
+/* Takes optional arguments, consult optargs_bitmask. */
+int
+do_cryptsetup_reencrypt (const char *device, const char *key, int keyslot,
+ const char *cipher)
+{
+ const char *argv[MAX_ARGS];
+ size_t i = 0;
+ char keyslot_s[16];
+
+ char *tempfile = write_key_to_temp (key);
+ if (!tempfile)
+ return -1;
+
+ ADD_ARG (argv, i, str_cryptsetup_reencrypt);
+ ADD_ARG (argv, i, "-q");
+ if ((optargs_bitmask & GUESTFS_CRYPTSETUP_REENCRYPT_CIPHER_BITMASK)) {
+ ADD_ARG (argv, i, "-c");
+ ADD_ARG (argv, i, cipher);
+ }
+ ADD_ARG (argv, i, "-d");
+ ADD_ARG (argv, i, tempfile);
+ ADD_ARG (argv, i, "-S");
+ snprintf (keyslot_s, sizeof keyslot_s, "%d", keyslot);
+ ADD_ARG (argv, i, keyslot_s);
+ ADD_ARG (argv, i, device);
+ ADD_ARG (argv, i, NULL);
+
+ CLEANUP_FREE char *err = NULL;
+ int r = commandv (NULL, &err, (const char * const *) argv);
+ remove_temp (tempfile);
+
+ if (r == -1) {
+ reply_with_error ("%s", err);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/generator/actions.ml b/generator/actions.ml
index 43de38b..057db8f 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -13265,6 +13265,24 @@ is removed." };
shortdesc = "search the entries associated to the given inode";
longdesc = "Internal function for find_inode." };
+ { defaults with
+ name = "cryptsetup_reencrypt"; added = (1, 35, 15);
+ style = RErr, [Device "device"; Key "key"; Int
"keyslot"], [OString "cipher"];
+ proc_nr = Some 471;
+ optional = Some "luksreencrypt";
+ shortdesc = "change the master volume key on a LUKS partition";
+ longdesc = "\
+This reencrypts a LUKS device with a new random master volume key,
+using the L<cryptsetup-reencrypt(8)> tool. A new passphrase C<key>
+is added in key slot C<keyslot>, and all other keyslots are erased.
+
+With no optional parameters, the same type of cipher is used. To
+change to a different cipher, supply the optional C<cipher> parameter.
+
+This command has to rewrite the entire C<device>, and so is both
+long running and will destroy all the data on the device if the
+operation is interrupted." };
+
]
(* Non-API meta-commands available only in guestfish.
diff --git a/gobject/Makefile.inc b/gobject/Makefile.inc
index 149e4c6..bb1ee3a 100644
--- a/gobject/Makefile.inc
+++ b/gobject/Makefile.inc
@@ -68,6 +68,7 @@ guestfs_gobject_headers= \
include/guestfs-gobject/optargs-copy_file_to_device.h \
include/guestfs-gobject/optargs-copy_file_to_file.h \
include/guestfs-gobject/optargs-cpio_out.h \
+ include/guestfs-gobject/optargs-cryptsetup_reencrypt.h \
include/guestfs-gobject/optargs-disk_create.h \
include/guestfs-gobject/optargs-download_blocks.h \
include/guestfs-gobject/optargs-e2fsck.h \
@@ -159,6 +160,7 @@ guestfs_gobject_sources= \
src/optargs-copy_file_to_device.c \
src/optargs-copy_file_to_file.c \
src/optargs-cpio_out.c \
+ src/optargs-cryptsetup_reencrypt.c \
src/optargs-disk_create.c \
src/optargs-download_blocks.c \
src/optargs-e2fsck.c \
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index 5f476b6..c305aa5 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-470
+471
--
2.10.2