\nocite{keetch2009practicalsandboxing}
\nocite{ISCWindowsACL}
\nocite{GoogleProjectZero}
% TODO: remplacer confiant
Après la présentation des objectifs liés aux communications inter-processus et à
l'implémentation Linux, nous pouvons essayer de reprendre le même modèle pour
l'implémentation Windows. Malheureusement celle-ci vient nous rappeler qu'un
changement de système implique parfois un changement de paradigme. La
documentation quelque peu hasardeuse va néanmoins nous permettre de mettre en
place une architecture similaire.

\section{Communication inter-processus}

Windows dispose de beaucoup de moyens de communication inter-processus. Parmi
ceux là, aucun ne va avoir les mêmes propriétés que les sockets Unix. Nous
allons même de base éliminer tous les moyens \og{}haut niveau\fg{} comme les ports COM
résolvant plutôt des problèmes d'interopérabilité et se concentrer sur les
moyens plus bas niveau.

\subsection{Les sockets Windows}

Les sockets Windows réimplémentent la même interface que les sockets Berkeley
mais ne fournissent pas de sockets locaux ou anonymes.  Ceux-ci passent par la
pile réseau pour l'envoi de message. On notera cependant l'implémentation de
\og{}TCP Loopback Fast Path\fg{} depuis Windows Server 2012. Cette fonctionnalité
conserve la sémantique du protocole TCP tout en désactivant des fonctionnalités
comme l'algorithme de Nagle. \cite{WindowsFastTCPLoopback}
C'est donc ce qui ressemble le plus aux sockets Unix, excepté l'accès au réseau
et le passage de descripteur de fichiers.



\subsection{Les canaux anonymes}

Les canaux anonymes donnent un moyen de communication unidirectionnel avec un
écrivain et un lecteur. Il faut donc utiliser une paire de canaux anonymes pour
pouvoir discuter en full-duplex, mais également utiliser un mécanisme pour
transmettre le \inltype{HANDLE} d'un processus à l'autre. À noter que la plupart
des fonctions sur les canaux nommés fonctionnent avec les canaux anonymes, ces
derniers étant implémentés comme des canaux nommés avec un nom particulier.

\subsection{Les canaux nommés}

Les canaux nommés sont capables de fonctionner en full-duplex et disposent
pleinement du système d'ACL global de Windows.

Ici, on va plutôt s'intéresser aux canaux nommés et voir comment on peut les
utiliser pour transmettre des messages et des ressources. La création d'un canal
nommé se fait avec avec la famille de fonction \inltype{CreateNamedPipe}. Dans
notre cas, on sera fortement tenté d'utiliser des \inltype{lpSecurityAttributes}
définis avec de bonnes valeurs, mais ce point sera exploré dans la suite du
document.

\begin{code}{c}{Prototype de \inltype{CreateNamedPipe}}
HANDLE CreateNamedPipeA(
  LPCSTR                lpName,
  DWORD                 dwOpenMode,
  DWORD                 dwPipeMode,
  DWORD                 nMaxInstances,
  DWORD                 nOutBufferSize,
  DWORD                 nInBufferSize,
  DWORD                 nDefaultTimeOut,
  LPSECURITY_ATTRIBUTES lpSecurityAttributes
);
\end{code}

\section{Transfert de ressources entre processus}

Windows dispose de trois mécanismes pour partager des ressources entre
processus. Les ressources sont représentées par des objets \inltype{HANDLE}.

La première méthode est l'héritage, qui a lieu lors de la création d'un nouveau
processus. Les descripteurs de fichiers marqués comme héritables, ou bien aucun
si \inltype{bInheritHandles} est précisé à \inltype{FALSE} lors de l'appel de
\inltype{CreateProcess}, seront récupérés dans le nouveau processus avec la même
valeur. Lorsqu'un \inltype{HANDLE} est hérité, il garde la même valeur dans le
nouveau processus et il faut donc le transmettre soit par IPC, soit par
paramètre de la ligne de commande, soit par injection de code dans le nouveau
processus.

La seconde méthode utilise la fonction \inltype{DuplicateHandle} pour injecter
le descripteur de fichier dans le nouveau processus. Dans ce cas-là, si l'appel
est fait depuis le processus parent, une nouvelle valeur est générée pour ce
\inltype{HANDLE} et il faut le transmettre au processus enfant par l'une des
méthodes mentionnées dans le cas de l'héritage.

\begin{code}{c}{Prototype de la fonction \inltype{DuplicateHandle}}
BOOL WINAPI DuplicateHandle(
  _In_  HANDLE   hSourceProcessHandle,
  _In_  HANDLE   hSourceHandle,
  _In_  HANDLE   hTargetProcessHandle,
  _Out_ LPHANDLE lpTargetHandle,
  _In_  DWORD    dwDesiredAccess,
  _In_  BOOL     bInheritHandle,
  _In_  DWORD    dwOptions
);
\end{code}

L'exploitation de \inltype{DuplicateHandle} demande à ce que chacun des deux
processus rentrant en jeu dans la fonction, à savoir
\inltype{hSourceProcessHandle} et \inltype{hTargetProcessHandle} disposent du
droit \inltype{PROCESS_DUP_HANDLE}. Étant donné que la fonction peut être
utilisée de la source vers la destination ou depuis la destination récupérant un
\inltype{HANDLE} appartenant à la source, le processus ayant accès à l'autre
processus est capable de copier tout accès existant et dispose donc des mêmes
droits que ce dernier.

Cette remarque est importante pour se rendre compte que l'utilisation de cette
méthode implique nécessairement un broker, qui sera suffisamment privilégié pour
accéder aux deux processus souhaitant partager une ressource. Tenter d'appliquer
cette fonction directement dans les workers impliquerait que chacun des workers
auraient les mêmes droits que ses voisin et, de façon transitive, aurait accès à
toutes les zones de privilèges connexes dans le graphe d'IPC.

Enfin, la troisième méthode consiste à utiliser les objets nommés qui sont
créés d'un côté par le processus parent, puis ouverts par les processus enfants
en les référençant par leur nom.

Dans le prototype, j'ai utilisé des canaux nommés pour faciliter la mise en place
mais j'ai également essayé d'utiliser des paires de canaux anonymes dans d'autres
codes simulant le fonctionnement des IPC. J'ai également prévu de mettre en
place la méthode utilisant \inltype{DuplicateHandle} et donc un broker central
pour pouvoir transférer des ressources de la même façon que sous Linux.
J'essayerai cependant de m'approcher d'un modèle orchestrateur avec d'autres
techniques mais nous allons voir qu'il n'y a pas vraiment d'alternative pour
l'instant.
