diff options
-rw-r--r-- | man/crypttab.xml | 12 | ||||
-rw-r--r-- | src/cryptsetup/cryptsetup.c | 44 |
2 files changed, 53 insertions, 3 deletions
diff --git a/man/crypttab.xml b/man/crypttab.xml index 42caf34308..737b232335 100644 --- a/man/crypttab.xml +++ b/man/crypttab.xml @@ -142,6 +142,18 @@ </varlistentry> <varlistentry> + <term><option>header=</option></term> + + <listitem><para>Use a detached (separated) + metadata device or file where the LUKS header + is stored. This option is only relevant for + LUKS devices. See + <citerefentry><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry> + for possible values and the default value of + this option.</para></listitem> + </varlistentry> + + <varlistentry> <term><option>keyfile-offset=</option></term> <listitem><para>Specifies the number of bytes to diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c index 21b1260f1b..15dea7b65b 100644 --- a/src/cryptsetup/cryptsetup.c +++ b/src/cryptsetup/cryptsetup.c @@ -43,6 +43,7 @@ static int arg_key_slot = CRYPT_ANY_SLOT; static unsigned arg_keyfile_size = 0; static unsigned arg_keyfile_offset = 0; static char *arg_hash = NULL; +static char *arg_header = NULL; static unsigned arg_tries = 3; static bool arg_readonly = false; static bool arg_verify = false; @@ -136,6 +137,23 @@ static int parse_one_option(const char *option) { free(arg_hash); arg_hash = t; + } else if (startswith(option, "header=")) { + arg_type = CRYPT_LUKS1; + + if (!path_is_absolute(option+7)) { + log_error("Header path '%s' is not absolute, refusing.", option+7); + return -EINVAL; + } + + if (arg_header) { + log_error("Duplicate header= options, refusing."); + return -EINVAL; + } + + arg_header = strdup(option+7); + if (!arg_header) + return log_oom(); + } else if (startswith(option, "tries=")) { if (safe_atou(option+6, &arg_tries) < 0) { @@ -375,6 +393,7 @@ static int attach_tcrypt(struct crypt_device *cd, static int attach_luks_or_plain(struct crypt_device *cd, const char *name, const char *key_file, + const char *data_device, char **passwords, uint32_t flags) { int r = 0; @@ -384,8 +403,16 @@ static int attach_luks_or_plain(struct crypt_device *cd, assert(name); assert(key_file || passwords); - if (!arg_type || streq(arg_type, CRYPT_LUKS1)) + if (!arg_type || streq(arg_type, CRYPT_LUKS1)) { r = crypt_load(cd, CRYPT_LUKS1, NULL); + if (r < 0) { + log_error("crypt_load() failed on device %s.\n", crypt_get_device_name(cd)); + return r; + } + + if (data_device) + r = crypt_set_data_device(cd, data_device); + } if ((!arg_type && r < 0) || streq_ptr(arg_type, CRYPT_PLAIN)) { struct crypt_params_plain params = {}; @@ -559,7 +586,12 @@ int main(int argc, char *argv[]) { } name = name_buffer ? name_buffer : argv[2]; - k = crypt_init(&cd, argv[3]); + if (arg_header) { + log_debug("LUKS header: %s", arg_header); + k = crypt_init(&cd, arg_header); + } else + k = crypt_init(&cd, argv[3]); + if (k) { log_error_errno(k, "crypt_init() failed: %m"); goto finish; @@ -610,7 +642,12 @@ int main(int argc, char *argv[]) { if (streq_ptr(arg_type, CRYPT_TCRYPT)) k = attach_tcrypt(cd, argv[2], key_file, passwords, flags); else - k = attach_luks_or_plain(cd, argv[2], key_file, passwords, flags); + k = attach_luks_or_plain(cd, + argv[2], + key_file, + arg_header ? argv[3] : NULL, + passwords, + flags); if (k >= 0) break; else if (k == -EAGAIN) { @@ -661,6 +698,7 @@ finish: free(arg_cipher); free(arg_hash); + free(arg_header); strv_free(arg_tcrypt_keyfiles); return r; |