Sonntag, 29. Dezember 2013

Jolla - SailfishOS einfacher Konfigurationsspeicher für QtQuick/QML Apps

Die meisten Apps müssen Konfigurationsdaten wie Servernamen oder Benutzerpräferenzen speichern. Diese Daten sollten von jeder Stelle der App zugreifbar sein, um sich die Übergabe von langen Parameterlisten sparen zu können. Natürlich muss die Speicherung persistent erfolgen, so dass die Konfiguration nicht nach dem Beenden der Applikation verloren geht.

Mein Ansatz besteht aus einem kleinen Javascript, das in alle QML Dateien importiert werden kann und die Daten in einer Datenbank speichert.

Vor dem ersten Start muss der Platzhalter <your app name> durch den Namen der jeweiligen Applikation ersetzt werden.

Die Funktion intialize() muss beim start der App aufgerufen werden. Danach kann mit getSetting() und setSetting() ein Key/Value Pair in der DB gespeichert werden.

Javascript:

Qt.include("QtQuick.LocalStorage")

function getDatabase() {
     return LocalStorage.openDatabaseSync("<your app name>", "1.0",  

            "StorageDatabase", 100000);
}

function initialize() {
    var db = getDatabase();
    db.transaction(
        function(tx) {
            tx.executeSql('CREATE TABLE IF NOT EXISTS'+

                   ' settings(setting TEXT UNIQUE, value TEXT)');
      });
}


function setSetting(setting, value) {
   var db = getDatabase();
   var res = "";
   db.transaction(function(tx) {
        var rs = tx.executeSql('INSERT OR REPLACE INTO settings'+

                       ' VALUES (?,?);', [setting,value]);
        if (rs.rowsAffected > 0) {
            res = "OK";
        } else {
            res = "NOK";
        }
   });
   return res;
}

function getSetting(setting) {
   var db = getDatabase();
   var res="";
   db.transaction(function(tx) {
     var rs = tx.executeSql('SELECT value FROM settings WHERE'+

                        ' setting=?;', [setting]);
     if (rs.rows.length > 0) {
          res = rs.rows.item(0).value;
     } else {
         res = "";
     }
  });
  return res;
}


Ein dazu passender QML Preferences Dialog könnte dann so aussehen:
import QtQuick 2.0
import Sailfish.Silica 1.0
import QtQuick.LocalStorage 2.0
import "storage.js" as Storage


Dialog {
    id: preferencePage
    DialogHeader { title: "Save" }
    anchors.fill: parent

        TextField {
            y:200
            id:serverName
            width: parent.width
            label: "Server URL"
            placeholderText: "Enter Sever Name"
            focus: true
            horizontalAlignment: left
        }

        TextField {
            id:deviceId
            anchors.top:serverName.bottom
            width: parent.width
            label: "REMSY Device Name"
            placeholderText: "Enter Device Name"
            focus: true
            horizontalAlignment: left
        }


    Component.onCompleted: {
        Storage.initialize();
        serverName.text=Storage.getSetting("serverurl");
        deviceId.text=Storage.getSetting("deviceid");
    }
    onAccepted: {
        Storage.setSetting("serverurl", serverName.text)
        Storage.setSetting("deviceid", deviceId.text)
    }
}

 

Dienstag, 2. Juli 2013

ePass 2003 Token für OpenVPN Tunnel einrichten

Der französische Anbieter gooze bietet die kostengünstigen und Open Source kompatiblen Smartcard Systeme des chinesischen Herstellers Feitian an. Die Smartcards und Tokens sind vergleichsweise preiswert und enthalten nicht die üblichen Abos, NDAs und andere Hürden, die einem bei anderen Anbietern für einen einfachen Einsatz im Weg stehen.

Darüberhinaus ist die Lieferung relativ schnell, wenn die Smartcards nicht irritierenderweise beim Zoll festsitzen oder die Lieferung aus China sich verspätet.

