From a085b4dd68927f21c1ed792f9dbf41c5675573e4 Mon Sep 17 00:00:00 2001 From: Richard Hughes Date: Thu, 28 Oct 2021 16:24:19 +0100 Subject: [PATCH] Add a 'created' property on the HSI security attribute --- libfwupd/fwupd-security-attr.c | 68 ++++++++++++++++++++++++++++++++++ libfwupd/fwupd-security-attr.h | 4 ++ libfwupd/fwupd-self-test.c | 3 ++ libfwupd/fwupd.map | 2 + src/fu-self-test.c | 2 + 5 files changed, 79 insertions(+) diff --git a/libfwupd/fwupd-security-attr.c b/libfwupd/fwupd-security-attr.c index c8f89ab5d..ea35a5fd8 100644 --- a/libfwupd/fwupd-security-attr.c +++ b/libfwupd/fwupd-security-attr.c @@ -30,6 +30,7 @@ typedef struct { gchar *name; gchar *plugin; gchar *url; + guint64 created; FwupdSecurityAttrLevel level; FwupdSecurityAttrResult result; FwupdSecurityAttrFlags flags; @@ -483,6 +484,40 @@ fwupd_security_attr_set_url(FwupdSecurityAttr *self, const gchar *url) g_free(priv->url); priv->url = g_strdup(url); } +/** + * fwupd_security_attr_get_created: + * @self: a #FwupdSecurityAttr + * + * Gets when the attribute was created. + * + * Returns: the UNIX time, or 0 if unset + * + * Since: 1.7.1 + **/ +guint64 +fwupd_security_attr_get_created(FwupdSecurityAttr *self) +{ + FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self); + g_return_val_if_fail(FWUPD_IS_SECURITY_ATTR(self), 0); + return priv->created; +} + +/** + * fwupd_security_attr_set_created: + * @self: a #FwupdSecurityAttr + * @created: the UNIX time + * + * Sets when the attribute was created. + * + * Since: 1.7.1 + **/ +void +fwupd_security_attr_set_created(FwupdSecurityAttr *self, guint64 created) +{ + FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self); + g_return_if_fail(FWUPD_IS_SECURITY_ATTR(self)); + priv->created = created; +} /** * fwupd_security_attr_get_name: @@ -688,6 +723,12 @@ fwupd_security_attr_to_variant(FwupdSecurityAttr *self) FWUPD_RESULT_KEY_APPSTREAM_ID, g_variant_new_string(priv->appstream_id)); } + if (priv->created > 0) { + g_variant_builder_add(&builder, + "{sv}", + FWUPD_RESULT_KEY_CREATED, + g_variant_new_uint64(priv->created)); + } if (priv->name != NULL) { g_variant_builder_add(&builder, "{sv}", @@ -802,6 +843,10 @@ fwupd_security_attr_from_key_value(FwupdSecurityAttr *self, const gchar *key, GV fwupd_security_attr_set_appstream_id(self, g_variant_get_string(value, NULL)); return; } + if (g_strcmp0(key, FWUPD_RESULT_KEY_CREATED) == 0) { + fwupd_security_attr_set_created(self, g_variant_get_uint64(value)); + return; + } if (g_strcmp0(key, FWUPD_RESULT_KEY_NAME) == 0) { fwupd_security_attr_set_name(self, g_variant_get_string(value, NULL)); return; @@ -934,6 +979,9 @@ fwupd_security_attr_from_json(FwupdSecurityAttr *self, JsonNode *json_node, GErr fwupd_security_attr_set_level( self, json_object_get_int_member_with_default(obj, FWUPD_RESULT_KEY_HSI_LEVEL, 0)); + fwupd_security_attr_set_created( + self, + json_object_get_int_member_with_default(obj, FWUPD_RESULT_KEY_CREATED, 0)); /* also optional */ if (json_object_has_member(obj, FWUPD_RESULT_KEY_HSI_RESULT)) { @@ -989,6 +1037,8 @@ fwupd_security_attr_to_json(FwupdSecurityAttr *self, JsonBuilder *builder) g_return_if_fail(builder != NULL); fwupd_common_json_add_string(builder, FWUPD_RESULT_KEY_APPSTREAM_ID, priv->appstream_id); + if (priv->created > 0) + fwupd_common_json_add_int(builder, FWUPD_RESULT_KEY_CREATED, priv->created); fwupd_common_json_add_int(builder, FWUPD_RESULT_KEY_HSI_LEVEL, priv->level); fwupd_common_json_add_string(builder, FWUPD_RESULT_KEY_HSI_RESULT, @@ -1027,6 +1077,21 @@ fwupd_security_attr_to_json(FwupdSecurityAttr *self, JsonBuilder *builder) } } +static void +fwupd_pad_kv_unx(GString *str, const gchar *key, guint64 value) +{ + g_autoptr(GDateTime) date = NULL; + g_autofree gchar *tmp = NULL; + + /* ignore */ + if (value == 0) + return; + + date = g_date_time_new_from_unix_utc((gint64)value); + tmp = g_date_time_format(date, "%F"); + fwupd_pad_kv_str(str, key, tmp); +} + /** * fwupd_security_attr_to_string: * @self: a #FwupdSecurityAttr @@ -1047,6 +1112,8 @@ fwupd_security_attr_to_string(FwupdSecurityAttr *self) str = g_string_new(""); fwupd_pad_kv_str(str, FWUPD_RESULT_KEY_APPSTREAM_ID, priv->appstream_id); + if (priv->created > 0) + fwupd_pad_kv_unx(str, FWUPD_RESULT_KEY_CREATED, priv->created); fwupd_pad_kv_int(str, FWUPD_RESULT_KEY_HSI_LEVEL, priv->level); fwupd_pad_kv_str(str, FWUPD_RESULT_KEY_HSI_RESULT, @@ -1089,6 +1156,7 @@ fwupd_security_attr_init(FwupdSecurityAttr *self) FwupdSecurityAttrPrivate *priv = GET_PRIVATE(self); priv->obsoletes = g_ptr_array_new_with_free_func(g_free); priv->guids = g_ptr_array_new_with_free_func(g_free); + priv->created = (guint64)g_get_real_time() / G_USEC_PER_SEC; } static void diff --git a/libfwupd/fwupd-security-attr.h b/libfwupd/fwupd-security-attr.h index 45ef91262..d24cfe30a 100644 --- a/libfwupd/fwupd-security-attr.h +++ b/libfwupd/fwupd-security-attr.h @@ -142,6 +142,10 @@ const gchar * fwupd_security_attr_get_url(FwupdSecurityAttr *self); void fwupd_security_attr_set_url(FwupdSecurityAttr *self, const gchar *url); +guint64 +fwupd_security_attr_get_created(FwupdSecurityAttr *self); +void +fwupd_security_attr_set_created(FwupdSecurityAttr *self, guint64 created); GPtrArray * fwupd_security_attr_get_obsoletes(FwupdSecurityAttr *self); void diff --git a/libfwupd/fwupd-self-test.c b/libfwupd/fwupd-self-test.c index e49804f97..242689b12 100644 --- a/libfwupd/fwupd-self-test.c +++ b/libfwupd/fwupd-self-test.c @@ -829,6 +829,9 @@ fwupd_security_attr_func(void) fwupd_security_attr_add_metadata(attr1, "KEY", "VALUE"); g_assert_cmpstr(fwupd_security_attr_get_metadata(attr1, "KEY"), ==, "VALUE"); + /* remove this from the output */ + fwupd_security_attr_set_created(attr1, 0); + str1 = fwupd_security_attr_to_string(attr1); ret = fu_test_compare_lines(str1, " AppstreamId: org.fwupd.hsi.baz\n" diff --git a/libfwupd/fwupd.map b/libfwupd/fwupd.map index 6cf9d5832..c3eb07901 100644 --- a/libfwupd/fwupd.map +++ b/libfwupd/fwupd.map @@ -715,6 +715,8 @@ LIBFWUPD_1.7.1 { fwupd_client_add_hint; fwupd_security_attr_flag_from_string; fwupd_security_attr_from_json; + fwupd_security_attr_get_created; fwupd_security_attr_result_from_string; + fwupd_security_attr_set_created; local: *; } LIBFWUPD_1.7.0; diff --git a/src/fu-self-test.c b/src/fu-self-test.c index f40d25420..17bf61f6c 100644 --- a/src/fu-self-test.c +++ b/src/fu-self-test.c @@ -3338,7 +3338,9 @@ fu_security_attr_func(gconstpointer user_data) g_autoptr(JsonParser) parser = json_parser_new(); fwupd_security_attr_set_plugin(attr1, "foo"); + fwupd_security_attr_set_created(attr1, 0); fwupd_security_attr_set_plugin(attr2, "bar"); + fwupd_security_attr_set_created(attr2, 0); fu_security_attrs_append(attrs1, attr1); fu_security_attrs_append(attrs1, attr2);