54

COMベースのクライアントサーバーセットアップに問題があります。COMサーバーはC#(.NET 4.0)で記述されており、(登録済みの)ローカルサーバーとして実行されます。

サーバーに接続するアプリケーションに応じて、他のクライアントはサーバーの実行に失敗します(HRESULTからの例外:0x80080005(CO_E_SERVER_EXEC_FAILURE))

根本的な問題はここで説明されています(セクションCOMは整合性を認識しています)。私の理解では、昇格したアプリケーションがより高い整合性レベルでサーバーを作成するという事実が原因です。次に、昇格されていない別のアプリケーションが接続する場合、同じインスタンスに接続することはできません。昇格されていないアプリケーションがプロセスを作成し、昇格されたアプリケーションが接続した場合も同じことが起こります。

このページで説明されている解決策を実装しようとしました。レジストリを変更して、すべてのクライアントが接続できるようにするセキュリティ記述子を設定します。C ++にはコードサンプルがありますが、これは.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);
}

ただし、これには望ましい効果はありません。2番目のクライアントが問題のオブジェクトのインスタンスを作成しようとすると、WindowsはCOMサーバーの別のインスタンスを起動しようとしますが、サーバーは2つのインスタンスが同じユーザーとして実行されるのを防ぎます。私が設定した権限を考えると、最初に2番目のインスタンスが起動することは期待できません。

クライアントアプリケーションの1つはMediumILで実行されており、もう1つはHigh ILで実行されているため、次のような必須ラベルのバリアントも試してみました。

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ツールを使用して同じキーを設定すると、起動権限を拒否することでサーバーの読み込みに失敗させることができます。

私のサーバープロセスは昇格を必要としないことを指摘したいと思います。昇格されたプロセスと昇格されていないプロセスの両方を単一のサーバーインスタンスに接続できるようにするにはどうすればよいですか?

4

2 に答える 2

1

Windows Vista セキュリティ モデル分析によると、名前付きパイプなどの共有オブジェクトを使用して異なる IL 間を移動する必要があります。また、共有オブジェクトには、使用されている最も低い IL と同等の IL が必要です。

于 2013-07-02T20:57:12.270 に答える
0

VSでDebugオプションをAny cpuに設定する必要があります。

于 2013-07-05T11:24:19.853 に答える