public IEnumerable <string> EnumerateAllowedIPAddresses() { return(allowedIPAddresses.Select(b => IPBanFirewallUtility.IPV4ToString(b))); }
// deleteRule will drop the rule and matching set before creating the rule and set, use this is you don't care to update the rule and set in place private List <uint> UpdateRule(string ruleName, string action, IEnumerable <string> ipAddresses, List <uint> existingIPAddresses, string hashType, int maxCount, bool deleteRule, IEnumerable <PortRange> allowPorts, CancellationToken cancelToken, out bool result) { string ipFile = GetSetFileName(ruleName); string ipFileTemp = ipFile + ".tmp"; List <uint> newIPAddressesUint = new List <uint>(); uint value = 0; // add and remove the appropriate ip addresses from the set using (StreamWriter writer = File.CreateText(ipFileTemp)) { if (cancelToken.IsCancellationRequested) { throw new OperationCanceledException(cancelToken); } writer.WriteLine($"create {ruleName} hash:{hashType} family {inetFamily} hashsize {hashSize} maxelem {maxCount} -exist"); foreach (string ipAddress in ipAddresses) { if (cancelToken.IsCancellationRequested) { throw new OperationCanceledException(cancelToken); } // only allow ipv4 for now if (IPAddressRange.TryParse(ipAddress, out IPAddressRange range) && range.Begin.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork && range.End.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork && // if deleting the rule, don't track the uint value (!deleteRule || (value = IPBanFirewallUtility.ParseIPV4(ipAddress)) != 0)) { try { if (range.Begin.Equals(range.End)) { writer.WriteLine($"add {ruleName} {range.Begin} -exist"); } else { writer.WriteLine($"add {ruleName} {range.ToCidrString()} -exist"); } if (!deleteRule) { newIPAddressesUint.Add(value); } } catch { // ignore invalid cidr ranges } } } newIPAddressesUint.Sort(); // if the rule was deleted, no need to add del entries if (!deleteRule) { // for ip that dropped out, remove from firewall foreach (uint droppedIP in existingIPAddresses.Where(e => newIPAddressesUint.BinarySearch(e) < 0)) { writer.WriteLine($"del {ruleName} {IPBanFirewallUtility.IPV4ToString(droppedIP)} -exist"); } } } if (cancelToken.IsCancellationRequested) { throw new OperationCanceledException(cancelToken); } else { // TODO: Is there an easier way to move to a file that exists? if (File.Exists(ipFile)) { DeleteFile(ipFile); } File.Move(ipFileTemp, ipFile); if (deleteRule) { DeleteRule(ruleName); } // restore the file to get the set updated result = (RunProcess("ipset", true, $"restore < \"{ipFile}\"") == 0); // ensure rule exists for the set CreateOrUpdateRule(ruleName, action, hashType, maxCount, allowPorts, cancelToken); } return(newIPAddressesUint); }