2010-10-31 24 views
5

Ich habe ein Internet Explorer-Add-in, geschrieben in C#, die über eine WCF Named-Pipe zu einer .NET-Desktop-Anwendung spricht. Die Desktop-App erstellt den ServiceHost für die netNamedPipeBinding, und jede Instanz des IE-Add-Ins erstellt eine ChannelFactory, um mit der App zu kommunizieren. Alles funktioniert gut unter Windows XP, aber unter Windows 7 wird eine Ausnahme unter dem geschützten Modus des IE ausgelöst.Wie die Integrität von WCF namens Pipe

System.ServiceModel.CommunicationException: Verbindung zum Endpunkt 'net.pipe: //localhost/MyApp.MyID' kann nicht hergestellt werden. ---> System.IO.PipeException: Ein Pipe-Endpunkt existiert für '\. \ Pipe ... guid ...', aber die Verbindung ist fehlgeschlagen: Zugriff wurde verweigert. (5, 0x5)

Das Ausführen des Add-Ins im geschützten Modus ist ein Szenario, das ich unterstützen muss. Mein Verständnis ist, dass, wenn ich das Integritätsniveau der Named-Pipe herabsetze, mein IE-Add-In erlaubt wird, darüber zu sprechen. Meine Frage ist, wie man das macht. Ich habe Dinge eingerichtet, um WCF zu verwenden, und würde es am liebsten so behalten. Kann ich WCF veranlassen, die Named Pipe mit der niedrigeren Integritätsebene zu erstellen? Welchen Code schreibe ich, um das zu ermöglichen?

Antwort

7

Ich glaube nicht, dass dies möglich ist.

Das Problem besteht darin, dass die Integritätskennzeichnung in der Sicherheitsbeschreibung angegeben werden muss, die beim Erstellen der Named Pipe bereitgestellt wird. In der Standard-NetNamedPipeBinding erfolgt dieser Aufruf an CreateNamedPipe innerhalb der privaten CreatePipe() Methode der internen WCF-Klasse System.ServiceModel.Channels.PipeConnectionListener. Ich kann keine Möglichkeit sehen, zu ändern, wie es die anfängliche Sicherheitsbeschreibung für die Pipe angibt.

Siehe this question and answer für eine Übersicht dessen, was wir erreichen müssen.

Das Schreiben eines benutzerdefinierten Named-Pipe-Transport-Bindungselements von Grund auf scheint der einzige Weg zu sein, um dies zu umgehen, was wir nur abwarten müssen, bis Microsoft einige Aktivierungsfunktionen in einer zukünftigen Version von WCF hinzufügt. Wenn Sie Zugriff auf Microsoft Connect haben, können Sie add your voice to the others requesting this feature.

EDIT: Ich war zu pessimistisch. Ich habe jetzt einen Weg gefunden, dies zu tun.

Der Schlüssel war, dass es stellte sich heraus, Sie müssen nicht unbedingt auf die Integrität Etikett in der Sicherheitsbeschreibung angeben, wenn das Rohr erstellt wird - aber Sie müssen die SACL ändern mit dem Griff aus CreateNamedPipe zurückgegeben, wenn der Hörer geöffnet - dh der allererste serverseitige Griff zum Rohr. Unter Verwendung eines anderen Handles schlägt der Versuch, das Integritätsetikett hinzuzufügen, immer fehl, da der dwOpenMode-Flag-Parameter CreateNamedPipe die Verwendung eines der Bits überlastet, um sowohl FILE_FLAG_FIRST_PIPE_INSTANCE als auch WRITE_OWNER zu bedeuten. Wir benötigen die letztgenannte Zugriffsberechtigung, um das Integritätslabel hinzuzufügen, aber das Vorhandensein des ersten führt dazu, dass der Aufruf an allen außer der ersten Pipelinstanz fehlschlägt.

Den ersten Rohrgriff zu ergattern ist keine triviale Aufgabe. WCF entfernt es in einer Instanz vom Typ System.ServiceModel.Channels.PipeConnectionListener.PendingAccept in einer Liste, die vom Pipe-Connection-Listener verwaltet wird. Der Verbindungs-Listener ist nicht dasselbe wie der Kanal-Listener (der einfach durch Überschreiben der BuildChannelListener<>-Methode eines Bindungselements gegriffen werden kann), und es ist viel schwieriger zu erreichen. Es beinhaltet Heroics mit Reflection, um den TransportManager für den Endpunkt zu lokalisieren, der einen Verweis auf den Verbindungs-Listener des Endpunkts enthält, und dann eine Kette von Verbindungs-Listenern abzuarbeiten (die je nach Konfiguration der Verfolgung variiert), bis der Rohrverbindungs-Listener gefunden wird . Wenn wir Glück haben, kann der erste Pipe-Handle in der Liste der ausstehenden Acceptoren des Hörers gefunden werden (obwohl es hier eine Race-Bedingung gibt - wenn ein Client eine Verbindung herstellt, bevor wir den Handle bekommen, wird er für immer verschwinden).

Sobald der Griff zur Verfügung, um die Integrität Senkung niedrige Integrität Kunden wth den Dienst zu kommunizieren, damit ist nur eine Frage der SetSecurityInfo auf dem Griff Aufruf die Integrität Etikett hinzuzufügen.

Ich plane zu decken diese einige Details auf my blog ist bald.