Skip to content

Commit 3dfa0e9

Browse files
committed
Tweak smarter mail log, other misc fixes
1 parent c945fef commit 3dfa0e9

9 files changed

+130
-89
lines changed

Core/IPBanDB.cs

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,16 @@ public IPBanDBTransaction(string connString)
9292
{
9393
DBConnection = new SqliteConnection(connString);
9494
DBConnection.Open();
95+
using (SqliteCommand command = DBConnection.CreateCommand())
96+
{
97+
command.CommandText = "PRAGMA auto_vacuum = INCREMENTAL;";
98+
command.ExecuteNonQuery();
99+
}
100+
using (SqliteCommand command = DBConnection.CreateCommand())
101+
{
102+
command.CommandText = "PRAGMA journal_mode = WAL;";
103+
command.ExecuteNonQuery();
104+
}
95105
DBTransaction = DBConnection.BeginTransaction(transactionLevel);
96106
}
97107

@@ -130,10 +140,6 @@ public void Rollback()
130140
public const string FileName = "ipban.sqlite";
131141

132142
private const System.Data.IsolationLevel transactionLevel = System.Data.IsolationLevel.Serializable;
133-
134-
// note that an ip that has a block count may not yet be in the ipAddressesAndBanDate dictionary
135-
// for locking, always use ipAddressesAndBanDate
136-
private readonly string dbPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, FileName);
137143
private readonly string connString;
138144

