Я не думаю, что это будет возможно.
Проблема заключается в том, что метка целостности должна быть указана в дескрипторе безопасности, предоставленном при создании Именованного канала. В стандартном 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
на дескрипторе для добавления метки целостности.
Я планирую рассказать об этом подробнее в моем блоге в ближайшее время.