RSS: Blog | Wiki | Forum

Easypackage

Un article de Easyneuf.

Notice : Page en cours d'écriture

Sommaire

[modifier] Concept

Le but de Easypackage est de permettre d'ajouter facilement des programmes au système d'exploitation (Easygate ou Opengate)

[modifier] Proposition

Pour faciliter la manipulation, on doit avoir la correspondance "1 programme = 1 fichier"

Le fichier contiendra toutes les données nécessaires au bon fonctionnement (idéalement, il ne devra dépendre d'aucun fichier particulier sur le système)

Le package devra être utilisable par un enfant ou toute personne sans avoir besoin d'être administrateur de la machine.

Télécharger le fichier, double cliquer dessus doit suffire pour l'exécuter.

Supprimer le fichier doit suffire pour le supprimer du système.

Une copie du fichier (par une clé USB par exemple) doit être suffisant pour pouvoir exécuter le programme sur une autre machine.

En option: - proposer un outil d'administration pour mettre à jour les programmes déjà téléchargé. - modifier 9panel pour afficher les nouveaux programmes.

[modifier] Avantages du système

1 programme == 1 fichier - pas dépendance à gérer - un seul fichier à télécharger pour l'utilisateur - ne pas avoir à gérer un (nouveau, nième) système de packages, dépendances, conflits ... - ne pas vouloir recréer une nouvelle distribution linux ... - permet de faire tester certains programmes à une clientèle donnée - avoir un retour sur le nombre d'utilisation du programme


[modifier] Désavantages

- Ne peut pas convenir a tous les programmes: daemons, petits programmes, utilitaires - Taille importante lors de petits programmes (+~5Mo) - Redondance des librairies dans le cas de plusieurs paquets - problème de sécurité (l'utilisateur peut exécuter des programmes qui n'étaient pas prévus) - problème de sécurité lors de faille sécurité.

[modifier] Implémentation (Proof of concept)

- Inspiration des projets existants :

==> autopackage (installation sur le système, nous sommes en read only)

==> klick (wrapper utilisant perl, python, et pas mal de librairies LSB ...) Projet intéressant dans la version 2 avec le module fuse. Les packages partent de la distribution Debian. informations en français

==> glick. Un projet similaire à klick mais utilisant fuse+ext2. A terme, le notre devra faire la même chose mais fuse+squashfs. Inconvénient : demande que les programmes aient été compilés avec --prefix=/proc/self/fd/xxx . Très bonne idée d'inclure l'image dans un binaire elf. Problème : les fichiers sur nos clefs USB ne sont pas exécutables. Possibilité de l'intégrer au buildroot, en changeant le préfixe de compilation.

==> système java (webstart & .jnlp)


- Ecriture from scratch binaire 12Ko (sur x86 + libcryto en .so) source 21ko buildroot/packages/9system/source/easypackage_helper.c

- Utilisation d'une clef RSA pour authentifier les packages. La liste des clefs reconnues sera mise dans le programme de lancement ou dans un fichier sur le système si le loader est inclus à l'archive. Le programme assume que toutes les clefs privées fassent la même taille (2048bits).

- Le format du fichier est une image squashfs. Il sera donc utilisable nativement par Linux. Un module fuse est envisagé pour éviter de mettre le loader suid root. La création du fichier se fera à l'aide de mksquashfs sans avoir besoin des droits de root.

- Le programme tourne dans un environnement chroot. Doit résoudre les problèmes de librairies c++. Meilleure sécurité du système. Quelques chemins du système original sont dupliqués dans l'environnement. (En réalité presque la totalité du système est disponible FIXME)

- Le système de package est aussi du readonly ... pas d'altération possible du programme.

- implémentation utilisant un loader suid root (pour pouvoir faire le chroot et monter le système de fichier).

- intégré au système de build existant, cible xxx-pkg (Exemple: make pingus-pkg)

- Modification de la liste des mimetypes (mime-share-info) pour ajouter notre format de package. Ainsi pcmanfm et les autres applications le reconnaissent immédiatement.

- Modification du kernel (via bin-misc.ko) pour exécuter automatiquement ce type de fichier binaire même si on reste en ligne de commande shell.

[modifier] Méthode rapide pour créer un paquet

Voir les pingus.mk, wormux.mk, gcompris.mk ... pour voir l'implémentation dans le 9buildroot

- Créer un répertoire ROOT. Tous les fichiers de l'image seront copiés dedans

- Créer le système de fichier minimum pour effectuer le chroot, les points de montages, ...

 for d in bin lib proc tmp dev etc sys .oldroot home usr/share/alsa usr/lib/dri; do \
   mkdir -p $(ROOT)/$$d; \
 done


- Copier tous les fichiers du système, généralement :

 make install DESTDIR=$(ROOT)


- Copier les libraries systèmes et toutes les libraries dont dépendent le programme

 install -m 755 $(TARGET_DIR)/bin/sh $(ROOT)/bin
 install -m 755 $(TARGET_DIR)/lib/ld-linux.so.2 $(ROOT)/lib/ld-linux.so.2
 install -m 644 $(TARGET_DIR)/lib/libcrypt.so.1 $(ROOT)/lib/
 install -m 644 $(TARGET_DIR)/lib/libc.so.6 $(ROOT)/lib/
 install -m 644 $(TARGET_DIR)/lib/librt.so.1 $(ROOT)/lib/ 
 install -m 644 $(TARGET_DIR)/lib/libdl.so.2 $(ROOT)/lib/
 install -m 644 $(TARGET_DIR)/lib/libgcc_s.so.1 $(ROOT)/lib/
 install -m 644 $(TARGET_DIR)/lib/libpthread.so.0 $(ROOT)/lib/
 install -m 644 $(TARGET_DIR)/lib/libstdc++.so.6 $(ROOT)/lib/
 install -m 644 $(TARGET_DIR)/lib/libresolv.so.2 $(ROOT)/lib/


- Copier les librairies du programme

 cp -a $(STAGING_DIR)/usr/lib/libSDL* $(ROOT)/lib
 cp -a $(STAGING_DIR)/usr/lib/libxml* $(ROOT)/lib
 cp -a $(STAGING_DIR)/usr/lib/libglib* $(ROOT)/lib
 cp -a $(STAGING_DIR)/usr/lib/libgobject* $(ROOT)/lib
 cp -a $(STAGING_DIR)/usr/lib/libsigc* $(ROOT)/lib
 cp -a $(STAGING_DIR)/usr/lib/libcurl* $(ROOT)/lib
 cp -a $(STAGING_DIR)/usr/lib/libssl* $(ROOT)/lib
 cp -a $(STAGING_DIR)/usr/lib/libcrypto* $(ROOT)/lib
 cp -a $(STAGING_DIR)/usr/lib/libpng* $(ROOT)/lib


- Créer le fichier de démarrage /init (exemple pour wormux)

 cat >> $(ROOT)/init <<__EOF
 #!/bin/sh
 /lib/ld-linux.so.2 /bin/wormux
 __EOF


- Rendre le script exécutable, et stripper les binaires

 chmod 755 $(ROOT)/init
 strip $(ROOT)/lib/* $(ROOT)/usr/lib


- Créer l'archive :

 mksquashfs $(ROOT) wormux-1.0.0.easypkg -noappend -all-root


- Signer le fichier généré :

 openssl dgst -sha512 -sign your_easygate.key -out wormux-1.0.0.easypkg.digest wormux-1.0.0.easypkg
 cat wormux-1.0.0.easypkg.digest >> wormux-1.0.0.easypkg


- Et le fichier sera reconnu par easypackage_helper

Méthode pour créer sa clef RSA :

 # Generate the key
 openssl genrsa -des3 -out your_easygate.key 2048
 # Export the public key
 openssl rsa -in your_easygate.key -pubout -out your_easygate.crt


Ajouter au format texte votre .crt dans le programme easygate_helper.c

     static const char *public_keys[] =
     {

/* Public key for easygate package (rsa 2048 bits) */ "-----BEGIN PUBLIC KEY-----\n" "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAswb6CdaN1B++FWj6/drW\n" "1BNxKtkmUqynsN68v83YqwvFCDHg099xN4HS7TNoM1m9POfuc+WTOH4/7zvfvgL3\n" "9TmDrljAV6iiGV0JXii7ST+i2NSmELOe69mDNMnS16JBnATgVmvmoM1KlSPnKkPC\n" "RAj+PwRKrCuD425tkDjLDr1tTC5ZdXvlOzrf6ZYbh1Rv3/bnUGqh+foCBJZ97FHy\n" "MenR9Ypjs3LdcRsBqgC5Z98xH6KyR1FJzeMViT9vNbcEZ1QhO7fCBfK4atAKzak4\n" "gPrMAHEoQoSQgSmA+xOjejihWL3UR6rBjPvQSC2TeWWTzbFWeyPGSaB1hreXxnFq\n" "qwIDAQAB\n" "-----END PUBLIC KEY-----\n", /* Add here other keys you want to accept, but all key need to * have the same size */ NULL

     };


