Allow multiple checksums on devices and releases

Although we supported other hashes than SHA1 (which is now moderately unsafe)
we had to switch the metadata provider and daemon on some kind of flag day to
using SHA256. Since that's somewhat impractical, just allow multiple checksums
to be set on objects and just try to match whatever is given in preference
order.

This also means we can easily transition to other hash types in the future.

The removed API was never present in a tarball release, so not an API break.
This commit is contained in:
Richard Hughes 2017-06-06 16:59:54 +01:00
parent 985ac07ab7
commit 68cc00c7e9
20 changed files with 342 additions and 277 deletions

View File

@ -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 * {sa{sv}} -> {a{sv}} -- we don't always want to send the device ID
* Rename FU_DEVICE_FLAG -> FWUPD_DEVICE_FLAG * Rename FU_DEVICE_FLAG -> FWUPD_DEVICE_FLAG
* Remove all deprecated API * Remove all deprecated API
* Remove FWUPD_RESULT_KEY_DEVICE_CHECKSUM_KIND
* Rename GetDetailsLocal() -> GetDetails() * Rename GetDetailsLocal() -> GetDetails()
* Rename UpdateMetadataWithId() -> UpdateMetadata() * Rename UpdateMetadataWithId() -> UpdateMetadata()
* Make DeviceAdded emit a FwupdDevice, not a FwupdResult * Make DeviceAdded emit a FwupdDevice, not a FwupdResult

View File

@ -0,0 +1,30 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
*
* 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 <glib.h>
GChecksumType fwupd_checksum_guess_kind (const gchar *checksum);
gchar *fwupd_checksum_format_for_display (const gchar *checksum);
#endif /* __FWUPD_COMMON_PRIVATE_H */

85
libfwupd/fwupd-common.c Normal file
View File

