C# 如何降低WCF命名管道的完整性

C# 如何降低WCF命名管道的完整性,c#,wcf,named-pipes,bho,protected-mode,C#,Wcf,Named Pipes,Bho,Protected Mode,我有一个用C#编写的internetexplorer插件,它通过一个名为pipe的WCF与一个.NET桌面应用程序通信。桌面应用程序为netNamedPipeBinding创建ServiceHost,IE加载项的每个实例都创建一个ChannelFactory来与应用程序对话。在Windows XP下一切正常,但在Windows 7的IE保护模式下会引发异常 System.ServiceModel.CommunicationException:无法连接到终结点的网络。pipe://localhos

我有一个用C#编写的internetexplorer插件,它通过一个名为pipe的WCF与一个.NET桌面应用程序通信。桌面应用程序为netNamedPipeBinding创建ServiceHost,IE加载项的每个实例都创建一个ChannelFactory来与应用程序对话。在Windows XP下一切正常,但在Windows 7的IE保护模式下会引发异常

System.ServiceModel.CommunicationException:无法连接到终结点的网络。pipe://localhost/MyApp.MyID'. ---> System.IO.PipeException:存在“\。\pipe…guid…”的管道终结点,但连接失败:访问被拒绝。(5,0x5)


在受保护模式下运行外接程序是我必须支持的场景。我的理解是,如果我降低命名管道的完整性级别,那么我的IE插件将被允许通过它进行对话。我的问题是如何做到这一点。我有东西设置使用WCF,并希望最好保持这种方式。我可以让WCF创建完整性级别较低的命名管道吗?我应该编写什么代码来实现这一点?

我认为这是不可能的

问题在于,在创建命名管道时,必须在提供的安全描述符中指定完整性标签。在标准NetNamedPipeBinding中,对
CreateNamedPipe
的调用发生在内部WCF类
System.ServiceModel.Channels.PipeConnectionListener
的私有
CreatePipe()
方法中。我看不出有什么方法可以改变它为管道指定初始安全描述符的方式

有关我们需要实现的目标的概要,请参阅

从头开始编写一个定制的命名管道传输绑定元素似乎是目前解决这个问题的唯一方法,如果失败,我们只能等待Microsoft在未来版本的WCF中添加一些启用功能。如果您有权访问Microsoft Connect,则可以

编辑: 我太悲观了。我现在已经找到了一种方法来做到这一点

关键是,在创建管道时,您不必在安全描述符中指定完整性标签,但必须在打开侦听器时使用CreateNamedPipe返回的句柄(即管道的第一个服务器端句柄)修改SACL。使用任何其他句柄,添加完整性标签的尝试总是失败的,因为
dwOpenMode
标志参数到
CreateNamedPipe
会重载其中一个位的使用,以表示
FILE\u flag\u FIRST\u PIPE\u INSTANCE
WRITE\u OWNER
。为了添加完整性标签,我们需要后者的访问权限,但是前者的存在会导致调用在除第一个管道实例之外的任何管道实例上失败

获得第一个管道句柄不是一件小事。WCF将其存储在类型为
System.ServiceModel.Channels.PipeConnectionListener.PendingAccept
的实例中,存储在管道连接侦听器维护的列表中。连接监听器与通道监听器不同(可以通过重写绑定元素的
BuildChannelListener
方法直接获取通道监听器),而且更难获得连接监听器。它涉及到使用反射来定位端点的TransportManager,该TransportManager保存对端点的连接侦听器的引用,然后沿着连接侦听器链工作(根据跟踪等的配置而变化),直到找到管道连接侦听器。如果幸运的话,第一个管道句柄可以在侦听器的挂起接受列表中找到(尽管这里有一个争用条件——如果客户端在我们获得句柄之前连接,它将永远消失)

一旦句柄可用,降低完整性以允许低完整性客户端与服务通信只需在句柄上调用
SetSecurityInfo
,即可添加完整性标签


我计划在不久的将来介绍这方面的一些细节。

博客链接对我来说已经过时了。