mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-04 09:47:00 +00:00
Add support for the Host Security ID
The HSI specification assigns a simple text ID to the current state of firmware security. As new vulnerabilities are found, and as protection measures are updated, new requirements will be added to the required firmware behaviours for each HSI value. The HSI specification is currently incomplete and in active development, and so the --force flag is required in all command line tools. The current ID value will probably change on a given platform so please do not start using the result for any kind of compliance requirements.
This commit is contained in:
parent
c1407ed14f
commit
196c6c69db
@ -2,6 +2,7 @@ _fwupdagent_cmd_list=(
|
||||
'get-devices'
|
||||
'get-updates'
|
||||
'get-upgrades'
|
||||
'security'
|
||||
)
|
||||
|
||||
_fwupdagent_opts=(
|
||||
|
@ -22,6 +22,7 @@ _fwupdmgr_cmd_list=(
|
||||
'reinstall'
|
||||
'refresh'
|
||||
'report-history'
|
||||
'security'
|
||||
'set-approved-firmware'
|
||||
'unlock'
|
||||
'update'
|
||||
|
@ -20,6 +20,7 @@ _fwupdtool_cmd_list=(
|
||||
'install-blob'
|
||||
'monitor'
|
||||
'reinstall'
|
||||
'security'
|
||||
'self-sign'
|
||||
'smbios-dump'
|
||||
'attach'
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "fwupd-enums.h"
|
||||
#include "fwupd-error.h"
|
||||
#include "fwupd-device-private.h"
|
||||
#include "fwupd-security-attr-private.h"
|
||||
#include "fwupd-release-private.h"
|
||||
#include "fwupd-remote-private.h"
|
||||
|
||||
@ -45,6 +46,7 @@ typedef struct {
|
||||
gchar *daemon_version;
|
||||
gchar *host_product;
|
||||
gchar *host_machine_id;
|
||||
gchar *host_security_id;
|
||||
GDBusConnection *conn;
|
||||
GDBusProxy *proxy;
|
||||
} FwupdClientPrivate;
|
||||
@ -66,6 +68,7 @@ enum {
|
||||
PROP_TAINTED,
|
||||
PROP_HOST_PRODUCT,
|
||||
PROP_HOST_MACHINE_ID,
|
||||
PROP_HOST_SECURITY_ID,
|
||||
PROP_INTERACTIVE,
|
||||
PROP_LAST
|
||||
};
|
||||
@ -128,6 +131,15 @@ fwupd_client_set_host_machine_id (FwupdClient *client, const gchar *host_machine
|
||||
g_object_notify (G_OBJECT (client), "host-machine-id");
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_client_set_host_security_id (FwupdClient *client, const gchar *host_security_id)
|
||||
{
|
||||
FwupdClientPrivate *priv = GET_PRIVATE (client);
|
||||
g_free (priv->host_security_id);
|
||||
priv->host_security_id = g_strdup (host_security_id);
|
||||
g_object_notify (G_OBJECT (client), "host-security-id");
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_client_set_daemon_version (FwupdClient *client, const gchar *daemon_version)
|
||||
{
|
||||
@ -201,6 +213,12 @@ fwupd_client_properties_changed_cb (GDBusProxy *proxy,
|
||||
if (val != NULL)
|
||||
fwupd_client_set_host_machine_id (client, g_variant_get_string (val, NULL));
|
||||
}
|
||||
if (g_variant_dict_contains (dict, "HostSecurityId")) {
|
||||
g_autoptr(GVariant) val = NULL;
|
||||
val = g_dbus_proxy_get_cached_property (proxy, "HostSecurityId");
|
||||
if (val != NULL)
|
||||
fwupd_client_set_host_security_id (client, g_variant_get_string (val, NULL));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -304,6 +322,9 @@ fwupd_client_connect (FwupdClient *client, GCancellable *cancellable, GError **e
|
||||
val = g_dbus_proxy_get_cached_property (priv->proxy, "HostMachineId");
|
||||
if (val != NULL)
|
||||
fwupd_client_set_host_machine_id (client, g_variant_get_string (val, NULL));
|
||||
val = g_dbus_proxy_get_cached_property (priv->proxy, "HostSecurityId");
|
||||
if (val != NULL)
|
||||
fwupd_client_set_host_security_id (client, g_variant_get_string (val, NULL));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -341,6 +362,48 @@ fwupd_client_fixup_dbus_error (GError *error)
|
||||
g_dbus_error_strip_remote_error (error);
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_client_get_host_security_attrs:
|
||||
* @client: A #FwupdClient
|
||||
* @cancellable: the #GCancellable, or %NULL
|
||||
* @error: the #GError, or %NULL
|
||||
*
|
||||
* Gets all the host security attributes from the daemon.
|
||||
*
|
||||
* Returns: (element-type FwupdSecurityAttr) (transfer container): attributes
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
GPtrArray *
|
||||
fwupd_client_get_host_security_attrs (FwupdClient *client, GCancellable *cancellable, GError **error)
|
||||
{
|
||||
FwupdClientPrivate *priv = GET_PRIVATE (client);
|
||||
g_autoptr(GVariant) val = NULL;
|
||||
|
||||
g_return_val_if_fail (FWUPD_IS_CLIENT (client), NULL);
|
||||
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
/* connect */
|
||||
if (!fwupd_client_connect (client, cancellable, error))
|
||||
return NULL;
|
||||
|
||||
/* call into daemon */
|
||||
val = g_dbus_proxy_call_sync (priv->proxy,
|
||||
"GetHostSecurityAttrs",
|
||||
NULL,
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
cancellable,
|
||||
error);
|
||||
if (val == NULL) {
|
||||
if (error != NULL)
|
||||
fwupd_client_fixup_dbus_error (*error);
|
||||
return NULL;
|
||||
}
|
||||
return fwupd_security_attr_array_from_variant (val);
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_client_get_devices:
|
||||
* @client: A #FwupdClient
|
||||
@ -1314,6 +1377,24 @@ fwupd_client_get_host_machine_id (FwupdClient *client)
|
||||
return priv->host_machine_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_client_get_host_security_id:
|
||||
* @client: A #FwupdClient
|
||||
*
|
||||
* Gets the string that represents the host machine ID
|
||||
*
|
||||
* Returns: a string, or %NULL for unknown.
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
const gchar *
|
||||
fwupd_client_get_host_security_id (FwupdClient *client)
|
||||
{
|
||||
FwupdClientPrivate *priv = GET_PRIVATE (client);
|
||||
g_return_val_if_fail (FWUPD_IS_CLIENT (client), NULL);
|
||||
return priv->host_security_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_client_get_status:
|
||||
* @client: A #FwupdClient
|
||||
@ -1869,6 +1950,9 @@ fwupd_client_get_property (GObject *object, guint prop_id,
|
||||
case PROP_HOST_MACHINE_ID:
|
||||
g_value_set_string (value, priv->host_machine_id);
|
||||
break;
|
||||
case PROP_HOST_SECURITY_ID:
|
||||
g_value_set_string (value, priv->host_security_id);
|
||||
break;
|
||||
case PROP_INTERACTIVE:
|
||||
g_value_set_boolean (value, priv->interactive);
|
||||
break;
|
||||
@ -2069,6 +2153,17 @@ fwupd_client_class_init (FwupdClientClass *klass)
|
||||
pspec = g_param_spec_string ("host-machine-id", NULL, NULL,
|
||||
NULL, G_PARAM_READABLE | G_PARAM_STATIC_NAME);
|
||||
g_object_class_install_property (object_class, PROP_HOST_MACHINE_ID, pspec);
|
||||
|
||||
/**
|
||||
* FwupdClient:host-security-id:
|
||||
*
|
||||
* The host machine-id string
|
||||
*
|
||||
* Since: 1.5.0
|
||||
*/
|
||||
pspec = g_param_spec_string ("host-security-id", NULL, NULL,
|
||||
NULL, G_PARAM_READABLE | G_PARAM_STATIC_NAME);
|
||||
g_object_class_install_property (object_class, PROP_HOST_SECURITY_ID, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2085,6 +2180,7 @@ fwupd_client_finalize (GObject *object)
|
||||
g_free (priv->daemon_version);
|
||||
g_free (priv->host_product);
|
||||
g_free (priv->host_machine_id);
|
||||
g_free (priv->host_security_id);
|
||||
if (priv->conn != NULL)
|
||||
g_object_unref (priv->conn);
|
||||
if (priv->proxy != NULL)
|
||||
|
@ -95,6 +95,9 @@ FwupdDevice *fwupd_client_get_results (FwupdClient *client,
|
||||
const gchar *device_id,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GPtrArray *fwupd_client_get_host_security_attrs (FwupdClient *client,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
FwupdDevice *fwupd_client_get_device_by_id (FwupdClient *client,
|
||||
const gchar *device_id,
|
||||
GCancellable *cancellable,
|
||||
@ -134,6 +137,7 @@ guint fwupd_client_get_percentage (FwupdClient *client);
|
||||
const gchar *fwupd_client_get_daemon_version (FwupdClient *client);
|
||||
const gchar *fwupd_client_get_host_product (FwupdClient *client);
|
||||
const gchar *fwupd_client_get_host_machine_id (FwupdClient *client);
|
||||
const gchar *fwupd_client_get_host_security_id (FwupdClient *client);
|
||||
|
||||
GPtrArray *fwupd_client_get_remotes (FwupdClient *client,
|
||||
GCancellable *cancellable,
|
||||
|
@ -449,6 +449,8 @@ LIBFWUPD_1.4.1 {
|
||||
|
||||
LIBFWUPD_1.5.0 {
|
||||
global:
|
||||
fwupd_client_get_host_security_attrs;
|
||||
fwupd_client_get_host_security_id;
|
||||
fwupd_security_attr_add_flag;
|
||||
fwupd_security_attr_add_obsolete;
|
||||
fwupd_security_attr_array_from_variant;
|
||||
|
@ -116,6 +116,9 @@ gboolean fu_plugin_runner_clear_results (FuPlugin *self,
|
||||
gboolean fu_plugin_runner_get_results (FuPlugin *self,
|
||||
FuDevice *device,
|
||||
GError **error);
|
||||
gboolean fu_plugin_runner_add_security_attrs (FuPlugin *self,
|
||||
GPtrArray *attrs,
|
||||
GError **error);
|
||||
gint fu_plugin_name_compare (FuPlugin *plugin1,
|
||||
FuPlugin *plugin2);
|
||||
gint fu_plugin_order_compare (FuPlugin *plugin1,
|
||||
|
@ -359,3 +359,16 @@ gboolean fu_plugin_device_created (FuPlugin *plugin,
|
||||
**/
|
||||
void fu_plugin_device_registered (FuPlugin *plugin,
|
||||
FuDevice *dev);
|
||||
/**
|
||||
* fu_plugin_add_security_attrs
|
||||
* @plugin: A #FuPlugin
|
||||
* @attrs: A #GPtrArray of #FwupdSecurityAttr
|
||||
* @error: A #GError or NULL
|
||||
*
|
||||
* Function that asks plugins to add Host Security Attributes.
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
gboolean fu_plugin_add_security_attrs (FuPlugin *plugin,
|
||||
GPtrArray *attrs,
|
||||
GError **error);
|
||||
|
@ -1579,6 +1579,26 @@ fu_plugin_runner_update_reload (FuPlugin *self, FuDevice *device, GError **error
|
||||
return fu_device_reload (device, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_plugin_runner_add_security_attrs:
|
||||
* @self: a #FuPlugin
|
||||
* @attrs: (element-type FwupdSecurityAttr): a #GPtrArray of attributes
|
||||
* @error: a #GError or NULL
|
||||
*
|
||||
* Runs the composite_prepare routine for the plugin
|
||||
*
|
||||
* Returns: #TRUE for success, #FALSE for failure
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
gboolean
|
||||
fu_plugin_runner_add_security_attrs (FuPlugin *self, GPtrArray *attrs, GError **error)
|
||||
{
|
||||
return fu_plugin_runner_device_array_generic (self, attrs,
|
||||
"fu_plugin_add_security_attrs",
|
||||
error);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_plugin_add_udev_subsystem:
|
||||
* @self: a #FuPlugin
|
||||
|
@ -585,6 +585,7 @@ LIBFWUPDPLUGIN_1.5.0 {
|
||||
global:
|
||||
fu_common_filename_glob;
|
||||
fu_common_is_cpu_intel;
|
||||
fu_plugin_runner_add_security_attrs;
|
||||
fu_plugin_runner_device_added;
|
||||
fu_udev_device_get_parent_name;
|
||||
fu_udev_device_get_sysfs_attr;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "fu-util-common.h"
|
||||
#include "fwupd-device-private.h"
|
||||
#include "fwupd-enums-private.h"
|
||||
#include "fwupd-security-attr-private.h"
|
||||
|
||||
struct FuUtilPrivate {
|
||||
GCancellable *cancellable;
|
||||
@ -113,6 +114,37 @@ fu_util_add_updates_json (FuUtilPrivate *priv, JsonBuilder *builder, GError **er
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_util_add_security_attributes_json (FuUtilPrivate *priv, JsonBuilder *builder, GError **error)
|
||||
{
|
||||
g_autoptr(GPtrArray) attrs = NULL;
|
||||
|
||||
/* not ready yet */
|
||||
if ((priv->flags & FWUPD_INSTALL_FLAG_FORCE) == 0) {
|
||||
g_set_error_literal (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"The HSI specification is not yet complete. "
|
||||
"To ignore this warning, use --force");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* get attrs from daemon */
|
||||
attrs = fwupd_client_get_host_security_attrs (priv->client, NULL, error);
|
||||
if (attrs == NULL)
|
||||
return FALSE;
|
||||
json_builder_set_member_name (builder, "HostSecurityAttributes");
|
||||
json_builder_begin_array (builder);
|
||||
for (guint i = 0; i < attrs->len; i++) {
|
||||
FwupdSecurityAttr *attr = g_ptr_array_index (attrs, i);
|
||||
json_builder_begin_object (builder);
|
||||
fwupd_security_attr_to_json (attr, builder);
|
||||
json_builder_end_object (builder);
|
||||
}
|
||||
json_builder_end_array (builder);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_util_get_devices (FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
{
|
||||
@ -199,6 +231,49 @@ fu_util_get_updates (FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_util_security (FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
{
|
||||
g_autofree gchar *data = NULL;
|
||||
g_autoptr(JsonBuilder) builder = NULL;
|
||||
g_autoptr(JsonGenerator) json_generator = NULL;
|
||||
g_autoptr(JsonNode) json_root = NULL;
|
||||
|
||||
/* check args */
|
||||
if (g_strv_length (values) != 0) {
|
||||
g_set_error_literal (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_ARGS,
|
||||
"Invalid arguments");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* create header */
|
||||
builder = json_builder_new ();
|
||||
json_builder_begin_object (builder);
|
||||
if (!fu_util_add_security_attributes_json (priv, builder, error))
|
||||
return FALSE;
|
||||
json_builder_end_object (builder);
|
||||
|
||||
/* export as a string */
|
||||
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_literal (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INTERNAL,
|
||||
"Failed to convert to JSON string");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* just print */
|
||||
g_print ("%s\n", data);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_util_ignore_cb (const gchar *log_domain, GLogLevelFlags log_level,
|
||||
const gchar *message, gpointer user_data)
|
||||
@ -280,6 +355,11 @@ main (int argc, char *argv[])
|
||||
/* TRANSLATORS: command description */
|
||||
_("Gets the list of updates for connected hardware"),
|
||||
fu_util_get_updates);
|
||||
fu_util_cmd_array_add (cmd_array,
|
||||
"security", NULL,
|
||||
/* TRANSLATORS: command description */
|
||||
_("Gets the host security attributes"),
|
||||
fu_util_security);
|
||||
|
||||
/* sort by command name */
|
||||
fu_util_cmd_array_sort (cmd_array);
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "fu-plugin-private.h"
|
||||
#include "fu-quirks.h"
|
||||
#include "fu-remote-list.h"
|
||||
#include "fu-security-attrs.h"
|
||||
#include "fu-smbios-private.h"
|
||||
#include "fu-udev-device-private.h"
|
||||
#include "fu-usb-device-private.h"
|
||||
@ -99,6 +100,8 @@ struct _FuEngine
|
||||
gchar *host_machine_id;
|
||||
JcatContext *jcat_context;
|
||||
gboolean loaded;
|
||||
gchar *host_security_id;
|
||||
gboolean host_security_id_valid;
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -133,6 +136,7 @@ fu_engine_emit_changed (FuEngine *self)
|
||||
static void
|
||||
fu_engine_emit_device_changed (FuEngine *self, FuDevice *device)
|
||||
{
|
||||
self->host_security_id_valid = FALSE;
|
||||
g_signal_emit (self, signals[SIGNAL_DEVICE_CHANGED], 0, device);
|
||||
}
|
||||
|
||||
@ -5026,6 +5030,56 @@ fu_engine_get_host_machine_id (FuEngine *self)
|
||||
return self->host_machine_id;
|
||||
}
|
||||
|
||||
GPtrArray *
|
||||
fu_engine_get_host_security_attrs (FuEngine *self, GError **error)
|
||||
{
|
||||
GPtrArray *plugins = fu_plugin_list_get_all (self->plugin_list);
|
||||
g_autoptr(GPtrArray) attrs = NULL;
|
||||
|
||||
attrs = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
|
||||
for (guint j = 0; j < plugins->len; j++) {
|
||||
FuPlugin *plugin_tmp = g_ptr_array_index (plugins, j);
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
if (!fu_plugin_runner_add_security_attrs (plugin_tmp,
|
||||
attrs,
|
||||
&error_local)) {
|
||||
FwupdSecurityAttr *attr;
|
||||
g_autofree gchar *appstream_id = NULL;
|
||||
g_autofree gchar *msg = NULL;
|
||||
appstream_id = g_strdup_printf ("org.fwupd.plugin.%s",
|
||||
fu_plugin_get_name (plugin_tmp));
|
||||
msg = g_strdup_printf ("Failed to add HSI attribute: %s",
|
||||
error_local->message);
|
||||
attr = fwupd_security_attr_new (appstream_id);
|
||||
fwupd_security_attr_set_name (attr, "fwupd");
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ISSUE);
|
||||
fwupd_security_attr_set_result (attr, msg);
|
||||
g_ptr_array_add (attrs, attr);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* set the obsoletes flag for each attr */
|
||||
fu_security_attrs_depsolve (attrs);
|
||||
return g_steal_pointer (&attrs);
|
||||
}
|
||||
|
||||
const gchar *
|
||||
fu_engine_get_host_security_id (FuEngine *self)
|
||||
{
|
||||
g_return_val_if_fail (FU_IS_ENGINE (self), NULL);
|
||||
|
||||
/* rebuild */
|
||||
if (!self->host_security_id_valid) {
|
||||
g_autoptr(GPtrArray) attrs = fu_engine_get_host_security_attrs (self, NULL);
|
||||
g_free (self->host_security_id);
|
||||
self->host_security_id = fu_security_attrs_calculate_hsi (attrs);
|
||||
self->host_security_id_valid = TRUE;
|
||||
}
|
||||
|
||||
return self->host_security_id;
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_engine_load_plugins (FuEngine *self, GError **error)
|
||||
{
|
||||
@ -5745,6 +5799,7 @@ fu_engine_finalize (GObject *obj)
|
||||
g_source_remove (self->coldplug_id);
|
||||
|
||||
g_free (self->host_machine_id);
|
||||
g_free (self->host_security_id);
|
||||
g_object_unref (self->idle);
|
||||
g_object_unref (self->config);
|
||||
g_object_unref (self->remote_list);
|
||||
|
@ -49,6 +49,7 @@ gboolean fu_engine_load_plugins (FuEngine *self,
|
||||
gboolean fu_engine_get_tainted (FuEngine *self);
|
||||
const gchar *fu_engine_get_host_product (FuEngine *self);
|
||||
const gchar *fu_engine_get_host_machine_id (FuEngine *self);
|
||||
const gchar *fu_engine_get_host_security_id (FuEngine *self);
|
||||
FwupdStatus fu_engine_get_status (FuEngine *self);
|
||||
XbSilo *fu_engine_get_silo_from_blob (FuEngine *self,
|
||||
GBytes *blob_cab,
|
||||
@ -82,6 +83,8 @@ GPtrArray *fu_engine_get_upgrades (FuEngine *self,
|
||||
FwupdDevice *fu_engine_get_results (FuEngine *self,
|
||||
const gchar *device_id,
|
||||
GError **error);
|
||||
GPtrArray *fu_engine_get_host_security_attrs (FuEngine *self,
|
||||
GError **error);
|
||||
gboolean fu_engine_clear_results (FuEngine *self,
|
||||
const gchar *device_id,
|
||||
GError **error);
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <jcat.h>
|
||||
|
||||
#include "fwupd-device-private.h"
|
||||
#include "fwupd-security-attr-private.h"
|
||||
#include "fwupd-release-private.h"
|
||||
#include "fwupd-remote-private.h"
|
||||
#include "fwupd-resources.h"
|
||||
@ -254,6 +255,22 @@ fu_main_device_array_to_variant (FuMainPrivate *priv, const gchar *sender,
|
||||
return g_variant_new ("(aa{sv})", &builder);
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
fu_main_security_attr_array_to_variant (FuMainPrivate *priv, GPtrArray *attrs)
|
||||
{
|
||||
GVariantBuilder builder;
|
||||
|
||||
g_return_val_if_fail (attrs->len > 0, NULL);
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
|
||||
|
||||
for (guint i = 0; i < attrs->len; i++) {
|
||||
FwupdSecurityAttr *security_attr = g_ptr_array_index (attrs, i);
|
||||
GVariant *tmp = fwupd_security_attr_to_variant (security_attr);
|
||||
g_variant_builder_add_value (&builder, tmp);
|
||||
}
|
||||
return g_variant_new ("(aa{sv})", &builder);
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
fu_main_release_array_to_variant (GPtrArray *results)
|
||||
{
|
||||
@ -987,6 +1004,18 @@ fu_main_daemon_method_call (GDBusConnection *connection, const gchar *sender,
|
||||
g_dbus_method_invocation_return_value (invocation, val);
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0 (method_name, "GetHostSecurityAttrs") == 0) {
|
||||
g_autoptr(GPtrArray) attrs = NULL;
|
||||
g_debug ("Called %s()", method_name);
|
||||
attrs = fu_engine_get_host_security_attrs (priv->engine, &error);
|
||||
if (attrs == NULL) {
|
||||
g_dbus_method_invocation_return_gerror (invocation, error);
|
||||
return;
|
||||
}
|
||||
val = fu_main_security_attr_array_to_variant (priv, attrs);
|
||||
g_dbus_method_invocation_return_value (invocation, val);
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0 (method_name, "ClearResults") == 0) {
|
||||
const gchar *device_id;
|
||||
g_variant_get (parameters, "(&s)", &device_id);
|
||||
@ -1388,6 +1417,9 @@ fu_main_daemon_get_property (GDBusConnection *connection_, const gchar *sender,
|
||||
if (g_strcmp0 (property_name, "HostMachineId") == 0)
|
||||
return g_variant_new_string (fu_engine_get_host_machine_id (priv->engine));
|
||||
|
||||
if (g_strcmp0 (property_name, "HostSecurityId") == 0)
|
||||
return g_variant_new_string (fu_engine_get_host_security_id (priv->engine));
|
||||
|
||||
if (g_strcmp0 (property_name, "Interactive") == 0)
|
||||
return g_variant_new_boolean (isatty (fileno (stdout)) != 0);
|
||||
|
||||
|
115
src/fu-security-attrs.c
Normal file
115
src/fu-security-attrs.c
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "fwupd-security-attr.h"
|
||||
|
||||
#include "fu-security-attrs.h"
|
||||
|
||||
gchar *
|
||||
fu_security_attrs_calculate_hsi (GPtrArray *attrs)
|
||||
{
|
||||
guint hsi_number = 0;
|
||||
FwupdSecurityAttrFlags flags = FWUPD_SECURITY_ATTR_FLAG_NONE;
|
||||
GString *str = g_string_new ("HSI:");
|
||||
const FwupdSecurityAttrFlags hpi_suffixes[] = {
|
||||
FWUPD_SECURITY_ATTR_FLAG_RUNTIME_UPDATES,
|
||||
FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ATTESTATION,
|
||||
FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ISSUE,
|
||||
FWUPD_SECURITY_ATTR_FLAG_NONE,
|
||||
};
|
||||
|
||||
/* find the highest HSI number where there are no failures and at least
|
||||
* one success */
|
||||
for (guint j = 1; j <= FWUPD_SECURITY_ATTR_LEVEL_LAST; j++) {
|
||||
gboolean success_cnt = 0;
|
||||
gboolean failure_cnt = 0;
|
||||
for (guint i = 0; i < attrs->len; i++) {
|
||||
FwupdSecurityAttr *attr = g_ptr_array_index (attrs, i);
|
||||
if (fwupd_security_attr_get_level (attr) != j)
|
||||
continue;
|
||||
if (fwupd_security_attr_has_flag (attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS))
|
||||
success_cnt++;
|
||||
else if (!fwupd_security_attr_has_flag (attr, FWUPD_SECURITY_ATTR_FLAG_OBSOLETED))
|
||||
failure_cnt++;
|
||||
}
|
||||
|
||||
/* abort */
|
||||
if (failure_cnt > 0) {
|
||||
hsi_number = j - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* we matched at least one thing on this level */
|
||||
if (success_cnt > 0)
|
||||
hsi_number = j;
|
||||
}
|
||||
|
||||
/* get a logical OR of the runtime flags */
|
||||
for (guint i = 0; i < attrs->len; i++) {
|
||||
FwupdSecurityAttr *attr = g_ptr_array_index (attrs, i);
|
||||
if (fwupd_security_attr_has_flag (attr, FWUPD_SECURITY_ATTR_FLAG_OBSOLETED))
|
||||
continue;
|
||||
/* positive things */
|
||||
if (fwupd_security_attr_has_flag (attr, FWUPD_SECURITY_ATTR_FLAG_RUNTIME_UPDATES) ||
|
||||
fwupd_security_attr_has_flag (attr, FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ATTESTATION)) {
|
||||
if (!fwupd_security_attr_has_flag (attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS))
|
||||
continue;
|
||||
}
|
||||
/* negative things */
|
||||
if (fwupd_security_attr_has_flag (attr, FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ISSUE)) {
|
||||
if (fwupd_security_attr_has_flag (attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS))
|
||||
continue;
|
||||
}
|
||||
flags |= fwupd_security_attr_get_flags (attr);
|
||||
}
|
||||
|
||||
g_string_append_printf (str, "%u", hsi_number);
|
||||
if (flags & (FWUPD_SECURITY_ATTR_FLAG_RUNTIME_UPDATES |
|
||||
FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ATTESTATION |
|
||||
FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ISSUE)) {
|
||||
g_string_append (str, "+");
|
||||
for (guint j = 0; hpi_suffixes[j] != FWUPD_SECURITY_ATTR_FLAG_NONE; j++) {
|
||||
if (flags & hpi_suffixes[j])
|
||||
g_string_append (str, fwupd_security_attr_flag_to_suffix (hpi_suffixes[j]));
|
||||
}
|
||||
}
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
fu_security_attrs_depsolve (GPtrArray *attrs)
|
||||
{
|
||||
g_autoptr(GHashTable) attrs_by_id = NULL;
|
||||
|
||||
/* make hash of ID -> object */
|
||||
attrs_by_id = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
for (guint i = 0; i < attrs->len; i++) {
|
||||
FwupdSecurityAttr *attr = g_ptr_array_index (attrs, i);
|
||||
g_hash_table_insert (attrs_by_id,
|
||||
(gpointer) fwupd_security_attr_get_appstream_id (attr),
|
||||
(gpointer) attr);
|
||||
}
|
||||
|
||||
/* set flat where required */
|
||||
for (guint i = 0; i < attrs->len; i++) {
|
||||
FwupdSecurityAttr *attr = g_ptr_array_index (attrs, i);
|
||||
GPtrArray *obsoletes = fwupd_security_attr_get_obsoletes (attr);
|
||||
for (guint j = 0; j < obsoletes->len; j++) {
|
||||
const gchar *obsolete = g_ptr_array_index (obsoletes, j);
|
||||
FwupdSecurityAttr *attr_tmp = g_hash_table_lookup (attrs_by_id, obsolete);
|
||||
if (attr_tmp != NULL) {
|
||||
g_debug ("security attr %s obsoleted by %s", obsolete,
|
||||
fwupd_security_attr_get_appstream_id (attr));
|
||||
fwupd_security_attr_add_flag (attr_tmp,
|
||||
FWUPD_SECURITY_ATTR_FLAG_OBSOLETED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
12
src/fu-security-attrs.h
Normal file
12
src/fu-security-attrs.h
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
gchar *fu_security_attrs_calculate_hsi (GPtrArray *attrs);
|
||||
void fu_security_attrs_depsolve (GPtrArray *attrs);
|
@ -25,6 +25,7 @@
|
||||
#include "fu-plugin-list.h"
|
||||
#include "fu-progressbar.h"
|
||||
#include "fu-hash.h"
|
||||
#include "fu-security-attrs.h"
|
||||
#include "fu-smbios-private.h"
|
||||
|
||||
typedef struct {
|
||||
@ -151,6 +152,75 @@ fu_engine_generate_md_func (gconstpointer user_data)
|
||||
g_assert_cmpstr (tmp, ==, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_plugin_hsi_func (gconstpointer user_data)
|
||||
{
|
||||
FwupdSecurityAttr *attr;
|
||||
g_autofree gchar *hsi1 = NULL;
|
||||
g_autofree gchar *hsi2 = NULL;
|
||||
g_autofree gchar *hsi3 = NULL;
|
||||
g_autofree gchar *hsi4 = NULL;
|
||||
g_autofree gchar *hsi5 = NULL;
|
||||
g_autofree gchar *hsi6 = NULL;
|
||||
g_autofree gchar *hsi7 = NULL;
|
||||
g_autoptr(FuEngine) engine = fu_engine_new (FU_APP_FLAGS_NONE);
|
||||
g_autoptr(GPtrArray) attrs = NULL;
|
||||
|
||||
/* no attrs */
|
||||
attrs = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
|
||||
hsi1 = fu_security_attrs_calculate_hsi (attrs);
|
||||
g_assert_cmpstr (hsi1, ==, "HSI:0");
|
||||
|
||||
/* just success from HSI:1 */
|
||||
attr = fwupd_security_attr_new ("org.fwupd.Hsi.BIOSWE");
|
||||
fwupd_security_attr_set_level (attr, 1);
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
|
||||
g_ptr_array_add (attrs, attr);
|
||||
hsi2 = fu_security_attrs_calculate_hsi (attrs);
|
||||
g_assert_cmpstr (hsi2, ==, "HSI:1");
|
||||
|
||||
/* add failed from HSI:2, so still HSI:1 */
|
||||
attr = fwupd_security_attr_new ("org.fwupd.Hsi.PRX");
|
||||
fwupd_security_attr_set_level (attr, 2);
|
||||
g_ptr_array_add (attrs, attr);
|
||||
hsi3 = fu_security_attrs_calculate_hsi (attrs);
|
||||
g_assert_cmpstr (hsi3, ==, "HSI:1");
|
||||
|
||||
/* add attr from HSI:3, obsoleting the failure */
|
||||
attr = fwupd_security_attr_new ("org.fwupd.Hsi.BIOSGuard");
|
||||
fwupd_security_attr_set_level (attr, 3);
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
|
||||
fwupd_security_attr_add_obsolete (attr, "org.fwupd.Hsi.PRX");
|
||||
g_ptr_array_add (attrs, attr);
|
||||
fu_security_attrs_depsolve (attrs);
|
||||
hsi4 = fu_security_attrs_calculate_hsi (attrs);
|
||||
g_assert_cmpstr (hsi4, ==, "HSI:3");
|
||||
|
||||
/* add taint that was fine */
|
||||
attr = fwupd_security_attr_new ("org.fwupd.Hsi.PluginsTainted");
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ISSUE);
|
||||
g_ptr_array_add (attrs, attr);
|
||||
hsi5 = fu_security_attrs_calculate_hsi (attrs);
|
||||
g_assert_cmpstr (hsi5, ==, "HSI:3");
|
||||
|
||||
/* add updates and attestation */
|
||||
attr = fwupd_security_attr_new ("org.fwupd.Hsi.LVFS");
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_RUNTIME_UPDATES);
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ATTESTATION);
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
|
||||
g_ptr_array_add (attrs, attr);
|
||||
hsi6 = fu_security_attrs_calculate_hsi (attrs);
|
||||
g_assert_cmpstr (hsi6, ==, "HSI:3+UA");
|
||||
|
||||
/* add issue that was uncool */
|
||||
attr = fwupd_security_attr_new ("org.fwupd.Hsi.Swap");
|
||||
fwupd_security_attr_add_flag (attr, FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ISSUE);
|
||||
g_ptr_array_add (attrs, attr);
|
||||
hsi7 = fu_security_attrs_calculate_hsi (attrs);
|
||||
g_assert_cmpstr (hsi7, ==, "HSI:3+UA!");
|
||||
}
|
||||
|
||||
static void
|
||||
fu_plugin_hash_func (gconstpointer user_data)
|
||||
{
|
||||
@ -2980,6 +3050,8 @@ main (int argc, char **argv)
|
||||
g_test_add_data_func ("/fwupd/progressbar", self,
|
||||
fu_progressbar_func);
|
||||
}
|
||||
g_test_add_data_func ("/fwupd/plugin{hsi}", self,
|
||||
fu_plugin_hsi_func);
|
||||
g_test_add_data_func ("/fwupd/plugin{build-hash}", self,
|
||||
fu_plugin_hash_func);
|
||||
g_test_add_data_func ("/fwupd/plugin{module}", self,
|
||||
|
@ -1937,6 +1937,38 @@ fu_util_get_remotes (FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_util_security (FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
{
|
||||
g_autoptr(GPtrArray) attrs = NULL;
|
||||
g_autofree gchar *str = NULL;
|
||||
|
||||
/* not ready yet */
|
||||
if ((priv->flags & FWUPD_INSTALL_FLAG_FORCE) == 0) {
|
||||
g_set_error_literal (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"The HSI specification is not yet complete. "
|
||||
"To ignore this warning, use --force");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!fu_util_start_engine (priv, FU_ENGINE_LOAD_FLAG_NONE, error))
|
||||
return FALSE;
|
||||
|
||||
/* TRANSLATORS: this is a string like 'HSI:2-U' */
|
||||
g_print ("%s \033[1m%s\033[0m\n", _("Host Security ID:"),
|
||||
fu_engine_get_host_security_id (priv->engine));
|
||||
|
||||
/* print the "why" */
|
||||
attrs = fu_engine_get_host_security_attrs (priv->engine, error);
|
||||
if (attrs == NULL)
|
||||
return FALSE;
|
||||
str = fu_util_security_attrs_to_string (attrs);
|
||||
g_print ("%s\n", str);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@ -2176,6 +2208,12 @@ main (int argc, char *argv[])
|
||||
/* TRANSLATORS: command description */
|
||||
_("Refresh metadata from remote server"),
|
||||
fu_util_refresh);
|
||||
fu_util_cmd_array_add (cmd_array,
|
||||
"security",
|
||||
NULL,
|
||||
/* TRANSLATORS: command description */
|
||||
_("Gets the host security attributes."),
|
||||
fu_util_security);
|
||||
|
||||
/* do stuff on ctrl+c */
|
||||
priv->cancellable = g_cancellable_new ();
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "fu-common.h"
|
||||
#include "fu-util-common.h"
|
||||
#include "fu-device.h"
|
||||
#include "fu-security-attrs.h"
|
||||
|
||||
#ifdef HAVE_SYSTEMD
|
||||
#include "fu-systemd.h"
|
||||
@ -1547,3 +1548,71 @@ fu_util_remote_to_string (FwupdRemote *remote, guint idt)
|
||||
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_security_attr_append_str (FwupdSecurityAttr *attr, GString *str)
|
||||
{
|
||||
if (fwupd_security_attr_has_flag (attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS)) {
|
||||
g_string_append_printf (str, "\033[32m✔\033[0m ");
|
||||
} else {
|
||||
g_string_append_printf (str, "\033[31m✘\033[0m ");
|
||||
}
|
||||
g_string_append_printf (str, "%s", fwupd_security_attr_get_name (attr));
|
||||
if (fwupd_security_attr_get_result (attr) != NULL) {
|
||||
g_string_append_printf (str, ": %s",
|
||||
fwupd_security_attr_get_result (attr));
|
||||
} else {
|
||||
g_string_append_printf (str, ": %s",
|
||||
fwupd_security_attr_has_flag (attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS)
|
||||
? "OK" : "Failed");
|
||||
}
|
||||
if (fwupd_security_attr_has_flag (attr, FWUPD_SECURITY_ATTR_FLAG_OBSOLETED))
|
||||
g_string_append (str, " (obsoleted)");
|
||||
g_string_append_printf (str, "\n");
|
||||
}
|
||||
|
||||
gchar *
|
||||
fu_util_security_attrs_to_string (GPtrArray *attrs)
|
||||
{
|
||||
FwupdSecurityAttrFlags flags = FWUPD_SECURITY_ATTR_FLAG_NONE;
|
||||
const FwupdSecurityAttrFlags hpi_suffixes[] = {
|
||||
FWUPD_SECURITY_ATTR_FLAG_RUNTIME_UPDATES,
|
||||
FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ATTESTATION,
|
||||
FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ISSUE,
|
||||
FWUPD_SECURITY_ATTR_FLAG_NONE,
|
||||
};
|
||||
GString *str = g_string_new (NULL);
|
||||
|
||||
for (guint j = 1; j <= FWUPD_SECURITY_ATTR_LEVEL_LAST; j++) {
|
||||
gboolean has_header = FALSE;
|
||||
for (guint i = 0; i < attrs->len; i++) {
|
||||
FwupdSecurityAttr *attr = g_ptr_array_index (attrs, i);
|
||||
if (fwupd_security_attr_get_level (attr) != j)
|
||||
continue;
|
||||
if (!has_header) {
|
||||
g_string_append_printf (str, "\n\033[1mHSI-%u\033[0m\n", j);
|
||||
has_header = TRUE;
|
||||
}
|
||||
fu_security_attr_append_str (attr, str);
|
||||
}
|
||||
}
|
||||
for (guint i = 0; i < attrs->len; i++) {
|
||||
FwupdSecurityAttr *attr = g_ptr_array_index (attrs, i);
|
||||
flags |= fwupd_security_attr_get_flags (attr);
|
||||
}
|
||||
for (guint j = 0; hpi_suffixes[j] != FWUPD_SECURITY_ATTR_FLAG_NONE; j++) {
|
||||
if (flags & hpi_suffixes[j]) {
|
||||
g_string_append_printf (str, "\n\033[1m%s -%s\033[0m\n",
|
||||
/* TRANSLATORS: this is the HSI suffix */
|
||||
_("Runtime Suffix"),
|
||||
fwupd_security_attr_flag_to_suffix (hpi_suffixes[j]));
|
||||
for (guint i = 0; i < attrs->len; i++) {
|
||||
FwupdSecurityAttr *attr = g_ptr_array_index (attrs, i);
|
||||
if (!fwupd_security_attr_has_flag (attr, hpi_suffixes[j]))
|
||||
continue;
|
||||
fu_security_attr_append_str (attr, str);
|
||||
}
|
||||
}
|
||||
}
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
@ -77,3 +77,4 @@ gchar *fu_util_release_to_string (FwupdRelease *rel,
|
||||
guint idt);
|
||||
gchar *fu_util_remote_to_string (FwupdRemote *remote,
|
||||
guint idt);
|
||||
gchar *fu_util_security_attrs_to_string (GPtrArray *attrs);
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "fu-history.h"
|
||||
#include "fu-plugin-private.h"
|
||||
#include "fu-progressbar.h"
|
||||
#include "fu-security-attrs.h"
|
||||
#include "fu-util-common.h"
|
||||
#include "fwupd-common-private.h"
|
||||
|
||||
@ -2364,6 +2365,37 @@ fu_util_modify_config (FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_util_security (FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
{
|
||||
g_autoptr(GPtrArray) attrs = NULL;
|
||||
g_autofree gchar *str = NULL;
|
||||
|
||||
/* not ready yet */
|
||||
if ((priv->flags & FWUPD_INSTALL_FLAG_FORCE) == 0) {
|
||||
g_set_error_literal (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"The HSI specification is not yet complete. "
|
||||
"To ignore this warning, use --force");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* TRANSLATORS: this is a string like 'HSI:2-U' */
|
||||
g_print ("%s \033[1m%s\033[0m\n", _("Host Security ID:"),
|
||||
fwupd_client_get_host_security_id (priv->client));
|
||||
|
||||
/* print the "why" */
|
||||
attrs = fwupd_client_get_host_security_attrs (priv->client,
|
||||
priv->cancellable,
|
||||
error);
|
||||
if (attrs == NULL)
|
||||
return FALSE;
|
||||
str = fu_util_security_attrs_to_string (attrs);
|
||||
g_print ("%s\n", str);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_util_ignore_cb (const gchar *log_domain, GLogLevelFlags log_level,
|
||||
const gchar *message, gpointer user_data)
|
||||
@ -2678,7 +2710,12 @@ main (int argc, char *argv[])
|
||||
/* TRANSLATORS: command description */
|
||||
_("Reinstall current firmware on the device."),
|
||||
fu_util_reinstall);
|
||||
|
||||
fu_util_cmd_array_add (cmd_array,
|
||||
"security",
|
||||
NULL,
|
||||
/* TRANSLATORS: command description */
|
||||
_("Gets the host security attributes."),
|
||||
fu_util_security);
|
||||
|
||||
/* do stuff on ctrl+c */
|
||||
priv->cancellable = g_cancellable_new ();
|
||||
|
@ -131,6 +131,7 @@ fwupdtool = executable(
|
||||
'fu-plugin-list.c',
|
||||
'fu-progressbar.c',
|
||||
'fu-remote-list.c',
|
||||
'fu-security-attrs.c',
|
||||
'fu-util-common.c',
|
||||
systemd_src
|
||||
],
|
||||
@ -229,6 +230,7 @@ executable(
|
||||
'fu-main.c',
|
||||
'fu-plugin-list.c',
|
||||
'fu-remote-list.c',
|
||||
'fu-security-attrs.c',
|
||||
systemd_src
|
||||
],
|
||||
include_directories : [
|
||||
@ -285,6 +287,7 @@ if get_option('tests')
|
||||
'fu-plugin-list.c',
|
||||
'fu-progressbar.c',
|
||||
'fu-remote-list.c',
|
||||
'fu-security-attrs.c',
|
||||
'fu-self-test.c',
|
||||
systemd_src
|
||||
],
|
||||
|
@ -44,6 +44,17 @@
|
||||
</doc:doc>
|
||||
</property>
|
||||
|
||||
<!--***********************************************************-->
|
||||
<property name='HostSecurityId' type='s' access='read'>
|
||||
<doc:doc>
|
||||
<doc:description>
|
||||
<doc:para>
|
||||
The Host Security ID, for instance <doc:tt>HSI:2UA</doc:tt>
|
||||
</doc:para>
|
||||
</doc:description>
|
||||
</doc:doc>
|
||||
</property>
|
||||
|
||||
<!--***********************************************************-->
|
||||
<property name='Tainted' type='b' access='read'>
|
||||
<doc:doc>
|
||||
@ -242,6 +253,24 @@
|
||||
</arg>
|
||||
</method>
|
||||
|
||||
<!--***********************************************************-->
|
||||
<method name='GetHostSecurityAttrs'>
|
||||
<doc:doc>
|
||||
<doc:description>
|
||||
<doc:para>
|
||||
Gets a list of all the Host Security ID attributes.
|
||||
</doc:para>
|
||||
</doc:description>
|
||||
</doc:doc>
|
||||
<arg type='aa{sv}' name='attrs' direction='out'>
|
||||
<doc:doc>
|
||||
<doc:summary>
|
||||
<doc:para>An array of HSI attributes, with any properties set on each.</doc:para>
|
||||
</doc:summary>
|
||||
</doc:doc>
|
||||
</arg>
|
||||
</method>
|
||||
|
||||
<!--***********************************************************-->
|
||||
<method name='Install'>
|
||||
<doc:doc>
|
||||
|
Loading…
Reference in New Issue
Block a user