Подтвердить что ты не робот

Стороннее приложение нарушает наше приложение WCF

Наше приложение использует WCF по именованным каналам для связи между двумя процессами (обратите внимание: ни один из них не является службой Windows). Наше приложение работает без инцидентов уже пару лет.

Теперь мы получаем сообщения о том, что присутствие стороннего приложения (в частности, Garmin Express) ломается. Я установил Garmin Express в дом и подтвердил поведение. В частности, "Служба обновления ядра Garmin" при запуске приводит к сбою нашего приложения.

Когда служба Garmin запущена, начинается "сервисная" часть нашего приложения и не возникает проблем с созданием конечной точки WCF. Но когда клиент запускается и пытается подключиться к службе, он терпит неудачу с EndpointNotFoundException, как будто служба даже не работает.

На этом этапе я могу буквально остановить службу Garmin с панели управления Services, а затем повторно запустить клиента, даже не перезапустив нашу собственную услугу. Если я снова запустил сервис Garmin, дальнейшие попытки запустить клиент потерпят неудачу. Таким образом, это, по крайней мере, доказывает, что наша служба WCF работает и работает все время, а программное обеспечение Garmin каким-то образом блокирует способность наших клиентов подключаться к нему.

Мы используем собственное имя для адреса конечной точки (например, "net.pipe://localhost/MyPrivateApplication" ). Я попытался изменить этот адрес на другие имена, но это не влияет на проблему.

Как другое приложение, просто запустив, нарушит нашу собственную способность приложения использовать WCF?

Обновление: по запросу здесь приведен фрагмент кода со стороны службы. Я упростил его из нашего исходного кода, пытаясь изолировать проблему. Пока что ни одно изменение, которое я сделал, не повлияло на проблему.

MyService service = new MyService();
ServiceHost host = new ServiceHost(service);
string hostAddress = new Uri("net.pipe://localhost/MyWCFConnection");
host.AddServiceEndpoint(typeof(IMyService), new NetNamedPipeBinding(), hostAddress);
host.Open();
4b9b3361

Ответ 1

Один из возможных ответов на ваш вопрос "Как другое приложение, просто запустив, сломает наше собственное приложение...":

Я понятия не имею, действительно ли служба Garmin использует WCF NetNamedPipeBinding, но это одна из возможностей, которую вы должны исследовать. Эту проблему можно избежать всегда используя абсолютные URL-адреса для конечных точек NetNamedPipe.


ОК, поэтому, следуя обновлениям вопроса, мы теперь знаем, что служба Garmin использует WCF NetNamedPipeBinding, и мы знаем, что ваше приложение регистрирует свою службу с использованием абсолютного адреса, поэтому приведенное выше объяснение не является полной историей.

