This allows us to do two things:
* Attach after a failed update, so the user isn't left with 'dead' hardware
* Split the detach and attach actions into different plugins in the future
This also allows us to have a separate vfunc to get the new version number
after flashing the firmware, as this may be handled in a different plugin to
the detach phase.
Notably, bootloaders for this class of device export an incorrect DFU interface.
Additionally, allow setting the buffer size for the UPLOAD to a larger size
than the defined device transfer size, which allows us to return the full
packet from the larger XMEGA devices.
Ignoring the warning is not good enough when we're setting policy based on the
specific version. Use the new quirk functionality to do this easily, which
also allows us to remove one more thing in the quirk mega-bitfield.
In the latest version of the LVFS you can restrict the firmware to a specific
machine type, for instance a specific baseboard vendor. This is the same as
done in Microsoft Update using the CHID mechanism.
This commit adds support for the <hardware> requires type, although it needs to
be built against appstream-glib 0.7.4 to be supported and/or tested.
This allows us to remove the Jabra-specific quirk entry in the device bitfield,
and more importantly allows us to support some more Jabra devices in the future
without code changes.
This is slightly more verbose than desired as we also have to include the quirk
information when running the dfu-tool, which does not have an already set-up
FuQuirks object as it has no plugin.
When fwupd is installed in long-term support distros it's very hard to backport
new versions as new hardware is released.
There are several reasons why we can't just include the mapping and quirk
information in the AppStream metadata:
* The extra data is hugely specific to the installed fwupd plugin versions
* The device-id is per-device, and the mapping is usually per-plugin
* Often the information is needed before the FuDevice is created
* There are security implications in allowing plugins to handle new devices
The idea with quirks is that the end user can drop an additional (or replace
an existing) file in a .d director with a simple format and the hardware will
magically start working. This assumes no new quirks are required, as this would
obviously need code changes, but allows us to get most existing devices working
in an easy way without the user compiling anything.
This allows us to fix issues like https://github.com/hughsie/fwupd/issues/265
The data for these was just being generated internally based on the ID and the
basename of the original URI, and that's easy for the calling application to do
itself.
This allows a plugin to see if a GUID is supported in the AppStream metadata of
configured remotes. It allows plugins to skip devices that are not supported
and that do bad things when probed.
By removing the device from the hash table before we add it to the devices
array we could inadvertently drop the last object reference if the plugin is
not using the (optional) cache.
Just re-arrange things to fix https://github.com/hughsie/fwupd/issues/259
Specifically, fix the progressbar to:
* Print at 100% after an 'unknown' percentage task has completed
* Refresh the progressbar if being called without a main loop running
* Allow the progressbar to start with a h-offset without moving 'left'
* Don't cause high CPU load when calling fu_progressbar_update() ever few us
Also, add some unit tests to discover all the issues.
It only remained on FwupdResult because I couldn't make up my mind about whether
it was a property of the device, or the firmware release. It's more logically
the latter, as you could have a .cab file with multiple versions of the
firmware and only the first being signed.
UEFI updates don't need to be retried since a785a1c. If the call to Install()
failed with NOT_SUPPORTED we can just show the error rather than doing the
little dance and involving the offline pending database for no reason.
Fixes some of https://github.com/hughsie/fwupd/issues/255
For a few months the lvfs-testing remote has not included firmware already
present in the stable lvfs remote. This means if you enable the testing remote
then components in the stable remote are not available to fwupd.
Instead of a simplistic check on the component ID, add the missing releases
no matter the ordering of the remotes.
This was only ever added for gnome-software, and is too inflexible for anything
else. It turns out we don't even need it in GNOME, as we can construct a
suitable ID ourselves using the existing values.
It was also ambiguous whether the unique ID was in reference to the device
or release -- and for gnome-software we need both.
It only remained on FwupdResult because I couldn't make up my mind about whether
it was a property of the device, or the firmware release. It's more logically
the former, and that's how plugins are using it.
This allows us to show the devices in a GUI with a nice icon. Some of the icon
mappings are not perfect and I'll be asking the GNOME designers for some
additions to the icon specification.
Custom vendor icons can also be specified, and /usr/share/fwupd/icons would be
a good place to put them. If vendor icons are used they should show a physical
device with the branding, rather than just the vendor logo.
We can use the power of g_autoptr() to automatically close devices that have
gone out of scope. When everything is converted we can drop the GUsbContect
AUTO_OPEN_DEVICES flag which is making us look bad in powertop.
The Linux DMI class still does not provide the information we need, and parsing
the blob directly also allows the Dell and Redfish plugins to get the raw data.
Over the months the original meaning of ALLOW_OFFLINE and ALLOW_ONLINE have be
lost, and there is now a confusing mixture of uses in the source tree. With this
commit we make it clear the UPDATABLE flag is used to specify when the device is
updatable (e.g. from the desktop live session, or from the systemd offline
updates mode, or both) and the NEEDS_REBOOT flag lets us know when the update
is actually going to be done.
For instance, a UEFI UpdateCapsule can be *scheduled* from either the desktop
or from the update mode (but the latter would be a bit weird), but does require
a reboot. Some devices might only be updatable outside the live session, for
instance a hard drive update or a GPU update -- there's just too much going on
with a live session and we want to tightly control what's running during the
firmware flash.
This also means we don't have to "retry" the update when scheduling an update
that really can be scheduled whenever, but just requires a reboot to apply.
Handling this in one place prevents plugins setting different values for
non-string values like TRUE/false or with different ways to represent integers.
This could be used, for instance, to set a property on ThunderBolt controllers
inside Dell computers saying that they support forcing the power level during
coldplug. It could also be used to set the dock type for the synapticsmst hub.
Adding this level of complexity allows us to avoid the creep of HAVE_DELL and
HAVE_LENOVO into seemingly unrelated plugins, and also allows us to have
multiple vendor plugins providing the same end result with two different
vendor-specific mechanisms.
According to some best practices this is a good idea, but in this specific case
the certificate will have been installed by the admin or package manager and
so is less important.
This also switches around the test for the self signed key to now fail, as the
generated certificate is no longer loaded into the trust list. This is a more
useful test as it more accurately represents what the fwupd daemon is doing.
As a side-note the detached signature from the derivate cannot be generated
using `--no-p7-include-cert` as only the main LVFS-CA certificate is shipped
with fwupd.
This means we return an error when encountering a rollback attack. This can
currently be performed by providing the old metadata and old signature when
calling into UpdateMetadata.
We can use this as an alternative for GPG. No PKCS7 certificates are currently
installed by fwupd and it's expected that the LVFS will still only provide GPG
detached signatures.
If an OEM distributor wants to sign firmware with a PKCS7 and the corresponding
certificate is provided then the firmware will be marked as valid.
Only firmware shipping with a .p7b file will use the PKCS7 functionality,
similarly remote metadata validation will default to GPG unless Keyring=pkcs7
is specified in the config file.
In this mode, both the metadata and firmware is stored on the local filesystem
and distributed using a distribution system like OSTree.
Fixes https://github.com/hughsie/fwupd/issues/162
This avoids open()ing and close()ing multiple times on hotplug -- which in
itself isn't a huge problem as the requests are refcounted in libusb, but it
matters hugely when a plugin accidentally closes a device that was not opened.
As all the devices are going to be opened anyway (to read the vendor strings)
and the cost of keeping the device is open is tiny, just get libgusb to
auto-open *all* devices and keep them open for the duration.
Fixes: https://github.com/hughsie/fwupd/issues/155
When reading with g_dir_read_name() the returned files do not have to be sorted
in any particular order and could even change between invokation. This patch
makes debugging the interactions between plugins much easier.
The items that 0.6.13 requires are now guarded by a version test.
This should allow running fwupd master on more distros that haven't
yet picked up appstream-glib 0.6.13.
We used to do this dance to avoid reading the Option ROM on hardware by default
(some faulty hardware would crash...) but now we're doing the verify update in
the daemon there's no need to split this into two steps.
Fixes: https://github.com/hughsie/fwupd/issues/149
The idea here is that we move a lot of the 'meat' out of fu-main into the
engine. This also lets us simplify a lot of things and ensures the user
authentication is simple and easy to audit.
If something changes the cache behind our back (e.g. deleting or updating the
file) we need to reload the list of remotes so that the age is correctly shown.
Note: we have to transfer the mtime (not the age) when creating the GVariant,
as we want calls to fwupd_remote_get_age() to update the value without getting
the remote from the daemon each time.
Now we have multiple remotes that can be enabled or changed at runtime we need
to do several things better:
* Only load components from remotes that are enabled
* Only load a component if a higher priority remote has not already added it
Rather than just appending all recieved metadata into one big XML file, save
the original metadata .xml.gz files in /var/lib/fwupd/remotes.d and only load
them in the correct priority order if the remote is known and enabled.
Remove the old /var/cache/app-info/xmls/fwupd.xml file, also noting it wasn't
really a cache file at all but actually something quite important.
The list of verification hashes is certainly not a cache, it's important data
that needs to be kept for a long time somewhere important.
Move it from /var/cache/app-info/xmls to /var/lib/fwupd and delete the old file
as it may have now-incorrect contents.
When processing the file handles it seems g_variant_get() actually wants to
write the fd integer. This bug does not happen every time, and seems to vanish
every time under valgrind.
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1460429
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 provides a new "hwids" subcommand for fwupdmgr that shows the
hardware GUIDs on the local system. It also provides API that plugins can use
to self-disable when a specific HWID does not match.
The GUIDs used in this implementation match that of ComputerHardwareIds.exe
This allows us to 'tag' the components with the correct remote ID value, which
then means we can tell where the firmware information has come from when saving
a composite store. It also allows us use the correct username and password in
the future when downloading the firmware blob itself.
Keep the old D-Bus method around to preserve API for existing clients.
Add the concept of 'remotes' that can dropped into /etc and used as firmware
metadata sources. This may be desirable when firmware is only accessable with
a valid support contract or from behind a VPN.
Make systemd and ConsoleKit support an optional compile time flag
with both enabled by default. If both are used, the ifdef/elif will
ensure only the systemd calls are used so there's no conflict.
It appears the enormity of replacing a directory with a file is just too much
for package managers in 2017.
I guess we might ship other things in /usr/libexec/fwupd/ in the future.
If this is not done the origin from the last file that was read (which might be
from Fedora, for instance) will be used. This isn't hugely important but can
give misleading and confusing unique-id's in gnome-software.
Automake and autoconf are impossible to fully understand and Meson now provides
everything we need for a much smaller, faster, and more understandable build.
See http://mesonbuild.com/ for more information.
Packagers should still enable it so that tracking lost memory
in plugins is possible, but on some distros some archs don't
have valgrind available which would otherwise prevent fwupd
from running.
This is as problem currently for Debian unstable where some
archs valgrind fails to compile.
Poll each plugin, and only register the service when all the delayed coldplug
devices have been added to the device list. This prevents returning an error
when calling "fwupdmgr get-devices" for the very first time.
Resolves: https://github.com/hughsie/fwupd/issues/82
This allows a plugin to signal the daemon that something has happened and that
all plugins should wake up connected devices, re-add them all and then put the
devices back to powersave mode. Any duplicate devices will be ignored.
This functionality is required so that AppStream metadata can check the fwupd
version, the firmware version, bootloader version or a combination of all three.
This allows us to have new markup specified in the MetaInfo or AppStream XML:
<requires>
<id compare="ge" version="0.8.1">org.freedesktop.fwupd</id>
<firmware compare="ge" version="0.1.2"/>
</requires>
This means that only updates that match these versions will be shown.
failed to open plugin
/usr/lib/x86_64-linux-gnu/fwupd-plugins-2/libfu_plugin_dfu.so:
failed to open plugin:
/usr/lib/x86_64-linux-gnu/fwupd-plugins-2/libfu_plugin_dfu.so:
undefined symbol: dfu_device_upload
The user will not be notified about firmware security updates all the time they
are on battery power. It's better to handle this in the client prompting the
user to connect the AC power source.
This is a large commit that removes all the providers and turns them into
plugins. I think having both providers _and_ plugins was super confusing.
Plugins are loaded at runtime so you could in theory develop a new plugin
without putting it in the fwupd source tree, although there are no installed
headers or PC files as I'm not sure it's a good idea at this stage.
This commit moves all the per-provider docs, tests, notes, debug dumps and test
data to plugin-specific directories -- these also allows the plugin author to
"own" more of the source tree so we don't enforce fu- prefixes and the style
guide everywhere.
This allows us to run the same action on all the plugins in the future, so we
could have a prepare(FuPlugin, FuDevice) and cleanup(FuPlugin, FuDevice) run
on *all* plugins, so doing an update using one plugin would allow us to work
around hardware quirks in other plugins.
If I've broken your out-of-tree provider it's trivial to port to the new API
with sed and a fixed up build file. If you need help please let me know.
This means we don't have more that one thread just watching for the USB
hotplug events. To achieve this split up the coldplug into setup and coldplug
phases and run the enumerate just once in the daemon.
ifdef cannot be used to determine if a C symbol is defined, as it’s
evaluated by the preprocessor, before symbols are parsed. Instead, try
to detect whether polkit.h is suitably recent enough to define its own
auto-cleanup functions.
Signed-off-by: Richard Hughes <richard@hughsie.com>
Providers that have both online and offline update methods don't
do verification that the device actually supports that mode.
This caused problems for Dell TPM devices where if you called
$ fwupdmgr install tpm.cab
It would attempt to use the online stub added in 1d97c8b5.
This would of course fall over requiring you to call with
$ fwupdmgr install tpm.cab --allow-offline
This fix will guarantee that the current install fallback
logic takes into account both device and provider support
for online/offline.
This means we have a different cache-id for locally modified .cab files.
This allows us to update the text in the metadata without reloading the client.
This provider will provide support for items that can be flashed
as capsules but aren't present in the ESRT table.
The MST hub and TBT NVM are not yet updatable, but GUIDs are
created to represent them when they are.
Although it's convenient that you can just log in as root and add another
trusted key, it makes the selinux developers unhappy. Use a private keystore
in /var/lib/fwupd/gnupg to avoid the possibility of a somehow hacked fwupd
being able to export the root gpg secrets if any happened to exist.
If you've trusted keys other than the LVFS for metadata or firmware you'll need
to re-import them into this new location.
See b7f12bd377
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1303531
It appears that some expensive USB sound cards do not like the DFU interface
being claimed at the same time the kernel starts using a different endpoint.
I suspect this is a device bug or limitation in some reference implementation
somewhere, but seeing as we only need the interface when verifying or writing
new firmware the sensible thing to do is not claim it until required.
Fixes: https://github.com/hughsie/fwupd/issues/50
This allows us to return multiple results from one file, for instance where the
firmware.cab file contains multiple metainfo.xml files.
This allows us to show all the entries in the firmware file, rather than
searching for the installed device that matches and falling back to just the
first listed item.
Although other checks may also fail, the error shown when trying
to install a CAB that matches a GUID on the system that is locked
should be a message to unlock the device.
For example, matching on the 'USB\VID_0000&PID_0000&REV_0000' GUID rather than
the 'USB\VID_0000&PID_0000' GUID.
This is now possible as we can specify multiple GUIDs for a device.
Under some circumstances a provider may want to prevent a user from
performing a flash without additional user interaction.
Providers can opt into this behavior by checking for
FWUPD_INSTALL_FLAG_FORCE in the update routine.
It might not be technically correct if multiple ESRT entries
are supported on the system, but these don't currently exist
and this is an improvement over it being set to null and
showing messages like:
"(null) has firmware updates"
691e02d652 [fu_keyring_setup] added a signing
server and configured to not have interactive pin entry
[gpgme_set_pinentry_mode]
This signing server was reverted in 5c35abb1a5
but the non-interactive pin entry setting for gpgme remained.
This functionality was only added in gnupg 2.1. If not running on gnupg 2.1
gpgme will give silent errors when importing keys. The silent errors were
fixed in 0.7.0 in c5e8921dfd. Unfortunately
that makes an implicit dependency on gnupg 2.1 to use fwupd.
This commit will allow older gnupg versions (< 2.1) to continue to work without
negative implications for fwupd.
This allows us to do two things:
* Start up much faster, now typically under 150ms on fast machines
* Stop hard-locking machines with dodgy hardware or non-free kernel drivers
The last point in particular was causing gnome-software a bad reputation, as
fwupd was only auto-started the when gnome-software was launched, which read
the Option ROM which then hardlocked some machines.
Note: We still unconditionally read the Option ROM when verifying, although
this is a seldom used feature, and easier to correlate with hard lockups on
faulty hardware.
This will make it easier for other quirks to be added later without
needing to remember to poke through all the code to find everywhere
they were mentioned.
This allows vendors such as Dell to use encodings such as AA.BB.CC.DD rather
than the default of AA.BB.CCDD which is used by Intel and Microsoft.
Existing metainfo.xml files with version numbers prefixed with '0x' are
automatically converted to the new scheme.
Based on a patch Mario Limonciello, many thanks.
Allow devices to have a specific device ID, which also matches other equivalent
IDs from other providers
This allows the user to plug in one type of device, and not match a different
cached device that also matches the same provider.
This allows us to match up the AppStream data we've parsed in gnome-software and the firmware update we've got from fwupd. This means we can get access to some of the data that fwupd doesn't care about, for instance the how-to-upgrade screenshots.
The DFU specification specifies that only one of the DFU interfaces has to
export a functional descriptor; I assumed they all had to. Adding support
for this kind of device rapidly turned into a massive restructure and it was
all too complicated anyway.
Reorganise the code so that we can support these kinds of devices and clean up
the API so it's sane and easy to use. This also allows us to generate the
GObject introspection GIR and to also install libdfu as a shared library.
If you've got any comments about the API, please shout now as when 6.0 is
released it will become API and ABI stable.
Using our own special version for the input for the GUID calculations means
that the result is not 'googlable'.
This does have the result of changing the GUIDs stored in the 'verify' database
but given the string->GUID function in appstream-glib has also changed to
become standards compliant and that only a few people are using it I felt it
was worth the pain.
In most cases this is out of chance, but in some random cases the gzip
decompressor decides to reuse the input buffer as a decompression buffer,
which means we get junk data after the decompressed text.
To solve this, just truncate the data at the reported size, and then feed this
into the XML parser.
Fixes: https://github.com/hughsie/fwupd/issues/36
If we send junk to UpdateMetadata() the deamon did something like this:
* Clear existing entries from memory
* Try to load junk file into memory -> error
This left us with no entries in the in-memory store, which required the user to
either keep retrying the 'fwupdmgr update' until it worked or just forced them
to restart fwupd so it loaded the old valid store from the cache file.
Now, only clear the in-memory store and add the new firmware entries when
we know the file has been parsed correctly.
Fixes: https://github.com/hughsie/fwupd/issues/35
This allows a vendor to upload a single file that targets different versions of
the same hardware. If this feature is used, the metainfo.xml files *must* have
something like <checksum target="content" filename="firmware2.rom"/> inside the
latest <release> tag.
readlink() man page says that applications must not rely on it returning
null-terminated links. This commit switches it to use g_file_read_link()
instead that has much nicer API and shields us from readlink() oddities.
On devices with a lot of PCI devices this can take a couple of seconds per
device, and if this feature is not desired then disabling it saves system
resources.
The firmware may be more generic, and it also allows us to match the GUID then
doing 'verify' on a device with a different device PID than the firmware
actually declares.
This allows the text clients like fwupdmgr to convert to UTF-8 text, and
graphical clients can use the markdown target to ensure the links are made
clickable and paragraphs are presented in the right way.
For large files, EVENT_CREATED gets emitted when the first chunk hits the disk,
not when the file has finished copying. To fix, just wait for the file monitor
to hint that all the changes in the operation have happened and then process
the firmware files.
This downloads the latest version of the firmware and applies it to any
matching hardware. e.g.
$ fwupdmgr update
Downloading 1.2.3 for ColorHug...
Updating 1.2.3 on ColorHug...
* Loading firmware
* Decompressing firmware
* Restarting device
* Writing firmware to device
* Verifying firmware from device
* Restarting device
Done!
The way this works is we try with the user settings, and if this fails with
NotSupported and the offline flag is unset then we retry the action with a
warning and the flag manually set.
I chose to do this in the client rather than the daemon as I don't want to
encode too many magic rules when we don't know the kind of devices that will
appear in the future.
Fixes the other half of https://github.com/hughsie/fwupd/pull/23
It seems a little odd to call it 'Update' when it's being used for downgrading
and reinstalling as well.
As we're making things simpler, just use a single 'install' action in fwupdmgr
rather than 'install', 'update-online', 'update-offline'. We can use the flags
and fallbacks to do the right thing in all cases, and make the typical case
(installing a local file to any matching hardware) simple.
Fixes half of https://github.com/hughsie/fwupd/pull/23
This only returns the latest version, if you actually need to know details
about all versions including downgrades then you still need to load the
AppStream metadata and match devices manually.
fwupdate will handle creating the appropriate BootNext entry.
No other changes are needed from fwupd.
Signed-off-by: Richard Hughes <richard@hughsie.com>