diff --git a/README.md b/README.md index 41d6ba571..bd66e82f0 100644 --- a/README.md +++ b/README.md @@ -1,94 +1,7 @@ fwupd ===== -fwupd is a simple daemon to allow session software to update device firmware on -your local machine. It's designed for desktops, but this project is probably -quite interesting for phones, tablets and server farms, so I'd be really happy -if this gets used on other non-desktop hardware. - -You can either use a GUI software manager like GNOME Software to view and apply -updates, the command-line tool or the system D-Bus interface directly. - -Introduction ------------- - -Updating firmware easily is actually split into two parts: - - * Providing metadata about what vendor updates are available (AppStream) - * A mechanism to actually apply the file onto specific hardware (this project) - -What do we actually need to apply firmware easily? A raw binary firmware file -isn't so useful, and so Microsoft have decided we should all package it up in a -.cab file (a bit like a .zip file) along with a .inf file that describes the -update in more detail. The .inf file gives us the hardware ID of what the -firmware is referring to, as well as the vendor and a short update description. - -I'm asking friendly upstream vendors to also include a MetaInfo file alongside -the .inf file in the firmware .cab file. This means we can have fully localized -update descriptions, along with all the usual things you'd expect from an -update, e.g. the upstream vendor, the licensing information, etc. - -A lot of people don't have UEFI hardware that is capable of applying capsule -firmware updates, so I've also added a ColorHug provider, which predictably also -lets you update the firmware on your ColorHug devices. - -I'm also happy to accept patches for other hardware that supports updates, -although the internal API isn't 100% stable yet. The provider concept allows -vendors to do pretty much anything to get the list of attached hardware, as long -as a unique hardware component is in some way mapped to a GUID value. -Ideally the tools would be open source, or better still not needing any external -tools at all. Reading a VID/PID and then writing firmware to a chip usually -isn't rocket science. - -What is standardised is the metadata, using AppStream 0.9 as the interchange -format. A lot of tools already talk AppStream and so this makes working with -other desktop and server tools very easy. Actually generating the AppStream -metadata can either be done using using `appstream-builder` or the Linux -Vendor Firmware Service. - -Security --------- - -By default, any users are able to install firmware to removable hardware. -The logic here is that if the hardware can be removed, it can easily be moved to -a device that the user already has root access on, and asking for authentication -would just be security theatre. - -For non-removable devices, e.g. UEFI firmware, admin users are able to update -firmware without the root password. By default, we already let admin user and -root update glibc and the kernel without additional authentication, and these -would be a much easier target to backdoor. The firmware updates themselves -have a checksum, and the metadata describing this checksum is provided by the -distribution either as GPG-signed repository metadata, or installed from a -package, which is expected to also be signed. It is important that clients that -are downloading firmware for fwupd check the checksum before asking fwupd to -update a specific device. - -User Interaction ----------------- - -No user interaction should be required when actually applying updates. Making -it prohibited means we can do the upgrade with a fancy graphical splash screen, -without having to worry about locales and input methods. Updating firmware -should be no more dangerous than installing a new kernel or glibc package. - -Offline Updates Lifecycle -------------------------- - -Offline updates are done using a special boot target which means that the usual -graphical environment is not started. Once the firmware update has completed the -system will reboot. - -Devices go through the following lifecycles: - - * created -> `SCHEDULED` -> `SUCCESS` -> deleted - * created -> `SCHEDULED` -> `FAILED` -> deleted - -Any user-visible output is available using the `GetResults()` D-Bus method, and -the database entry is only deleted once the `ClearResults()` method is called. - -The results are obtained and cleared either using a provider-supplied method -or using a small SQLite database located at `/var/lib/fwupd/pending.db` +This project aims to make updating firmware on Linux automatic, safe and reliable. ColorHug Support ---------------- @@ -98,195 +11,14 @@ provides. Compile it from source https://github.com/hughsie/colord or grab the RPMs here http://people.freedesktop.org/~hughsient/fedora/ If you don't want or need this functionality you can use the -`--disable-colorhug` option. +--disable-colorhug option. UEFI Support ------------ -If you're wondering where to get `fwupdate` from, either compile it form source -(you might also need a newer `efivar`) from https://github.com/rhinstaller/fwupdate +If you're wondering where to get fwupdate from, either compile it form source +(you might also need a newer efivar) from https://github.com/rhinstaller/fwupdate or grab the RPMs here https://pjones.fedorapeople.org/fwupdate/ -If you don't want or need this functionality you can use the `--disable-uefi` +If you don't want or need this functionality you can use the --disable-uefi option. - -Vendor Firmware Updates -======================= - -This document explains what steps a vendor needs to take so that firmware -updates are downloaded and applied to user hardware automatically. - -Different hardware update methods can be supported, but would require a new -plugin and there would need to be interfaces available to be able to write -(or at least trigger) the firmware from userspace as the root user. - -What do I have to do? ---------------------- - -As per the [Microsoft guidelines](https://msdn.microsoft.com/en-us/library/windows/hardware/dn917810%28v=vs.85%29.aspx), -package up your firmware into a `.cab` file, with these files inside: - -* The actual `.cap` file your engineers have created -* The `.inf` file describing the .cap file, - described [here](https://msdn.microsoft.com/en-us/library/windows/hardware/ff547402%28v=vs.85%29.aspx) -* The optional `.asc` file which is a detached GPG signature of the firmware file. -* The optional `.metainfo.xml` file with a long description and extra metadata, - described [here](http://www.freedesktop.org/software/appstream/docs/sect-Quickstart-Addons.html) - -You can create a `.cab` file using `makecab.exe` on Windows and `gcab --create` -on Linux. - -It is recommended you name the `.cab` file with the hardware name and the version -number, e.g. `colorhug-als-1.2.3.cab`. It's mandatory that the files inside the -`.cab` file have the same basename, for example this is would be valid: - - colorhug2-1.2.3.cab - |- firmware.inf - |- firmware.bin - |- firmware.bin.asc - \- firmware.metainfo.xml - -An example `.inf` file might look like this: - -```ini -[Version] -Class=Firmware -ClassGuid={f2e7dd72-6468-4e36-b6f1-6488f42c1b52} -DriverVer=03/03/2015,3.0.2 - -[Firmware_CopyFiles] -firmware.bin - -[Firmware_AddReg] -HKR,,FirmwareId,,{84f40464-9272-4ef7-9399-cd95f12da696} -HKR,,FirmwareVersion,%REG_DWORD%,0x0000000 -HKR,,FirmwareFilename,,firmware.bin - -``` - -An example `.metainfo.xml` file might look like this: - -```xml - - - - 84f40464-9272-4ef7-9399-cd95f12da696 - ColorHugALS Firmware - Firmware for the ColorHugALS Ambient Light Sensor - -

