Beispiel #1
0
        public IEnumerable <string> EnumerateAllowedIPAddresses()
        {
            string tempFile = OSUtility.GetTempFileName();

            try
            {
                RunProcess("ipset", true, $"save > \"{tempFile}\"");
                bool inAllow = true;
                foreach (string line in File.ReadLines(tempFile))
                {
                    string[] pieces = line.Split(' ');
                    if (pieces.Length > 1 && pieces[0].Equals("create", StringComparison.OrdinalIgnoreCase))
                    {
                        inAllow = (pieces[1].Equals(AllowRuleName));
                    }
                    else if (inAllow && pieces.Length > 2 && pieces[0] == "add")
                    {
                        yield return(pieces[2]);
                    }
                }
            }
            finally
            {
                ExtensionMethods.FileDeleteWithRetry(tempFile);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="onRun">Action to execute for run</param>
        /// <param name="onStop">Action to execute on stop</param>
        private IPBanServiceRunner(Func <CancellationToken, Task> onRun, Func <CancellationToken, Task> onStop)
        {
            Logger.Warn("Initializing service");
            Directory.SetCurrentDirectory(AppContext.BaseDirectory);
            OSUtility.AddAppDomainExceptionHandlers(AppDomain.CurrentDomain);
            var hostBuilder = new HostBuilder()
                              .ConfigureServices((hostContext, services) =>
            {
                services.AddHostedService <IPBanServiceRunner>(provider => this);
            });

            this.onRun  = onRun;
            this.onStop = onStop;
            if (Microsoft.Extensions.Hosting.WindowsServices.WindowsServiceHelpers.IsWindowsService())
            {
                Logger.Warn("Running as a Windows service");
                hostBuilder.UseWindowsService();
            }
            else if (Microsoft.Extensions.Hosting.Systemd.SystemdHelpers.IsSystemdService())
            {
                Logger.Warn("Running as a systemd service");
                hostBuilder.UseSystemd();
            }
            else
            {
                // adding console lifetime wrecks things if actually running under a service
                Logger.Warn("Running as a console app");
                hostBuilder.UseConsoleLifetime();
            }
            hostBuilder.UseContentRoot(AppContext.BaseDirectory);
            host = hostBuilder.Build();
        }
Beispiel #3
0
 public override IEnumerable<string> EnumerateBannedIPAddresses()
 {
     string tempFile = OSUtility.GetTempFileName();
     try
     {
         RunProcess("ipset", true, $"save > \"{tempFile}\"");
         bool inBlockRule = true;
         foreach (string line in File.ReadLines(tempFile))
         {
             string[] pieces = line.Split(' ');
             if (pieces.Length > 1 && pieces[0].Equals("create", StringComparison.OrdinalIgnoreCase))
             {
                 inBlockRule = (!pieces[1].Equals(AllowRuleName) &&
                     (pieces[1].StartsWith(BlockRulePrefix) || pieces[1].StartsWith(RulePrefix + "6_Block_")));
             }
             else if (inBlockRule && pieces.Length > 2 && pieces[0] == "add")
             {
                 yield return pieces[2];
             }
         }
     }
     finally
     {
         ExtensionMethods.FileDeleteWithRetry(tempFile);
     }
 }
Beispiel #4
0
        public IEnumerable <IPAddressRange> EnumerateIPAddresses(string ruleNamePrefix = null)
        {
            string tempFile = OSUtility.GetTempFileName();

            try
            {
                string prefix = RulePrefix + (ruleNamePrefix ?? string.Empty);
                RunProcess("ipset", true, $"save > \"{tempFile}\"");
                bool inSet = false;
                foreach (string line in File.ReadLines(tempFile))
                {
                    string[] pieces = line.Split(' ');
                    if (pieces.Length > 1 && pieces[0].Equals("create", StringComparison.OrdinalIgnoreCase))
                    {
                        inSet = (pieces[1].StartsWith(prefix, StringComparison.OrdinalIgnoreCase));
                    }
                    else if (inSet && pieces.Length > 2 && pieces[0] == "add")
                    {
                        yield return(IPAddressRange.Parse(pieces[2]));
                    }
                }
            }
            finally
            {
                ExtensionMethods.FileDeleteWithRetry(tempFile);
            }
        }
Beispiel #5
0
        private static void LoadVersionFromWmic()
        {
            string tempFile = OSUtility.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.
            // this process can hang and fail to run after windows update or other cases on system restart,
            // so put a short timeout in and fallback to WMI api if needed
            Exception lastError = null;

            Logger.Info("Attempting to load os info from wmic");

            // attempt to run wmic to generate the info we want
            StartProcessAndWait(5000, "cmd", "/C wmic path Win32_OperatingSystem get Caption,Version /format:table > \"" + tempFile + "\"");

            // try up to 10 times to read the file in case file is still in use
            try
            {
                for (int i = 0; i < 10; i++)
                {
                    try
                    {
                        // if this throws, we will try again
                        string[] lines = File.ReadAllLines(tempFile);

                        // if we have enough lines, try to parse them out
                        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();
                                return;
                            }
                        }

                        throw new InvalidDataException("Invalid file generated by wmic");
                    }
                    catch (Exception ex)
                    {
                        lastError = ex;
                        if (ex is InvalidDataException)
                        {
                            break;
                        }
                    }
                    Thread.Sleep(200);
                }
            }
            finally
            {
                ExtensionMethods.FileDeleteWithRetry(tempFile);
            }
            throw new ApplicationException("Unable to load os version using wmic", lastError);
        }
 private async Task RunWindowsService(string[] args)
 {
     // if we have no console input and we are not in IIS, run as windows service
     if (Console.IsInputRedirected && !OSUtility.IsRunningInProcessIIS())
     {
         // create and start using Windows service APIs
         windowsService = new IPBanWindowsServiceRunner(this, args);
         await windowsService.Run();
     }
     else
     {
         await RunConsoleService(args);
     }
 }
