Skip to content

Commit

Permalink
Add process to run on unban option, 1.5.9 version
Browse files Browse the repository at this point in the history
  • Loading branch information
jjxtra committed Jan 9, 2021
1 parent cbe258a commit ce8919d
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 47 deletions.
4 changes: 3 additions & 1 deletion IPBan/IPBan.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
<OutputType>Exe</OutputType>
<TargetFrameworks>net5.0</TargetFrameworks>
<PlatformTarget>AnyCPU</PlatformTarget>
<Version>1.5.8</Version>
<Version>1.5.9</Version>
<AssemblyVersion>1.5.9</AssemblyVersion>
<FileVersion>1.5.9</FileVersion>
<Company>Digital Ruby, LLC</Company>
<Copyright>(c) 2010 Digital Ruby, LLC</Copyright>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
Expand Down
4 changes: 2 additions & 2 deletions IPBan/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.5.8")]
[assembly: AssemblyFileVersion("1.5.8")]
[assembly: AssemblyVersion("1.5.9")]
[assembly: AssemblyFileVersion("1.5.9")]
11 changes: 10 additions & 1 deletion IPBanCore/Core/IPBan/IPBanConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ public void Dispose()
private readonly Regex userNameWhitelistRegex;
private readonly int failedLoginAttemptsBeforeBanUserNameWhitelist = 20;
private readonly string processToRunOnBan;
private readonly string processToRunOnUnban;
private readonly bool useDefaultBannedIPAddressHandler;
private readonly string getUrlUpdate;
private readonly string getUrlStart;
Expand Down Expand Up @@ -299,6 +300,9 @@ private IPBanConfig(XmlDocument doc, IDnsLookup dns = null, IDnsServerList dnsLi
logFiles = emptyLogFilesToParseArray;
}
GetConfig<string>("ProcessToRunOnBan", ref processToRunOnBan);
processToRunOnBan = processToRunOnBan?.Trim();
GetConfig<string>("ProcessToRunOnUnban", ref processToRunOnUnban);
processToRunOnUnban = processToRunOnUnban?.Trim();
GetConfig<bool>("UseDefaultBannedIPAddressHandler", ref useDefaultBannedIPAddressHandler);

string userNameWhitelistString = GetConfig<string>("UserNameWhitelist", string.Empty);
Expand Down Expand Up @@ -1073,10 +1077,15 @@ public IReadOnlyCollection<IPAddressRange> Whitelist
public int FailedLoginAttemptsBeforeBanUserNameWhitelist { get { return failedLoginAttemptsBeforeBanUserNameWhitelist; } }

/// <summary>
/// Process to run on ban. See ReplaceUrl of IPBanService for place-holders.
/// Process to run on ban. See ReplaceUrl in IPBanService.cs for place-holders.
/// </summary>
public string ProcessToRunOnBan { get { return processToRunOnBan; } }

/// <summary>
/// Process to run on unban. See ReplaceUrl in IPBanService.cs for place-holders.
/// </summary>
public string ProcessToRunOnUnban { get { return processToRunOnUnban; } }

/// <summary>
/// Whether to use the default banned ip address handler
/// </summary>
Expand Down
76 changes: 37 additions & 39 deletions IPBanCore/Core/IPBan/IPBanService_Private.cs
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ private async Task ProcessPendingFailedLogins(IReadOnlyList<IPAddressLogEvent> i
}
}
CommitTransaction(transaction);
ExecuteExternalProcessForBannedIPAddresses(bannedIpAddresses);
ExecuteExternalProcessForIPAddresses(Config.ProcessToRunOnBan, bannedIpAddresses);
}
catch (Exception ex)
{
Expand Down Expand Up @@ -480,54 +480,47 @@ private void AddBannedIPAddress(string ipAddress, string source, string userName
}
}

