X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcryptsetup%2Fcryptsetup-generator.c;h=05061c0704fe5593759ea56dbb415bf096a2e2c0;hb=5e07a79e84ab8b045b9df1a2719f14fc84471a1d;hp=c1581ef9c8a7be55a18044eed0c2356803780631;hpb=0fa9e53d12a64981e071e0adb24698f4735e2599;p=elogind.git diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c index c1581ef9c..05061c070 100644 --- a/src/cryptsetup/cryptsetup-generator.c +++ b/src/cryptsetup/cryptsetup-generator.c @@ -30,12 +30,15 @@ #include "log.h" #include "mkdir.h" #include "path-util.h" +#include "fstab-util.h" #include "strv.h" #include "unit-name.h" #include "util.h" typedef struct crypto_device { char *uuid; + char *keyfile; + char *name; char *options; bool create; } crypto_device; @@ -48,35 +51,6 @@ static Hashmap *arg_disks = NULL; static char *arg_default_options = NULL; static char *arg_default_keyfile = NULL; -static bool has_option(const char *haystack, const char *needle) { - const char *f = haystack; - size_t l; - - assert(needle); - - if (!haystack) - return false; - - l = strlen(needle); - - while ((f = strstr(f, needle))) { - - if (f > haystack && f[-1] != ',') { - f++; - continue; - } - - if (f[l] != 0 && f[l] != ',') { - f++; - continue; - } - - return true; - } - - return false; -} - static int create_disk( const char *name, const char *device, @@ -93,10 +67,10 @@ static int create_disk( assert(name); assert(device); - noauto = has_option(options, "noauto"); - nofail = has_option(options, "nofail"); - tmp = has_option(options, "tmp"); - swap = has_option(options, "swap"); + noauto = fstab_test_yes_no_option(options, "noauto\0" "auto\0"); + nofail = fstab_test_yes_no_option(options, "nofail\0" "fail\0"); + tmp = fstab_test_option(options, "tmp\0"); + swap = fstab_test_option(options, "swap\0"); if (tmp && swap) { log_error("Device '%s' cannot be both 'tmp' and 'swap'. Ignoring.", name); @@ -209,7 +183,7 @@ static int create_disk( if (ferror(f)) return log_error_errno(errno, "Failed to write file %s: %m", p); - from = strappenda("../", n); + from = strjoina("../", n); if (!noauto) { @@ -264,6 +238,8 @@ static void free_arg_disks(void) { while ((d = hashmap_steal_first(arg_disks))) { free(d->uuid); + free(d->keyfile); + free(d->name); free(d->options); free(d); } @@ -284,7 +260,7 @@ static crypto_device *get_crypto_device(const char *uuid) { return NULL; d->create = false; - d->options = NULL; + d->keyfile = d->options = d->name = NULL; d->uuid = strdup(uuid); if (!d->uuid) { @@ -348,9 +324,34 @@ 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(); + } else if (STR_IN_SET(key, "luks.name", "rd.luks.name") && 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(); + + d->create = arg_whitelist = true; + + free(d->name); + d->name = uuid_value; + uuid_value = NULL; + } else + log_warning("Failed to parse luks name switch %s. Ignoring.", value); + } return 0; @@ -435,14 +436,16 @@ static int add_proc_cmdline_devices(void) { HASHMAP_FOREACH(d, arg_disks, i) { const char *options; - _cleanup_free_ char *name = NULL, *device = NULL; + _cleanup_free_ char *device = NULL; if (!d->create) continue; - name = strappend("luks-", d->uuid); - if (!name) - return log_oom(); + if (!d->name) { + d->name = strappend("luks-", d->uuid); + if (!d->name) + return log_oom(); + } device = strappend("UUID=", d->uuid); if (!device) @@ -455,7 +458,7 @@ static int add_proc_cmdline_devices(void) { else options = "timeout=0"; - r = create_disk(name, device, arg_default_keyfile, options); + r = create_disk(d->name, device, d->keyfile ?: arg_default_keyfile, options); if (r < 0) return r; }