54 votes

Autoriser la connexion à un serveur COM .NET dont le niveau d'intégrité n'est pas le même.

J'ai un problème avec une configuration client-serveur basée sur COM. Le serveur COM est écrit en C# (.NET 4.0) et fonctionne comme un serveur local (enregistré).

En fonction de l'application qui se connecte au serveur, les autres clients recevront une L'exécution du serveur a échoué (Exception de HRESULT : 0x80080005 (CO_E_SERVER_EXEC_FAILURE)

La question sous-jacente est expliquée ici (dans la section COM is integrity aware) . D'après ce que je comprends, le problème est dû au fait qu'une application élevée crée le serveur avec un niveau d'intégrité plus élevé. Lorsqu'une autre application non élevée se connecte ensuite, elle n'est pas autorisée à se connecter à la même instance. La même chose se produit lorsqu'une application non élevée crée le processus, suivi d'une application élevée qui se connecte.

J'ai essayé de mettre en œuvre la solution décrite sur le site Web de la Commission européenne. page : modifier le registre pour définir un descripteur de sécurité qui devrait permettre à tous les clients de se connecter. Il existe un exemple de code en C++, mais cela fait effectivement la même chose en .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);
}

Cependant, cela n'a pas l'effet escompté. Lorsque le deuxième client tente de créer une instance de l'objet en question, Windows essaie de lancer une instance distincte de mon serveur COM, mais ce dernier empêche l'exécution de deux instances sous le même utilisateur. Compte tenu des permissions que j'ai définies, je ne m'attendrais pas à ce qu'une deuxième instance soit lancée en premier lieu.

Étant donné que l'une des applications client est exécutée en IL moyen et l'autre en IL élevé, j'ai également expérimenté des variantes de l'option étiquette obligatoire comme :

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)

J'ai également essayé de définir le ROTFlags à 0x1 (ROTFLAGS_ALLOWANYCLIENT) comme suggéré sur la page, toujours aucun changement de comportement.

J'ai établi que la valeur de registre LaunchPermission est utilisée d'une manière ou d'une autre. Je ne parviens pas à découvrir où elle est lue à l'aide de Process Monitor, mais lorsque j'utilise la commande dcomcnfg.exe pour définir la même clé, je peux forcer le serveur à échouer le chargement en refusant les autorisations de lancement.

Je tiens à souligner que le processus de mon serveur n'a pas besoin d'être élevé. Comment puis-je faire en sorte que les processus élevés et non élevés puissent se connecter à une seule instance de serveur ?

1voto

user2214497 Points 51

Selon Analyse du modèle de sécurité de Windows Vista vous devrez utiliser des objets partagés tels qu'un tuyau nommé pour passer entre les différents IL. De plus, l'objet partagé doit avoir un IL équivalent à votre IL le plus bas utilisé.

0voto

Prakash Points 11

Vous devez régler l'option Debug sur Any cpu dans VS.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X