允许连接到具有不匹配完整性级别的.NET COM服务器 [英] Allowing connection to .NET COM server with mismatching integrity level

查看:112
本文介绍了允许连接到具有不匹配完整性级别的.NET COM服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm having an issue with a COM based client-server setup. The COM server is written in C# (.NET 4.0) and runs as a (registered) local server.

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

Depending on which application connects to the server, other clients will receive a Server execution failed (Exception from HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE)

解释了基本问题此处(在COM部分中是完整性感知)。据我所知,它是由以下事实引起的:提升的应用程序创建的服务器具有更高的完整性级别;然后再连接另一个非提升的应用程序时,则不允许连接到同一实例;当非提升的应用程序创建进程,然后提升的应用程序进行连接时,也会发生相同的情况。 。

The underlying issue is explained here (in the section COM is integrity aware). The way I understand it, it is being caused by the fact that an elevated application creates the server with a higher integrity level. When another non-elevated application then connects, it is not allowed to connect to the same instance. The same happens when a non-elevated application creates the process, followed an elevated application connecting.

我已经尝试实现页面:正在修改注册表设置一个安全描述符,该描述符应允许所有客户端连接。在C ++中有一个代码示例,但这实际上是一回事在.NET中:

I've tried to implement the solution described on the page: modifying the registry to set a security descriptor that should allow all clients to connect. There is a code sample in C++, but this does effectively the same thing in .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 Server的单独实例,但是该服务器阻止两个实例以同一用户身份运行。鉴于我已设置的权限,我不希望第二个实例首先启动。

However, this does not have the desired effect. When the second client tries to create an instance of the object in question, Windows tries to launch a separate instance of my COM Server, but the server prevents two instances from running as the same user. Given the permissions I've set, I would not expect a second instance to launch in the first place.

由于其中一个客户端应用程序在Medium IL中运行,并且在High IL中,我还尝试了必填标签上的变体,像这样:

Since one of the client applications is running in Medium IL and the other in High IL, I also experimented with variants on the mandatory label, like:

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),仍然没有行为上的变化。

I've also tried setting the ROTFlags registry key to 0x1 (ROTFLAGS_ALLOWANYCLIENT) as suggested on the page, still no change in behavior.

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

I've established that the LaunchPermission registry value is being used in some way. I cannot discover where it's being read using Process Monitor, but when I use the dcomcnfg.exe tool to set the same key, I can force the server to fail loading by denying launch permissions.

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

I would like to point out that my server process does not need elevation. How do I make both elevated and non-elevated processes capable of connecting to a single server instance?

推荐答案

根据 Windows Vista安全模型分析,您将需要使用共享对象,例如命名管道不同的IL。另外,共享对象的IL应该等于所使用的最低IL。

According to Windows Vista Security Model Analysis you will need to use shared objects such as a named pipe to go between the different IL. Also, the shared object should have an IL equivalent to your lowest IL being used.

这篇关于允许连接到具有不匹配完整性级别的.NET COM服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