允许连接到具有不匹配完整性级别的.NET COM服务器 [英] Allowing connection to .NET COM server with mismatching integrity level
问题描述
我在基于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屋!