@ -0,0 +1,85 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
*
* 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 <string.h>
/**
* 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);
}

View File

@ -25,6 +25,7 @@
#include <gio/gio.h> #include <gio/gio.h>
#include <string.h> #include <string.h>
#include "fwupd-common-private.h"
#include "fwupd-enums-private.h" #include "fwupd-enums-private.h"
#include "fwupd-error.h" #include "fwupd-error.h"
#include "fwupd-device-private.h" #include "fwupd-device-private.h"
@ -47,8 +48,7 @@ typedef struct {
gchar *version; gchar *version;
gchar *version_lowest; gchar *version_lowest;
gchar *version_bootloader; gchar *version_bootloader;
gchar *checksum; GPtrArray *checksums;
GChecksumType checksum_kind;
guint32 flashes_left; guint32 flashes_left;
} FwupdDevicePrivate; } 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)) #define GET_PRIVATE(o) (fwupd_device_get_instance_private (o))
/** /**
* fwupd_device_get_checksum: * fwupd_device_get_checksums:
* @device: A #FwupdDevice * @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 * Since: 0.9.3
**/ **/
const gchar * GPtrArray *
fwupd_device_get_checksum (FwupdDevice *device) fwupd_device_get_checksums (FwupdDevice *device)
{ {
FwupdDevicePrivate *priv = GET_PRIVATE (device); FwupdDevicePrivate *priv = GET_PRIVATE (device);
g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL); 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 * @device: A #FwupdDevice
* @checksum: the device checksum * @checksum: the device checksum
* *
@ -83,47 +83,12 @@ fwupd_device_get_checksum (FwupdDevice *device)
* Since: 0.9.3 * Since: 0.9.3
**/ **/
void void
fwupd_device_set_checksum (FwupdDevice *device, const gchar *checksum) fwupd_device_add_checksum (FwupdDevice *device, const gchar *checksum)
{ {
FwupdDevicePrivate *priv = GET_PRIVATE (device); FwupdDevicePrivate *priv = GET_PRIVATE (device);
g_return_if_fail (FWUPD_IS_DEVICE (device)); g_return_if_fail (FWUPD_IS_DEVICE (device));
g_free (priv->checksum); g_return_if_fail (checksum != NULL);
priv->checksum = g_strdup (checksum); g_ptr_array_add (priv->checksums, 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;
} }
/** /**
@ -776,13 +741,17 @@ fwupd_device_to_variant_builder (FwupdDevice *device, GVariantBuilder *builder)
FWUPD_RESULT_KEY_DEVICE_DESCRIPTION, FWUPD_RESULT_KEY_DEVICE_DESCRIPTION,
g_variant_new_string (priv->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}", g_variant_builder_add (builder, "{sv}",
FWUPD_RESULT_KEY_DEVICE_CHECKSUM, FWUPD_RESULT_KEY_DEVICE_CHECKSUM,
g_variant_new_string (priv->checksum)); g_variant_new_string (str->str));
g_variant_builder_add (builder, "{sv}",
FWUPD_RESULT_KEY_DEVICE_CHECKSUM_KIND,
g_variant_new_uint32 (priv->checksum_kind));
} }
if (priv->provider != NULL) { if (priv->provider != NULL) {
g_variant_builder_add (builder, "{sv}", g_variant_builder_add (builder, "{sv}",
@ -878,11 +847,11 @@ fwupd_device_from_key_value (FwupdDevice *device, const gchar *key, GVariant *va
return; return;
} }
if (g_strcmp0 (key, FWUPD_RESULT_KEY_DEVICE_CHECKSUM) == 0) { if (g_strcmp0 (key, FWUPD_RESULT_KEY_DEVICE_CHECKSUM) == 0) {
fwupd_device_set_checksum (device, g_variant_get_string (value, NULL)); guint i;
return; const gchar *checksums = g_variant_get_string (value, NULL);
} g_auto(GStrv) split = g_strsplit (checksums, ",", -1);
if (g_strcmp0 (key, FWUPD_RESULT_KEY_DEVICE_CHECKSUM_KIND) == 0) { for (i = 0; split[i] != NULL; i++)
fwupd_device_set_checksum_kind (device, g_variant_get_uint32 (value)); fwupd_device_add_checksum (device, split[i]);
return; return;
} }
if (g_strcmp0 (key, FWUPD_RESULT_KEY_DEVICE_PLUGIN) == 0) { 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); 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 static void
fwupd_pad_kv_dfl (GString *str, const gchar *key, guint64 device_flags) 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_DESCRIPTION, priv->description);
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DEVICE_PLUGIN, priv->provider); 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_dfl (str, FWUPD_RESULT_KEY_DEVICE_FLAGS, priv->flags);
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DEVICE_CHECKSUM, priv->checksum); for (guint i = 0; i < priv->checksums->len; i++) {
if (priv->checksum != NULL) const gchar *checksum = g_ptr_array_index (priv->checksums, i);
fwupd_pad_kv_csk (str, FWUPD_RESULT_KEY_DEVICE_CHECKSUM_KIND, priv->checksum_kind); 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_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, priv->version);
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DEVICE_VERSION_LOWEST, priv->version_lowest); 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); FwupdDevicePrivate *priv = GET_PRIVATE (device);
priv->guids = g_ptr_array_new_with_free_func (g_free); 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 static void
@ -1044,7 +1002,6 @@ fwupd_device_finalize (GObject *object)
FwupdDevicePrivate *priv = GET_PRIVATE (device); FwupdDevicePrivate *priv = GET_PRIVATE (device);
g_free (priv->description); g_free (priv->description);
g_free (priv->checksum);
g_free (priv->id); g_free (priv->id);
g_free (priv->name); g_free (priv->name);
g_free (priv->vendor); g_free (priv->vendor);
@ -1053,6 +1010,7 @@ fwupd_device_finalize (GObject *object)
g_free (priv->version_lowest); g_free (priv->version_lowest);
g_free (priv->version_bootloader); g_free (priv->version_bootloader);
g_ptr_array_unref (priv->guids); g_ptr_array_unref (priv->guids);
g_ptr_array_unref (priv->checksums);
G_OBJECT_CLASS (fwupd_device_parent_class)->finalize (object); G_OBJECT_CLASS (fwupd_device_parent_class)->finalize (object);
} }

View File

@ -86,12 +86,9 @@ void fwupd_device_set_created (FwupdDevice *device,
guint64 fwupd_device_get_modified (FwupdDevice *device); guint64 fwupd_device_get_modified (FwupdDevice *device);
void fwupd_device_set_modified (FwupdDevice *device, void fwupd_device_set_modified (FwupdDevice *device,
guint64 modified); guint64 modified);
const gchar *fwupd_device_get_checksum (FwupdDevice *device); GPtrArray *fwupd_device_get_checksums (FwupdDevice *device);
void fwupd_device_set_checksum (FwupdDevice *device, void fwupd_device_add_checksum (FwupdDevice *device,
const gchar *checksum); 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); const gchar *fwupd_device_get_provider (FwupdDevice *device);
void fwupd_device_set_provider (FwupdDevice *device, void fwupd_device_set_provider (FwupdDevice *device,
const gchar *provider); const gchar *provider);

View File

@ -25,6 +25,7 @@
#include <gio/gio.h> #include <gio/gio.h>
#include <string.h> #include <string.h>
#include "fwupd-common-private.h"
#include "fwupd-enums-private.h" #include "fwupd-enums-private.h"
#include "fwupd-error.h" #include "fwupd-error.h"
#include "fwupd-release-private.h" #include "fwupd-release-private.h"
@ -32,8 +33,7 @@
static void fwupd_release_finalize (GObject *object); static void fwupd_release_finalize (GObject *object);
typedef struct { typedef struct {
gchar *checksum; GPtrArray *checksums;
GChecksumType checksum_kind;
gchar *description; gchar *description;
gchar *filename; gchar *filename;
gchar *homepage; gchar *homepage;
@ -160,25 +160,25 @@ fwupd_release_set_filename (FwupdRelease *release, const gchar *filename)
} }
/** /**
* fwupd_release_get_checksum: * fwupd_device_get_checksums:
* @release: A #FwupdRelease * @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 * Since: 0.9.3
**/ **/
const gchar * GPtrArray *
fwupd_release_get_checksum (FwupdRelease *release) fwupd_release_get_checksums (FwupdRelease *release)
{ {
FwupdReleasePrivate *priv = GET_PRIVATE (release); FwupdReleasePrivate *priv = GET_PRIVATE (release);
g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL); 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 * @release: A #FwupdRelease
* @checksum: the update checksum * @checksum: the update checksum
* *
@ -187,47 +187,12 @@ fwupd_release_get_checksum (FwupdRelease *release)
* Since: 0.9.3 * Since: 0.9.3
**/ **/
void void
fwupd_release_set_checksum (FwupdRelease *release, const gchar *checksum) fwupd_release_add_checksum (FwupdRelease *release, const gchar *checksum)
{ {
FwupdReleasePrivate *priv = GET_PRIVATE (release); FwupdReleasePrivate *priv = GET_PRIVATE (release);
g_return_if_fail (FWUPD_IS_RELEASE (release)); g_return_if_fail (FWUPD_IS_RELEASE (release));
g_free (priv->checksum); g_return_if_fail (checksum != NULL);
priv->checksum = g_strdup (checksum); g_ptr_array_add (priv->checksums, 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;
} }
/** /**
@ -597,13 +562,18 @@ fwupd_release_to_variant_builder (FwupdRelease *release, GVariantBuilder *builde
FWUPD_RESULT_KEY_UPDATE_DESCRIPTION, FWUPD_RESULT_KEY_UPDATE_DESCRIPTION,
g_variant_new_string (priv->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}", g_variant_builder_add (builder, "{sv}",
FWUPD_RESULT_KEY_UPDATE_CHECKSUM, FWUPD_RESULT_KEY_UPDATE_CHECKSUM,
g_variant_new_string (priv->checksum)); g_variant_new_string (str->str));
g_variant_builder_add (builder, "{sv}",
FWUPD_RESULT_KEY_UPDATE_CHECKSUM_KIND,
g_variant_new_uint32 (priv->checksum_kind));
} }
if (priv->uri != NULL) { if (priv->uri != NULL) {
g_variant_builder_add (builder, "{sv}", g_variant_builder_add (builder, "{sv}",
@ -694,11 +664,10 @@ fwupd_release_from_key_value (FwupdRelease *release, const gchar *key, GVariant
return; return;
} }
if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_CHECKSUM) == 0) { if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_CHECKSUM) == 0) {
fwupd_release_set_checksum (release, g_variant_get_string (value, NULL)); const gchar *checksums = g_variant_get_string (value, NULL);
return; g_auto(GStrv) split = g_strsplit (checksums, ",", -1);
} for (guint i = 0; split[i] != NULL; i++)
if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_CHECKSUM_KIND) == 0) { fwupd_release_add_checksum (release, split[i]);
fwupd_release_set_checksum_kind (release, g_variant_get_uint32 (value));
return; return;
} }
if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_URI) == 0) { 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); 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 static void
fwupd_pad_kv_siz (GString *str, const gchar *key, guint64 value) 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_DESCRIPTION, priv->description);
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_VERSION, priv->version); 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_FILENAME, priv->filename);
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_CHECKSUM, priv->checksum); for (guint i = 0; i < priv->checksums->len; i++) {
if (priv->checksum != NULL) const gchar *checksum = g_ptr_array_index (priv->checksums, i);
fwupd_pad_kv_csk (str, FWUPD_RESULT_KEY_UPDATE_CHECKSUM_KIND, priv->checksum_kind); 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_str (str, FWUPD_RESULT_KEY_UPDATE_LICENSE, priv->license);
fwupd_pad_kv_siz (str, FWUPD_RESULT_KEY_UPDATE_SIZE, priv->size); fwupd_pad_kv_siz (str, FWUPD_RESULT_KEY_UPDATE_SIZE, priv->size);
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_URI, priv->uri); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_URI, priv->uri);
@ -804,7 +762,7 @@ static void
fwupd_release_init (FwupdRelease *release) fwupd_release_init (FwupdRelease *release)
{ {
FwupdReleasePrivate *priv = GET_PRIVATE (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 static void
@ -815,7 +773,6 @@ fwupd_release_finalize (GObject *object)
g_free (priv->description); g_free (priv->description);
g_free (priv->filename); g_free (priv->filename);
g_free (priv->checksum);
g_free (priv->appstream_id); g_free (priv->appstream_id);
g_free (priv->license); g_free (priv->license);
g_free (priv->name); g_free (priv->name);
@ -825,6 +782,7 @@ fwupd_release_finalize (GObject *object)
g_free (priv->vendor); g_free (priv->vendor);
g_free (priv->version); g_free (priv->version);
g_free (priv->remote_id); g_free (priv->remote_id);
g_ptr_array_unref (priv->checksums);
G_OBJECT_CLASS (fwupd_release_parent_class)->finalize (object); G_OBJECT_CLASS (fwupd_release_parent_class)->finalize (object);
} }

View File

@ -53,12 +53,10 @@ void fwupd_release_set_version (FwupdRelease *release,
const gchar *fwupd_release_get_uri (FwupdRelease *release); const gchar *fwupd_release_get_uri (FwupdRelease *release);
void fwupd_release_set_uri (FwupdRelease *release, void fwupd_release_set_uri (FwupdRelease *release,
const gchar *uri); const gchar *uri);
const gchar *fwupd_release_get_checksum (FwupdRelease *release); GPtrArray *fwupd_release_get_checksums (FwupdRelease *release);
void fwupd_release_set_checksum (FwupdRelease *release, void fwupd_release_add_checksum (FwupdRelease *release,
const gchar *checksum); 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); const gchar *fwupd_release_get_filename (FwupdRelease *release);
void fwupd_release_set_filename (FwupdRelease *release, void fwupd_release_set_filename (FwupdRelease *release,
const gchar *filename); const gchar *filename);

View File

@ -25,6 +25,7 @@
#include <gio/gio.h> #include <gio/gio.h>
#include <string.h> #include <string.h>
#include "fwupd-common-private.h"
#include "fwupd-device-private.h" #include "fwupd-device-private.h"
#include "fwupd-enums-private.h" #include "fwupd-enums-private.h"
#include "fwupd-error.h" #include "fwupd-error.h"
@ -638,8 +639,15 @@ const gchar *
fwupd_result_get_update_checksum (FwupdResult *result) fwupd_result_get_update_checksum (FwupdResult *result)
{ {
FwupdResultPrivate *priv = GET_PRIVATE (result); FwupdResultPrivate *priv = GET_PRIVATE (result);
GPtrArray *checksums;
g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL); 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); FwupdResultPrivate *priv = GET_PRIVATE (result);
g_return_if_fail (FWUPD_IS_RESULT (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 GChecksumType
fwupd_result_get_update_checksum_kind (FwupdResult *result) fwupd_result_get_update_checksum_kind (FwupdResult *result)
{ {
FwupdResultPrivate *priv = GET_PRIVATE (result); return G_CHECKSUM_SHA1;
g_return_val_if_fail (FWUPD_IS_RESULT (result), 0);
return fwupd_release_get_checksum_kind (priv->release);
} }
/** /**
@ -689,9 +695,6 @@ fwupd_result_get_update_checksum_kind (FwupdResult *result)
void void
fwupd_result_set_update_checksum_kind (FwupdResult *result, GChecksumType checkum_kind) 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) fwupd_result_get_device_checksum (FwupdResult *result)
{ {
FwupdResultPrivate *priv = GET_PRIVATE (result); FwupdResultPrivate *priv = GET_PRIVATE (result);
GPtrArray *checksums;
g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL); 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); FwupdResultPrivate *priv = GET_PRIVATE (result);
g_return_if_fail (FWUPD_IS_RESULT (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 GChecksumType
fwupd_result_get_device_checksum_kind (FwupdResult *result) fwupd_result_get_device_checksum_kind (FwupdResult *result)
{ {
FwupdResultPrivate *priv = GET_PRIVATE (result); return G_CHECKSUM_SHA1;
g_return_val_if_fail (FWUPD_IS_RESULT (result), 0);
return fwupd_device_get_checksum_kind (priv->device);
} }
/** /**
@ -934,9 +942,6 @@ fwupd_result_get_device_checksum_kind (FwupdResult *result)
void void
fwupd_result_set_device_checksum_kind (FwupdResult *result, GChecksumType checkum_kind) 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);
} }
/** /**

View File

@ -129,14 +129,14 @@ guint64 fwupd_result_get_device_modified (FwupdResult *result);
G_DEPRECATED_FOR(fwupd_device_set_modified) G_DEPRECATED_FOR(fwupd_device_set_modified)
void fwupd_result_set_device_modified (FwupdResult *result, void fwupd_result_set_device_modified (FwupdResult *result,
guint64 device_modified); 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); 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, void fwupd_result_set_device_checksum (FwupdResult *result,
const gchar *device_checksum); 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); 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, void fwupd_result_set_device_checksum_kind (FwupdResult *result,
GChecksumType checkum_kind); GChecksumType checkum_kind);
G_DEPRECATED_FOR(fwupd_device_get_provider) 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); FwupdUpdateState fwupd_result_get_update_state (FwupdResult *result);
void fwupd_result_set_update_state (FwupdResult *result, void fwupd_result_set_update_state (FwupdResult *result,
FwupdUpdateState update_state); 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); 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, void fwupd_result_set_update_checksum (FwupdResult *result,
const gchar *update_checksum); 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); 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, void fwupd_result_set_update_checksum_kind (FwupdResult *result,
GChecksumType checkum_kind); GChecksumType checkum_kind);
G_DEPRECATED_FOR(fwupd_release_get_uri) G_DEPRECATED_FOR(fwupd_release_get_uri)

View File

@ -107,8 +107,7 @@ fwupd_result_func (void)
/* create dummy object */ /* create dummy object */
result = fwupd_result_new (); result = fwupd_result_new ();
dev = fwupd_result_get_device (result); dev = fwupd_result_get_device (result);
fwupd_device_set_checksum (dev, "beefdead"); fwupd_device_add_checksum (dev, "beefdead");
fwupd_device_set_checksum_kind (dev, G_CHECKSUM_SHA256);
fwupd_device_set_created (dev, 1); fwupd_device_set_created (dev, 1);
fwupd_device_set_flags (dev, FWUPD_DEVICE_FLAG_ALLOW_OFFLINE); fwupd_device_set_flags (dev, FWUPD_DEVICE_FLAG_ALLOW_OFFLINE);
fwupd_device_set_id (dev, "USB:foo"); 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); fwupd_result_set_update_trust_flags (result, FWUPD_TRUST_FLAG_PAYLOAD);
rel = fwupd_result_get_release (result); rel = fwupd_result_get_release (result);
fwupd_release_set_checksum (rel, "deadbeef"); fwupd_release_add_checksum (rel, "deadbeef");
fwupd_release_set_description (rel, "<p>Hi there!</p>"); fwupd_release_set_description (rel, "<p>Hi there!</p>");
fwupd_release_set_filename (rel, "firmware.bin"); fwupd_release_set_filename (rel, "firmware.bin");
fwupd_release_set_appstream_id (rel, "org.dave.ColorHug.firmware"); 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" " Guid: 00000000-0000-0000-0000-000000000000\n"
" DeviceID: USB:foo\n" " DeviceID: USB:foo\n"
" Flags: allow-offline|require-ac\n" " Flags: allow-offline|require-ac\n"
" FirmwareHash: beefdead\n" " FirmwareHash: SHA1(beefdead)\n"
" DeviceChecksumKind: sha256\n"
" Created: 1970-01-01\n" " Created: 1970-01-01\n"
" Modified: 1970-01-02\n" " Modified: 1970-01-02\n"
" AppstreamId: org.dave.ColorHug.firmware\n" " AppstreamId: org.dave.ColorHug.firmware\n"
" UpdateDescription: <p>Hi there!</p>\n" " UpdateDescription: <p>Hi there!</p>\n"
" UpdateVersion: 1.2.3\n" " UpdateVersion: 1.2.3\n"
" FilenameCab: firmware.bin\n" " FilenameCab: firmware.bin\n"
" UpdateHash: deadbeef\n" " UpdateHash: SHA1(deadbeef)\n"
" UpdateChecksumKind: sha1\n"
" Size: 1.0 kB\n" " Size: 1.0 kB\n"
" UpdateUri: http://foo.com\n" " UpdateUri: http://foo.com\n"
" Trusted: payload\n", &error); " Trusted: payload\n", &error);

View File

@ -33,6 +33,7 @@ fwupd = shared_library(
'fwupd', 'fwupd',
sources : [ sources : [
'fwupd-client.c', 'fwupd-client.c',
'fwupd-common.c',
'fwupd-device.c', 'fwupd-device.c',
'fwupd-enums.c', 'fwupd-enums.c',
'fwupd-error.c', 'fwupd-error.c',

View File

@ -103,9 +103,11 @@ fu_plugin_verify (FuPlugin *plugin,
FuPluginVerifyFlags flags, FuPluginVerifyFlags flags,
GError **error) GError **error)
{ {
GChecksumType checksum_type;
g_autofree gchar *hash = NULL;
g_autoptr(GBytes) blob_fw = NULL; g_autoptr(GBytes) blob_fw = NULL;
GChecksumType checksum_types[] = {
G_CHECKSUM_SHA1,
G_CHECKSUM_SHA256,
0 };
/* get data */ /* get data */
fu_plugin_set_status (plugin, FWUPD_STATUS_DEVICE_VERIFY); fu_plugin_set_status (plugin, FWUPD_STATUS_DEVICE_VERIFY);
@ -115,12 +117,11 @@ fu_plugin_verify (FuPlugin *plugin,
error); error);
if (blob_fw == NULL) if (blob_fw == NULL)
return FALSE; return FALSE;
for (guint i = 0; checksum_types[i] != 0; i++) {
/* set new checksum */ g_autofree gchar *hash = NULL;
checksum_type = fu_plugin_get_checksum_type (flags); hash = g_compute_checksum_for_bytes (checksum_types[i], blob_fw);
hash = g_compute_checksum_for_bytes (checksum_type, blob_fw); fu_device_add_checksum (dev, hash);
fu_device_set_checksum (dev, hash); }
fu_device_set_checksum_kind (dev, checksum_type);
fu_plugin_set_status (plugin, FWUPD_STATUS_IDLE); fu_plugin_set_status (plugin, FWUPD_STATUS_IDLE);
return TRUE; return TRUE;
} }

View File

@ -169,11 +169,13 @@ fu_plugin_verify (FuPlugin *plugin,
{ {
FuPluginData *data = fu_plugin_get_data (plugin); FuPluginData *data = fu_plugin_get_data (plugin);
FuPluginItem *item; FuPluginItem *item;
GChecksumType checksum_type;
gsize len; gsize len;
g_autoptr(GError) error_local = NULL; g_autoptr(GError) error_local = NULL;
g_autofree gchar *hash = NULL;
g_autofree guint8 *data2 = NULL; g_autofree guint8 *data2 = NULL;
GChecksumType checksum_types[] = {
G_CHECKSUM_SHA1,
G_CHECKSUM_SHA256,
0 };
/* find item */ /* find item */
item = g_hash_table_lookup (data->devices, fu_device_get_id (device)); item = g_hash_table_lookup (data->devices, fu_device_get_id (device));
@ -208,10 +210,12 @@ fu_plugin_verify (FuPlugin *plugin,
} }
/* get the checksum */ /* get the checksum */
checksum_type = fu_plugin_get_checksum_type (flags); for (guint i = 0; checksum_types[i] != 0; i++) {
hash = g_compute_checksum_for_data (checksum_type, (guchar *) data2, len); g_autofree gchar *hash = NULL;
fu_device_set_checksum (device, hash); hash = g_compute_checksum_for_data (checksum_types[i],
fu_device_set_checksum_kind (device, checksum_type); (guchar *) data2, len);
fu_device_add_checksum (device, hash);
}
/* we're done here */ /* we're done here */
if (!g_usb_device_close (item->usb_device, &error_local)) if (!g_usb_device_close (item->usb_device, &error_local))

View File

@ -287,13 +287,15 @@ fu_plugin_verify (FuPlugin *plugin,
{ {
FuPluginData *data = fu_plugin_get_data (plugin); FuPluginData *data = fu_plugin_get_data (plugin);
GBytes *blob_fw; GBytes *blob_fw;
GChecksumType checksum_type;
DfuDevice *device; DfuDevice *device;
const gchar *platform_id; const gchar *platform_id;
g_autofree gchar *hash = NULL;
g_autoptr(DfuDevice) dfu_device = NULL; g_autoptr(DfuDevice) dfu_device = NULL;
g_autoptr(DfuFirmware) dfu_firmware = NULL; g_autoptr(DfuFirmware) dfu_firmware = NULL;
g_autoptr(GError) error_local = NULL; g_autoptr(GError) error_local = NULL;
GChecksumType checksum_types[] = {
G_CHECKSUM_SHA1,
G_CHECKSUM_SHA256,
0 };
/* get device */ /* get device */
platform_id = fu_device_get_id (dev); 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); blob_fw = dfu_firmware_write_data (dfu_firmware, error);
if (blob_fw == NULL) if (blob_fw == NULL)
return FALSE; return FALSE;
checksum_type = fu_plugin_get_checksum_type (flags); for (guint i = 0; checksum_types[i] != 0; i++) {
hash = g_compute_checksum_for_bytes (checksum_type, blob_fw); g_autofree gchar *hash = NULL;
fu_device_set_checksum (dev, hash); hash = g_compute_checksum_for_bytes (checksum_types[i], blob_fw);
fu_device_set_checksum_kind (dev, checksum_type); fu_device_add_checksum (dev, hash);
}
fu_plugin_set_status (plugin, FWUPD_STATUS_IDLE); fu_plugin_set_status (plugin, FWUPD_STATUS_IDLE);
return TRUE; return TRUE;
} }

View File

@ -105,7 +105,7 @@ fu_plugin_verify (FuPlugin *plugin,
rom = fu_rom_new (); rom = fu_rom_new ();
if (!fu_rom_load_file (rom, file, FU_ROM_LOAD_FLAG_BLANK_PPID, NULL, error)) if (!fu_rom_load_file (rom, file, FU_ROM_LOAD_FLAG_BLANK_PPID, NULL, error))
return FALSE; return FALSE;
fu_device_set_checksum (device, fu_rom_get_checksum (rom)); fu_device_add_checksum (device, fu_rom_get_checksum (rom));
return TRUE; return TRUE;
} }

View File

@ -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_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_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_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_add_checksum(d,v) fwupd_device_add_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_set_created(d,v) fwupd_device_set_created(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_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) #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_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_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_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_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_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) #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) #define fu_device_set_flashes_left(d,v) fwupd_device_set_flashes_left(fwupd_result_get_device(FWUPD_RESULT(d)),v)
/* compat getters */ /* compat getters */
#define fu_device_get_checksum(d) fwupd_device_get_checksum(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_checksum_kind(d) fwupd_device_get_checksum_kind(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_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_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_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_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_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_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_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_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)) #define fu_device_get_update_state(d) fwupd_result_get_update_state(FWUPD_RESULT(d))

View File

@ -33,6 +33,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <fcntl.h> #include <fcntl.h>
#include "fwupd-common-private.h"
#include "fwupd-enums-private.h" #include "fwupd-enums-private.h"
#include "fwupd-release-private.h" #include "fwupd-release-private.h"
#include "fwupd-resources.h" #include "fwupd-resources.h"
@ -327,7 +328,7 @@ fu_main_set_release_from_item (FwupdRelease *rel, AsRelease *release)
if (csum != NULL) { if (csum != NULL) {
tmp = as_checksum_get_value (csum); tmp = as_checksum_get_value (csum);
if (tmp != NULL) 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)); 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) fu_main_verify_update_device_to_app (FuDevice *device)
{ {
AsApp *app = NULL; AsApp *app = NULL;
GPtrArray *checksums;
g_autofree gchar *id = NULL; g_autofree gchar *id = NULL;
g_autoptr(AsChecksum) csum = NULL;
g_autoptr(AsProvide) prov = NULL; g_autoptr(AsProvide) prov = NULL;
g_autoptr(AsRelease) rel = 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); as_app_set_kind (app, AS_APP_KIND_FIRMWARE);
rel = as_release_new (); rel = as_release_new ();
as_release_set_version (rel, fu_device_get_version (device)); as_release_set_version (rel, fu_device_get_version (device));
csum = as_checksum_new (); checksums = fu_device_get_checksums (device);
as_checksum_set_kind (csum, fu_device_get_checksum_kind (device)); for (guint j = 0; j < checksums->len; j++) {
as_checksum_set_value (csum, fu_device_get_checksum (device)); 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_checksum_set_target (csum, AS_CHECKSUM_TARGET_CONTENT);
as_release_add_checksum (rel, csum); as_release_add_checksum (rel, csum);
}
as_app_add_release (app, rel); as_app_add_release (app, rel);
prov = as_provide_new (); prov = as_provide_new ();
as_provide_set_kind (prov, AS_PROVIDE_KIND_FIRMWARE_FLASHED); 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 ++) { for (guint i = 0; i < helper->devices->len; i ++) {
FuDevice *device = g_ptr_array_index (helper->devices, i); FuDevice *device = g_ptr_array_index (helper->devices, i);
FuDeviceItem *item; FuDeviceItem *item;
GPtrArray *checksums;
g_autoptr(AsApp) app = NULL; g_autoptr(AsApp) app = NULL;
item = fu_main_get_item_by_id (helper->priv, 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 */ /* 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, if (!fu_plugin_runner_verify (item->plugin,
item->device, item->device,
FU_PLUGIN_VERIFY_FLAG_NONE, FU_PLUGIN_VERIFY_FLAG_NONE,
@ -557,7 +564,7 @@ fu_main_plugin_verify_update_authenticated (FuMainAuthHelper *helper, GError **e
} }
/* we got nothing */ /* we got nothing */
if (fu_device_get_checksum (item->device) == NULL) { if (checksums->len == 0) {
g_set_error_literal (error, g_set_error_literal (error,
FWUPD_ERROR, FWUPD_ERROR,
FWUPD_ERROR_NOT_SUPPORTED, FWUPD_ERROR_NOT_SUPPORTED,
@ -2170,6 +2177,7 @@ fu_main_daemon_method_call (GDBusConnection *connection, const gchar *sender,
AsChecksum *csum; AsChecksum *csum;
AsRelease *release; AsRelease *release;
FuDeviceItem *item = NULL; FuDeviceItem *item = NULL;
GPtrArray *checksums;
const gchar *hash = NULL; const gchar *hash = NULL;
const gchar *id = NULL; const gchar *id = NULL;
const gchar *version = 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); fu_main_invocation_return_error (priv, invocation, error);
return; 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) { if (g_strcmp0 (as_checksum_get_value (csum), hash) != 0) {
g_set_error (&error, g_set_error (&error,
FWUPD_ERROR, FWUPD_ERROR,

View File

@ -1141,11 +1141,3 @@ fu_plugin_new (void)
plugin = g_object_new (FU_TYPE_PLUGIN, NULL); plugin = g_object_new (FU_TYPE_PLUGIN, NULL);
return plugin; 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;
}

View File

@ -55,7 +55,6 @@ struct _FuPluginClass
typedef enum { typedef enum {
FU_PLUGIN_VERIFY_FLAG_NONE = 0, FU_PLUGIN_VERIFY_FLAG_NONE = 0,
FU_PLUGIN_VERIFY_FLAG_USE_SHA256 = 1 << 0,
FU_PLUGIN_VERIFY_FLAG_LAST FU_PLUGIN_VERIFY_FLAG_LAST
} FuPluginVerifyFlags; } FuPluginVerifyFlags;
@ -84,7 +83,6 @@ void fu_plugin_recoldplug (FuPlugin *plugin);
void fu_plugin_set_coldplug_delay (FuPlugin *plugin, void fu_plugin_set_coldplug_delay (FuPlugin *plugin,
guint duration); guint duration);
gboolean fu_plugin_has_device_delay (FuPlugin *plugin); gboolean fu_plugin_has_device_delay (FuPlugin *plugin);
GChecksumType fu_plugin_get_checksum_type (FuPluginVerifyFlags flags);
gpointer fu_plugin_cache_lookup (FuPlugin *plugin, gpointer fu_plugin_cache_lookup (FuPlugin *plugin,
const gchar *id); const gchar *id);
void fu_plugin_cache_remove (FuPlugin *plugin, void fu_plugin_cache_remove (FuPlugin *plugin,

View File

@ -39,6 +39,7 @@
#include "fu-hwids.h" #include "fu-hwids.h"
#include "fu-pending.h" #include "fu-pending.h"
#include "fu-plugin-private.h" #include "fu-plugin-private.h"
#include "fwupd-common-private.h"
#ifndef GUdevClient_autoptr #ifndef GUdevClient_autoptr
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevClient, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevClient, g_object_unref)
@ -704,9 +705,9 @@ fu_util_download_file (FuUtilPrivate *priv,
SoupURI *uri, SoupURI *uri,
const gchar *fn, const gchar *fn,
const gchar *checksum_expected, const gchar *checksum_expected,
GChecksumType checksum_type,
GError **error) GError **error)
{ {
GChecksumType checksum_type;
const gchar *http_proxy; const gchar *http_proxy;
guint status_code; guint status_code;
g_autoptr(GError) error_local = NULL; g_autoptr(GError) error_local = NULL;
@ -717,6 +718,7 @@ fu_util_download_file (FuUtilPrivate *priv,
g_autoptr(SoupSession) session = NULL; g_autoptr(SoupSession) session = NULL;
/* check if the file already exists with the right checksum */ /* 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)) { if (fu_util_file_exists_with_checksum (fn, checksum_expected, checksum_type)) {
g_debug ("skpping download as file already exists"); g_debug ("skpping download as file already exists");
return TRUE; return TRUE;
@ -829,13 +831,13 @@ fu_util_download_metadata_for_remote (FuUtilPrivate *priv,
/* download the metadata */ /* download the metadata */
filename = g_build_filename (cache_dir, fwupd_remote_get_filename (remote), NULL); filename = g_build_filename (cache_dir, fwupd_remote_get_filename (remote), NULL);
if (!fu_util_download_file (priv, fwupd_remote_get_uri (remote), if (!fu_util_download_file (priv, fwupd_remote_get_uri (remote),
filename, NULL, 0, error)) filename, NULL, error))
return FALSE; return FALSE;
/* download the signature */ /* download the signature */
filename_asc = g_build_filename (cache_dir, fwupd_remote_get_filename_asc (remote), NULL); 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), if (!fu_util_download_file (priv, fwupd_remote_get_uri_asc (remote),
filename_asc, NULL, 0, error)) filename_asc, NULL, error))
return FALSE; return FALSE;
/* send all this to fwupd */ /* send all this to fwupd */
@ -905,20 +907,6 @@ fu_util_get_results (FuUtilPrivate *priv, gchar **values, GError **error)
return TRUE; 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 static gboolean
fu_util_get_releases (FuUtilPrivate *priv, gchar **values, GError **error) 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; return FALSE;
for (guint i = 0; i < rels->len; i++) { for (guint i = 0; i < rels->len; i++) {
FwupdRelease *rel = g_ptr_array_index (rels, i); FwupdRelease *rel = g_ptr_array_index (rels, i);
GPtrArray *checksums;
const gchar *tmp = fwupd_release_get_description (rel); const gchar *tmp = fwupd_release_get_description (rel);
/* TRANSLATORS: section header for release version number */ /* 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 */ /* TRANSLATORS: section header for firmware description */
fu_util_print_data (_("Description"), desc); fu_util_print_data (_("Description"), desc);
} }
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 */ /* TRANSLATORS: section header for firmware checksum */
fu_util_print_data (_("Checksum"), fwupd_release_get_checksum (rel)); fu_util_print_data (_("Checksum"), checksum_display);
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);
} }
/* new line between all but last entries */ /* 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 *results = NULL;
GPtrArray *guids; GPtrArray *guids;
GChecksumType checksum_type;
const gchar *tmp; const gchar *tmp;
/* print any updates */ /* 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); FwupdResult *res = g_ptr_array_index (results, i);
FwupdDevice *dev = fwupd_result_get_device (res); FwupdDevice *dev = fwupd_result_get_device (res);
FwupdRelease *rel = fwupd_result_get_release (res); FwupdRelease *rel = fwupd_result_get_release (res);
GPtrArray *checksums;
/* TRANSLATORS: first replacement is device name */ /* TRANSLATORS: first replacement is device name */
g_print (_("%s has firmware updates:"), fwupd_device_get_name (dev)); 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"), fu_util_print_data (_("Update Remote ID"),
fwupd_release_get_remote_id (rel)); fwupd_release_get_remote_id (rel));
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 */ /* TRANSLATORS: section header for firmware checksum */
fu_util_print_data (_("Update Checksum"), fu_util_print_data (_("Update Checksum"), checksum_display);
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);
} }
/* TRANSLATORS: section header for firmware remote http:// */ /* TRANSLATORS: section header for firmware remote http:// */
@ -1207,12 +1193,32 @@ fu_util_monitor (FuUtilPrivate *priv, gchar **values, GError **error)
return TRUE; 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 static gboolean
fu_util_update_device_with_release (FuUtilPrivate *priv, fu_util_update_device_with_release (FuUtilPrivate *priv,
FwupdDevice *dev, FwupdDevice *dev,
FwupdRelease *rel, FwupdRelease *rel,
GError **error) GError **error)
{ {
GPtrArray *checksums;
const gchar *remote_id; const gchar *remote_id;
const gchar *uri_tmp; const gchar *uri_tmp;
g_autofree gchar *basename = NULL; g_autofree gchar *basename = NULL;
@ -1249,9 +1255,9 @@ fu_util_update_device_with_release (FuUtilPrivate *priv,
fwupd_device_get_name (dev)); fwupd_device_get_name (dev));
basename = g_path_get_basename (uri_tmp); basename = g_path_get_basename (uri_tmp);
fn = g_build_filename (cache_dir, basename, NULL); fn = g_build_filename (cache_dir, basename, NULL);
checksums = fwupd_release_get_checksums (rel);
if (!fu_util_download_file (priv, uri, fn, if (!fu_util_download_file (priv, uri, fn,
fwupd_release_get_checksum (rel), fu_util_get_best_checksum (checksums),
fwupd_release_get_checksum_kind (rel),
error)) error))
return FALSE; return FALSE;
g_print ("Updating %s on %s...\n", 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); FwupdResult *res = g_ptr_array_index (results, i);
FwupdDevice *dev = fwupd_result_get_device (res); FwupdDevice *dev = fwupd_result_get_device (res);
FwupdRelease *rel = fwupd_result_get_release (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; continue;
if (fwupd_release_get_uri (rel) == NULL) if (fwupd_release_get_uri (rel) == NULL)
continue; continue;