123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Runtime.InteropServices;
- using System.Text;
- using System.Threading.Tasks;
- namespace MediaBrowser.ServerApplication.Native
- {
- /// <summary>
- /// http://blogs.msdn.com/b/fiddler/archive/2011/12/10/fiddler-windows-8-apps-enable-LoopUtil-network-isolation-exemption.aspx
- /// </summary>
- public class LoopUtil
- {
- //http://msdn.microsoft.com/en-us/library/windows/desktop/aa379595(v=vs.85).aspx
- [StructLayout(LayoutKind.Sequential)]
- internal struct SID_AND_ATTRIBUTES
- {
- public IntPtr Sid;
- public uint Attributes;
- }
- [StructLayoutAttribute(LayoutKind.Sequential)]
- internal struct INET_FIREWALL_AC_CAPABILITIES
- {
- public uint count;
- public IntPtr capabilities; //SID_AND_ATTRIBUTES
- }
- [StructLayoutAttribute(LayoutKind.Sequential)]
- internal struct INET_FIREWALL_AC_BINARIES
- {
- public uint count;
- public IntPtr binaries;
- }
- [StructLayoutAttribute(LayoutKind.Sequential)]
- internal struct INET_FIREWALL_APP_CONTAINER
- {
- internal IntPtr appContainerSid;
- internal IntPtr userSid;
- [MarshalAs(UnmanagedType.LPWStr)]
- public string appContainerName;
- [MarshalAs(UnmanagedType.LPWStr)]
- public string displayName;
- [MarshalAs(UnmanagedType.LPWStr)]
- public string description;
- internal INET_FIREWALL_AC_CAPABILITIES capabilities;
- internal INET_FIREWALL_AC_BINARIES binaries;
- [MarshalAs(UnmanagedType.LPWStr)]
- public string workingDirectory;
- [MarshalAs(UnmanagedType.LPWStr)]
- public string packageFullName;
- }
- // Call this API to free the memory returned by the Enumeration API
- [DllImport("FirewallAPI.dll")]
- internal static extern void NetworkIsolationFreeAppContainers(IntPtr pACs);
- // Call this API to load the current list of LoopUtil-enabled AppContainers
- [DllImport("FirewallAPI.dll")]
- internal static extern uint NetworkIsolationGetAppContainerConfig(out uint pdwCntACs, out IntPtr appContainerSids);
- // Call this API to set the LoopUtil-exemption list
- [DllImport("FirewallAPI.dll")]
- private static extern uint NetworkIsolationSetAppContainerConfig(uint pdwCntACs, SID_AND_ATTRIBUTES[] appContainerSids);
- // Use this API to convert a string SID into an actual SID
- [DllImport("advapi32.dll", SetLastError = true)]
- internal static extern bool ConvertStringSidToSid(string strSid, out IntPtr pSid);
- [DllImport("advapi32", CharSet = CharSet.Auto, SetLastError = true)]
- static extern bool ConvertSidToStringSid(
- [MarshalAs(UnmanagedType.LPArray)] byte[] pSID,
- out IntPtr ptrSid);
- [DllImport("advapi32", CharSet = CharSet.Auto, SetLastError = true)]
- static extern bool ConvertSidToStringSid(IntPtr pSid, out string strSid);
- // Use this API to convert a string reference (e.g. "@{blah.pri?ms-resource://whatever}") into a plain string
- [DllImport("shlwapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
- internal static extern int SHLoadIndirectString(string pszSource, StringBuilder pszOutBuf);
- // Call this API to enumerate all of the AppContainers on the system
- [DllImport("FirewallAPI.dll")]
- internal static extern uint NetworkIsolationEnumAppContainers(uint Flags, out uint pdwCntPublicACs, out IntPtr ppACs);
- // DWORD NetworkIsolationEnumAppContainers(
- // _In_ DWORD Flags,
- // _Out_ DWORD *pdwNumPublicAppCs,
- // _Out_ PINET_FIREWALL_APP_CONTAINER *ppPublicAppCs
- //);
- //http://msdn.microsoft.com/en-gb/library/windows/desktop/hh968116.aspx
- enum NETISO_FLAG
- {
- NETISO_FLAG_FORCE_COMPUTE_BINARIES = 0x1,
- NETISO_FLAG_MAX = 0x2
- }
- public class AppContainer
- {
- public String appContainerName { get; set; }
- public String displayName { get; set; }
- public String workingDirectory { get; set; }
- public String StringSid { get; set; }
- public List<uint> capabilities { get; set; }
- public bool LoopUtil { get; set; }
- public AppContainer(String _appContainerName, String _displayName, String _workingDirectory, IntPtr _sid)
- {
- this.appContainerName = _appContainerName;
- this.displayName = _displayName;
- this.workingDirectory = _workingDirectory;
- String tempSid;
- ConvertSidToStringSid(_sid, out tempSid);
- this.StringSid = tempSid;
- }
- }
- internal List<LoopUtil.INET_FIREWALL_APP_CONTAINER> _AppList;
- internal List<LoopUtil.SID_AND_ATTRIBUTES> _AppListConfig;
- public List<AppContainer> Apps = new List<AppContainer>();
- internal IntPtr _pACs;
- public LoopUtil()
- {
- LoadApps();
- }
- public void LoadApps()
- {
- Apps.Clear();
- _pACs = IntPtr.Zero;
- //Full List of Apps
- _AppList = PI_NetworkIsolationEnumAppContainers();
- //List of Apps that have LoopUtil enabled.
- _AppListConfig = PI_NetworkIsolationGetAppContainerConfig();
- foreach (var PI_app in _AppList)
- {
- AppContainer app = new AppContainer(PI_app.appContainerName, PI_app.displayName, PI_app.workingDirectory, PI_app.appContainerSid);
- var app_capabilities = LoopUtil.getCapabilites(PI_app.capabilities);
- if (app_capabilities.Count > 0)
- {
- //var sid = new SecurityIdentifier(app_capabilities[0], 0);
- IntPtr arrayValue = IntPtr.Zero;
- //var b = LoopUtil.ConvertStringSidToSid(app_capabilities[0].Sid, out arrayValue);
- //string mysid;
- //var b = LoopUtil.ConvertSidToStringSid(app_capabilities[0].Sid, out mysid);
- }
- app.LoopUtil = CheckLoopback(PI_app.appContainerSid);
- Apps.Add(app);
- }
- }
- private bool CheckLoopback(IntPtr intPtr)
- {
- foreach (SID_AND_ATTRIBUTES item in _AppListConfig)
- {
- string left, right;
- ConvertSidToStringSid(item.Sid, out left);
- ConvertSidToStringSid(intPtr, out right);
- if (left == right)
- {
- return true;
- }
- }
- return false;
- }
- private bool CreateExcemptions(string appName)
- {
- var hasChanges = false;
- foreach (var app in Apps)
- {
- if ((app.appContainerName ?? string.Empty).IndexOf(appName, StringComparison.OrdinalIgnoreCase) != -1 ||
- (app.displayName ?? string.Empty).IndexOf(appName, StringComparison.OrdinalIgnoreCase) != -1)
- {
- if (!app.LoopUtil)
- {
- app.LoopUtil = true;
- hasChanges = true;
- }
- }
- }
- return hasChanges;
- }
- public static void Run(string appName)
- {
- var util = new LoopUtil();
- util.LoadApps();
- var hasChanges = util.CreateExcemptions(appName);
- if (hasChanges)
- {
- util.SaveLoopbackState();
- }
- util.SaveLoopbackState();
- }
- private static List<SID_AND_ATTRIBUTES> getCapabilites(INET_FIREWALL_AC_CAPABILITIES cap)
- {
- List<SID_AND_ATTRIBUTES> mycap = new List<SID_AND_ATTRIBUTES>();
- IntPtr arrayValue = cap.capabilities;
- var structSize = Marshal.SizeOf(typeof(SID_AND_ATTRIBUTES));
- for (var i = 0; i < cap.count; i++)
- {
- var cur = (SID_AND_ATTRIBUTES)Marshal.PtrToStructure(arrayValue, typeof(SID_AND_ATTRIBUTES));
- mycap.Add(cur);
- arrayValue = new IntPtr((long)(arrayValue) + (long)(structSize));
- }
- return mycap;
- }
- private static List<SID_AND_ATTRIBUTES> getContainerSID(INET_FIREWALL_AC_CAPABILITIES cap)
- {
- List<SID_AND_ATTRIBUTES> mycap = new List<SID_AND_ATTRIBUTES>();
- IntPtr arrayValue = cap.capabilities;
- var structSize = Marshal.SizeOf(typeof(SID_AND_ATTRIBUTES));
- for (var i = 0; i < cap.count; i++)
- {
- var cur = (SID_AND_ATTRIBUTES)Marshal.PtrToStructure(arrayValue, typeof(SID_AND_ATTRIBUTES));
- mycap.Add(cur);
- arrayValue = new IntPtr((long)(arrayValue) + (long)(structSize));
- }
- return mycap;
- }
- private static List<SID_AND_ATTRIBUTES> PI_NetworkIsolationGetAppContainerConfig()
- {
- IntPtr arrayValue = IntPtr.Zero;
- uint size = 0;
- var list = new List<SID_AND_ATTRIBUTES>();
- // Pin down variables
- GCHandle handle_pdwCntPublicACs = GCHandle.Alloc(size, GCHandleType.Pinned);
- GCHandle handle_ppACs = GCHandle.Alloc(arrayValue, GCHandleType.Pinned);
- uint retval = NetworkIsolationGetAppContainerConfig(out size, out arrayValue);
- var structSize = Marshal.SizeOf(typeof(SID_AND_ATTRIBUTES));
- for (var i = 0; i < size; i++)
- {
- var cur = (SID_AND_ATTRIBUTES)Marshal.PtrToStructure(arrayValue, typeof(SID_AND_ATTRIBUTES));
- list.Add(cur);
- arrayValue = new IntPtr((long)(arrayValue) + (long)(structSize));
- }
- //release pinned variables.
- handle_pdwCntPublicACs.Free();
- handle_ppACs.Free();
- return list;
- }
- private List<INET_FIREWALL_APP_CONTAINER> PI_NetworkIsolationEnumAppContainers()
- {
- IntPtr arrayValue = IntPtr.Zero;
- uint size = 0;
- var list = new List<INET_FIREWALL_APP_CONTAINER>();
- // Pin down variables
- GCHandle handle_pdwCntPublicACs = GCHandle.Alloc(size, GCHandleType.Pinned);
- GCHandle handle_ppACs = GCHandle.Alloc(arrayValue, GCHandleType.Pinned);
- //uint retval2 = NetworkIsolationGetAppContainerConfig( out size, out arrayValue);
- uint retval = NetworkIsolationEnumAppContainers((Int32)NETISO_FLAG.NETISO_FLAG_MAX, out size, out arrayValue);
- _pACs = arrayValue; //store the pointer so it can be freed when we close the form
- var structSize = Marshal.SizeOf(typeof(INET_FIREWALL_APP_CONTAINER));
- for (var i = 0; i < size; i++)
- {
- var cur = (INET_FIREWALL_APP_CONTAINER)Marshal.PtrToStructure(arrayValue, typeof(INET_FIREWALL_APP_CONTAINER));
- list.Add(cur);
- arrayValue = new IntPtr((long)(arrayValue) + (long)(structSize));
- }
- //release pinned variables.
- handle_pdwCntPublicACs.Free();
- handle_ppACs.Free();
- return list;
- }
- public bool SaveLoopbackState()
- {
- var countEnabled = CountEnabledLoopUtil();
- SID_AND_ATTRIBUTES[] arr = new SID_AND_ATTRIBUTES[countEnabled];
- int count = 0;
- for (int i = 0; i < Apps.Count; i++)
- {
- if (Apps[i].LoopUtil)
- {
- arr[count].Attributes = 0;
- //TO DO:
- IntPtr ptr;
- ConvertStringSidToSid(Apps[i].StringSid, out ptr);
- arr[count].Sid = ptr;
- count++;
- }
- }
- if (NetworkIsolationSetAppContainerConfig((uint)countEnabled, arr) == 0)
- {
- return true;
- }
- else
- { return false; }
- }
- private int CountEnabledLoopUtil()
- {
- var count = 0;
- for (int i = 0; i < Apps.Count; i++)
- {
- if (Apps[i].LoopUtil)
- {
- count++;
- }
- }
- return count;
- }
- public void FreeResources()
- {
- NetworkIsolationFreeAppContainers(_pACs);
- }
- }
- }
|