Home > Allgemeines, Open Source, Systemverwaltung, Web 2.0 > Eigene Firefox-Erweiterung für automatischen Update signieren

Eigene Firefox-Erweiterung für automatischen Update signieren

Ich habe uns bei system worx GmbH&Co. KG vor geraumer Zeit eine eigene Firefox-Extension gebastelt, um meinen Kollegen und unseren Partnern einen schnellen Zugriff auf wichtige Links und unsere webgestützen Tools und Prozesse zu geben.

Sieht dann in etwa so aus:

system work Firefox Toolbar

Meine Kollegen verlassen sich voll auf diese Toolbar und nutzen sie permanent für ihre tägliche Arbeit. Naturgemäß ändert sich des öfteren etwas am Inhalt dieser Extension. Es kommen neue Links dazu, alte fallen weg oder ändern sich. Man entwickelt sich ja permanent weiter, nicht wahr 😉 ?

Deshalb benötigen wir den automatischen Update-Mechanismus für Firefox-Addons, damit ich diese Extension zentral pflegen kann und meine Kollegen automatisch die dabei geänderten Versionen bekommen.

In diesem Artikel werde ich jetzt, auch als Notizzettel für mich ;-), die notwendigen Schritte aufzeigen, damit dieser Update-Mechanismus problemlos funktioniert.

Vorab : Ich gehe hier nicht auf die Entwicklung eines Firefox-Addons ein. Dazu gibt es Bücher, Anleitungen im Internet und Entwicklungsumgebungen (z.B. Eclipse), oder man kann mich dafür engagieren 😉 … Es geht hier rein um den Update-Mechanismus und die Sicherheitsvorkehrungen in Firefox, damit diese Updates sicher funktionieren.

Voraussetzungen und prinzipieller Mechanismus

Eine Firefox-Extensions ist ein sog. xpi-File. z.B. „myextension.xpi“ . Diese Datei liegt auf unserem Webserver und kann z.b. über die URL  http(s)://<myserver.mydomain.de>/myextension.xpi einfach und einmalig installiert werden. Das kennen ja die meisten von der Firefox-Addon-Site https://addons.mozilla.org/de/firefox/ mit den veröffentlichten vielen Erweiterungen. Macht wenig Sinn unsere spezifische interne Erweiterung dort anzubieten. Ich denke, das versteht sich von selbst ;-)…

Damit der automatische Update dann klappt, und Firefox bei einer neuen Version unserer Erweiterung diese automatisch installiert, benötigen wir an der gleichen Stelle noch ein sog. Update-Manifest. Dabei handelt es sich um ein XML-File mit einer definierten Struktur und Inhalten, passend zu unserem xpi-File. Der Name ist egal. Muss nur im Install-Manifest in der Extension selbst stehen.

Das Update-Manifest (rdf-Datei) sieht dann ungefähr so aus (keine sinnvollen Daten hier ;-)…) :

<?xml version=“1.0″?>
<RDF:RDF xmlns:em=“http://www.mozilla.org/2004/em-rdf#“
xmlns:NC=“http://home.netscape.com/NC-rdf#“
xmlns:RDF=“http://www.w3.org/1999/02/22-rdf-syntax-ns#“>
<RDF:Description RDF:about=“rdf:#$Zwl281″
em:version=“1.46″>
<em:targetApplication RDF:resource=“rdf:#$0xl281″/>
</RDF:Description>
<RDF:Description RDF:about=“urn:mozilla:extension:myextension@mydomain.de“
em:signature=“MIGTMACGBqGSIb3DQEBDQUVA4GBAJSrhvDWzS37u+4XcYK7M8CoBEW29jX/8pQ1JQZ8B/0xliWas7luLPyuPRtJQtWb1EGQ986BfCQfFHPyqQsm5RjKhDO9ESGUEAcgIjOeg1BPRC1NqZi8kixY8fxbb5gk9HLAHNTdFnSnMx4N+AtBSe9luCGXbbgvy/f9F7mGVd6Z“>
<em:updates RDF:resource=“rdf:#$Ywl281″/>
</RDF:Description>
<RDF:Seq RDF:about=“rdf:#$Ywl281″>
<RDF:li RDF:resource=“rdf:#$Zwl281″/>
</RDF:Seq>
<RDF:Description RDF:about=“rdf:#$0xl281″
em:id=“{ec8030f7-c20b-464e-9b0d-13a3a9e97384}“
em:minVersion=“1.5″
em:maxVersion=“3.*“
em:updateLink=“http://myserver.mydomain.de/myextension.xpi“
em:updateHash=“sha1:9b01cee0811c76d9540c7306c1fdedbfd9170346″ />
</RDF:RDF>

