2010-10-31 23 views
5

我有一個使用C#編寫的Internet Explorer加載項,它通過WCF命名管道與.NET桌面應用程序通信。桌面應用程序爲netNamedPipeBinding創建ServiceHost,並且IE加載項的每個實例都會創建一個ChannelFactory來與應用程序交談。在Windows XP下一切正常,但在Windows 7的IE保護模式下拋出異常。如何降低WCF命名管道的完整性

System.ServiceModel.CommunicationException:無法連接到端點'net.pipe://localhost/MyApp.MyID'。 ---> System.IO.PipeException:管道端點存在'\。\ pipe ... guid ...',但連接失敗:訪問被拒絕。 (5,爲0x5)

運行保護模式下加載項是一個場景,我必須支持。我的理解是,如果我降低命名管道的完整性級別,那麼我的IE加載項將被允許通過它。我的問題是如何做到這一點。我有東西安裝使用WCF,並希望保持這種方式。我可以讓WCF創建具有較低完整性級別的命名管道嗎?我寫了什麼代碼來實現這一目標?

回答

7

我不認爲這是可能的。

的問題是,完整性標籤在創建命名管道時所提供的安全描述符中指定。在標準的NetNamedPipeBinding中,對CreateNamedPipe的調用發生在內部WCF類System.ServiceModel.Channels.PipeConnectionListener的專用CreatePipe()方法內部。我看不到一種方法來改變它如何指定管道的初始安全描述符。

爲我們所需要達到的大綱見this question and answer

從頭開始編寫一個自定義的命名管道傳輸綁定元素似乎是目前解決此問題的唯一方法,否則我們只能等待Microsoft在未來版本的WCF中添加一些啓用功能。如果您有權訪問Microsoft Connect,則可以使用add your voice to the others requesting this feature

編輯: 我太悲觀。我現在已經找到了一種方法來做到這一點。

的關鍵是,它變成了你不一定要指定在安全描述符中的完整性標籤創建管道時 - 但你必須使用手柄從CreateNamedPipe時返回時,聽衆是修改SACL打開 - 即管道的第一個服務器端手柄。使用任何其它手柄,增加完整性標籤的嘗試總是失敗,因爲dwOpenMode標誌參數CreateNamedPipe重載使用中的一個比特的意思都FILE_FLAG_FIRST_PIPE_INSTANCEWRITE_OWNER。我們需要後者的訪問權限才能添加完整性標籤,但前者的存在會導致調用在除第一個管道實例外的任何失敗中失敗。

獲取第一管手柄的保持是不是一個簡單的任務。 WCF將它放在類型爲System.ServiceModel.Channels.PipeConnectionListener.PendingAccept的實例中,並存儲在由管道連接監聽器維護的列表中。連接偵聽器與通道偵聽器不同(它可以通過覆蓋綁定元素的BuildChannelListener<>方法直接獲取),並且這很難實現。它涉及使用反射的英雄,爲端點定位TransportManager,該端點擁有對端點連接監聽器的引用,然後處理連接監聽器鏈(根據跟蹤等配置而變化),直到找到管道連接監聽器。如果我們幸運的話,可以在聽衆未決的接受名單中找到第一個管子句柄(儘管這裏存在競爭條件 - 如果客戶在我們拿到句柄之前連接,它將永遠消失)。

一旦句柄可用,降低完整性以允許低完整性客戶端與服務進行通信只需在句柄上調用SetSecurityInfo即可添加完整性標籤。

我打算在很短的時間內介紹一下my blog的一些細節。