Move the LVFS website to the fwupd project

This commit is contained in:
Richard Hughes 2015-07-16 17:12:27 +01:00
parent 8ffbd403cb
commit 60a7210318
25 changed files with 10889 additions and 273 deletions

278
README.md
View File

@ -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.
<code>--disable-colorhug<code> 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 <code>fwupdate<code> from, either compile it form source
(you might also need a newer <code>efivar<code>) 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 <code>--disable-uefi<code>
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
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright 2015 Richard Hughes <richard@hughsie.com> -->
<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 redistributable you have to indicate it in in the
`.metainfo.xml` file with `<project_license>proprietary</project_license>`.
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 '<id>' 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.

790
docs/architecture-plan.svg Normal file
View File

@ -0,0 +1,790 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="1052.3622"
height="744.09448"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="architecture-plan.svg"
inkscape:export-filename="/home/hughsie/Code/colord/doc/website/img/architecture-plan.png"
inkscape:export-xdpi="59.99197"
inkscape:export-ydpi="59.99197">
<defs
id="defs4">
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Send"
style="overflow:visible;">
<path
id="path3875"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
transform="scale(0.2) rotate(180) translate(6,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Mend"
style="overflow:visible;">
<path
id="path3869"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
transform="scale(0.4) rotate(180) translate(10,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Sstart"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Sstart"
style="overflow:visible">
<path
id="path3872"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
transform="scale(0.2) translate(6,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Lstart"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Lstart"
style="overflow:visible">
<path
id="path3860"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
transform="scale(0.8) translate(12.5,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Sstart"
orient="auto"
refY="0"
refX="0"
id="Arrow1Sstart-5"
style="overflow:visible">
<path
inkscape:connector-curvature="0"
id="path3872-4"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(0.2,0,0,0.2,1.2,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-7"
style="overflow:visible">
<path
inkscape:connector-curvature="0"
id="path3875-0"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Sstart"
orient="auto"
refY="0"
refX="0"
id="Arrow1Sstart-5-1"
style="overflow:visible">
<path
inkscape:connector-curvature="0"
id="path3872-4-4"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(0.2,0,0,0.2,1.2,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-7-6"
style="overflow:visible">
<path
inkscape:connector-curvature="0"
id="path3875-0-2"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Sstart"
orient="auto"
refY="0"
refX="0"
id="Arrow1Sstart-8"
style="overflow:visible">
<path
inkscape:connector-curvature="0"
id="path3872-5"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(0.2,0,0,0.2,1.2,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-9"
style="overflow:visible">
<path
inkscape:connector-curvature="0"
id="path3875-04"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send-7-9"
style="overflow:visible">
<path
inkscape:connector-curvature="0"
id="path3875-0-1"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.7"
inkscape:cx="491.33991"
inkscape:cy="175.26692"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
showguides="true"
inkscape:guide-bbox="true"
inkscape:window-width="1920"
inkscape:window-height="1016"
inkscape:window-x="0"
inkscape:window-y="867"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid2985"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-308.2677)">
<rect
style="fill:#f29097;fill-opacity:1;stroke:#000000;stroke-width:2.88675141000000002;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="rect2987"
width="240"
height="60"
x="420"
y="672.36218"
ry="20"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:'Bitstream Vera Sans';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
x="541.35742"
y="713.39734"
id="text2989"
sodipodi:linespacing="125%"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067"><tspan
sodipodi:role="line"
id="tspan2991"
x="541.35742"
y="713.39734"
style="text-align:center;text-anchor:middle">fwupd</tspan></text>
<rect
ry="20"
y="872.36218"
x="180"
height="60"
width="180"
id="rect2993"
style="fill:#ffffc8;fill-opacity:1;stroke:#000000;stroke-width:2.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067" />
<text
sodipodi:linespacing="125%"
id="text2995"
y="912.37256"
x="268.61694"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:'Bitstream Vera Sans';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
xml:space="preserve"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067"><tspan
style="font-size:27.5px;text-align:center;text-anchor:middle"
y="912.37256"
x="268.61694"
id="tspan2997"
sodipodi:role="line">ESRT</tspan></text>
<rect
ry="20"
y="672.36218"
x="180"
height="60"
width="180"
id="rect2993-4"
style="fill:#ffffc8;fill-opacity:1;stroke:#000000;stroke-width:2.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:2.5, 2.5;stroke-dashoffset:0"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067" />
<text
sodipodi:linespacing="80.000001%"
id="text2995-9"
y="701.61426"
x="269.32861"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:80.00000119%;font-family:'Bitstream Vera Sans';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
xml:space="preserve"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067"><tspan
style="font-size:27.5px;line-height:80.00000119%;text-align:center;text-anchor:middle"
y="701.61426"
x="269.32861"
id="tspan2997-9"
sodipodi:role="line">Vendor</tspan><tspan
style="font-size:27.5px;line-height:80.00000119%;text-align:center;text-anchor:middle"
y="723.61426"
x="269.32861"
sodipodi:role="line"
id="tspan4991">Provders</tspan></text>
<rect
style="fill:#ffffc8;fill-opacity:1;stroke:#000000;stroke-width:2.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="rect3023-9"
width="180"
height="60"
x="180"
y="772.36218"
ry="20"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:'Bitstream Vera Sans';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
x="269.21448"
y="812.61426"
id="text3025-0"
sodipodi:linespacing="125%"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067"><tspan
sodipodi:role="line"
id="tspan3027-2"
x="269.21448"
y="812.61426"
style="font-size:27.5px;text-align:center;text-anchor:middle">Udev</tspan></text>
<rect
ry="20"
y="672.36218"
x="720"
height="60"
width="180"
id="rect3053"
style="fill:#ff96ff;fill-opacity:1;stroke:#000000;stroke-width:2.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067" />
<text
sodipodi:linespacing="125%"
id="text3055"
y="709.94885"
x="810.50354"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:'Bitstream Vera Sans';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
xml:space="preserve"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067"><tspan
style="font-size:27.5px;text-align:center;text-anchor:middle"
y="709.94885"
x="810.50354"
id="tspan3057"
sodipodi:role="line">systemd</tspan></text>
<rect
style="fill:#64ffff;fill-opacity:1;stroke:#000000;stroke-width:2.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect3059"
width="180"
height="60"
x="719.54187"
y="772.36218"
ry="20"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:'Bitstream Vera Sans';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
x="809.04504"
y="809.94885"
id="text3061"
sodipodi:linespacing="125%"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067"><tspan
sodipodi:role="line"
id="tspan3063"
x="809.04504"
y="809.94885"
style="font-size:27.5px;text-align:center;text-anchor:middle">pending.db</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:none;marker-end:url(#Arrow1Send)"
d="m 360,712.36218 60,0"
id="path3841"
inkscape:connector-curvature="0"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067" />
<path
style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:none;marker-end:url(#Arrow1Send)"
d="m 360,792.36218 115,0 0,-60"
id="path3843"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067" />
<path
style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:;marker-end:url(#Arrow1Send)"
d="m 360,892.36218 140,0 0,-160"
id="path3845"
inkscape:connector-curvature="0"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067" />
<path
style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Arrow1Sstart);marker-end:none"
d="m 718.97997,712.36218 -60,0"
id="path3849"
inkscape:connector-curvature="0"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067" />
<path
style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Sstart);marker-end:url(#Arrow1Send)"
d="m 720,792.36218 -110,0 0,-60"
id="path3851"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067" />
<path
style="fill:none;stroke:#000000;stroke-width:0.95742708px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 40,652.36218 880,0"
id="path5615"
inkscape:connector-curvature="0"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067" />
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="48.285713"
y="643.2193"
id="text5617"
sodipodi:linespacing="125%"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067"><tspan
sodipodi:role="line"
id="tspan5619"
x="48.285713"
y="643.2193"
style="font-size:32px">session</tspan></text>
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
x="48.857143"
y="683.21936"
id="text5621"
sodipodi:linespacing="125%"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067"><tspan
sodipodi:role="line"
id="tspan5623"
x="48.857143"
y="683.21936"
style="font-size:32px">system</tspan></text>
<rect
ry="20"
y="452.36218"
x="440"
height="60"
width="200"
id="rect5625"
style="fill:#83a2ff;fill-opacity:1;stroke:#000000;stroke-width:2.635;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067" />
<path
style="fill:none;stroke:#000096;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:;marker-end:url(#Arrow1Send-7)"
d="m 540,672.36218 0,-160"
id="path5631"
inkscape:connector-curvature="0"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067" />
<rect
ry="20"
y="552.36218"
x="280"
height="60"
width="180.64258"
id="rect5625-3"
style="fill:#83a2ff;fill-opacity:1;stroke:#000000;stroke-width:2.50445843;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067" />
<text
sodipodi:linespacing="125%"
id="text5627-6"
y="590.36218"
x="372.64258"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:'Bitstream Vera Sans';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
xml:space="preserve"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067"><tspan
style="font-size:27.5px;text-align:center;text-anchor:middle"
y="590.36218"
x="372.64258"
id="tspan5629-6"
sodipodi:role="line">fwupdmgr</tspan></text>
<rect
ry="20"
y="452.36218"
x="720"
height="60"
width="180"
id="rect5657"
style="fill:#a6bdbd;fill-opacity:1;stroke:#000000;stroke-width:2.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067" />
<text
sodipodi:linespacing="89.999998%"
id="text5659"
y="480.50946"
x="810.64258"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:89.99999762%;font-family:'Bitstream Vera Sans';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
xml:space="preserve"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067"><tspan
style="font-size:27.5px;line-height:89.99999762%;text-align:center;text-anchor:middle"
y="480.50946"
x="810.64258"
id="tspan5661"
sodipodi:role="line">download</tspan><tspan
style="font-size:27.5px;line-height:89.99999762%;text-align:center;text-anchor:middle"
y="502.10947"
x="810.64258"
sodipodi:role="line"
id="tspan4993">cache</tspan></text>
<path
style="fill:none;stroke:#000096;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Sstart-5);marker-end:none"
d="m 460,592.36218 40,0 0,80"
id="path5663"
inkscape:connector-curvature="0"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067" />
<rect
ry="20"
y="452.36218"
x="180"
height="60"
width="180"
id="rect5675"
style="fill:#cbffc8;fill-opacity:1;stroke:#000000;stroke-width:2.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067" />
<path
style="fill:none;stroke:#000000;stroke-width:4.61880207000000009;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:none;marker-end:url(#Arrow1Send-7)"
d="m 360,492.36218 80,0"
id="path5673"
inkscape:connector-curvature="0"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067" />
<text
sodipodi:linespacing="125%"
id="text5677"
y="492.19128"
x="268.98621"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:'Bitstream Vera Sans';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
xml:space="preserve"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067"><tspan
style="font-size:27.5px;text-align:center;text-anchor:middle"
y="492.19128"
x="268.98621"
id="tspan5679"
sodipodi:role="line">Internet</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:4.61880207;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:url(#Arrow1Sstart-5);marker-end:url(#Arrow1Send-7)"
d="m 640,492.36218 80,0"
id="path5673-3"
inkscape:connector-curvature="0"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:'Bitstream Vera Sans';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
x="370"
y="807.36218"
id="text7146-2-2"
sodipodi:linespacing="125%"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067"><tspan
sodipodi:role="line"
id="tspan7148-7-6"
x="370"
y="807.36218"
style="font-size:12px">Gudev + rules</tspan></text>
<text
sodipodi:linespacing="125%"
id="text7584"
y="784.36218"
x="665"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
xml:space="preserve"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067"><tspan
style="font-size:12px"
y="784.36218"
x="665"
id="tspan7586"
sodipodi:role="line">sqlite</tspan></text>
<text
sodipodi:linespacing="125%"
id="text3912"
y="486.36218"
x="660"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
xml:space="preserve"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067"><tspan
style="font-size:12px"
y="486.36218"
x="660"
id="tspan3914"
sodipodi:role="line">$home</tspan></text>
<text
sodipodi:linespacing="125%"
id="text5627-8"
y="495.72552"
x="532.26953"
style="font-style:normal;font-weight:normal;font-size:28.10403442px;line-height:125%;font-family:'Bitstream Vera Sans';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
xml:space="preserve"
transform="scale(1.0144841,0.98572269)"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067"><tspan
style="font-size:21.25px;text-align:center;text-anchor:middle"
y="495.72552"
x="532.26953"
sodipodi:role="line"
id="tspan3086-5">gnome-software</tspan></text>
<path
inkscape:connector-curvature="0"
id="path4995"
d="m 579.85714,672.36218 0,-160"
style="fill:none;stroke:#000096;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Arrow1Sstart-5)"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067" />
<text
sodipodi:linespacing="125%"
id="text3912-9"
y="-587.11932"
x="536.76471"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:'Bitstream Vera Sans';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
xml:space="preserve"
transform="matrix(0,1,-1,0,0,0)"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067"><tspan
style="font-size:12px"
y="-587.11932"
x="536.76471"
id="tspan3914-1"
sodipodi:role="line">UpdateMetadata()</tspan></text>
<text
sodipodi:linespacing="125%"
id="text3912-9-1"
y="-547.26221"
x="542.479"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:'Bitstream Vera Sans';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
xml:space="preserve"
transform="matrix(0,1,-1,0,0,0)"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067"><tspan
style="font-size:12px"
y="-547.26221"
x="542.479"
id="tspan3914-1-0"
sodipodi:role="line">GetDevices()</tspan></text>
<rect
ry="20"
y="871.09338"
x="-899.54187"
height="60"
width="180"
id="rect2993-0"
style="fill:#ffffc8;fill-opacity:1;stroke:#000000;stroke-width:2.5;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
transform="scale(-1,1)"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067" />
<text
sodipodi:linespacing="125%"
id="text2995-2"
y="908.68005"
x="809.47473"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:'Bitstream Vera Sans';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
xml:space="preserve"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067"><tspan
style="font-size:27.5px;text-align:center;text-anchor:middle"
y="908.68005"
x="809.47473"
id="tspan2997-94"
sodipodi:role="line">sysfs</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send-7-6)"
d="m 720.04697,892.36218 -140,0 0,-160.00005"
id="path3845-0"
inkscape:connector-curvature="0"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067" />
<text
sodipodi:linespacing="125%"
id="text3912-93"
y="484.21933"
x="367.75699"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:'Bitstream Vera Sans';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
xml:space="preserve"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067"><tspan
style="font-size:12px"
y="484.21933"
x="367.75699"
id="tspan3914-6"
sodipodi:role="line">metadata</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:'Bitstream Vera Sans';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
x="368.57144"
y="507.07648"
id="text5147"
sodipodi:linespacing="125%"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067"><tspan
sodipodi:role="line"
id="tspan5149"
x="368.57144"
y="507.07648"
style="font-size:12px">firmware</tspan></text>
<rect
ry="20"
y="-1011.0447"
x="440"
height="60"
width="200"
id="rect5625-0"
style="fill:#64ffff;fill-opacity:1;stroke:#000000;stroke-width:2.63499999;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
transform="scale(1,-1)"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067" />
<path
style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Arrow1Sstart);marker-end:url(#Arrow1Send)"
d="m 540,739.61613 0,210"
id="path5631-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067" />
<text
sodipodi:linespacing="125%"
id="text5627-8-5"
y="1000.9299"
x="532.25916"
style="font-style:normal;font-weight:normal;font-size:28.10403442px;line-height:125%;font-family:'Bitstream Vera Sans';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
xml:space="preserve"
transform="scale(1.0144841,0.98572269)"
inkscape:export-filename="/home/hughsie/Code/fwupd/docs/website/img/architecture-plan.png"
inkscape:export-xdpi="71.67067"
inkscape:export-ydpi="71.67067"><tspan
style="font-size:21.25px;text-align:center;text-anchor:middle"
y="1000.9299"
x="532.25916"
sodipodi:role="line"
id="tspan3086-5-8">AppStream XML</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 34 KiB

7
docs/website/.htaccess Normal file
View File

@ -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

View File

@ -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

40
docs/website/README.md Normal file
View File

@ -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');

8671
docs/website/banner.svg Normal file

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 653 KiB

35
docs/website/db.php Normal file
View File

@ -0,0 +1,35 @@
<?php
/*
* Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
*
* 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();
}
?>

View File

@ -0,0 +1,171 @@
<!DOCTYPE html>
<!-- Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
Licensed under the GNU General Public License Version 2 -->
<html>
<head>
<title>fwupd: Firmware Update Daemon</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,300' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="style.css" type="text/css" media="screen"/>
<link rel="shortcut icon" href="favicon.ico"/>
</head>
<body>
<h1 class="banner">fwupd: Firmware<br> Update Daemon</h1>
<h1>Introduction</h1>
<p>
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 <a href="http://www.hughski.com/">ColorHug</a> devices.
</p>
<p>
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.
</p>
<p>
<a href="http://www.freedesktop.org/software/appstream/docs/">AppStream 0.9</a>
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 <code>appstream-builder</code> or the
<a href="vendors.html">Linux Vendor Firmware Service</a>.
</p>
<h1>Architecture</h1>
<p>
fwupd is implemented as a D-Bus activated service that is autostarted when
required.
</p>
<img src="img/architecture-plan.png" alt="architecture-plan"/>
<p>
The 'client' which is typically <code>gnome-software</code> or <code>fwupd</code>
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.
</p>
<h2>Getting the code</h2>
<p>
The latest code is always available at <a href="https://github.com/hughsie/fwupd">GitHub</a>
and this is also the place to file <a href="https://github.com/hughsie/fwupd/issues">bugs or feature requests</a>.
You can trivially get the code by doing:
</p>
<pre>
$ git clone https://github.com/hughsie/fwupd.git
</pre>
<p>
You can also install all the required dependancies using:
</p>
<pre>
$ sudo dnf install docbook-utils gettext intltool libgudev1-devel \
colord-devel polkit-devel libgcab1-devel \
sqlite-devel gpgme-devel fwupdate-devel
</pre>
<h2>How does fwupd know the device firmware version?</h2>
<p>
There are currently several ways to detect the firmware version:
</p>
<ul>
<li>USB firmware version extensions (see below)</li>
<li>The <code>bcdVersion</code> for some USB devices</li>
<li>Parsing the option ROM and searching for serial numbers</li>
<li>Using <code>libfwupdate</code> to get the ESRT table data</li>
<li>Using a custom provider (not covered here)</li>
</ul>
<h3>USB Firmware Version Extensions</h3>
<p>
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.
</p>
<p>
To implement the firmware version extension just create an interface descriptor
with class code <code>0xff</code>, subclass code <code>0x46</code> and
protocol <code>0x57</code> pointing to a string descriptor with the firmware version.
An example commit to the ColorHug project can be found
<a href="https://github.com/hughski/colorhug2-firmware/commit/5e1bb64ad722a9d2d95927e305fd869b4a3a46a8">here</a>.
</p>
<p>
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.
</p>
<p>
To implement this, add an interface descriptor with class code <code>0xff</code>, subclass
code <code>0x47</code> and protocol <code>0x55</code> pointing to a string descriptor with the GUID.
If the GUID matches the <code>&lt;id&gt;</code> obtained from the AppStream metadata then the
device will be shown.
An example commit to the ColorHug project can be found
<a href="https://github.com/hughski/colorhug2-firmware/commit/f974638ac17b0e50f21987e2f1d982374cabe22c">here</a>.
</p>
<h2>Offline Updates Lifecycle</h2>
<p>
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.
</p>
<p>
Devices go through the following lifecycles:
</p>
<ol>
<li>created &rarr; <code>SCHEDULED</code> &rarr; <code>SUCCESS</code> &rarr; deleted</li>
<li>created &rarr; <code>SCHEDULED</code> &rarr; <code>FAILED</code> &rarr; deleted</li>
</ol>
<p>
Any user-visible output is available using the <code>GetResults()</code> D-Bus method, and
the database entry is only deleted once the <code>ClearResults()</code> method is called.
</p>
<p>
The results are obtained and cleared either using a provider-supplied method
or using a small SQLite database located at <code>/var/lib/fwupd/pending.db</code>
</p>
<h2>Adding Trusted Keys</h2>
<p>
Installing a public key to <code>/etc/pki/fwupd</code> 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 <b>upgraded</b> (but not downgraded)
without the user or administrator
password.
</p>
<p>
Only very few keys will be installed <i>by default</i>. These are the keys of
vendors who have a proven security track record and a thorough understanding of
public-private key security.
</p>
<p>
In particular, private keys should <b>only</b> 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.
</p>
<h3>Adding a New Key</h3>
<p>
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.
</p>
<p><a href="index.html">Go back to the main page</a></p>
<p class="footer">
Copyright <a href="mailto:richard@hughsie.com">Richard Hughes 2015</a>
</p>
</body>
</html>

55
docs/website/dump.php Normal file
View File

@ -0,0 +1,55 @@
<!DOCTYPE html>
<!-- Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
Licensed under the GNU General Public License Version 2 -->
<html>
<head>
<title>Linux Vendor Firmware Service</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<link rel="stylesheet" href="style.css" type="text/css" media="screen"/>
<link rel="shortcut icon" href="favicon.ico"/>
</head>
<body>
<h1>History</h1>
<table class="history">
<tr>
<th>Vendor</th>
<th>Filename</th>
<th>Hash</th>
</tr>
<?php
include 'db.php';
function lvfs_get_vendor_name($db, $id) {
$res = $db->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 '<tr>';
echo '<td>' . $vendor_name . '</td>';
echo '<td>' . $row["filename"] . '</td>';
echo '<td>' . $row["hash"] . '</td>';
echo '</tr>';
}
lvfs_disconnect_db($db);
?>
</table>
<p class="footer">
Copyright <a href="mailto:richard@hughsie.com">Richard Hughes 2015</a>
</p>
</body>
</html>

BIN
docs/website/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
docs/website/img/dbus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

View File

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="94.142853"
height="94.142853"
viewBox="0 0 94.14285 94.142852"
id="svg48042"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="nav-devs.svg">
<defs
id="defs48044" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="-11.37141"
inkscape:cy="75.907192"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="2560"
inkscape:window-height="1376"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
units="px"
inkscape:snap-bbox="true"
inkscape:snap-bbox-midpoints="true"
inkscape:bbox-nodes="true"
inkscape:bbox-paths="true">
<inkscape:grid
type="xygrid"
id="grid48871"
originx="-3.6083983e-06"
originy="0.14284787" />
</sodipodi:namedview>
<metadata
id="metadata48047">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-446.69823,-860.95734)">
<g
transform="translate(160.26965,499.59515)"
id="g48765">
<circle
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#4e9a06;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="circle43602"
cx="333.5"
cy="408.43362"
r="47.071426" />
<g
style="display:inline"
transform="matrix(-2,0,0,2,941.00042,-178.66898)"
inkscape:label="builder"
id="g27305">
<rect
y="285.01559"
x="295.50021"
height="16"
width="16"
id="rect27307"
style="display:inline;opacity:0;fill:#ffffff;fill-opacity:1;stroke:none" />
<path
id="path27321"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 299.50023,293.01558 1.06629,1.91069 -0.98216,2.08931 -0.53125,0 0.44712,-2.46875 -1.45313,-0.26562 0.0194,1.73011 -0.57544,-0.004 -0.44398,-1.67945 -0.57812,0.1562 0.0157,2.5 -0.5625,0.0312 -0.82813,-2.5625 1.39553,-1.44525 0.006,-0.98548 2.99242,-0.006 z m 3.40623,-6.01019 a 1.5277282,1.5277282 0 0 1 1.52832,1.52734 1.5277282,1.5277282 0 0 1 -0.12305,0.59473 l 1.49902,1.82031 a 2.5,2.5 0 0 1 0.18946,-0.01 2.5,2.5 0 0 1 2.5,2.5 2.5,2.5 0 0 1 -2.5,2.5 2.5,2.5 0 0 1 -2.5,-2.5 2.5,2.5 0 0 1 0.29394,-1.17089 l -0.87793,-2.20704 a 1.5277282,1.5277282 0 0 1 -0.01,9.8e-4 1.5277282,1.5277282 0 0 1 -1.35645,-0.82715 l -1.95019,0.44824 a 1.5277282,1.5277282 0 0 1 -1.51075,1.30664 1.5277282,1.5277282 0 0 1 -1.52734,-1.52733 1.5277282,1.5277282 0 0 1 1.52734,-1.52832 1.5277282,1.5277282 0 0 1 1.36817,0.85351 l 1.94239,-0.49805 a 1.5277282,1.5277282 0 0 1 1.50683,-1.2832 z m 4.10939,9.60003 1.42579,1.41016 0.9082,0.2207 c 0.0884,0.0276 0.15625,0.13433 0.15625,0.25586 l 0,1.52344 -7.00586,0 0,-1.54492 c 0,-0.14377 0.0693,-0.19958 0.19922,-0.23438 l 0.77539,-0.2207 1.54492,-1.40039 a 3.328125,3.328125 0 0 0 0.98047,0.15234 3.328125,3.328125 0 0 0 1.01562,-0.16211 z"
inkscape:connector-curvature="0" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.1 KiB

125
docs/website/img/nav-hw.svg Normal file
View File

@ -0,0 +1,125 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="94.142853"
height="94.142853"
viewBox="0 0 94.14285 94.142852"
id="svg48042"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="nav-hw.svg">
<defs
id="defs48044" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="-4.0358056"
inkscape:cy="88.064222"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="2560"
inkscape:window-height="1376"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
units="px"
inkscape:snap-bbox="true"
inkscape:snap-bbox-midpoints="true"
inkscape:bbox-nodes="true"
inkscape:bbox-paths="true">
<inkscape:grid
type="xygrid"
id="grid48871"
originx="-3.6083983e-06"
originy="0.14284787" />
</sodipodi:namedview>
<metadata
id="metadata48047">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-446.69823,-860.95734)">
<g
transform="translate(42.269653,499.59515)"
id="g48771">
<g
id="g43614"
transform="translate(292,5)">
<circle
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#3465a4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="circle43616"
cx="159.5"
cy="403.43362"
r="47.071426" />
</g>
<g
inkscape:label="media-removable"
id="g9503"
transform="matrix(1.9999998,0,0,1.9999998,194.03088,-543.63768)"
style="display:inline">
<g
inkscape:label="input-projector"
id="g9435"
transform="translate(19.968586,0)">
<g
inkscape:label="insert-headphones"
id="g9437"
transform="translate(20.031414,0)">
<g
inkscape:label="musicplayer"
id="g9439"
transform="translate(20,0)">
<rect
y="467"
x="61.000198"
height="16"
width="16.000002"
id="rect9441"
style="fill:none;stroke:none" />
</g>
</g>
</g>
<path
style="fill:#ffffff;fill-opacity:1;stroke:none"
d="m 133.0002,473 0,5.06173 c 0,2.7358 -1.784,4.93827 -4,4.93827 -2.216,0 -4,-2.20247 -4,-4.93827 l 0,-5.06173 z"
id="rect9463"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssscc" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:none"
d="m 126.00022,468 0,4 5.99998,0 0,-4 -5.99998,0 z m 0.99998,1 1.00002,0 0,1 -1.00002,0 0,-1 z m 3,0 1.00002,0 0,1 -1.00002,0 0,-1 z"
id="rect9466"
inkscape:connector-curvature="0" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="26.569204mm"
height="26.569204mm"
viewBox="0 0 94.14285 94.142852"
id="svg48042"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="nav-users.svg">
<defs
id="defs48044" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.35"
inkscape:cx="-787.41252"
inkscape:cy="422.59513"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="2560"
inkscape:window-height="1376"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1" />
<metadata
id="metadata48047">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-446.69823,-860.81449)">
<g
transform="translate(277.26966,499.45229)"
id="g48757">
<circle
r="47.071426"
cy="408.43362"
cx="216.5"
id="path38742"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#f57900;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
<g
transform="matrix(2,0,0,2,118.95231,-282.61415)"
inkscape:label="avatar-default"
id="g6234"
style="display:inline">
<rect
style="color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:1;marker:none"
id="rect20566"
width="16"
height="16"
x="41.000198"
y="337"
inkscape:label="a" />
<g
transform="translate(-577.9998,-648.3622)"
id="g3938">
<path
style="fill:#ffffff;fill-opacity:1;stroke:none"
d="m 629.55469,993.45593 c -0.70541,0.62353 -1.53918,0.90625 -2.55469,0.90625 -1.01551,0 -1.85318,-0.29053 -2.55859,-0.91406 -1.10938,0.36328 -2.43603,1.28775 -2.4375,2.90234 L 622,999.36218 c -7.2e-4,0.554 0.446,1.00002 1,1.00002 l 8,0 c 0.554,0 1,-0.44602 1,-1.00002 l 0,-3 c 0,-1.38672 -1.10231,-2.5558 -2.44531,-2.90625 z"
id="path3940-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csccsssscc" />
<circle
transform="matrix(1.2,0,0,1.2,567.6,579.36217)"
id="path3942-6"
style="color:#bebebe;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;enable-background:accumulate"
cx="49.5"
cy="342.5"
r="2.5" />
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

65
docs/website/index.html Normal file
View File

@ -0,0 +1,65 @@
<!DOCTYPE html>
<!-- Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
Licensed under the GNU General Public License Version 2 -->
<html>
<head>
<title>fwupd: Updating Firmware in Linux</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,300' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="style.css" type="text/css" media="screen"/>
<link rel="shortcut icon" href="favicon.ico"/>
</head>
<body>
<h1 class="banner">fwupd: Updating<br>Firmware in Linux</h1>
<h1>Introduction</h1>
<p>
This project aims to make updating firmware on Linux automatic, safe and reliable.
</p>
<nav class="buttons">
<a id="users" href="users.html">For end users</a>
<a id="devs" href="developers.html">For developers</a>
<a id="hw" href="vendors.html">For hardware vendors</a>
</nav>
<h2>About</h2>
<p>
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.
</p>
<p>
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.
</p>
<p>
Providing a firmware update service actually requires two things:
<ol>
<li>Vendors providing information about what updates are available for specific hardware</li>
<li>A mechanism to actually deploy the firmware onto the hardware itself</li>
</ol>
<p>
Traditionally firmware is packaged up in a <code>cab</code> file which includes
an <code>inf</code> 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.
</p>
<p class="footer">
Copyright <a href="mailto:richard@hughsie.com">Richard Hughes 2015</a>
</p>
</body>
</html>

60
docs/website/result.php Normal file
View File

@ -0,0 +1,60 @@
<!DOCTYPE html>
<!-- Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
Licensed under the GNU General Public License Version 2 -->
<html>
<head>
<title>Linux Vendor Firmware Service</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<link rel="stylesheet" href="style.css" type="text/css" media="screen"/>
<link rel="shortcut icon" href="favicon.ico"/>
</head>
<body>
<?php
if ($_GET["result"] == 'True')
echo '<h1>Result: Success</h1>';
else
echo '<h1>Result: Failed</h1>';
?>
<table class="history">
<tr>
<th>Test</th>
<th>Result</th>
</tr>
<?php
function lvfs_result($get_id, $title, $error_msg) {
echo '<tr><td>' . $title . '</td><td>';
if ($_GET[$get_id] == 'False')
echo '&#x2610; ' . $error_msg;
else
echo '&#x2611; Passed';
echo '</td></tr>';
}
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 <code>cab</code> file');
lvfs_result('metadata', 'Metadata', 'The firmware file had no valid metadata');
lvfs_result('exists', 'Version Check', 'The firmware file already exists');
?>
</table>
<p>
<a href="vendors.html">Go back to the submission page</a>.
</p>
<p class="footer">
Copyright <a href="mailto:richard@hughsie.com">Richard Hughes 2015</a>
</p>
</body>
</html>

172
docs/website/style.css Normal file
View File

@ -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%;
}

125
docs/website/upload.php Normal file
View File

@ -0,0 +1,125 @@
<?php
/*
* Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
*
* 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);
?>

165
docs/website/users.html Normal file
View File

@ -0,0 +1,165 @@
<!DOCTYPE html>
<!-- Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
Licensed under the GNU General Public License Version 2 -->
<html>
<head>
<title>fwupd: Firmware Update Daemon</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,300' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="style.css" type="text/css" media="screen"/>
<link rel="shortcut icon" href="favicon.ico"/>
<script src="https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js"></script>
</head>
<body>
<h1 class="banner">fwupd: Firmware<br> Update Daemon</h1>
<h1>Introduction</h1>
<p>
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.
</p>
<h2>Using GNOME Software</h2>
<p>
New versions of GNOME Software will show and auto-download pending updates automatically:
</p>
<a href="img/gnome-software1.png"><img alt="gnome-software updates panel" src="img/gnome-software1-thumb.png"/></a>
<p>
Double clicking on the <code>cab</code> file is also supported:
</p>
<a href="img/gnome-software2.png"><img alt="gnome-software updates panel" src="img/gnome-software2-thumb.png"/></a>
<h2>Using the command line</h2>
<p>
fwupd ships a command line <code>fwupdmgr</code> program.
This allows administrators to get the list of upgradable devices,
schedule offline updates or installing firmware on the live system.
</p>
<pre class="prettyprint">
$ 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
</pre>
<p>
You can see all the command line options using <code>--help</code>:
</p>
<pre class="prettyprint">
$ 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
</pre>
<h2>Using the D-Bus API</h2>
<p>
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.
</p>
<a href="img/dbus.png"><img alt="d-feet screenshot" src="img/dbus.png"/></a>
<pre class="prettyprint">
$ $ 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': <uint64 0>},
'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': <uint64 0>},
'CHug-usb:00:01:04:04':
{'Guid': <'84f40464-9272-4ef7-9399-cd95f12da696'>,
'DisplayName': <'ColorHugALS'>,
'Provider': <'ColorHug'>,
'Version': <'4.0.0'>,
'Flags': <uint64 6>}},)
</pre>
<h2>Security</h2>
<p>
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.
</p>
<p>
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.
</p>
<h2>User Interaction</h2>
<p>
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.
</p>
<p><a href="index.html">Go back to the main page</a></p>
<p class="footer">
Copyright <a href="mailto:richard@hughsie.com">Richard Hughes 2015</a>
</p>
</body>
</html>

198
docs/website/vendors.html Normal file
View File

@ -0,0 +1,198 @@
<!DOCTYPE html>
<!-- Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
Licensed under the GNU General Public License Version 2 -->
<html>
<head>
<title>Linux Vendor Firmware Service</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,300' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="style.css" type="text/css" media="screen"/>
<link rel="shortcut icon" href="favicon.ico"/>
<script src="https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js"></script>
</head>
<body>
<h1 class="banner">Linux Vendor<br>Firmware Service</h1>
<h1>Introduction</h1>
<p>
This page provides a place for hardware vendors to submit packaged
firmware updates, typically <code>cab</code> files.
This <em>fire-and-forget</em> service allows vendors to submit firmware updates
without generating and hosting metadata themselves.
</p>
<p>
Clients such as <a href="https://github.com/hughsie/fwupd/blob/master/README.md">fwupd</a>
periodically check for updated metadata at this site and will offer the firmware
to end users or be installed automatically depending on site policy.
</p>
<p>
NOTE: This service should only be used to distribute firmware that is
<em>flashed</em> onto non-volatile memory.
It is not designed for firmware that has to be uploaded to devices every time
the device is used.
</p>
<p>
There is no charge to vendors for the hosting or distribution of content.
</p>
<p>When files are submitted the following actions are performed:</p>
<ol>
<li>The update metadata is <a href="https://github.com/hughsie/fwupd/blob/master/README.md#what-do-i-have-to-do">checked for correctness</a>.</li>
<li>The firmware capsule is signed with <a href="mooo">our GPG key</a>.</li>
<li>The new <code>cab</code> file is moved to <a href="dump.php">our infrastructure</a>.</li>
<li>The metadata is added to <a href="downloads/firmware.xml.gz">our database</a>.</li>
</ol>
<h1>Upload Firmware</h1>
<p>
<b>It is imperative that updates have been verified to work correctly on
all matching hardware.</b>
</p>
<h2>Legal</h2>
<p>By uploading a firmware file you must agree that:</p>
<ul>
<li>You are legally permitted to submit the firmware.</li>
<li>The submitted firmware file is permitted to be mirrored by our site.</li>
<li>The firmware installation must complete without requiring user input.</li>
<li>Firmware must not engage in malicious activity (e.g. be viruses, worms, or exploit security issues).</li>
<li>Firmware can only be removed from this archive in exceptional cases.</li>
</ul>
<form action="upload.php" method="post" enctype="multipart/form-data">
<table class="upload">
<tr>
<th width="150px">Vendor Key:</th>
<td><input type="text" id="auth" name="auth" placeholder="5be94d63-58d2-410e-bc49-eecb22637a8e" required size="36"/></td>
</tr>
<tr><th width="150px">Contact Email:</th><td><input type="email" name="update_contact" required size="36"/></td></tr>
<tr><th width="150px">Firmware:</th><td><input type="file" name="file" required/></td></tr>
</table>
<input type="submit" class="submit" value="Upload"/>
</form>
<h1>Help With Submitting Firmware</h1>
<p>
If you are <b>not</b> 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.
</p>
<p>
As per the <a href="https://msdn.microsoft.com/en-us/library/windows/hardware/dn917810%28v=vs.85%29.aspx">Microsoft guidelines</a>
package up your firmware into a <code>cab</code> file, with these files inside:
</p>
<ul>
<li>The actual <code>cap</code> file your engineers have created</li>
<li>The <code>inf</code> file <a href="https://msdn.microsoft.com/en-us/library/windows/hardware/ff547402%28v=vs.85%29.aspx">describing the .cap file</a>.</li>
<li>The optional <code>asc</code> file which is a detached GPG signature of the firmware file.</li>
<li>The optional <code>metainfo.xml</code> file with <a href="http://www.freedesktop.org/software/appstream/docs/sect-Quickstart-Addons.html">a long description and extra metadata</a></li>
</ul>
<p>
You can create a <code>cab</code> file using <code>makecab.exe</code> on Windows and <code>gcab --create</code>
on Linux.
</p>
<p>
It is recommended you name the <code>cab</code> file with the hardware name and the version
number, e.g. <code>colorhug-als-1.2.3.cab</code>. It's mandatory that the files inside the
<code>cab</code> file have the same basename, for example this is would be valid:
</p>
<p>
<pre>
colorhug2-1.2.3.cab
|- firmware.inf
|- firmware.bin
|- firmware.bin.asc
\- firmware.metainfo.xml
</pre>
</p>
<p>
An example <code>inf</code> file looks like this:
</p>
<p>
<pre class="prettyprint lang-sh">
[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
</pre>
</p>
<p>
An example <code>metainfo.xml</code> file looks like this:
</p>
<p>
<pre class="prettyprint">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!-- Copyright 2015 Richard Hughes <richard@hughsie.com> --&gt;
&lt;component type="firmware"&gt;
&lt;id&gt;84f40464-9272-4ef7-9399-cd95f12da696&lt;/id&gt;
&lt;name&gt;ColorHugALS Firmware&lt;/name&gt;
&lt;summary&gt;Firmware for the ColorHugALS Ambient Light Sensor&lt;/summary&gt;
&lt;description&gt;
&lt;p&gt;
Updating the firmware on your ColorHugALS device improves performance and
adds new features.
&lt;/p&gt;
&lt;/description&gt;
&lt;url type="homepage"&gt;http://www.hughski.com/&lt;/url&gt;
&lt;metadata_license&gt;CC0-1.0&lt;/metadata_license&gt;
&lt;project_license&gt;GPL-2.0+&lt;/project_license&gt;
&lt;developer_name&gt;Hughski Limited&lt;/developer_name&gt;
&lt;releases&gt;
&lt;release version="3.0.2" timestamp="1424116753"&gt;
&lt;location&gt;http://www.hughski.com/downloads/colorhug-als/firmware/colorhug-als-3.0.2.cab&lt;/location&gt;
&lt;description&gt;
&lt;p&gt;This stable release fixes the following bugs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fix the return code from GetHardwareVersion&lt;/li&gt;
&lt;li&gt;Scale the output of TakeReadingRaw by the datasheet values&lt;/li&gt;
&lt;/ul&gt;
&lt;/description&gt;
&lt;/release&gt;
&lt;/releases&gt;
&lt;/component&gt;
</pre>
</p>
<p>
If the firmware is not free software you have to indicate it in the
<code>metainfo.xml</code> file with <code>&lt;project_license&gt;proprietary&lt;/project_license&gt;</code>.
</p>
<h2>Why does the LVFS project sign my firmware?</h2>
<p>
The Linux Vendor Firmware Project signs the firmware image and repacks
the files into a new cabinet file for several reasons:
</p>
<ul>
<li>Only trusted vendors have access to the LVFS service, so we can be sure the firmware actually came from the vendor</li>
<li>Clients do not (yet) verify the signatures in the <code>cat</code> file</li>
<li>Not all software trusts the Microsoft WHQL certificate</li>
<li>We ensure that only required files are included in the cabinet file, typically making the download size much smaller</li>
</ul>
<h2>Validation</h2>
<p>
The best way to validate the metainfo file or firmware before submission is by using the
<code>appstream-util validate</code> tool available from the
<a href="https://github.com/hughsie/appstream-glib">appstream-glib</a> project.
</p>
<p><a href="index.html">Go back to the main page</a></p>
<p class="footer">
Copyright <a href="mailto:richard@hughsie.com">Richard Hughes 2015</a>
</p>
</body>
</html>