X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fcryptsetup%2Fcryptsetup-generator.c;h=967c5e6e0b373875426e7052e782fd1611a2dc76;hp=fd2080b539b75fdfd5457819c0bbeec9b25151a4;hb=8c11d3c1b5851f05d63198a92833be80616750e9;hpb=68395007f39b326978d7936f203be8fcd24bd222 diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c index fd2080b53..967c5e6e0 100644 --- a/src/cryptsetup/cryptsetup-generator.c +++ b/src/cryptsetup/cryptsetup-generator.c @@ -70,15 +70,22 @@ static int create_disk( const char *password, const char *options) { - char _cleanup_free_ *p = NULL, *n = NULL, *d = NULL, *u = NULL, *from = NULL, *to = NULL, *e = NULL; - FILE _cleanup_fclose_ *f = NULL; - bool noauto, nofail; + _cleanup_free_ char *p = NULL, *n = NULL, *d = NULL, *u = NULL, *from = NULL, *to = NULL, *e = NULL; + _cleanup_fclose_ FILE *f = NULL; + bool noauto, nofail, tmp, swap; assert(name); assert(device); noauto = has_option(options, "noauto"); nofail = has_option(options, "nofail"); + tmp = has_option(options, "tmp"); + swap = has_option(options, "swap"); + + if (tmp && swap) { + log_error("Device '%s' cannot be both 'tmp' and 'swap'. Ignoring.", name); + return -EINVAL; + } n = unit_name_from_path_instance("systemd-cryptsetup", name, ".service"); if (!n) @@ -151,12 +158,12 @@ static int create_disk( name, u, strempty(password), strempty(options), name); - if (has_option(options, "tmp")) + if (tmp) fprintf(f, "ExecStartPost=/sbin/mke2fs '/dev/mapper/%s'\n", name); - if (has_option(options, "swap")) + if (swap) fprintf(f, "ExecStartPost=/sbin/mkswap '/dev/mapper/%s'\n", name); @@ -179,7 +186,7 @@ static int create_disk( mkdir_parents_label(to, 0755); if (symlink(from, to) < 0) { - log_error("Failed to create symlink '%s' to '%s': %m", from, to); + log_error("Failed to create symlink %s: %m", to); return -errno; } @@ -193,7 +200,7 @@ static int create_disk( mkdir_parents_label(to, 0755); if (symlink(from, to) < 0) { - log_error("Failed to create symlink '%s' to '%s': %m", from, to); + log_error("Failed to create symlink %s: %m", to); return -errno; } } @@ -209,7 +216,7 @@ static int create_disk( mkdir_parents_label(to, 0755); if (symlink(from, to) < 0) { - log_error("Failed to create symlink '%s' to '%s': %m", from, to); + log_error("Failed to create symlink %s: %m", to); return -errno; } @@ -233,8 +240,8 @@ static int create_disk( return 0; } -static int parse_proc_cmdline(char ***arg_proc_cmdline_disks) { - char _cleanup_free_ *line = NULL; +static int parse_proc_cmdline(char ***arg_proc_cmdline_disks, char **arg_proc_cmdline_keyfile) { + _cleanup_free_ char *line = NULL; char *w = NULL, *state = NULL; int r; size_t l; @@ -249,7 +256,7 @@ static int parse_proc_cmdline(char ***arg_proc_cmdline_disks) { } FOREACH_WORD_QUOTED(w, l, line, state) { - char _cleanup_free_ *word = NULL; + _cleanup_free_ char *word = NULL; word = strndup(w, l); if (!word) @@ -300,6 +307,21 @@ static int parse_proc_cmdline(char ***arg_proc_cmdline_disks) { return log_oom(); } + } else if (startswith(word, "luks.key=")) { + *arg_proc_cmdline_keyfile = strdup(word + 9); + if (!*arg_proc_cmdline_keyfile) + return log_oom(); + + } else if (startswith(word, "rd.luks.key=")) { + + if (in_initrd()) { + if (*arg_proc_cmdline_keyfile) + free(*arg_proc_cmdline_keyfile); + *arg_proc_cmdline_keyfile = strdup(word + 12); + if (!*arg_proc_cmdline_keyfile) + return log_oom(); + } + } else if (startswith(word, "luks.") || (in_initrd() && startswith(word, "rd.luks."))) { @@ -313,12 +335,13 @@ static int parse_proc_cmdline(char ***arg_proc_cmdline_disks) { } int main(int argc, char *argv[]) { - FILE _cleanup_fclose_ *f = NULL; + _cleanup_strv_free_ char **arg_proc_cmdline_disks_done = NULL; + _cleanup_strv_free_ char **arg_proc_cmdline_disks = NULL; + _cleanup_free_ char *arg_proc_cmdline_keyfile = NULL; + _cleanup_fclose_ FILE *f = NULL; unsigned n = 0; int r = EXIT_SUCCESS; char **i; - char _cleanup_strv_free_ **arg_proc_cmdline_disks_done = NULL; - char _cleanup_strv_free_ **arg_proc_cmdline_disks = NULL; if (argc > 1 && argc != 4) { log_error("This program takes three or no arguments."); @@ -334,15 +357,16 @@ int main(int argc, char *argv[]) { umask(0022); - if (parse_proc_cmdline(&arg_proc_cmdline_disks) < 0) + if (parse_proc_cmdline(&arg_proc_cmdline_disks, &arg_proc_cmdline_keyfile) < 0) return EXIT_FAILURE; if (!arg_enabled) return EXIT_SUCCESS; if (arg_read_crypttab) { - f = fopen("/etc/crypttab", "re"); + struct stat st; + f = fopen("/etc/crypttab", "re"); if (!f) { if (errno == ENOENT) r = EXIT_SUCCESS; @@ -350,9 +374,26 @@ int main(int argc, char *argv[]) { r = EXIT_FAILURE; log_error("Failed to open /etc/crypttab: %m"); } - } else for (;;) { + + goto next; + } + + if (fstat(fileno(f), &st) < 0) { + log_error("Failed to stat /etc/crypttab: %m"); + r = EXIT_FAILURE; + goto next; + } + + /* If we readd support for specifying passphrases + * directly in crypttabe we should upgrade the warning + * below, though possibly only if a passphrase is + * specified directly. */ + if (st.st_mode & 0005) + log_debug("/etc/crypttab is world-readable. This is usually not a good idea."); + + for (;;) { char line[LINE_MAX], *l; - char _cleanup_free_ *name = NULL, *device = NULL, *password = NULL, *options = NULL; + _cleanup_free_ char *name = NULL, *device = NULL, *password = NULL, *options = NULL; int k; if (!fgets(line, sizeof(line), f)) @@ -377,7 +418,7 @@ int main(int argc, char *argv[]) { for /etc/crypttab and only generate units for those. */ STRV_FOREACH(i, arg_proc_cmdline_disks) { - char _cleanup_free_ *proc_device = NULL, *proc_name = NULL; + _cleanup_free_ char *proc_device = NULL, *proc_name = NULL; const char *p = *i; if (startswith(p, "luks-")) @@ -404,13 +445,14 @@ int main(int argc, char *argv[]) { } } +next: STRV_FOREACH(i, arg_proc_cmdline_disks) { /* Generate units for those UUIDs, which were specified on the kernel command line and not yet written. */ - char _cleanup_free_ *name = NULL, *device = NULL; + _cleanup_free_ char *name = NULL, *device = NULL; const char *p = *i; if (startswith(p, "luks-")) @@ -425,7 +467,7 @@ int main(int argc, char *argv[]) { if (!name || !device) return log_oom(); - if (create_disk(name, device, NULL, "timeout=0") < 0) + if (create_disk(name, device, arg_proc_cmdline_keyfile, "timeout=0") < 0) r = EXIT_FAILURE; }