diff options
author | Lennart Poettering <lennart@poettering.net> | 2016-12-05 16:26:48 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2016-12-07 18:38:41 +0100 |
commit | 18b5886e562a3702ed8923e568a7555d2ab1880a (patch) | |
tree | f5dd924a0fd9f5e8436b3bf85c72167ac89eae32 /src/dissect/dissect.c | |
parent | cf139e6025d499eb93ff51acb1218662a208ff96 (diff) |
dissect: add support for encrypted images
This adds support to the image dissector to deal with encrypted images (only
LUKS). Given that we now have a neatly isolated image dissector codebase, let's
add a new feature to it: support for automatically dealing with encrypted
images. This is then exposed in systemd-dissect and nspawn.
It's pretty basic: only support for passphrase-based encryption.
In order to ensure that "systemd-dissect --mount" results in mount points whose
backing LUKS DM devices are cleaned up automatically we use the DM_DEV_REMOVE
ioctl() directly on the device (in DM_DEFERRED_REMOVE mode). libgcryptsetup at
the moment doesn't provide a proper API for this. Thankfully, the ioctl() API
is pretty easy to use.
Diffstat (limited to 'src/dissect/dissect.c')
-rw-r--r-- | src/dissect/dissect.c | 46 |
1 files changed, 38 insertions, 8 deletions
diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c index 93ece05948..5e6848acb4 100644 --- a/src/dissect/dissect.c +++ b/src/dissect/dissect.c @@ -34,7 +34,7 @@ static enum { } arg_action = ACTION_DISSECT; static const char *arg_image = NULL; static const char *arg_path = NULL; -static bool arg_read_only = false; +static DissectImageFlags arg_flags = DISSECT_IMAGE_DISCARD_ON_LOOP; static void help(void) { printf("%s [OPTIONS...] IMAGE\n" @@ -43,7 +43,8 @@ static void help(void) { " -h --help Show this help\n" " --version Show package version\n" " -m --mount Mount the image to the specified directory\n" - " -r --read-only Mount read-only\n", + " -r --read-only Mount read-only\n" + " --discard=MODE Choose 'discard' mode (disabled, loop, all, crypto)\n", program_invocation_short_name, program_invocation_short_name); } @@ -52,6 +53,7 @@ static int parse_argv(int argc, char *argv[]) { enum { ARG_VERSION = 0x100, + ARG_DISCARD, }; static const struct option options[] = { @@ -59,6 +61,7 @@ static int parse_argv(int argc, char *argv[]) { { "version", no_argument, NULL, ARG_VERSION }, { "mount", no_argument, NULL, 'm' }, { "read-only", no_argument, NULL, 'r' }, + { "discard", required_argument, NULL, ARG_DISCARD }, {} }; @@ -83,7 +86,23 @@ static int parse_argv(int argc, char *argv[]) { break; case 'r': - arg_read_only = true; + arg_flags |= DISSECT_IMAGE_READ_ONLY; + break; + + case ARG_DISCARD: + if (streq(optarg, "disabled")) + arg_flags &= ~(DISSECT_IMAGE_DISCARD_ON_LOOP|DISSECT_IMAGE_DISCARD|DISSECT_IMAGE_DISCARD_ON_CRYPTO); + else if (streq(optarg, "loop")) + arg_flags = (arg_flags & ~(DISSECT_IMAGE_DISCARD|DISSECT_IMAGE_DISCARD_ON_CRYPTO)) | DISSECT_IMAGE_DISCARD_ON_LOOP; + else if (streq(optarg, "all")) + arg_flags = (arg_flags & ~(DISSECT_IMAGE_DISCARD_ON_CRYPTO)) | DISSECT_IMAGE_DISCARD_ON_LOOP | DISSECT_IMAGE_DISCARD; + else if (streq(optarg, "crypt")) + arg_flags |= DISSECT_IMAGE_DISCARD_ON_LOOP | DISSECT_IMAGE_DISCARD | DISSECT_IMAGE_DISCARD_ON_CRYPTO; + else { + log_error("Unknown --discard= parameter: %s", optarg); + return -EINVAL; + } + break; case '?': @@ -104,7 +123,7 @@ static int parse_argv(int argc, char *argv[]) { } arg_image = argv[optind]; - arg_read_only = true; + arg_flags |= DISSECT_IMAGE_READ_ONLY; break; case ACTION_MOUNT: @@ -126,6 +145,7 @@ static int parse_argv(int argc, char *argv[]) { int main(int argc, char *argv[]) { _cleanup_(loop_device_unrefp) LoopDevice *d = NULL; + _cleanup_(decrypted_image_unrefp) DecryptedImage *di = NULL; _cleanup_(dissected_image_unrefp) DissectedImage *m = NULL; int r; @@ -136,7 +156,7 @@ int main(int argc, char *argv[]) { if (r <= 0) goto finish; - r = loop_device_make_by_path(arg_image, arg_read_only ? O_RDONLY : O_RDWR, &d); + r = loop_device_make_by_path(arg_image, (arg_flags & DISSECT_IMAGE_READ_ONLY) ? O_RDONLY : O_RDWR, &d); if (r < 0) { log_error_errno(r, "Failed to set up loopback device: %m"); goto finish; @@ -186,14 +206,24 @@ int main(int argc, char *argv[]) { } case ACTION_MOUNT: - r = dissected_image_mount(m, arg_path, - (arg_read_only ? DISSECTED_IMAGE_READ_ONLY : 0) | - DISSECTED_IMAGE_DISCARD_ON_LOOP); + r = dissected_image_decrypt_interactively(m, NULL, arg_flags, &di); + if (r < 0) + goto finish; + + r = dissected_image_mount(m, arg_path, arg_flags); if (r < 0) { log_error_errno(r, "Failed to mount image: %m"); goto finish; } + if (di) { + r = decrypted_image_relinquish(di); + if (r < 0) { + log_error_errno(r, "Failed to relinquish DM devices: %m"); + goto finish; + } + } + loop_device_relinquish(d); break; |