chiark / gitweb /
cryptsetup-generator: Add support for UUID-specific key files on kernel command line
authorJan Janssen <medhefgo@web.de>
Tue, 2 Dec 2014 17:49:29 +0000 (18:49 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 5 Dec 2014 00:29:43 +0000 (01:29 +0100)
man/systemd-cryptsetup-generator.xml
src/cryptsetup/cryptsetup-generator.c

index ff94e88..d4a9cc7 100644 (file)
                                 <term><varname>luks.key=</varname></term>
                                 <term><varname>rd.luks.key=</varname></term>
 
-                                <listitem><para>Takes a password file as argument.</para>
+                                <listitem><para>Takes a password file name as argument or
+                                a LUKS super block UUID followed by a '=' and a password
+                                file name.</para>
+
                                 <para>For those entries specified with
                                 <varname>rd.luks.uuid=</varname> or <varname>luks.uuid=</varname>,
-                                the password file will be set to the password file specified by
-                                <varname>rd.luks.key=</varname> or <varname>luks.key</varname></para>
+                                the password file will be set to the one specified by
+                                <varname>rd.luks.key=</varname> or <varname>luks.key=</varname>
+                                of the corresponding UUID, or the password file that was specified
+                                without a UUID.</para>
                                 <para><varname>rd.luks.key=</varname>
                                 is honored only by initial RAM disk
                                 (initrd) while
index c1581ef..efbcb3a 100644 (file)
@@ -36,6 +36,7 @@
 
 typedef struct crypto_device {
         char *uuid;
+        char *keyfile;
         char *options;
         bool create;
 } crypto_device;
@@ -264,6 +265,7 @@ static void free_arg_disks(void) {
 
         while ((d = hashmap_steal_first(arg_disks))) {
                 free(d->uuid);
+                free(d->keyfile);
                 free(d->options);
                 free(d);
         }
@@ -284,7 +286,7 @@ static crypto_device *get_crypto_device(const char *uuid) {
                         return NULL;
 
                 d->create = false;
-                d->options = NULL;
+                d->keyfile = d->options = NULL;
 
                 d->uuid = strdup(uuid);
                 if (!d->uuid) {
@@ -348,7 +350,16 @@ static int parse_proc_cmdline_item(const char *key, const char *value) {
 
         } else if (STR_IN_SET(key, "luks.key", "rd.luks.key") && value) {
 
-                if (free_and_strdup(&arg_default_keyfile, value))
+                r = sscanf(value, "%m[0-9a-fA-F-]=%ms", &uuid, &uuid_value);
+                if (r == 2) {
+                        d = get_crypto_device(uuid);
+                        if (!d)
+                                return log_oom();
+
+                        free(d->keyfile);
+                        d->keyfile = uuid_value;
+                        uuid_value = NULL;
+                } else if (free_and_strdup(&arg_default_keyfile, value))
                         return log_oom();
 
         }
@@ -455,7 +466,7 @@ static int add_proc_cmdline_devices(void) {
                 else
                         options = "timeout=0";
 
-                r = create_disk(name, device, arg_default_keyfile, options);
+                r = create_disk(name, device, d->keyfile ?: arg_default_keyfile, options);
                 if (r < 0)
                         return r;
         }