De tous les protocoles et plateformes supportés par Remote Desktop Manager, RDP sur Windows est de loin le plus important. Bien que Microsoft propose son client de bureau à distance officiel sur toutes les plateformes (à l'exception de Linux), la seule interface client RDP permettant l’intégration par des tiers est celle sur Windows. FreeRDP est l’unique client RDP multiplateforme adéquat, mais il ne rivalisera jamais avec le client RDP officiel de Windows (MSTSC). En fait, pour offrir les fonctionnalités souhaitées par les clients, nous avons besoin de la flexibilité de FreeRDP (source libre), mais à l'intérieur du client RDP de Microsoft (source fermée).
Construire nos propres portes
Le client RDP de Microsoft est remarquable, mais il n’expose pas tout ce qui est requis afin d’implémenter les demandes de fonctionnalités que nous avons. Lorsqu’on se heurte à un mur, on peut s’arrêter ou tenter de construire de nouvelles portes dans des endroits inédits. Voilà à quoi nous nous sommes attelés avec le projet Devolutions MsRdpEx : un ensemble de nouvelles « portes » que nous avons ouvertes au moyen de la bibliothèque Microsoft Detours pour l’accrochage d'API. Le projet se base sur l’interface publique ActiveX RDP pour exposer les composants et propriétés internes inaccessibles en temps normal. Une première fonctionnalité d’accrochage d'API RDP est déjà offerte dans RDM 2022.2.
Qu'est-ce que l’accrochage d'API?
L’accrochage d'API semble plus complexe qu’il ne l’est en réalité : il modifie un programme en mémoire pour intercepter un appel de fonction et le rediriger vers une fonction « hook » que vous contrôlez. Ainsi, en accrochant la fonction LoadLibrary, il est possible de modifier son comportement afin que le chargement de « mstscax.dll » charge « MsRdpEx.dll » à la place. Autrement dit, vous pouvez « mentir » à l’application en déformant le comportement réel de la fonction. Ce ne sont pas toutes les fonctions qui peuvent être accrochées. Certaines sont plus susceptibles d’être modifiées que d’autres, ou simplement hors de portée.
Rétro-ingénierie
C’est un logiciel à source fermée, n’est-ce pas? Ce qui signifie qu’il n’y a pas de documentation et de code source à consulter. Vous pouvez en savoir plus sur la rétro-ingénierie des fichiers binaires de Microsoft dans notre article de blogue : Finding Secret RDP Registry Keys Using IDA Free. Il s’agit d’un processus long et fastidieux, et ce même si le résultat final ne consiste qu’à inverser un bit quelque part. À titre d’exemple, notre intégration non officielle MSRDC s’est brisée il y a peu dû à un mystérieux code d’erreur 3334. Il nous a fallu deux jours entiers de débogage acharné pour découvrir qu’une nouvelle propriété interne devrait être définie à « vrai ».
Options RDP étendues
Quel type d’option dans le client RDP nécessite un accrochage d'API? Voici une liste non exhaustive :
UserSpecifiedServerName : Une option interne requise pour préciser le nom du serveur pour la validation TLS et Kerberos. Elle est utilisée avec le protocole RD Gateway, mais n’est pas exposée pour les connexions RDP comme celles que nous faisons pour Devolutions Gateway.
KDCProxyName : Une option bien documentée pour injecter un serveur proxy KDC dynamiquement pour permettre Kerberos, mais elle n'est appliquée que pour les connexions RD Gateway.
UsingSavedCreds : Une option interne mal configurée si un mot de passe est défini au moment de la connexion (bien que ce dernier ne soit pas sauvegardé). Cela interrompt l’injection des identifiants lorsque la stratégie de groupe « Toujours demander un mot de passe à la connexion » est activée.
DisableUDPTransport : Incroyable, mais vrai, cette option interne ne peut être définie que par des clés de registre, ce qui empêche un contrôle précis à partir d’un gestionnaire de connexion.
Les deux premières options, UserSpecifiedServerName et KDCProxyName, sont essentielles pour faciliter l’utilisation de Kerberos en dehors du réseau de l’entreprise, mais elles sont limitées exclusivement au protocole RD Gateway. Nous avons prévu une fonction de proxy KDC dans Devolutions Gateway pour les exploiter, mais nous aurions voulu éviter de faire un si long détour par l’accrochage d'API pour y parvenir.
Azure Virtual Desktop
Plusieurs utilisateurs ont demandé le support d'Azure Virtual Desktop, et nous sommes actuellement à mi-chemin du travail à faire. Si tout se passe bien, nous devrions avoir une première intégration AVD dans RDM 2022.3, avec des améliorations ajoutées par la suite. Voici une liste des défis auxquels nous sommes confrontés :
-
MSRDC est indispensable pour AVD, mais n'expose pas officiellement une API pour l'intégration.
-
MSRDC exige la signature RDP côté serveur, ce qui empêche la gestion des paramètres côté client.
-
Les extensions du protocole AVD ne sont pas documentées, ce qui n'est pas le cas du protocole RDP standard.
-
Les appels de contrôle AVD pour le flux Web RDP faits avec Azure ne sont pas documentés.
Nous avons réussi à intégrer MSRDC pour les connexions RDP standards, c’est-à-dire à la fois en mode intégré et en mode externe. MSRDC contient un DLL prêt à l’emploi (rdclientax.dll) exposant la même interface ActiveX RDP que le DLL intégré de MSTSC (mstscax.dll).
AVD introduit une dizaine de nouvelles options de fichiers RDP, ainsi que des propriétés internes correspondantes pour l'ActiveX. Il a été difficile de déterminer leur nature et leur signification, mais nous avons au moins réussi à les importer/exporter adéquatement dans RDM pour le moment.
Une signature problématique
Tout se déroulait bien jusqu’à ce que nous nous butions à un premier obstacle de taille : les fichiers AVD RDP sont signés côté serveur et publiés par un flux Web spécifique que seul MSRDC est en mesure de récupérer. Toutefois, MSRDC ne pourra pas établir de connexions AVD avec des fichiers RDP non signés, et vous ne pouvez pas modifier les options RDP côté client sans rompre la signature. Houston, nous avons un problème!
Lorsque Remote Desktop Manager lance MSTSC ou MSRDC en mode externe, il génère un fichier .RDP temporaire contenant toutes les options de l'entrée de connexion. Si vous modifiez l'entrée de connexion RDP dans RDM, vous obtiendrez un fichier RDP différent. Ce problème ne peut être contourné que par la création d'une entrée de connexion liée à un fichier RDP local non modifié, mais vous ne pouvez pas encore le modifier.
Pourquoi ne pas signer les fichiers localement? Cette solution a été envisagée, mais elle requiert une certification d’une autorité connue et fiable. Les stratégies d’accrochage d’API pour l’utilisation d’une signature valide à partir d'un certificat autosigné étaient aussi restreintes. Il nous a fallu environ deux semaines de dur labeur pour enfin trouver une façon de contourner la vérification de signature des fichiers RDP pour les connexions AVD, et réussir à lancer une première connexion AVD avec MSRDC depuis RDM.
Avons-nous atteint notre but?
Nous avançons lentement, mais sûrement. Les connexions AVD ont un contexte d'authentification supplémentaire avec Azure, et le gérer correctement sera un défi de taille. L’injection des identifiants RDP standards est également défaillante, nous devrons donc probablement trouver un autre moyen de procéder. L'interface utilisateur des options spécifiques à l'AVD n'est pas encore terminée, et il est ardu de les nommer et de les structurer correctement lorsqu’elles ne sont pas documentées. La priorité est de la faire fonctionner avec MSRDC en tant que programme externe, car les connexions AVD avec MSRDC en mode intégré entraînent un plusieurs défis.
Conclusion
L’accrochage d’API est intéressant, mais il doit être envisagé comme dernier recours. La plupart de ces options étendues auraient été normalement exposées publiquement et officiellement, ce qui nous aurait évité de passer du temps à faire de la rétro-ingénierie et de l’accrochage API. Faites-vous partie des clients d'Azure Virtual Desktop? Dans le cas contraire, êtes-vous intéressé par l'utilisation de MSRDC au lieu de MSTSC? Ces deux cas n'étant pas officiellement pris en charge, nous vous serions reconnaissants d'envoyer vos commentaires à Microsoft à ce sujet!