Skip to content

Avash v0.9.0

Choose a tag to compare

@github-actions github-actions released this 05 Sep 10:23
· 13 commits to main since this release

Avash 0.9.0

  • Démarrage plus court : xterm.js chargé à part. Deux repères de mesure
    ont montré que l'exécution des modules au démarrage (303 ms de médiane)
    tenait presque entière dans la lecture et la compilation du paquet
    (283 ms), l'évaluation (13 ms) et l'initialisation d'avash (7 ms) n'y
    étant pour rien. xterm.js et ses extensions, la moitié du paquet, sont
    désormais chargés par imports dynamiques (web/xterm-charge.ts), à
    l'oisiveté juste après l'accueil ou au premier terminal : le paquet
    principal passe de 666 à 172 Ko, DOMContentLoaded de 323 à 205 ms de
    médiane, le premier contenu peint de 190 à 152 ms, la latence à la frappe
    inchangée (mesures dans docs/feuille-de-route.md, axe 3).
  • Sous AVASH_HOME, les téléchargements restent sous ce toit. Le dossier
    de réception (panneau SFTP, fichiers reçus d'un bureau RDP) était celui du
    système même quand la variable isolait le reste : sous Windows, où
    dirs::download_dir() l'ignore, un bac à sable de test écrivait dans le
    vrai dossier Téléchargements de l'utilisateur. Le sous-dossier des
    téléchargements du foyer est pris s'il existe, le foyer sinon ; un test
    d'intégration et un test du processus le vérifient.
  • La suite bout en bout complète tourne sous Windows. Quatre passages
    instrumentés pour trouver que l'action « doubleClick » du protocole
    n'atteint jamais le DOM par le serveur WebDriver embarqué : toute session
    ouverte par double-clic sur un hôte restait « jamais live » sans qu'un seul
    appel n'atteigne le cœur. Les scénarios ouvrent un hôte par une aide qui
    émet l'événement à la main sur ce chemin ; de même pour la frappe dans un
    terminal, le serveur ne synthétisant que keydown et keyup quand xterm.js
    prend les caractères sur l'événement input de son textarea ; le chemin
    d'un enregistrement n'est plus présumé commencer par / ; le scénario de
    réouverture des
    onglets, qui recharge la page, se saute sur ce chemin (le rechargement
    coupe le pilotage embarqué) ; waitForPort attend jusqu'à quinze
    secondes, dépassé une fois en suite complète. Le job e2e-windows de la
    chaîne joue désormais cette suite complète à chaque poussée (sshd
    d'OpenSSH Server, serveurs RDP et VNC de test construits sur place), au
    lieu des seuls scénarios sans serveur ; le workflow d'essai qui a servi
    aux sept passages est retiré.
  • Miroir GitLab : le second double-clic sur un hôte. Dans le scénario de
    la vue partagée, le second double-clic suivait immédiatement le premier
    « live », pendant que la barre latérale se reconstruisait (le voyant de la
    ligne) ; la référence était caduque et le double-clic tombait dans le vide
    sans erreur sous WebKitWebDriver. L'aide qui ouvre un hôte attend que la
    même ligne soit rendue deux fois de suite avant de cliquer.
  • Chaîne : références visuelles renouvelées (la palette a trois entrées
    de plus : son, partage, diagnostic) ; le workflow qualité ne combinait plus
    --in-place et --jobs, que cargo-mutants refuse ensemble.
  • Un dossier du poste comme lecteur du bureau distant (redirection de
    lecteur, MS-RDPEFS).
    La fiche d'un bureau RDP et la connexion directe
    prennent un « dossier partagé » (champ ou sélecteur du système) ; le
    processus RDP annonce alors le canal rdpdr avec un lecteur « Avash »,
    que le distant voit comme un disque réseau : l'explorateur y lit, écrit,
    crée, renomme et supprime, et n'importe quel programme distant y ouvre un
    fichier. Le serveur pilote tout par des requêtes d'entrée-sortie (ouvrir,
    lire, écrire, énumérer, informations de fichier et de volume, disposition,
    renommage, verrous) ; rdp-sidecar/src/disque.rs y répond depuis un fil
    dédié, hors de la boucle de session, par completion_id. Chaque chemin
    venu du serveur est ramené sous la racine partagée avant toute ouverture
    (.. refusé, parent résolu liens compris et tenu sous la racine, lien en
    dernier composant non suivi) : un serveur hostile ne sort pas du dossier.
    Le volume se présente en NTFS distant (pas FAT32, dont l'explorateur
    refuserait les fichiers de plus de quatre gigaoctets), avec l'espace réel
    du disque du poste. MS-RDPEFS exige que rdpdr soit annoncé avec rdpsnd
    : le son coupé, un canal audio muet (aucun format, pas de drapeau ALIVE)
    reste annoncé pour que le lecteur réponde. Huit tests dans le processus
    (confinement, aller-retour créer-écrire-relire, énumération par motif
    DOS, suppression et renommage, volume, réponse par le fil, motif, dates)
    et deux dans l'interface (dossier absent refusé avant tout lancement, drapeaux du processus). Le
    serveur de test gagne son côté serveur RDPDR (test-rdp-server/src/rdpdr/
    : annonce 1.12, capacités, UserLoggedOn, puis un scénario fixe qui lit
    le volume, énumère, lit bonjour.txt et écrit ecrit.txt, une ligne par
    étape sur sa sortie), sur un ironrdp-server porté dans
    test-rdp-server/vendor/ avec un point d'attache de canal statique que
    le paquet n'offre pas ; 27 tests (décodeurs écrits à la main, automate,
    dialogue complet avec le canal client du paquet), éprouvé aussi contre
    xfreerdp 3.31. Deux scénarios bout en bout : par le formulaire, puis le
    processus seul avec le son coupé.
  • VNC chiffré : VeNCrypt, avec le certificat épinglé. Quand le serveur
    offre le type de sécurité VeNCrypt, le client porté le choisit, négocie la
    version 0.2 et un sous-type X.509 (X509Vnc d'abord, X509None sinon ;
    les sous-types TLS anonymes, sans certificat, sont refusés parce qu'ils ne
    prouvent pas à qui l'on parle), rend le flux au processus qui monte TLS
    (rdp-sidecar/src/vnc_tls.rs, le même rustls que le RDP), puis
    s'authentifie sous TLS. Le certificat n'est pas jugé par une autorité mais
    épinglé comme en RDP : clé publique mémorisée au premier contact sous
    vnc:<hôte>:<port> dans rdp_known_hosts, et un changement refuse la
    connexion avant que le mot de passe ne parte, empreintes à l'appui. Sans
    VeNCrypt, l'authentification VNC classique en clair reste ce qu'elle était
    ; le formulaire le dit. Le serveur VNC de test gagne un terminateur
    VeNCrypt (--tls-port, --cert, --key) qui mène la poignée de main et
    TLS puis relie le client au serveur RFB en clair ; deux scénarios bout en
    bout : la connexion chiffrée (type 19, X509Vnc, TLS, pixels, empreinte
    épinglée) et le refus d'un certificat qui change, raison affichée. Au
    passage, l'incrustation « connexion fermée » rend entière une erreur du
    processus sur plusieurs lignes : elle n'en montrait que la dernière, et un
    certificat changé se résumait à « retirez la ligne de rdp_known_hosts ».
  • Le son du bureau distant. Le processus RDP annonce le canal rdpsnd
    (MS-RDPEA) avec du PCM 16 bits seulement (44,1 et 48 kHz, stéréo et mono)
    et relaie chaque bloc d'ondes à l'interface (message [20], cadence et
    canaux en tête, un mégaoctet au plus par bloc), qui le joue par WebAudio
    bout à bout sur un curseur de temps, avec le volume que le serveur demande
    ([21]). Aucun périphérique audio ni bibliothèque native dans le
    processus : rien à embarquer dans l'AppImage, rien à réclamer au bac à
    sable Flatpak, et pas de codec à faire décoder à un serveur hostile. La
    palette coupe ou rétablit le son pour les prochaines connexions (le canal
    n'est alors pas annoncé, --sans-son). Trois tests dans le processus
    (formats, message, relais), trois en Vitest (en-tête, désentrelacement,
    gain), et un scénario bout en bout qui pilote le processus contre le
    serveur de test, lequel joue un la 440 Hz : PCM 44,1 kHz stéréo relayé en
    temps réel, pas du silence, et rien avec --sans-son.
  • Un onglet fermé laissait son conteneur. closeSession demandait le
    conteneur du terminal après l'avoir disposé, quand xterm avait déjà
    détaché son élément : chaque onglet de terminal fermé laissait un
    conteneur vide dans la zone centrale. Le conteneur se retient avant.
    Vu en écrivant le scénario de la vue partagée, qui compte les conteneurs.
  • Test d'annulation d'un téléchargement rendu déterministe. Sur
    l'exécuteur macOS de la chaîne, le transfert de 400 Kio finissait avant
    que la boucle de progression n'ait posé le drapeau d'annulation : Ok au
    lieu de « annulé ». Le fichier passe à 8 Mio (seize blocs par bande, le
    drapeau est vu), et la propriété « la reprise ne relit pas les bandes que
    la carte dit faites » a son propre test, sur une carte posée à la main.
  • Publication : un seul motif pour les signatures. Le workflow Release
    listait *.app.tar.gz.sig en plus de *.sig : la signature macOS partait
    deux fois, et la seconde copie, en écrasement, tombait sur un fichier que la
    première venait de remplacer (« Not Found »). La 0.8.0 est restée en
    brouillon sans cette signature, terminée à la main (signature reprise de
    l'artefact du même run, empreintes, manifeste et attestations vérifiés,
    puis publication). Le motif en double est retiré.
  • Port série. « Connexion directe » gagne un mode Série : le port (ceux
    du poste sont proposés, un chemin se tape aussi) et la vitesse, 8 bits sans
    parité ni contrôle de flux, le réglage des consoles de commutateurs, de
    routeurs et de cartes. La session vit dans un onglet de terminal comme une
    session SSH (mêmes canaux, même pump, enregistrement asciicast compris),
    sans SFTP ni sonde d'OS. Deux fils bloquants lisent et écrivent le port
    (serialport, sans libudev) ; fermer l'onglet ferme le port. Testé sur un
    pseudo-terminal (openpty) dans le cœur, et de bout en bout sur un
    pseudo-terminal tenu par socat qui renvoie ce qu'il reçoit ; le chemin
    doit ressembler à un port (/dev/…, COMn), pas à un fichier quelconque.
  • Vue partagée. Ctrl+Maj+E (le raccourci de Terminator, ou la palette) met l'onglet actif et le
    suivant côte à côte, chacun dans son volet ; un terminal SSH et un bureau
    RDP ou VNC se partagent l'écran de la même façon. L'onglet actif est celui
    des deux qui a le clavier ; cliquer un onglet qui n'est dans aucun volet le
    met à la place de l'actif ; fermer l'un des deux referme le partage. Les
    terminaux se réajustent à leur volet, et un bureau distant affiché dans un
    volet se redimensionne à sa taille (le processus n'envoie d'images qu'aux
    bureaux visibles, comme avant). Ce que la zone centrale montre passe
    maintenant par un seul endroit (web/vue-partagee.ts) au lieu de quatre
    boucles qui se recopiaient. Scénario bout en bout sur deux sessions SSH.
  • Les onglets de la dernière fois se rouvrent. À chaque ouverture ou
    fermeture d'onglet, la liste de ce qui est ouvert (alias SSH, bureaux RDP
    et VNC enregistrés ; jamais une connexion directe, qui n'a ni configuration
    ni mot de passe rejouable) est écrite dans le répertoire de configuration
    (onglets.json, 32 entrées au plus). Au lancement suivant, l'accueil dit
    « La dernière fois, N onglets étaient ouverts » et propose de les rouvrir,
    dans l'ordre ; « Ignorer » efface la mémoire. Proposé, jamais imposé : un
    onglet SSH rouvert peut demander un mot de passe. Un hôte supprimé depuis
    n'est pas compté. Écrit à chaque changement plutôt qu'à la fermeture,
    parce que WebKitGTK ne laisse pas toujours le temps d'un beforeunload.
    Deux tests Rust (aller-retour, fichier cassé et liste trop longue), deux
    tests Vitest (ce qui est retenu, ce qui est proposé) et un scénario bout en
    bout qui recharge le front sur le sshd local.
  • « Exporter un diagnostic… » dans la palette : l'utilisateur choisit un
    fichier, le cœur y écrit (en 0600, d'un seul tenant) ce qu'un ticket a
    besoin de savoir : version, moteur web, système et session graphique,
    emballage (AppImage, Flatpak…), chemin du processus de bureau distant,
    réponse du trousseau et de l'agent SSH, variables d'environnement suivies,
    la configuration en nombre (hôtes, dossiers, rebonds, clés ; bureaux RDP et
    VNC ; tunnels) et les dernières lignes du processus de chaque session de
    bureau distant ouverte. Jamais un mot de passe ni un nom d'hôte de
    ~/.ssh/config ; l'en-tête rappelle que les journaux peuvent citer
    l'adresse d'un serveur. Le trousseau est sondé sur une entrée qui n'existe
    pas : « mot de passe redemandé à chaque fois » vient presque toujours d'un
    trousseau absent, que l'application masque à dessein le reste du temps.
    Quatre tests (texte, collecte sans recopier les hôtes, écriture 0600 et
    refus d'un chemin relatif) et un scénario bout en bout sur la commande.

Vérifier un fichier téléchargé : sha256sum -c SHA256SUMS depuis le dossier de téléchargement, et gh attestation verify <fichier> --repo AdrienAvalon/avash pour sa provenance. La nomenclature logicielle (SBOM, SPDX) est jointe et attestée elle aussi. Mise à jour automatique depuis une version installée : pastille de version, « vérifier les mises à jour ».

Full Changelog: v0.8.0...v0.9.0