Ganz schön wirr, nicht wahr ;-). Ist aber beherrschbar. Siehe Dokumentationen und Bücher. So einige Kleinigkeiten beschreibe ich aber nachstehend.

Nun benötigen wir noch 2 Tools

1) Ein Tool um diese lange „em:signature=“-Zeichenkette zu erzeugen (im Install-Manifest wird eine ähnlich wirre lange Zeichenkette benötigt, die zu dieser Signature passt :  „em:updateKey=“.  Für die Fachleute : Es handelt sich hier um ein public/private RSA cryptographic key pair)

2) Ein anderes Tool, mit dem wir den Update-Hash erzeugen (em:updateHash=“sha1:9b0……)

Für (1) nehmen wir ein frei verfügbares Programm namens McCoy (was für Trekkies 😉 …).

Für (2) verwende ich „md5deep„. Gibt aber noch andere Möglichkeiten. Hier beschreibe ich den md5deep-Weg.

Vorgang der Erzeugung eines signierten Addons und des Update-Manifests

1. Wir haben unser fertiges lokal getestetes Firefox-Addon mit einem korrekten install.rdf.

Dann rufen wir unseren McCoy auf:

sh>../mccoy/mccoy

Zuerst werden wir nach unserem Master-Passwort gefragt (mussten wir beim allerersten Aufruf des Teils angeben)

McCoy Master Password

Danach haben wir die Möglichkeit unseren updateKey (s.u.) zu erzeugen und sofort ins install.rdf zu schreiben:

updatekey install.rdf

Bei „sx RSA“ handelt es sich um unsere einmalig erzeugtes (über Menüpunkt „keys“) public/private RSA cryptographic key pair. Wir müssen das Ding später hier einfach nus auswählen/selektieren.

Wie oben gezeigt, klicken wird dann auf den Knopf „Install“ und müssen dann über den üblichen Datei-Auswahl-Dialog unser install.rdf finden und anklicken. Fertig mit Schritt 1 🙂

2. Erzeugung des xpi und des Update-Hashs

Das xpi ist ein gepacktes File mit enthaltenen jar-Files. Ich benutze dafür dieses Script hier :  http://kb.mozillazine.org/Bash_build_script

So nun haben wir ein xpi rumliegen. Wir benötigen jetzt noch das passende signierte Update-RDF-File mit dem richtigen Update-Hash.

Erzeugung des Update-Hashs:

sh> ../md5deep/sha1deep myextension.xpi

Wir wollen also einen SH1-Hash erzeugen.

Ausgabe ist dann so etwas :

9cd1cff0800b75d9541b7306c1fdddbfd9170445 /…./myextension.xpi

Dieser lange fette String ist unser Hash, den wir in unser Update-RDF kopieren müssen (siehe oben) :  em:updateHash=“sha1:9cd1cff0800b75d9541b7306c1fdddbfd9170445“ />

Ja und jetzt benötigen wir wieder unseren McCoy:

Signieren update rdf

Gleiche Spiel wie vorher :  Update-RDF suchen und anklicken …

Das war es !

Jetzt können wir das xpi-File und unsere signiertes update.rdf auf den Server kopieren und alle, die unsere Extension installiert haben, bekommen automatisch die neue Version installiert.

Kein Problem, wenn man das Verfahren kennt, nicht wahr 😉 …

Ach ja : Dieses Verfahren funktioniert auch, wenn man KEINEN SSL-Server (https) mit gültigem gekauften Zertifikat hat. Klappt auch mit einfachem unverschlüsselten http !