X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcryptsetup%2Fcryptsetup-generator.c;h=81b770890a170510ad31ff6a5b38e12fb4e66902;hb=2b68185ac97a98bf9d6f31b2ac1fddbaaffaa887;hp=fd2080b539b75fdfd5457819c0bbeec9b25151a4;hpb=68395007f39b326978d7936f203be8fcd24bd222;p=elogind.git diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c index fd2080b53..81b770890 100644 --- a/src/cryptsetup/cryptsetup-generator.c +++ b/src/cryptsetup/cryptsetup-generator.c @@ -70,8 +70,8 @@ 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; + _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; assert(name); @@ -179,7 +179,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 +193,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 +209,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 +233,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 +249,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 +300,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 +328,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 +350,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 +367,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 +411,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 +438,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 +460,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; }