Beispiel #7
0
 private async Task RunWindowsService(string[] args)
 {
     // if we have no console input and we are not in IIS and not running an installer, run as windows service
     if (Console.IsInputRedirected && !OSUtility.IsRunningInProcessIIS() &&
         !args.Any(a => a.StartsWith("-install", StringComparison.OrdinalIgnoreCase)))
     {
         // create and start using Windows service APIs
         windowsService = new IPBanWindowsServiceRunner(this, args);
         await windowsService.Run();
     }
     else
     {
         await RunConsoleService(args);
     }
 }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="onRun">Action to execute for run</param>
        /// <param name="onStop">Action to execute on stop</param>
        private IPBanServiceRunner(Func <CancellationToken, Task> onRun, Func <CancellationToken, Task> onStop)
        {
            Logger.Warn("Initializing service");
            Directory.SetCurrentDirectory(AppContext.BaseDirectory);
            OSUtility.AddAppDomainExceptionHandlers(AppDomain.CurrentDomain);
            var hostBuilder = new HostBuilder()
                              .ConfigureServices((hostContext, services) =>
            {
                services.AddHostedService <IPBanServiceRunner>(provider => this);
            });

            this.onRun  = onRun;
            this.onStop = onStop;
            hostBuilder.UseContentRoot(AppContext.BaseDirectory);
            SetupHostService(hostBuilder);
            host = hostBuilder.Build();
        }