private void ExecuteExternalProcessForBannedIPAddresses(IReadOnlyCollection<IPAddressLogEvent> bannedIPAddresses)
private void ExecuteExternalProcessForIPAddresses(string programToRun, IReadOnlyCollection<IPAddressLogEvent> bannedIPAddresses)
{
if (bannedIPAddresses.Count == 0)
if (bannedIPAddresses.Count == 0 || string.IsNullOrWhiteSpace(programToRun))
{
return;
}

// kick off external process and delegate notification in another thread
string programToRunConfigString = (Config.ProcessToRunOnBan ?? string.Empty).Trim();
if (string.IsNullOrWhiteSpace(programToRunConfigString))
{
return;
}

RunTask(() =>
{
foreach (var bannedIp in bannedIPAddresses)
{
// Run a process if one is in config
if (!string.IsNullOrWhiteSpace(programToRunConfigString))
if (bannedIp is null || string.IsNullOrWhiteSpace(bannedIp.IPAddress))
{
continue;
}

try
{
try
string[] pieces = programToRun.Split('|');
if (pieces.Length == 2)
{
string[] pieces = programToRunConfigString.Split('|');
if (pieces.Length == 2)
string program = Path.GetFullPath(pieces[0]);
string arguments = pieces[1].Replace("###IPADDRESS###", bannedIp.IPAddress)
.Replace("###SOURCE###", bannedIp.Source ?? string.Empty)
.Replace("###USERNAME###", bannedIp.UserName ?? string.Empty);
ProcessStartInfo psi = new ProcessStartInfo
{
string program = Path.GetFullPath(pieces[0]);
string arguments = pieces[1].Replace("###IPADDRESS###", bannedIp.IPAddress)
.Replace("###SOURCE###", bannedIp.Source)
.Replace("###USERNAME###", bannedIp.UserName);
ProcessStartInfo psi = new ProcessStartInfo
{
FileName = program,
WorkingDirectory = Path.GetDirectoryName(program),
Arguments = arguments
};
using Process p = Process.Start(psi);
}
else
{
throw new ArgumentException("Invalid config option for process to run on ban: " + programToRunConfigString);
}
FileName = program,
WorkingDirectory = Path.GetDirectoryName(program),
Arguments = arguments
};
using Process p = Process.Start(psi);
}
catch (Exception ex)
else
{
Logger.Error("Failed to execute process on ban", ex);
throw new ArgumentException("Invalid config option for process to run: " + programToRun);
}
}
catch (Exception ex)
{
Logger.Error("Failed to execute process " + programToRun, ex);
}
}
});
}
Expand Down Expand Up @@ -728,20 +721,22 @@ private void HandleExpiredLoginsAndBans(DateTime failLoginCutOff, DateTime banCu

private async Task UpdateExpiredIPAddressStates()
{
HashSet<string> unbanIPAddressesToNotifyDelegate = (IPBanDelegate is null ? null : new HashSet<string>());
HashSet<string> unbannedIPAddresses = 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);
HandleWhitelistChanged(transaction, unbannedIPAddresses);
HandleExpiredLoginsAndBans(failLoginCutOff, banCutOff, transaction, unbannedIPAddresses);
ExecuteExternalProcessForIPAddresses(Config.ProcessToRunOnUnban, unbannedIPAddresses
.Select(i => new IPAddressLogEvent(i, null, null, 0, IPAddressEventType.Unblocked)).ToArray());

// notify delegate of all unbanned ip addresses
if (IPBanDelegate != null)
{
foreach (string ip in unbanIPAddressesToNotifyDelegate)
foreach (string ip in unbannedIPAddresses)
{
await IPBanDelegate.IPAddressBanned(ip, null, null, MachineGuid, OSName, OSVersion, UtcNow, false);
}
Expand Down Expand Up @@ -1046,6 +1041,7 @@ private Task ProcessPendingLogEvents()
}

List<IPAddressLogEvent> bannedIPs = new List<IPAddressLogEvent>();
List<IPAddressLogEvent> unbannedIPs = new List<IPAddressLogEvent>();
object transaction = BeginTransaction();
try
{
Expand Down Expand Up @@ -1089,6 +1085,7 @@ private Task ProcessPendingLogEvents()
case IPAddressEventType.Unblocked:
DB.SetIPAddressesState(new string[] { evt.IPAddress }, IPBanDB.IPAddressState.RemovePending, transaction);
firewallNeedsBlockedIPAddressesUpdate = true;
unbannedIPs.Add(evt);
break;
}
}
Expand All @@ -1099,7 +1096,8 @@ private Task ProcessPendingLogEvents()
RollbackTransaction(transaction);
Logger.Error(ex);
}
ExecuteExternalProcessForBannedIPAddresses(bannedIPs);
ExecuteExternalProcessForIPAddresses(Config.ProcessToRunOnBan, bannedIPs);
ExecuteExternalProcessForIPAddresses(Config.ProcessToRunOnUnban, unbannedIPs);
return Task.CompletedTask;
}

Expand Down
6 changes: 3 additions & 3 deletions IPBanCore/IPBanCore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
<PreserveCompilationContext>true</PreserveCompilationContext>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<PackageId>DigitalRuby.IPBanCore</PackageId>
<Version>1.5.8</Version>
<Version>1.5.9</Version>
<AssemblyVersion>1.5.9</AssemblyVersion>
<FileVersion>1.5.9</FileVersion>
<Authors>Jeff Johnson</Authors>
<Company>Digital Ruby, LLC</Company>
<Product>IPBan</Product>
Expand All @@ -26,8 +28,6 @@
<OutputType>Library</OutputType>
<StartupObject />
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<AssemblyVersion>1.5.8</AssemblyVersion>
<FileVersion>1.5.8</FileVersion>
<IsTrimmable>false</IsTrimmable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
Expand Down
8 changes: 7 additions & 1 deletion IPBanCore/ipban.config
Original file line number Diff line number Diff line change
Expand Up @@ -829,10 +829,16 @@

<!---
Run an external process when a ban occurs. Separate the process and any arguments with a pipe (|). ###IPADDRESS### will be replaced with the actual IP which was banned. The pipe is required.
Example: c:\system files\on_ip_banned.exe|###IPADDRESS### -q
Example: c:\files\on_ip_banned.exe|###IPADDRESS### -q
-->
<add key="ProcessToRunOnBan" value=""/>

<!---
Run an external process when an unban occurs. Separate the process and any arguments with a pipe (|). ###IPADDRESS### will be replaced with the actual IP which was unbanned. The pipe is required.
Example: c:\files\on_ip_unbanned.exe|###IPADDRESS### -q
-->
<add key="ProcessToRunOnUnban" value=""/>

<!--
Firewall rules to create to allow or block ip addresses, one per line. Great way to persist firewall rules.
Format is rule-name;allow or block;ip list (comma spearated);allowed port list (comma separated);platform regex
Expand Down
1 change: 1 addition & 0 deletions IPBanTests/IPBanConfigTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ public async Task TestDefaultConfig()
Assert.AreEqual("IPBan_", cfg.FirewallRulePrefix);
Assert.AreEqual(TimeSpan.FromSeconds(1.0), cfg.MinimumTimeBetweenFailedLoginAttempts);
Assert.IsEmpty(cfg.ProcessToRunOnBan);
Assert.IsEmpty(cfg.ProcessToRunOnUnban);
Assert.IsFalse(cfg.ResetFailedLoginCountForUnbannedIPAddresses);
Assert.IsTrue(cfg.UseDefaultBannedIPAddressHandler);
Assert.IsEmpty(cfg.UserNameWhitelist);
Expand Down

0 comments on commit ce8919d

Please sign in to comment.