public void TestSingle() { using (var ctx = new Context()) { int localPort = 80; IPAddress remoteAddress = IPAddress.Parse("192.168.1.1"); int remotePort = 128; int protocol = 6; string record = $"X\tYes\tAllow\t{localPort}\t{remoteAddress}\t{remotePort}\t{protocol}"; WindowsFirewallRule rule = WindowsFirewallRuleParser.ParseRecord( WindowsFirewallRuleParserTest.HeaderIndex, record, '\t'); var packetVars = new WindowsFirewallPacketVariables(ctx); Solver s = ctx.MkSolver(); s.Assert(rule.Matches(ctx, packetVars)); Status result = s.Check(); Assert.AreEqual(Status.SATISFIABLE, result); var packet = new WindowsFirewallPacket(s.Model); Assert.AreEqual(remoteAddress, packet.SourceAddress); Assert.AreEqual(remotePort, packet.SourcePort); Assert.AreEqual(localPort, packet.DestinationPort); Assert.AreEqual(protocol, packet.Protocol); } }
public void TestAllowByDefault() { using (var ctx = new Context()) { IPAddress allowed = IPAddress.Parse("128.0.0.1"); string lowerBlock = "X\tYes\tBlock\tAny\t0.0.0.0-128.0.0.0\tAny\tAny"; string upperBlock = "Y\tYes\tBlock\tAny\t128.0.0.2-255.255.255.255\tAny\tAny"; string text = $"{WindowsFirewallRuleParserTest.HeaderText}\n{lowerBlock}\n{upperBlock}"; var firewall = new WindowsFirewall { BlockByDefault = false, Rules = WindowsFirewallRuleParser.Parse(text, '\t').ToList() }; var packetVars = new WindowsFirewallPacketVariables(ctx); Solver s = ctx.MkSolver(); s.Assert(firewall.Allows(ctx, packetVars)); Status result = s.Check(); Assert.AreEqual(Status.SATISFIABLE, result); var packet = new WindowsFirewallPacket(s.Model); Assert.AreEqual(allowed, packet.SourceAddress); Assert.AreEqual(null, packet.SourcePort); Assert.AreEqual(null, packet.DestinationPort); Assert.AreEqual(null, packet.Protocol); } }
public void TestAllowSingle() { using (var ctx = new Context()) { int localPort = 80; IPAddress remoteAddress = IPAddress.Parse("192.168.1.1"); int remotePort = 128; int protocol = 6; string record = $"X\tYes\tAllow\t{localPort}\t{remoteAddress}\t{remotePort}\t{protocol}"; string text = $"{WindowsFirewallRuleParserTest.HeaderText}\n{record}"; var firewall = new WindowsFirewall { BlockByDefault = true, Rules = WindowsFirewallRuleParser.Parse(text, '\t').ToList() }; var packetVars = new WindowsFirewallPacketVariables(ctx); Solver s = ctx.MkSolver(); s.Assert(firewall.Allows(ctx, packetVars)); Status result = s.Check(); Assert.AreEqual(Status.SATISFIABLE, result); var packet = new WindowsFirewallPacket(s.Model); Assert.AreEqual(remoteAddress, packet.SourceAddress); Assert.AreEqual(remotePort, packet.SourcePort); Assert.AreEqual(localPort, packet.DestinationPort); Assert.AreEqual(protocol, packet.Protocol); } }
public void TestMultipleDifferences() { int localPort = 8080; int remotePort = 256; int protocol = 17; string record = $"X\tYes\tAllow\t{localPort}\t255.255.255.0-255.255.255.15\t{remotePort}\t{protocol}"; string text = $"{WindowsFirewallRuleParserTest.HeaderText}\n{record}"; var f1 = new WindowsFirewall { Name = "1", BlockByDefault = true, Rules = WindowsFirewallRuleParser.Parse(text, '\t').ToList() }; record = $"X\tYes\tAllow\t{localPort}\t255.255.255.0-255.255.255.2\t{remotePort}\t{protocol}"; string record2 = $"Y\tYes\tAllow\t{localPort}\t255.255.255.4-255.255.255.6\t{remotePort}\t{protocol}"; string record3 = $"Y\tYes\tAllow\t{localPort}\t255.255.255.8-255.255.255.10\t{remotePort}\t{protocol}"; string record4 = $"Y\tYes\tAllow\t{localPort}\t255.255.255.12-255.255.255.15\t{remotePort}\t{protocol}"; text = $"{WindowsFirewallRuleParserTest.HeaderText}\n{record}\n{record2}\n{record3}\n{record4}"; var f2 = new WindowsFirewall { Name = "2", BlockByDefault = true, Rules = WindowsFirewallRuleParser.Parse(text, '\t').ToList() }; var inconsistencies = WindowsFirewallEquivalenceCheck.CheckEquivalence(f1, f2).ToList(); var expected = new HashSet <IPAddress> { IPAddress.Parse("255.255.255.3"), IPAddress.Parse("255.255.255.7"), IPAddress.Parse("255.255.255.11") }; Assert.AreEqual(3, inconsistencies.Count); foreach (var inconsistency in inconsistencies) { Assert.AreEqual("1", inconsistency.Firewalls.Item1.Name); Assert.IsTrue(inconsistency.Allowed.Item1); Assert.AreEqual("2", inconsistency.Firewalls.Item2.Name); Assert.IsFalse(inconsistency.Allowed.Item2); Assert.AreEqual(1, inconsistency.RuleMatches.Item1.Count); Assert.AreEqual("X", inconsistency.RuleMatches.Item1.Single().Name); Assert.AreEqual(0, inconsistency.RuleMatches.Item2.Count); Assert.AreEqual(remotePort, inconsistency.Packet.SourcePort); Assert.AreEqual(localPort, inconsistency.Packet.DestinationPort); Assert.AreEqual(protocol, inconsistency.Packet.Protocol); Assert.IsTrue(expected.Contains(inconsistency.Packet.SourceAddress)); expected.Remove(inconsistency.Packet.SourceAddress); } Assert.IsFalse(expected.Any()); }
public void TestSameFirewall() { string record = "X\tYes\tAllow\t80\t192.168.1.1\t128\t6"; string record2 = "Y\tYes\tAllow\t8080\t127.0.0.1\t256\t6"; string text = $"{WindowsFirewallRuleParserTest.HeaderText}\n{record}\n{record2}"; var firewall = new WindowsFirewall { BlockByDefault = true, Rules = WindowsFirewallRuleParser.Parse(text, '\t').ToList() }; var inconsistencies = WindowsFirewallEquivalenceCheck.CheckEquivalence(firewall, firewall); Assert.IsFalse(inconsistencies.Any()); }
/// <summary> /// Returns a list of inconsistencies between two firewall files. /// </summary> /// <param name="options">Options controlling the check.</param> /// <returns>A list of firewall inconsistencies.</returns> public static List <WindowsFirewallInconsistency> CheckFirewalls(Options options) { Console.WriteLine("Parsing first firewall..."); WindowsFirewall f1 = new WindowsFirewall { BlockByDefault = options.Firewall1BlockByDefault, Rules = WindowsFirewallRuleParser.Parse(File.ReadAllText(options.Firewall1Filepath), '\t').ToList() }; Console.WriteLine("Parsing second firewall..."); WindowsFirewall f2 = new WindowsFirewall { BlockByDefault = options.Firewall2BlockByDefault, Rules = WindowsFirewallRuleParser.Parse(File.ReadAllText(options.Firewall2Filepath), '\t').ToList() }; Console.WriteLine("Running equivalence check..."); return(WindowsFirewallEquivalenceCheck.CheckEquivalence(f1, f2).Take(options.InconsistencyCount).ToList()); }
public void TestSingleDifference() { int localPort = 80; int remotePort = 128; int protocol = 6; string record = $"X\tYes\tAllow\t{localPort}\t192.168.1.0-192.168.1.10\t{remotePort}\t{protocol}"; string text = $"{WindowsFirewallRuleParserTest.HeaderText}\n{record}"; var f1 = new WindowsFirewall { Name = "1", BlockByDefault = true, Rules = WindowsFirewallRuleParser.Parse(text, '\t').ToList() }; record = $"X\tYes\tAllow\t{localPort}\t192.168.1.0-192.168.1.4\t{remotePort}\t{protocol}"; string record2 = $"Y\tYes\tAllow\t{localPort}\t192.168.1.6-192.168.1.10\t{remotePort}\t{protocol}"; text = $"{WindowsFirewallRuleParserTest.HeaderText}\n{record}\n{record2}"; var f2 = new WindowsFirewall { Name = "2", BlockByDefault = true, Rules = WindowsFirewallRuleParser.Parse(text, '\t').ToList() }; var inconstistencies = WindowsFirewallEquivalenceCheck.CheckEquivalence(f1, f2).ToList(); Assert.AreEqual(1, inconstistencies.Count); WindowsFirewallInconsistency inconsistency = inconstistencies.Single(); Assert.AreEqual("1", inconsistency.Firewalls.Item1.Name); Assert.IsTrue(inconsistency.Allowed.Item1); Assert.AreEqual("2", inconsistency.Firewalls.Item2.Name); Assert.IsFalse(inconsistency.Allowed.Item2); Assert.AreEqual(1, inconsistency.RuleMatches.Item1.Count); Assert.AreEqual("X", inconsistency.RuleMatches.Item1.Single().Name); Assert.AreEqual(0, inconsistency.RuleMatches.Item2.Count); Assert.AreEqual(IPAddress.Parse("192.168.1.5"), inconsistency.Packet.SourceAddress); Assert.AreEqual(remotePort, inconsistency.Packet.SourcePort); Assert.AreEqual(localPort, inconsistency.Packet.DestinationPort); Assert.AreEqual(protocol, inconsistency.Packet.Protocol); }
public void TestConflict() { using (var ctx = new Context()) { int localPort = 80; IPAddress remoteAddress = IPAddress.Parse("192.168.1.1"); int remotePort = 128; int protocol = 6; string allowRecord = $"X\tYes\tAllow\t{localPort}\t{remoteAddress}\t{remotePort}\t{protocol}"; string blockRecord = $"Y\tYes\tBlock\t{localPort}\t{remoteAddress}\t{remotePort}\t{protocol}"; string text = $"{WindowsFirewallRuleParserTest.HeaderText}\n{allowRecord}\n{blockRecord}"; var firewall = new WindowsFirewall { BlockByDefault = true, Rules = WindowsFirewallRuleParser.Parse(text, '\t').ToList() }; var packetVars = new WindowsFirewallPacketVariables(ctx); Solver s = ctx.MkSolver(); s.Assert(firewall.Allows(ctx, packetVars)); Status result = s.Check(); Assert.AreEqual(Status.UNSATISFIABLE, result); } }
public void TestEquivalentFirewalls() { string record = "X\tYes\tAllow\t80\t192.168.1.0-192.168.1.10\t128\t6"; string text = $"{WindowsFirewallRuleParserTest.HeaderText}\n{record}"; var f1 = new WindowsFirewall { BlockByDefault = true, Rules = WindowsFirewallRuleParser.Parse(text, '\t').ToList() }; record = "X\tYes\tAllow\t80\t192.168.1.0-192.168.1.5\t128\t6"; string record2 = "Y\tYes\tAllow\t80\t192.168.1.6-192.168.1.10\t128\t6"; text = $"{WindowsFirewallRuleParserTest.HeaderText}\n{record}\n{record2}"; var f2 = new WindowsFirewall { BlockByDefault = true, Rules = WindowsFirewallRuleParser.Parse(text, '\t').ToList() }; var inconstistencies = WindowsFirewallEquivalenceCheck.CheckEquivalence(f1, f2); Assert.IsFalse(inconstistencies.Any()); }
public static void TestPacket(Options options) { Console.WriteLine("Parsing firewall rules..."); WindowsFirewall firewall = new WindowsFirewall { BlockByDefault = options.FirewallBlockByDefault, Rules = WindowsFirewallRuleParser.Parse(File.ReadAllText(options.FirewallFilepath), '\t').ToList() }; int protocolNumber; bool anyProtocol = false; if (!NetworkProtocol.TryGetProtocolNumber(options.Protocol, out protocolNumber)) { if (string.Equals("Any", options.Protocol, StringComparison.InvariantCultureIgnoreCase)) { anyProtocol = true; } else { protocolNumber = int.Parse(options.Protocol); } } WindowsFirewallPacket packet = new WindowsFirewallPacket { SourceAddress = IPAddress.Parse(options.SourceAddress), SourcePort = string.Equals("Any", options.SourcePort, StringComparison.InvariantCultureIgnoreCase) ? null : (int?)int.Parse(options.SourcePort), DestinationPort = string.Equals("Any", options.DestinationPort, StringComparison.InvariantCultureIgnoreCase) ? null : (int?)int.Parse(options.DestinationPort), Protocol = anyProtocol ? null : (int?)protocolNumber }; Console.WriteLine("Checking action of firewall on packet..."); using (var ctx = new Context()) { Solver s = ctx.MkSolver(); var packetVars = new WindowsFirewallPacketVariables(ctx); s.Assert(packet.Matches(ctx, packetVars)); s.Check(); if (s.Model.Eval(firewall.Allows(ctx, packetVars)).IsTrue) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Packet is allowed by firewall."); Console.ResetColor(); } else { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Packet is NOT allowed by firewall."); Console.ResetColor(); } List <WindowsFirewallRule> ruleMatches = firewall.GetMatches(ctx, packetVars, s.Model).ToList(); if (!ruleMatches.Any()) { Console.WriteLine("No firewall rules match the test packet."); return; } Console.WriteLine(); Console.WriteLine("Firewall rules matching the test packet:"); Console.WriteLine("-------------------------------------------------------------------------"); Console.WriteLine("| Action | Rule Name |"); Console.WriteLine("-------------------------------------------------------------------------"); foreach (WindowsFirewallRule rule in ruleMatches) { Console.WriteLine( $"| {(rule.Allow ? "Allow" : "Block"), 6} " + $"| {rule.Name.Substring(0, Math.Min(rule.Name.Length, 60)), -60} |"); } Console.WriteLine("-------------------------------------------------------------------------"); } }