- Updating the firmware on your ColorHugALS device improves performance and - adds new features. -

-
- http://www.hughski.com/ - CC0-1.0 - GPL-2.0+ - Hughski Limited - - - http://www.hughski.com/downloads/colorhug-als/firmware/colorhug-als-3.0.2.cab - -

This stable release fixes the following bugs:

-
    -
  • Fix the return code from GetHardwareVersion
  • -
  • Scale the output of TakeReadingRaw by the datasheet values
  • -
-
-
-
-
-``` - -If the firmware is not redistributable you have to indicate it in in the -`.metainfo.xml` file with `proprietary`. -If the firmware location is not stable you can use the Linux Vendor Firmware -Service to mirror your file. - -Questions ---------- - -### Where will this data be used? - -We will scrape the `.inf` and `.metainfo.xml` files when building and composing -metadata for distributions; end users will still be downloading the `.cab` -files directly from the vendor site. - -### How do I know if my appdata XML is correct? - -The best way to validate the data is by using the `appstream-util validate` -tool available from the [appstream-glib](https://github.com/hughsie/appstream-glib) project. - -### Where do I submit the `.cab` files? - -The easiest way to upload new firmware is to use the [Linux Vendor Firmware -Service](https://beta-lvfs.rhcloud.com/) which will validate your firmware, -generate the metadata and mirror them automatically. - -Vendors can also produce and upload the AppStream metadata themselves using the -`appstream-builder` command line tool, for example: - -```sh -appstream-builder \ - --basename=colorhug-firmware \ - --origin=hughski \ - ColorHug*/firmware-releases/*.*.*/*.cab -``` - -...will produce this file: http://www.hughski.com/downloads/colorhug-firmware.xml - -Please [email us](mailto://richard@hughsie.com) if you want more help using -either generation method. - -### How does fwupd know the device firmware version? - -For generic USB devices you can use a firmware vendor extensions that are used -by a few OpenHardware projects. This means the fwupd daemon can obtain the -GUID and firmware version without claiming the interface on the device and -preventing other software from using it. -For closed-source devices a product-specific provider can also be used, although -this isn't covered here. - -To implement the firmware version extension just create an interface descriptor -with class code `0xff`, subclass code `0x46` and protocol `0x57` pointing to a -string descriptor with the firmware version. -An example commit to the ColorHug project can be found [here](https://github.com/hughski/colorhug2-firmware/commit/5e1bb64ad722a9d2d95927e305fd869b4a3a46a8). - -Furthermore, using the firmware GUID extension allows fwupd to detect firmware -updates for devices it does not know how to update. -These types of devices will however show up in the command line and GUI tools, -so the user is at least aware that updates are available. - -To implement this, add an interface descriptor with class code `0xff`, subclass -code `0x47` and protocol `0x55` pointing to a string descriptor with the GUID. -If the GUID matches the '' obtained from the AppStream metadata then the -device will be shown. -An example commit to the ColorHug project can be found [here](https://github.com/hughski/colorhug2-firmware/commit/f974638ac17b0e50f21987e2f1d982374cabe22c). - -Adding Trusted Keys -=================== - -Introduction ------------- - -Installing a public key to `/etc/pki/fwupd` allows firmware signed with a -matching private key to be recognized as trusted, which may require less -authentication to install than for untrusted files. By default trusted firmware -can be **upgraded** (but not downgraded) without the user or administrator -password. - -Only very few keys will be installed *by default*. These are the keys of -vendors who have a proven security track record and a thorough understanding of -public-private key security. - -In particular, private keys should **only** be kept on Hardware Security -Mechanisms, and used on machines (or virtual machine) that have limited network -access, or networking completely disabled. The machine and any backups also -need to be kept physically secure. - -Adding a New Key ----------------- - -If you think your key should be added by default and trusted by all users, -please open a pull request with details about your company including items such -as a day time phone number and any relevant security policies already in place. diff --git a/docs/architecture-plan.svg b/docs/architecture-plan.svg new file mode 100644 index 000000000..b49aad1e2 --- /dev/null +++ b/docs/architecture-plan.svg @@ -0,0 +1,790 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + fwupd + + ESRT + + VendorProvders + + Udev + + systemd + + pending.db + + + + + + + session + system + + + + fwupdmgr + + downloadcache + + + + Internet + + Gudev + rules + sqlite + $home + gnome-software + + UpdateMetadata() + GetDevices() + + sysfs + + metadata + firmware + + + AppStream XML + + diff --git a/docs/website/.htaccess b/docs/website/.htaccess new file mode 100644 index 000000000..eeb1ec150 --- /dev/null +++ b/docs/website/.htaccess @@ -0,0 +1,7 @@ +RewriteEngine on +RewriteCond %{HTTP:X-Forwarded-Proto} !https +RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R,L] + +# Don't compress gzipped files +SetEnv no-gzip 1 +SetEnv dont-vary 1 diff --git a/docs/website/.openshift/action_hooks/build b/docs/website/.openshift/action_hooks/build new file mode 100755 index 000000000..74dc4dc93 --- /dev/null +++ b/docs/website/.openshift/action_hooks/build @@ -0,0 +1,3 @@ +#!/bin/bash +ln -s ${OPENSHIFT_DATA_DIR}uploads ${OPENSHIFT_REPO_DIR}uploads +ln -s ${OPENSHIFT_DATA_DIR}downloads ${OPENSHIFT_REPO_DIR}downloads diff --git a/docs/website/README.md b/docs/website/README.md new file mode 100644 index 000000000..44a71db4c --- /dev/null +++ b/docs/website/README.md @@ -0,0 +1,40 @@ +Linux Vendor Firmware Service +============================= + +This is the website for the Linux Vendor Firmware Service + +IMPORTANT: This needs to be hosted over SSL, i.e. with a `https://` prefix. + +Using +----- + +Using `index.html` you can upload files to the upload directory. +You can also dump all the user-visible databases using `dump.php`. + +Installation +------------ + +The default upload path of /var/www/html/lvfs/uploads needs to be writable by +the apache user. You might have to tweak your SELinux policy too. + +We also need a SQL server somewhere, with the following tables set up: + + CREATE TABLE `firmware` ( + `vendor_key` varchar(36) DEFAULT NULL, + `update_contact` varchar(255) DEFAULT NULL, + `addr` varchar(16) DEFAULT NULL, + `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `filename` varchar(255) DEFAULT NULL, + `hash` varchar(40) DEFAULT NULL + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + CREATE TABLE `users` ( + `guid` varchar(36) NOT NULL DEFAULT '', + `name` varchar(128) DEFAULT NULL + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +Just modify the `db.php` file with your login credentials. You can insert +authorised vendors with: + +INSERT INTO `users` (`guid`, `name`) VALUES +('06350563-5b58-4c1d-8959-d9a216188604', 'Vendor1'), +('579caa6c-29d3-4efa-8f4d-bd2ff46af798', 'Vendor2'); diff --git a/docs/website/banner.svg b/docs/website/banner.svg new file mode 100644 index 000000000..913757262 --- /dev/null +++ b/docs/website/banner.svg @@ -0,0 +1,8671 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + Linux VendorFirmware Service + + + + + + diff --git a/docs/website/db.php b/docs/website/db.php new file mode 100644 index 000000000..0f8dcb74d --- /dev/null +++ b/docs/website/db.php @@ -0,0 +1,35 @@ + + * + * Licensed under the GNU General Public License Version 2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +function lvfs_connect_db() { + return new mysqli($_ENV["OPENSHIFT_MYSQL_DB_HOST"], + $_ENV["OPENSHIFT_MYSQL_DB_USERNAME"], + $_ENV["OPENSHIFT_MYSQL_DB_PASSWORD"], + "beta", + (int) $_ENV["OPENSHIFT_MYSQL_DB_PORT"]); +} + +function lvfs_disconnect_db($db) { + $db->close(); +} + +?> diff --git a/docs/website/developers.html b/docs/website/developers.html new file mode 100644 index 000000000..558c600d6 --- /dev/null +++ b/docs/website/developers.html @@ -0,0 +1,171 @@ + + + + + +fwupd: Firmware Update Daemon + + + + + + + + +

