mirror of
https://github.com/systemd/systemd.git
synced 2024-10-26 08:55:40 +03:00
cryptsetup-generator: Add luks.link-volume-key= command line option.
This option adds link-volume-key= option to all configured LUKS device activated by systemd-cryptsetup. The device unit may origin in either crypttab file or kernel command line option. The resulting link-volume-key= paramater replaces all eventually added link-volume-key options added per device either in crypttab file or kernel command line. The value may be in following formats: link-volume-key="@u" (all keys linked in the root user keyring, user type) link-volume-key="@u::%logon" (all keys linked in the root user keyring, logon type) link-volume-key="my_custom_keyring" (all keys linked in my_custom_keyring keyring, user type) link-volume-key="my_custom_keyring::%logon" (all keys linked in my_custom_keyring keyring, logon type) The referenced keyring (via keyring description) must exist in advance of invoking device activation units.
This commit is contained in:
parent
bca6c78daf
commit
c91c6c2a47
@ -221,6 +221,63 @@
|
||||
<xi:include href="version-info.xml" xpointer="v208"/>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>luks.link-volume-key=</varname></term>
|
||||
<term><varname>rd.luks.link-volume-key=</varname></term>
|
||||
|
||||
<listitem><para>Specifies a kernel key type and a kernel keyring where
|
||||
LUKS2 volume keys get linked during the device activation. This option
|
||||
only supports the automatic flavor where key description of a linked
|
||||
key is derived from LUKS device uuid upon activation (unlike
|
||||
<literal>link-vokume-key</literal> parameter of
|
||||
<option>luks.options</option> where also specific key description
|
||||
may be added).</para>
|
||||
|
||||
<para>If this option is used, all units originating from either
|
||||
<filename>/etc/crypttab</filename> or kernel command line will get
|
||||
<literal>link-volume-key</literal> option added among LUKS parameters.
|
||||
It will eventually replace original parameter specified either
|
||||
in the file or on the kernel commandl line.</para>
|
||||
|
||||
<para>The key type and kernel keyring may be specified like follows (first
|
||||
matching rule will apply):</para>
|
||||
|
||||
<para>The value<literal>auto</literal> will get all volume keys uploaded
|
||||
in a <literal>user</literal> type keys linked in the user keyring
|
||||
(<literal>@u</literal>).</para>
|
||||
|
||||
<para>The value<literal>auto-logon</literal> will get all volume keys uploaded
|
||||
in a <literal>logon</literal> type keys linked in the user keyring
|
||||
(<literal>@u</literal>).</para>
|
||||
|
||||
<para>If no <literal>::</literal> substring is specified, the value gets
|
||||
interpreted as a target keyring description where volume keys
|
||||
will be linked in <literal>user</literal> type keys. The prefix
|
||||
<literal>%:</literal> or <literal>%keyring:</literal> may be ommited
|
||||
from keyring descriptions.</para>
|
||||
|
||||
<para>If <literal>::</literal> substring is specified, the substring
|
||||
in front of <literal>::</literal> gets interpreted as a keyring
|
||||
description. The remaining string beyond <literal>::</literal> must
|
||||
represent key type description. The prefix
|
||||
<literal>%:</literal> or <literal>%keyring:</literal> may be ommited
|
||||
from keyring descriptions.</para>
|
||||
|
||||
<para>See
|
||||
<citerefentry project='man-pages'><refentrytitle>keyctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||
for more information on key descriptions (KEY IDENTIFIERS section).</para>
|
||||
|
||||
<para>Note that the linked volume keys are not cleaned up automatically when
|
||||
devices are detached.</para>
|
||||
|
||||
<para><varname>rd.luks.link-volume-key=</varname> is honored only by initial
|
||||
RAM disk (initrd) while <varname>luks.link-volume-key=</varname> is
|
||||
honored by both the main system and in the initrd.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v257"/>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "path-util.h"
|
||||
#include "proc-cmdline.h"
|
||||
#include "specifier.h"
|
||||
#include "string-util-fundamental.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "unit-name.h"
|
||||
@ -44,10 +45,12 @@ static bool arg_allow_list = false;
|
||||
static Hashmap *arg_disks = NULL;
|
||||
static char *arg_default_options = NULL;
|
||||
static char *arg_default_keyfile = NULL;
|
||||
static char *arg_default_key_keyring = NULL;
|
||||
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_disks, hashmap_freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_default_options, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_default_keyfile, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_default_key_keyring, freep);
|
||||
|
||||
static int split_locationspec(const char *locationspec, char **ret_file, char **ret_device) {
|
||||
_cleanup_free_ char *file = NULL, *device = NULL;
|
||||
@ -790,13 +793,35 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
|
||||
free_and_replace(d->name, uuid_value);
|
||||
} else
|
||||
log_warning("Failed to parse luks name switch %s. Ignoring.", value);
|
||||
} else if (streq(key, "luks.link-volume-key")) {
|
||||
const char *c, *sep;
|
||||
|
||||
if (proc_cmdline_value_missing(key, value))
|
||||
return 0;
|
||||
|
||||
sep = strstr(value, "::");
|
||||
|
||||
/* reject specification including key description */
|
||||
if (sep && sep[2] != '%')
|
||||
return log_warning_errno(0, "Failed to parse default luks keyring switch %s. Ignoring.", value);
|
||||
|
||||
if (sep) {
|
||||
/* reject full specification */
|
||||
c = strchr(sep + 3, ':');
|
||||
if (c)
|
||||
return log_warning_errno(0, "Failed to parse default luks keyring switch %s. Ignoring.", value);
|
||||
}
|
||||
|
||||
if (free_and_strdup(&arg_default_key_keyring, value) < 0)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_crypttab_device(const char *name, const char *device, const char *keyspec, const char *options) {
|
||||
_cleanup_free_ char *keyfile = NULL, *keydev = NULL, *headerdev = NULL, *filtered_header = NULL;
|
||||
_cleanup_free_ char *keyfile = NULL, *keydev = NULL, *headerdev = NULL, *filtered_header = NULL,
|
||||
*new_options = NULL;
|
||||
crypto_device *d = NULL;
|
||||
char *uuid;
|
||||
int r;
|
||||
@ -825,6 +850,17 @@ static int add_crypttab_device(const char *name, const char *device, const char
|
||||
options = filtered_header;
|
||||
}
|
||||
|
||||
if (arg_default_key_keyring && options && (!d || !d->options)) {
|
||||
if (isempty(options))
|
||||
new_options = strjoin("link-volume-key=", arg_default_key_keyring);
|
||||
else
|
||||
new_options = strjoin(options, ",link-volume-key=", arg_default_key_keyring);
|
||||
if (!new_options)
|
||||
return log_oom();
|
||||
|
||||
options = new_options;
|
||||
}
|
||||
|
||||
r = create_disk(name,
|
||||
device,
|
||||
keyfile,
|
||||
@ -916,6 +952,31 @@ static int add_proc_cmdline_devices(void) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int add_default_key_keyring_to_devices(void) {
|
||||
crypto_device *d;
|
||||
|
||||
if (!arg_default_key_keyring)
|
||||
return 0;
|
||||
|
||||
HASHMAP_FOREACH(d, arg_disks) {
|
||||
_cleanup_free_ char *new_options = NULL;
|
||||
|
||||
if (!d->create)
|
||||
continue;
|
||||
|
||||
if (isempty(d->options))
|
||||
new_options = strjoin("link-volume-key=", arg_default_key_keyring);
|
||||
else
|
||||
new_options = strjoin(d->options, ",link-volume-key=", arg_default_key_keyring);
|
||||
if (!new_options)
|
||||
return log_oom();
|
||||
|
||||
free_and_replace(d->options, new_options);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(crypt_device_hash_ops, char, string_hash_func, string_compare_func,
|
||||
crypto_device, crypt_device_free);
|
||||
|
||||
@ -938,6 +999,10 @@ static int run(const char *dest, const char *dest_early, const char *dest_late)
|
||||
if (!arg_enabled)
|
||||
return 0;
|
||||
|
||||
r = add_default_key_keyring_to_devices();
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = add_crypttab_devices();
|
||||
RET_GATHER(r, add_proc_cmdline_devices());
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user