Hardening consulting

Opensourcing d'ogon

Mieux vaut tard que jamais ! Il y a quatre ans, je faisais un talk sur FreeRDS à la XDC 2014 où j'annonçais que nous en ferions l'open sourcing sans doute fin 2014, et déjà c'était quelque chose d'initialement prévu pour Septembre 2014. Finalement l'openSourcing tant attendu est là, mais en Avril 2018: juste un tout petit peu de retard !


Présentation

Du retard

Alors évidement il s'en est passé des choses depuis fin 2014. Pour commencer, le nom du projet a changé: le nom FreeRDS appartenait à un des membres du projet, et ce sur quoi nous avons travaillé a radicalement divergé de la collaboration commune des débuts, d'où la nécessité de changer de nom. Nous avions pensé à fireRDS, le dépôt de nom avait été entamé: la marque déposée peut être contestée pendant 90 jours, après elle est acquise. Et il se trouve qu'une énorme société (indice: j'achète désormais mes livres à la librarie) exploitant le nom fire pour ses logiciels, a fait de l'intimidation juridique 10 jours avant la fin de la période de contestation. Après concertation, ne voulait pas faire le pot de terre contre le pot de fer, nous avons laissé fireRDS pour finalement choisir ogon comme nom de projet (feu en russe).

Et pendant ce temps là...

Bien sûr, le périmètre du projet s'est aussi étoffé en 3 années de travail. Depuis 2014, nous avons ajouté entre autre:

  • le support du son via un module pulseaudio;
  • la gestion du multi-touch (écrans tactiles) sur tous les backends;
  • le support du channel egfx ainsi que de l'encodage en h264 (encodage seulement en utilisant OpenH264 pour l'instant);
  • des implémentations de la redirection disque ou du presse-papier (clipboard);
  • pour le backend Qt, l'accélération matériel en utilisant les DRI rendernodes, ce qui permet d'avoir des programmes fait en QML;
  • et tout un tas d'autres petits détails qui ont consolidé le projet;

License

Coté license, nous envisagions la license Apache 2.0 et finalement c'est la license GNU Affero qui a été retenue de manière à ce que les contributions soient forcément rendues publiques (comme c'est un logiciel serveur). Coté contribution, la signature d'un CLA (Contributor Licence Agreement) est nécessaire pour éviter le genre de problème qu'a rencontré FreeRDP à ses débuts au moment du changement de license, et pour blinder l'appartenance des contributions.

Mais c'est quoi ogon ?

TLDR; ogon est un serveur RDP pour Linux comme xrdp.

Pour être plus précis, il s'agit d'un environnement pour faire du RDP sous Linux, c'est à dire qu'il y a la partie serveur RDP ainsi que toute une série de composants annexes qui permet de publier des applications en RDP, d'écrire des channels et d'interagir avec les clients RDP. Par rapport à xrdp, ogon essaye d'implémenter tous les standards récents en laissant de coté les aspects opérations vectorielles (encore appelé RDP à la papa). Pour l'instant le projet ne vise que Linux, mais nous avons tout fait pour qu'il n'y ai pas d'obstacle majeur à un fonctionnement sous Windows.

Quelques aspects techniques

Composants


Dans l'architecture ogon, nous avons les composants suivants:

  • le serveur RDP (ogon-rdp-server) qui va gérer tous les aspects du protocole RDP;
  • le sessionManager (ogon-session-manager) qui s'occupe des autorisations, authentifications et de la gestion des sessions. Le serveur et le sessionManager dialoguent entre eux pour gérer la session d'un utilisateur. Ce composant écoute aussi en thrift pour l'administration des channels, des utilisateurs ou des sessions;
  • nous avons le backend qui va générer le contenu visible qui sera ensuite encodé et envoyé au client par le composant serveur. Le backend dialogue avec le serveur RDP par le biais d'une socket locale et d'une mémoire partagée;
  • enfin, on a des implémentations de channels qui peuvent être présentes dans des programmes externes (comme le module son pour pulseaudio par exemple), elles vont dialoguer avec le sessionManager pour obtenir l'ouverture d'un channel, et ensuite le programme dialoguera directement avec le serveur RDP;

backends

Pour l'instant 3 backends existent:

  • un backend Qt qui permet de générer le contenu visible à partir d'un application Qt, c'est par exemple de cette manière qu'est implémentée l'écran d'authentification: une application plein écran qui dialogue avec le sessionManager pour authentifier l'utilisateur. Ce backend se présente sous la forme d'un plugin de plateforme Qt, on peut donc prendre n'importe quelle application Qt, lui demander d'utiliser ce QPA comme moteur de rendu et d'entrée, et l'application est visible via ogon. Autre avantage non négligeable: on peut développer l'application tranquillement sur son desktop et ensuite l'exporter via ogon;
  • le backend xogon qui permet d'avoir un environnement X11 exporté à travers ogon. En gros cela permet d'avoir sa session X habituelle à distance à travers du RDP;
  • il existe enfin un module pour faire la même chose avec weston (serveur wayland de référence);

Serveur RDP

Par choix, le serveur RDP ne gère strictement aucune vieille opération vectorielle, tout se fait en bitmap plus ou moins encodé. Cela a notablement facilité l'écriture des backends qui n'ont qu'à partager un framebuffer avec le serveur. Dans le pire des cas, le serveur se sert de bitmap updates, mais avec la grande majorité des clients, il peux faire de l'encodage en remoteFx ou en H264 qui sont beaucoup plus performant en terme de consommation réseau (mais pas CPU).

Synopsis pour un login


Rien de tel qu'un petit exemple pour voir comment les composants interagissent entre eux. Prenons l'exemple d'un utilisateur qui se connecte sur le serveur ogon:

  1. la connection entrante est acceptée, et la négociation RDP est faite jusqu'à la phase d'activation;
  2. le serveur RDP contacte le sessionManager avec les éventuels login / mot de passe qui ont été envoyés lors de la négociation;
  3. si les identifiants sont corrects, on passe directement à l'étape 5. Sinon le sessionManager va instancier un process implémentant le formulaire de login (le greeter), et demander au serveur RDP de se connecter sur ce générateur de contenu. L'utilisateur voit un formulaire d'identification;
  4. l'utilisateur saisi ses login / mot de passe et pour valider les identifiants, le greeter contacte le sessionManager (à travers la connection au serveur RDP). Si les identifiants sont incorrects une erreur est renvoyée et l'application du greeter affiche un message ad-hoc: "identifiant invalide". Sinon étape suivante;
  5. le sessionManager instancie l'application de session: la plupart du temps le serveur xogon et demande au serveur RDP de se connecter dessus.

J'ai simplifié à dessein le lancement du serveur X, qui est un peu plus compliqué que présenté car on doit faire ça sous l'identité de l'utilisateur, et interagir avec systemd pour que les autorisations correctes soient accordées.

Conclusion

Voilà de quoi vous mettre l'eau à la bouche. Le projet ogon est toute une infrastructure pour faire du RDP sous Linux, je n'en ai présenté que les fonctions basiques. Mais maintenant que le projet est public, nous attendons avec impatience les retours et les contributions.