Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Shawn Webb
Fwupd
Commits
8dd4c1c4
Commit
8dd4c1c4
authored
Mar 03, 2019
by
Richard Hughes
Browse files
Allow restricting firmware updates for enterprise use
parent
640faed9
Changes
27
Hide whitespace changes
Inline
Side-by-side
README.md
View file @
8dd4c1c4
...
...
@@ -72,6 +72,28 @@ To clear the local history of updates:
Only updates that were distributed from the LVFS will be reported to the LVFS.
Enterprise Use
--------------
The flow of updates can be controlled in the enterprise using the
"approved updates" feature. This allows the domain administrator to filter
the possible updates from a central server (e.g. the LVFS, or a mirror)
to only firmware that have been tested specifically in your organisation.
The list of approved updates can be enabled by adding
`ApprovalRequired=true`
to the remote configuration file, e.g.
`lvfs.conf`
. Once enabled, the
list of approved updates can be set in
`daemon.conf`
using a comma delimited list.
For example:
ApprovedFirmware=foo,bar
Where
`foo,bar`
refers to the container checksums that would correspond
to two updates in the metadata file.
Additionally, the list of approved firmware can be supplemented using
`fwupdmgr set-approved-firmware baz`
or using the D-Bus interface.
Other frontends
-------------------
...
...
data/bash-completion/fwupdmgr
View file @
8dd4c1c4
...
...
@@ -6,6 +6,7 @@ _fwupdmgr_cmd_list=(
'disable-remote'
'downgrade'
'enable-remote'
'get-approved-firmware'
'get-details'
'get-devices'
'get-history'
...
...
@@ -19,6 +20,7 @@ _fwupdmgr_cmd_list=(
'modify-remote'
'refresh'
'report-history'
'set-approved-firmware'
'unlock'
'update'
'verify'
...
...
data/remotes.d/fwupd.conf
View file @
8dd4c1c4
...
...
@@ -5,3 +5,4 @@ Enabled=true
Title
=
Core
Keyring
=
none
MetadataURI
=
file
://@
datadir
@/
fwupd
/
remotes
.
d
/
fwupd
/
metadata
.
xml
ApprovalRequired
=
false
data/remotes.d/lvfs-testing.conf
View file @
8dd4c1c4
...
...
@@ -9,3 +9,4 @@ ReportURI=https://fwupd.org/lvfs/firmware/report
Username
=
Password
=
OrderBefore
=
lvfs
,
fwupd
ApprovalRequired
=
false
data/remotes.d/lvfs.conf
View file @
8dd4c1c4
...
...
@@ -7,3 +7,4 @@ Keyring=gpg
MetadataURI
=
https
://
cdn
.
fwupd
.
org
/
downloads
/
firmware
.
xml
.
gz
ReportURI
=
https
://
fwupd
.
org
/
lvfs
/
firmware
/
report
OrderBefore
=
fwupd
ApprovalRequired
=
false
data/remotes.d/vendor-directory.conf
View file @
8dd4c1c4
...
...
@@ -5,3 +5,4 @@ Enabled=false
Title
=
Vendor
(
Automatic
)
Keyring
=
none
MetadataURI
=
file
://@
datadir
@/
fwupd
/
remotes
.
d
/
vendor
/
firmware
ApprovalRequired
=
false
data/remotes.d/vendor.conf
View file @
8dd4c1c4
...
...
@@ -5,3 +5,4 @@ Enabled=false
Title
=
Vendor
Keyring
=
none
MetadataURI
=
file
://@
datadir
@/
fwupd
/
remotes
.
d
/
vendor
/
vendor
.
xml
.
gz
ApprovalRequired
=
false
data/tests/fwupd/daemon.conf
View file @
8dd4c1c4
[
fwupd
]
ArchiveSizeMax
=
5
ApprovedFirmware
=
deadbeef
data/tests/remotes.d/testing.conf
View file @
8dd4c1c4
[
fwupd
Remote
]
Enabled
=
true
MetadataURI
=
file
:///
tmp
/
fwupd
-
self
-
test
/
testing
.
xml
ApprovalRequired
=
true
libfwupd/fwupd-client.c
View file @
8dd4c1c4
...
...
@@ -1364,6 +1364,98 @@ fwupd_client_get_remotes (FwupdClient *client, GCancellable *cancellable, GError
return
fwupd_client_parse_remotes_from_data
(
val
);
}
/**
* fwupd_client_get_approved_firmware:
* @client: A #FwupdClient
* @cancellable: the #GCancellable, or %NULL
* @error: the #GError, or %NULL
*
* Gets the list of approved firmware.
*
* Returns: (transfer full): list of remotes, or %NULL
*
* Since: 1.2.6
**/
gchar
**
fwupd_client_get_approved_firmware
(
FwupdClient
*
client
,
GCancellable
*
cancellable
,
GError
**
error
)
{
FwupdClientPrivate
*
priv
=
GET_PRIVATE
(
client
);
g_autoptr
(
GVariant
)
val
=
NULL
;
gchar
**
retval
=
NULL
;
g_return_val_if_fail
(
FWUPD_IS_CLIENT
(
client
),
NULL
);
g_return_val_if_fail
(
cancellable
==
NULL
||
G_IS_CANCELLABLE
(
cancellable
),
NULL
);
g_return_val_if_fail
(
error
==
NULL
||
*
error
==
NULL
,
NULL
);
/* connect */
if
(
!
fwupd_client_connect
(
client
,
cancellable
,
error
))
return
NULL
;
/* call into daemon */
val
=
g_dbus_proxy_call_sync
(
priv
->
proxy
,
"GetApprovedFirmware"
,
NULL
,
G_DBUS_CALL_FLAGS_NONE
,
-
1
,
cancellable
,
error
);
if
(
val
==
NULL
)
{
if
(
error
!=
NULL
)
fwupd_client_fixup_dbus_error
(
*
error
);
return
NULL
;
}
g_variant_get
(
val
,
"(^as)"
,
&
retval
);
return
retval
;
}
/**
* fwupd_client_set_approved_firmware:
* @client: A #FwupdClient
* @checksums: Array of checksums
* @cancellable: the #GCancellable, or %NULL
* @error: the #GError, or %NULL
*
* Sets the list of approved firmware.
*
* Returns: %TRUE for success
*
* Since: 1.2.6
**/
gboolean
fwupd_client_set_approved_firmware
(
FwupdClient
*
client
,
gchar
**
checksums
,
GCancellable
*
cancellable
,
GError
**
error
)
{
FwupdClientPrivate
*
priv
=
GET_PRIVATE
(
client
);
g_autoptr
(
GVariant
)
val
=
NULL
;
g_return_val_if_fail
(
FWUPD_IS_CLIENT
(
client
),
FALSE
);
g_return_val_if_fail
(
cancellable
==
NULL
||
G_IS_CANCELLABLE
(
cancellable
),
FALSE
);
g_return_val_if_fail
(
error
==
NULL
||
*
error
==
NULL
,
FALSE
);
/* connect */
if
(
!
fwupd_client_connect
(
client
,
cancellable
,
error
))
return
FALSE
;
/* call into daemon */
val
=
g_dbus_proxy_call_sync
(
priv
->
proxy
,
"SetApprovedFirmware"
,
g_variant_new
(
"(^as)"
,
checksums
),
G_DBUS_CALL_FLAGS_NONE
,
-
1
,
cancellable
,
error
);
if
(
val
==
NULL
)
{
if
(
error
!=
NULL
)
fwupd_client_fixup_dbus_error
(
*
error
);
return
FALSE
;
}
return
TRUE
;
}
/**
* fwupd_client_modify_remote:
* @client: A #FwupdClient
...
...
libfwupd/fwupd-client.h
View file @
8dd4c1c4
...
...
@@ -131,4 +131,12 @@ FwupdRemote *fwupd_client_get_remote_by_id (FwupdClient *client,
GCancellable
*
cancellable
,
GError
**
error
);
gchar
**
fwupd_client_get_approved_firmware
(
FwupdClient
*
client
,
GCancellable
*
cancellable
,
GError
**
error
);
gboolean
fwupd_client_set_approved_firmware
(
FwupdClient
*
client
,
gchar
**
checksums
,
GCancellable
*
cancellable
,
GError
**
error
);
G_END_DECLS
libfwupd/fwupd-enums.c
View file @
8dd4c1c4
...
...
@@ -391,6 +391,8 @@ fwupd_release_flag_to_string (FwupdReleaseFlags release_flag)
return
"is-downgrade"
;
if
(
release_flag
==
FWUPD_RELEASE_FLAG_BLOCKED_VERSION
)
return
"blocked-version"
;
if
(
release_flag
==
FWUPD_RELEASE_FLAG_BLOCKED_APPROVAL
)
return
"blocked-approval"
;
return
NULL
;
}
...
...
@@ -417,5 +419,7 @@ fwupd_release_flag_from_string (const gchar *release_flag)
return
FWUPD_RELEASE_FLAG_IS_DOWNGRADE
;
if
(
g_strcmp0
(
release_flag
,
"blocked-version"
)
==
0
)
return
FWUPD_RELEASE_FLAG_BLOCKED_VERSION
;
if
(
g_strcmp0
(
release_flag
,
"blocked-approval"
)
==
0
)
return
FWUPD_RELEASE_FLAG_BLOCKED_APPROVAL
;
return
FWUPD_RELEASE_FLAG_NONE
;
}
libfwupd/fwupd-enums.h
View file @
8dd4c1c4
...
...
@@ -124,6 +124,7 @@ typedef guint64 FwupdDeviceFlags;
* @FWUPD_RELEASE_FLAG_IS_UPGRADE: Is newer than the device version
* @FWUPD_RELEASE_FLAG_IS_DOWNGRADE: Is older than the device version
* @FWUPD_RELEASE_FLAG_BLOCKED_VERSION: Blocked as below device version-lowest
* @FWUPD_RELEASE_FLAG_BLOCKED_APPROVAL: Blocked as release not approved
*
* The release flags.
**/
...
...
@@ -133,6 +134,7 @@ typedef guint64 FwupdDeviceFlags;
#define FWUPD_RELEASE_FLAG_IS_UPGRADE (1u << 2)
/* Since: 1.2.6 */
#define FWUPD_RELEASE_FLAG_IS_DOWNGRADE (1u << 3)
/* Since: 1.2.6 */
#define FWUPD_RELEASE_FLAG_BLOCKED_VERSION (1u << 4)
/* Since: 1.2.6 */
#define FWUPD_RELEASE_FLAG_BLOCKED_APPROVAL (1u << 5)
/* Since: 1.2.6 */
#define FWUPD_RELEASE_FLAG_UNKNOWN G_MAXUINT64
/* Since: 1.2.6 */
typedef
guint64
FwupdReleaseFlags
;
...
...
libfwupd/fwupd-remote.c
View file @
8dd4c1c4
...
...
@@ -42,6 +42,7 @@ typedef struct {
gchar
*
filename_cache_sig
;
gchar
*
filename_source
;
gboolean
enabled
;
gboolean
approval_required
;
gint
priority
;
guint64
mtime
;
gchar
**
order_after
;
...
...
@@ -52,6 +53,7 @@ enum {
PROP_0
,
PROP_ID
,
PROP_ENABLED
,
PROP_APPROVAL_REQUIRED
,
PROP_LAST
};
...
...
@@ -410,6 +412,7 @@ fwupd_remote_load_from_filename (FwupdRemote *self,
/* extract data */
priv
->
enabled
=
g_key_file_get_boolean
(
kf
,
group
,
"Enabled"
,
NULL
);
priv
->
approval_required
=
g_key_file_get_boolean
(
kf
,
group
,
"ApprovalRequired"
,
NULL
);
priv
->
title
=
g_key_file_get_string
(
kf
,
group
,
"Title"
,
NULL
);
/* reporting is optional */
...
...
@@ -910,6 +913,25 @@ fwupd_remote_get_enabled (FwupdRemote *self)
return
priv
->
enabled
;
}
/**
* fwupd_remote_get_approval_required:
* @self: A #FwupdRemote
*
* Gets if firmware from the remote should be checked against the list
* of a approved checksums.
*
* Returns: a #TRUE if the remote is restricted
*
* Since: 1.2.6
**/
gboolean
fwupd_remote_get_approval_required
(
FwupdRemote
*
self
)
{
FwupdRemotePrivate
*
priv
=
GET_PRIVATE
(
self
);
g_return_val_if_fail
(
FWUPD_IS_REMOTE
(
self
),
FALSE
);
return
priv
->
approval_required
;
}
/**
* fwupd_remote_get_id:
* @self: A #FwupdRemote
...
...
@@ -969,6 +991,8 @@ fwupd_remote_set_from_variant_iter (FwupdRemote *self, GVariantIter *iter)
fwupd_remote_set_checksum
(
self
,
g_variant_get_string
(
value
,
NULL
));
}
else
if
(
g_strcmp0
(
key
,
"Enabled"
)
==
0
)
{
priv
->
enabled
=
g_variant_get_boolean
(
value
);
}
else
if
(
g_strcmp0
(
key
,
"ApprovalRequired"
)
==
0
)
{
priv
->
approval_required
=
g_variant_get_boolean
(
value
);
}
else
if
(
g_strcmp0
(
key
,
"Priority"
)
==
0
)
{
priv
->
priority
=
g_variant_get_int32
(
value
);
}
else
if
(
g_strcmp0
(
key
,
"ModificationTime"
)
==
0
)
{
...
...
@@ -1061,6 +1085,8 @@ fwupd_remote_to_variant (FwupdRemote *self)
}
g_variant_builder_add
(
&
builder
,
"{sv}"
,
"Enabled"
,
g_variant_new_boolean
(
priv
->
enabled
));
g_variant_builder_add
(
&
builder
,
"{sv}"
,
"ApprovalRequired"
,
g_variant_new_boolean
(
priv
->
approval_required
));
return
g_variant_new
(
"a{sv}"
,
&
builder
);
}
...
...
@@ -1075,6 +1101,9 @@ fwupd_remote_get_property (GObject *obj, guint prop_id,
case
PROP_ENABLED
:
g_value_set_boolean
(
value
,
priv
->
enabled
);
break
;
case
PROP_APPROVAL_REQUIRED
:
g_value_set_boolean
(
value
,
priv
->
approval_required
);
break
;
case
PROP_ID
:
g_value_set_string
(
value
,
priv
->
id
);
break
;
...
...
@@ -1095,6 +1124,9 @@ fwupd_remote_set_property (GObject *obj, guint prop_id,
case
PROP_ENABLED
:
priv
->
enabled
=
g_value_get_boolean
(
value
);
break
;
case
PROP_APPROVAL_REQUIRED
:
priv
->
approval_required
=
g_value_get_boolean
(
value
);
break
;
case
PROP_ID
:
fwupd_remote_set_id
(
self
,
g_value_get_string
(
value
));
break
;
...
...
@@ -1134,6 +1166,18 @@ fwupd_remote_class_init (FwupdRemoteClass *klass)
pspec
=
g_param_spec_boolean
(
"enabled"
,
NULL
,
NULL
,
FALSE
,
G_PARAM_READWRITE
|
G_PARAM_STATIC_NAME
);
g_object_class_install_property
(
object_class
,
PROP_ENABLED
,
pspec
);
/**
* FwupdRemote:approval-required:
*
* If firmware from the remote should be checked against the system
* list of approved firmware.
*
* Since: 1.2.6
*/
pspec
=
g_param_spec_boolean
(
"approval-required"
,
NULL
,
NULL
,
FALSE
,
G_PARAM_READWRITE
|
G_PARAM_STATIC_NAME
);
g_object_class_install_property
(
object_class
,
PROP_APPROVAL_REQUIRED
,
pspec
);
}
static
void
...
...
libfwupd/fwupd-remote.h
View file @
8dd4c1c4
...
...
@@ -61,6 +61,7 @@ const gchar *fwupd_remote_get_report_uri (FwupdRemote *self);
const
gchar
*
fwupd_remote_get_metadata_uri
(
FwupdRemote
*
self
);
const
gchar
*
fwupd_remote_get_metadata_uri_sig
(
FwupdRemote
*
self
);
gboolean
fwupd_remote_get_enabled
(
FwupdRemote
*
self
);
gboolean
fwupd_remote_get_approval_required
(
FwupdRemote
*
self
);
gint
fwupd_remote_get_priority
(
FwupdRemote
*
self
);
guint64
fwupd_remote_get_age
(
FwupdRemote
*
self
);
FwupdRemoteKind
fwupd_remote_get_kind
(
FwupdRemote
*
self
);
...
...
libfwupd/fwupd.map
View file @
8dd4c1c4
...
...
@@ -324,6 +324,8 @@ LIBFWUPD_1.2.5 {
LIBFWUPD_1.2.6 {
global:
fwupd_client_activate;
fwupd_client_get_approved_firmware;
fwupd_client_set_approved_firmware;
fwupd_device_to_json;
fwupd_release_add_flag;
fwupd_release_flag_from_string;
...
...
@@ -333,5 +335,6 @@ LIBFWUPD_1.2.6 {
fwupd_release_remove_flag;
fwupd_release_set_flags;
fwupd_release_to_json;
fwupd_remote_get_approval_required;
local: *;
} LIBFWUPD_1.2.5;
policy/org.freedesktop.fwupd.policy.in
View file @
8dd4c1c4
...
...
@@ -123,4 +123,15 @@
</defaults>
</action>
<action
id=
"org.freedesktop.fwupd.set-approved-firmware"
>
<description>
Sets the list of approved firmware
</description>
<!-- TRANSLATORS: this is the PolicyKit modal dialog -->
<message>
Authentication is required to set the list of approved firmware
</message>
<defaults>
<allow_any>
auth_admin
</allow_any>
<allow_inactive>
no
</allow_inactive>
<allow_active>
auth_admin_keep
</allow_active>
</defaults>
</action>
</policyconfig>
src/fu-config.c
View file @
8dd4c1c4
...
...
@@ -30,6 +30,7 @@ struct _FuConfig
GPtrArray
*
monitors
;
GPtrArray
*
blacklist_devices
;
GPtrArray
*
blacklist_plugins
;
GPtrArray
*
approved_firmware
;
guint64
archive_size_max
;
guint
idle_timeout
;
XbSilo
*
silo
;
...
...
@@ -357,6 +358,7 @@ fu_config_load_from_file (FuConfig *self, const gchar *config_file,
GFileMonitor
*
monitor
;
guint64
archive_size_max
;
guint
idle_timeout
;
g_auto
(
GStrv
)
approved_firmware
=
NULL
;
g_auto
(
GStrv
)
devices
=
NULL
;
g_auto
(
GStrv
)
plugins
=
NULL
;
g_autoptr
(
GFile
)
file
=
NULL
;
...
...
@@ -364,6 +366,7 @@ fu_config_load_from_file (FuConfig *self, const gchar *config_file,
/* ensure empty in case we're called from a monitor change */
g_ptr_array_set_size
(
self
->
blacklist_devices
,
0
);
g_ptr_array_set_size
(
self
->
blacklist_plugins
,
0
);
g_ptr_array_set_size
(
self
->
approved_firmware
,
0
);
g_ptr_array_set_size
(
self
->
monitors
,
0
);
g_ptr_array_set_size
(
self
->
remotes
,
0
);
...
...
@@ -407,6 +410,19 @@ fu_config_load_from_file (FuConfig *self, const gchar *config_file,
}
}
/* get approved firmware */
approved_firmware
=
g_key_file_get_string_list
(
self
->
keyfile
,
"fwupd"
,
"ApprovedFirmware"
,
NULL
,
/* length */
NULL
);
if
(
approved_firmware
!=
NULL
)
{
for
(
guint
i
=
0
;
approved_firmware
[
i
]
!=
NULL
;
i
++
)
{
g_ptr_array_add
(
self
->
approved_firmware
,
g_strdup
(
approved_firmware
[
i
]));
}
}
/* get maximum archive size, defaulting to something sane */
archive_size_max
=
g_key_file_get_uint64
(
self
->
keyfile
,
"fwupd"
,
...
...
@@ -553,6 +569,13 @@ fu_config_get_blacklist_plugins (FuConfig *self)
return
self
->
blacklist_plugins
;
}
GPtrArray
*
fu_config_get_approved_firmware
(
FuConfig
*
self
)
{
g_return_val_if_fail
(
FU_IS_CONFIG
(
self
),
NULL
);
return
self
->
approved_firmware
;
}
static
void
fu_config_class_init
(
FuConfigClass
*
klass
)
{
...
...
@@ -567,6 +590,7 @@ fu_config_init (FuConfig *self)
self
->
keyfile
=
g_key_file_new
();
self
->
blacklist_devices
=
g_ptr_array_new_with_free_func
(
g_free
);
self
->
blacklist_plugins
=
g_ptr_array_new_with_free_func
(
g_free
);
self
->
approved_firmware
=
g_ptr_array_new_with_free_func
(
g_free
);
self
->
remotes
=
g_ptr_array_new_with_free_func
((
GDestroyNotify
)
g_object_unref
);
self
->
monitors
=
g_ptr_array_new_with_free_func
((
GDestroyNotify
)
g_object_unref
);
}
...
...
@@ -583,6 +607,7 @@ fu_config_finalize (GObject *obj)
g_key_file_unref
(
self
->
keyfile
);
g_ptr_array_unref
(
self
->
blacklist_devices
);
g_ptr_array_unref
(
self
->
blacklist_plugins
);
g_ptr_array_unref
(
self
->
approved_firmware
);
g_ptr_array_unref
(
self
->
remotes
);
g_ptr_array_unref
(
self
->
monitors
);
...
...
src/fu-config.h
View file @
8dd4c1c4
...
...
@@ -23,6 +23,7 @@ guint64 fu_config_get_archive_size_max (FuConfig *self);
guint
fu_config_get_idle_timeout
(
FuConfig
*
self
);
GPtrArray
*
fu_config_get_blacklist_devices
(
FuConfig
*
self
);
GPtrArray
*
fu_config_get_blacklist_plugins
(
FuConfig
*
self
);
GPtrArray
*
fu_config_get_approved_firmware
(
FuConfig
*
self
);
GPtrArray
*
fu_config_get_remotes
(
FuConfig
*
self
);
FwupdRemote
*
fu_config_get_remote_by_id
(
FuConfig
*
self
,
const
gchar
*
remote_id
);
...
...
src/fu-engine.c
View file @
8dd4c1c4
...
...
@@ -71,6 +71,7 @@ struct _FuEngine
FuQuirks
*
quirks
;
GHashTable
*
runtime_versions
;
GHashTable
*
compile_versions
;
GHashTable
*
approved_firmware
;
gboolean
loaded
;
};
...
...
@@ -2697,6 +2698,19 @@ fu_engine_sort_releases_cb (gconstpointer a, gconstpointer b)
fwupd_release_get_version
(
rel_a
));
}
static
gboolean
fu_engine_check_release_is_approved
(
FuEngine
*
self
,
FwupdRelease
*
rel
)
{
GPtrArray
*
csums
=
fwupd_release_get_checksums
(
rel
);
for
(
guint
i
=
0
;
i
<
csums
->
len
;
i
++
)
{
const
gchar
*
csum
=
g_ptr_array_index
(
csums
,
i
);
g_debug
(
"checking %s against approved list"
,
csum
);
if
(
g_hash_table_lookup
(
self
->
approved_firmware
,
csum
)
!=
NULL
)
return
TRUE
;
}
return
FALSE
;
}
static
gboolean
fu_engine_add_releases_for_device_component
(
FuEngine
*
self
,
FuDevice
*
device
,
...
...
@@ -2726,6 +2740,7 @@ fu_engine_add_releases_for_device_component (FuEngine *self,
}
for
(
guint
i
=
0
;
i
<
releases_tmp
->
len
;
i
++
)
{
XbNode
*
release
=
g_ptr_array_index
(
releases_tmp
,
i
);
const
gchar
*
remote_id
;
const
gchar
*
update_message
;
gint
vercmp
;
GPtrArray
*
checksums
;
...
...
@@ -2760,6 +2775,17 @@ fu_engine_add_releases_for_device_component (FuEngine *self,
fwupd_release_add_flag
(
rel
,
FWUPD_RELEASE_FLAG_BLOCKED_VERSION
);
}
/* check if remote is whitelisting firmware */
remote_id
=
fwupd_release_get_remote_id
(
rel
);
if
(
remote_id
!=
NULL
)
{
FwupdRemote
*
remote
=
fu_engine_get_remote_by_id
(
self
,
remote_id
,
NULL
);
if
(
remote
!=
NULL
&&
fwupd_remote_get_approval_required
(
remote
)
&&
!
fu_engine_check_release_is_approved
(
self
,
rel
))
{
fwupd_release_add_flag
(
rel
,
FWUPD_RELEASE_FLAG_BLOCKED_APPROVAL
);
}
}
/* add update message if exists but device doesn't already have one */
update_message
=
fwupd_release_get_update_message
(
rel
);
if
(
fwupd_device_get_update_message
(
FWUPD_DEVICE
(
device
))
==
NULL
&&
...
...
@@ -2995,6 +3021,24 @@ fu_engine_get_downgrades (FuEngine *self, const gchar *device_id, GError **error
return
g_steal_pointer
(
&
releases
);
}
GPtrArray
*
fu_engine_get_approved_firmware
(
FuEngine
*
self
)
{
GPtrArray
*
checksums
=
g_ptr_array_new_with_free_func
(
g_free
);
g_autoptr
(
GList
)
keys
=
g_hash_table_get_keys
(
self
->
approved_firmware
);
for
(
GList
*
l
=
keys
;
l
!=
NULL
;
l
=
l
->
next
)
{
const
gchar
*
csum
=
l
->
data
;
g_ptr_array_add
(
checksums
,
g_strdup
(
csum
));
}
return
checksums
;
}
void
fu_engine_add_approved_firmware
(
FuEngine
*
self
,
const
gchar
*
checksum
)
{
g_hash_table_add
(
self
->
approved_firmware
,
g_strdup
(
checksum
));
}
/**
* fu_engine_get_upgrades:
* @self: A #FuEngine
...
...
@@ -3060,6 +3104,17 @@ fu_engine_get_upgrades (FuEngine *self, const gchar *device_id, GError **error)
fu_device_get_version
(
device
));
continue
;
}
/* not approved */
if
(
fwupd_release_has_flag
(
rel_tmp
,
FWUPD_RELEASE_FLAG_BLOCKED_APPROVAL
))
{
g_string_append_printf
(
error_str
,
"%s=not-approved, "
,
fwupd_release_get_version
(
rel_tmp
));
g_debug
(
"ignoring %s as not approved as required by %s"
,
fwupd_release_get_version
(
rel_tmp
),
fwupd_release_get_remote_id
(
rel_tmp
));
continue
;
}
g_ptr_array_add
(
releases
,
g_object_ref
(
rel_tmp
));
}
if
(
error_str
->
len
>
2
)
...
...
@@ -4104,6 +4159,8 @@ fu_engine_udev_uevent_cb (GUdevClient *gudev_client,
gboolean
fu_engine_load
(
FuEngine
*
self
,
GError
**
error
)
{
g_autoptr
(
GPtrArray
)
checksums
=
NULL
;
g_return_val_if_fail
(
FU_IS_ENGINE
(
self
),
FALSE
);
g_return_val_if_fail
(
error
==
NULL
||
*
error
==
NULL
,
FALSE
);
...
...
@@ -4117,6 +4174,22 @@ fu_engine_load (FuEngine *self, GError **error)
return
FALSE
;
}
/* get hardcoded approved firmware */
checksums
=
fu_config_get_approved_firmware
(
self
->
config
);
for
(
guint
i
=
0
;
i
<
checksums
->
len
;
i
++
)
{
const
gchar
*
csum
=
g_ptr_array_index
(
checksums
,
i
);
fu_engine_add_approved_firmware
(
self
,
csum
);
}
/* get extra firmware saved to the database */
checksums
=
fu_history_get_approved_firmware
(
self
->
history
,
error
);
if
(
checksums
==
NULL
)
return
FALSE
;
for
(
guint
i
=
0
;
i
<
checksums
->
len
;
i
++
)
{
const
gchar
*
csum
=
g_ptr_array_index
(
checksums
,
i
);
fu_engine_add_approved_firmware
(
self
,
csum
);
}
/* set up idle exit */
if
((
self
->
app_flags
&
FU_APP_FLAGS_NO_IDLE_SOURCES
)
==
0
)
fu_idle_set_timeout
(
self
->
idle
,
fu_config_get_idle_timeout
(
self
->
config
));
...
...
@@ -4276,6 +4349,7 @@ fu_engine_init (FuEngine *self)
self
->
udev_subsystems
=
g_ptr_array_new_with_free_func
(
g_free
);
self
->
runtime_versions
=
g_hash_table_new_full
(
g_str_hash
,
g_str_equal
,
g_free
,
g_free
);
self
->
compile_versions
=
g_hash_table_new_full
(
g_str_hash
,
g_str_equal
,
g_free
,
g_free
);
self
->
approved_firmware
=
g_hash_table_new_full
(
g_str_hash
,
g_str_equal
,
g_free
,
NULL
);
g_signal_connect
(
self
->
idle
,
"notify::status"
,
G_CALLBACK
(
fu_engine_idle_status_notify_cb
),
self
);
...
...
@@ -4328,6 +4402,7 @@ fu_engine_finalize (GObject *obj)
g_ptr_array_unref
(
self
->
udev_subsystems
);
g_hash_table_unref
(
self
->
runtime_versions
);
g_hash_table_unref
(
self
->
compile_versions
);
g_hash_table_unref
(
self
->
approved_firmware
);
g_object_unref
(
self
->
plugin_list
);
G_OBJECT_CLASS
(
fu_engine_parent_class
)
->
finalize
(
obj
);
...
...
Prev
1
2
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment