diff --git a/libfwupd/README.md b/libfwupd/README.md index 48f307a15..51702f621 100644 --- a/libfwupd/README.md +++ b/libfwupd/README.md @@ -6,6 +6,7 @@ When we next bump soname the following changes are planned: * {sa{sv}} -> {a{sv}} -- we don't always want to send the device ID * Rename FU_DEVICE_FLAG -> FWUPD_DEVICE_FLAG * Remove all deprecated API + * Remove FWUPD_RESULT_KEY_DEVICE_CHECKSUM_KIND * Rename GetDetailsLocal() -> GetDetails() * Rename UpdateMetadataWithId() -> UpdateMetadata() * Make DeviceAdded emit a FwupdDevice, not a FwupdResult diff --git a/libfwupd/fwupd-common-private.h b/libfwupd/fwupd-common-private.h new file mode 100644 index 000000000..22de34b4f --- /dev/null +++ b/libfwupd/fwupd-common-private.h @@ -0,0 +1,30 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Copyright (C) 2017 Richard Hughes + * + * Licensed under the GNU Lesser General Public License Version 2.1 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __FWUPD_COMMON_PRIVATE_H +#define __FWUPD_COMMON_PRIVATE_H + +#include + +GChecksumType fwupd_checksum_guess_kind (const gchar *checksum); +gchar *fwupd_checksum_format_for_display (const gchar *checksum); + +#endif /* __FWUPD_COMMON_PRIVATE_H */ diff --git a/libfwupd/fwupd-common.c b/libfwupd/fwupd-common.c new file mode 100644 index 000000000..04e89751b --- /dev/null +++ b/libfwupd/fwupd-common.c @@ -0,0 +1,85 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Copyright (C) 2017 Richard Hughes + * + * Licensed under the GNU Lesser General Public License Version 2.1 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include "fwupd-common-private.h" + +#include + +/** + * fwupd_checksum_guess_kind: + * @checksum: A checksum + * + * Guesses the checksum kind based on the length of the hash. + * + * Returns: a #GChecksumType, e.g. %G_CHECKSUM_SHA1 + * + * Since: 0.9.3 + **/ +GChecksumType +fwupd_checksum_guess_kind (const gchar *checksum) +{ + guint len; + if (checksum == NULL) + return G_CHECKSUM_SHA1; + len = strlen (checksum); + if (len == 32) + return G_CHECKSUM_MD5; + if (len == 40) + return G_CHECKSUM_SHA1; + if (len == 64) + return G_CHECKSUM_SHA256; + if (len == 128) + return G_CHECKSUM_SHA512; + return G_CHECKSUM_SHA1; +} + +static const gchar * +_g_checksum_type_to_string (GChecksumType checksum_type) +{ + if (checksum_type == G_CHECKSUM_MD5) + return "MD5"; + if (checksum_type == G_CHECKSUM_SHA1) + return "SHA1"; + if (checksum_type == G_CHECKSUM_SHA256) + return "SHA256"; + if (checksum_type == G_CHECKSUM_SHA512) + return "SHA512"; + return NULL; +} + +/** + * fwupd_checksum_format_for_display: + * @checksum: A checksum + * + * Formats a checksum for display. + * + * Returns: text, or %NULL for invalid + * + * Since: 0.9.3 + **/ +gchar * +fwupd_checksum_format_for_display (const gchar *checksum) +{ + GChecksumType kind = fwupd_checksum_guess_kind (checksum); + return g_strdup_printf ("%s(%s)", _g_checksum_type_to_string (kind), checksum); +} diff --git a/libfwupd/fwupd-device.c b/libfwupd/fwupd-device.c index 613a1d12b..ae78ee766 100644 --- a/libfwupd/fwupd-device.c +++ b/libfwupd/fwupd-device.c @@ -25,6 +25,7 @@ #include #include +#include "fwupd-common-private.h" #include "fwupd-enums-private.h" #include "fwupd-error.h" #include "fwupd-device-private.h" @@ -47,8 +48,7 @@ typedef struct { gchar *version; gchar *version_lowest; gchar *version_bootloader; - gchar *checksum; - GChecksumType checksum_kind; + GPtrArray *checksums; guint32 flashes_left; } FwupdDevicePrivate; @@ -56,25 +56,25 @@ G_DEFINE_TYPE_WITH_PRIVATE (FwupdDevice, fwupd_device, G_TYPE_OBJECT) #define GET_PRIVATE(o) (fwupd_device_get_instance_private (o)) /** - * fwupd_device_get_checksum: + * fwupd_device_get_checksums: * @device: A #FwupdDevice * - * Gets the device checksum. + * Gets the device checksums. * - * Returns: the device checksum, or %NULL if unset + * Returns: (element-type utf8) (transfer none): the checksums, which may be empty * * Since: 0.9.3 **/ -const gchar * -fwupd_device_get_checksum (FwupdDevice *device) +GPtrArray * +fwupd_device_get_checksums (FwupdDevice *device) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL); - return priv->checksum; + return priv->checksums; } /** - * fwupd_device_set_checksum: + * fwupd_device_add_checksum: * @device: A #FwupdDevice * @checksum: the device checksum * @@ -83,47 +83,12 @@ fwupd_device_get_checksum (FwupdDevice *device) * Since: 0.9.3 **/ void -fwupd_device_set_checksum (FwupdDevice *device, const gchar *checksum) +fwupd_device_add_checksum (FwupdDevice *device, const gchar *checksum) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (FWUPD_IS_DEVICE (device)); - g_free (priv->checksum); - priv->checksum = g_strdup (checksum); -} - -/** - * fwupd_device_get_checksum_kind: - * @device: A #FwupdDevice - * - * Gets the device checkum kind. - * - * Returns: the #GChecksumType - * - * Since: 0.9.3 - **/ -GChecksumType -fwupd_device_get_checksum_kind (FwupdDevice *device) -{ - FwupdDevicePrivate *priv = GET_PRIVATE (device); - g_return_val_if_fail (FWUPD_IS_DEVICE (device), 0); - return priv->checksum_kind; -} - -/** - * fwupd_device_set_checksum_kind: - * @device: A #FwupdDevice - * @checkum_kind: the checksum kind, e.g. %G_CHECKSUM_SHA1 - * - * Sets the device checkum kind. - * - * Since: 0.9.3 - **/ -void -fwupd_device_set_checksum_kind (FwupdDevice *device, GChecksumType checkum_kind) -{ - FwupdDevicePrivate *priv = GET_PRIVATE (device); - g_return_if_fail (FWUPD_IS_DEVICE (device)); - priv->checksum_kind = checkum_kind; + g_return_if_fail (checksum != NULL); + g_ptr_array_add (priv->checksums, g_strdup (checksum)); } /** @@ -776,13 +741,17 @@ fwupd_device_to_variant_builder (FwupdDevice *device, GVariantBuilder *builder) FWUPD_RESULT_KEY_DEVICE_DESCRIPTION, g_variant_new_string (priv->description)); } - if (priv->checksum != NULL) { + if (priv->checksums->len > 0) { + g_autoptr(GString) str = g_string_new (""); + for (guint i = 0; i < priv->checksums->len; i++) { + const gchar *checksum = g_ptr_array_index (priv->checksums, i); + g_string_append_printf (str, "%s,", checksum); + } + if (str->len > 0) + g_string_truncate (str, str->len - 1); g_variant_builder_add (builder, "{sv}", FWUPD_RESULT_KEY_DEVICE_CHECKSUM, - g_variant_new_string (priv->checksum)); - g_variant_builder_add (builder, "{sv}", - FWUPD_RESULT_KEY_DEVICE_CHECKSUM_KIND, - g_variant_new_uint32 (priv->checksum_kind)); + g_variant_new_string (str->str)); } if (priv->provider != NULL) { g_variant_builder_add (builder, "{sv}", @@ -878,11 +847,11 @@ fwupd_device_from_key_value (FwupdDevice *device, const gchar *key, GVariant *va return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_DEVICE_CHECKSUM) == 0) { - fwupd_device_set_checksum (device, g_variant_get_string (value, NULL)); - return; - } - if (g_strcmp0 (key, FWUPD_RESULT_KEY_DEVICE_CHECKSUM_KIND) == 0) { - fwupd_device_set_checksum_kind (device, g_variant_get_uint32 (value)); + guint i; + const gchar *checksums = g_variant_get_string (value, NULL); + g_auto(GStrv) split = g_strsplit (checksums, ",", -1); + for (i = 0; split[i] != NULL; i++) + fwupd_device_add_checksum (device, split[i]); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_DEVICE_PLUGIN) == 0) { @@ -934,19 +903,6 @@ fwupd_pad_kv_unx (GString *str, const gchar *key, guint64 value) fwupd_pad_kv_str (str, key, tmp); } -static void -fwupd_pad_kv_csk (GString *str, const gchar *key, GChecksumType checksum_type) -{ - const gchar *tmp = "unknown"; - if (checksum_type == G_CHECKSUM_SHA1) - tmp = "sha1"; - else if (checksum_type == G_CHECKSUM_SHA256) - tmp = "sha256"; - else if (checksum_type == G_CHECKSUM_SHA512) - tmp = "sha512"; - fwupd_pad_kv_str (str, key, tmp); -} - static void fwupd_pad_kv_dfl (GString *str, const gchar *key, guint64 device_flags) { @@ -1007,9 +963,11 @@ fwupd_device_to_string (FwupdDevice *device) fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DEVICE_DESCRIPTION, priv->description); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DEVICE_PLUGIN, priv->provider); fwupd_pad_kv_dfl (str, FWUPD_RESULT_KEY_DEVICE_FLAGS, priv->flags); - fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DEVICE_CHECKSUM, priv->checksum); - if (priv->checksum != NULL) - fwupd_pad_kv_csk (str, FWUPD_RESULT_KEY_DEVICE_CHECKSUM_KIND, priv->checksum_kind); + for (guint i = 0; i < priv->checksums->len; i++) { + const gchar *checksum = g_ptr_array_index (priv->checksums, i); + g_autofree gchar *checksum_display = fwupd_checksum_format_for_display (checksum); + fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DEVICE_CHECKSUM, checksum_display); + } fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DEVICE_VENDOR, priv->vendor); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DEVICE_VERSION, priv->version); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DEVICE_VERSION_LOWEST, priv->version_lowest); @@ -1034,7 +992,7 @@ fwupd_device_init (FwupdDevice *device) { FwupdDevicePrivate *priv = GET_PRIVATE (device); priv->guids = g_ptr_array_new_with_free_func (g_free); - priv->checksum_kind = G_CHECKSUM_SHA1; + priv->checksums = g_ptr_array_new_with_free_func (g_free); } static void @@ -1044,7 +1002,6 @@ fwupd_device_finalize (GObject *object) FwupdDevicePrivate *priv = GET_PRIVATE (device); g_free (priv->description); - g_free (priv->checksum); g_free (priv->id); g_free (priv->name); g_free (priv->vendor); @@ -1053,6 +1010,7 @@ fwupd_device_finalize (GObject *object) g_free (priv->version_lowest); g_free (priv->version_bootloader); g_ptr_array_unref (priv->guids); + g_ptr_array_unref (priv->checksums); G_OBJECT_CLASS (fwupd_device_parent_class)->finalize (object); } diff --git a/libfwupd/fwupd-device.h b/libfwupd/fwupd-device.h index 9fc2f5ba0..cc5fcc8ea 100644 --- a/libfwupd/fwupd-device.h +++ b/libfwupd/fwupd-device.h @@ -86,12 +86,9 @@ void fwupd_device_set_created (FwupdDevice *device, guint64 fwupd_device_get_modified (FwupdDevice *device); void fwupd_device_set_modified (FwupdDevice *device, guint64 modified); -const gchar *fwupd_device_get_checksum (FwupdDevice *device); -void fwupd_device_set_checksum (FwupdDevice *device, +GPtrArray *fwupd_device_get_checksums (FwupdDevice *device); +void fwupd_device_add_checksum (FwupdDevice *device, const gchar *checksum); -GChecksumType fwupd_device_get_checksum_kind (FwupdDevice *device); -void fwupd_device_set_checksum_kind (FwupdDevice *device, - GChecksumType checkum_kind); const gchar *fwupd_device_get_provider (FwupdDevice *device); void fwupd_device_set_provider (FwupdDevice *device, const gchar *provider); diff --git a/libfwupd/fwupd-release.c b/libfwupd/fwupd-release.c index da82c62ef..65bc67325 100644 --- a/libfwupd/fwupd-release.c +++ b/libfwupd/fwupd-release.c @@ -25,6 +25,7 @@ #include #include +#include "fwupd-common-private.h" #include "fwupd-enums-private.h" #include "fwupd-error.h" #include "fwupd-release-private.h" @@ -32,8 +33,7 @@ static void fwupd_release_finalize (GObject *object); typedef struct { - gchar *checksum; - GChecksumType checksum_kind; + GPtrArray *checksums; gchar *description; gchar *filename; gchar *homepage; @@ -160,25 +160,25 @@ fwupd_release_set_filename (FwupdRelease *release, const gchar *filename) } /** - * fwupd_release_get_checksum: - * @release: A #FwupdRelease + * fwupd_device_get_checksums: + * @device: A #FwupdDevice * - * Gets the update checksum. + * Gets the device checksums. * - * Returns: the update checksum, or %NULL if unset + * Returns: (element-type utf8) (transfer none): the checksums, which may be empty * * Since: 0.9.3 **/ -const gchar * -fwupd_release_get_checksum (FwupdRelease *release) +GPtrArray * +fwupd_release_get_checksums (FwupdRelease *release) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL); - return priv->checksum; + return priv->checksums; } /** - * fwupd_release_set_checksum: + * fwupd_release_add_checksum: * @release: A #FwupdRelease * @checksum: the update checksum * @@ -187,47 +187,12 @@ fwupd_release_get_checksum (FwupdRelease *release) * Since: 0.9.3 **/ void -fwupd_release_set_checksum (FwupdRelease *release, const gchar *checksum) +fwupd_release_add_checksum (FwupdRelease *release, const gchar *checksum) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_if_fail (FWUPD_IS_RELEASE (release)); - g_free (priv->checksum); - priv->checksum = g_strdup (checksum); -} - -/** - * fwupd_release_get_checksum_kind: - * @release: A #FwupdRelease - * - * Gets the update checkum kind. - * - * Returns: the #GChecksumType - * - * Since: 0.9.3 - **/ -GChecksumType -fwupd_release_get_checksum_kind (FwupdRelease *release) -{ - FwupdReleasePrivate *priv = GET_PRIVATE (release); - g_return_val_if_fail (FWUPD_IS_RELEASE (release), 0); - return priv->checksum_kind; -} - -/** - * fwupd_release_set_checksum_kind: - * @release: A #FwupdRelease - * @checkum_kind: the checksum kind, e.g. %G_CHECKSUM_SHA1 - * - * Sets the update checkum kind. - * - * Since: 0.9.3 - **/ -void -fwupd_release_set_checksum_kind (FwupdRelease *release, GChecksumType checkum_kind) -{ - FwupdReleasePrivate *priv = GET_PRIVATE (release); - g_return_if_fail (FWUPD_IS_RELEASE (release)); - priv->checksum_kind = checkum_kind; + g_return_if_fail (checksum != NULL); + g_ptr_array_add (priv->checksums, g_strdup (checksum)); } /** @@ -597,13 +562,18 @@ fwupd_release_to_variant_builder (FwupdRelease *release, GVariantBuilder *builde FWUPD_RESULT_KEY_UPDATE_DESCRIPTION, g_variant_new_string (priv->description)); } - if (priv->checksum != NULL) { + if (priv->checksums->len > 0) { + guint i; + g_autoptr(GString) str = g_string_new (""); + for (i = 0; i < priv->checksums->len; i++) { + const gchar *checksum = g_ptr_array_index (priv->checksums, i); + g_string_append_printf (str, "%s,", checksum); + } + if (str->len > 0) + g_string_truncate (str, str->len - 1); g_variant_builder_add (builder, "{sv}", FWUPD_RESULT_KEY_UPDATE_CHECKSUM, - g_variant_new_string (priv->checksum)); - g_variant_builder_add (builder, "{sv}", - FWUPD_RESULT_KEY_UPDATE_CHECKSUM_KIND, - g_variant_new_uint32 (priv->checksum_kind)); + g_variant_new_string (str->str)); } if (priv->uri != NULL) { g_variant_builder_add (builder, "{sv}", @@ -694,11 +664,10 @@ fwupd_release_from_key_value (FwupdRelease *release, const gchar *key, GVariant return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_CHECKSUM) == 0) { - fwupd_release_set_checksum (release, g_variant_get_string (value, NULL)); - return; - } - if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_CHECKSUM_KIND) == 0) { - fwupd_release_set_checksum_kind (release, g_variant_get_uint32 (value)); + const gchar *checksums = g_variant_get_string (value, NULL); + g_auto(GStrv) split = g_strsplit (checksums, ",", -1); + for (guint i = 0; split[i] != NULL; i++) + fwupd_release_add_checksum (release, split[i]); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_URI) == 0) { @@ -731,19 +700,6 @@ fwupd_pad_kv_str (GString *str, const gchar *key, const gchar *value) g_string_append_printf (str, "%s\n", value); } -static void -fwupd_pad_kv_csk (GString *str, const gchar *key, GChecksumType checksum_type) -{ - const gchar *tmp = "unknown"; - if (checksum_type == G_CHECKSUM_SHA1) - tmp = "sha1"; - else if (checksum_type == G_CHECKSUM_SHA256) - tmp = "sha256"; - else if (checksum_type == G_CHECKSUM_SHA512) - tmp = "sha512"; - fwupd_pad_kv_str (str, key, tmp); -} - static void fwupd_pad_kv_siz (GString *str, const gchar *key, guint64 value) { @@ -781,9 +737,11 @@ fwupd_release_to_string (FwupdRelease *release) fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_DESCRIPTION, priv->description); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_VERSION, priv->version); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_FILENAME, priv->filename); - fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_CHECKSUM, priv->checksum); - if (priv->checksum != NULL) - fwupd_pad_kv_csk (str, FWUPD_RESULT_KEY_UPDATE_CHECKSUM_KIND, priv->checksum_kind); + for (guint i = 0; i < priv->checksums->len; i++) { + const gchar *checksum = g_ptr_array_index (priv->checksums, i); + g_autofree gchar *checksum_display = fwupd_checksum_format_for_display (checksum); + fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_CHECKSUM, checksum_display); + } fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_LICENSE, priv->license); fwupd_pad_kv_siz (str, FWUPD_RESULT_KEY_UPDATE_SIZE, priv->size); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_URI, priv->uri); @@ -804,7 +762,7 @@ static void fwupd_release_init (FwupdRelease *release) { FwupdReleasePrivate *priv = GET_PRIVATE (release); - priv->checksum_kind = G_CHECKSUM_SHA1; + priv->checksums = g_ptr_array_new_with_free_func (g_free); } static void @@ -815,7 +773,6 @@ fwupd_release_finalize (GObject *object) g_free (priv->description); g_free (priv->filename); - g_free (priv->checksum); g_free (priv->appstream_id); g_free (priv->license); g_free (priv->name); @@ -825,6 +782,7 @@ fwupd_release_finalize (GObject *object) g_free (priv->vendor); g_free (priv->version); g_free (priv->remote_id); + g_ptr_array_unref (priv->checksums); G_OBJECT_CLASS (fwupd_release_parent_class)->finalize (object); } diff --git a/libfwupd/fwupd-release.h b/libfwupd/fwupd-release.h index f84b2341b..79be0ef9a 100644 --- a/libfwupd/fwupd-release.h +++ b/libfwupd/fwupd-release.h @@ -53,12 +53,10 @@ void fwupd_release_set_version (FwupdRelease *release, const gchar *fwupd_release_get_uri (FwupdRelease *release); void fwupd_release_set_uri (FwupdRelease *release, const gchar *uri); -const gchar *fwupd_release_get_checksum (FwupdRelease *release); -void fwupd_release_set_checksum (FwupdRelease *release, +GPtrArray *fwupd_release_get_checksums (FwupdRelease *release); +void fwupd_release_add_checksum (FwupdRelease *release, const gchar *checksum); -GChecksumType fwupd_release_get_checksum_kind (FwupdRelease *release); -void fwupd_release_set_checksum_kind (FwupdRelease *release, - GChecksumType checkum_kind); + const gchar *fwupd_release_get_filename (FwupdRelease *release); void fwupd_release_set_filename (FwupdRelease *release, const gchar *filename); diff --git a/libfwupd/fwupd-result.c b/libfwupd/fwupd-result.c index 3cf1c2e5c..6ff4105c1 100644 --- a/libfwupd/fwupd-result.c +++ b/libfwupd/fwupd-result.c @@ -25,6 +25,7 @@ #include #include +#include "fwupd-common-private.h" #include "fwupd-device-private.h" #include "fwupd-enums-private.h" #include "fwupd-error.h" @@ -638,8 +639,15 @@ const gchar * fwupd_result_get_update_checksum (FwupdResult *result) { FwupdResultPrivate *priv = GET_PRIVATE (result); + GPtrArray *checksums; g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL); - return fwupd_release_get_checksum (priv->release); + checksums = fwupd_release_get_checksums (priv->release); + for (guint i = 0; i < checksums->len; i++) { + const gchar *checksum = g_ptr_array_index (checksums, i); + if (fwupd_checksum_guess_kind (checksum) == G_CHECKSUM_SHA1) + return checksum; + } + return NULL; } /** @@ -656,7 +664,7 @@ fwupd_result_set_update_checksum (FwupdResult *result, const gchar *update_check { FwupdResultPrivate *priv = GET_PRIVATE (result); g_return_if_fail (FWUPD_IS_RESULT (result)); - fwupd_release_set_checksum (priv->release, update_checksum); + fwupd_release_add_checksum (priv->release, update_checksum); } /** @@ -672,9 +680,7 @@ fwupd_result_set_update_checksum (FwupdResult *result, const gchar *update_check GChecksumType fwupd_result_get_update_checksum_kind (FwupdResult *result) { - FwupdResultPrivate *priv = GET_PRIVATE (result); - g_return_val_if_fail (FWUPD_IS_RESULT (result), 0); - return fwupd_release_get_checksum_kind (priv->release); + return G_CHECKSUM_SHA1; } /** @@ -689,9 +695,6 @@ fwupd_result_get_update_checksum_kind (FwupdResult *result) void fwupd_result_set_update_checksum_kind (FwupdResult *result, GChecksumType checkum_kind) { - FwupdResultPrivate *priv = GET_PRIVATE (result); - g_return_if_fail (FWUPD_IS_RESULT (result)); - fwupd_release_set_checksum_kind (priv->release, checkum_kind); } /** @@ -883,8 +886,15 @@ const gchar * fwupd_result_get_device_checksum (FwupdResult *result) { FwupdResultPrivate *priv = GET_PRIVATE (result); + GPtrArray *checksums; g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL); - return fwupd_device_get_checksum (priv->device); + checksums = fwupd_device_get_checksums (priv->device); + for (guint i = 0; i < checksums->len; i++) { + const gchar *checksum = g_ptr_array_index (checksums, i); + if (fwupd_checksum_guess_kind (checksum) == G_CHECKSUM_SHA1) + return checksum; + } + return NULL; } /** @@ -901,7 +911,7 @@ fwupd_result_set_device_checksum (FwupdResult *result, const gchar *device_check { FwupdResultPrivate *priv = GET_PRIVATE (result); g_return_if_fail (FWUPD_IS_RESULT (result)); - fwupd_device_set_checksum (priv->device, device_checksum); + fwupd_device_add_checksum (priv->device, device_checksum); } /** @@ -917,9 +927,7 @@ fwupd_result_set_device_checksum (FwupdResult *result, const gchar *device_check GChecksumType fwupd_result_get_device_checksum_kind (FwupdResult *result) { - FwupdResultPrivate *priv = GET_PRIVATE (result); - g_return_val_if_fail (FWUPD_IS_RESULT (result), 0); - return fwupd_device_get_checksum_kind (priv->device); + return G_CHECKSUM_SHA1; } /** @@ -934,9 +942,6 @@ fwupd_result_get_device_checksum_kind (FwupdResult *result) void fwupd_result_set_device_checksum_kind (FwupdResult *result, GChecksumType checkum_kind) { - FwupdResultPrivate *priv = GET_PRIVATE (result); - g_return_if_fail (FWUPD_IS_RESULT (result)); - fwupd_device_set_checksum_kind (priv->device, checkum_kind); } /** diff --git a/libfwupd/fwupd-result.h b/libfwupd/fwupd-result.h index ab5f1b673..8eb470831 100644 --- a/libfwupd/fwupd-result.h +++ b/libfwupd/fwupd-result.h @@ -129,14 +129,14 @@ guint64 fwupd_result_get_device_modified (FwupdResult *result); G_DEPRECATED_FOR(fwupd_device_set_modified) void fwupd_result_set_device_modified (FwupdResult *result, guint64 device_modified); -G_DEPRECATED_FOR(fwupd_device_get_checksum) +G_DEPRECATED_FOR(fwupd_device_get_checksums) const gchar *fwupd_result_get_device_checksum (FwupdResult *result); -G_DEPRECATED_FOR(fwupd_device_set_checksum) +G_DEPRECATED_FOR(fwupd_device_add_checksum) void fwupd_result_set_device_checksum (FwupdResult *result, const gchar *device_checksum); -G_DEPRECATED_FOR(fwupd_device_get_checksum_kind) +G_DEPRECATED_FOR(fwupd_device_get_checksums) GChecksumType fwupd_result_get_device_checksum_kind (FwupdResult *result); -G_DEPRECATED_FOR(fwupd_device_set_checksum_kind) +G_DEPRECATED_FOR(fwupd_device_add_checksum) void fwupd_result_set_device_checksum_kind (FwupdResult *result, GChecksumType checkum_kind); G_DEPRECATED_FOR(fwupd_device_get_provider) @@ -169,14 +169,14 @@ void fwupd_result_set_update_filename (FwupdResult *result, FwupdUpdateState fwupd_result_get_update_state (FwupdResult *result); void fwupd_result_set_update_state (FwupdResult *result, FwupdUpdateState update_state); -G_DEPRECATED_FOR(fwupd_release_get_checksum) +G_DEPRECATED_FOR(fwupd_release_get_checksums) const gchar *fwupd_result_get_update_checksum (FwupdResult *result); -G_DEPRECATED_FOR(fwupd_release_set_checksum) +G_DEPRECATED_FOR(fwupd_release_add_checksum) void fwupd_result_set_update_checksum (FwupdResult *result, const gchar *update_checksum); -G_DEPRECATED_FOR(fwupd_release_get_checksum_kind) +G_DEPRECATED_FOR(fwupd_release_get_checksums) GChecksumType fwupd_result_get_update_checksum_kind (FwupdResult *result); -G_DEPRECATED_FOR(fwupd_release_set_checksum_kind) +G_DEPRECATED_FOR(fwupd_release_add_checksum) void fwupd_result_set_update_checksum_kind (FwupdResult *result, GChecksumType checkum_kind); G_DEPRECATED_FOR(fwupd_release_get_uri) diff --git a/libfwupd/fwupd-self-test.c b/libfwupd/fwupd-self-test.c index 9506f06c2..54c29c28c 100644 --- a/libfwupd/fwupd-self-test.c +++ b/libfwupd/fwupd-self-test.c @@ -107,8 +107,7 @@ fwupd_result_func (void) /* create dummy object */ result = fwupd_result_new (); dev = fwupd_result_get_device (result); - fwupd_device_set_checksum (dev, "beefdead"); - fwupd_device_set_checksum_kind (dev, G_CHECKSUM_SHA256); + fwupd_device_add_checksum (dev, "beefdead"); fwupd_device_set_created (dev, 1); fwupd_device_set_flags (dev, FWUPD_DEVICE_FLAG_ALLOW_OFFLINE); fwupd_device_set_id (dev, "USB:foo"); @@ -120,7 +119,7 @@ fwupd_result_func (void) fwupd_result_set_update_trust_flags (result, FWUPD_TRUST_FLAG_PAYLOAD); rel = fwupd_result_get_release (result); - fwupd_release_set_checksum (rel, "deadbeef"); + fwupd_release_add_checksum (rel, "deadbeef"); fwupd_release_set_description (rel, "

