/// <summary> /// Create a firewall /// </summary> /// <param name="rulePrefix">Rule prefix or null for default</param> /// <returns>Firewall</returns> public static IIPBanFirewall CreateFirewall(string rulePrefix = null, IIPBanFirewall existing = null) { try { int priority = int.MinValue; Type firewallType = typeof(IIPBanFirewall); IReadOnlyCollection <Type> allTypes = ExtensionMethods.GetAllTypes(); var q = from fwType in allTypes where fwType.IsPublic && fwType != firewallType && firewallType.IsAssignableFrom(fwType) && fwType.GetCustomAttribute <RequiredOperatingSystemAttribute>() != null && fwType.GetCustomAttribute <RequiredOperatingSystemAttribute>().IsMatch select new { FirewallType = fwType, OS = fwType.GetCustomAttribute <RequiredOperatingSystemAttribute>(), Name = fwType.GetCustomAttribute <CustomNameAttribute>() }; var array = q.OrderBy(f => f.OS.Priority).ToArray(); foreach (var result in array) { // look up the requested firewall by os name bool matchPriority = priority < result.OS.Priority; if (matchPriority) { // if IsAvailable method is provided, attempt to call MethodInfo available = result.FirewallType.GetMethod("IsAvailable", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy); if (available != null) { try { if (!Convert.ToBoolean(available.Invoke(null, null))) { continue; } } catch { continue; } } firewallType = result.FirewallType; priority = result.OS.Priority; } } if (firewallType is null || firewallType == typeof(IIPBanFirewall)) { throw new ArgumentException("Firewall is null, at least one type should implement IIPBanFirewall"); } if (existing != null && existing.GetType().Equals(firewallType)) { return(existing); } return(Activator.CreateInstance(firewallType, new object[] { rulePrefix }) as IIPBanFirewall); } catch (Exception ex) { throw new ArgumentException("Unable to create firewall, please double check your Firewall configuration property", ex); } }
/// <summary> /// Create an IPBanService by searching all types in all assemblies /// </summary> /// <returns>IPBanService (if not found an exception is thrown)</returns> public static T CreateService <T>() where T : IPBanService { Type typeOfT = typeof(T); // if any derived class of IPBanService, use that List <Type> allTypes = ExtensionMethods.GetAllTypes(); var q = from type in allTypes where typeOfT.IsAssignableFrom(type) select type; Type instanceType = (q.FirstOrDefault() ?? typeof(IPBanService)); return(Activator.CreateInstance(instanceType, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, null, null) as T); }
/// <summary> /// Create a firewall /// </summary> /// <param name="osAndFirewall">Dictionary of string operating system name (Windows, Linux, OSX) and firewall class</param> /// <param name="rulePrefix">Rule prefix or null for default</param> /// <returns>Firewall</returns> public static IIPBanFirewall CreateFirewall(IReadOnlyDictionary <string, string> osAndFirewall, string rulePrefix = null, IIPBanFirewall existing = null) { try { bool foundFirewallType = false; int priority = int.MinValue; Type firewallType = typeof(IIPBanFirewall); List <Type> allTypes = ExtensionMethods.GetAllTypes(); var q = from fwType in allTypes where fwType.IsPublic && fwType != firewallType && firewallType.IsAssignableFrom(fwType) && fwType.GetCustomAttribute <RequiredOperatingSystemAttribute>() != null && fwType.GetCustomAttribute <RequiredOperatingSystemAttribute>().IsValid select new { FirewallType = fwType, OS = fwType.GetCustomAttribute <RequiredOperatingSystemAttribute>(), Name = fwType.GetCustomAttribute <CustomNameAttribute>() }; var array = q.ToArray(); foreach (var result in array) { // look up the requested firewall by os name bool matchPriority = priority < result.OS.Priority; if (matchPriority) { bool matchName = true; if (osAndFirewall != null && osAndFirewall.Count != 0 && (osAndFirewall.TryGetValue(OSUtility.Instance.Name, out string firewallToUse) || osAndFirewall.TryGetValue("*", out firewallToUse))) { matchName = result.Name.Name.Equals(firewallToUse, StringComparison.OrdinalIgnoreCase); } if (matchName) { // if IsAvailable method is provided, attempt to call MethodInfo available = result.FirewallType.GetMethod("IsAvailable", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy); if (available != null) { try { if (!Convert.ToBoolean(available.Invoke(null, null))) { continue; } } catch { continue; } } firewallType = result.FirewallType; priority = result.OS.Priority; foundFirewallType = true; } } } if (firewallType is null) { throw new ArgumentException("Firewall is null, at least one type should implement IIPBanFirewall"); } else if (osAndFirewall.Count != 0 && !foundFirewallType) { string typeString = string.Join(',', osAndFirewall.Select(kv => kv.Key + ":" + kv.Value)); throw new ArgumentException("Unable to find firewalls of types: " + typeString + ", osname: " + OSUtility.Instance.Name); } if (existing != null && existing.GetType().Equals(firewallType)) { return(existing); } return(Activator.CreateInstance(firewallType, new object[] { rulePrefix }) as IIPBanFirewall); } catch (Exception ex) { throw new ArgumentException("Unable to create firewall, please double check your Firewall configuration property", ex); } }
/// <summary> /// Create a firewall /// </summary> /// <param name="rulePrefix">Rule prefix or null for default</param> /// <returns>Firewall</returns> public static IIPBanFirewall CreateFirewall(string rulePrefix = null, IIPBanFirewall existing = null) { try { int priority = int.MinValue; Type firewallType = typeof(IIPBanFirewall); Type fallbackType = null; IReadOnlyCollection <Type> allTypes = ExtensionMethods.GetAllTypes(); var q = from fwType in allTypes where fwType.IsPublic && fwType != firewallType && firewallType.IsAssignableFrom(fwType) && fwType.GetCustomAttribute <RequiredOperatingSystemAttribute>() != null && fwType.GetCustomAttribute <RequiredOperatingSystemAttribute>().IsMatch select new { FirewallType = fwType, OS = fwType.GetCustomAttribute <RequiredOperatingSystemAttribute>(), Name = fwType.GetCustomAttribute <CustomNameAttribute>() }; var array = q.OrderBy(f => f.OS.Priority).ToArray(); foreach (var result in array) { // look up the requested firewall by os name bool matchPriority = priority < result.OS.Priority; if (matchPriority) { // if IsAvailable method is provided, attempt to call MethodInfo available = result.FirewallType.GetMethod("IsAvailable", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy); if (available != null) { try { if (!Convert.ToBoolean(available.Invoke(null, null))) { continue; } } catch { continue; } } firewallType = result.FirewallType; priority = result.OS.Priority; fallbackType = result.OS.FallbackFirewallType; } } if (firewallType is null || firewallType == typeof(IIPBanFirewall)) { throw new ArgumentException("Firewall is null, at least one type should implement IIPBanFirewall"); } RequiredOperatingSystemAttribute fallbackAttr = fallbackType?.GetCustomAttribute <RequiredOperatingSystemAttribute>(); Type existingType = existing?.GetType(); if (existingType != null && // if we have an existing firewall and ( firewallType.Equals(existingType)) || // if the existing firewall is the desired type or ( fallbackType != null && // we have a fallback type and ( fallbackType.Equals(existingType) || // the existing firewall is the fallback type or ( // the fallback firewall has another fallback firewall and it matches the existing type fallbackAttr?.FallbackFirewallType != null && fallbackAttr.FallbackFirewallType.Equals(existingType) ) ) ) ) { return(existing); } try { return(Activator.CreateInstance(firewallType, new object[] { rulePrefix }) as IIPBanFirewall); } catch (Exception ex) { // see if there's a fallback if (fallbackType is null) { throw; } Logger.Error(ex, "Failed to create firewall of type {0}, falling back to firewall type {1}", firewallType, fallbackType); try { return(Activator.CreateInstance(fallbackType, new object[] { rulePrefix }) as IIPBanFirewall); } catch (Exception ex2) { // last fallback attempt if (fallbackAttr?.FallbackFirewallType is null) { throw; } Logger.Error(ex2, "Failed to create firewall of type {0}, falling back to final attempt with firewall type {1}", fallbackType, fallbackAttr.FallbackFirewallType); return(Activator.CreateInstance(fallbackAttr.FallbackFirewallType, new object[] { rulePrefix }) as IIPBanFirewall); } } } catch (Exception ex) { throw new ArgumentException("Unable to create firewall, please double check your Firewall configuration property", ex); } }