fwupd: Firmware
Update Daemon

+ +

Introduction

+

+A lot of people don't have UEFI hardware that is capable of applying capsule +firmware updates, so I've also added a ColorHug provider, which predictably also +lets you update the firmware on your ColorHug devices. +

+

+I'm also happy to accept patches for other hardware that supports updates. +The provider concept allows vendors to do pretty much anything to get the list +of attached hardware, as long as a unique hardware component is in some way +mapped to a GUID value. +Ideally the tools would be open source, or better still not needing any external +tools at all. +Reading a VID/PID and then writing firmware to a chip usually isn't rocket science. +

+

+AppStream 0.9 +is used as the interchange format for update descriptions. +A lot of tools already talk AppStream and so this makes working with +other desktop and server tools very easy. Actually generating the AppStream +metadata can either be done using using appstream-builder or the +Linux Vendor Firmware Service. +

+ +

Architecture

+

+fwupd is implemented as a D-Bus activated service that is autostarted when +required. +

+architecture-plan +

+The 'client' which is typically gnome-software or fwupd +does all the query, download and schedule steps. +This means that the daemon has no network access and only acts as the mechanism +for clients. +

+ +

Getting the code

+

+The latest code is always available at GitHub +and this is also the place to file bugs or feature requests. +You can trivially get the code by doing: +

