private async Task UpdateExpiredIPAddressStates() { HashSet <string> unbanIPAddressesToNotifyDelegate = (IPBanDelegate is null ? null : new HashSet <string>()); DateTime now = UtcNow; DateTime failLoginCutOff = (now - Config.ExpireTime); DateTime banCutOff = now; object transaction = DB.BeginTransaction(); try { HandleWhitelistChanged(transaction, unbanIPAddressesToNotifyDelegate); HandleExpiredLoginsAndBans(failLoginCutOff, banCutOff, transaction, unbanIPAddressesToNotifyDelegate); // notify delegate of all unbanned ip addresses if (IPBanDelegate != null) { foreach (string ip in unbanIPAddressesToNotifyDelegate) { await IPBanDelegate.IPAddressBanned(ip, null, null, MachineGuid, OSName, OSVersion, UtcNow, false); } } } catch (Exception ex) { Logger.Error(ex); DB.RollbackTransaction(transaction); } finally { DB.CommitTransaction(transaction); } }
private void AddBannedIPAddress(string ipAddress, string source, string userName, List <IPAddressLogEvent> bannedIpAddresses, DateTime startBanDate, bool configBlacklisted, int counter, string extraInfo, object transaction, bool external) { // never ban whitelisted ip addresses if (IsWhitelisted(ipAddress)) { Logger.Info("Ignoring ban request for whitelisted ip address {0}", ipAddress); return; } TimeSpan[] banTimes = Config.BanTimes; TimeSpan banTime = banTimes.First(); DateTime banEndDate = startBanDate + banTime; // if we have an ip in the database, use the ban time to move to the next ban slot in the list of ban times // if ban times only has one entry, do not do this if (banTimes.Length > 1 && ipDB.TryGetIPAddress(ipAddress, out IPBanDB.IPAddressEntry ipEntry, transaction) && ipEntry.BanStartDate != null && ipEntry.BanEndDate != null) { // find the next ban time in the array banTime = ipEntry.BanEndDate.Value - ipEntry.BanStartDate.Value; for (int i = 0; i < banTimes.Length; i++) { if (banTime < banTimes[i]) { // ban for next timespan banTime = banTimes[i]; banEndDate = startBanDate + banTime; Logger.Info("Moving to next ban duration {0} at index {1} for ip {1}", banTimes[i], i, ipAddress); break; } } } int adjustedCount = (counter <= 0 ? Config.FailedLoginAttemptsBeforeBan : counter); bannedIpAddresses?.Add(new IPAddressLogEvent(ipAddress, userName, source, adjustedCount, IPAddressEventType.Blocked)); if (ipDB.SetBanDates(ipAddress, startBanDate, banEndDate, UtcNow, transaction)) { firewallNeedsBlockedIPAddressesUpdate = true; } Logger.Warn(startBanDate, "Banning ip address: {0}, user name: {1}, config black listed: {2}, count: {3}, extra info: {4}, duration: {5}", ipAddress, userName, configBlacklisted, counter, extraInfo, banTime); // if this is a delegate callback (counter of 0), exit out - we don't want to run handlers or processes for shared banned ip addresses if (counter <= 0) { return; } else if (BannedIPAddressHandler != null && System.Net.IPAddress.TryParse(ipAddress, out System.Net.IPAddress ipAddressObj) && !ipAddressObj.IsInternal()) { try { ExecuteTask(BannedIPAddressHandler.HandleBannedIPAddress(ipAddress, source, userName, OSName, OSVersion, AssemblyVersion, RequestMaker)); } catch { // eat exception, delicious } } if (IPBanDelegate != null && !external) { try { ExecuteTask(IPBanDelegate.IPAddressBanned(ipAddress, source, userName, MachineGuid, OSName, OSVersion, UtcNow, true)); } catch (Exception ex) { Logger.Info("Error calling ipban delegate with banned ip address: " + ex.ToString()); } } }