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 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 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 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 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("-------------------------------------------------------------------------");
            }
        }