Richard W.M. Jones
2016-Dec-02 17:04 UTC
[Libguestfs] [PATCH] New API: cryptsetup_reencrypt: change the master volume key on LUKS partitions.
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