Das Token ePass2003 ist ein USB-Stick mit integrierter Smartcard und  Kartenleser. Die Einrichtung des Tokens für die Verwendung mit opnevpn unter Mint 14 LMDE ist wird im Folgenden beschrieben.

Die aktuellen Debian Distributionen enthalten nicht die aktuellsten OpenSC Treiber. Auch wenn der Sicherheitsimpact abgewägt werden muss habe ich mich entscheiden das Repository von Gooze zu verwenden um passende und geprüfte OpenSC Pakete zu bekommen.

Um dies zu erreichen muss das Repository von Gooze der sources.list hinzugefügt werden. Da Mint 14 im Wesentlichen auf debian Wheezy basiert, wird das Wheezy Repo der sources.list hinzugefügt.

Als erstes müssen diese zwei Zeilen der Datei /etc/apt/sources.list hinzugefügt werden:

deb http://apt.gooze.eu/debian/ wheezy main
deb-src http://apt.gooze.eu/debian/ wheezy main 

Mit:

# wget -q "http://apt.gooze.eu/257FF7B2.asc" -O- | sudo apt-key add -

wird der Schlüssel für die Gooze Packages dem Keyring hinzugefügt.
Im Ordner /etc/apt/preferences.d/ die Datei gooze mit folgendem Inhalt anlegen:

Package: *
Pin: origin o=apt.gooze.eu
Pin-Priority: 1001 


Nach der Ausführung von apt-get update können alle notwendigen Pakete mit der Anweisung:

# apt-get install pcscd pcsc-tools libccid libpcsclite1 openvpn opensc/staging

installiert werden.

Das ePass2003 ist im Auslieferungszustand für die Feitian Windows-Treiber vorbereitet. Das verhindert die korrekte Erkennung unter Linux. Um das Token unter Linux "sichtbar" zu machen muss das Token neu initialisiert werden.

Während der Initialisierung werden die PIN und die PUK (SuperPIN) vereinbart, sowie ein Label, das verschiedene Programme bei der Nachfrage nach der PIN als Text verwenden.


$ pkcs15-init -E
$ pkcs15-init --create-pkcs15 --profile pkcs15+onepin \
    --use-default-transport-key --pin 123456 \
    --puk 7891011 --label "Peter Mustermann"


Ist die Initialisierung erfolgreich sollte die Anweisung:

$ pkcs15-tool --dump

ungefähr die folgende Ausgabe liefern.

PKCS#15 Card [Peter Mustermann]:
    Version        : 0
    Serial number  : 1234567890091101
    Manufacturer ID: EnterSafe
    Last update    : 20120630083313Z
    Flags          : EID compliant

PIN [User PIN]
    Object Flags   : [0x3], private, modifiable
    ID             : 01
    Flags          : [0x32], local, initialized, needs-padding
    Length         : min_len:4, max_len:16, stored_len:16
    Pad char       : 0x00
    Reference      : 1 (0x01)
    Type           : ascii-numeric
    Path           : 3f005015

...


Damit ist das Token betriebsbereit und kann mit Schlüsseln und Zertifikaten bespielt werden.

Wie man sich einen Schlüssel und ein Zertifikat für SSL erstellt ist erschöpfend im Netz beschrieben, weswegen ich diesen Punkt überspringe und davon ausgehe, das sich der Leser im Besitz einer gültigen PKCS#12 (.p12) Datei befindet.

Mit den Anweisungen:

$ openssl pkcs12 -in cert.p12 -clcerts -nokeys -out petercert.pem
$ openssl pkcs12 -in cert.p12 -cacerts -nokeys -out root.pem
$ openssl pkcs12 -in cert.p12 -nocerts -out peterkey.pem


werden die notwendigen Dateien aus der PKCS#12 Datei extrahiert.

Mit:

$ pkcs15-init --store-private-key peterkey.pem --auth-id 01 --pin 123456

wird der Schlüssel auf dem Token gespeichert. Während dieser Prozedur wird dem Schlüssel eine ID zugewiesen die ausgelesen werden muss, um das Zertifikat mit diesem Schlüssel zu assoziieren.

