Compare commits

...

No commits in common. "c8" and "c9s-uprev_1.9.10" have entirely different histories.

16 changed files with 1784 additions and 1379 deletions

1
.fwupd.metadata Normal file
View File

@ -0,0 +1 @@
c6c492b9acf3c741c8273c9b49db5400ae755e6b fwupd-1.9.10.tar.xz

111
.gitignore vendored
View File

@ -1,10 +1,101 @@
SOURCES/DBXUpdate-20100307-x64.cab
SOURCES/DBXUpdate-20140413-x64.cab
SOURCES/DBXUpdate-20160809-x64.cab
SOURCES/DBXUpdate-20200729-aa64.cab
SOURCES/DBXUpdate-20200729-ia32.cab
SOURCES/DBXUpdate-20200729-x64.cab
SOURCES/almalinuxsecurebootca0.cer
SOURCES/fwupd-1.7.8.tar.xz
SOURCES/fwupd-efi-1.3.tar.xz
SOURCES/libjcat-0.1.9.tar.xz
/fwupd-0.1.0.tar.xz
/fwupd-0.1.1.tar.xz
/fwupd-0.1.2.tar.xz
/fwupd-0.1.3.tar.xz
/fwupd-0.1.4.tar.xz
/fwupd-0.1.5.tar.xz
/fwupd-0.1.6.tar.xz
/fwupd-0.5.0.tar.xz
/fwupd-0.5.1.tar.xz
/fwupd-0.5.2.tar.xz
/fwupd-0.5.3.tar.xz
/fwupd-0.5.4.tar.xz
/fwupd-0.6.0.tar.xz
/fwupd-0.6.1.tar.xz
/fwupd-0.6.2.tar.xz
/fwupd-0.6.3.tar.xz
/fwupd-0.7.0.tar.xz
/fwupd-0.7.1.tar.xz
/fwupd-0.7.2.tar.xz
/fwupd-0.7.3.tar.xz
/fwupd-0.7.4.tar.xz
/fwupd-0.7.5.tar.xz
/fwupd-0.8.0.tar.xz
/fwupd-0.8.1.tar.xz
/fwupd-0.8.2.tar.xz
/fwupd-0.9.2.tar.xz
/fwupd-0.9.3.tar.xz
/fwupd-0.9.4.tar.xz
/fwupd-0.9.5.tar.xz
/fwupd-0.9.6.tar.xz
/fwupd-0.9.7.tar.xz
/fwupd-1.0.0.tar.xz
/fwupd-1.0.1.tar.xz
/fwupd-1.0.2.tar.xz
/fwupd-1.0.3.tar.xz
/fwupd-1.0.4.tar.xz
/fwupd-1.0.5.tar.xz
/fwupd-1.0.6.tar.xz
/fwupd-1.0.7.tar.xz
/fwupd-1.0.8.tar.xz
/fwupd-1.1.0.tar.xz
/fwupd-1.1.1.tar.xz
/fwupd-1.1.2.tar.xz
/fwupd-1.1.3.tar.xz
/fwupd-1.2.0.tar.xz
/fwupd-1.2.1.tar.xz
/fwupd-1.2.2.tar.xz
/fwupd-1.2.3.tar.xz
/fwupd-1.2.4.tar.xz
/fwupd-1.2.5.tar.xz
/fwupd-1.2.6.tar.xz
/fwupd-1.2.7.tar.xz
/fwupd-1.2.8.tar.xz
/fwupd-1.2.9.tar.xz
/fwupd-1.2.10.tar.xz
/fwupd-1.3.2.tar.xz
/fwupd-1.3.3.tar.xz
/fwupd-1.3.4.tar.xz
/fwupd-1.3.5.tar.xz
/fwupd-1.3.6.tar.xz
/fwupd-1.3.7.tar.xz
/fwupd-1.3.8.tar.xz
/fwupd-1.3.9.tar.xz
/fwupd-1.4.0.tar.xz
/fwupd-1.4.1.tar.xz
/fwupd-1.4.2.tar.xz
/fwupd-1.4.3.tar.xz
/fwupd-1.4.4.tar.xz
/fwupd-1.4.5.tar.xz
/fwupd-1.4.6.tar.xz
/fwupd-1.5.0.tar.xz
/fwupd-1.5.1.tar.xz
/fwupd-1.5.2.tar.xz
/fwupd-1.5.3.tar.xz
/fwupd-1.5.4.tar.xz
/fwupd-1.5.5.tar.xz
/fwupd-1.5.9.tar.xz
/DBXUpdate-20100307-x64.cab
/DBXUpdate-20140413-x64.cab
/DBXUpdate-20160809-x64.cab
/DBXUpdate-20200729-aa64.cab
/DBXUpdate-20200729-ia32.cab
/DBXUpdate-20200729-x64.cab
/fwupd-1.7.1.tar.xz
/fwupd-efi-1.1.tar.xz
/fwupd-1.7.4.tar.xz
/fwupd-1.7.9.tar.xz
/fwupd-efi-1.3.tar.xz
/DBXUpdate-20210429-x64.cab
/DBXUpdate-20220812-aa64.cab
/DBXUpdate-20220812-ia32.cab
/DBXUpdate-20220812-x64.cab
/fwupd-1.7.10.tar.xz
/fwupd-efi-1.3.tar.xz
/fwupd-efi-1.4.tar.xz
/fwupd-1.8.10.tar.xz
/fwupd-1.8.16.tar.xz
/DBXUpdate-20230509-aa64.cab
/DBXUpdate-20230509-ia32.cab
/DBXUpdate-20230509-x64.cab
/fwupd-1.9.10.tar.xz

