]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
pcrlock: add vl method for list-components
authorLuca Boccassi <luca.boccassi@gmail.com>
Mon, 6 Jul 2026 18:52:13 +0000 (19:52 +0100)
committerLuca Boccassi <luca.boccassi@gmail.com>
Wed, 8 Jul 2026 15:22:05 +0000 (16:22 +0100)
Add varlink method wrapper for list-components verb.

src/pcrlock/pcrlock.c
src/shared/varlink-io.systemd.PCRLock.c
test/units/TEST-70-TPM2.pcrlock.sh

index 60891c1e6601b6f1b4027e9d61ca07d52865a099..1b4d90d2a831665c8241127b16616b8e4d186f8c 100644 (file)
@@ -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,
index c1e8876b1d496b2d9e4f1e717b6d2c8cdf1ddf5a..62b5ce0aa5f7828afbce1b67f8ffa230c08f9a6f 100644 (file)
@@ -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."),
index 1b6a063adf2c565b8bee98581abe24cb297d2e7c..a9680af8df0b2cfcb67592987648062f3c1f9b02 100755 (executable)
@@ -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}'