$ pkcs15-tool --list-keys

Listet alle Schlüssel des Tokens mit deren Ids:

Using reader with a card: Feitian ePass2003 00 00
Private RSA Key [Certificate]
    Object Flags   : [0x3], private, modifiable
    Usage          : [0x4], sign
    Access Flags   : [0xD], sensitive, alwaysSensitive, neverExtrac
    ModLength      : 2048
    Key ref        : 0 (0x0)
    Native         : yes
    Path           : 3f0050152900
    Auth ID        : 01
    ID             : 012347050ef750567872b7e7aa80539110b0e921
    GUID           : {0abc494d-2712-32dc-b64d-be218b23ce90}


Die ID muss beim Speichern des Zertifikates angegeben werde:

# pkcs15-init --store-certificate petercert.pem --auth-id 01 \
   --id  012347050ef750567872b7e7aa80539110b0e921 --format pem


Das Token ist jetzt vollständig eingerichtet.

Um das Token für openvpn nutzbar zu machen muss eine Client Konfiguration im Ordner /etc/openvpn angelegt werden. Openvpn erzeugt seine eigenen IDs mit denen es Schlüssel auf dem Token identifiziert. Diese ID wird mit:

# openvpn --show-pkcs11-ids /usr/lib/opensc-pkcs11.so

ausgelesen und sieht ungefähr so aus:

The following objects are available for use.
Each object shown below may be used as parameter to
--pkcs11-id option please remember to use single quote mark.

Certificate
       DN:             /C=DE/ST=Berlin/L=Berlin/O=Foobar GmbH/OU=FooSecurity/CN=Peter Mustermann
       Serial:         09
       Serialized id:  EnterSafe/PKCS\x2315/6257011116091101/Peter\x20Mustermann\x20\x28User\x20PIN\x29/0
012347050ef750567872b7e7aa80539110b0e9211


Der gelb markierte Hinweis ist unbedingt zu beachten, da ansonsten die \ Zeichen falsch interpretiert und das Zeritifkat nicht mehr zugeordnet werden kann.

Eine minimale /etc/openvpn/client.conf könnte dann so aussehen, wobei hierzu unbedingt die Dokumentation der OpenVPN Website konsultiert werden sollte.
Außerdem hängt der Inhalt der Datei von den Einstellungen ab, die auf der Serverseite durchgeführt worden sind. Für einen einfachen minimalen Test reicht das angegebene Beispiel in jedoch aus.

client
dev tun
proto udp
remote vpn.foobar.com
nobind
persist-key
persist-tun
ca /etc/openvpn/certs/foobar-ca.cert
pkcs11-providers /usr/lib/opensc-pkcs11.so
pkcs11-id '
EnterSafe/PKCS\x2315/6257011116091101/Peter\x20Mustermann\x20\x28User\x20PIN\x29/0012347050ef750567872b7e7aa80539110b0e9211'
comp-lzo


Mit der Anweisung:

# openvpn --config /etc/openvpn/vpn.sourcepark.biz --verb 2

beginnt der Aufbau der Tunnelverbindung. Sobald der Server kontaktiert wurde und der SSL Handshake begonnen hat wird die PIN abgefragt. Nach Eingabe der korrekten PIN wird die Tunnelverbindung etabliert und kann verwendet werden.

Das Erstellen der Zertifikate und die korrekte Verwendung verlangen etwas Übung. Sollte das Token nicht wie gewünscht arbeiten, kann man den Tunnel testweise nur mit den Zertifikaten aufbauen, und anschlie0end die geprüften Zertifkate auf das Token übertragen.

Eine OpenVPN Client Konfiguration, die mit der Zertifkats- und Schlüsseldatei arbeitet würde so aussehen:

client
dev tun
proto udp
remote vpn.foobar.com
nobind
persist-key
persist-tun
ca /etc/openvpn/certs/foobar-ca.cert
cert /etc/openvpn/certs/petercert.pem
key /etc/openvpn/private/peterkey.pem
comp-lzo

