cryptsetup-generator.c revision d0d6944cdc17295b17875054ac05e667fe496fed
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering This file is part of systemd.
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering Copyright 2010 Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering systemd is free software; you can redistribute it and/or modify it
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering under the terms of the GNU Lesser General Public License as published by
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering (at your option) any later version.
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering systemd is distributed in the hope that it will be useful, but
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering Lesser General Public License for more details.
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering You should have received a copy of the GNU Lesser General Public License
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poetteringstatic bool arg_enabled = true;
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensenstatic bool arg_read_crypttab = true;
a09abc4ae0bdc0200324eaa0416f23ff2170ec4eLennart Poetteringstatic char **arg_proc_cmdline_disks = NULL;
d18d46ecea80a7f07415edb9264af6a254fd70bbZbigniew Jędrzejewski-Szmekstatic bool has_option(const char *haystack, const char *needle) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering const char *f = haystack;
d18d46ecea80a7f07415edb9264af6a254fd70bbZbigniew Jędrzejewski-Szmek if (f[l] != 0 && f[l] != ',') {
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poettering char *p = NULL, *n = NULL, *d = NULL, *u = NULL, *from = NULL, *to = NULL, *e = NULL;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering n = unit_name_from_path_instance("systemd-cryptsetup", name, ".service");
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek log_error("Failed to allocate unit name.");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_error("Failed to allocate unit file name.");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_error("Failed to allocate device node.");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_error("Failed to allocate device name.");
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek log_error("Failed to create unit file: %m");
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek "# Automatically generated by systemd-cryptsetup-generator\n\n"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "Description=Cryptography Setup for %%I\n"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "Documentation=man:systemd-cryptsetup@.service(8)\n"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "SourcePath=/etc/crypttab\n"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "Conflicts=umount.target\n"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "DefaultDependencies=no\n"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "BindTo=%s dev-mapper-%%i.device\n"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "After=systemd-readahead-collect.service systemd-readahead-replay.service %s\n"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "Before=umount.target\n",
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "Before=cryptsetup.target\n");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (password && (streq(password, "/dev/urandom") ||
12a717f8347f3daf0ae46a2b71c7d011d9c12feaZbigniew Jędrzejewski-Szmek streq(password, "/dev/random") ||
92ee6447b1deef7c79962a8121fdf8e58acb3a83Zbigniew Jędrzejewski-Szmek streq(password, "/dev/hw_random")))
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek fputs("After=systemd-random-seed-load.service\n", f);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "\n[Service]\n"
d18d46ecea80a7f07415edb9264af6a254fd70bbZbigniew Jędrzejewski-Szmek "Type=oneshot\n"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "RemainAfterExit=yes\n"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "TimeoutSec=0\n" /* the binary handles timeouts anyway */
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s' '%s' '%s'\n"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n",
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering name, u, strempty(password), strempty(options),
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "ExecStartPost=/sbin/mke2fs '/dev/mapper/%s'\n",
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering "ExecStartPost=/sbin/mkswap '/dev/mapper/%s'\n",
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering to = join(arg_dest, "/", d, ".wants/", n, NULL);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_error("Failed to create symlink '%s' to '%s': %m", from, to);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering to = join(arg_dest, "/cryptsetup.target.requires/", n, NULL);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek to = join(arg_dest, "/cryptsetup.target.wants/", n, NULL);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek log_error("Failed to create symlink '%s' to '%s': %m", from, to);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering to = join(arg_dest, "/dev-mapper-", e, ".device.requires/", n, NULL);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_error("Failed to create symlink '%s' to '%s': %m", from, to);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poetteringstatic int parse_proc_cmdline(void) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering r = read_one_line_file("/proc/cmdline", &line);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek if (startswith(word, "luks=")) {
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek log_warning("Failed to parse luks switch %s. Ignoring.", word + 5);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering } else if (startswith(word, "rd.luks=")) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_warning("Failed to parse luks switch %s. Ignoring.", word + 8);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering } else if (startswith(word, "luks.crypttab=")) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_warning("Failed to parse luks crypttab switch %s. Ignoring.", word + 14);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering } else if (startswith(word, "rd.luks.crypttab=")) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_warning("Failed to parse luks crypttab switch %s. Ignoring.", word + 17);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering } else if (startswith(word, "luks.uuid=")) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering t = strv_append(arg_proc_cmdline_disks, word + 10);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering } else if (startswith(word, "rd.luks.uuid=")) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering t = strv_append(arg_proc_cmdline_disks, word + 13);
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering (in_initrd() && startswith(word, "rd.luks."))) {
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering log_warning("Unknown kernel switch %s. Ignoring.", word);
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering unsigned n = 0;
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering log_error("This program takes three or no arguments.");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering STRV_FOREACH(i, arg_proc_cmdline_disks) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering const char *p = *i;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering if (create_disk(name, device, NULL, NULL) < 0)
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering log_error("Failed to open /etc/crypttab: %m");
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poettering char *name = NULL, *device = NULL, *password = NULL, *options = NULL;
f7a5bb2842037fa27dbc99d92c3fee7fe1bbbc2aZbigniew Jędrzejewski-Szmek if (*l == '#' || *l == 0)
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt k = sscanf(l, "%ms %ms %ms %ms", &name, &device, &password, &options);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering log_error("Failed to parse /etc/crypttab:%u, ignoring.", n);