Beispiel #9
0
        /// <summary>
        /// Create a detached process
        /// </summary>
        /// <param name="fileName">File name to execute</param>
        /// <param name="arguments">Arguments</param>
        public static void CreateDetachedProcess(string fileName, string arguments)
        {
            if (OSUtility.IsWindows)
            {
                Logger.Warn("Running detached process {0} {1}", fileName, arguments);

                var processInformation = new ProcessUtility.PROCESS_INFORMATION();
                var startupInfo        = new ProcessUtility.STARTUPINFO();
                var sa = new ProcessUtility.SECURITY_ATTRIBUTES();
                sa.Length = Marshal.SizeOf(sa);
                CreateProcess(null, "\"" + fileName + "\" " + arguments, ref sa, ref sa, false,
                              DETACHED_PROCESS,
                              IntPtr.Zero, Path.GetDirectoryName(fileName), ref startupInfo, out processInformation);
            }
            else
            {
                // ensure process is executable
                OSUtility.StartProcessAndWait("sudo", "chmod +x \"" + fileName + "\"");

                // use Linux at, should have been installed earlier
                ProcessStartInfo info = new()
                {
                    // Linux uses nohup and " &" to detach the process
                    // sudo -b to force it into the background
                    Arguments        = "-c \"echo sudo \\\"" + fileName + "\\\" " + arguments.Replace("\"", "\\\"") + " | at now\"",
                    CreateNoWindow   = true,
                    FileName         = "/bin/bash",
                    UseShellExecute  = false,
                    WindowStyle      = ProcessWindowStyle.Hidden,
                    WorkingDirectory = Path.GetDirectoryName(fileName)
                };

                Logger.Warn("Running detached process {0} {1}", info.FileName, info.Arguments);

                // do not get a reference and do not dispose, this process is orphaned from this process
                Process.Start(info);
            }
        }
    }
Beispiel #10
0
        /// <summary>
        /// Run the service
        /// </summary>
        /// <param name="requireAdministrator">True to require administrator, false otherwise</param>
        /// <returns>Exit code</returns>
        public async Task RunAsync(bool requireAdministrator = true)
        {
            if (requireAdministrator)
            {
                ExtensionMethods.RequireAdministrator();
            }

            if (args.Length != 0 && (args[0].Equals("info", StringComparison.OrdinalIgnoreCase) || args[0].Equals("-info", StringComparison.OrdinalIgnoreCase)))
            {
                Logger.Warn("System info: {0}", OSUtility.OSString());
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                await RunWindowsService(args);
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                await RunLinuxService(args);
            }
            else
            {
                throw new PlatformNotSupportedException();
            }
        }
Beispiel #11
0
        /// <summary>
        /// Initialize and start the service
        /// </summary>
        public async Task StartAsync()
        {
            if (IsRunning)
            {
                return;
            }

            try
            {
                IsRunning = true;
                ipDB      = new IPBanDB(DatabasePath ?? "ipban.sqlite");
                AddWindowsEventViewer();
                AddUpdater(new IPBanUnblockIPAddressesUpdater(this, Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "unban.txt")));
                AddUpdater(new IPBanBlockIPAddressesUpdater(this, Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ban.txt")));
                AssemblyVersion = IPBanService.IPBanAssembly.GetName().Version.ToString();
                await ReadAppSettings();

                UpdateBannedIPAddressesOnStart();
                IPBanDelegate?.Start(this);
                if (!ManualCycle)
                {
                    if (RunFirstCycleRightAway)
                    {
                        await RunCycle(); // run one cycle right away
                    }
                    cycleTimer          = new System.Timers.Timer(Config.CycleTime.TotalMilliseconds);
                    cycleTimer.Elapsed += async(sender, e) => await CycleTimerElapsed(sender, e);

                    cycleTimer.Start();
                }
                Logger.Warn("IPBan {0} service started and initialized. Operating System: {1}", OSUtility.Name, OSUtility.OSString());
                Logger.WriteLogLevels();
            }
            catch (Exception ex)
            {
                Logger.Error("Critical error in IPBanService.Start", ex);
            }
        }
Beispiel #12
0
        // 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
        protected bool UpdateRuleDelta(string ruleName, string action, IEnumerable <IPBanFirewallIPAddressDelta> deltas, string hashType,
                                       int maxCount, bool deleteRule, IEnumerable <PortRange> allowPorts, CancellationToken cancelToken)
        {
            string ipFileTemp = OSUtility.GetTempFileName();

            try
            {
                // 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 (IPBanFirewallIPAddressDelta delta in deltas)
                    {
                        if (cancelToken.IsCancellationRequested)
                        {
                            throw new OperationCanceledException(cancelToken);
                        }

                        if (IPAddressRange.TryParse(delta.IPAddress, out IPAddressRange range) &&
                            range.Begin.AddressFamily == addressFamily && range.End.AddressFamily == addressFamily)
                        {
                            try
                            {
                                if (delta.Added)
                                {
                                    if (range.Begin.Equals(range.End))
                                    {
                                        writer.WriteLine($"add {ruleName} {range.Begin} -exist");
                                    }
                                    else
                                    {
                                        writer.WriteLine($"add {ruleName} {range.ToCidrString()} -exist");
                                    }
                                }
                                else
                                {
                                    if (range.Begin.Equals(range.End))
                                    {
                                        writer.WriteLine($"del {ruleName} {range.Begin} -exist");
                                    }
                                    else
                                    {
                                        writer.WriteLine($"del {ruleName} {range.ToCidrString()} -exist");
                                    }
                                }
                            }
                            catch
                            {
                                // ignore invalid cidr ranges
                            }
                        }
                    }
                }

                if (cancelToken.IsCancellationRequested)
                {
                    throw new OperationCanceledException(cancelToken);
                }
                else
                {
                    // restore the deltas into the existing set
                    bool result = (RunProcess("ipset", true, $"restore < \"{ipFileTemp}\"") == 0);
                    CreateOrUpdateRule(ruleName, action, hashType, maxCount, allowPorts, cancelToken);
                    return(result);
                }
            }
            finally
            {
                ExtensionMethods.FileDeleteWithRetry(ipFileTemp);
            }
        }
