From: Luca Boccassi Date: Mon, 6 Jul 2026 18:52:13 +0000 (+0100) Subject: pcrlock: add vl method for list-components X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=feda6f31d8cd69e1e677a331fd76b857a1bde800;p=thirdparty%2Fsystemd.git pcrlock: add vl method for list-components Add varlink method wrapper for list-components verb. --- diff --git a/src/pcrlock/pcrlock.c b/src/pcrlock/pcrlock.c index 60891c1e660..1b4d90d2a83 100644 --- a/src/pcrlock/pcrlock.c +++ b/src/pcrlock/pcrlock.c @@ -2674,18 +2674,12 @@ static int verb_show_cel(int argc, char *argv[], uintptr_t _data, void *userdata return 0; } -VERB_NOARG(verb_list_components, "list-components", - "List defined .pcrlock components"); -static int verb_list_components(int argc, char *argv[], uintptr_t _data, void *userdata) { +static int event_log_load_and_process_components(EventLog **ret) { _cleanup_(event_log_freep) EventLog *el = NULL; - _cleanup_(table_unrefp) Table *table = NULL; - enum { - BEFORE_LOCATION, - BETWEEN_LOCATION, - AFTER_LOCATION, - } loc = BEFORE_LOCATION; int r; + assert(ret); + el = event_log_new(); if (!el) return log_oom(); @@ -2702,6 +2696,26 @@ static int verb_list_components(int argc, char *argv[], uintptr_t _data, void *u if (r < 0) return r; + *ret = TAKE_PTR(el); + return 0; +} + +VERB_NOARG(verb_list_components, "list-components", + "List defined .pcrlock components"); +static int verb_list_components(int argc, char *argv[], uintptr_t _data, void *userdata) { + _cleanup_(event_log_freep) EventLog *el = NULL; + _cleanup_(table_unrefp) Table *table = NULL; + enum { + BEFORE_LOCATION, + BETWEEN_LOCATION, + AFTER_LOCATION, + } loc = BEFORE_LOCATION; + int r; + + r = event_log_load_and_process_components(&el); + if (r < 0) + return r; + table = table_new("id", "variants"); if (!table) return log_oom(); @@ -5442,6 +5456,54 @@ static int vl_method_read_event_log(sd_varlink *link, sd_json_variant *parameter return 0; } +static int vl_method_list_components(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) { + _cleanup_(event_log_freep) EventLog *el = NULL; + int r; + + assert(link); + assert(FLAGS_SET(flags, SD_VARLINK_METHOD_MORE)); + + r = sd_varlink_dispatch(link, parameters, /* dispatch_table= */ NULL, /* userdata= */ NULL); + if (r != 0) + return r; + + r = event_log_load_and_process_components(&el); + if (r < 0) + return r; + + r = sd_varlink_set_sentinel(link, NULL); + if (r < 0) + return r; + + FOREACH_ARRAY(c, el->components, el->n_components) { + _cleanup_(sd_json_variant_unrefp) sd_json_variant *variants = NULL; + + FOREACH_ARRAY(variant, (*c)->variants, (*c)->n_variants) { + r = sd_json_variant_append_arraybo( + &variants, + SD_JSON_BUILD_PAIR_STRING("id", (*variant)->id), + SD_JSON_BUILD_PAIR_STRING("path", (*variant)->path)); + if (r < 0) + return r; + } + + if (!variants) { + r = sd_json_variant_new_array(&variants, NULL, 0); + if (r < 0) + return r; + } + + r = sd_varlink_replybo( + link, + SD_JSON_BUILD_PAIR_STRING("id", (*c)->id), + SD_JSON_BUILD_PAIR_VARIANT("variants", variants)); + if (r < 0) + return r; + } + + return 0; +} + typedef struct MethodMakePolicyParameters { bool force; } MethodMakePolicyParameters; @@ -5614,6 +5676,7 @@ static int run(int argc, char *argv[]) { r = sd_varlink_server_bind_method_many( varlink_server, "io.systemd.PCRLock.ReadEventLog", vl_method_read_event_log, + "io.systemd.PCRLock.ListComponents", vl_method_list_components, "io.systemd.PCRLock.MakePolicy", vl_method_make_policy, "io.systemd.PCRLock.RemovePolicy", vl_method_remove_policy, "io.systemd.PCRLock.Lock", vl_method_lock, diff --git a/src/shared/varlink-io.systemd.PCRLock.c b/src/shared/varlink-io.systemd.PCRLock.c index c1e8876b1d4..62b5ce0aa5f 100644 --- a/src/shared/varlink-io.systemd.PCRLock.c +++ b/src/shared/varlink-io.systemd.PCRLock.c @@ -7,6 +7,21 @@ static SD_VARLINK_DEFINE_METHOD_FULL( SD_VARLINK_REQUIRES_MORE, SD_VARLINK_DEFINE_OUTPUT(record, SD_VARLINK_OBJECT, 0)); +static SD_VARLINK_DEFINE_STRUCT_TYPE( + ComponentVariant, + SD_VARLINK_FIELD_COMMENT("The identifier of this component variant."), + SD_VARLINK_DEFINE_FIELD(id, SD_VARLINK_STRING, 0), + SD_VARLINK_FIELD_COMMENT("The path of the .pcrlock file that defines this variant."), + SD_VARLINK_DEFINE_FIELD(path, SD_VARLINK_STRING, 0)); + +static SD_VARLINK_DEFINE_METHOD_FULL( + ListComponents, + SD_VARLINK_REQUIRES_MORE, + SD_VARLINK_FIELD_COMMENT("The identifier of the component."), + SD_VARLINK_DEFINE_OUTPUT(id, SD_VARLINK_STRING, 0), + SD_VARLINK_FIELD_COMMENT("The variants defined for this component, each backed by a .pcrlock file."), + SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(variants, ComponentVariant, SD_VARLINK_ARRAY)); + static SD_VARLINK_DEFINE_METHOD( MakePolicy, SD_VARLINK_DEFINE_INPUT(force, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE)); @@ -39,6 +54,10 @@ SD_VARLINK_DEFINE_INTERFACE( io_systemd_PCRLock, "io.systemd.PCRLock", &vl_method_ReadEventLog, + SD_VARLINK_SYMBOL_COMMENT("A single variant of a .pcrlock component, i.e. one alternative the component may take, backed by a specific .pcrlock file."), + &vl_type_ComponentVariant, + SD_VARLINK_SYMBOL_COMMENT("Lists the defined .pcrlock components, streamed one component per reply. Must be called with the 'more' flag."), + &vl_method_ListComponents, &vl_method_MakePolicy, &vl_method_RemovePolicy, SD_VARLINK_SYMBOL_COMMENT("The category of measurements a .pcrlock file can be generated for or removed, as used by the Lock() method."), diff --git a/test/units/TEST-70-TPM2.pcrlock.sh b/test/units/TEST-70-TPM2.pcrlock.sh index 1b6a063adf2..a9680af8df0 100755 --- a/test/units/TEST-70-TPM2.pcrlock.sh +++ b/test/units/TEST-70-TPM2.pcrlock.sh @@ -242,6 +242,7 @@ systemctl restart systemd-pcrlock.socket varlinkctl call /run/systemd/io.systemd.PCRLock io.systemd.PCRLock.RemovePolicy '{}' varlinkctl call /run/systemd/io.systemd.PCRLock io.systemd.PCRLock.MakePolicy '{}' varlinkctl call --collect --json=pretty /run/systemd/io.systemd.PCRLock io.systemd.PCRLock.ReadEventLog '{}' +varlinkctl call --collect --json=pretty /run/systemd/io.systemd.PCRLock io.systemd.PCRLock.ListComponents '{}' varlinkctl call /run/systemd/io.systemd.PCRLock io.systemd.PCRLock.Lock '{"category":"firmwareConfig"}' varlinkctl call /run/systemd/io.systemd.PCRLock io.systemd.PCRLock.Lock '{"category":"firmwareConfig","lock":false}' varlinkctl call /run/systemd/io.systemd.PCRLock io.systemd.PCRLock.Lock '{"category":"firmwareCode","lock":false}'