允许连接到具有不匹配完整性级别的.NET COM服务器

时间:2012-08-20 14:32:14

标签: c# .net com uac

我遇到基于COM的客户端 - 服务器设置问题。 COM服务器使用C#(.NET 4.0)编写,并作为(已注册的)本地服务器运行。

根据连接到服务器的应用程序,其他客户端将收到服务器执行失败(HRESULT异常:0x80080005(CO_E_SERVER_EXEC_FAILURE)

解释了潜在问题here (in the section COM is integrity aware)。我理解它的方式,是由于提升的应用程序创建具有更高完整性级别的服务器这一事实。当另一个未提升的应用程序连接时,不允许连接到同一个实例。当非提升的应用程序创建进程时,会发生同样的情况,然后是提升的应用程序连接。

我尝试实现page中描述的解决方案:修改注册表以设置应允许所有客户端连接的安全描述符。在C ++中有code sample,但这在.NET中实际上是相同的:

// Security Descriptor with NO_EXECUTE_UP
var sd = new RawSecurityDescriptor("O:BAG:BAD:(A;;0xb;;;WD)S:(ML;;NX;;;LW)");
byte[] securityDescriptor = new Byte[sd.BinaryLength];
sd.GetBinaryForm(securityDescriptor, 0);

RegistryKey key = Registry.ClassesRoot.OpenSubKey("AppID\\{APP-ID-GUID}", true);
if (key == null)
{
    key = Registry.ClassesRoot.CreateSubKey("AppID\\{APP-ID-GUID}");
}

using (key)
{
    key.SetValue("LaunchPermission", securityDescriptor, RegistryValueKind.Binary);
}

但是,这没有达到预期的效果。当第二个客户端尝试创建相关对象的实例时,Windows会尝试启动COM服务器的单独实例,但服务器会阻止两个实例作为同一用户运行。鉴于我设置的权限,我不希望第一个实例首先启动。

由于其中一个客户端应用程序在Medium IL中运行,另一个在High IL中运行,我还在mandatory label上尝试了变体,如:

O:BAG:BAD:(A;;0xb;;;WD)S:(ML;;NX;;;ME)
O:BAG:BAD:(A;;0xb;;;WD)S:(ML;;NX;;;LW)(ML;;NX;;;ME)(ML;;NX;;;HI)

我也尝试按照页面上的建议将ROTFlags注册表项设置为0x1(ROTFLAGS_ALLOWANYCLIENT),但行为仍未改变。

我已经确定正在以某种方式使用LaunchPermission注册表值。我无法发现使用Process Monitor读取它的位置,但是当我使用dcomcnfg.exe工具设置相同的密钥时,我可以通过拒绝启动权限来强制服务器加载失败。

我想指出我的服务器进程不需要提升。如何使提升和非提升的进程都能够连接到单个服务器实例?

2 个答案:

答案 0 :(得分:1)

根据Windows Vista Security Model Analysis,您需要使用共享对象(如命名管道)在不同的IL之间进行操作。此外,共享对象的IL应等于您使用的最低IL。

答案 1 :(得分:0)

你必须将Debug选项设置为VS中的Any cpu。