Lowlight.fr

Il est maintenant temps de s'affranchir de ces limites et de ces restrictions, et de s'élever à un niveau supérieur...

The ghost in the shell
Masamune Shirow

Les systèmes de fichiers

Les **systèmes de fichiers**, ou **FS** °(File System)° servent à stocker et organiser des données tout en exploitant au maximum l'espace disponible. De nombreuses normes existent (ext, FAT, NTFS, etc.) mais toutes reposent généralement tous sur le même principe.

Cet article consiste en une **présentation** du système de fichier lowlighter/file-system (documentation) que j'ai réalisé, d'une **explication** sur la structure du FS et de sa conception, ainsi que sur la **protection** des données.

Démonstration

Afin de mieux appréhender la suite de l'article, je vous invite à intéragir avec l'**interface** °(à droite)°, qui permet de manipuler l'**image disque** °(à gauche)°.

Lisez la section **A propos** située ci-dessous pour de plus amples informations sur l'utilisation de cette démonstration.

Le fonctionnement de l'**image disque** sera expliqué un peu plus tard, mais sachez que l'interface ne manipule **que** des données présentes sur l'image °(en dehors des applications et du code JavaScript permettant de faire fonctionner le système)°.

C'est-à-dire que tout le contenu affiché par l'**explorateur** de fichiers est disponible sur l'image, que ce soit des fichiers textes, images ou audio. Il vaut en réalité voir l'image disque comme une sort de gigantesque **QR-Code**.

Par défaut une dizaine de fichiers et dossiers sont disponibles pour vous montrer toute l'étendue du programme. Voici une liste °(non exhaustive)° des actions que vous pourriez tester :

  • Ouvrir le dossier **/home**
  • Ouvrir les fichiers multimédias
  • Editer les fichiers textes
  • Créer un nouveau fichier ou dossier
  • Exécuter le script **/home/demo.cmd**
  • Crypter l'image
  • Ouvrir un terminal et tapez la commande "**tree /**" pour afficher l'arborescence complète de l'image

Les fichiers multimédias ont été encodés en Base 64 avant d'être enregistrés sur l'image. Il est déconseillé de les ouvrir en tant que fichier texte car cela pourrait ralentir votre navigateur.

Vous pouvez enregistrer l'image puis la téléverser de nouveau en cliquant sur l'icône **Charger image** pour retrouver toutes vos données.

L'interface graphique permet de facilement naviguer à travers le contenu de l'image disque et prodigue confort et ergonomie à l'utilisateur. Seuls deux commandes sont à retenir :

  • **Clic gauche** sur une icône pour lancer l'application correspondante ou pour ouvrir un fichier ou un dossier
  • **Clic droit** °(hors bureau)° pour afficher le menu contextuel

L'invité de commande procure un usage plus pragmatique, destiné aux utilisateurs plus expérimentés et permet d'exploiter au mieux les possibilités du programme.

Un **clic gauche** sur l'icône **Terminal** permet d'ouvrir un nouvel invité de commande. Vous pouvez ensuite saisir l'une des commandes ci-dessous.