+
+$ git clone https://github.com/hughsie/fwupd.git
+
+

+You can also install all the required dependancies using: +

+
+$ sudo dnf install docbook-utils gettext intltool libgudev1-devel \
+                   colord-devel polkit-devel libgcab1-devel \
+                   sqlite-devel gpgme-devel fwupdate-devel
+
+ +

How does fwupd know the device firmware version?

+

+There are currently several ways to detect the firmware version: +

+
    +
  • USB firmware version extensions (see below)
  • +
  • The bcdVersion for some USB devices
  • +
  • Parsing the option ROM and searching for serial numbers
  • +
  • Using libfwupdate to get the ESRT table data
  • +
  • Using a custom provider (not covered here)
  • +
+ +

USB Firmware Version Extensions

+

+For generic USB devices you can use a firmware vendor extensions that are used +by several OpenHardware projects. +This means the fwupd daemon can obtain the GUID and firmware version without +claiming the interface on the device and preventing other software from using it. +

+

+To implement the firmware version extension just create an interface descriptor +with class code 0xff, subclass code 0x46 and +protocol 0x57 pointing to a string descriptor with the firmware version. +An example commit to the ColorHug project can be found +here. +

+

+Furthermore, using the firmware GUID extension allows fwupd to detect firmware +updates for devices it does not know how to update. +These types of devices will however show up in the command line and GUI tools, +so the user is at least aware that updates are available. +

+

+To implement this, add an interface descriptor with class code 0xff, subclass +code 0x47 and protocol 0x55 pointing to a string descriptor with the GUID. +If the GUID matches the <id> obtained from the AppStream metadata then the +device will be shown. +An example commit to the ColorHug project can be found +here. +

+ +

Offline Updates Lifecycle

+

+Offline updates are done using a special boot target which means that the usual +graphical environment is not started. Once the firmware update has completed the +system will reboot. +

+

+Devices go through the following lifecycles: +

+
    +
  1. created → SCHEDULEDSUCCESS → deleted
  2. +
  3. created → SCHEDULEDFAILED → deleted
  4. +
+

+Any user-visible output is available using the GetResults() D-Bus method, and +the database entry is only deleted once the ClearResults() method is called. +

+

+The results are obtained and cleared either using a provider-supplied method +or using a small SQLite database located at /var/lib/fwupd/pending.db +

+ +

Adding Trusted Keys

+

+Installing a public key to /etc/pki/fwupd allows firmware signed with a +matching private key to be recognized as trusted, which may require less +authentication to install than for untrusted files. +By default trusted firmware can be upgraded (but not downgraded) +without the user or administrator +password. +

+

+Only very few keys will be installed by default. These are the keys of +vendors who have a proven security track record and a thorough understanding of +public-private key security. +

+

+In particular, private keys should only be kept on Hardware Security +Mechanisms, and used on machines (or virtual machine) that have limited network +access, or networking completely disabled. +The machine and any backups also need to be kept physically secure. +

+

Adding a New Key

+

+If you think your key should be added by default and trusted by all users, +please open a pull request with details about your company including items such +as a daytime phone number and any relevant security policies already in place. +

+ +

Go back to the main page

+ + + + + + diff --git a/docs/website/dump.php b/docs/website/dump.php new file mode 100644 index 000000000..aa35b23e1 --- /dev/null +++ b/docs/website/dump.php @@ -0,0 +1,55 @@ + + + + +Linux Vendor Firmware Service + + + + + + + +

History

