mirror of
https://git.proxmox.com/git/fwupd
synced 2025-07-27 12:54:58 +00:00
fu_history: fu_security_attr: Convert secutiry attr to json and write to DB.
1. Create hsi_history table to store the security attributes. 2. Convert all security entities to a json string and write to database. Signed-off-by: Kate Hsuan <hpa@redhat.com> Changes in v1: 1. Fixed typo: "his_history" to "hsi_history" 2. g_autofree all gchar pointer. 3. Removed unnecessary g_warning messages. 4. Moved the json format comment to Document comment. 5. Add an error handling for json converter. Changes in v2: 1. Declare all pointers using g_auto_ptr. 2. The warning messages of JSON conversion and DB writing errors were added. 3. "Since: 1.7.0" was added to the document comment. Changes in v3: 1. Fix variable declaration. 2. Remove unecessary data type casting. Changes in v4: 1. Fix migration schema. Changes in v5: 1. Fix hsi_history column name declaration. Changes in v6: Column name was modified from last to timestamp.
This commit is contained in:
parent
5c60beae29
commit
db04223167
@ -5908,6 +5908,8 @@ fu_engine_ensure_security_attrs(FuEngine *self)
|
|||||||
GPtrArray *plugins = fu_plugin_list_get_all(self->plugin_list);
|
GPtrArray *plugins = fu_plugin_list_get_all(self->plugin_list);
|
||||||
g_autoptr(GPtrArray) devices = fu_device_list_get_all(self->device_list);
|
g_autoptr(GPtrArray) devices = fu_device_list_get_all(self->device_list);
|
||||||
g_autoptr(GPtrArray) items = NULL;
|
g_autoptr(GPtrArray) items = NULL;
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
g_autofree gchar *data = NULL;
|
||||||
|
|
||||||
/* already valid */
|
/* already valid */
|
||||||
if (self->host_security_id != NULL)
|
if (self->host_security_id != NULL)
|
||||||
@ -5952,6 +5954,20 @@ fu_engine_ensure_security_attrs(FuEngine *self)
|
|||||||
/* distil into one simple string */
|
/* distil into one simple string */
|
||||||
g_free(self->host_security_id);
|
g_free(self->host_security_id);
|
||||||
self->host_security_id = fu_engine_attrs_calculate_hsi_for_chassis(self);
|
self->host_security_id = fu_engine_attrs_calculate_hsi_for_chassis(self);
|
||||||
|
|
||||||
|
/* Convert Security attribute to json string */
|
||||||
|
data = fu_security_attrs_to_json_string(self->host_security_attrs, &error);
|
||||||
|
|
||||||
|
/* Store string to db */
|
||||||
|
if (data == NULL) {
|
||||||
|
g_warning("Fail to convert security attributes to string: %s", error->message);
|
||||||
|
} else {
|
||||||
|
if (fu_history_add_security_attribute(self->history,
|
||||||
|
data,
|
||||||
|
self->host_security_id,
|
||||||
|
&error) == FALSE)
|
||||||
|
g_warning("Fail to write security attribute to DB: %s", error->message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const gchar *
|
const gchar *
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
#include "fu-history.h"
|
#include "fu-history.h"
|
||||||
#include "fu-mutex.h"
|
#include "fu-mutex.h"
|
||||||
|
|
||||||
#define FU_HISTORY_CURRENT_SCHEMA_VERSION 6
|
#define FU_HISTORY_CURRENT_SCHEMA_VERSION 7
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fu_history_finalize(GObject *object);
|
fu_history_finalize(GObject *object);
|
||||||
@ -183,6 +183,10 @@ fu_history_create_database(FuHistory *self, GError **error)
|
|||||||
"checksum TEXT);"
|
"checksum TEXT);"
|
||||||
"CREATE TABLE IF NOT EXISTS blocked_firmware ("
|
"CREATE TABLE IF NOT EXISTS blocked_firmware ("
|
||||||
"checksum TEXT);"
|
"checksum TEXT);"
|
||||||
|
"CREATE TABLE IF NOT EXISTS hsi_history ("
|
||||||
|
"timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,"
|
||||||
|
"hsi_details TEXT DEFAULT NULL,"
|
||||||
|
"hsi_score TEXT DEFAULT NULL);"
|
||||||
"COMMIT;",
|
"COMMIT;",
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
@ -307,6 +311,29 @@ fu_history_migrate_database_v5(FuHistory *self, GError **error)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
fu_history_migrate_database_v6(FuHistory *self, GError **error)
|
||||||
|
{
|
||||||
|
gint rc;
|
||||||
|
rc = sqlite3_exec(self->db,
|
||||||
|
"CREATE TABLE IF NOT EXISTS hsi_history ("
|
||||||
|
"timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,"
|
||||||
|
"hsi_details TEXT DEFAULT NULL,"
|
||||||
|
"hsi_score TEXT DEFAULT NULL);",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
if (rc != SQLITE_OK) {
|
||||||
|
g_set_error(error,
|
||||||
|
FWUPD_ERROR,
|
||||||
|
FWUPD_ERROR_INTERNAL,
|
||||||
|
"Failed to create table: %s",
|
||||||
|
sqlite3_errmsg(self->db));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* returns 0 if database is not initialized */
|
/* returns 0 if database is not initialized */
|
||||||
static guint
|
static guint
|
||||||
fu_history_get_schema_version(FuHistory *self)
|
fu_history_get_schema_version(FuHistory *self)
|
||||||
@ -363,6 +390,10 @@ fu_history_create_or_migrate(FuHistory *self, guint schema_ver, GError **error)
|
|||||||
case 5:
|
case 5:
|
||||||
if (!fu_history_migrate_database_v5(self, error))
|
if (!fu_history_migrate_database_v5(self, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
/* fall through */
|
||||||
|
case 6:
|
||||||
|
if (!fu_history_migrate_database_v6(self, error))
|
||||||
|
return FALSE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* this is probably okay, but return an error if we ever delete
|
/* this is probably okay, but return an error if we ever delete
|
||||||
@ -1283,6 +1314,42 @@ fu_history_add_blocked_firmware(FuHistory *self, const gchar *checksum, GError *
|
|||||||
return fu_history_stmt_exec(self, stmt, NULL, error);
|
return fu_history_stmt_exec(self, stmt, NULL, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
fu_history_add_security_attribute(FuHistory *self,
|
||||||
|
const gchar *security_attr_json,
|
||||||
|
const gchar *hsi_score,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
gint rc;
|
||||||
|
g_autoptr(sqlite3_stmt) stmt = NULL;
|
||||||
|
g_autoptr(GRWLockWriterLocker) locker = NULL;
|
||||||
|
g_return_val_if_fail(FU_IS_HISTORY(self), FALSE);
|
||||||
|
|
||||||
|
/* lazy load */
|
||||||
|
if (!fu_history_load(self, error))
|
||||||
|
return FALSE;
|
||||||
|
/* remove entries */
|
||||||
|
locker = g_rw_lock_writer_locker_new(&self->db_mutex);
|
||||||
|
g_return_val_if_fail(locker != NULL, FALSE);
|
||||||
|
rc = sqlite3_prepare_v2(self->db,
|
||||||
|
"INSERT INTO hsi_history (hsi_details, hsi_score)"
|
||||||
|
"VALUES (?1, ?2)",
|
||||||
|
-1,
|
||||||
|
&stmt,
|
||||||
|
NULL);
|
||||||
|
if (rc != SQLITE_OK) {
|
||||||
|
g_set_error(error,
|
||||||
|
FWUPD_ERROR,
|
||||||
|
FWUPD_ERROR_INTERNAL,
|
||||||
|
"Failed to prepare SQL to write security attribute: %s",
|
||||||
|
sqlite3_errmsg(self->db));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
sqlite3_bind_text(stmt, 1, security_attr_json, -1, SQLITE_STATIC);
|
||||||
|
sqlite3_bind_text(stmt, 2, hsi_score, -1, SQLITE_STATIC);
|
||||||
|
return fu_history_stmt_exec(self, stmt, NULL, error);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fu_history_class_init(FuHistoryClass *klass)
|
fu_history_class_init(FuHistoryClass *klass)
|
||||||
{
|
{
|
||||||
|
@ -48,3 +48,8 @@ gboolean
|
|||||||
fu_history_add_blocked_firmware(FuHistory *self, const gchar *checksum, GError **error);
|
fu_history_add_blocked_firmware(FuHistory *self, const gchar *checksum, GError **error);
|
||||||
GPtrArray *
|
GPtrArray *
|
||||||
fu_history_get_blocked_firmware(FuHistory *self, GError **error);
|
fu_history_get_blocked_firmware(FuHistory *self, GError **error);
|
||||||
|
gboolean
|
||||||
|
fu_history_add_security_attribute(FuHistory *self,
|
||||||
|
const gchar *security_attr_json,
|
||||||
|
const gchar *hsi_score,
|
||||||
|
GError **error);
|
||||||
|
@ -8,9 +8,12 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
|
#include <json-glib/json-glib.h>
|
||||||
|
|
||||||
#include "fwupd-security-attr-private.h"
|
#include "fwupd-security-attr-private.h"
|
||||||
|
|
||||||
|
#include "fu-security-attrs-private.h"
|
||||||
|
|
||||||
gchar *
|
gchar *
|
||||||
fu_security_attr_get_name(FwupdSecurityAttr *attr)
|
fu_security_attr_get_name(FwupdSecurityAttr *attr)
|
||||||
{
|
{
|
||||||
@ -247,3 +250,72 @@ fu_security_attr_get_result(FwupdSecurityAttr *attr)
|
|||||||
/* TRANSLATORS: Suffix: the fallback HSI result */
|
/* TRANSLATORS: Suffix: the fallback HSI result */
|
||||||
return _("Failed");
|
return _("Failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fu_security_attrs_to_json_string:
|
||||||
|
* Convert security attribute to JSON string.
|
||||||
|
* @attrs: a pointer for a FuSecurityAttrs data structure.
|
||||||
|
* @error: return location for an error
|
||||||
|
*
|
||||||
|
* fu_security_attrs_to_json_string() converts FuSecurityAttrs and return the
|
||||||
|
* string pointer. The converted JSON format is shown as follows:
|
||||||
|
* {
|
||||||
|
* "SecurityAttrs": {
|
||||||
|
* "Attrs": [
|
||||||
|
* {
|
||||||
|
* "name": "aaa",
|
||||||
|
* "value": "bbb"
|
||||||
|
* }
|
||||||
|
* ]
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* Returns: A string and NULL on fail.
|
||||||
|
*
|
||||||
|
* Since: 1.7.0
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
gchar *
|
||||||
|
fu_security_attrs_to_json_string(FuSecurityAttrs *attrs, GError **error)
|
||||||
|
{
|
||||||
|
g_autofree gchar *data = NULL;
|
||||||
|
g_autoptr(JsonGenerator) json_generator = NULL;
|
||||||
|
g_autoptr(JsonBuilder) builder = json_builder_new();
|
||||||
|
g_autoptr(JsonNode) json_root = NULL;
|
||||||
|
fu_security_attrs_to_json(attrs, builder);
|
||||||
|
json_root = json_builder_get_root(builder);
|
||||||
|
json_generator = json_generator_new();
|
||||||
|
json_generator_set_pretty(json_generator, TRUE);
|
||||||
|
json_generator_set_root(json_generator, json_root);
|
||||||
|
data = json_generator_to_data(json_generator, NULL);
|
||||||
|
if (data == NULL) {
|
||||||
|
g_set_error(error,
|
||||||
|
FWUPD_ERROR,
|
||||||
|
FWUPD_ERROR_INTERNAL,
|
||||||
|
"Failed to convert security attribute to json.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return g_steal_pointer(&data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fu_security_attrs_to_json(FuSecurityAttrs *attrs, JsonBuilder *builder)
|
||||||
|
{
|
||||||
|
g_autoptr(GPtrArray) items = NULL;
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
json_builder_begin_object(builder);
|
||||||
|
json_builder_set_member_name(builder, "SecurityAttrs");
|
||||||
|
json_builder_begin_object(builder);
|
||||||
|
json_builder_set_member_name(builder, "Attrs");
|
||||||
|
json_builder_begin_array(builder);
|
||||||
|
items = fu_security_attrs_get_all(attrs);
|
||||||
|
for (guint i = 0; i < items->len; i++) {
|
||||||
|
FwupdSecurityAttr *attr = g_ptr_array_index(items, i);
|
||||||
|
json_builder_begin_object(builder);
|
||||||
|
fwupd_security_attr_to_json(attr, builder);
|
||||||
|
json_builder_end_object(builder);
|
||||||
|
}
|
||||||
|
json_builder_end_array(builder);
|
||||||
|
json_builder_end_object(builder);
|
||||||
|
json_builder_end_object(builder);
|
||||||
|
}
|
||||||
|
@ -7,8 +7,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <fwupd.h>
|
#include <fwupd.h>
|
||||||
|
#include <json-glib/json-glib.h>
|
||||||
|
|
||||||
|
#include "fu-security-attrs-private.h"
|
||||||
|
|
||||||
gchar *
|
gchar *
|
||||||
fu_security_attr_get_name(FwupdSecurityAttr *attr);
|
fu_security_attr_get_name(FwupdSecurityAttr *attr);
|
||||||
const gchar *
|
const gchar *
|
||||||
fu_security_attr_get_result(FwupdSecurityAttr *attr);
|
fu_security_attr_get_result(FwupdSecurityAttr *attr);
|
||||||
|
void
|
||||||
|
fu_security_attrs_to_json(FuSecurityAttrs *attrs, JsonBuilder *builder);
|
||||||
|
gchar *
|
||||||
|
fu_security_attrs_to_json_string(FuSecurityAttrs *attrs, GError **error);
|
||||||
|
Loading…
Reference in New Issue
Block a user