Как снизить целостность именованной трубы WCF - PullRequest
5 голосов
/ 31 октября 2010

У меня есть надстройка Internet Explorer, написанная на C #, которая взаимодействует через именованный канал WCF с настольным приложением .NET. Настольное приложение создает ServiceHost для netNamedPipeBinding, а каждый экземпляр надстройки IE создает ChannelFactory для связи с приложением. В Windows XP все работает нормально, но в защищенном режиме IE в Windows 7 создается исключение.

System.ServiceModel.CommunicationException: Невозможно подключиться к конечной точке 'net.pipe: //localhost/MyApp.MyID'. ---> System.IO.PipeException: конечная точка канала существует для '\. \ Pipe ... guid ...', но соединение не удалось: доступ запрещен. (5, 0x5)

Запуск надстройки в защищенном режиме - это сценарий, который я должен поддерживать. Насколько я понимаю, если я понизлю уровень целостности именованного канала, моей надстройке IE будет разрешено общаться через него. Мой вопрос, как это сделать. У меня есть настройки для использования WCF, и я бы хотел, чтобы все было так. Можно ли заставить WCF создать именованный канал с более низким уровнем целостности? Какой код я пишу, чтобы это произошло?

1 Ответ

7 голосов
/ 21 декабря 2010

Я не думаю, что это будет возможно.

Проблема заключается в том, что метка целостности должна быть указана в дескрипторе безопасности, предоставленном при создании Именованного канала. В стандартном NetNamedPipeBinding этот вызов CreateNamedPipe происходит внутри частного CreatePipe() метода внутреннего класса WCF System.ServiceModel.Channels.PipeConnectionListener. Я не вижу способа изменить способ определения исходного дескриптора безопасности для канала.

См. этот вопрос и ответ , чтобы получить общее представление о том, чего нам нужно достичь.

Создание настраиваемого элемента привязки именованного транспортного конвейера с нуля в настоящее время кажется единственным способом обойти это, в противном случае нам просто нужно подождать, пока Microsoft добавит некоторые включающие функции в будущую версию WCF. Если у вас есть доступ к Microsoft Connect, вы можете добавить свой голос другим, запрашивающим эту функцию .

EDIT: Я был слишком пессимистичен. Теперь я нашел способ сделать это.

Ключ заключался в том, что, как оказалось, необязательно указывать метку целостности в дескрипторе безопасности при создании канала, но необходимо изменить SACL, используя дескриптор, возвращенный из CreateNamedPipe, когда слушатель открыт т. е. самый первый дескриптор на стороне сервера. При использовании любого другого дескриптора попытка добавить метку целостности всегда терпит неудачу, поскольку параметр флага dwOpenMode для CreateNamedPipe перегружает использование одного из битов, что означает оба значения FILE_FLAG_FIRST_PIPE_INSTANCE и WRITE_OWNER. Для добавления метки целостности нам понадобится последнее разрешение на доступ, но наличие первого вызывает сбой вызова на любом, кроме первого экземпляра канала.

Получение первой рукоятки трубы не является тривиальным делом. WCF сжимает его в экземпляре типа System.ServiceModel.Channels.PipeConnectionListener.PendingAccept, хранящемся в списке, поддерживаемом прослушивателем соединения канала. Прослушиватель подключений - это не то же самое, что прослушиватель каналов (который можно получить напрямую путем переопределения метода BuildChannelListener<> элемента привязки), и получить его гораздо сложнее. Он включает в себя героику с использованием отражения, чтобы найти TransportManager для конечной точки, которая содержит ссылку на прослушиватель соединения конечной точки, а затем обрабатывать цепочку прослушивателей соединения (которая зависит от конфигурации трассировки и т. Д.), Пока не будет найден прослушиватель соединения канала , Если нам повезет, первый дескриптор канала может быть найден в списке ожидающих принятия слушателя (хотя здесь есть условие гонки - если клиент соединяется до того, как мы получим дескриптор, он исчезнет навсегда).

Как только дескриптор станет доступен, понижение целостности, чтобы позволить клиентам с низким уровнем целостности обмениваться данными со службой, - это просто вызов SetSecurityInfo на дескрипторе для добавления метки целостности.

Я планирую рассказать об этом подробнее в моем блоге в ближайшее время.

...