+ + + + + + + + +query('SELECT name FROM users WHERE guid = "' . $id . '";'); + return $res->fetch_assoc()['name']; +} + +$db = lvfs_connect_db(); +$res = $db->query('SELECT * FROM firmware'); +while ($row = $res->fetch_assoc()) { + $vendor_name = lvfs_get_vendor_name($db, $row["vendor_key"]); + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; +} + +lvfs_disconnect_db($db); + +?> +
VendorFilenameHash
' . $vendor_name . '' . $row["filename"] . '' . $row["hash"] . '
+ + + + + + + diff --git a/docs/website/favicon.ico b/docs/website/favicon.ico new file mode 100644 index 000000000..ef1639c3a Binary files /dev/null and b/docs/website/favicon.ico differ diff --git a/docs/website/img/architecture-plan.png b/docs/website/img/architecture-plan.png new file mode 100644 index 000000000..f8ccf9097 Binary files /dev/null and b/docs/website/img/architecture-plan.png differ diff --git a/docs/website/img/dbus.png b/docs/website/img/dbus.png new file mode 100644 index 000000000..aef9ed2ed Binary files /dev/null and b/docs/website/img/dbus.png differ diff --git a/docs/website/img/gnome-software1-thumb.png b/docs/website/img/gnome-software1-thumb.png new file mode 100644 index 000000000..d26c3317c Binary files /dev/null and b/docs/website/img/gnome-software1-thumb.png differ diff --git a/docs/website/img/gnome-software1.png b/docs/website/img/gnome-software1.png new file mode 100644 index 000000000..df1d27263 Binary files /dev/null and b/docs/website/img/gnome-software1.png differ diff --git a/docs/website/img/gnome-software2-thumb.png b/docs/website/img/gnome-software2-thumb.png new file mode 100644 index 000000000..a28e2932c Binary files /dev/null and b/docs/website/img/gnome-software2-thumb.png differ diff --git a/docs/website/img/gnome-software2.png b/docs/website/img/gnome-software2.png new file mode 100644 index 000000000..b84d08a9a Binary files /dev/null and b/docs/website/img/gnome-software2.png differ diff --git a/docs/website/img/nav-devs.svg b/docs/website/img/nav-devs.svg new file mode 100644 index 000000000..ed6044c41 --- /dev/null +++ b/docs/website/img/nav-devs.svg @@ -0,0 +1,100 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/docs/website/img/nav-hw.svg b/docs/website/img/nav-hw.svg new file mode 100644 index 000000000..43dcdab6d --- /dev/null +++ b/docs/website/img/nav-hw.svg @@ -0,0 +1,125 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/website/img/nav-users.svg b/docs/website/img/nav-users.svg new file mode 100644 index 000000000..88abc8b76 --- /dev/null +++ b/docs/website/img/nav-users.svg @@ -0,0 +1,102 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/docs/website/index.html b/docs/website/index.html new file mode 100644 index 000000000..36265cce7 --- /dev/null +++ b/docs/website/index.html @@ -0,0 +1,65 @@ + + + + + +fwupd: Updating Firmware in Linux + + + + + + + + +

fwupd: Updating
Firmware in Linux

+ +

Introduction

+

+This project aims to make updating firmware on Linux automatic, safe and reliable. +

+ + + +

About

+ +

+To update a BIOS or network card firmware in Linux traditionally meant rebooting into Microsoft Windows, or +preparing a MSDOS floppy disk (!) and hoping that everything would +work after the update. +

+ +

+Now that we have UEFI as a boot mechanism it's much more important to +update firmware on devices, as these updates can fix serious security bugs. +Periodically searching a vendor website for updates is a manual and +error-prone task and not something we should ask users to do. +

+ +

+Providing a firmware update service actually requires two things: +

    +
  1. Vendors providing information about what updates are available for specific hardware
  2. +
  3. A mechanism to actually deploy the firmware onto the hardware itself
  4. +
+ +

+Traditionally firmware is packaged up in a cab file which includes +an inf file that describes the update in more detail. +We can also add extra metadata so we can have fully localized update descriptions, +along with all the usual things you'd expect from an update, for example, +security classification and licensing information. +

+ + + + + + diff --git a/docs/website/result.php b/docs/website/result.php new file mode 100644 index 000000000..02523960e --- /dev/null +++ b/docs/website/result.php @@ -0,0 +1,60 @@ + + + + +Linux Vendor Firmware Service + + + + + + + +Result: Success'; +else + echo '

Result: Failed

'; +?> + + + + + + + + +'; +} + +lvfs_result('authkey', 'Auth Key', 'Did not match any registered vendors'); +lvfs_result('sizecheck', 'Size Check', 'File was too small or large'); +lvfs_result('filetype', 'File Type', 'Not a valid cab file'); +lvfs_result('metadata', 'Metadata', 'The firmware file had no valid metadata'); +lvfs_result('exists', 'Version Check', 'The firmware file already exists'); + +?> + +
TestResult
' . $title . ''; + if ($_GET[$get_id] == 'False') + echo '☐ ' . $error_msg; + else + echo '☑ Passed'; + echo '
+ +

+ Go back to the submission page. +