qui devient :

     static const char *public_keys[] =
     {

/* Public key for easygate package (rsa 2048 bits) */ "-----BEGIN PUBLIC KEY-----\n" "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAswb6CdaN1B++FWj6/drW\n" "1BNxKtkmUqynsN68v83YqwvFCDHg099xN4HS7TNoM1m9POfuc+WTOH4/7zvfvgL3\n" "9TmDrljAV6iiGV0JXii7ST+i2NSmELOe69mDNMnS16JBnATgVmvmoM1KlSPnKkPC\n" "RAj+PwRKrCuD425tkDjLDr1tTC5ZdXvlOzrf6ZYbh1Rv3/bnUGqh+foCBJZ97FHy\n" "MenR9Ypjs3LdcRsBqgC5Z98xH6KyR1FJzeMViT9vNbcEZ1QhO7fCBfK4atAKzak4\n" "gPrMAHEoQoSQgSmA+xOjejihWL3UR6rBjPvQSC2TeWWTzbFWeyPGSaB1hreXxnFq\n" "qwIDAQAB\n" "-----END PUBLIC KEY-----\n", /* La nouvelle clef de xxxx yyyyy <xxxx.yyyy@toto.com> */ "-----BEGIN PUBLIC KEY-----\n" "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvZcgPTLt6O66+Tq/gVDJ\n" "C8lXyNJB1Xza83RTWzzOoHeQvsJFloylLA5XvGVDvgnpo3wFC6zwXcGvMZQCm3yx\n" "A4ZqxD+Cc1j7hwr2YAIK+VDPlte8OBZ0rSeRGdIsDEezoB5KNZeIFz5XEEfuRM1e\n" "cbaBbQui0DxDjSN44iAkkgKjnSbaM7gRFDCzKOrPLQBA4AydzcZaf4kQNeg1q/7E\n" "LDIeLNxex3SPcfnxYUPuOSLqTYmLhHQF9h3X8dDQV80Uq7UtFgvsgHJFzz24PVzK\n" "zBCopy1FZtNFJLPDC+Y4SznPjVBfnIBhIGbedGsBehTJzGftwLyvtH0rukdly4D5\n" "8wIDAQAB\n" "-----END PUBLIC KEY-----\n", NULL

     };

[modifier] Packages disponibles

Voir la page dédiée : liste des packages

[modifier] TODO

- Proposer une interface web pour télécharger les modules

- Utiliser fuse pour le loader (évitera les problèmes de root)

- Lire les clefs publiques depuis un fichier sur l'easygate

- Reporter les anomalies à l'utilisateur.

- Faire une prison (jail) solide) et dynamique sans devoir trop exporter du système de fichiers d'origine. ==> ne pas exporter tout /dev/ (uniquement input, sound pas les disques ...) ==> ne pas exporter tout /proc ... ==> /sys est-il utilisé par tous les programmes ?

- Proposer un format de méta-données que l'on puisse mettre dans le squashfs pour indiquer l'icône, le nom, ...

- Résoudre le problème des locales ... les jeux sont traduits mais setlocale() retourne une erreur. ==> problème à moitié fixé en copiant les libs gconv et locale-archive

- Si le binaire n'est pas signé, proposer une boite de dialogue à l'utilisateur pour lui demander son accord pour le lancement.