Beispiel #13
0
        /// <summary>
        /// Static constructor
        /// </summary>
        static OSUtility()
        {
            try
            {
                tempFolder = Path.GetTempPath();
                if (string.IsNullOrWhiteSpace(tempFolder))
                {
                    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                    {
                        tempFolder = "c:\\temp";
                    }
                    else
                    {
                        tempFolder = "/tmp";
                    }
                }
                Directory.CreateDirectory(tempFolder);

                // 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))
                {
                    isLinux = true;
                    string tempFile = OSUtility.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();
                    ExtensionMethods.FileDeleteWithRetry(tempFile);
                    if (string.IsNullOrWhiteSpace(versionText))
                    {
                        Logger.Error(new IOException("Unable to load os version from /etc/*release* ..."));
                    }
                    else
                    {
                        Name         = OSUtility.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))
                {
                    isWindows   = true;
                    processVerb = "runas";
                    Name        = OSUtility.Windows;
                    string tempFile = OSUtility.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);
                                ExtensionMethods.FileDeleteWithRetry(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
                                {
                                    Logger.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
                    isMac        = true;
                    Name         = OSUtility.Mac;
                    FriendlyName = "OSX";
                }
                else
                {
                    Name         = OSUtility.Unknown;
                    FriendlyName = "Unknown";
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Error determining platform info", ex);
            }
        }
Beispiel #14
0
        // 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
        protected bool UpdateRule(string ruleName, string action, IEnumerable <string> ipAddresses, string hashType, int maxCount,
                                  IEnumerable <PortRange> allowPorts, CancellationToken cancelToken)
        {
#if ENABLE_FIREWALL_PROFILING
            Stopwatch timer = Stopwatch.StartNew();
#endif

            string ipFileTemp = OSUtility.GetTempFileName();
            try
            {
                // add and remove the appropriate ip addresses from the set
                using (StreamWriter writer = File.CreateText(ipFileTemp))
                {
                    if (cancelToken.IsCancellationRequested)
                    {
                        throw new OperationCanceledException(cancelToken);
                    }
                    RunProcess("ipset", true, out IReadOnlyList <string> sets, "-L -n");
                    if (sets.Contains(ruleName))
                    {
                        writer.WriteLine($"flush {ruleName}");// hash:{hashType} family {INetFamily} hashsize {hashSize} maxelem {maxCount} -exist");
                    }
                    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);
                        }

                        if (IPAddressRange.TryParse(ipAddress, out IPAddressRange range) &&
                            range.Begin.AddressFamily == addressFamily && range.End.AddressFamily == addressFamily)
                        {
                            try
                            {
                                if (hashType != hashTypeCidrMask || range.Begin.Equals(range.End))
                                {
                                    writer.WriteLine($"add {ruleName} {range.Begin} -exist");
                                }
                                else
                                {
                                    writer.WriteLine($"add {ruleName} {range.ToCidrString()} -exist");
                                }
                            }
                            catch
                            {
                                // ignore invalid cidr ranges
                            }
                        }
                    }
                }

                if (cancelToken.IsCancellationRequested)
                {
                    throw new OperationCanceledException(cancelToken);
                }
                else
                {
                    // restore the set
                    bool result = (RunProcess("ipset", true, $"restore < \"{ipFileTemp}\"") == 0);
                    CreateOrUpdateRule(ruleName, action, hashType, maxCount, allowPorts, cancelToken);
                    return(result);
                }
            }
            finally
            {
                ExtensionMethods.FileDeleteWithRetry(ipFileTemp);

#if ENABLE_FIREWALL_PROFILING
                timer.Stop();
                Logger.Warn("BlockIPAddressesDelta rule '{0}' took {1:0.00}ms with {2} ips",
                            ruleName, timer.Elapsed.TotalMilliseconds, ipAddresses.Count());
#endif
            }
        }
