diff --git a/libfwupd/fwupd-enums.c b/libfwupd/fwupd-enums.c index 0f01a19ae..54ea1a850 100644 --- a/libfwupd/fwupd-enums.c +++ b/libfwupd/fwupd-enums.c @@ -169,6 +169,10 @@ fwupd_device_flag_to_string (FwupdDeviceFlags device_flag) return "only-supported"; if (device_flag == FWUPD_DEVICE_FLAG_WILL_DISAPPEAR) return "will-disappear"; + if (device_flag == FWUPD_DEVICE_FLAG_CAN_VERIFY) + return "can-verify"; + if (device_flag == FWUPD_DEVICE_FLAG_CAN_VERIFY_IMAGE) + return "can-verify-image"; if (device_flag == FWUPD_DEVICE_FLAG_UNKNOWN) return "unknown"; return NULL; @@ -239,6 +243,10 @@ fwupd_device_flag_from_string (const gchar *device_flag) return FWUPD_DEVICE_FLAG_ONLY_SUPPORTED; if (g_strcmp0 (device_flag, "will-disappear") == 0) return FWUPD_DEVICE_FLAG_WILL_DISAPPEAR; + if (g_strcmp0 (device_flag, "can-verify") == 0) + return FWUPD_DEVICE_FLAG_CAN_VERIFY; + if (g_strcmp0 (device_flag, "can-verify-image") == 0) + return FWUPD_DEVICE_FLAG_CAN_VERIFY_IMAGE; return FWUPD_DEVICE_FLAG_UNKNOWN; } diff --git a/libfwupd/fwupd-enums.h b/libfwupd/fwupd-enums.h index 08e9edef2..224a16b39 100644 --- a/libfwupd/fwupd-enums.h +++ b/libfwupd/fwupd-enums.h @@ -92,6 +92,8 @@ typedef enum { * @FWUPD_DEVICE_FLAG_ENSURE_SEMVER: Ensure the version is a valid semantic version, e.g. numbers separated with dots * @FWUPD_DEVICE_FLAG_ONLY_SUPPORTED: Only devices supported in the metadata will be opened * @FWUPD_DEVICE_FLAG_WILL_DISAPPEAR: Device will disappear after update and can't be verified + * @FWUPD_DEVICE_FLAG_CAN_VERIFY: Device checksums can be compared against metadata + * @FWUPD_DEVICE_FLAG_CAN_VERIFY_IMAGE: Image can be dumped from device for verification * * The device flags. **/ @@ -121,6 +123,8 @@ typedef enum { #define FWUPD_DEVICE_FLAG_HISTORICAL (1u << 22) /* Since: 1.3.2 */ #define FWUPD_DEVICE_FLAG_ONLY_SUPPORTED (1u << 23) /* Since: 1.3.3 */ #define FWUPD_DEVICE_FLAG_WILL_DISAPPEAR (1u << 24) /* Since: 1.3.3 */ +#define FWUPD_DEVICE_FLAG_CAN_VERIFY (1u << 25) /* Since: 1.3.3 */ +#define FWUPD_DEVICE_FLAG_CAN_VERIFY_IMAGE (1u << 26) /* Since: 1.3.3 */ #define FWUPD_DEVICE_FLAG_UNKNOWN G_MAXUINT64 /* Since: 0.7.3 */ typedef guint64 FwupdDeviceFlags; diff --git a/plugins/optionrom/fu-optionrom-device.c b/plugins/optionrom/fu-optionrom-device.c index 27c977fe4..494fb005a 100644 --- a/plugins/optionrom/fu-optionrom-device.c +++ b/plugins/optionrom/fu-optionrom-device.c @@ -91,6 +91,7 @@ fu_optionrom_device_init (FuOptionromDevice *self) { fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_INTERNAL); fu_device_add_icon (FU_DEVICE (self), "audio-card"); + fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_CAN_VERIFY_IMAGE); } static void diff --git a/plugins/superio/fu-superio-device.c b/plugins/superio/fu-superio-device.c index 9d2d5cfa0..63a03b7a6 100644 --- a/plugins/superio/fu-superio-device.c +++ b/plugins/superio/fu-superio-device.c @@ -448,6 +448,7 @@ fu_superio_device_init (FuSuperioDevice *self) { fu_device_set_physical_id (FU_DEVICE (self), "/dev/port"); fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_INTERNAL); + fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_CAN_VERIFY_IMAGE); fu_device_set_summary (FU_DEVICE (self), "Embedded Controller"); fu_device_add_icon (FU_DEVICE (self), "computer"); } diff --git a/plugins/superio/fu-superio-it89-device.c b/plugins/superio/fu-superio-it89-device.c index fda199c70..d226c0c49 100644 --- a/plugins/superio/fu-superio-it89-device.c +++ b/plugins/superio/fu-superio-it89-device.c @@ -468,7 +468,7 @@ fu_superio_it89_device_detach (FuDevice *device, GError **error) } /* success */ - fu_device_add_flag (self, FWUPD_DEVICE_FLAG_IS_BOOTLOADER); + fu_device_add_flag (device, FWUPD_DEVICE_FLAG_IS_BOOTLOADER); return TRUE; } diff --git a/plugins/synaptics-prometheus/fu-synaprom-device.c b/plugins/synaptics-prometheus/fu-synaprom-device.c index 74906a874..1171055e6 100644 --- a/plugins/synaptics-prometheus/fu-synaprom-device.c +++ b/plugins/synaptics-prometheus/fu-synaprom-device.c @@ -434,6 +434,7 @@ static void fu_synaprom_device_init (FuSynapromDevice *self) { fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE); + fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_CAN_VERIFY); fu_device_set_remove_delay (FU_DEVICE (self), FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE); fu_device_set_name (FU_DEVICE (self), "Prometheus"); fu_device_set_summary (FU_DEVICE (self), "Fingerprint reader"); diff --git a/plugins/test/fu-plugin-test.c b/plugins/test/fu-plugin-test.c index 4d586cb0d..de1462678 100644 --- a/plugins/test/fu-plugin-test.c +++ b/plugins/test/fu-plugin-test.c @@ -41,6 +41,7 @@ fu_plugin_coldplug (FuPlugin *plugin, GError **error) fu_device_set_name (device, "Integrated_Webcam(TM)"); fu_device_add_icon (device, "preferences-desktop-keyboard"); fu_device_add_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE); + fu_device_add_flag (device, FWUPD_DEVICE_FLAG_CAN_VERIFY); fu_device_set_summary (device, "A fake webcam"); fu_device_set_vendor (device, "ACME Corp."); fu_device_set_vendor_id (device, "USB:0x046D"); diff --git a/plugins/uefi/fu-uefi-device.c b/plugins/uefi/fu-uefi-device.c index 0d88aaf44..554733c58 100644 --- a/plugins/uefi/fu-uefi-device.c +++ b/plugins/uefi/fu-uefi-device.c @@ -554,6 +554,7 @@ fu_uefi_device_probe (FuDevice *device, GError **error) /* set the PCR0 as the device checksum */ if (self->kind == FU_UEFI_DEVICE_KIND_SYSTEM_FIRMWARE) { g_autoptr(GError) error_local = NULL; + fu_device_add_flag (device, FWUPD_DEVICE_FLAG_CAN_VERIFY); if (!fu_uefi_device_add_system_checksum (device, &error_local)) g_warning ("Failed to get PCR0s: %s", error_local->message); } diff --git a/src/fu-device.c b/src/fu-device.c index 6adfa1267..c1b7f5750 100644 --- a/src/fu-device.c +++ b/src/fu-device.c @@ -1405,6 +1405,14 @@ fu_device_get_physical_id (FuDevice *self) return priv->physical_id; } +void +fu_device_add_flag (FuDevice *self, FwupdDeviceFlags flag) +{ + if (flag & FWUPD_DEVICE_FLAG_CAN_VERIFY_IMAGE) + flag |= FWUPD_DEVICE_FLAG_CAN_VERIFY; + fwupd_device_add_flag (FWUPD_DEVICE (self), flag); +} + static void fu_device_set_custom_flag (FuDevice *self, const gchar *hint) { @@ -1911,8 +1919,10 @@ fu_device_read_firmware (FuDevice *self, GError **error) g_return_val_if_fail (FU_IS_DEVICE (self), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); - /* no plugin-specific method */ - if (klass->read_firmware == NULL) { + + /* no plugin-specific method or device doesn't support */ + if (!fu_device_has_flag (self, FWUPD_DEVICE_FLAG_CAN_VERIFY_IMAGE) || + klass->read_firmware == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, diff --git a/src/fu-device.h b/src/fu-device.h index 68b556dc2..6365103ee 100644 --- a/src/fu-device.h +++ b/src/fu-device.h @@ -83,7 +83,6 @@ struct _FuDeviceClass FuDevice *fu_device_new (void); /* helpful casting macros */ -#define fu_device_add_flag(d,v) fwupd_device_add_flag(FWUPD_DEVICE(d),v) #define fu_device_remove_flag(d,v) fwupd_device_remove_flag(FWUPD_DEVICE(d),v) #define fu_device_has_flag(d,v) fwupd_device_has_flag(FWUPD_DEVICE(d),v) #define fu_device_has_instance_id(d,v) fwupd_device_has_instance_id(FWUPD_DEVICE(d),v) @@ -179,6 +178,8 @@ void fu_device_set_physical_id (FuDevice *self, const gchar *fu_device_get_logical_id (FuDevice *self); void fu_device_set_logical_id (FuDevice *self, const gchar *logical_id); +void fu_device_add_flag (FuDevice *self, + FwupdDeviceFlags flag); const gchar *fu_device_get_custom_flags (FuDevice *self); gboolean fu_device_has_custom_flag (FuDevice *self, const gchar *hint); diff --git a/src/fu-engine.c b/src/fu-engine.c index 5d738a996..dafa6daf9 100644 --- a/src/fu-engine.c +++ b/src/fu-engine.c @@ -827,10 +827,12 @@ fu_engine_verify (FuEngine *self, const gchar *device_id, GError **error) if (plugin == NULL) return FALSE; - /* set the device firmware hash */ - if (!fu_plugin_runner_verify (plugin, device, - FU_PLUGIN_VERIFY_FLAG_NONE, error)) - return FALSE; + /* update the device firmware hashes if possible */ + if (fu_device_has_flag (device, FWUPD_DEVICE_FLAG_CAN_VERIFY_IMAGE)) { + if (!fu_plugin_runner_verify (plugin, device, + FU_PLUGIN_VERIFY_FLAG_NONE, error)) + return FALSE; + } /* find component in metadata */ version = fu_device_get_version (device); @@ -874,7 +876,7 @@ fu_engine_verify (FuEngine *self, const gchar *device_id, GError **error) g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND, - "No version %s", version); + "No release found for version %s", version); return FALSE; } diff --git a/src/fu-plugin.c b/src/fu-plugin.c index 8ee58a107..c85f54ac8 100644 --- a/src/fu-plugin.c +++ b/src/fu-plugin.c @@ -1752,7 +1752,6 @@ fu_plugin_runner_verify (FuPlugin *self, /* optional */ g_module_symbol (priv->module, "fu_plugin_verify", (gpointer *) &func); if (func == NULL) { - g_debug ("running superclassed read_firmware() on %s", priv->name); return fu_plugin_device_read_firmware (self, device, error); } diff --git a/src/fu-util.c b/src/fu-util.c index 02445f735..6f5fd4754 100644 --- a/src/fu-util.c +++ b/src/fu-util.c @@ -1056,6 +1056,7 @@ fu_util_verify_update (FuUtilPrivate *priv, gchar **values, GError **error) { g_autoptr(FwupdDevice) dev = NULL; + priv->filter_include |= FWUPD_DEVICE_FLAG_CAN_VERIFY; dev = fu_util_get_device_or_prompt (priv, values, error); if (dev == NULL) return FALSE; @@ -1489,6 +1490,7 @@ fu_util_verify (FuUtilPrivate *priv, gchar **values, GError **error) { g_autoptr(FwupdDevice) dev = NULL; + priv->filter_include |= FWUPD_DEVICE_FLAG_CAN_VERIFY; dev = fu_util_get_device_or_prompt (priv, values, error); if (dev == NULL) return FALSE; @@ -2450,7 +2452,7 @@ main (int argc, char *argv[]) "verify", "[DEVICE_ID]", /* TRANSLATORS: command description */ - _("Gets the cryptographic hash of the dumped firmware"), + _("Checks cryptographic hash matches firmware"), fu_util_verify); fu_util_cmd_array_add (cmd_array, "unlock", @@ -2504,7 +2506,7 @@ main (int argc, char *argv[]) "verify-update", "[DEVICE_ID]", /* TRANSLATORS: command description */ - _("Update the stored metadata with current ROM contents"), + _("Update the stored cryptographic hash with current ROM contents"), fu_util_verify_update); fu_util_cmd_array_add (cmd_array, "modify-remote",