Вот еще одна гипотеза:

  • Предположим, что служба Garmin работает в процессе, который имеет привилегию безопасности SeCreateGlobalPrivilege (которую служба Windows будет иметь, если специально не закодирована, чтобы отключить эту привилегию).
  • Предположим, что он также регистрирует свою конечную точку Named Pipe WCF с базовым адресом net.pipe://localhost и относительными адресами конечных точек.
  • Теперь его метаданные службы будут опубликованы с использованием объекта сопоставления общей памяти с именем в глобальном пространстве имен.
  • Ваше служебное приложение не является службой Windows. Моя гипотеза заключается в том, что у ее процесса нет привилегии безопасности SeCreateGlobalPrivilege. Если это так, его метаданные службы будут опубликованы с использованием объекта сопоставления общей памяти только в пространстве имен локального сеанса.
  • Теперь ваш клиентский процесс пытается инициировать соединение, когда служба Garmin запущена... стек канала на стороне клиента WCF. Элемент NetNamedPipeBinding пытается найти метаданные службы для вашей службы на основе вашего URL-адреса службы net.pipe://локальный/MyWCFConnection. Как поясняется в приведенной выше ссылке, он будет выполнять поиск, используя различные варианты URL-адреса службы, в свою очередь, чтобы получить имя для объекта общей памяти, содержащего метаданные. Сначала он просматривается в глобальном пространстве имен, для полного списка вариантов по очереди, прежде чем смотреть в пространство имен.
  • В этом случае первая попытка будет для имени, полученного из "net.pipe://+/MyWCFConnection", и, по-видимому, ему не удается найти объект с этим именем в глобальном пространстве имен.
  • Однако вторая попытка будет основана на варианте "net.pipe://+/", и это будет соответствовать имени сопоставления общей памяти службы Garmin, опубликованного в глобальном пространстве имен. Из-за порядка поиска он никогда не попадет в ваши метаданные службы, опубликованные в пространстве имен локального сеанса.
  • Ваш клиент пытается подключиться к сервисному каналу Garmin. Предположим, что у службы Garmin есть определенная безопасность, которая приводит к отказу вашего клиента от отказа в доступе (например, он может установить ACL на своем канале). Результат может выглядеть как EndpointNotFoundException. [ LATER EDIT: На самом деле, скорее всего, происходит то, что ваш клиент фактически подключается к сервису Garmin, инициируя рукопожатие с преамбулой протокола кадрирования и получая отказ от отказа протокола кадров (http://schemas.microsoft.com/ws/2006/05/framing/faults/EndpointNotFound), потому что URL-адрес, запрошенный в записи Via, не будет соответствовать ожидаемому сервису Garmin. После этого связывание прекращает соединение и всплывает эта ошибка для вашего клиентского кода как исключение EndpointNotFoundException.]

Что вы можете сделать? Я бы предложил:

  • Если вышеупомянутая гипотеза или что-то подобное может быть подтверждено, и Garmin использует базовую + относительную адресацию с базой только net.pipe://localhost, лучше всего было бы заставить их владеть проблемой: они могли бы исправить такие проблема очень легко, изменив их базовый адрес на нечто более вероятное, чтобы быть уникальным.
  • Возможно, вы можете обойти это, найдя какой-то способ для вашего приложения-службы работать с привилегией безопасности SeCreateGlobalPrivilege: это непросто, не делая его службой Windows или работая как администратор, но, возможно, не исключая. Затем ваши метаданные также будут опубликованы в глобальном пространстве имен, и поиск клиента найдет его перед Garmin's.
  • [Редактировать позже] Возможно, существует обходное решение, связанное с установкой свойства HostNameComparisonMode привязки к Exact и использованием синонима для localhost как главной части URL-адреса службы (например, net.pipe://127.0.0.1/MyWCFConnection). Это может вести поиск по вариантам Garmin, чтобы ваш клиент имел возможность рассматривать имена в пространстве имен Local session. Я не знаю, что это сработает, но стоит попробовать, я бы подумал.
  • И очень длинный снимок: Есть ли у вашей компании отношения с Microsoft? Возможно, это серьезный недостаток дизайна в WCF: если вы беспокоитесь об этом, возможно, вы захотите, чтобы Microsoft выпустила патч QFE для него, например. чтобы предоставить свойство привязки, чтобы сообщить стеке на стороне клиента только попробовать пространство имен Local.

Ответ 2

Мы в Microsoft обнулили эту проблему тем, как Garmin Core Update Service создает именованные каналы. Именованные каналы могут быть созданы в разных областях - глобальном и локальном. Глобальный охват по сути является машинным, а локальный - специфичным для пользователя.  Приложение Garmins

а. работающий как системный сервис, поэтому область прослушивания сервиса named pipe является глобальной.

б. прослушивание корневого адреса "net.pipe://localhost/" (например, без каких-либо подпутей/сегментов).

с. Использование режима сравнения имен хостов StrongWildcard.

д. Элементы от a до c означают, что приложение Garmins по существу является уловкой для любого соединения net-pipe, которое не соответствует чему-то более конкретному.

е. Это также означает, что Garmin полностью блокирует всех слушателей, которые используют локальную область действия

Идеальное решение для этого было бы изменением в приложении Garmin таким образом, чтобы он регистрировал слушателя net.pipe с более конкретным URL-адресом.

Ответ 3

Я нашел метод для отображения, какие приложения используют net.pipe (хотя не обязательно, которые используют его неправильно).

Сначала загрузите приложение Handle от sysinternals:

https://technet.microsoft.com/en-us/sysinternals/handle.aspx?f=255&MSPPError=-2147217396

Затем откройте командную строку с правами администратора и запустите "Handle.exe net.pipe" (без кавычек). Это перечислит все приложения, использующие net.pipe, которые в настоящее время работают. Оттуда вы можете убивать или отключать по одному, пока ваш преступник не будет обнаружен. Я почти никогда не использую более 4-5 процессов. Если вам не удалось запустить командную строку от имени администратора, она может дать 0 результатов.

Ниже приведены все найденные приложения, которые мешают работе с net.pipe:

  • "Служба поддержки HP Support Framework" - затронуты только некоторые версии
  • "Служба обновления Garmin Core" - исправлено в новых версиях, но не работает
  • "WBE Service" - используется парой ноутбуков Dell в сочетании с беспроводной док-станцией
  • Служба Intel (R) Security Assist - я видел пару ноутбуков Win10 в начале 2016 года.
  • "Сервис Baraccuda WSA" - Агент веб-безопасности. Вероятно, расстроит клиента, если вы отключите это.
  • "DropboxOEM.exe" - вариант Dropbox для включения в приобретенные в магазине ПК. Пока заметил только на Win10. Это уникально, потому что это первое, что я обнаружил, это не служба Windows, насколько я могу судить.
  • "MTC Service" - устанавливается на некоторых компьютерах марки Getac. Не уверен, что он делает.
  • "pcdrcui.exe" - не служба, но запускается с правами администратора. Компонент Dell SupportAssist.
  • "Mitchell1/Shopkey SE Connection" или "ShopHubService" или "Mitchel1/Shopkey Data Backup Service" - служба синхронизации данных. Не уверен, что все это делает.

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