forked from DigitalRuby/IPBan
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathIPBanWindowsFirewall.cs
150 lines (137 loc) · 5.24 KB
/
IPBanWindowsFirewall.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#region Imports
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using NetFwTypeLib;
#endregion Imports
namespace IPBan
{
/// <summary>
/// Helper class for Windows Firewall (NetFwTypeLib). Must call Initialize first!
/// </summary>
public static class IPBanWindowsFirewall
{
private const string clsidFwPolicy2 = "{E2B3C97F-6AE1-41AC-817A-F6F92166D7DD}";
private const string clsidFwRule = "{2C5BC43E-3369-4C33-AB0C-BE9469677AF4}";
private const int maxIpAddressesPerRule = 1000; // do not change!
private static INetFwPolicy2 policy;
public static string RulePrefix { get; private set; }
/// <summary>
/// Initialize - call this from the main thread to avoid COM issues
/// </summary>
/// <param name="rulePrefix">Rule prefix</param>
public static void Initialize(string rulePrefix)
{
Type objectType = Type.GetTypeFromCLSID(new Guid(clsidFwPolicy2));
policy = Activator.CreateInstance(objectType) as INetFwPolicy2;
RulePrefix = (string.IsNullOrWhiteSpace(rulePrefix) ? "IPBan_BlockIPAddresses_" : rulePrefix);
}
private static string CreateRuleStringForIPAddresses(string[] ipAddresses, int index, int count)
{
if (count == 0 || index >= ipAddresses.Length)
{
return string.Empty;
}
// don't overrun array
count = Math.Min(count, ipAddresses.Length - index);
StringBuilder b = new StringBuilder(count * 16);
b.Append(ipAddresses[index]);
for (int i = index + 1; i < index + count; i++)
{
b.Append(',');
b.Append(ipAddresses[i]);
}
return b.ToString();
}
private static void CreateRule(string[] ipAddresses, int index, int count)
{
Type type = Type.GetTypeFromCLSID(new Guid(clsidFwRule));
string ruleName = RulePrefix + index;
string remoteIpString = CreateRuleStringForIPAddresses(ipAddresses, index, count);
INetFwRule rule = null;
try
{
rule = policy.Rules.Item(ruleName);
}
catch
{
// ignore exception, assume does not exist
}
if (rule == null)
{
rule = Activator.CreateInstance(type) as INetFwRule;
rule.Name = ruleName;
rule.Enabled = true;
rule.Action = NET_FW_ACTION_.NET_FW_ACTION_BLOCK;
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
rule.Protocol = (int)NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_ANY;
policy.Rules.Add(rule);
}
rule.RemoteAddresses = remoteIpString;
}
/// <summary>
/// Creates new rules to block all the ip addresses, and removes any left-over rules. Exceptions are logged.
/// </summary>
/// <param name="ipAddresses">IP Addresses</param>
/// <returns>True if success, false if error</returns>
public static bool CreateRules(string[] ipAddresses)
{
try
{
int i;
for (i = 0; i < ipAddresses.Length; i += maxIpAddressesPerRule)
{
CreateRule(ipAddresses, i, maxIpAddressesPerRule);
}
DeleteRules(i);
return true;
}
catch (Exception ex)
{
Log.Write(LogLevel.Error, ex.ToString());
return false;
}
}
/// <summary>
/// Delete all rules with a name beginning with the rule prefix. Exceptions are logged.
/// </summary>
/// <param name="startIndex">The start index to begin deleting rules at. The index is appended to the rule prefix.</param>
/// <returns>True if success, false if error</returns>
public static bool DeleteRules(int startIndex = 0)
{
try
{
List<INetFwRule> toDelete = new List<INetFwRule>();
foreach (INetFwRule rule in policy.Rules)
{
if (rule.Name.StartsWith(RulePrefix))
{
int index = int.Parse(rule.Name.Substring(RulePrefix.Length));
if (index >= startIndex)
{
rule.Enabled = false;
toDelete.Add(rule);
}
}
}
foreach (INetFwRule rule in toDelete)
{
policy.Rules.Remove(rule.Name);
}
return true;
}
catch (Exception ex)
{
Log.Write(LogLevel.Error, ex.ToString());
return false;
}
}
}
}