From 38e3c61dbb1ad69e7df910d07fa8b47f3d97f660 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 22 Sep 2023 17:55:39 +0200 Subject: [PATCH 01/11] man/cryptenroll: link to crypttab(5) for examples I was missing an example of how to use cryptenroll. We have that, but in another page. Instead of repeating, let's just direct the user to the right place. Also, reformat synopsis to the "official" non-nested syntax. --- man/systemd-cryptenroll.xml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/man/systemd-cryptenroll.xml b/man/systemd-cryptenroll.xml index 27b072cbdb..cd01791acf 100644 --- a/man/systemd-cryptenroll.xml +++ b/man/systemd-cryptenroll.xml @@ -22,7 +22,9 @@ - systemd-cryptenroll OPTIONS DEVICE + systemd-cryptenroll + OPTIONS + DEVICE @@ -545,6 +547,14 @@ On success, 0 is returned, a non-zero failure code otherwise. + + Examples + + crypttab5 and + systemd-measure1 + contain various examples employing systemd-cryptenroll. + + See Also From 12c346d8e82dbe9a97a4666b1f9e2771bb54207c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 22 Sep 2023 18:27:10 +0200 Subject: [PATCH 02/11] man/crypttab: do not recommend using /dev/sdX symlinks in /etc/crypttab This is just wrong. Quering the symlink names with udevadm is not the easiest, but I think that's the safest way for a documented example. --- TODO | 4 ++++ man/fido2-crypttab.sh | 16 ++++++++++------ man/tpm2-crypttab.sh | 16 ++++++++++------ man/yubikey-crypttab.sh | 16 ++++++++++------ 4 files changed, 34 insertions(+), 18 deletions(-) diff --git a/TODO b/TODO index 8cff6379af..a47698f587 100644 --- a/TODO +++ b/TODO @@ -386,6 +386,10 @@ Features: * udevd: extend memory pressure logic: also kill any idle worker processes +* udevadm: to make symlink querying with udevadm nicer: + - do not enable the pager for queries like 'udevadm info -q -r symlink' + - add mode with newlines instead of spaces (for grep)? + * SIGRTMIN+18 and memory pressure handling should still be added to: hostnamed, localed, oomd, timedated. diff --git a/man/fido2-crypttab.sh b/man/fido2-crypttab.sh index fe7351520a..c29c0245f4 100644 --- a/man/fido2-crypttab.sh +++ b/man/fido2-crypttab.sh @@ -8,13 +8,17 @@ sudo systemd-cryptenroll --fido2-device=auto /dev/sdXn sudo /usr/lib/systemd/systemd-cryptsetup attach mytest /dev/sdXn - fido2-device=auto # If that worked, let's now add the same line persistently to /etc/crypttab, -# for the future. -sudo bash -c 'echo "mytest /dev/sdXn - fido2-device=auto" >>/etc/crypttab' +# for the future. We don't want to use the (unstable) /dev/sdX name, so let's +# figure out a stable link: +udevadm info -q -r symlink /dev/sdXn -# Depending on your distribution and encryption setup, you may need -# to manually regenerate your initramfs to be able to use -# a FIDO2-Device to unlock the partition during early boot. -# More information at https://unix.stackexchange.com/a/705809 +# Now add the line using the by-uuid symlink to /etc/crypttab: +sudo bash -c 'echo "mytest /dev/disk/by-uuid/... - fido2-device=auto" >>/etc/crypttab' + +# Depending on your distribution and encryption setup, you may need to manually +# regenerate your initramfs to be able to use a FIDO2 device to unlock the +# partition during early boot. +# More information at https://unix.stackexchange.com/a/705809. # On Fedora based systems: sudo dracut --force # On Debian based systems: diff --git a/man/tpm2-crypttab.sh b/man/tpm2-crypttab.sh index f5f6e3a43d..1b7074a0de 100644 --- a/man/tpm2-crypttab.sh +++ b/man/tpm2-crypttab.sh @@ -8,13 +8,17 @@ sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7 /dev/sdXn sudo /usr/lib/systemd/systemd-cryptsetup attach mytest /dev/sdXn - tpm2-device=auto # If that worked, let's now add the same line persistently to /etc/crypttab, -# for the future. -sudo bash -c 'echo "mytest /dev/sdXn - tpm2-device=auto" >>/etc/crypttab' +# for the future. We don't want to use the (unstable) /dev/sdX name, so let's +# figure out a stable link: +udevadm info -q -r symlink /dev/sdXn -# Depending on your distribution and encryption setup, you may need -# to manually regenerate your initramfs to be able to use -# a TPM2 security chip to unlock the partition during early boot. -# More information at https://unix.stackexchange.com/a/705809 +# Now add the line using the by-uuid symlink to /etc/crypttab: +sudo bash -c 'echo "mytest /dev/disk/by-uuid/... - tpm2-device=auto" >>/etc/crypttab' + +# Depending on your distribution and encryption setup, you may need to manually +# regenerate your initramfs to be able to use a TPM2 security chip to unlock +# the partition during early boot. +# More information at https://unix.stackexchange.com/a/705809. # On Fedora based systems: sudo dracut --force # On Debian based systems: diff --git a/man/yubikey-crypttab.sh b/man/yubikey-crypttab.sh index f50a349631..d355afbd1b 100644 --- a/man/yubikey-crypttab.sh +++ b/man/yubikey-crypttab.sh @@ -24,13 +24,17 @@ sudo systemd-cryptenroll --pkcs11-token-uri=auto /dev/sdXn sudo /usr/lib/systemd/systemd-cryptsetup attach mytest /dev/sdXn - pkcs11-uri=auto # If that worked, let's now add the same line persistently to /etc/crypttab, -# for the future. -sudo bash -c 'echo "mytest /dev/sdXn - pkcs11-uri=auto" >>/etc/crypttab' +# for the future. We don't want to use the (unstable) /dev/sdX name, so let's +# figure out a stable link: +udevadm info -q -r symlink /dev/sdXn -# Depending on your distribution and encryption setup, you may need -# to manually regenerate your initramfs to be able to use a -# Yubikey / PKCS#11 Token to unlock the partition during early boot. -# More information at https://unix.stackexchange.com/a/705809 +# Now add the line using the by-uuid symlink to /etc/crypttab: +sudo bash -c 'echo "mytest /dev/disk/by-uuid/... - pkcs11-uri=auto" >>/etc/crypttab' + +# Depending on your distribution and encryption setup, you may need to manually +# regenerate your initramfs to be able to use a Yubikey / PKCS#11 token to +# unlock the partition during early boot. +# More information at https://unix.stackexchange.com/a/705809. # On Fedora based systems: sudo dracut --force # On Debian based systems: From 4381474f7f77af2eb1ce8b5c37165c8aeb1a6419 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 22 Sep 2023 18:37:49 +0200 Subject: [PATCH 03/11] man/crypttab: add a more comprehensive example of encrypted device setup --- man/tpm2-crypttab.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/man/tpm2-crypttab.sh b/man/tpm2-crypttab.sh index 1b7074a0de..b457fc2306 100644 --- a/man/tpm2-crypttab.sh +++ b/man/tpm2-crypttab.sh @@ -15,6 +15,22 @@ udevadm info -q -r symlink /dev/sdXn # Now add the line using the by-uuid symlink to /etc/crypttab: sudo bash -c 'echo "mytest /dev/disk/by-uuid/... - tpm2-device=auto" >>/etc/crypttab' +# And now let's check that automatic unlocking works: +sudo /usr/lib/systemd/systemd-cryptsetup detach mytest +sudo systemctl daemon-reload +sudo systemctl start cryptsetup.target +systemctl is-active systemd-cryptsetup@mytest.service + +# Once we have the device which will be unlocked automatically, we can use it. +# Usually we would create a file system and add it to /etc/fstab: +sudo mkfs.ext4 /dev/mapper/mytest +# This prints a 'Filesystem UUID', which we can use as a stable name: +sudo bash -c 'echo "/dev/disk/by-uuid/... /var/mytest ext4 defaults,x-systemd.mkdir 0 2" >>/etc/fstab' +# And now let's check that the mounting works: +sudo systemctl daemon-reload +sudo systemctl start /var/mytest +systemctl status /var/mytest + # Depending on your distribution and encryption setup, you may need to manually # regenerate your initramfs to be able to use a TPM2 security chip to unlock # the partition during early boot. From 5f5f1ba169b12cb342fb939a02bd8336eb9be69e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 22 Sep 2023 18:37:55 +0200 Subject: [PATCH 04/11] man/crypttab: fix indentation --- man/crypttab.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/man/crypttab.xml b/man/crypttab.xml index f90217da10..3e003156d2 100644 --- a/man/crypttab.xml +++ b/man/crypttab.xml @@ -957,7 +957,7 @@ external /dev/sda3 keyfile:LABEL=keydev keyfile-timeout=10s,cipher=xchac systemd-cryptenroll1 to add it in the LUKS2 volume: - + A few notes on the above: @@ -977,7 +977,7 @@ external /dev/sda3 keyfile:LABEL=keydev keyfile-timeout=10s,cipher=xchac set up a FIDO2 security token for this purpose for a LUKS2 volume, using systemd-cryptenroll1: - + @@ -988,7 +988,7 @@ external /dev/sda3 keyfile:LABEL=keydev keyfile-timeout=10s,cipher=xchac using systemd-cryptenroll1: - + From 4cc8e81db535cbf576b45aabb77521bf2c6ef60e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 22 Sep 2023 20:36:44 +0200 Subject: [PATCH 05/11] cryptenroll: align tables --- src/cryptenroll/cryptenroll.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/cryptenroll/cryptenroll.c b/src/cryptenroll/cryptenroll.c index 1ffa2fb5f2..45a058f426 100644 --- a/src/cryptenroll/cryptenroll.c +++ b/src/cryptenroll/cryptenroll.c @@ -78,9 +78,9 @@ static bool wipe_requested(void) { static const char* const enroll_type_table[_ENROLL_TYPE_MAX] = { [ENROLL_PASSWORD] = "password", [ENROLL_RECOVERY] = "recovery", - [ENROLL_PKCS11] = "pkcs11", - [ENROLL_FIDO2] = "fido2", - [ENROLL_TPM2] = "tpm2", + [ENROLL_PKCS11] = "pkcs11", + [ENROLL_FIDO2] = "fido2", + [ENROLL_TPM2] = "tpm2", }; DEFINE_STRING_TABLE_LOOKUP(enroll_type, EnrollType); @@ -88,9 +88,9 @@ DEFINE_STRING_TABLE_LOOKUP(enroll_type, EnrollType); static const char *const luks2_token_type_table[_ENROLL_TYPE_MAX] = { /* ENROLL_PASSWORD has no entry here, as slots of this type do not have a token in the LUKS2 header */ [ENROLL_RECOVERY] = "systemd-recovery", - [ENROLL_PKCS11] = "systemd-pkcs11", - [ENROLL_FIDO2] = "systemd-fido2", - [ENROLL_TPM2] = "systemd-tpm2", + [ENROLL_PKCS11] = "systemd-pkcs11", + [ENROLL_FIDO2] = "systemd-fido2", + [ENROLL_TPM2] = "systemd-tpm2", }; DEFINE_STRING_TABLE_LOOKUP(luks2_token_type, EnrollType); @@ -150,7 +150,6 @@ static int help(void) { } static int parse_argv(int argc, char *argv[]) { - enum { ARG_VERSION = 0x100, ARG_PASSWORD, From 166015faf585bceadd39770368ae4dbdb6a49e57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 23 Sep 2023 11:56:13 +0200 Subject: [PATCH 06/11] cryptsetup: add parse_argv() and implement --version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All public programs are expected to have that. The --help output is adjusted to follow the usual style (highlighting, listing of options). The OPTIONS positional argument is renamed to "CONFIG", because we now also have "OPTIONS…" to describe the non-positional options. --- src/cryptsetup/cryptsetup.c | 99 ++++++++++++++++++++++++++----------- 1 file changed, 69 insertions(+), 30 deletions(-) diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c index 4fb5fe89ef..5e283a7dd0 100644 --- a/src/cryptsetup/cryptsetup.c +++ b/src/cryptsetup/cryptsetup.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include +#include #include #include #include @@ -12,6 +13,7 @@ #include "alloc-util.h" #include "ask-password-api.h" +#include "build.h" #include "cryptsetup-fido2.h" #include "cryptsetup-keyfile.h" #include "cryptsetup-pkcs11.h" @@ -127,7 +129,6 @@ PassphraseType passphrase_type_from_string(const char *s); DEFINE_STRING_TABLE_LOOKUP(passphrase_type, PassphraseType); /* Options Debian's crypttab knows we don't: - check= checkargs= noearly @@ -501,7 +502,7 @@ static int parse_one_option(const char *option) { return 0; } -static int parse_options(const char *options) { +static int parse_crypt_config(const char *options) { assert(options); for (;;) { @@ -2025,21 +2026,62 @@ static int help(void) { _cleanup_free_ char *link = NULL; int r; - r = terminal_urlify_man("systemd-cryptsetup@.service", "8", &link); + r = terminal_urlify_man("systemd-cryptsetup", "8", &link); if (r < 0) return log_oom(); - printf("%s attach VOLUME SOURCEDEVICE [KEY-FILE] [OPTIONS]\n" - "%s detach VOLUME\n\n" - "Attaches or detaches an encrypted block device.\n" - "\nSee the %s for details.\n", - program_invocation_short_name, + printf("%1$s attach VOLUME SOURCE-DEVICE [KEY-FILE] [CONFIG]\n" + "%1$s detach VOLUME\n\n" + "%2$sAttach or detach an encrypted block device.%3$s\n\n" + " -h --help Show this help\n" + " --version Show package version\n" + "\nSee the %4$s for details.\n", program_invocation_short_name, + ansi_highlight(), + ansi_normal(), link); return 0; } +static int parse_argv(int argc, char *argv[]) { + enum { + ARG_VERSION = 0x100, + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + {} + }; + + int c; + + assert(argc >= 0); + assert(argv); + + if (argv_looks_like_help(argc, argv)) + return help(); + + while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) + switch (c) { + + case 'h': + return help(); + + case ARG_VERSION: + return version(); + + case '?': + return -EINVAL; + + default: + assert_not_reached(); + } + + return 1; +} + static uint32_t determine_flags(void) { uint32_t flags = 0; @@ -2086,25 +2128,24 @@ static int run(int argc, char *argv[]) { const char *verb; int r; - if (argv_looks_like_help(argc, argv)) - return help(); - - if (argc < 3) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "This program requires at least two arguments."); - log_setup(); - cryptsetup_enable_logging(NULL); - umask(0022); - verb = argv[1]; + r = parse_argv(argc, argv); + if (r <= 0) + return r; + + cryptsetup_enable_logging(NULL); + + if (argc - optind < 2) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "This program requires at least two arguments."); + verb = ASSERT_PTR(argv[optind]); if (streq(verb, "attach")) { _unused_ _cleanup_(remove_and_erasep) const char *destroy_key_file = NULL; _cleanup_(erase_and_freep) void *key_data = NULL; - const char *volume, *source, *key_file, *options; crypt_status_info status; size_t key_data_size = 0; uint32_t flags = 0; @@ -2112,15 +2153,15 @@ static int run(int argc, char *argv[]) { usec_t until; PassphraseType passphrase_type = PASSPHRASE_NONE; - /* Arguments: systemd-cryptsetup attach VOLUME SOURCE-DEVICE [KEY-FILE] [OPTIONS] */ + /* Arguments: systemd-cryptsetup attach VOLUME SOURCE-DEVICE [KEY-FILE] [CONFIG] */ - if (argc < 4) + if (argc - optind < 3) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "attach requires at least two arguments."); - volume = argv[2]; - source = argv[3]; - key_file = mangle_none(argc >= 5 ? argv[4] : NULL); - options = mangle_none(argc >= 6 ? argv[5] : NULL); + const char *volume = ASSERT_PTR(argv[optind + 1]), + *source = ASSERT_PTR(argv[optind + 2]), + *key_file = argc - optind >= 4 ? mangle_none(argv[optind + 3]) : NULL, + *config = argc - optind >= 5 ? mangle_none(argv[optind + 4]) : NULL; if (!filename_is_valid(volume)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Volume name '%s' is not valid.", volume); @@ -2130,8 +2171,8 @@ static int run(int argc, char *argv[]) { key_file = NULL; } - if (options) { - r = parse_options(options); + if (config) { + r = parse_crypt_config(config); if (r < 0) return r; } @@ -2313,9 +2354,7 @@ static int run(int argc, char *argv[]) { return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Too many attempts to activate; giving up."); } else if (streq(verb, "detach")) { - const char *volume; - - volume = argv[2]; + const char *volume = ASSERT_PTR(argv[optind + 1]); if (!filename_is_valid(volume)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Volume name '%s' is not valid.", volume); From 5bae80bd44521084da8aba2512b1b3f22e5e10df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 23 Sep 2023 11:59:55 +0200 Subject: [PATCH 07/11] cryptsetup: fail with error if extraneous arguments are specified MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So far the program would silently ignore those… I think it's better to fail. --- src/cryptsetup/cryptsetup.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c index 5e283a7dd0..a7577d8113 100644 --- a/src/cryptsetup/cryptsetup.c +++ b/src/cryptsetup/cryptsetup.c @@ -2157,6 +2157,8 @@ static int run(int argc, char *argv[]) { if (argc - optind < 3) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "attach requires at least two arguments."); + if (argc - optind >= 6) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "attach does not accept more than four arguments."); const char *volume = ASSERT_PTR(argv[optind + 1]), *source = ASSERT_PTR(argv[optind + 2]), @@ -2356,6 +2358,9 @@ static int run(int argc, char *argv[]) { } else if (streq(verb, "detach")) { const char *volume = ASSERT_PTR(argv[optind + 1]); + if (argc - optind >= 3) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "attach does not accept more than one argument."); + if (!filename_is_valid(volume)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Volume name '%s' is not valid.", volume); From fb8d67cd3481c21ce45b17eb4fb52a54cafc0944 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 22 Sep 2023 18:47:05 +0200 Subject: [PATCH 08/11] meson: move systemd-cryptsetup to /usr/bin This was requested, though I think an issue was never filed. If people are supposed to invoke it, even for testing, then it's reasonable to make it "public". --- man/fido2-crypttab.sh | 2 +- man/systemd-cryptsetup@.service.xml | 2 +- man/systemd-measure.xml | 2 +- man/tpm2-crypttab.sh | 4 ++-- man/yubikey-crypttab.sh | 2 +- meson.build | 2 +- src/cryptsetup/meson.build | 10 +++++++++- 7 files changed, 16 insertions(+), 8 deletions(-) diff --git a/man/fido2-crypttab.sh b/man/fido2-crypttab.sh index c29c0245f4..43654a5236 100644 --- a/man/fido2-crypttab.sh +++ b/man/fido2-crypttab.sh @@ -5,7 +5,7 @@ sudo systemd-cryptenroll --fido2-device=auto /dev/sdXn # Test: Let's run systemd-cryptsetup to test if this worked. -sudo /usr/lib/systemd/systemd-cryptsetup attach mytest /dev/sdXn - fido2-device=auto +sudo systemd-cryptsetup attach mytest /dev/sdXn - fido2-device=auto # If that worked, let's now add the same line persistently to /etc/crypttab, # for the future. We don't want to use the (unstable) /dev/sdX name, so let's diff --git a/man/systemd-cryptsetup@.service.xml b/man/systemd-cryptsetup@.service.xml index 1697ccc0f3..91a4f2eb9d 100644 --- a/man/systemd-cryptsetup@.service.xml +++ b/man/systemd-cryptsetup@.service.xml @@ -27,7 +27,7 @@ systemd-cryptsetup@.service system-systemd\x2dcryptsetup.slice - /usr/lib/systemd/systemd-cryptsetup + systemd-cryptsetup diff --git a/man/systemd-measure.xml b/man/systemd-measure.xml index 3568fb5435..4d5595e721 100644 --- a/man/systemd-measure.xml +++ b/man/systemd-measure.xml @@ -294,7 +294,7 @@ $ openssl rsa -pubout -in tpm2-pcr-private.pem -out tpm2-pcr-public.pem And then unlock the device with the signature: - # /usr/lib/systemd/systemd-cryptsetup attach \ + # systemd-cryptsetup attach \ volume5 /dev/sda5 - \ tpm2-device=auto,tpm2-signature=/path/to/tpm2-pcr-signature.json diff --git a/man/tpm2-crypttab.sh b/man/tpm2-crypttab.sh index b457fc2306..2be349959f 100644 --- a/man/tpm2-crypttab.sh +++ b/man/tpm2-crypttab.sh @@ -5,7 +5,7 @@ sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7 /dev/sdXn # Test: Let's run systemd-cryptsetup to test if this worked. -sudo /usr/lib/systemd/systemd-cryptsetup attach mytest /dev/sdXn - tpm2-device=auto +sudo systemd-cryptsetup attach mytest /dev/sdXn - tpm2-device=auto # If that worked, let's now add the same line persistently to /etc/crypttab, # for the future. We don't want to use the (unstable) /dev/sdX name, so let's @@ -16,7 +16,7 @@ udevadm info -q -r symlink /dev/sdXn sudo bash -c 'echo "mytest /dev/disk/by-uuid/... - tpm2-device=auto" >>/etc/crypttab' # And now let's check that automatic unlocking works: -sudo /usr/lib/systemd/systemd-cryptsetup detach mytest +sudo systemd-cryptsetup detach mytest sudo systemctl daemon-reload sudo systemctl start cryptsetup.target systemctl is-active systemd-cryptsetup@mytest.service diff --git a/man/yubikey-crypttab.sh b/man/yubikey-crypttab.sh index d355afbd1b..a66a88fe1c 100644 --- a/man/yubikey-crypttab.sh +++ b/man/yubikey-crypttab.sh @@ -21,7 +21,7 @@ rm pubkey.pem sudo systemd-cryptenroll --pkcs11-token-uri=auto /dev/sdXn # Test: Let's run systemd-cryptsetup to test if this all worked. -sudo /usr/lib/systemd/systemd-cryptsetup attach mytest /dev/sdXn - pkcs11-uri=auto +sudo systemd-cryptsetup attach mytest /dev/sdXn - pkcs11-uri=auto # If that worked, let's now add the same line persistently to /etc/crypttab, # for the future. We don't want to use the (unstable) /dev/sdX name, so let's diff --git a/meson.build b/meson.build index bf25bcba43..df506b7873 100644 --- a/meson.build +++ b/meson.build @@ -226,7 +226,7 @@ conf.set_quoted('SYSTEMCTL_BINARY_PATH', bindir / 'systemct conf.set_quoted('SYSTEMD_BINARY_PATH', libexecdir / 'systemd') conf.set_quoted('SYSTEMD_CATALOG_DIR', catalogdir) conf.set_quoted('SYSTEMD_CGROUPS_AGENT_PATH', libexecdir / 'systemd-cgroups-agent') -conf.set_quoted('SYSTEMD_CRYPTSETUP_PATH', libexecdir / 'systemd-cryptsetup') +conf.set_quoted('SYSTEMD_CRYPTSETUP_PATH', bindir / 'systemd-cryptsetup') conf.set_quoted('SYSTEMD_EXPORT_PATH', libexecdir / 'systemd-export') conf.set_quoted('SYSTEMD_FSCK_PATH', libexecdir / 'systemd-fsck') conf.set_quoted('SYSTEMD_GROWFS_PATH', libexecdir / 'systemd-growfs') diff --git a/src/cryptsetup/meson.build b/src/cryptsetup/meson.build index 6f7aa3c796..e034cb7d24 100644 --- a/src/cryptsetup/meson.build +++ b/src/cryptsetup/meson.build @@ -16,8 +16,9 @@ if conf.get('HAVE_TPM2') == 1 endif executables += [ - libexec_template + { + executable_template + { 'name' : 'systemd-cryptsetup', + 'public' : true, 'conditions' : ['HAVE_LIBCRYPTSETUP'], 'sources' : systemd_cryptsetup_sources, 'dependencies' : [ @@ -32,3 +33,10 @@ executables += [ 'sources' : files('cryptsetup-generator.c'), }, ] + +if conf.get('HAVE_LIBCRYPTSETUP') == 1 + # symlink for backwards compatibility after rename + meson.add_install_script(sh, '-c', + ln_s.format(bindir / 'systemd-cryptsetup', + libexecdir / 'systemd-cryptsetup')) +endif From a1ca52c2daf9d5f6f6922a627793dc2cbd0ad20c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 26 Sep 2023 17:03:15 +0200 Subject: [PATCH 09/11] meson: add comments to compat symlinks --- meson.build | 1 + src/resolve/meson.build | 1 + 2 files changed, 2 insertions(+) diff --git a/meson.build b/meson.build index df506b7873..3d161bc996 100644 --- a/meson.build +++ b/meson.build @@ -2416,6 +2416,7 @@ ukify = custom_target( if want_ukify public_programs += ukify + # symlink for backwards compatibility after rename meson.add_install_script(sh, '-c', ln_s.format(bindir / 'ukify', libexecdir / 'ukify')) diff --git a/src/resolve/meson.build b/src/resolve/meson.build index 0f62d09087..2c34dc5032 100644 --- a/src/resolve/meson.build +++ b/src/resolve/meson.build @@ -225,6 +225,7 @@ if conf.get('ENABLE_RESOLVE') == 1 ln_s.format(bindir / 'resolvectl', sbindir / 'resolvconf')) + # symlink for backwards compatibility after rename meson.add_install_script(sh, '-c', ln_s.format(bindir / 'resolvectl', bindir / 'systemd-resolve')) From ab68c6fb08d8112530f58dbca3bf0622922c7234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 22 Sep 2023 18:50:37 +0200 Subject: [PATCH 10/11] TEST-70: use new cryptsetup path --- test/units/testsuite-70.sh | 71 +++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 36 deletions(-) diff --git a/test/units/testsuite-70.sh b/test/units/testsuite-70.sh index 6480c46bf8..1fe47ae748 100755 --- a/test/units/testsuite-70.sh +++ b/test/units/testsuite-70.sh @@ -3,7 +3,6 @@ set -ex set -o pipefail -SD_CRYPTSETUP="/usr/lib/systemd/systemd-cryptsetup" SD_MEASURE="/usr/lib/systemd/systemd-measure" SD_PCRPHASE="/usr/lib/systemd/systemd-pcrphase" export SYSTEMD_LOG_LEVEL=debug @@ -29,10 +28,10 @@ tpm_check_failure_with_wrong_pin() { # We need to be careful not to trigger DA lockout; allow 2 failures tpm2_dictionarylockout -s -n 2 - (! PIN=$badpin "$SD_CRYPTSETUP" attach test-volume "$testimg" - tpm2-device=auto,headless=1) + (! PIN=$badpin systemd-cryptsetup attach test-volume "$testimg" - tpm2-device=auto,headless=1) # Verify the correct PIN works, to be sure the failure wasn't a DA lockout - PIN=$goodpin "$SD_CRYPTSETUP" attach test-volume "$testimg" - tpm2-device=auto,headless=1 - "$SD_CRYPTSETUP" detach test-volume + PIN=$goodpin systemd-cryptsetup attach test-volume "$testimg" - tpm2-device=auto,headless=1 + systemd-cryptsetup detach test-volume # Clear/reset the DA lockout counter tpm2_dictionarylockout -c } @@ -50,18 +49,18 @@ systemd-cryptenroll --unlock-key-file=/tmp/passphrase --tpm2-device=auto "$img" # Enroll unlock with default PCR policy PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto "$img" -"$SD_CRYPTSETUP" attach test-volume "$img" - tpm2-device=auto,headless=1 -"$SD_CRYPTSETUP" detach test-volume +systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1 +systemd-cryptsetup detach test-volume # Check with wrong PCR tpm2_pcrextend 7:sha256=0000000000000000000000000000000000000000000000000000000000000000 -(! "$SD_CRYPTSETUP" attach test-volume "$img" - tpm2-device=auto,headless=1) +(! systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1) # Enroll unlock with PCR+PIN policy systemd-cryptenroll --wipe-slot=tpm2 "$img" PASSWORD=passphrase NEWPIN=123456 systemd-cryptenroll --tpm2-device=auto --tpm2-with-pin=true "$img" -PIN=123456 "$SD_CRYPTSETUP" attach test-volume "$img" - tpm2-device=auto,headless=1 -"$SD_CRYPTSETUP" detach test-volume +PIN=123456 systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1 +systemd-cryptsetup detach test-volume # Check failure with wrong PIN; try a few times to make sure we avoid DA lockout for _ in {0..3}; do @@ -70,8 +69,8 @@ done # Check LUKS2 token plugin unlock (i.e. without specifying tpm2-device=auto) if cryptsetup_has_token_plugin_support; then - PIN=123456 "$SD_CRYPTSETUP" attach test-volume "$img" - headless=1 - "$SD_CRYPTSETUP" detach test-volume + PIN=123456 systemd-cryptsetup attach test-volume "$img" - headless=1 + systemd-cryptsetup detach test-volume # Check failure with wrong PIN for _ in {0..3}; do @@ -83,39 +82,39 @@ fi # Check failure with wrong PCR (and correct PIN) tpm2_pcrextend 7:sha256=0000000000000000000000000000000000000000000000000000000000000000 -(! PIN=123456 "$SD_CRYPTSETUP" attach test-volume "$img" - tpm2-device=auto,headless=1) +(! PIN=123456 systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1) # Enroll unlock with PCR 0+7 systemd-cryptenroll --wipe-slot=tpm2 "$img" PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7 "$img" -"$SD_CRYPTSETUP" attach test-volume "$img" - tpm2-device=auto,headless=1 -"$SD_CRYPTSETUP" detach test-volume +systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1 +systemd-cryptsetup detach test-volume # Check with wrong PCR 0 tpm2_pcrextend 0:sha256=0000000000000000000000000000000000000000000000000000000000000000 -(! "$SD_CRYPTSETUP" attach test-volume "$img" - tpm2-device=auto,headless=1) +(! systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1) if tpm_has_pcr sha256 12; then # Enroll using an explict PCR value (that does match current PCR value) systemd-cryptenroll --wipe-slot=tpm2 "$img" EXPECTED_PCR_VALUE=$(cat /sys/class/tpm/tpm0/pcr-sha256/12) PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs="12:sha256=$EXPECTED_PCR_VALUE" "$img" - "$SD_CRYPTSETUP" attach test-volume "$img" - tpm2-device=auto,headless=1 - "$SD_CRYPTSETUP" detach test-volume + systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1 + systemd-cryptsetup detach test-volume # Same as above plus more PCRs without the value or alg specified systemd-cryptenroll --wipe-slot=tpm2 "$img" EXPECTED_PCR_VALUE=$(cat /sys/class/tpm/tpm0/pcr-sha256/12) PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs="1,12:sha256=$EXPECTED_PCR_VALUE,3" "$img" - "$SD_CRYPTSETUP" attach test-volume "$img" - tpm2-device=auto,headless=1 - "$SD_CRYPTSETUP" detach test-volume + systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1 + systemd-cryptsetup detach test-volume # Same as above plus more PCRs with hash alg specified but hash value not specified systemd-cryptenroll --wipe-slot=tpm2 "$img" EXPECTED_PCR_VALUE=$(cat /sys/class/tpm/tpm0/pcr-sha256/12) PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs="1:sha256,12:sha256=$EXPECTED_PCR_VALUE,3" "$img" - "$SD_CRYPTSETUP" attach test-volume "$img" - tpm2-device=auto,headless=1 - "$SD_CRYPTSETUP" detach test-volume + systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1 + systemd-cryptsetup detach test-volume # Now the interesting part, enrolling using a hash value that doesn't match the current PCR value systemd-cryptenroll --wipe-slot=tpm2 "$img" @@ -123,10 +122,10 @@ if tpm_has_pcr sha256 12; then CURRENT_PCR_VALUE=$(cat /sys/class/tpm/tpm0/pcr-sha256/12) EXPECTED_PCR_VALUE=$(cat /tmp/pcr.dat /tmp/pcr.dat | openssl dgst -sha256 -r | cut -d ' ' -f 1) PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs="12:sha256=$EXPECTED_PCR_VALUE" "$img" - (! "$SD_CRYPTSETUP" attach test-volume "$img" - tpm2-device=auto,headless=1) + (! systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1) tpm2_pcrextend "12:sha256=$CURRENT_PCR_VALUE" - "$SD_CRYPTSETUP" attach test-volume "$img" - tpm2-device=auto,headless=1 - "$SD_CRYPTSETUP" detach test-volume + systemd-cryptsetup attach test-volume "$img" - tpm2-device=auto,headless=1 + systemd-cryptsetup detach test-volume rm -f /tmp/pcr.dat fi @@ -208,24 +207,24 @@ if [[ -x "$SD_MEASURE" ]] && tpm_has_pcr sha1 11 && tpm_has_pcr sha256 11; then systemd-cryptenroll --unlock-key-file=/tmp/passphrase --tpm2-device=auto --tpm2-public-key="/tmp/pcrsign-public.pem" --tpm2-signature="/tmp/pcrsign.sig2" "$img" # Check if we can activate that (without the token module stuff) - SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 "$SD_CRYPTSETUP" attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig2",headless=1 - SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 "$SD_CRYPTSETUP" detach test-volume2 + SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 systemd-cryptsetup attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig2",headless=1 + SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 systemd-cryptsetup detach test-volume2 # Check if we can activate that (and a second time with the token module stuff enabled) - SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=1 "$SD_CRYPTSETUP" attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig2",headless=1 - SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=1 "$SD_CRYPTSETUP" detach test-volume2 + SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=1 systemd-cryptsetup attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig2",headless=1 + SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=1 systemd-cryptsetup detach test-volume2 # After extending the PCR things should fail tpm2_pcrextend 11:sha256=0000000000000000000000000000000000000000000000000000000000000000 - (! SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 "$SD_CRYPTSETUP" attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig2",headless=1) - (! SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=1 "$SD_CRYPTSETUP" attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig2",headless=1) + (! SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 systemd-cryptsetup attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig2",headless=1) + (! SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=1 systemd-cryptsetup attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig2",headless=1) # But once we sign the current PCRs, we should be able to unlock again "$SD_MEASURE" sign --current "${MEASURE_BANKS[@]}" --private-key="/tmp/pcrsign-private.pem" --public-key="/tmp/pcrsign-public.pem" --phase=: >"/tmp/pcrsign.sig3" - SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 "$SD_CRYPTSETUP" attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig3",headless=1 - "$SD_CRYPTSETUP" detach test-volume2 - SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=1 "$SD_CRYPTSETUP" attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig3",headless=1 - "$SD_CRYPTSETUP" detach test-volume2 + SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 systemd-cryptsetup attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig3",headless=1 + systemd-cryptsetup detach test-volume2 + SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=1 systemd-cryptsetup attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig3",headless=1 + systemd-cryptsetup detach test-volume2 # Test --append mode and de-duplication. With the same parameters signing should not add a new entry "$SD_MEASURE" sign --current "${MEASURE_BANKS[@]}" --private-key="/tmp/pcrsign-private.pem" --public-key="/tmp/pcrsign-public.pem" --phase=: --append="/tmp/pcrsign.sig3" >"/tmp/pcrsign.sig4" @@ -236,8 +235,8 @@ if [[ -x "$SD_MEASURE" ]] && tpm_has_pcr sha1 11 && tpm_has_pcr sha256 11; then (! cmp "/tmp/pcrsign.sig4" "/tmp/pcrsign.sig5") # Should still be good to unlock, given the old entry still exists - SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 "$SD_CRYPTSETUP" attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig5",headless=1 - "$SD_CRYPTSETUP" detach test-volume2 + SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE=0 systemd-cryptsetup attach test-volume2 "$img" - tpm2-device=auto,tpm2-signature="/tmp/pcrsign.sig5",headless=1 + systemd-cryptsetup detach test-volume2 # Adding both signatures once more should not change anything, due to the deduplication "$SD_MEASURE" sign --current "${MEASURE_BANKS[@]}" --private-key="/tmp/pcrsign-private.pem" --public-key="/tmp/pcrsign-public.pem" --phase=: --append="/tmp/pcrsign.sig5" >"/tmp/pcrsign.sig6" From 10aeee95d01bed3608c8a6b760d9023206eacc2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 23 Sep 2023 13:43:55 +0200 Subject: [PATCH 11/11] =?UTF-8?q?man:=20rename=20systemd-cryptsetup@.servi?= =?UTF-8?q?ce=20=E2=86=92=20systemd-cryptsetup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We already had the other name as alias, so this just changes what is the "main" name. The text is adjusted to describe the command briefly. --- man/rules/meson.build | 4 +- ...up@.service.xml => systemd-cryptsetup.xml} | 48 ++++++++++++++----- 2 files changed, 38 insertions(+), 14 deletions(-) rename man/{systemd-cryptsetup@.service.xml => systemd-cryptsetup.xml} (69%) diff --git a/man/rules/meson.build b/man/rules/meson.build index 2884cc32b4..7e145ac0b1 100644 --- a/man/rules/meson.build +++ b/man/rules/meson.build @@ -914,9 +914,9 @@ manpages = [ ['systemd-creds', '1', [], ''], ['systemd-cryptenroll', '1', [], 'HAVE_LIBCRYPTSETUP'], ['systemd-cryptsetup-generator', '8', [], 'HAVE_LIBCRYPTSETUP'], - ['systemd-cryptsetup@.service', + ['systemd-cryptsetup', '8', - ['systemd-cryptsetup'], + ['systemd-cryptsetup@.service'], 'HAVE_LIBCRYPTSETUP'], ['systemd-debug-generator', '8', [], ''], ['systemd-delta', '1', [], ''], diff --git a/man/systemd-cryptsetup@.service.xml b/man/systemd-cryptsetup.xml similarity index 69% rename from man/systemd-cryptsetup@.service.xml rename to man/systemd-cryptsetup.xml index 91a4f2eb9d..493236da83 100644 --- a/man/systemd-cryptsetup@.service.xml +++ b/man/systemd-cryptsetup.xml @@ -3,38 +3,62 @@ - + - systemd-cryptsetup@.service + systemd-cryptsetup systemd - systemd-cryptsetup@.service + systemd-cryptsetup 8 + systemd-cryptsetup systemd-cryptsetup@.service - systemd-cryptsetup Full disk decryption logic + + systemd-cryptsetup + OPTIONS + attach + VOLUME + SOURCE-DEVICE + KEY-FILE + CONFIG + + + + systemd-cryptsetup + OPTIONS + detach + VOLUME + + systemd-cryptsetup@.service system-systemd\x2dcryptsetup.slice - systemd-cryptsetup Description - systemd-cryptsetup@.service is a service responsible for setting up encrypted - block devices. It is instantiated for each device that requires decryption for access. + systemd-cryptsetup is used to set up (with attach) and tear + down (with detach) access to an encrypted block device. It is primarily used via + systemd-cryptsetup@.service during early boot, but may also be be called manually. + The positional arguments VOLUME, SOURCEDEVICE, + KEY-FILE, and CRYPTTAB-OPTIONS have the same meaning as the + fields in crypttab5. + + + systemd-cryptsetup@.service is a service responsible for providing access to + encrypted block devices. It is instantiated for each device that requires decryption. systemd-cryptsetup@.service instances are part of the system-systemd\x2dcryptsetup.slice slice, which is destroyed only very late in the @@ -51,9 +75,9 @@ translated into systemd-cryptsetup@.service units by systemd-cryptsetup-generator8. - In order to unlock a volume a password or binary key is - required. systemd-cryptsetup@.service tries to acquire a suitable password or binary - key via the following mechanisms, tried in order: + In order to unlock a volume a password or binary key is required. + systemd-cryptsetup@.service tries to acquire a suitable password or binary key via + the following mechanisms, tried in order: If a key file is explicitly configured (via the third column in @@ -67,8 +91,8 @@ too, if a PKCS#11/FIDO2/TPM2 token/device is configured, any key found this way is decrypted before use. - If the try-empty-password option is specified it is then attempted - to unlock the volume with an empty password. + If the try-empty-password option is specified then unlocking the + volume with an empty password is attempted. The kernel keyring is then checked for a suitable cached password from previous attempts.