我有一个用 C# 编写的 Internet Explorer 加载项,它通过 WCF 命名管道与 .NET 桌面应用程序进行通信。桌面应用程序为 netNamedPipeBinding 创建 ServiceHost,并且 IE 加载项的每个实例都会创建一个 ChannelFactory 来与应用程序通信。在 Windows XP 下一切正常,但在 Windows 7 中 IE 的保护模式下抛出异常。
System.ServiceModel.CommunicationException:无法连接到端点“net.pipe://localhost/MyApp.MyID”。 ---> System.IO.PipeException: '\.\pipe...guid...' 存在管道端点,但连接失败:访问被拒绝。 (5, 0x5)
在保护模式下运行加载项是我必须支持的方案。我的理解是,如果我降低命名管道的完整性级别,那么我的 IE 加载项将被允许通过它进行通信。我的问题是如何做到这一点。我已经设置了使用 WCF 的功能,并且希望保持这种状态。我可以让 WCF 创建完整性级别较低的命名管道吗?我需要编写什么代码来实现这一点?
我认为这是不可能的。
问题在于,必须在创建命名管道时提供的安全描述符中指定完整性标签。在标准 NetNamedPipeBinding 中,调用CreateNamedPipe
发生在私人内部CreatePipe()
内部WCF类的方法System.ServiceModel.Channels.PipeConnectionListener
。我看不出有什么方法可以改变它指定管道初始安全描述符的方式。
See 这个问题和答案概述我们需要实现的目标。
从头开始编写自定义命名管道传输绑定元素似乎是目前解决此问题的唯一方法,否则我们只能等待 Microsoft 在 WCF 的未来版本中添加一些支持功能。如果您有权访问 Microsoft Connect,您可以将您的声音添加到请求此功能的其他人中.
编辑:
我太悲观了。我现在找到了一种方法来做到这一点。
关键是,事实证明,在创建管道时,您不一定必须在安全描述符中指定完整性标签 - 但您必须使用打开侦听器时从 CreateNamedPipe 返回的句柄修改 SACL - 即管道的第一个服务器端句柄。使用任何其他句柄,添加完整性标签的尝试总是失败,因为dwOpenMode
标志参数为CreateNamedPipe
重载使用其中一位来表示两者FILE_FLAG_FIRST_PIPE_INSTANCE
and WRITE_OWNER
。我们需要后者的访问权限才能添加完整性标签,但前者的存在会导致调用在除第一个管道实例之外的任何管道实例上失败。
掌握第一个管柄并非易事。 WCF 将其存储在该类型的实例中System.ServiceModel.Channels.PipeConnectionListener.PendingAccept
,存储在由管道连接侦听器维护的列表中。连接侦听器与通道侦听器不同(可以通过覆盖直接获取)BuildChannelListener<>
绑定元素的方法),并且更难获得。它涉及使用反射来定位端点的 TransportManager(它保存对端点的连接侦听器的引用)的英勇行为,然后沿着连接侦听器链(根据跟踪等的配置而变化)进行工作,直到找到管道连接侦听器。如果幸运的话,可以在侦听器的待处理接受列表中找到第一个管道句柄(尽管这里存在竞争条件 - 如果客户端在我们获取句柄之前连接,它将永远消失)。
一旦句柄可用,只需调用即可降低完整性以允许低完整性客户端与服务进行通信SetSecurityInfo
在手柄上添加完整性标签。
我计划介绍这一点的一些细节my blog soon.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)