Kann mit dieser Konfiguration kein Tunnel etabliert werden liegt es an den Zertifikaten. Lässt sich mit der Angegebenen Konfiguration ein Tunnel aufbauen, arbeitet der Treiber oder das Token nicht korrekt.

Samstag, 27. April 2013

Sennheiser MM 450-X unter Mint 14 LMDE einbinden

Mit dem Bluetooth Headset unter Linux Musik hören ist leider immer noch ein wenig schwierig. Die meisten Headsets werden nach dem Pairing in der Ansicht der verfügbaren Audiohardware gelistet, aber das klappt leider nicht immer.
Für alle bei denen das nicht funktioniert hat, hier eine kurze Beschreibung wie ich mein Sennheiser MM 450-X Headset unter Mint 14 LMDE installiert habe.

Das Headset ließ sich nur mit dem Rechner verbinden, wenn man im Bluetoot Pairing Dialog den Typ auf "Alle Typen" stellt. Das Pairing ist problemlos und das Device erschient in der Liste der bekannten Geräte.

Als Wiedergabegerät lässt es sich jedoch noch nicht verwenden. Das Paket bluez-alsa muss installiert werden um Bluetooth Audio Geräte für Alsa verfügbar zu machen.

    apt-get install bluez-alsa

Damit das Headset auch unter einem bestimmten Namen als Gerät verwendet werden muss eine .asound Datei im Homeverzeichnis angelegt werden.

pcm.btheadset {
   type plug
   slave {
       pcm {
           type bluetooth
           device 00:16:94:0B:97:F6
           profile "auto"
       }  
   }  
   hint {
       show on
       description "Sennheiser MX-450"
   }  
}
ctl.btheadset {
  type bluetooth
}
 


Abmelden und wieder anmelden oder besser den Rechner neu starten.

Mit dem Kommando:

    mplayer -ao alsa:device=btheadset <Eine MP3 Datei>

kann geprüft werden, ob das Headset schon funktioniert.

Sollte kein Audio über das Headset wiedergegeben werden und die Ausgabe von mplayer ungefähr so aussehen:

Selected audio codec: [mpg123] afm: mpg123 (MPEG 1.0/2.0/2.5 layers I, II, III)
==========================================================================
bt_audio_service_open: connect() failed: Connection refused (111)
[AO_ALSA] Playback open error: Connection refused
Failed to initialize audio driver 'alsa:device=btheadset'
Could not open/initialize audio device -> no sound.
Audio: no sound
Video: no video


muss in die Datei /etc/bluetooth/audio.conf in der Sektion [General] die Zeile:

    Enable=Socket
 
hinzugefügt werden. Anschließend muss der Bluetooth Dienst mit /etc/init.d/bluetooth restart neu gestartet werden.

Ein erneuter Start des mplayers sollte jetzt die Tonwiedergabe über das Headset lenken.

Der letzte Schritt zu einer vollständigen Integration in den Desktop, ist die installation des pulseaudio bluetooth Moduls und von pavucontrol mit:

    apt-get install pulseaudio-module-bluetooth pavucontrol

Anschließend den pulsaudio Daemon mit  pulseaudio -k neu starten.
Unter Mint 14 LMDE hat das Bluetooth Tray Icon in meiner Installation einen Fehler. Wähle ich aus dem Pop-Up Menü des Try-Icons das Headset aus und wähle verbinden, wird keine Verbindung zum Headset hergestellt.
Wähle ich aus dem Pop-Up Menü den Menüpunkt Bluetooth Einstellungen und verbinde das Headset dort wird die Verbindung korrekt hergestellt.

Das Headset sollte jetzt als Audiohardware in pavucontrol angezeigt werden.


Sollte die Tonqualität an ein Handygespräch erinnern, muss im Konfigurations-Tab von pavucontrol das Profil A2DP ausgewählt werden.