diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml index e0fb212239b..10518dc791d 100644 --- a/man/systemd-analyze.xml +++ b/man/systemd-analyze.xml @@ -177,6 +177,11 @@ image-policy POLICY + + systemd-analyze + OPTIONS + has-tpm2 + systemd-analyze OPTIONS @@ -948,6 +953,35 @@ default ignore - - + + <command>systemd-analyze has-tpm2</command> + + Reports whether the system is equipped with a usable TPM2 device. If a TPM2 device has been + discovered, is supported, and is being used by firmware, by the OS kernel drivers and by userspace + (i.e. systemd) this prints yes and exits with exit status zero. If no such device is + discovered/supported/used, prints no. Otherwise prints + partial. In either of these two cases exits with non-zero exit status. It also shows + five lines indicating separately whether firmware, drivers, the system, the kernel and libraries + discovered/support/use TPM2. + + Note, this checks for TPM 2.0 devices only, and does not consider TPM 1.2 at all. + + Combine with to suppress the output. + + + Example Output + + yes ++firmware ++driver ++system ++subsystem ++libraries + + + + + <command>systemd-analyze pcrs <optional><replaceable>PCR</replaceable>…</optional></command> @@ -1653,6 +1687,12 @@ io.systemd.credential:vmm.notify_socket=vsock-stream:2:254570042 12, 0, 11 is returned if the second version string is respectively larger, equal, or smaller to the first. In the three-argument form, 0 or 1 if the condition is respectively true or false. + + In case of the has-tpm2 command returns 0 if a TPM2 device is discovered, + supported and used by firmware, driver, and userspace (i.e. systemd). Otherwise returns the OR + combination of the value 1 (in case firmware support is missing), 2 (in case driver support is missing) + and 4 (in case userspace support is missing). If no TPM2 support is available at all, value 7 is hence + returned. diff --git a/man/systemd-creds.xml b/man/systemd-creds.xml index c8419d357a1..8f972eeffba 100644 --- a/man/systemd-creds.xml +++ b/man/systemd-creds.xml @@ -177,22 +177,6 @@ - - has-tpm2 - - Reports whether the system is equipped with a TPM2 device usable for protecting - credentials. If a TPM2 device has been discovered, is supported, and is being used by firmware, - by the OS kernel drivers and by userspace (i.e. systemd) this prints yes and exits - with exit status zero. If no such device is discovered/supported/used, prints - no. Otherwise prints partial. In either of these two cases - exits with non-zero exit status. It also shows four lines indicating separately whether firmware, - drivers, the system and the kernel discovered/support/use TPM2. - - Combine with to suppress the output. - - - - @@ -445,8 +429,7 @@ - When used with has-tpm2 suppresses the output, and only returns an - exit status indicating support for TPM2. + Suppress additional output. @@ -461,12 +444,6 @@ Exit status On success, 0 is returned. - - In case of the has-tpm2 command returns 0 if a TPM2 device is discovered, - supported and used by firmware, driver, and userspace (i.e. systemd). Otherwise returns the OR - combination of the value 1 (in case firmware support is missing), 2 (in case driver support is missing) - and 4 (in case userspace support is missing). If no TPM2 support is available at all, value 7 is hence - returned. diff --git a/src/analyze/analyze-has-tpm2.c b/src/analyze/analyze-has-tpm2.c new file mode 100644 index 00000000000..3e13be9f160 --- /dev/null +++ b/src/analyze/analyze-has-tpm2.c @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "analyze.h" +#include "analyze-has-tpm2.h" +#include "tpm2-util.h" + +int verb_has_tpm2(int argc, char **argv, void *userdata) { + return verb_has_tpm2_generic(arg_quiet); +} diff --git a/src/analyze/analyze-has-tpm2.h b/src/analyze/analyze-has-tpm2.h new file mode 100644 index 00000000000..c7c639228d8 --- /dev/null +++ b/src/analyze/analyze-has-tpm2.h @@ -0,0 +1,4 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +int verb_has_tpm2(int argc, char *argv[], void *userdata); diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c index 1e199e30b70..24188311ff4 100644 --- a/src/analyze/analyze.c +++ b/src/analyze/analyze.c @@ -26,6 +26,7 @@ #include "analyze-exit-status.h" #include "analyze-fdstore.h" #include "analyze-filesystems.h" +#include "analyze-has-tpm2.h" #include "analyze-image-policy.h" #include "analyze-inspect-elf.h" #include "analyze-log-control.h" @@ -253,6 +254,7 @@ static int help(int argc, char *argv[], void *userdata) { "\n%3$sExecutable Analysis:%4$s\n" " inspect-elf FILE... Parse and print ELF package metadata\n" "\n%3$sTPM Operations:%4$s\n" + " has-tpm2 Report whether TPM2 support is available\n" " pcrs [PCR...] Show TPM2 PCRs and their names\n" " srk [>FILE] Write TPM2 SRK (to FILE)\n" "\n%3$sOptions:%4$s\n" @@ -700,6 +702,7 @@ static int run(int argc, char *argv[]) { { "malloc", VERB_ANY, VERB_ANY, 0, verb_malloc }, { "fdstore", 2, VERB_ANY, 0, verb_fdstore }, { "image-policy", 2, 2, 0, verb_image_policy }, + { "has-tpm2", VERB_ANY, 1, 0, verb_has_tpm2 }, { "pcrs", VERB_ANY, VERB_ANY, 0, verb_pcrs }, { "srk", VERB_ANY, 1, 0, verb_srk }, { "architectures", VERB_ANY, VERB_ANY, 0, verb_architectures }, diff --git a/src/analyze/meson.build b/src/analyze/meson.build index a307923c22e..c42db1a6336 100644 --- a/src/analyze/meson.build +++ b/src/analyze/meson.build @@ -14,6 +14,7 @@ systemd_analyze_sources = files( 'analyze-exit-status.c', 'analyze-fdstore.c', 'analyze-filesystems.c', + 'analyze-has-tpm2.c', 'analyze-image-policy.c', 'analyze-inspect-elf.c', 'analyze-log-control.c', diff --git a/src/creds/creds.c b/src/creds/creds.c index 7eec323b9ff..2e28ff3e0ab 100644 --- a/src/creds/creds.c +++ b/src/creds/creds.c @@ -7,6 +7,7 @@ #include "sd-varlink.h" #include "build.h" +#include "build-path.h" #include "bus-polkit.h" #include "creds-util.h" #include "dirent-util.h" @@ -690,35 +691,10 @@ static int verb_setup(int argc, char **argv, void *userdata) { } static int verb_has_tpm2(int argc, char **argv, void *userdata) { - Tpm2Support s; + if (!arg_quiet) + log_notice("The 'systemd-creds %1$s' command has been replaced by 'systemd-analyze %1$s'. Redirecting invocation.", argv[optind]); - s = tpm2_support(); - - if (!arg_quiet) { - if (s == TPM2_SUPPORT_FULL) - puts("yes"); - else if (s == TPM2_SUPPORT_NONE) - puts("no"); - else - puts("partial"); - - printf("%sfirmware\n" - "%sdriver\n" - "%ssystem\n" - "%ssubsystem\n" - "%slibraries\n", - plus_minus(s & TPM2_SUPPORT_FIRMWARE), - plus_minus(s & TPM2_SUPPORT_DRIVER), - plus_minus(s & TPM2_SUPPORT_SYSTEM), - plus_minus(s & TPM2_SUPPORT_SUBSYSTEM), - plus_minus(s & TPM2_SUPPORT_LIBRARIES)); - } - - /* Return inverted bit flags. So that TPM2_SUPPORT_FULL becomes EXIT_SUCCESS and the other values - * become some reasonable values 1…7. i.e. the flags we return here tell what is missing rather than - * what is there, acknowledging the fact that for process exit statuses it is customary to return - * zero (EXIT_FAILURE) when all is good, instead of all being bad. */ - return ~s & TPM2_SUPPORT_FULL; + return verb_has_tpm2_generic(arg_quiet); } static int verb_help(int argc, char **argv, void *userdata) { @@ -739,7 +715,6 @@ static int verb_help(int argc, char **argv, void *userdata) { " ciphertext credential file\n" " decrypt INPUT [OUTPUT] Decrypt ciphertext credential file and write to\n" " plaintext credential file\n" - " has-tpm2 Report whether TPM2 support is available\n" " -h --help Show this help\n" " --version Show package version\n" "\n%3$sOptions:%4$s\n" @@ -774,7 +749,6 @@ static int verb_help(int argc, char **argv, void *userdata) { " --user Select user-scoped credential encryption\n" " --uid=UID Select user for scoped credentials\n" " --allow-null Allow decrypting credentials with empty key\n" - " -q --quiet Suppress output for 'has-tpm2' verb\n" "\nSee the %2$s for details.\n", program_invocation_short_name, link, diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 10de296124a..38e4da40127 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -7907,6 +7907,38 @@ Tpm2Support tpm2_support(void) { return support; } +int verb_has_tpm2_generic(bool quiet) { + Tpm2Support s; + + s = tpm2_support(); + + if (!quiet) { + if (s == TPM2_SUPPORT_FULL) + puts("yes"); + else if (s == TPM2_SUPPORT_NONE) + puts("no"); + else + puts("partial"); + + printf("%sfirmware\n" + "%sdriver\n" + "%ssystem\n" + "%ssubsystem\n" + "%slibraries\n", + plus_minus(s & TPM2_SUPPORT_FIRMWARE), + plus_minus(s & TPM2_SUPPORT_DRIVER), + plus_minus(s & TPM2_SUPPORT_SYSTEM), + plus_minus(s & TPM2_SUPPORT_SUBSYSTEM), + plus_minus(s & TPM2_SUPPORT_LIBRARIES)); + } + + /* Return inverted bit flags. So that TPM2_SUPPORT_FULL becomes EXIT_SUCCESS and the other values + * become some reasonable values 1…7. i.e. the flags we return here tell what is missing rather than + * what is there, acknowledging the fact that for process exit statuses it is customary to return + * zero (EXIT_FAILURE) when all is good, instead of all being bad. */ + return ~s & TPM2_SUPPORT_FULL; +} + #if HAVE_TPM2 static void tpm2_pcr_values_apply_default_hash_alg(Tpm2PCRValue *pcr_values, size_t n_pcr_values) { TPMI_ALG_HASH default_hash = 0; diff --git a/src/shared/tpm2-util.h b/src/shared/tpm2-util.h index 6ab6c00af3a..31ce2e89dbc 100644 --- a/src/shared/tpm2-util.h +++ b/src/shared/tpm2-util.h @@ -463,6 +463,8 @@ typedef enum Tpm2Support { Tpm2Support tpm2_support(void); +int verb_has_tpm2_generic(bool quiet); + int tpm2_parse_pcr_argument(const char *arg, Tpm2PCRValue **ret_pcr_values, size_t *ret_n_pcr_values); int tpm2_parse_pcr_argument_append(const char *arg, Tpm2PCRValue **ret_pcr_values, size_t *ret_n_pcr_values); int tpm2_parse_pcr_argument_to_mask(const char *arg, uint32_t *mask); diff --git a/test/units/TEST-65-ANALYZE.sh b/test/units/TEST-65-ANALYZE.sh index 9fc2de1a21d..db1cc585c75 100755 --- a/test/units/TEST-65-ANALYZE.sh +++ b/test/units/TEST-65-ANALYZE.sh @@ -965,6 +965,13 @@ systemd-analyze condition --instance=tmp --unit=systemd-growfs@.service systemd-analyze verify --instance=tmp --man=no systemd-growfs@.service systemd-analyze security --instance=tmp systemd-growfs@.service +systemd-analyze has-tpm2 ||: +if systemd-analyze has-tpm2 -q ; then + echo "have tpm2" +else + echo "have no tpm2" +fi + systemd-analyze log-level info touch /testok