2015-10-23 9 views
0

Итак, у меня уже есть неплохая идея, как программно настроить правила брандмауэра с помощью COM-интерфейса INetFwPolicy2 и INetFwRule. Тем не менее, как я могу использовать COM-взаимодействие для настройки правила для определенного приложения «Modern App»/«Metro App»/«Store App»?Как настроить правило для приложения Store с помощью брандмауэра Windows?

Если я использую MMC брандмауэра, я могу перейти к:

правило -> Свойства -> Программы и услуги -> Пакеты приложений

и разрешить/блокировать указанные пакеты там. Но я понятия не имею, как это сделать в коде. Я нашел интерфейс INetFwRule3, который обеспечивает свойство LocalAppPackageId, что я и предполагаю, делает все волшебство. Но LocalAppPackageId содержит SID пакета, а не его имя, например, microsoft.windows.photos_8wekyb3d8bbwe. Итак, как я могу заблокировать пакет, который я хочу, когда все, что я знаю, это его имя? Думаю, мне нужно получить SID, так как я могу это найти? Является ли область SID локальной (уникальной для каждой машины), или я могу просто записать код SID, как только найду его, и не буду искать динамически динамически?

ответ

1

SID для контейнера приложения можно найти с помощью API-интерфейсов NetworkIsolationEnumAppContainers и ConvertSidToStringSid. Это то, что Fiddler does в их AppContainer Loopback Exemption Utility (вот как я нашел API).

Если вам небезразличен только SID и ничего больше, проще использовать DeriveAppContainerSidFromAppContainerName/ConvertSidToStringSid комбо. Вы даже не должны использовать ConvertSidToStringSid, рамки .NET уже обеспечивает преобразование:

private static string SidToString(IntPtr sid) 
{ 
    return new SecurityIdentifier(sid).Value; 
} 

достаточно Любопытно, что DeriveAppContainerSidFromAppContainerName не проверяет, существует ли контейнер приложение на системе, кажется, просто взять любой входной вас бросать на него и генерировать SID из этой информации в одиночку (например, хеш-функцию).

Так полный код:

public static string AppContainerNameToSid(string appContainerName) 
{ 
    var sid = IntPtr.Zero; 
    try 
    { 
     if (DeriveAppContainerSidFromAppContainerName(appContainerName, out sid) == 0) 
      return new SecurityIdentifier(sid).Value; 
     else 
      return null; 
    } 
    finally 
    { 
     if (sid != IntPtr.Zero) 
      FreeSid(sid); 
    } 
} 

[DllImport("userenv.dll", SetLastError = false, CharSet = CharSet.Unicode)] 
private static extern int DeriveAppContainerSidFromAppContainerName(string appContainerName, out IntPtr sid); 

[DllImport("advapi32.dll", SetLastError = false)] 
private static extern IntPtr FreeSid(IntPtr sid);