139145
private int ExecuteNonQuery(string cmdText, params object[] param)
@@ -147,7 +153,7 @@ private int ExecuteNonQuery(SqliteConnection conn, SqliteTransaction tran, strin
147153
if (conn == null)
148154
{
149155
conn = new SqliteConnection(connString);
150-
conn.Open();
156+
OpenConnection(conn);
151157
closeConn = true;
152158
}
153159
try
@@ -174,10 +180,10 @@ private int ExecuteNonQuery(SqliteConnection conn, SqliteTransaction tran, strin
174180

175181
private T ExecuteScalar<T>(string cmdText, params object[] param)
176182
{
177-
using (SqliteConnection connection = new SqliteConnection(connString))
183+
using (SqliteConnection conn = new SqliteConnection(connString))
178184
{
179-
connection.Open();
180-
using (SqliteCommand command = connection.CreateCommand())
185+
OpenConnection(conn);
186+
using (SqliteCommand command = conn.CreateCommand())
181187
{
182188
command.CommandText = cmdText;
183189
for (int i = 0; i < param.Length; i++)
@@ -195,7 +201,7 @@ private SqliteDataReader ExecuteReader(string query, SqliteConnection conn, Sqli
195201
if (conn == null)
196202
{
197203
conn = new SqliteConnection(connString);
198-
conn.Open();
204+
OpenConnection(conn);
199205
closeConnection = true;
200206
}
201207
SqliteCommand command = conn.CreateCommand();
@@ -208,6 +214,13 @@ private SqliteDataReader ExecuteReader(string query, SqliteConnection conn, Sqli
208214
return command.ExecuteReader((closeConnection ? System.Data.CommandBehavior.CloseConnection : System.Data.CommandBehavior.Default));
209215
}
210216

217+
private void OpenConnection(SqliteConnection conn)
218+
{
219+
conn.Open();
220+
ExecuteNonQuery(conn, null, "PRAGMA auto_vacuum = INCREMENTAL;");
221+
ExecuteNonQuery(conn, null, "PRAGMA journal_mode = WAL;");
222+
}
223+
211224
private IPAddressEntry ParseIPAddressEntry(SqliteDataReader reader)
212225
{
213226
string ipAddress = reader.GetString(0);
@@ -245,6 +258,7 @@ ON CONFLICT(IPAddress)
245258

246259
private void Initialize()
247260
{
261+
IPBanLog.Info("Initializing IPBan database at {0}", connString);
248262
SQLitePCL.Batteries.Init();
249263
ExecuteNonQuery("PRAGMA auto_vacuum = INCREMENTAL;");
250264
ExecuteNonQuery("PRAGMA journal_mode = WAL;");
@@ -268,8 +282,9 @@ private void Initialize()
268282
/// <summary>
269283
/// Constructor
270284
/// </summary>
271-
public IPBanDB()
285+
public IPBanDB(string dbPath = null)
272286
{
287+
dbPath = (string.IsNullOrWhiteSpace(dbPath) ? Path.Combine(AppDomain.CurrentDomain.BaseDirectory, FileName) : dbPath);
273288
connString = "Data Source=" + dbPath;
274289
Initialize();
275290
}
@@ -466,7 +481,7 @@ public int SetBannedIPAddresses(IEnumerable<KeyValuePair<string, DateTime>> ipAd
466481
int count = 0;
467482
using (SqliteConnection conn = new SqliteConnection(connString))
468483
{
469-
conn.Open();
484+
OpenConnection(conn);
470485
using (SqliteTransaction tran = conn.BeginTransaction(transactionLevel))
471486
{
472487
foreach (KeyValuePair<string, DateTime> ipAddress in ipAddresses)
@@ -494,7 +509,7 @@ public int SetIPAddressesState(IEnumerable<string> ipAddresses, IPAddressState s
494509
SqliteConnection conn = (ipDBTransaction?.DBConnection ?? new SqliteConnection(connString));
495510
if (commit)
496511
{
497-
conn.Open();
512+
OpenConnection(conn);
498513
}
499514
SqliteTransaction tran = (ipDBTransaction?.DBTransaction ?? conn.BeginTransaction(transactionLevel));
500515
int stateInt = (int)state;
@@ -537,7 +552,7 @@ public IEnumerable<IPBanFirewallIPAddressDelta> EnumerateIPAddressesDelta(bool c
537552
{
538553
using (SqliteConnection conn = new SqliteConnection(connString))
539554
{
540-
conn.Open();
555+
OpenConnection(conn);
541556
using (SqliteTransaction tran = conn.BeginTransaction(transactionLevel))
542557
{
543558
using (SqliteDataReader reader = ExecuteReader("SELECT IPAddressText, State FROM IPAddresses WHERE State IN (1, 2) ORDER BY IPAddressText", conn, tran))
@@ -629,7 +644,7 @@ public int DeleteIPAddresses(IEnumerable<string> ipAddresses)
629644

630645
using (SqliteConnection conn = new SqliteConnection(connString))
631646
{
632-
conn.Open();
647+
OpenConnection(conn);
633648
using (SqliteTransaction tran = conn.BeginTransaction(transactionLevel))
634649
{
635650
foreach (string ipAddress in ipAddresses)

Core/IPBanFirewallUtility.cs

Lines changed: 56 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -103,70 +103,77 @@ public static bool TryNormalizeIPAddress(this string ipAddress, out string norma
103103
/// <returns>Firewall</returns>
104104
public static IIPBanFirewall CreateFirewall(IReadOnlyDictionary<string, string> osAndFirewall, string rulePrefix = null, IIPBanFirewall existing = null)
105105
{
106-
bool foundFirewallType = false;
107-
int priority = int.MinValue;
108-
Type firewallType = typeof(IIPBanFirewall);
109-
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies().ToArray();
110-
Type[] types = assemblies.SelectMany(a => a.GetTypes()).ToArray();
111-
var q =
112-
from fwType in types
113-
where fwType.IsPublic &&
114-
fwType != firewallType &&
115-
firewallType.IsAssignableFrom(fwType) &&
116-
fwType.GetCustomAttribute<RequiredOperatingSystemAttribute>() != null &&
117-
fwType.GetCustomAttribute<RequiredOperatingSystemAttribute>().IsValid
118-
select new { FirewallType = fwType, OS = fwType.GetCustomAttribute<RequiredOperatingSystemAttribute>(), Name = fwType.GetCustomAttribute<CustomNameAttribute>() };
119-
var array = q.ToArray();
120-
foreach (var result in array)
106+
try
121107
{
122-
// look up the requested firewall by os name
123-
bool matchPriority = priority < result.OS.Priority;
124-
if (matchPriority)
108+
bool foundFirewallType = false;
109+
int priority = int.MinValue;
110+
Type firewallType = typeof(IIPBanFirewall);
111+
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies().ToArray();
112+
Type[] types = assemblies.SelectMany(a => a.GetTypes()).ToArray();
113+
var q =
114+
from fwType in types
115+
where fwType.IsPublic &&
116+
fwType != firewallType &&
117+
firewallType.IsAssignableFrom(fwType) &&
118+
fwType.GetCustomAttribute<RequiredOperatingSystemAttribute>() != null &&
119+
fwType.GetCustomAttribute<RequiredOperatingSystemAttribute>().IsValid
120+
select new { FirewallType = fwType, OS = fwType.GetCustomAttribute<RequiredOperatingSystemAttribute>(), Name = fwType.GetCustomAttribute<CustomNameAttribute>() };
121+
var array = q.ToArray();
122+
foreach (var result in array)
125123
{
126-
bool matchName = true;
127-
if (osAndFirewall != null && osAndFirewall.Count != 0 &&
128-
(osAndFirewall.TryGetValue(IPBanOS.Name, out string firewallToUse) || osAndFirewall.TryGetValue("*", out firewallToUse)))
129-
{
130-
matchName = result.Name.Name.Equals(firewallToUse, StringComparison.OrdinalIgnoreCase);
131-
}
132-
if (matchName)
124+
// look up the requested firewall by os name
125+
bool matchPriority = priority < result.OS.Priority;
126+
if (matchPriority)
133127
{
134-
// if IsAvailable method is provided, attempt to call
135-
MethodInfo available = result.FirewallType.GetMethod("IsAvailable", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
136-
if (available != null)
128+
bool matchName = true;
129+
if (osAndFirewall != null && osAndFirewall.Count != 0 &&
130+
(osAndFirewall.TryGetValue(IPBanOS.Name, out string firewallToUse) || osAndFirewall.TryGetValue("*", out firewallToUse)))
137131
{
138-
try
132+
matchName = result.Name.Name.Equals(firewallToUse, StringComparison.OrdinalIgnoreCase);
133+
}
134+
if (matchName)
135+
{
136+
// if IsAvailable method is provided, attempt to call
137+
MethodInfo available = result.FirewallType.GetMethod("IsAvailable", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
138+
if (available != null)
139139
{
140-
if (!Convert.ToBoolean(available.Invoke(null, null)))
140+
try
141+
{
142+
if (!Convert.ToBoolean(available.Invoke(null, null)))
143+
{
144+
continue;
145+
}
146+
}
147+
catch
141148
{
142149
continue;
143150
}
144151
}
145-
catch
146-
{
147-
continue;
148-
}
152+
firewallType = result.FirewallType;
153+
priority = result.OS.Priority;
154+
foundFirewallType = true;
149155
}
150-
firewallType = result.FirewallType;
151-
priority = result.OS.Priority;
152-
foundFirewallType = true;
153156
}
154157
}
158+
if (firewallType == null)
159+
{
160+
throw new ArgumentException("Firewall is null, at least one type should implement IIPBanFirewall");
161+
}
162+
else if (osAndFirewall.Count != 0 && !foundFirewallType)
163+
{
164+
string typeString = string.Join(',', osAndFirewall.Select(kv => kv.Key + ":" + kv.Value));
165+
throw new ArgumentException("Unable to find firewalls of types: " + typeString + ", osname: " + IPBanOS.Name);
166+
}
167+
if (existing != null && existing.GetType().Equals(firewallType))
168+
{
169+
return existing;
170+
}
171+
return Activator.CreateInstance(firewallType, new object[] { rulePrefix }) as IIPBanFirewall;
155172
}
156-
if (firewallType == null)
157-
{
158-
throw new ArgumentException("Firewall is null, at least one type should implement IIPBanFirewall");
159-
}
160-
else if (osAndFirewall.Count != 0 && !foundFirewallType)
161-
{
162-
string typeString = string.Join(',', osAndFirewall.Select(kv => kv.Key + ":" + kv.Value));
163-
throw new ArgumentException("Unable to find firewalls of types: " + typeString + ", osname: " + IPBanOS.Name);
164-
}
165-
if (existing != null && existing.GetType().Equals(firewallType))
173+
catch (Exception ex)
166174
{
167-
return existing;
175+
throw new ArgumentException("Unable to create firewall, please double check your Firewall configuration property", ex);
168176
}
169-
return Activator.CreateInstance(firewallType, new object[] { rulePrefix }) as IIPBanFirewall;
170177
}
171178

172179
/// <summary>

Core/IPBanMemoryFirewall.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,11 @@ private string ScrubRuleNamePrefix(string ruleNamePrefix)
268268
return (RulePrefix + (ruleNamePrefix ?? string.Empty)).Trim('_');
269269
}
270270

271+
public IPBanMemoryFirewall(string rulePrefix = null)
272+
{
273+
RulePrefix = (string.IsNullOrWhiteSpace(rulePrefix) ? RulePrefix : rulePrefix);
274+
}
275+
271276
public void Update()
272277
{
273278
}

Core/IPBanService.cs

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,12 @@ private class IPAddressPendingEvent
6969
private System.Timers.Timer cycleTimer;
7070
private bool firewallNeedsBlockedIPAddressesUpdate;
7171
private bool gotStartUrl;
72+
private IPBanDB ipDB;
7273

7374
// batch failed logins every cycle
7475
private readonly List<IPAddressPendingEvent> pendingFailedLogins = new List<IPAddressPendingEvent>();
7576
private readonly List<IPAddressPendingEvent> pendingSuccessfulLogins = new List<IPAddressPendingEvent>();
7677
private readonly List<IPAddressLogEvent> pendingLogEvents = new List<IPAddressLogEvent>();
77-
78-
// note that an ip that has a block count may not yet be in the ipAddressesAndBanDate dictionary
79-
// for locking, always use ipAddressesAndBanDate
80-
private readonly IPBanDB ipDB;
81-
8278
private readonly object configLock = new object();
8379
private readonly HashSet<IUpdater> updaters = new HashSet<IUpdater>();
8480
private readonly HashSet<IPBanLogFileScanner> logFilesToParse = new HashSet<IPBanLogFileScanner>();
@@ -908,7 +904,10 @@ private void ProcessPendingLogEvents()
908904
IPBanLog.Error(ex);
909905
}
910906
ExecuteExternalProcessForBannedIPAddresses(bannedIPs);
911-
UnblockIPAddresses(unbannedIPs);
907+
if (unbannedIPs.Count != 0)
908+
{
909+
UnblockIPAddresses(unbannedIPs);
910+
}
912911
}
913912

914913
/// <summary>
@@ -918,7 +917,6 @@ protected IPBanService()
918917
{
919918
OSName = IPBanOS.Name + (string.IsNullOrWhiteSpace(IPBanOS.FriendlyName) ? string.Empty : " (" + IPBanOS.FriendlyName + ")");
920919
OSVersion = IPBanOS.Version;
921-
ipDB = new IPBanDB();
922920
}
923921

924922
/// <summary>
@@ -1121,7 +1119,7 @@ public void Dispose()
11211119
{
11221120
file.Dispose();
11231121
}
1124-
ipDB.Dispose();
1122+
ipDB?.Dispose();
11251123
IPBanLog.Warn("Stopped IPBan service");
11261124
}
11271125
catch
@@ -1140,7 +1138,8 @@ public void Start()
11401138
return;
11411139
}
11421140

1143-
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
1141+
ipDB = new IPBanDB(DatabasePath);
1142+
if (UseWindowsEventViewer && RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
11441143
{
11451144
// attach Windows event viewer to the service
11461145
EventViewer = new IPBanWindowsEventViewer(this);
@@ -1422,30 +1421,35 @@ public static void DisposeIPBanTestService(IPBanService service)
14221421
/// </summary>
14231422
public IPBanConfig Config { get; private set; }
14241423

1424+
/// <summary>
1425+
/// Version of the software
1426+
/// </summary>
1427+
public string Version { get; set; } = Assembly.GetEntryAssembly().GetName().Version.ToString();
1428+
14251429
/// <summary>
14261430
/// Local ip address
14271431
/// </summary>
1428-
public string LocalIPAddressString { get; private set; }
1432+
public string LocalIPAddressString { get; set; }
14291433

14301434
/// <summary>
14311435
/// Remote ip address
14321436
/// </summary>
1433-
public string RemoteIPAddressString { get; private set; }
1437+
public string RemoteIPAddressString { get; set; }
14341438

14351439
/// <summary>
14361440
/// Fully qualified domain name
14371441
/// </summary>
1438-
public string FQDN { get; private set; }
1442+
public string FQDN { get; set; }
14391443

14401444
/// <summary>
1441-
/// Version of the software
1445+
/// Machine guid, null/empty for none
14421446
/// </summary>
1443-
public string Version { get; private set; } = Assembly.GetEntryAssembly().GetName().Version.ToString();
1447+
public string MachineGuid { get; set; }
14441448

14451449
/// <summary>
1446-
/// Machine guid, null/empty for none
1450+
/// Override the sqlite database path, leave null for default
14471451
/// </summary>
1448-
public string MachineGuid { get; set; }
1452+
public string DatabasePath { get; set; }
14491453

14501454
/// <summary>
14511455
/// External delegate to allow external config, whitelist, blacklist, etc.
@@ -1482,6 +1486,11 @@ public static void DisposeIPBanTestService(IPBanService service)
14821486
/// </summary>
14831487
public IPBanWindowsEventViewer EventViewer { get; private set; }
14841488

1489+
/// <summary>
1490+
/// Whether to link up to the Windows event viewer on Start
1491+
/// </summary>
1492+
public bool UseWindowsEventViewer { get; set; } = true;
1493+
14851494
/// <summary>
14861495
/// Log files to parse
14871496
/// </summary>

IPBan.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
<PackageReference Include="Microsoft.Packaging.Tools.Trimming" Version="1.1.0-preview1-26619-01" />
5555
<PackageReference Include="Microsoft.Windows.Compatibility" Version="2.1.1" />
5656
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
57-
<PackageReference Include="NLog" Version="4.6.4" />
57+
<PackageReference Include="NLog" Version="4.6.5" />
5858
</ItemGroup>
5959

6060
<ItemGroup>

0 commit comments

Comments
 (0)