示例#1
0
        private List <uint> LoadIPAddresses(string ruleName, string action, string hashType, int maxCount)
        {
            List <uint> ipAddresses = new List <uint>();

            try
            {
                if (hashType != "ip")
                {
                    throw new ArgumentException("Can only load hash of type 'ip'");
                }

                CreateOrUpdateRule(ruleName, action, hashType, maxCount, null, default);

                // copy ip addresses from the rule to the set
                string fileName = GetSetFileName(ruleName);
                if (File.Exists(fileName))
                {
                    uint value;
                    foreach (string line in File.ReadLines(fileName).Skip(1))
                    {
                        string[] pieces = line.Split(' ');
                        if (pieces.Length > 2 && pieces[0] == "add" && (value = IPBanFirewallUtility.ParseIPV4(pieces[2])) != 0)
                        {
                            ipAddresses.Add(value);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                IPBanLog.Error(ex);
            }

            return(ipAddresses);
        }
示例#2
0
        private int RunProcess(string program, bool requireExitCode, out IReadOnlyList <string> lines, string commandLine, params object[] args)
        {
            commandLine = program + " " + string.Format(commandLine, args);
            commandLine = "-c \"" + commandLine.Replace("\"", "\\\"") + "\"";
            IPBanLog.Debug("Running firewall process: /bin/bash {0}", commandLine);
            Process p = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    FileName               = "/bin/bash",
                    Arguments              = commandLine,
                    UseShellExecute        = false,
                    CreateNoWindow         = true,
                    RedirectStandardOutput = true
                }
            };

            p.Start();
            List <string> lineList = new List <string>();
            string        line;

            while ((line = p.StandardOutput.ReadLine()) != null)
            {
                lineList.Add(line);
            }
            lines = lineList;
            p.WaitForExit();
            if (requireExitCode && p.ExitCode != 0)
            {
                IPBanLog.Error("Process {0} had exit code {1}", commandLine, p.ExitCode);
            }
            return(p.ExitCode);
        }
示例#3
0
 private void EventRecordWritten(object sender, EventRecordWrittenEventArgs e)
 {
     try
     {
         if (e != null && e.EventRecord != null)
         {
             EventRecord rec = e.EventRecord;
             string      xml = null;
             try
             {
                 xml = rec.ToXml();
             }
             catch
             {
             }
             if (xml != null)
             {
                 ProcessEventViewerXml(xml);
             }
         }
     }
     catch (Exception ex)
     {
         IPBanLog.Error(ex);
     }
 }
示例#4
0
 public bool DeleteRules(int startIndex = 0)
 {
     try
     {
         lock (policy)
         {
             for (int i = startIndex; ; i += maxIpAddressesPerRule)
             {
                 string ruleName = RulePrefix + i.ToString(CultureInfo.InvariantCulture);
                 try
                 {
                     INetFwRule rule = policy.Rules.Item(ruleName);
                     if (rule == null)
                     {
                         break;
                     }
                     policy.Rules.Remove(ruleName);
                 }
                 catch
                 {
                     break;
                 }
             }
         }
         return(true);
     }
     catch (Exception ex)
     {
         IPBanLog.Error(ex);
         return(false);
     }
 }
示例#5
0
        private void PingFiles()
        {
            try
            {
                pingTimer.Enabled = false;
            }
            catch
            {
            }

            try
            {
                // re-open files and read one byte to flush disk cache
                foreach (WatchedFile file in UpdateWatchedFiles())
                {
                    // if file length has changed, ping the file
                    bool delete = false;
                    long len    = new FileInfo(file.FileName).Length;

                    // if file has shrunk (deleted and recreated for example) reset positions to 0
                    if (len < file.LastLength || len < file.LastPosition)
                    {
                        file.LastPosition = 0;
                    }

                    // use file info for length compare to avoid doing a full file open
                    if (len != file.LastLength)
                    {
                        using (FileStream fs = new FileStream(file.FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                        {
                            file.LastLength = len;
                            delete          = PingFile(file, fs);
                        }
                    }
                    if (delete)
                    {
                        try
                        {
                            File.Delete(file.FileName);
                        }
                        catch
                        {
                            // OK someone else might have it open, in which case we have no chance to delete
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                IPBanLog.Error(ex);
            }

            try
            {
                pingTimer.Enabled = true;
            }
            catch
            {
            }
        }
示例#6
0
 public bool IsIPAddressAllowed(string ipAddress)
 {
     try
     {
         lock (policy)
         {
             for (int i = 0; ; i += MaxIpAddressesPerRule)
             {
                 string ruleName = allowRulePrefix + i.ToString(CultureInfo.InvariantCulture);
                 try
                 {
                     INetFwRule rule = policy.Rules.Item(ruleName);
                     if (rule == null)
                     {
                         break;
                     }
                     else if (rule.RemoteAddresses.Contains(ipAddress))
                     {
                         return(true);
                     }
                 }
                 catch
                 {
                     // OK, rule does not exist
                 }
             }
         }
     }
     catch (Exception ex)
     {
         IPBanLog.Error(ex);
     }
     return(false);
 }
示例#7
0
        private void SetupEventLogWatcher()
        {
            try
            {
                List <string> ignored     = new List <string>();
                string        queryString = GetEventLogQueryString(ignored);
                if (queryString != previousQueryString)
                {
                    IPBanLog.Warn("Event viewer query string: {0}", queryString);
                    foreach (string path in ignored)
                    {
                        IPBanLog.Warn("Ignoring event viewer path {0}", path);
                    }

                    watcher?.Dispose();
                    query   = new EventLogQuery(null, PathType.LogName, queryString);
                    watcher = new EventLogWatcher(query);
                    watcher.EventRecordWritten += EventRecordWritten;
                    watcher.Enabled             = true;
                    previousQueryString         = queryString;
                }
            }
            catch (Exception ex)
            {
                IPBanLog.Error("Failed to create event viewer watcher", ex);
            }
        }
示例#8
0
        public Task <bool> BlockIPAddresses(string ruleNamePrefix, IEnumerable <IPAddressRange> ranges, IEnumerable <PortRange> allowedPorts, CancellationToken cancelToken = default)
        {
            if (string.IsNullOrWhiteSpace(ruleNamePrefix))
            {
                return(Task.FromResult(false));
            }

            try
            {
                string prefix = (RulePrefix + ruleNamePrefix).TrimEnd('_') + "_";

                // recreate rules
                int           counter = 0;
                int           index   = 0;
                StringBuilder ipList  = new StringBuilder();
                foreach (IPAddressRange range in ranges)
                {
                    if (cancelToken.IsCancellationRequested)
                    {
                        throw new OperationCanceledException(cancelToken);
                    }
                    ipList.Append(range.ToCidrString());
                    ipList.Append(',');
                    if (++counter == MaxIpAddressesPerRule)
                    {
                        ipList.Length--; // remove ending comma
                        GetOrCreateRule(prefix + index.ToString(CultureInfo.InvariantCulture), ipList.ToString(), NET_FW_ACTION_.NET_FW_ACTION_BLOCK, allowedPorts);
                        counter = 0;
                        index  += MaxIpAddressesPerRule;
                        ipList.Clear();
                    }
                }
                if (cancelToken.IsCancellationRequested)
                {
                    throw new OperationCanceledException(cancelToken);
                }

                // create rule for any leftover ip addresses
                if (ipList.Length > 1)
                {
                    ipList.Length--; // remove ending comma
                    GetOrCreateRule(prefix + index.ToString(CultureInfo.InvariantCulture), ipList.ToString(), NET_FW_ACTION_.NET_FW_ACTION_BLOCK, allowedPorts);
                    index += MaxIpAddressesPerRule;
                }

                // delete any leftover rules
                DeleteRules(prefix, index);
                return(Task.FromResult(true));
            }
            catch (Exception ex)
            {
                IPBanLog.Error(ex);
                return(Task.FromResult(false));
            }
        }
示例#9
0
 public Task <bool> BlockIPAddresses(IEnumerable <string> ipAddresses, CancellationToken cancelToken = default)
 {
     try
     {
         bannedIPAddresses = UpdateRule(blockRuleName, "DROP", ipAddresses, bannedIPAddresses, "ip", blockRuleMaxCount, false, null, cancelToken, out bool result);
         return(Task.FromResult(result));
     }
     catch (Exception ex)
     {
         IPBanLog.Error(ex);
         return(Task.FromResult(false));
     }
 }
示例#10
0
 public Task <bool> AllowIPAddresses(IEnumerable <string> ipAddresses, CancellationToken cancelToken = default)
 {
     try
     {
         allowedIPAddresses = UpdateRule(allowRuleName, "ACCEPT", ipAddresses, allowedIPAddresses, "ip", allowRuleMaxCount, false, null, cancelToken, out bool result);
         return(Task.FromResult <bool>(result));
     }
     catch (Exception ex)
     {
         IPBanLog.Error(ex);
         return(Task.FromResult <bool>(false));
     }
 }
示例#11
0
 /// <summary>
 /// Update - if the text file path exists, all ip addresses from each line will be unbanned
 /// </summary>
 public void Update()
 {
     try
     {
         if (File.Exists(textFilePath))
         {
             UnbanIPAddresses(File.ReadLines(textFilePath));
             File.Delete(textFilePath);
         }
     }
     catch (Exception ex)
     {
         IPBanLog.Error(ex);
     }
 }
示例#12
0
        public void UnblockIPAddresses(IEnumerable <string> ipAddresses)
        {
            try
            {
                lock (policy)
                {
                    for (int i = 0; ; i += MaxIpAddressesPerRule)
                    {
                        string ruleName = RulePrefix + i.ToString(CultureInfo.InvariantCulture);
                        try
                        {
                            INetFwRule rule = policy.Rules.Item(ruleName);
                            if (rule == null)
                            {
                                // no more rules to check
                                break;
                            }
                            string remoteIPs = rule.RemoteAddresses;
                            foreach (string ipAddress in ipAddresses)
                            {
                                remoteIPs = Regex.Replace(remoteIPs, ipAddress.Replace(".", "\\.") + "\\/[^,]+,?", ",", RegexOptions.IgnoreCase);
                                remoteIPs = remoteIPs.Replace(",,", ",");
                                remoteIPs = remoteIPs.Trim().Trim(',');
                            }

                            // ensure we don't have a block rule with no ip addresses, this will block the entire world (WTF Microsoft)...
                            if (string.IsNullOrWhiteSpace(remoteIPs))
                            {
                                policy.Rules.Remove(rule.Name);
                            }
                            else
                            {
                                rule.RemoteAddresses = remoteIPs;
                            }
                        }
                        catch
                        {
                            // no more rules to check
                            break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                IPBanLog.Error(ex);
            }
        }
示例#13
0
 public bool BlockIPAddresses(IReadOnlyList <string> ipAddresses)
 {
     try
     {
         int i;
         for (i = 0; i < ipAddresses.Count; i += maxIpAddressesPerRule)
         {
             CreateBlockRule(ipAddresses, i, maxIpAddressesPerRule);
         }
         DeleteRules(i);
         return(true);
     }
     catch (Exception ex)
     {
         IPBanLog.Error(ex);
         return(false);
     }
 }
示例#14
0
 public Task <bool> AllowIPAddresses(IEnumerable <string> ipAddresses, CancellationToken cancelToken = default)
 {
     try
     {
         List <string> ipAddressesList = new List <string>();
         int           i = 0;
         foreach (string ipAddress in ipAddresses)
         {
             if (cancelToken.IsCancellationRequested)
             {
                 throw new OperationCanceledException();
             }
             ipAddressesList.Add(ipAddress);
             if (ipAddressesList.Count == MaxIpAddressesPerRule)
             {
                 string remoteIP = CreateRuleStringForIPAddresses(ipAddressesList, i, MaxIpAddressesPerRule);
                 GetOrCreateRule(allowRulePrefix + i.ToString(CultureInfo.InvariantCulture), remoteIP, NET_FW_ACTION_.NET_FW_ACTION_ALLOW);
                 i += MaxIpAddressesPerRule;
                 ipAddressesList.Clear();
             }
         }
         if (cancelToken.IsCancellationRequested)
         {
             throw new OperationCanceledException();
         }
         if (ipAddressesList.Count != 0)
         {
             string remoteIP = CreateRuleStringForIPAddresses(ipAddressesList, i, MaxIpAddressesPerRule);
             GetOrCreateRule(allowRulePrefix + i.ToString(CultureInfo.InvariantCulture), remoteIP, NET_FW_ACTION_.NET_FW_ACTION_ALLOW);
             i += MaxIpAddressesPerRule;
         }
         if (cancelToken.IsCancellationRequested)
         {
             throw new OperationCanceledException();
         }
         DeleteRules(allowRulePrefix, i);
         return(Task.FromResult <bool>(true));
     }
     catch (Exception ex)
     {
         IPBanLog.Error(ex);
         return(Task.FromResult <bool>(false));
     }
 }
示例#15
0
        public Task <bool> BlockIPAddresses(string ruleNamePrefix, IEnumerable <IPAddressRange> ranges, IEnumerable <PortRange> allowedPorts, CancellationToken cancelToken = default)
        {
            if (string.IsNullOrWhiteSpace(ruleNamePrefix))
            {
                return(Task.FromResult(false));
            }

            try
            {
                string ruleName = RulePrefix + "_" + ruleNamePrefix + "_0";
                UpdateRule(ruleName, "DROP", ranges.Select(r => r.ToCidrString()), null, "net", blockRuleRangesMaxCount, true, allowedPorts, cancelToken, out bool result);
                return(Task.FromResult(result));
            }
            catch (Exception ex)
            {
                IPBanLog.Error(ex);
                return(Task.FromResult(false));
            }
        }
示例#16
0
 private static void LoadVersionFromWmiApi()
 {
     try
     {
         // WMI API sometimes fails to initialize on .NET core on some systems, not sure why...
         // fall-back to WMI, maybe future .NET core versions will fix the bug
         using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT Caption, Version FROM Win32_OperatingSystem"))
         {
             foreach (var result in searcher.Get())
             {
                 FriendlyName = result["Caption"] as string;
                 Version      = result["Version"] as string;
                 break;
             }
         }
     }
     catch (Exception ex)
     {
         IPBanLog.Error(ex, "Unable to load os version from wmi api");
     }
 }
示例#17
0
 public Task <bool> BlockIPAddresses(IEnumerable <string> ipAddresses, CancellationToken cancelToken = default)
 {
     try
     {
         int           i = 0;
         List <string> ipAddressesList = new List <string>();
         foreach (string ipAddress in ipAddresses)
         {
             if (cancelToken.IsCancellationRequested)
             {
                 throw new OperationCanceledException(cancelToken);
             }
             ipAddressesList.Add(ipAddress);
             if (ipAddressesList.Count == MaxIpAddressesPerRule)
             {
                 CreateBlockRule(ipAddressesList, 0, MaxIpAddressesPerRule, RulePrefix + i.ToStringInvariant());
                 i += MaxIpAddressesPerRule;
                 ipAddressesList.Clear();
             }
         }
         if (cancelToken.IsCancellationRequested)
         {
             throw new OperationCanceledException(cancelToken);
         }
         if (ipAddressesList.Count != 0)
         {
             CreateBlockRule(ipAddressesList, 0, MaxIpAddressesPerRule, RulePrefix + i.ToStringInvariant());
             i += MaxIpAddressesPerRule;
         }
         DeleteRules(RulePrefix, i);
         return(Task.FromResult(true));
     }
     catch (Exception ex)
     {
         IPBanLog.Error(ex);
         return(Task.FromResult(false));
     }
 }
示例#18
0
 public bool IsIPAddressAllowed(string ipAddress)
 {
     try
     {
         lock (policy)
         {
             string ruleName = RulePrefix + "AllowIPAddresses";
             try
             {
                 INetFwRule rule = policy.Rules.Item(ruleName);
                 return(rule != null && rule.RemoteAddresses.Contains(ipAddress));
             }
             catch
             {
                 // OK, rule does not exist
             }
         }
     }
     catch (Exception ex)
     {
         IPBanLog.Error(ex);
     }
     return(false);
 }
示例#19
0
        static IPBanOS()
        {
            try
            {
                Version     = Environment.OSVersion.VersionString;
                Description = RuntimeInformation.OSDescription;
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    string tempFile = Path.GetTempFileName();
                    Process.Start("/bin/bash", "-c \"cat /etc/*release* > " + tempFile + "\"").WaitForExit();
                    string versionText = File.ReadAllText(tempFile);
                    File.Delete(tempFile);
                    Name         = IPBanOS.Linux;
                    FriendlyName = ExtractRegex(versionText, "^(Id|Distrib_Id)=(?<value>.*?)$", string.Empty);
                    if (FriendlyName.Length != 0)
                    {
                        string codeName = ExtractRegex(versionText, "^(Name|Distrib_CodeName)=(?<value>.+)$", string.Empty);
                        if (codeName.Length != 0)
                        {
                            FriendlyName += " - " + codeName;
                        }
                        Version = ExtractRegex(versionText, "^Version_Id=(?<value>.+)$", Version);
                    }
                }
                else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    Name = IPBanOS.Windows;
                    string tempFile = Path.GetTempFileName();

                    // .net core WMI has a strange bug where WMI will not initialize on some systems
                    // since this is the only place where WMI is used, we can just work-around it
                    // with the wmic executable, which exists (as of 2018) on all supported Windows.
                    StartProcessAndWait("cmd", "/C wmic path Win32_OperatingSystem get Caption,Version /format:table > \"" + tempFile + "\"");
                    if (File.Exists(tempFile))
                    {
                        string[] lines = File.ReadAllLines(tempFile);
                        File.Delete(tempFile);
                        if (lines.Length > 1)
                        {
                            int versionIndex = lines[0].IndexOf("Version");
                            if (versionIndex >= 0)
                            {
                                FriendlyName = lines[1].Substring(0, versionIndex - 1).Trim();
                                Version      = lines[1].Substring(versionIndex).Trim();
                            }
                        }
                    }
                    else
                    {
                        // fall-back to WMI, maybe future .NET core versions will fix the bug
                        using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT Caption, Version FROM Win32_OperatingSystem"))
                        {
                            foreach (var result in searcher.Get())
                            {
                                FriendlyName = result["Caption"] as string;
                                Version      = result["Version"] as string;
                                break;
                            }
                        }
                    }
                }
                else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
                {
                    // TODO: Implement better for MAC
                    Name         = IPBanOS.Mac;
                    FriendlyName = "OSX";
                }
                else
                {
                    Name         = IPBanOS.Unknown;
                    FriendlyName = "Unknown";
                }
            }
            catch (Exception ex)
            {
                IPBanLog.Error(ex);
            }
        }
示例#20
0
        private IPBanConfig(string xml, IDnsLookup dns)
        {
            this.dns = dns;

            // deserialize with XmlDocument, the .net core Configuration class is quite buggy
            XmlDocument doc = new XmlDocument();

            doc.LoadXml(xml);
            foreach (XmlNode node in doc.SelectNodes("//appSettings/add"))
            {
                appSettings[node.Attributes["key"].Value] = node.Attributes["value"].Value;
            }

            GetConfig <int>("FailedLoginAttemptsBeforeBan", ref failedLoginAttemptsBeforeBan);
            GetConfig <TimeSpan>("BanTime", ref banTime);
            GetConfig <bool>("ClearBannedIPAddressesOnRestart", ref clearBannedIPAddressesOnRestart);
            GetConfig <TimeSpan>("ExpireTime", ref expireTime);
            GetConfig <TimeSpan>("CycleTime", ref cycleTime);
            GetConfig <TimeSpan>("MinimumTimeBetweenFailedLoginAttempts", ref minimumTimeBetweenFailedLoginAttempts);
            GetConfig <string>("FirewallRulePrefix", ref firewallRulePrefix);
            GetConfig <bool>("CreateWhitelistFirewallRule", ref createWhitelistFirewallRule);

            string whiteListString      = GetConfig <string>("Whitelist", string.Empty);
            string whiteListRegexString = GetConfig <string>("WhitelistRegex", string.Empty);
            string blacklistString      = GetConfig <string>("Blacklist", string.Empty);
            string blacklistRegexString = GetConfig <string>("BlacklistRegex", string.Empty);

            PopulateList(whiteList, ref whiteListRegex, whiteListString, whiteListRegexString);
            PopulateList(blackList, ref blackListRegex, blacklistString, blacklistRegexString);
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                expressions = new XmlSerializer(typeof(ExpressionsToBlock)).Deserialize(new XmlNodeReader(doc.SelectSingleNode("//ExpressionsToBlock"))) as ExpressionsToBlock;
                if (expressions != null)
                {
                    foreach (ExpressionsToBlockGroup group in expressions.Groups)
                    {
                        foreach (ExpressionToBlock expression in group.Expressions)
                        {
                            expression.Regex = (expression.Regex ?? string.Empty).Trim();
                        }
                    }
                }
            }
            else
            {
                expressions = new ExpressionsToBlock {
                    Groups = new ExpressionsToBlockGroup[0]
                };
            }
            try
            {
                LogFilesToParse logFilesToParse = new XmlSerializer(typeof(LogFilesToParse)).Deserialize(new XmlNodeReader(doc.SelectSingleNode("//LogFilesToParse"))) as LogFilesToParse;
                logFiles = (logFilesToParse == null ? new LogFileToParse[0] : logFilesToParse.LogFiles);
            }
            catch (Exception ex)
            {
                IPBanLog.Error(ex);
                logFiles = new LogFileToParse[0];
            }
            GetConfig <string>("ProcessToRunOnBan", ref processToRunOnBan);

            // retrieve firewall configuration
            string[] firewallTypes = GetConfig <string>("FirewallType", string.Empty).Split(',', StringSplitOptions.RemoveEmptyEntries);
            foreach (string firewallOSAndType in firewallTypes)
            {
                string[] pieces = firewallOSAndType.Split(':');
                if (pieces.Length == 2)
                {
                    osAndFirewallType[pieces[0]] = pieces[1];
                }
            }

            string userNameWhiteListString = GetConfig <string>("UserNameWhiteList", string.Empty);

            foreach (string userName in userNameWhiteListString.Split(','))
            {
                string userNameTrimmed = userName.Normalize().Trim();
                if (userNameTrimmed.Length > 0)
                {
                    userNameWhitelist.Add(userNameTrimmed);
                }
            }
            GetConfig <int>("UserNameWhiteListMinimumEditDistance", ref userNameWhitelistMaximumEditDistance);
            GetConfig <int>("FailedLoginAttemptsBeforeBanUserNameWhitelist", ref failedLoginAttemptsBeforeBanUserNameWhitelist);
            GetConfig <string>("GetUrlUpdate", ref getUrlUpdate);
            GetConfig <string>("GetUrlStart", ref getUrlStart);
            GetConfig <string>("GetUrlStop", ref getUrlStop);
            GetConfig <string>("GetUrlConfig", ref getUrlConfig);
            GetConfig <string>("ExternalIPAddressUrl", ref externalIPAddressUrl);
        }
示例#21
0
        static IPBanOS()
        {
            try
            {
                // start off with built in version info, this is not as detailed or nice as we like,
                //  so we try some other ways to get more detailed information
                Version     = Environment.OSVersion.VersionString;
                Description = RuntimeInformation.OSDescription;

                // attempt to get detailed version info
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    string tempFile = Path.GetTempFileName();
                    Process.Start("/bin/bash", "-c \"cat /etc/*release* > " + tempFile + "\"").WaitForExit();
                    System.Threading.Tasks.Task.Delay(100); // wait a small bit for file to really be closed
                    string versionText = File.ReadAllText(tempFile).Trim();
                    File.Delete(tempFile);
                    if (string.IsNullOrWhiteSpace(versionText))
                    {
                        IPBanLog.Error(new IOException("Unable to load os version from /etc/*release* ..."));
                    }
                    else
                    {
                        Name         = IPBanOS.Linux;
                        FriendlyName = ExtractRegex(versionText, "^(Id|Distrib_Id)=(?<value>.*?)$", string.Empty);
                        if (FriendlyName.Length != 0)
                        {
                            string codeName = ExtractRegex(versionText, "^(Name|Distrib_CodeName)=(?<value>.+)$", string.Empty);
                            if (codeName.Length != 0)
                            {
                                FriendlyName += " - " + codeName;
                            }
                            Version = ExtractRegex(versionText, "^Version_Id=(?<value>.+)$", Version);
                        }
                    }
                }
                else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    Name = IPBanOS.Windows;
                    string tempFile = Path.GetTempFileName();

                    // .net core WMI has a strange bug where WMI will not initialize on some systems
                    // since this is the only place where WMI is used, we can just work-around it
                    // with the wmic executable, which exists (as of 2018) on all supported Windows.
                    StartProcessAndWait("cmd", "/C wmic path Win32_OperatingSystem get Caption,Version /format:table > \"" + tempFile + "\"");
                    if (File.Exists(tempFile))
                    {
                        // try up to 10 times to read the file
                        for (int i = 0; i < 10; i++)
                        {
                            try
                            {
                                string[] lines = File.ReadAllLines(tempFile);
                                File.Delete(tempFile);
                                if (lines.Length > 1)
                                {
                                    int versionIndex = lines[0].IndexOf("Version");
                                    if (versionIndex >= 0)
                                    {
                                        FriendlyName = lines[1].Substring(0, versionIndex - 1).Trim();
                                        Version      = lines[1].Substring(versionIndex).Trim();
                                        break;
                                    }
                                }
                                throw new IOException("Invalid file generated from wmic");
                            }
                            catch (Exception ex)
                            {
                                if (i < 9)
                                {
                                    System.Threading.Tasks.Task.Delay(200).Wait();
                                }
                                else
                                {
                                    IPBanLog.Error(ex, "Unable to load os version using wmic, trying wmi api...");

                                    // last resort, try wmi api
                                    LoadVersionFromWmiApi();
                                }
                            }
                        }
                    }
                    else
                    {
                        // last resort, try wmi api
                        LoadVersionFromWmiApi();
                    }
                }
                else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
                {
                    // TODO: Implement better for MAC
                    Name         = IPBanOS.Mac;
                    FriendlyName = "OSX";
                }
                else
                {
                    Name         = IPBanOS.Unknown;
                    FriendlyName = "Unknown";
                }
            }
            catch (Exception ex)
            {
                IPBanLog.Error(ex);
            }
        }
示例#22
0
        private bool GetOrCreateRule(string ruleName, string remoteIPAddresses, NET_FW_ACTION_ action, IEnumerable <PortRange> allowedPorts = null)
        {
            remoteIPAddresses = (remoteIPAddresses ?? string.Empty).Trim();
            bool emptyIPAddressString = string.IsNullOrWhiteSpace(remoteIPAddresses) || remoteIPAddresses == "*";
            bool ruleNeedsToBeAdded   = false;

            lock (policy)
            {
recreateRule:
                INetFwRule rule = null;
                try
                {
                    rule = policy.Rules.Item(ruleName);
                }
                catch
                {
                    // ignore exception, assume does not exist
                }
                if (rule == null)
                {
                    rule                = Activator.CreateInstance(ruleType) as INetFwRule;
                    rule.Name           = ruleName;
                    rule.Enabled        = true;
                    rule.Action         = action;
                    rule.Description    = "Automatically created by IPBan";
                    rule.Direction      = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN;
                    rule.EdgeTraversal  = false;
                    rule.Grouping       = "IPBan";
                    rule.LocalAddresses = "*";
                    rule.Profiles       = int.MaxValue; // all
                    ruleNeedsToBeAdded  = true;
                }

                // do not ever set an empty string, Windows treats this as * which means everything
                if (!emptyIPAddressString)
                {
                    try
                    {
                        PortRange[] allowedPortsArray = (allowedPorts?.ToArray());
                        if (allowedPortsArray != null && allowedPortsArray.Length != 0)
                        {
                            rule.Protocol = (int)NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_TCP;
                            string localPorts;
                            if (action == NET_FW_ACTION_.NET_FW_ACTION_BLOCK)
                            {
                                localPorts = IPBanFirewallUtility.GetPortRangeStringBlockExcept(allowedPortsArray);
                            }
                            else
                            {
                                localPorts = IPBanFirewallUtility.GetPortRangeStringAllow(allowedPortsArray);
                            }
                            rule.LocalPorts = localPorts;
                        }
                        else
                        {
                            try
                            {
                                rule.Protocol = (int)NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_ANY;
                            }
                            catch
                            {
                                // failed to set protocol to any, we are switching from tcp back to any without ports, the only option is to
                                //  recreate the rule
                                if (!ruleNeedsToBeAdded)
                                {
                                    policy.Rules.Remove(ruleName);
                                    goto recreateRule;
                                }
                            }
                        }
                        rule.RemoteAddresses = remoteIPAddresses;
                    }
                    catch (Exception ex)
                    {
                        // if something failed, do not create the rule
                        emptyIPAddressString = true;
                        IPBanLog.Error(ex);
                    }
                }

                if (emptyIPAddressString || string.IsNullOrWhiteSpace(rule.RemoteAddresses) || rule.RemoteAddresses == "*")
                {
                    // if no ip addresses, remove the rule as it will allow or block everything with an empty RemoteAddresses string
                    try
                    {
                        rule = null;
                        policy.Rules.Remove(ruleName);
                    }
                    catch
                    {
                    }
                }
                else if (ruleNeedsToBeAdded)
                {
                    policy.Rules.Add(rule);
                }
                return(rule != null);
            }
        }