Hi there!

"); fwupd_release_set_filename (rel, "firmware.bin"); fwupd_release_set_appstream_id (rel, "org.dave.ColorHug.firmware"); @@ -141,16 +140,14 @@ fwupd_result_func (void) " Guid: 00000000-0000-0000-0000-000000000000\n" " DeviceID: USB:foo\n" " Flags: allow-offline|require-ac\n" - " FirmwareHash: beefdead\n" - " DeviceChecksumKind: sha256\n" + " FirmwareHash: SHA1(beefdead)\n" " Created: 1970-01-01\n" " Modified: 1970-01-02\n" " AppstreamId: org.dave.ColorHug.firmware\n" " UpdateDescription:

Hi there!

\n" " UpdateVersion: 1.2.3\n" " FilenameCab: firmware.bin\n" - " UpdateHash: deadbeef\n" - " UpdateChecksumKind: sha1\n" + " UpdateHash: SHA1(deadbeef)\n" " Size: 1.0 kB\n" " UpdateUri: http://foo.com\n" " Trusted: payload\n", &error); diff --git a/libfwupd/meson.build b/libfwupd/meson.build index bdbfc176c..e27ef55e4 100644 --- a/libfwupd/meson.build +++ b/libfwupd/meson.build @@ -33,6 +33,7 @@ fwupd = shared_library( 'fwupd', sources : [ 'fwupd-client.c', + 'fwupd-common.c', 'fwupd-device.c', 'fwupd-enums.c', 'fwupd-error.c', diff --git a/plugins/altos/fu-plugin-altos.c b/plugins/altos/fu-plugin-altos.c index 19d248c84..e89163756 100644 --- a/plugins/altos/fu-plugin-altos.c +++ b/plugins/altos/fu-plugin-altos.c @@ -103,9 +103,11 @@ fu_plugin_verify (FuPlugin *plugin, FuPluginVerifyFlags flags, GError **error) { - GChecksumType checksum_type; - g_autofree gchar *hash = NULL; g_autoptr(GBytes) blob_fw = NULL; + GChecksumType checksum_types[] = { + G_CHECKSUM_SHA1, + G_CHECKSUM_SHA256, + 0 }; /* get data */ fu_plugin_set_status (plugin, FWUPD_STATUS_DEVICE_VERIFY); @@ -115,12 +117,11 @@ fu_plugin_verify (FuPlugin *plugin, error); if (blob_fw == NULL) return FALSE; - - /* set new checksum */ - checksum_type = fu_plugin_get_checksum_type (flags); - hash = g_compute_checksum_for_bytes (checksum_type, blob_fw); - fu_device_set_checksum (dev, hash); - fu_device_set_checksum_kind (dev, checksum_type); + for (guint i = 0; checksum_types[i] != 0; i++) { + g_autofree gchar *hash = NULL; + hash = g_compute_checksum_for_bytes (checksum_types[i], blob_fw); + fu_device_add_checksum (dev, hash); + } fu_plugin_set_status (plugin, FWUPD_STATUS_IDLE); return TRUE; } diff --git a/plugins/colorhug/fu-plugin-colorhug.c b/plugins/colorhug/fu-plugin-colorhug.c index dec402034..f493941c2 100644 --- a/plugins/colorhug/fu-plugin-colorhug.c +++ b/plugins/colorhug/fu-plugin-colorhug.c @@ -169,11 +169,13 @@ fu_plugin_verify (FuPlugin *plugin, { FuPluginData *data = fu_plugin_get_data (plugin); FuPluginItem *item; - GChecksumType checksum_type; gsize len; g_autoptr(GError) error_local = NULL; - g_autofree gchar *hash = NULL; g_autofree guint8 *data2 = NULL; + GChecksumType checksum_types[] = { + G_CHECKSUM_SHA1, + G_CHECKSUM_SHA256, + 0 }; /* find item */ item = g_hash_table_lookup (data->devices, fu_device_get_id (device)); @@ -208,10 +210,12 @@ fu_plugin_verify (FuPlugin *plugin, } /* get the checksum */ - checksum_type = fu_plugin_get_checksum_type (flags); - hash = g_compute_checksum_for_data (checksum_type, (guchar *) data2, len); - fu_device_set_checksum (device, hash); - fu_device_set_checksum_kind (device, checksum_type); + for (guint i = 0; checksum_types[i] != 0; i++) { + g_autofree gchar *hash = NULL; + hash = g_compute_checksum_for_data (checksum_types[i], + (guchar *) data2, len); + fu_device_add_checksum (device, hash); + } /* we're done here */ if (!g_usb_device_close (item->usb_device, &error_local)) diff --git a/plugins/dfu/fu-plugin-dfu.c b/plugins/dfu/fu-plugin-dfu.c index b2335ffac..e04592a69 100644 --- a/plugins/dfu/fu-plugin-dfu.c +++ b/plugins/dfu/fu-plugin-dfu.c @@ -287,13 +287,15 @@ fu_plugin_verify (FuPlugin *plugin, { FuPluginData *data = fu_plugin_get_data (plugin); GBytes *blob_fw; - GChecksumType checksum_type; DfuDevice *device; const gchar *platform_id; - g_autofree gchar *hash = NULL; g_autoptr(DfuDevice) dfu_device = NULL; g_autoptr(DfuFirmware) dfu_firmware = NULL; g_autoptr(GError) error_local = NULL; + GChecksumType checksum_types[] = { + G_CHECKSUM_SHA1, + G_CHECKSUM_SHA256, + 0 }; /* get device */ platform_id = fu_device_get_id (dev); @@ -347,10 +349,11 @@ fu_plugin_verify (FuPlugin *plugin, blob_fw = dfu_firmware_write_data (dfu_firmware, error); if (blob_fw == NULL) return FALSE; - checksum_type = fu_plugin_get_checksum_type (flags); - hash = g_compute_checksum_for_bytes (checksum_type, blob_fw); - fu_device_set_checksum (dev, hash); - fu_device_set_checksum_kind (dev, checksum_type); + for (guint i = 0; checksum_types[i] != 0; i++) { + g_autofree gchar *hash = NULL; + hash = g_compute_checksum_for_bytes (checksum_types[i], blob_fw); + fu_device_add_checksum (dev, hash); + } fu_plugin_set_status (plugin, FWUPD_STATUS_IDLE); return TRUE; } diff --git a/plugins/udev/fu-plugin-udev.c b/plugins/udev/fu-plugin-udev.c index d210a5cfa..928654d45 100644 --- a/plugins/udev/fu-plugin-udev.c +++ b/plugins/udev/fu-plugin-udev.c @@ -105,7 +105,7 @@ fu_plugin_verify (FuPlugin *plugin, rom = fu_rom_new (); if (!fu_rom_load_file (rom, file, FU_ROM_LOAD_FLAG_BLANK_PPID, NULL, error)) return FALSE; - fu_device_set_checksum (device, fu_rom_get_checksum (rom)); + fu_device_add_checksum (device, fu_rom_get_checksum (rom)); return TRUE; } diff --git a/src/fu-device.h b/src/fu-device.h index a8f42fea0..acc96cbd9 100644 --- a/src/fu-device.h +++ b/src/fu-device.h @@ -41,8 +41,7 @@ FuDevice *fu_device_new (void); #define fu_device_add_flag(d,v) fwupd_device_add_flag(fwupd_result_get_device(FWUPD_RESULT(d)),v) #define fu_device_remove_flag(d,v) fwupd_device_remove_flag(fwupd_result_get_device(FWUPD_RESULT(d)),v) #define fu_device_has_flag(d,v) fwupd_device_has_flag(fwupd_result_get_device(FWUPD_RESULT(d)),v) -#define fu_device_set_checksum(d,v) fwupd_device_set_checksum(fwupd_result_get_device(FWUPD_RESULT(d)),v) -#define fu_device_set_checksum_kind(d,v) fwupd_device_set_checksum_kind(fwupd_result_get_device(FWUPD_RESULT(d)),v) +#define fu_device_add_checksum(d,v) fwupd_device_add_checksum(fwupd_result_get_device(FWUPD_RESULT(d)),v) #define fu_device_set_created(d,v) fwupd_device_set_created(fwupd_result_get_device(FWUPD_RESULT(d)),v) #define fu_device_set_description(d,v) fwupd_device_set_description(fwupd_result_get_device(FWUPD_RESULT(d)),v) #define fu_device_set_flags(d,v) fwupd_device_set_flags(fwupd_result_get_device(FWUPD_RESULT(d)),v) @@ -51,7 +50,6 @@ FuDevice *fu_device_new (void); #define fu_device_set_modified(d,v) fwupd_device_set_modified(fwupd_result_get_device(FWUPD_RESULT(d)),v) #define fu_device_set_plugin(d,v) fwupd_device_set_provider(fwupd_result_get_device(FWUPD_RESULT(d)),v) #define fu_device_set_unique_id(d,v) fwupd_result_set_unique_id(FWUPD_RESULT(d),v) -#define fu_device_set_update_checksum(d,v) fwupd_release_set_checksum(fwupd_result_get_release(FWUPD_RESULT(d)),v) #define fu_device_set_update_description(d,v) fwupd_release_set_description(fwupd_result_get_release(FWUPD_RESULT(d)),v) #define fu_device_set_update_error(d,v) fwupd_result_set_update_error(FWUPD_RESULT(d),v) #define fu_device_set_update_filename(d,v) fwupd_release_set_filename(fwupd_result_get_release(FWUPD_RESULT(d)),v) @@ -72,15 +70,13 @@ FuDevice *fu_device_new (void); #define fu_device_set_flashes_left(d,v) fwupd_device_set_flashes_left(fwupd_result_get_device(FWUPD_RESULT(d)),v) /* compat getters */ -#define fu_device_get_checksum(d) fwupd_device_get_checksum(fwupd_result_get_device(FWUPD_RESULT(d))) -#define fu_device_get_checksum_kind(d) fwupd_device_get_checksum_kind(fwupd_result_get_device(FWUPD_RESULT(d))) +#define fu_device_get_checksums(d) fwupd_device_get_checksums(fwupd_result_get_device(FWUPD_RESULT(d))) #define fu_device_get_flags(d) fwupd_device_get_flags(fwupd_result_get_device(FWUPD_RESULT(d))) #define fu_device_get_guids(d) fwupd_device_get_guids(fwupd_result_get_device(FWUPD_RESULT(d))) #define fu_device_get_guid_default(d) fwupd_device_get_guid_default(fwupd_result_get_device(FWUPD_RESULT(d))) #define fu_device_get_name(d) fwupd_device_get_name(fwupd_result_get_device(FWUPD_RESULT(d))) #define fu_device_get_id(d) fwupd_device_get_id(fwupd_result_get_device(FWUPD_RESULT(d))) #define fu_device_get_plugin(d) fwupd_device_get_provider(fwupd_result_get_device(FWUPD_RESULT(d))) -#define fu_device_get_update_checksum(d) fwupd_release_get_checksum(fwupd_result_get_release(FWUPD_RESULT(d))) #define fu_device_get_update_error(d) fwupd_result_get_update_error(FWUPD_RESULT(d)) #define fu_device_get_update_filename(d) fwupd_release_get_filename(fwupd_result_get_release(FWUPD_RESULT(d))) #define fu_device_get_update_state(d) fwupd_result_get_update_state(FWUPD_RESULT(d)) diff --git a/src/fu-main.c b/src/fu-main.c index 271f71b55..e0d89d1a2 100644 --- a/src/fu-main.c +++ b/src/fu-main.c @@ -33,6 +33,7 @@ #include #include +#include "fwupd-common-private.h" #include "fwupd-enums-private.h" #include "fwupd-release-private.h" #include "fwupd-resources.h" @@ -327,7 +328,7 @@ fu_main_set_release_from_item (FwupdRelease *rel, AsRelease *release) if (csum != NULL) { tmp = as_checksum_get_value (csum); if (tmp != NULL) - fwupd_release_set_checksum (rel, tmp); + fwupd_release_add_checksum (rel, tmp); } fwupd_release_set_size (rel, as_release_get_size (release, AS_SIZE_KIND_INSTALLED)); } @@ -477,8 +478,8 @@ static AsApp * fu_main_verify_update_device_to_app (FuDevice *device) { AsApp *app = NULL; + GPtrArray *checksums; g_autofree gchar *id = NULL; - g_autoptr(AsChecksum) csum = NULL; g_autoptr(AsProvide) prov = NULL; g_autoptr(AsRelease) rel = NULL; @@ -491,11 +492,15 @@ fu_main_verify_update_device_to_app (FuDevice *device) as_app_set_kind (app, AS_APP_KIND_FIRMWARE); rel = as_release_new (); as_release_set_version (rel, fu_device_get_version (device)); - csum = as_checksum_new (); - as_checksum_set_kind (csum, fu_device_get_checksum_kind (device)); - as_checksum_set_value (csum, fu_device_get_checksum (device)); - as_checksum_set_target (csum, AS_CHECKSUM_TARGET_CONTENT); - as_release_add_checksum (rel, csum); + checksums = fu_device_get_checksums (device); + for (guint j = 0; j < checksums->len; j++) { + const gchar *checksum = g_ptr_array_index (checksums, j); + g_autoptr(AsChecksum) csum = as_checksum_new (); + as_checksum_set_kind (csum, fwupd_checksum_guess_kind (checksum)); + as_checksum_set_value (csum, checksum); + as_checksum_set_target (csum, AS_CHECKSUM_TARGET_CONTENT); + as_release_add_checksum (rel, csum); + } as_app_add_release (app, rel); prov = as_provide_new (); as_provide_set_kind (prov, AS_PROVIDE_KIND_FIRMWARE_FLASHED); @@ -524,6 +529,7 @@ fu_main_plugin_verify_update_authenticated (FuMainAuthHelper *helper, GError **e for (guint i = 0; i < helper->devices->len; i ++) { FuDevice *device = g_ptr_array_index (helper->devices, i); FuDeviceItem *item; + GPtrArray *checksums; g_autoptr(AsApp) app = NULL; item = fu_main_get_item_by_id (helper->priv, @@ -547,7 +553,8 @@ fu_main_plugin_verify_update_authenticated (FuMainAuthHelper *helper, GError **e } /* get the checksum */ - if (fu_device_get_checksum (item->device) == NULL) { + checksums = fu_device_get_checksums (item->device); + if (checksums->len == 0) { if (!fu_plugin_runner_verify (item->plugin, item->device, FU_PLUGIN_VERIFY_FLAG_NONE, @@ -557,7 +564,7 @@ fu_main_plugin_verify_update_authenticated (FuMainAuthHelper *helper, GError **e } /* we got nothing */ - if (fu_device_get_checksum (item->device) == NULL) { + if (checksums->len == 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, @@ -2170,6 +2177,7 @@ fu_main_daemon_method_call (GDBusConnection *connection, const gchar *sender, AsChecksum *csum; AsRelease *release; FuDeviceItem *item = NULL; + GPtrArray *checksums; const gchar *hash = NULL; const gchar *id = NULL; const gchar *version = NULL; @@ -2229,7 +2237,33 @@ fu_main_daemon_method_call (GDBusConnection *connection, const gchar *sender, fu_main_invocation_return_error (priv, invocation, error); return; } - hash = fu_device_get_checksum (item->device); + + /* get the matching checksum */ + checksums = fu_device_get_checksums (item->device); + if (checksums->len == 0) { + g_set_error (&error, + FWUPD_ERROR, + FWUPD_ERROR_NOT_FOUND, + "No device checksums for %s", version); + fu_main_invocation_return_error (priv, invocation, error); + return; + } + for (guint j = 0; j < checksums->len; j++) { + const gchar *hash_tmp = g_ptr_array_index (checksums, j); + GChecksumType hash_kind = fwupd_checksum_guess_kind (hash_tmp); + if (as_checksum_get_kind (csum) == hash_kind) { + hash = hash_tmp; + break; + } + } + if (hash == NULL) { + g_set_error (&error, + FWUPD_ERROR, + FWUPD_ERROR_NOT_FOUND, + "No matching hash kind for %s", version); + fu_main_invocation_return_error (priv, invocation, error); + return; + } if (g_strcmp0 (as_checksum_get_value (csum), hash) != 0) { g_set_error (&error, FWUPD_ERROR, diff --git a/src/fu-plugin.c b/src/fu-plugin.c index 370e6662d..24ab8f53b 100644 --- a/src/fu-plugin.c +++ b/src/fu-plugin.c @@ -1141,11 +1141,3 @@ fu_plugin_new (void) plugin = g_object_new (FU_TYPE_PLUGIN, NULL); return plugin; } - -GChecksumType -fu_plugin_get_checksum_type (FuPluginVerifyFlags flags) -{ - if (flags & FU_PLUGIN_VERIFY_FLAG_USE_SHA256) - return G_CHECKSUM_SHA256; - return G_CHECKSUM_SHA1; -} diff --git a/src/fu-plugin.h b/src/fu-plugin.h index 12366bf41..0bf53ac20 100644 --- a/src/fu-plugin.h +++ b/src/fu-plugin.h @@ -55,7 +55,6 @@ struct _FuPluginClass typedef enum { FU_PLUGIN_VERIFY_FLAG_NONE = 0, - FU_PLUGIN_VERIFY_FLAG_USE_SHA256 = 1 << 0, FU_PLUGIN_VERIFY_FLAG_LAST } FuPluginVerifyFlags; @@ -84,7 +83,6 @@ void fu_plugin_recoldplug (FuPlugin *plugin); void fu_plugin_set_coldplug_delay (FuPlugin *plugin, guint duration); gboolean fu_plugin_has_device_delay (FuPlugin *plugin); -GChecksumType fu_plugin_get_checksum_type (FuPluginVerifyFlags flags); gpointer fu_plugin_cache_lookup (FuPlugin *plugin, const gchar *id); void fu_plugin_cache_remove (FuPlugin *plugin, diff --git a/src/fu-util.c b/src/fu-util.c index b13b66430..14501e822 100644 --- a/src/fu-util.c +++ b/src/fu-util.c @@ -39,6 +39,7 @@ #include "fu-hwids.h" #include "fu-pending.h" #include "fu-plugin-private.h" +#include "fwupd-common-private.h" #ifndef GUdevClient_autoptr G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevClient, g_object_unref) @@ -704,9 +705,9 @@ fu_util_download_file (FuUtilPrivate *priv, SoupURI *uri, const gchar *fn, const gchar *checksum_expected, - GChecksumType checksum_type, GError **error) { + GChecksumType checksum_type; const gchar *http_proxy; guint status_code; g_autoptr(GError) error_local = NULL; @@ -717,6 +718,7 @@ fu_util_download_file (FuUtilPrivate *priv, g_autoptr(SoupSession) session = NULL; /* check if the file already exists with the right checksum */ + checksum_type = fwupd_checksum_guess_kind (checksum_expected); if (fu_util_file_exists_with_checksum (fn, checksum_expected, checksum_type)) { g_debug ("skpping download as file already exists"); return TRUE; @@ -829,13 +831,13 @@ fu_util_download_metadata_for_remote (FuUtilPrivate *priv, /* download the metadata */ filename = g_build_filename (cache_dir, fwupd_remote_get_filename (remote), NULL); if (!fu_util_download_file (priv, fwupd_remote_get_uri (remote), - filename, NULL, 0, error)) + filename, NULL, error)) return FALSE; /* download the signature */ filename_asc = g_build_filename (cache_dir, fwupd_remote_get_filename_asc (remote), NULL); if (!fu_util_download_file (priv, fwupd_remote_get_uri_asc (remote), - filename_asc, NULL, 0, error)) + filename_asc, NULL, error)) return FALSE; /* send all this to fwupd */ @@ -905,20 +907,6 @@ fu_util_get_results (FuUtilPrivate *priv, gchar **values, GError **error) return TRUE; } -static const gchar * -_g_checksum_type_to_string (GChecksumType checksum_type) -{ - if (checksum_type == G_CHECKSUM_MD5) - return "md5"; - if (checksum_type == G_CHECKSUM_SHA1) - return "sha1"; - if (checksum_type == G_CHECKSUM_SHA256) - return "sha256"; - if (checksum_type == G_CHECKSUM_SHA512) - return "sha512"; - return NULL; -} - static gboolean fu_util_get_releases (FuUtilPrivate *priv, gchar **values, GError **error) { @@ -942,6 +930,7 @@ fu_util_get_releases (FuUtilPrivate *priv, gchar **values, GError **error) return FALSE; for (guint i = 0; i < rels->len; i++) { FwupdRelease *rel = g_ptr_array_index (rels, i); + GPtrArray *checksums; const gchar *tmp = fwupd_release_get_description (rel); /* TRANSLATORS: section header for release version number */ @@ -956,14 +945,13 @@ fu_util_get_releases (FuUtilPrivate *priv, gchar **values, GError **error) /* TRANSLATORS: section header for firmware description */ fu_util_print_data (_("Description"), desc); } - - /* TRANSLATORS: section header for firmware checksum */ - fu_util_print_data (_("Checksum"), fwupd_release_get_checksum (rel)); - if (fwupd_release_get_checksum (rel) != NULL) { - GChecksumType checksum_type = fwupd_release_get_checksum_kind (rel); - tmp = _g_checksum_type_to_string (checksum_type); - /* TRANSLATORS: section header for firmware checksum type */ - fu_util_print_data (_("Checksum Type"), tmp); + checksums = fwupd_device_get_checksums (dev); + for (guint j = 0; j < checksums->len; j++) { + const gchar *checksum = g_ptr_array_index (checksums, j); + g_autofree gchar *checksum_display; + checksum_display = fwupd_checksum_format_for_display (checksum); + /* TRANSLATORS: section header for firmware checksum */ + fu_util_print_data (_("Checksum"), checksum_display); } /* new line between all but last entries */ @@ -1071,7 +1059,6 @@ fu_util_get_updates (FuUtilPrivate *priv, gchar **values, GError **error) { GPtrArray *results = NULL; GPtrArray *guids; - GChecksumType checksum_type; const gchar *tmp; /* print any updates */ @@ -1082,6 +1069,7 @@ fu_util_get_updates (FuUtilPrivate *priv, gchar **values, GError **error) FwupdResult *res = g_ptr_array_index (results, i); FwupdDevice *dev = fwupd_result_get_device (res); FwupdRelease *rel = fwupd_result_get_release (res); + GPtrArray *checksums; /* TRANSLATORS: first replacement is device name */ g_print (_("%s has firmware updates:"), fwupd_device_get_name (dev)); @@ -1105,15 +1093,13 @@ fu_util_get_updates (FuUtilPrivate *priv, gchar **values, GError **error) fu_util_print_data (_("Update Remote ID"), fwupd_release_get_remote_id (rel)); - /* TRANSLATORS: section header for firmware checksum */ - fu_util_print_data (_("Update Checksum"), - fwupd_release_get_checksum (rel)); - - /* TRANSLATORS: section header for firmware checksum type */ - if (fwupd_release_get_checksum (rel) != NULL) { - checksum_type = fwupd_release_get_checksum_kind (rel); - tmp = _g_checksum_type_to_string (checksum_type); - fu_util_print_data (_("Update Checksum Type"), tmp); + checksums = fwupd_device_get_checksums (dev); + for (guint j = 0; j < checksums->len; j++) { + const gchar *checksum = g_ptr_array_index (checksums, j); + g_autofree gchar *checksum_display; + checksum_display = fwupd_checksum_format_for_display (checksum); + /* TRANSLATORS: section header for firmware checksum */ + fu_util_print_data (_("Update Checksum"), checksum_display); } /* TRANSLATORS: section header for firmware remote http:// */ @@ -1207,12 +1193,32 @@ fu_util_monitor (FuUtilPrivate *priv, gchar **values, GError **error) return TRUE; } +/* return in order of security */ +static const gchar * +fu_util_get_best_checksum (GPtrArray *checksums) +{ + GChecksumType checksum_types[] = { + G_CHECKSUM_SHA512, + G_CHECKSUM_SHA256, + G_CHECKSUM_SHA1, + 0 }; + for (guint i = 0; checksum_types[i] != 0; i++) { + for (guint j = 0; j < checksums->len; j++) { + const gchar *checksum = g_ptr_array_index (checksums, j); + if (fwupd_checksum_guess_kind (checksum) == checksum_types[i]) + return checksum; + } + } + return NULL; +} + static gboolean fu_util_update_device_with_release (FuUtilPrivate *priv, FwupdDevice *dev, FwupdRelease *rel, GError **error) { + GPtrArray *checksums; const gchar *remote_id; const gchar *uri_tmp; g_autofree gchar *basename = NULL; @@ -1249,9 +1255,9 @@ fu_util_update_device_with_release (FuUtilPrivate *priv, fwupd_device_get_name (dev)); basename = g_path_get_basename (uri_tmp); fn = g_build_filename (cache_dir, basename, NULL); + checksums = fwupd_release_get_checksums (rel); if (!fu_util_download_file (priv, uri, fn, - fwupd_release_get_checksum (rel), - fwupd_release_get_checksum_kind (rel), + fu_util_get_best_checksum (checksums), error)) return FALSE; g_print ("Updating %s on %s...\n", @@ -1273,7 +1279,8 @@ fu_util_update (FuUtilPrivate *priv, gchar **values, GError **error) FwupdResult *res = g_ptr_array_index (results, i); FwupdDevice *dev = fwupd_result_get_device (res); FwupdRelease *rel = fwupd_result_get_release (res); - if (fwupd_release_get_checksum (rel) == NULL) + GPtrArray *checksums = fwupd_release_get_checksums (rel); + if (checksums->len == 0) continue; if (fwupd_release_get_uri (rel) == NULL) continue;