Beispiel #15
0
        private async Task ProcessPendingFailedLogins(IReadOnlyList <IPAddressLogEvent> ipAddresses)
        {
            List <IPAddressLogEvent> bannedIpAddresses = new List <IPAddressLogEvent>();
            object transaction = BeginTransaction();

            try
            {
                foreach (IPAddressLogEvent failedLogin in ipAddresses)
                {
                    try
                    {
                        string ipAddress = failedLogin.IPAddress;
                        string userName  = failedLogin.UserName;
                        string source    = failedLogin.Source;
                        if (IsWhitelisted(ipAddress))
                        {
                            Logger.Warn("Login failure, ignoring whitelisted ip address {0}, {1}, {2}", ipAddress, userName, source);
                        }
                        else
                        {
                            int maxFailedLoginAttempts;
                            if (Config.IsWhitelisted(userName))
                            {
                                maxFailedLoginAttempts = Config.FailedLoginAttemptsBeforeBanUserNameWhitelist;
                            }
                            else
                            {
                                // see if there is an override for max failed login attempts
                                maxFailedLoginAttempts = (failedLogin.FailedLoginThreshold > 0 ? failedLogin.FailedLoginThreshold : Config.FailedLoginAttemptsBeforeBan);
                            }

                            DateTime now = failedLogin.Timestamp;

                            // check for the target user name for additional blacklisting checks
                            bool ipBlacklisted           = Config.IsBlackListed(ipAddress);
                            bool userBlacklisted         = (ipBlacklisted ? false : Config.IsBlackListed(userName));
                            bool userFailsWhitelistRegex = (userBlacklisted ? false : Config.UserNameFailsUserNameWhitelistRegex(userName));
                            bool editDistanceBlacklisted = (ipBlacklisted || userBlacklisted || userFailsWhitelistRegex ? false : !Config.IsUserNameWithinMaximumEditDistanceOfUserNameWhitelist(userName));
                            bool configBlacklisted       = ipBlacklisted || userBlacklisted || userFailsWhitelistRegex || editDistanceBlacklisted;

                            // if the event came in with a count of 0 that means it is an automatic ban
                            int incrementCount = (failedLogin.Count < 1 ? maxFailedLoginAttempts : failedLogin.Count);
                            int newCount       = ipDB.IncrementFailedLoginCount(ipAddress, userName, source, UtcNow, incrementCount, transaction);

                            Logger.Warn(now, "Login failure: {0}, {1}, {2}, {3}", ipAddress, userName, source, newCount);

                            // if the ip address is black listed or the ip address has reached the maximum failed login attempts before ban, ban the ip address
                            if (configBlacklisted || newCount >= maxFailedLoginAttempts)
                            {
                                Logger.Info("IP blacklisted: {0}, user name blacklisted: {1}, fails user name white list regex: {2}, user name edit distance blacklisted: {3}",
                                            ipBlacklisted, userBlacklisted, userFailsWhitelistRegex, editDistanceBlacklisted);

                                if (ipDB.TryGetIPAddressState(ipAddress, out IPBanDB.IPAddressState? state, transaction) &&
                                    (state.Value == IPBanDB.IPAddressState.Active || state.Value == IPBanDB.IPAddressState.AddPending))
                                {
                                    Logger.Warn(now, "IP {0}, {1}, {2} ban pending.", ipAddress, userName, source);
                                }
                                else
                                {
                                    Logger.Debug("Failed login count {0} >= ban count {1}{2}", newCount, maxFailedLoginAttempts, (configBlacklisted ? " config blacklisted" : string.Empty));

                                    // if delegate and non-zero count, forward on - count of 0 means it was from external source, like a delegate
                                    if (IPBanDelegate != null && !failedLogin.External)
                                    {
                                        await IPBanDelegate.LoginAttemptFailed(ipAddress, source, userName, MachineGuid, OSName, OSVersion, UtcNow);
                                    }
                                    AddBannedIPAddress(ipAddress, source, userName, bannedIpAddresses, now,
                                                       configBlacklisted, newCount, string.Empty, transaction, failedLogin.External);
                                }
                            }
                            else
                            {
                                Logger.Debug("Failed login count {0} <= ban count {1}", newCount, maxFailedLoginAttempts);
                                if (OSUtility.UserIsActive(userName))
                                {
                                    Logger.Warn("Login failed for known active user {0}", userName);
                                }

                                // if delegate and non-zero count, forward on - count of 0 means it was from external source, like a delegate
                                if (IPBanDelegate != null && !failedLogin.External)
                                {
                                    await IPBanDelegate.LoginAttemptFailed(ipAddress, source, userName, MachineGuid, OSName, OSVersion, UtcNow);
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.Error(ex);
                    }
                }
                CommitTransaction(transaction);
                ExecuteExternalProcessForBannedIPAddresses(bannedIpAddresses);
            }
            catch (Exception ex)
            {
                RollbackTransaction(transaction);
                Logger.Error(ex);
            }
        }
Beispiel #16
0
        private static void LoadOSInfo()
        {
            tempFolder = Path.GetTempPath();
            if (string.IsNullOrWhiteSpace(tempFolder))
            {
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    tempFolder = "c:\\temp";
                }
                else
                {
                    tempFolder = "/tmp";
                }
            }
            Directory.CreateDirectory(tempFolder);

            // 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
            CpuArchitecture = RuntimeInformation.ProcessArchitecture.ToString().ToLowerInvariant();
            Version         = Environment.OSVersion.Version.ToString();
            Description     = RuntimeInformation.OSDescription;

            // attempt to get detailed version info
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                Name    = FriendlyName = OSUtility.Linux;
                isLinux = true;
                string tempFile = OSUtility.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();
                ExtensionMethods.FileDeleteWithRetry(tempFile);
                if (string.IsNullOrWhiteSpace(versionText))
                {
                    Logger.Error(new IOException("Unable to load os version from /etc/*release* ..."));
                }
                else
                {
                    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        = FriendlyName = OSUtility.Windows;
                isWindows   = true;
                processVerb = "runas";
                try
                {
                    LoadVersionFromWmic();
                }
                catch (Exception ex)
                {
                    Logger.Error(ex, "Failed to load os info from wmic");

                    // last resort, try wmi api
                    LoadVersionFromWmiApi();
                }
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                // TODO: Implement better for MAC
                Name         = FriendlyName = OSUtility.Mac;
                FriendlyName = "OSX";
                isMac        = true;
            }
            else
            {
                Name         = OSUtility.Unknown;
                FriendlyName = "Unknown";
            }
        }