View File

@ -0,0 +1,25 @@
From e887e1fd8a94fa0c65c7941acd5dfde6f6f8791c Mon Sep 17 00:00:00 2001
From: Richard Hughes <richard@hughsie.com>
Date: Mon, 4 Dec 2023 12:02:09 +0000
Subject: [PATCH] Do not check jcat.pc for supported engines
---
data/pki/meson.build | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/data/pki/meson.build b/data/pki/meson.build
index 58719cb7e..44e9840dd 100644
--- a/data/pki/meson.build
+++ b/data/pki/meson.build
@@ -1,6 +1,6 @@
# only install files that are going to be used
-supported_gpg = libjcat.get_variable(pkgconfig: 'supported_gpg', default_value: '0') == '1'
-supported_pkcs7 = libjcat.get_variable(pkgconfig: 'supported_pkcs7', default_value: '0') == '1' or host_machine.system() == 'windows'
+supported_gpg = true
+supported_pkcs7 = true
if supported_gpg
install_data([
--
2.43.0

View File

@ -0,0 +1,91 @@
From cfd61f6958a46d5e9687f87caf04c94680382a9f Mon Sep 17 00:00:00 2001
From: Nicolas Frayer <nfrayer@redhat.com>
Date: Wed, 1 Feb 2023 12:13:45 +0100
Subject: [PATCH] generate_binary: Add NX COMPAT flag manually when genpeimg
missing
When genpeimg or python3-pefile is missing, add the NX COMPAT flag
manually by setting bit8 of the DllCharacteristics in the optional
header, clear the TimeDateStamp and update the checksum.
---
efi/generate_binary.py | 50 ++++++++++++++++++++++++++++++++++++++++--
1 file changed, 48 insertions(+), 2 deletions(-)
diff --git a/efi/generate_binary.py b/efi/generate_binary.py
index 7b802e7..10ab0b3 100755
--- a/efi/generate_binary.py
+++ b/efi/generate_binary.py
@@ -10,6 +10,13 @@
import subprocess
import sys
import argparse
+import os
+import struct
+
+COFF_HDR_OFFSET = 0x80
+OPTIONALHDR_CHECKSUM = COFF_HDR_OFFSET + 0x58
+OPTIONALHDR_DLLCHARACTERISTICS = COFF_HDR_OFFSET + 0x5E
+PEHEADER_TIMEDATASTAMP = COFF_HDR_OFFSET + 0x8
def _run_objcopy(args):
@@ -66,6 +73,27 @@ def _run_genpeimg(args):
sys.exit(1)
+def generate_checksum(data):
+ checksum_offset: int = OPTIONALHDR_CHECKSUM
+ checksum: int = 0
+ remainder: int = len(data) % 4
+ data_len: int = len(data) + ((4 - remainder) * (remainder != 0))
+ for i in range(int(data_len / 4)):
+ if i == int(checksum_offset / 4):
+ continue
+ if i + 1 == (int(data_len / 4)) and remainder:
+ dword = struct.unpack("I", data[i * 4 :] + (b"\0" * (4 - remainder)))[0]
+ else:
+ dword = struct.unpack("I", data[i * 4 : i * 4 + 4])[0]
+ checksum += dword
+ if checksum >= 2**32:
+ checksum = (checksum & 0xFFFFFFFF) + (checksum >> 32)
+ checksum = (checksum & 0xFFFF) + (checksum >> 16)
+ checksum = checksum + (checksum >> 16)
+ checksum = checksum & 0xFFFF
+ return checksum + len(data)
+
+
def _add_nx_pefile(args):
# unnecessary if we have genpeimg
if args.genpeimg:
@@ -73,8 +101,26 @@ def _add_nx_pefile(args):
try:
import pefile
except ImportError:
- print("Unable to add NX support to binaries without genpeimg or python3-pefile")
- sys.exit(1)
+ print("Adding NX support manually to the binary")
+ with open(args.outfile, "r+b") as fh:
+ buf = bytearray(fh.read(os.path.getsize(args.outfile)))
+ fh.seek(0)
+ DllCharacteristics = struct.unpack_from(
+ "<H", buf, OPTIONALHDR_DLLCHARACTERISTICS
+ )[0]
+ DllCharacteristics |= 0x100
+ struct.pack_into(
+ "<H", buf, OPTIONALHDR_DLLCHARACTERISTICS, DllCharacteristics
+ )
+
+ # set the timestamp to 0
+ struct.pack_into("<I", buf, PEHEADER_TIMEDATASTAMP, 0x0)
+
+ # as we have set the NX COMPAT bit, regenerate the checksum
+ struct.pack_into("<I", buf, OPTIONALHDR_CHECKSUM, generate_checksum(buf))
+ fh.write(buf)
+
+ return
pe = pefile.PE(args.outfile)
pe.OPTIONAL_HEADER.DllCharacteristics |= pefile.DLL_CHARACTERISTICS[
--
2.39.1

View File

@ -1,29 +0,0 @@
From 1fc24adecbb62b3cd77ef965c5daf1b72f6c7aa8 Mon Sep 17 00:00:00 2001
From: Richard Hughes <richard@hughsie.com>
Date: Tue, 22 Aug 2023 10:05:27 +0100
Subject: [PATCH] Use /usr/libexec/platform-python for RHEL
---
meson.build | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/meson.build b/meson.build
index bb406d616..ac90c8ee6 100644
--- a/meson.build
+++ b/meson.build
@@ -261,11 +261,7 @@ if libgcab.type_name() == 'pkgconfig' and cc.has_function('gcab_file_set_bytes',
endif
bashcomp = dependency('bash-completion', required: false)
-if host_machine.system() != 'freebsd'
- python3 = find_program('python3')
-else
- python3 = find_program('python3.8', 'python3', 'python3.9')
-endif
+python3 = find_program('/usr/libexec/platform-python')
if get_option('gnutls')
gnutls = dependency('gnutls', version : '>= 3.6.0')
--
2.41.0

View File

@ -1,28 +0,0 @@
From 442f7f9200fbf6ec509dd0ee40eae2e37b2fb73e Mon Sep 17 00:00:00 2001
From: Richard Hughes <richard@hughsie.com>
Date: Tue, 20 Sep 2022 08:06:12 +0100
Subject: [PATCH 1/3] redfish: Set the permissions of redfish.conf at install
time
Although typically we set the password using fu_plugin_set_secure_config_value()
or something like Ansible or Puppet -- the user could just edit the file with
vim and we still want the permissions set correctly.
---
plugins/redfish/meson.build | 1 +
1 file changed, 1 insertion(+)
diff --git a/plugins/redfish/meson.build b/plugins/redfish/meson.build
index 34ba4b7f6..7b19574de 100644
--- a/plugins/redfish/meson.build
+++ b/plugins/redfish/meson.build
@@ -48,6 +48,7 @@ shared_module('fu_plugin_redfish',
install_data(['redfish.conf'],
install_dir: join_paths(sysconfdir, 'fwupd'),
+ install_mode: 'rw-r-----',
)
if get_option('tests')
--
2.39.1

View File

@ -1,47 +0,0 @@
From 4f39b747a6d860e32a3000451dd2635366c81776 Mon Sep 17 00:00:00 2001
From: Richard Hughes <richard@hughsie.com>
Date: Tue, 20 Sep 2022 09:13:52 +0100
Subject: [PATCH 2/3] redfish: Only create users using IPMI when we know it's
going to work
Make the IPMI auto-account feature allow-listed on specific vendors as some IPMI
implementations are not specification compliant and do entirely the wrong thing.
---
plugins/redfish/fu-plugin-redfish.c | 8 ++++++++
plugins/redfish/redfish.quirk | 2 +-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/plugins/redfish/fu-plugin-redfish.c b/plugins/redfish/fu-plugin-redfish.c
index deb0fe742..3972d4b4b 100644
--- a/plugins/redfish/fu-plugin-redfish.c
+++ b/plugins/redfish/fu-plugin-redfish.c
@@ -422,6 +422,14 @@ fu_plugin_redfish_startup(FuPlugin *plugin, GError **error)
#ifdef HAVE_LINUX_IPMI_H
/* we got neither a type 42 entry or config value, lets try IPMI */
if (fu_redfish_backend_get_username(data->backend) == NULL) {
+ if (!fu_context_has_hwid_flag(fu_plugin_get_context(plugin), "ipmi-create-user")) {
+ g_set_error_literal(error,
+ FWUPD_ERROR,
+ FWUPD_ERROR_NOT_SUPPORTED,
+ "no username and password specified, "
+ "and no vendor quirk for 'ipmi-create-user'");
+ return FALSE;
+ }
if (!fu_plugin_get_config_value_boolean(plugin, "IpmiDisableCreateUser")) {
g_debug("attempting to create user using IPMI");
if (!fu_redfish_plugin_ipmi_create_user(plugin, error))
diff --git a/plugins/redfish/redfish.quirk b/plugins/redfish/redfish.quirk
index b12439926..5e9722fda 100644
--- a/plugins/redfish/redfish.quirk
+++ b/plugins/redfish/redfish.quirk
@@ -1,6 +1,6 @@
# Lenovo ThinkSystem
[42f00735-c9ab-5374-bd63-a5deee5881e0]
-Flags = wildcard-targets,reset-required
+Flags = wildcard-targets,reset-required,ipmi-create-user
[REDFISH\VENDOR_Lenovo&ID_BMC-Backup]
ParentGuid = REDFISH\VENDOR_Lenovo&ID_BMC-Primary
--
2.39.1

View File

@ -1,141 +0,0 @@
From 41575afd93ca0e68bced78ca43a4488f124906a1 Mon Sep 17 00:00:00 2001
From: Richard Hughes <richard@hughsie.com>
Date: Wed, 21 Sep 2022 14:56:10 +0100
Subject: [PATCH 3/3] Never save the Redfish passwords to a file readable by
users
When the redfish plugin automatically creates an OPERATOR user account on the
BMC we save the autogenerated password to /etc/fwupd/redfish.conf, ensuring it
is chmod'ed to 0660 before writing the file with g_key_file_save_to_file().
Under the covers, g_key_file_save_to_file() calls g_file_set_contents() with
the keyfile string data.
I was under the impression that G_FILE_CREATE_REPLACE_DESTINATION was being
used to copy permissions, but alas not.
GLib instead calls g_file_set_contents_full() with the mode hardcoded to 0666,
which undoes the previous chmod().
Use g_file_set_contents_full() with the correct mode for newer GLib versions,
and provide a fallback with the same semantics for older versions.
---
contrib/fwupd.spec.in | 3 ++
libfwupdplugin/fu-plugin.c | 65 +++++++++++++++++++++++++++++------
libfwupdplugin/fu-self-test.c | 57 ++++++++++++++++++++++++++++++
3 files changed, 114 insertions(+), 11 deletions(-)
diff --git a/contrib/fwupd.spec.in b/contrib/fwupd.spec.in
index a50e30a9c..0854fcf4f 100644
--- a/contrib/fwupd.spec.in
+++ b/contrib/fwupd.spec.in
@@ -313,6 +313,9 @@ for fn in /etc/fwupd/remotes.d/*.conf; do
fi
done
+# ensure this is private
+chmod 0660 /etc/fwupd/redfish.conf
+
%preun
%systemd_preun fwupd.service
diff --git a/libfwupdplugin/fu-plugin.c b/libfwupdplugin/fu-plugin.c
index 18042a028..04951de85 100644
--- a/libfwupdplugin/fu-plugin.c
+++ b/libfwupdplugin/fu-plugin.c
@@ -9,6 +9,7 @@
#include "config.h"
#include <errno.h>
+#include <fcntl.h>
#include <fwupd.h>
#include <glib/gstdio.h>
#include <gmodule.h>
@@ -2256,6 +2257,46 @@ fu_plugin_set_config_value(FuPlugin *self, const gchar *key, const gchar *value,
return g_key_file_save_to_file(keyfile, conf_path, error);
}
+#if !GLIB_CHECK_VERSION(2, 66, 0)
+
+#define G_FILE_SET_CONTENTS_CONSISTENT 0
+typedef guint GFileSetContentsFlags;
+static gboolean
+g_file_set_contents_full(const gchar *filename,
+ const gchar *contents,
+ gssize length,
+ GFileSetContentsFlags flags,
+ int mode,
+ GError **error)
+{
+ gint fd;
+ gssize wrote;
+
+ if (length < 0)
+ length = strlen(contents);
+ fd = g_open(filename, O_CREAT, mode);
+ if (fd <= 0) {
+ g_set_error(error,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "could not open %s file",
+ filename);
+ return FALSE;
+ }
+ wrote = write(fd, contents, length);
+ if (wrote != length) {
+ g_set_error(error,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "did not write %s file",
+ filename);
+ g_close(fd, NULL);
+ return FALSE;
+ }
+ return g_close(fd, error);
+}
+#endif
+
/**
* fu_plugin_set_secure_config_value:
* @self: a #FuPlugin
@@ -2277,7 +2318,8 @@ fu_plugin_set_secure_config_value(FuPlugin *self,
GError **error)
{
g_autofree gchar *conf_path = fu_plugin_get_config_filename(self);
- gint ret;
+ g_autofree gchar *data = NULL;
+ g_autoptr(GKeyFile) keyfile = g_key_file_new();
g_return_val_if_fail(FU_IS_PLUGIN(self), FALSE);
g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
@@ -2286,17 +2328,18 @@ fu_plugin_set_secure_config_value(FuPlugin *self,
g_set_error(error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND, "%s is missing", conf_path);
return FALSE;
}
- ret = g_chmod(conf_path, 0660);
- if (ret == -1) {
- g_set_error(error,
- FWUPD_ERROR,
- FWUPD_ERROR_INTERNAL,
- "failed to set permissions on %s",
- conf_path);
+ if (!g_key_file_load_from_file(keyfile, conf_path, G_KEY_FILE_KEEP_COMMENTS, error))
return FALSE;
- }
-
- return fu_plugin_set_config_value(self, key, value, error);
+ g_key_file_set_string(keyfile, fu_plugin_get_name(self), key, value);
+ data = g_key_file_to_data(keyfile, NULL, error);
+ if (data == NULL)
+ return FALSE;
+ return g_file_set_contents_full(conf_path,
+ data,
+ -1,
+ G_FILE_SET_CONTENTS_CONSISTENT,
+ 0660,
+ error);
}
/**
--
2.39.1

File diff suppressed because it is too large Load Diff

1545
fwupd.spec Normal file

File diff suppressed because it is too large Load Diff

6
gating.yaml Normal file
View File

@ -0,0 +1,6 @@
--- !Policy
product_versions:
- rhel-9
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: kernel-qe.kernel-ci.hardware-fwupd.tier0.functional}

BIN
redhatsecureboot301.cer Normal file

Binary file not shown.

BIN
redhatsecureboot503.cer Normal file

Binary file not shown.

BIN
redhatsecurebootca3.cer Normal file

Binary file not shown.

BIN
redhatsecurebootca5.cer Normal file

Binary file not shown.

15
sources Normal file
View File

@ -0,0 +1,15 @@
SHA512 (fwupd-1.9.10.tar.xz) = 308bcd3af84d82157492a2ee8dc6fa4d7df6a66cca64e45b3dff9b46d0367f7d3122671388b627f67ab59a69bac1cb36feeccd1668cce0487fe466736dd8b8cc
SHA512 (fwupd-efi-1.4.tar.xz) = c330409861a8c1e332a0d4fd49c54ef2c5bf7cdaca99d14de39b50fb35f0c490e9f7f7a4c9dd48181bd509cd358c43eb23659536aea93408c1fefb47629e4991
SHA512 (DBXUpdate-20100307-x64.cab) = f8ad56cf015f4cdc5c305856ff1f7a8589c25a2a671708c61883f427f38eb9b6a7abd3f2c8d79ef9d5076222255e42585917f8705a2a4b13f860bad4e02ec409
SHA512 (DBXUpdate-20140413-x64.cab) = 75771876a2309fa8ca083c2e76520173d434229b7cacf1e7636bd9b1bc4f871d745c348b9792bfb65fd9f40ef54c25bb427b1431151e817e7050b7829456731a
SHA512 (DBXUpdate-20160809-x64.cab) = c27c564999ae84515540f1a598cd0fd9ef3a80cdfaaf439f1c4cb04eaee0e73074548b6d76c21ca3af1ba9c4c0625907e821582998eb5617e33ecd412e6c8a13
SHA512 (DBXUpdate-20200729-aa64.cab) = 7a0cea13ed9b645fd9f1d5e3410a451d83643a75f5dc603272b0771b093f2c012f9a19419160403631c250cf64127ad2ce1c8fa2079b04064af73fe85b9add33
SHA512 (DBXUpdate-20200729-ia32.cab) = 578ec9cccf2001b8bfa54b66809a1662269677050e74bd3225536fbd2be56a8162c48669bd16ea553723580195df1693a28dc01fc1cf62ff06e36a2c5568f74f
SHA512 (DBXUpdate-20200729-x64.cab) = b8b195167d286a3f16aaa7c89149a0d5b4c8f53080e3265758b912f250fa655533c603359b7d1c989ebad6953ce443809b3317ec1d00f750326945ee0537e43b
SHA512 (DBXUpdate-20210429-x64.cab) = 7bc5e7780d105da89da367fbde7c33427bed6c37752b0ae6933793dfe96121c87e49629f14c3b762fc138b10e5c5b6db821dbdc56039ab761e3dca977fc7f817
SHA512 (DBXUpdate-20220812-aa64.cab) = 422ebd0b9d15a26ad12b98798229615a1f5e272a95993934de0cd9d4e4e75589b41eae6366b52b4e25e8766bd7cf74f95d220b719649b1f3864603e46c18c193
SHA512 (DBXUpdate-20220812-ia32.cab) = 09094cc747f865e21fc815199d6ad5b6d3b1c9e19621497e3fe7cdfc4b96e144e721673bdff9ea6204dd465e8a8e2da1cc2b4a4badfd1f4f82c54eace11acb42
SHA512 (DBXUpdate-20220812-x64.cab) = 03dde66a31241ccaa562c57bd9b6b824f2a6b5a1d10affe32ee5a0452056609c981f8f7633bfc65fd0c7da79455b071dd9e02b6af7c880fb1c4a6ffdf577bcdc
SHA512 (DBXUpdate-20230509-aa64.cab) = 259f2373d6ab4cd031fe8b993825ba4cf922306afb3da1617d7b4e9d4ac918018b463135f58ace884a2ceec01789f3b2b31aaf63e63501503e4efbcf46ce567b
SHA512 (DBXUpdate-20230509-ia32.cab) = e9983039fa5283bf8357c75874842d06ac76a36e90c76406ab864a2b76f557f9649e84be3eb20ab473486cd60a08847ece0ef4015145357969067561338a7977
SHA512 (DBXUpdate-20230509-x64.cab) = b2893b431adc3b155335a07e035979a2bf08b7c06975bde7c5561f5e5c1d8ed55f337e7a4782e6ad5c4c50c286cf474a1be356991784c88c23315c467fca30bb