Applications
**help** [command=help] Affiche de l'aide sur une commande
**explorer** [path=pwd] Ouvre une nouvelle instance de l'explorateur de fichiers
**terminal** Ouvre une nouvelle instance de l'invité de commande
Gestion des entrées
**rm** <path> [-r] Supprime une entrée (ajouter **-r** pour supprimer récursivement un dossier)
**mv** <path> <target> Déplace une entrée à l'endroit indiqué (ajouter -f pour spécifier un dossier)
**stat** <path> Affiche les propriétés d'une entrée (ajouter -f pour spécifier un dossier)
**chmod** <path> [-r|+r] [-w|+w] [-x|+x] [-d|+d] [-R|+R] [-W|+W] [-X|+X] [-D|+D] [-f] Modifie les permissions d'une entrée (ajouter **+r**, **+w**, **+x**, **+d** pour ajouter les droits de lecture, d'écriture, d'exécution et de suppression et **-r**, **-w**, **-x**, **-d** pour les supprimer. En miniscules pour le propriétaire et en majuscules pour les autres. Ajouter -f pour spécifier un dossier)
**chown** <path> <user> [-f] Modifie le propriétaire d'une entrée (ajouter -f pour spécifier un dossier)
Gestion des dossiers
**cd** [path=/home] Change de répertoire courant
**mkdir** <path> Crée un nouveau répertoire
**ls** [path=pwd] [-a] [-l] [-type=ALL|FOLDER|FILE] Liste les entrées du répertoire (ajouter **-a** pour lister les entrées cachées, **-l** pour afficher les propriétés de chaque entrée et **-type** pour filter les types d'entrées)
**tree** [path=pwd] [-a] Affiche l'arborescence en partant du répertoire spécifié (ajouter **-a** pour lister les entrées cachées)
Gestion des fichiers
**mkfile** <path> Crée un nouveau fichier
**edit** <path> Ouvre un fichier en tant qu'élément texte
**display** <path> Ouvre un fichier en tant qu'image
**play** <path> Ouvre un fichier en tant qu'élément audio
**exec** <path> Ouvre un fichier en tant que fichier script (la valeur du contexte est l'instance GUI)
Gestion des utilisateurs et des sessions
**su** <user> <password> Connexion avec un autre compte utilisateur
**adduser** <user> [password] Crée un nouveau compte utilisateur
**deluser** <user> <password> Supprime un compte utilisateur
**users** Affiche la liste des utilisateurs enregistrés
**whoami** Affiche le nom de l'utilisateur connecté
Cryptage de l'image
**encrypt** <key> Encrypte les données de l'image
**decrypt** <key> Décrypte les données de l'image
Système
**pwd** Affiche le chemin du répertoire courant
**env** Affiche les variables d'environnement système
**dstat** Affiche les propriétés du disque
Gestion des images disques
**dload** Lance l'utilitaire de chargement d'image disque
**dformat** [-size=400x400] [-table-size=512] [-block-size=256] [-entry-name-length=8|16|24|32] [-table-extended=y|n] Crée une nouvelle image (cela relancera l'interface après création) où :
  • **-size** est la taille de l'image (NB : cela modifie également la taille du canvas !)
  • **-table-size** est le nombre d'entrées maximum
  • **-block-size** est la taille unitaire d'un bloc de contenu
et
  • **-entry-name-length** est le nombre d'octets réservés aux nom de chaque entrée
  • **-table-extended** active la table étendue (ajoute les dates de création et d'édition, et les permissions pour chaque entrée)

Avec quelques notions de JavaScript, il est également possible d'ouvrir la **console web** afin d'intéragir directement avec le code. Tapez la ligne suivante pour créer un alias :


    let interface = Lowlight.FileSystem.Interface.LAST_INSTANCE
                    

Chaque accès en mémoire est synchronisé avec le **canvas**, ce qui signifie que modifier le canvas modifiera indirectement l'image, bien que la méthode **Image.write** ne soit pas appelé. Pour cette même raison, il est conseillé de désactiver la synchronisation lorsque vous effectuez de multiples opérations d'écriture.


    let image = interface.image
    image.sync(false)
    for (let i = 100; i < 300; i++) { image.write(0b11111111) }
    image.sync(true)
                    

Il est conseillé de consulter la **documentation** au préalable.

Système de fichiers : Une image structurée

L'**image disque** est consistituée d'une succession d'octets, ce qui a été représenté ci-dessus sous la forme d'une image. Chaque pixel représente donc les valeurs de 3 octets successifs, stockés dans les composantes Rouge, Verte et Bleue °(la composante Alpha étant ignorée)°. Les pixels noirs représentent par conséquent l'espace vierge.

Les systèmes de fichiers peuvent généralement être découpé en **trois** grandes parties :

L'en-tête

L'en-tête contient les **informations générales** sur l'image disque. On y trouve généralement la taille totale de l'image, son nom, le système de fichiers utilisé, etc. Cela permettra par la suite de mettre en place des méthodes pour manipuler les données présentes sur celle-ci.

Nomenclature utilisée pour l'en-tête des images présentes sur cette page.
BitsNOMDescription
4SIGNATURESignature, variant selon le type de disque °(12 ou 13)°
2ENTRY_NAMEEspace alloué °(en octets)° aux noms des entrées °(8, 16, 24 ou 32)°
1CRYPTEDIndique si les données de l'image sont cryptées ou non
1TABLE_EXTENDEDAjoute les dates de création et d'édition ainsi que les permissions aux entrées de la table d'allocation °(15 octets au lieu de 6 seront utilisés, en plus de l'espace alloué aux noms)°
24SIZETaille totale du disque
16TABLE_SIZENombre d'entrées dans la table d'allocation
16BLOCK_SIZETaille unitaire d'un bloc °(en octets)°

La table d'allocation

Celle-ci **répertorie** les différentes entrées (fichiers et dossiers) présentes sur le disque et contient généralement des métadonnées sur celles-ci, tel que les droits d'accès, leur propriétaire, les dates de dernier accès, etc. Sur la plupart des FS, on en compte au minimum 2, ce qui permet de réduire les temps d'accès mémoire en diminuant la complexité spatiale.

Lorsque la table est complète, il n'est plus possible de créer de nouvelles entrées, même s'il reste encore de l'espace disponible. En revanche, une table d'allocation trop grande réduit l'espace réservé aux blocs de contenu, qui peut en résulter en l'incapacité d'écrire du contenu dans les fichiers bien qu'il soit toujours possible d'en créer de nouveaux.

Nomenclature utilisée pour les entrées des images présentes sur cette page.
BitsNOMDescription
1TYPEType d'entrée °(fichier ou dossier)°
1VISIBILITYVisibilité de l'entrée °(visible ou cachée)°
6OWNERIdentifiant du propriétaire
16PARENTPointeur vers le dossier parent °(0 (root) et 65535 (null) sont des valeurs réservées)°
20BLOCKPointeur vers le premier bloc de contenu
34CREATIONDate de création de l'entrée °(année, mois, jour, heures, minutes et secondes)°
34EDITIONDate de la dernière modification de l'entrée °(année, mois, jour, heures, minutes et secondes)°
8PERMISIONSDroits de lecture, d'écriture, d'exécution et de suppressions °(propriétaire et autres utilisateurs)°
XNAMENom du fichier

Les clusters

Ces derniers permettent de **stocker** le contenu des entrées, et fonctionnent sur le principe d'une liste chaînée. Chaque bloc pointe vers le suivant, et en partant du premier qui est stockée dans l'une des entrées de la table d'allocation, on peut reconstituer le contenu de celle-ci.

Les blocs de contenus possèdent généralement une taille fixe et sont insécables. Cela signifie qu'il important de choisir judicieusement la taille unitaire d'un bloc. Lorsque celle-ci est grande, cela favorise les pertes d'espace, tandis qu'une taille trop petite encourage la fragmentation des données de l'image, ce qui ralentit les accès mémoires.

Nomenclature utilisée pour les blocs des images présentes sur cette page.
BitsNOMDescription
2(RESERVED)°Inutilisé°
1USEDIndique si le bloc est utilisé par l'une des entrées de l'image
1ENDIndique s'il s'agit du dernier bloc de contenu de l'une des entrées de l'image
20NEXTPointeur vers le bloc de contenu suivant

Les données de l'image sont-elles protégées ?

Les permissions ne sont gérées que par l'interface, ce qui signifie qu'un accès mémoire direct permet de lire les données de l'image disque sans aucune contrainte.

La **stéganographie** permet de dissimuler les données de l'image disque mais ne les protège pas directement. Toutefois, cela reste un rempart contre la plupart des humains.

La **cryptographie** quant à elle permet de réellement protéger les données en les rendant illisibles si on ne possède pas la **clé de cryptage**. Il y a cependant risque de **collision** °(en raison du hashage de la clé)°, ce qui pourrait sous certaines circonstances offrir l'accès aux données d'une image disque.

La suppression d'une entrée ne change pas l'image ?

Lorsqu'un fichier est **supprimé**, tous les blocs de contenus ne sont pas forcément remis à **0**. En effet, quelle que soit la valeur d'un bit, celui-ci occupera toujours la même place. Pour éviter des opérations d'écriture, le système modifie uniquement les bits indiquant si un espace est disponible ou non. Ainsi l'image ne change que très peu en apparence. C'est également pour cette même raison que lorsque vous supprimez des fichiers sur votre ordinateur, ceux-ci sont généralement récupérables partiellement °(voire totalement)° tant que vous n'avez pas réécrit trop de données. Pour supprimer totalement un fichier, il suffirait donc de mettre tous ses bits à 0 ou à 1.

Toutefois, peut-être avez-vous déjà entendu parler d'autres méthodes plus complexes sur l'effacement de données. En fait, certains disques physiques sont magnétiques °(ce qui n'est évidemment pas le cas d'une image **virtuelle**)°, et conservent une rémanence physique des données qui y ont été écrites. Ces méthodes permettent donc de rendre plus difficile la récupération des données.

Stéganographie : Une image peut en cacher une autre...

Puisqu'il est possible de stocker des données dans une image, il est également possible de **dissimuler** des données dans une image **déjà** existante : c'est ce qu'on appelle la **stéganographie**.

Cela implique cependant une lourde contrepartie pour ne pas trop déformer l'image originale. Il est nécessaire de n'utiliser que les **LSB** (bits de poids faibles) de chaque couleur, ce qui induit une baisse conséquente de l'espace de stockage disponible.

Sur l'image ci-dessous, de 0 à 7 bits ont été effacés pour illustrer ce processus de déformation.

Dans les images disques stéganographiées par le programme de cette page, seuls les deux derniers bits des composantes R, G et B ont été exploités, entrainant la perte de 75% en capacité d'écriture par rapport à la première image mais rendant par la même occasion très difficile de déceler la présence d'une image disque pour un simple humain.

Les méthodes de lecture et d'écriture ne sont pas tout à fait identiques avec celles de la précédente image. Afin de permettre à notre programme de faire la différence, il est nécessaire d'utiliser une **signature** différente.

Cryptographie : Protéger ses données

L'inconvénient de la technique ci-dessus est qu'elle ne fait que dissimuler les données et non les protéger. L'utilisation pour ce programme du format **UTF-8** °(qui étend la table ASCII dont les caractères sont généralement parmi les plus utilisés)° pourrait rapidement révéler la supercherie pour les plus aguerris.

En utilisant la **cryptographie** en complément, il devient extrêmement compliqué pour les personnes tierces d'accéder aux données stockées sur l'image puisque celles-ci sont cachées et illisibles, sans compter que le système de fichiers utilisé est peu répendu °(pour l'instant ?)°. De quoi éviter de se faire surprendre par la NSA.

Le cryptage est relativement simple. En utilisant un générateur pseudo-aléatoire **semé** à l'aide du hash de la clé fournie, chaque octet du disque °(sauf ceux les 4 premiers qui contiennent la signature et la taille totale ce qui pemet d'identifier l'image)° est décalé d'un nombre compris dans l'intervalle [0;255].

Comme le générateur produit toujours les mêmes nombres lorsqu'il est semé de la même façon, la clé permet de récupérer l'image originale en effectuant l'opération inverse. Ainsi en utilisant la clé de cryptage "**Kusanagi**" sur l'image disque de gauche, cela résulte en l'image de droite.