+ + + + + + + diff --git a/docs/website/style.css b/docs/website/style.css new file mode 100644 index 000000000..5012d1fc4 --- /dev/null +++ b/docs/website/style.css @@ -0,0 +1,172 @@ +body { + background: #fefeff; + color: #000000; + font-family: "Open Sans", Sans-Serif; + font-weight: 400; + max-width: 50em; + margin: 1em auto; + padding: 0 2em; + } + +h1, h2, h3 { + color: #000000; + font-family: "Open Sans", Sans-Serif; + font-weight: 300; + } + +h1.banner { + display: block; + width: 290px; + padding: 230px 0 0 240px; + margin: 0 auto; + height: 150px; + background: url('banner.svg') no-repeat 0 0; +} + +table.noteinformation { + background: #f5f5ff; + border: 1px outset #000000; + margin-left: 5px; + margin-right: 5px; + padding: 3px; + width: 80%; + } + +table.upload { + width: 60%; + margin: 2em auto; +} + +table.history { + width: 100%; +} + .history th { + font-weight: 300; + font-size: 120%; + white-space: nowrap; + padding-right: 1em; + } + .history td { + padding: .5em .5em .5em 0; + font-size: 70%; + white-space: nowrap; + } + +p.title { + color: #000000; + text-align: center; + font-weight: bolder; + font-size: 20px; + } + +p.footer { + color: #000000; + text-align: center; + margin-top: 3em; + } + +p.caption { + color: #000000; + text-align: center; + font-style: italic; + } + +th { + color: #000000; + text-align: left; + } + +a.indextitle { + color: #000147; + font-weight: bolder; + font-size: 20px; + } + +p.indextitle { + text-align: left; + font-size: 250%; + } + +table.title { + color: #000000; + background-color: #f5f5ff; + border: 1px outset #000000; + } + +img { + border: 0; + } + +img.caption { + border: 0; + text-align: center; + } + +code { + color: #000000; + font: 1.1em 'Courier New', Courier, Fixed; + margin-left: .3em; + margin-right: .3em; + } + +pre { + color: #000000; + background: #eeeeee; + border: 1px outset #000000; + padding: 3px; +} + +a:hover { + color: #147; + text-decoration: none; + } + +a { + color: #147; + text-decoration: none; + } + +td.title { + color: #000000; + font-weight: bold; + } + +nav.buttons { + width: 100%; + display: block; +} + nav.buttons a { + outline: none; + display: inline-block; + padding: 140px 4px 10px 4px; + width: 30%; + background-repeat: no-repeat; + background-position: center 30%; + background-size: 96px; + margin: 0; + text-align: center; + transition: background-size 200ms ease; + } + + nav.buttons a:hover { + background-size: 115px; + } + + #users { background-image: url('img/nav-users.svg'); } + #devs { background-image: url('img/nav-devs.svg'); } + #hw { background-image: url('img/nav-hw.svg'); } + +input.submit { + display: block; + margin: 0 auto; + outline: none; + margin-top: 1em; + border-width: 1px; + border-radius: 5px; + border-image: linear-gradient(to bottom, #1e5894, #033266); + padding: 10px; + font-weight: bold; + background-image: linear-gradient(to bottom, #3e78b4, #235296); + color: white; + width: 60%; +} diff --git a/docs/website/upload.php b/docs/website/upload.php new file mode 100644 index 000000000..290313cfb --- /dev/null +++ b/docs/website/upload.php @@ -0,0 +1,125 @@ + + * + * Licensed under the GNU General Public License Version 2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +include 'db.php'; + +$uploaddir = $_ENV["OPENSHIFT_DATA_DIR"] . '/uploads/'; + +function lvfs_check_auth($db, $auth_token) { + if ($auth_token == '') + return False; + if (!($stmt = $db->prepare('SELECT * FROM users WHERE guid = ?;'))) + die("failed to prepare: " . $db->error); + $stmt->bind_param("s", $auth_token); + if (!$stmt->execute()) + die("failed to execute: " . $db->error); + $res = $stmt->get_result(); + $stmt->close(); + if ($res->num_rows > 0) + return True; + return False; +} + +function lvfs_upload_firmware($db, $auth_token, $uploaddir, $file) { + + $success = False; + $uri = 'result.php?'; + + # check auth key + if (!lvfs_check_auth($db, $auth_token)) { + $success = False; + $uri = $uri . 'authkey=False&'; + } + + # check size + $size = $file['size']; + if ($size > 102400 || $size < 1280) { + $success = False; + $uri = $uri . 'sizecheck=False&'; + } + + # check the file is really a cab file + $data = file_get_contents($file['tmp_name']); + if (strcmp(substr($data,0,4), "MSCF") != 0) { + $success = False; + $uri = $uri . 'filetype=False&'; + } + + # check for metadata + if (strpos($data, ".metainfo.xml") == FALSE) { + $success = False; + $uri = $uri . 'metadata=False&'; + } + + # check the file does not already exist + $id = sha1($data); + $result = $db->query('SELECT * FROM firmware WHERE hash = "' . $id . '";'); + if ($result->num_rows > 0) { + $success = False; + $uri = $uri . 'exists=False&'; + } + + # only save if we passed all tests + if ($success = True) { + $destination = $uploaddir . $id . '.cab'; + #$destination = $uploaddir . $file['name']; + $handle = fopen($destination, "w"); + if ($handle == FALSE) { + header('HTTP/1.0 403 Forbidden'); + echo 'Write permission for ' . $uploaddir . ' missing'; + return; + } + if (fwrite($handle, $data) == FALSE) { + header('HTTP/1.0 413 Request Entity Too Large'); + echo 'Failed to write file'; + return; + } + fclose($handle); + + # log to database + $success = True; + $query = "INSERT INTO firmware (vendor_key, update_contact, addr, timestamp, filename, hash) " . + "VALUES (?, ?, ?, CURRENT_TIMESTAMP, ?, ?);"; + if (!($stmt = $db->prepare($query))) + die("failed to prepare: " . $db->error); + $stmt->bind_param("sssss", + $auth_token, + $_POST['update_contact'], + $_SERVER['REMOTE_ADDR'], + $file['name'], + $id); + if (!$stmt->execute()) + die("failed to execute: " . $stmt->error); + $stmt->close(); + } + + return $uri . 'result=' . $success; +} + +# connect to database and upload firmware +$db = lvfs_connect_db(); +$location = lvfs_upload_firmware($db, $_POST['auth'], $uploaddir, $_FILES['file']); +lvfs_disconnect_db($db); + +header('Location: ' . $location); + +?> diff --git a/docs/website/users.html b/docs/website/users.html new file mode 100644 index 000000000..0be499ea7 --- /dev/null +++ b/docs/website/users.html @@ -0,0 +1,165 @@ + + + + + +fwupd: Firmware Update Daemon + + + + + + + + + +

fwupd: Firmware
Update Daemon

+ +

Introduction

+

+fwupd is a simple daemon to allow session software to update device firmware on +your local machine. It's designed for desktops, but this project is +also usable on phones, tablets and on headless servers. +You can either use a GUI software manager like GNOME Software to view and apply +updates, the command-line tool or the system D-Bus interface directly. +

+ +

Using GNOME Software

+

+New versions of GNOME Software will show and auto-download pending updates automatically: +

+gnome-software updates panel +

+Double clicking on the cab file is also supported: +

+gnome-software updates panel + +

Using the command line

+

+fwupd ships a command line fwupdmgr program. +This allows administrators to get the list of upgradable devices, +schedule offline updates or installing firmware on the live system. +

+
+$ fwupdmgr get-devices
+Device: ro__sys_devices_pci0000_00_0000_00_1d_0_usb2_2_1_2_1_4_2_1_4_1_0
+  DisplayName:     USB 3.0 VL812 B2 Hub
+  Provider:        Udev
+  Guid:            26470009-97a8-4028-867a-bbbac6ee7bf0
+  Version:         9090
+  Internal:        False
+  AllowOnline:     False
+  AllowOffline:    False
+Device: ro__sys_devices_pci0000_00_0000_00_01_0_0000_01_00_0
+  DisplayName:     Barts LE [Radeon HD 6790]
+  Provider:        Udev
+  Guid:            e9b8eebd-b5f8-18d4-9fbd-d7da7711985c
+  Version:         013.012.000.019.000000
+  Internal:        False
+  AllowOnline:     False
+  AllowOffline:    False
+Device: CHug-usb:00:01:04:04
+  DisplayName:     ColorHugALS
+  Provider:        ColorHug
+  Guid:            84f40464-9272-4ef7-9399-cd95f12da696
+  Version:         4.0.0
+  Internal:        False
+  AllowOnline:     True
+  AllowOffline:    True
+
+

+You can see all the command line options using --help: +

+
+$ fwupdmgr --help
+Usage:
+  fwupdmgr [OPTION…]
+
+  clear-results                     Clears the results from the last update
+  get-details                       Gets details about a firmware file
+  get-devices                       Get all devices that support firmware updates
+  get-results                       Gets the results from the last update
+  get-updates                       Gets the list of updates for connected hardware
+  install                           Install a firmware file on this hardware
+  update-offline                    Install the update the next time the computer is rebooted
+  update-online                     Install the update now
+  update-prepared                   Install prepared updates now
+
+Help Options:
+  -h, --help        Show help options
+
+Application Options:
+  -v, --verbose     Show extra debugging information
+  -f, --force       Force the installation of firmware
+
+ +

Using the D-Bus API

+

+If there are supported devices available then the fwupd daemon will be +launched when queried for the first time. +This exports an interface that can be queried from any language with +a D-Bus binding such as C, Python or Java. +

+d-feet screenshot +
+$ $ gdbus call --system --dest org.freedesktop.fwupd --object-path / --method org.freedesktop.fwupd.GetDevices 
+({'ro__sys_devices_pci0000_00_0000_00_1d_0_usb2_2_1_2_1_4_2_1_4_1_0':
+   {'Vendor': <'VIA'>,
+    'Guid': <'26470009-97a8-4028-867a-bbbac6ee7bf0'>,
+    'DisplayName': <'USB 3.0 VL812 B2 Hub'>,
+    'Provider': <'Udev'>,
+    'Version': <'9090'>,
+    'Flags': },
+  'ro__sys_devices_pci0000_00_0000_00_01_0_0000_01_00_0':
+   {'Vendor': <'Advanced Micro Devices, Inc. [AMD/ATI]'>,
+    'Guid': <'e9b8eebd-b5f8-18d4-9fbd-d7da7711985c'>,
+    'DisplayName': <'Barts LE [Radeon HD 6790]'>,
+    'Provider': <'Udev'>,
+    'RomFilename': <'/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/rom'>,
+    'Version': <'013.012.000.019.000000'>,
+    'Flags': },
+  'CHug-usb:00:01:04:04':
+   {'Guid': <'84f40464-9272-4ef7-9399-cd95f12da696'>,
+    'DisplayName': <'ColorHugALS'>,
+    'Provider': <'ColorHug'>,
+    'Version': <'4.0.0'>,
+    'Flags': }},)
+
+ +

Security

+

+By default, any users are able to install firmware to removable hardware. +The logic here is that if the hardware can be removed, it can easily be moved to +a device that the user already has root access on, and asking for authentication +would just be security theatre. +

+

+For non-removable devices, e.g. UEFI firmware, admin users are able to update +trusted firmware without the root password. +By default, we already let admin user and root update glibc and the kernel +without additional authentication, and these would be a much easier target to backdoor. +The firmware updates themselves are signed and have a checksum, and the metadata +describing this checksum is provided by the distribution either as +GPG-signed repository metadata, or installed from a package, which is +expected to also be signed. +

+ +

User Interaction

+

+No user interaction should be required when actually applying updates. +Making it prohibited means we can do the upgrade with a fancy graphical +splash screen, without having to worry about locales and input methods. +Updating firmware should be no more dangerous than installing a new kernel +or glibc package. +

+ +

Go back to the main page

+ + + + + + diff --git a/docs/website/vendors.html b/docs/website/vendors.html new file mode 100644 index 000000000..55b6e6bd7 --- /dev/null +++ b/docs/website/vendors.html @@ -0,0 +1,198 @@ + + + + + +Linux Vendor Firmware Service + + + + + + + + + +

Linux Vendor
Firmware Service

+ +

Introduction

+

+ This page provides a place for hardware vendors to submit packaged + firmware updates, typically cab files. + This fire-and-forget service allows vendors to submit firmware updates + without generating and hosting metadata themselves. +

+

+ Clients such as fwupd + periodically check for updated metadata at this site and will offer the firmware + to end users or be installed automatically depending on site policy. +

+

+ NOTE: This service should only be used to distribute firmware that is + flashed onto non-volatile memory. + It is not designed for firmware that has to be uploaded to devices every time + the device is used. +

+

+ There is no charge to vendors for the hosting or distribution of content. +

+

When files are submitted the following actions are performed:

+
    +
  1. The update metadata is checked for correctness.
  2. +
  3. The firmware capsule is signed with our GPG key.
  4. +
  5. The new cab file is moved to our infrastructure.
  6. +
  7. The metadata is added to our database.
  8. +
+ +

Upload Firmware

+

+ It is imperative that updates have been verified to work correctly on + all matching hardware. +

+ +

Legal

+

By uploading a firmware file you must agree that:

+
    +
  • You are legally permitted to submit the firmware.
  • +
  • The submitted firmware file is permitted to be mirrored by our site.
  • +
  • The firmware installation must complete without requiring user input.
  • +
  • Firmware must not engage in malicious activity (e.g. be viruses, worms, or exploit security issues).
  • +
  • Firmware can only be removed from this archive in exceptional cases.
  • +
+
+ + + + + + + +
Vendor Key:
Contact Email:
Firmware:
+ +
+ +

Help With Submitting Firmware

+ +

+If you are not using the UEFI capsule update method you need to write a +plugin for fwupd to trigger the firmware update from userspace. +At the moment there is just UEFI and ColorHug providers, but others are welcome. +

+ +

+As per the Microsoft guidelines +package up your firmware into a cab file, with these files inside: +

+ +

+You can create a cab file using makecab.exe on Windows and gcab --create +on Linux. +

+

+It is recommended you name the cab file with the hardware name and the version +number, e.g. colorhug-als-1.2.3.cab. It's mandatory that the files inside the +cab file have the same basename, for example this is would be valid: +

+

+

+    colorhug2-1.2.3.cab
+     |- firmware.inf
+     |- firmware.bin
+     |- firmware.bin.asc
+     \- firmware.metainfo.xml
+
+

+

+An example inf file looks like this: +

+

+

+[Version]
+Class=Firmware
+ClassGuid={f2e7dd72-6468-4e36-b6f1-6488f42c1b52}
+DriverVer=03/03/2015,3.0.2
+
+[Firmware_CopyFiles]
+firmware.bin
+
+[Firmware_AddReg]
+HKR,,FirmwareId,,{84f40464-9272-4ef7-9399-cd95f12da696}
+HKR,,FirmwareVersion,%REG_DWORD%,0x0000000
+HKR,,FirmwareFilename,,firmware.bin
+
+

+

+An example metainfo.xml file looks like this: +

+

+

+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright 2015 Richard Hughes  -->
+<component type="firmware">
+  <id>84f40464-9272-4ef7-9399-cd95f12da696</id>
+  <name>ColorHugALS Firmware</name>
+  <summary>Firmware for the ColorHugALS Ambient Light Sensor</summary>
+  <description>
+    <p>
+      Updating the firmware on your ColorHugALS device improves performance and
+      adds new features.
+    </p>
+  </description>
+  <url type="homepage">http://www.hughski.com/</url>
+  <metadata_license>CC0-1.0</metadata_license>
+  <project_license>GPL-2.0+</project_license>
+  <developer_name>Hughski Limited</developer_name>
+  <releases>
+    <release version="3.0.2" timestamp="1424116753">
+      <location>http://www.hughski.com/downloads/colorhug-als/firmware/colorhug-als-3.0.2.cab</location>
+      <description>
+        <p>This stable release fixes the following bugs:</p>
+        <ul>
+          <li>Fix the return code from GetHardwareVersion</li>
+          <li>Scale the output of TakeReadingRaw by the datasheet values</li>
+        </ul>
+      </description>
+    </release>
+  </releases>
+</component>
+
+

+

+If the firmware is not free software you have to indicate it in the +metainfo.xml file with <project_license>proprietary</project_license>. +

+ +

Why does the LVFS project sign my firmware?

+

+The Linux Vendor Firmware Project signs the firmware image and repacks +the files into a new cabinet file for several reasons: +

+
    +
  • Only trusted vendors have access to the LVFS service, so we can be sure the firmware actually came from the vendor
  • +
  • Clients do not (yet) verify the signatures in the cat file
  • +
  • Not all software trusts the Microsoft WHQL certificate
  • +
  • We ensure that only required files are included in the cabinet file, typically making the download size much smaller
  • +
+ +

Validation

+

+The best way to validate the metainfo file or firmware before submission is by using the +appstream-util validate tool available from the +appstream-glib project. +

+ +

Go back to the main page

+ + + + + +