Example #1
0
        public override IpAddresses ResolveDNS(string host)
        {
            IpAddresses result = new IpAddresses();

            string getentPath = LocateExecutable("getent");

            if (getentPath != "")
            {
                // Note: CNAME record are automatically followed.
                SystemShell s = new SystemShell();
                s.Path = getentPath;
                s.Arguments.Add("ahosts");
                s.Arguments.Add(SystemShell.EscapeHost(host));
                s.NoDebugLog = true;
                if (s.Run())
                {
                    string o = s.Output;
                    o = o.CleanSpace();
                    foreach (string line in o.Split('\n'))
                    {
                        string[] fields = line.Split(' ');
                        if (fields.Length < 2)
                        {
                            continue;
                        }
                        if (fields[1].Trim() != "STREAM")
                        {
                            continue;
                        }
                        result.Add(fields[0].Trim());
                    }
                }
            }
            return(result);
        }
Example #2
0
        public void UpdateInterfaceStyle()
        {
            // AppleInterfaceStyle is user-level settings.
            // Setting the 'Dark mode' in preferences, don't change the interface style of the ROOT user, and AirVPN client run as root.
            // We detect the settings when this software relaunch itself, and here we update accordly the settings of the current (ROOT) user.
            string defaultsPath = Core.Platform.Instance.LocateExecutable("defaults");

            if (defaultsPath != "")
            {
                // If 'white', return error in StdErr and empty in StdOut.
                SystemShell s = new SystemShell();
                s.Path = defaultsPath;
                s.Arguments.Add("read");
                s.Arguments.Add("-g");
                s.Arguments.Add("AppleInterfaceStyle");
                s.Run();
                string rootColorMode = s.StdOut.Trim().ToLowerInvariant();
                if (rootColorMode == "")
                {
                    rootColorMode = "light";
                }
                string argsColorMode = Engine.Instance.Storage.Get("gui.osx.style");
                if (rootColorMode != argsColorMode)
                {
                    if (argsColorMode == "dark")
                    {
                        Core.SystemShell.Shell(defaultsPath, new string[] { "write", "-g", "AppleInterfaceStyle", "Dark" });
                    }
                    else
                    {
                        Core.SystemShell.Shell(defaultsPath, new string[] { "remove", "-g", "AppleInterfaceStyle" });
                    }
                }
            }
        }
Example #3
0
        public override bool RestartAsRoot()
        {
            string        path         = Platform.Instance.GetExecutablePath();
            List <string> args         = CommandLine.SystemEnvironment.GetFullArray();
            string        defaultsPath = Core.Platform.Instance.LocateExecutable("defaults");

            if (defaultsPath != "")
            {
                // If 'white', return error in StdErr and empty in StdOut.
                SystemShell s = new SystemShell();
                s.Path = defaultsPath;
                s.Arguments.Add("read");
                s.Arguments.Add("-g");
                s.Arguments.Add("AppleInterfaceStyle");
                s.Run();
                string colorMode = s.StdOut.Trim().ToLowerInvariant();
                if (colorMode == "dark")
                {
                    args.Add("gui.osx.style=\"dark\"");
                }
            }

            RootLauncher.LaunchExternalTool(path, args.ToArray());
            return(true);
        }
Example #4
0
        public override void Deactivation()
        {
            base.Deactivation();

            // Restore system rules
            SystemShell s = new SystemShell();

            s.Path = m_pfctlPath;
            s.Arguments.Add("-v");
            s.Arguments.Add("-f");
            s.Arguments.Add(SystemShell.EscapePath("/etc/pf.conf"));
            s.Run();

            if (m_filePfConf != null)
            {
                m_filePfConf.Close();
                m_filePfConf = null;
            }

            if (m_prevActive)
            {
            }
            else
            {
                SystemShell.Shell1(m_pfctlPath, "-d");
            }
        }
Example #5
0
        public override bool OnDnsSwitchDo(IpAddresses dns)
        {
            string mode = Engine.Instance.Storage.GetLower("dns.mode");

            if (mode == "auto")
            {
                string[] interfaces = GetInterfaces();
                foreach (string i in interfaces)
                {
                    string i2 = i.Trim();

                    string currentStr = SystemShell.Shell("/usr/sbin/networksetup", new string[] { "-getdnsservers", SystemShell.EscapeInsideQuote(i2) });

                    // v2
                    IpAddresses current = new IpAddresses();
                    foreach (string line in currentStr.Split('\n'))
                    {
                        string ip = line.Trim();
                        if (IpAddress.IsIP(ip))
                        {
                            current.Add(ip);
                        }
                    }

                    if (dns.Equals(current) == false)
                    {
                        DnsSwitchEntry e = new DnsSwitchEntry();
                        e.Name = i2;
                        e.Dns  = current.Addresses;
                        m_listDnsSwitch.Add(e);

                        SystemShell s = new SystemShell();
                        s.Path = LocateExecutable("networksetup");
                        s.Arguments.Add("-setdnsservers");
                        s.Arguments.Add(SystemShell.EscapeInsideQuote(i2));
                        if (dns.IPs.Count == 0)
                        {
                            s.Arguments.Add("empty");
                        }
                        else
                        {
                            foreach (IpAddress ip in dns.IPs)
                            {
                                s.Arguments.Add(ip.Address);
                            }
                        }
                        s.Run();

                        Engine.Instance.Logs.Log(LogType.Verbose, MessagesFormatter.Format(Messages.NetworkAdapterDnsDone, i2, ((current.Count == 0) ? "Automatic" : current.Addresses), dns.Addresses));
                    }
                }

                Recovery.Save();
            }

            base.OnDnsSwitchDo(dns);

            return(true);
        }
Example #6
0
        public override void OpenUrl(string url)
        {
            SystemShell s = new SystemShell();

            s.Path = LocateExecutable("xdg-open");
            s.Arguments.Add(url);
            s.WaitEnd = false;
            s.Run();
        }
Example #7
0
        public override void OpenFolder(string path)
        {
            SystemShell s = new SystemShell();

            s.Path = LocateExecutable("xdg-open");
            s.Arguments.Add(SystemShell.EscapePath(path));
            s.WaitEnd = false;
            s.Run();
        }
Example #8
0
        public string DoIptablesShell(string exe, string args, bool fatal)
        {
            lock (this)
            {
                // 2.14.0

                /*
                 * SystemShell s = new SystemShell();
                 * s.Path = Platform.Instance.LocateExecutable(exe);
                 * if (UtilsCore.CompareVersions(m_iptablesVersion, "1.4.21") >= 0)
                 * {
                 *      // 2.13.6 - The version 1.4.21 is generic Debian8. I don't find in official
                 *      // changelogs https://www.netfilter.org/projects/iptables/downloads.html
                 *      // the correct version. For sure don't exists in 1.4.14 of Debian7.
                 *      args = "--wait " + args;
                 * }
                 * if (args != "")
                 *      s.Arguments.Add(args); // Exception: all arguments as one, it works.
                 * if (fatal)
                 *      s.ExceptionIfFail = true;
                 * s.Run();
                 * return s.StdOut;
                 */

                // 2.14.1: Previous version use --wait if iptables >1.4.21. But there are issues about distro, even in the latest Debian unstable (2018).
                int    nTry          = 10;
                string lastestOutput = "";
                for (int iTry = 0; iTry < 10; iTry++)
                {
                    SystemShell s = new SystemShell();
                    s.Path = Platform.Instance.LocateExecutable(exe);
                    if (args != "")
                    {
                        s.Arguments.Add(args);                         // Exception: all arguments as one, it works.
                    }
                    if ((fatal) && (iTry == nTry - 1))
                    {
                        s.ExceptionIfFail = true;
                    }
                    s.Run();
                    if (s.StdErr.ToLowerInvariant().Contains("temporarily unavailable"))                     // Older Debian (iptables without --wait)
                    {
                        System.Threading.Thread.Sleep(500);
                        continue;
                    }
                    if (s.StdErr.ToLowerInvariant().Contains("xtables lock"))                     // Newest Debian (iptables with --wait but not automatic)
                    {
                        System.Threading.Thread.Sleep(500);
                        continue;
                    }
                    lastestOutput = s.StdOut;
                    return(lastestOutput);
                }
                return(lastestOutput);
            }
        }
Example #9
0
        public void SystemShellTest()
        {
            SystemShell systemShell = new SystemShell(new List <string> {
                "pathping", "nasa.com"
            });

            systemShell.Run();

            Assert.AreEqual("system shell", systemShell.Name);
            Assert.AreEqual("pathping", systemShell.Input[0]);
            Assert.AreEqual("nasa.com", systemShell.Input[1]);
        }
Example #10
0
        public override bool RouteRemove(Json jRoute)
        {
            IpAddress ip = jRoute["address"].Value as string;

            if (ip.Valid == false)
            {
                return(false);
            }
            IpAddress gateway = jRoute["gateway"].Value as string;

            if (gateway.Valid == false)
            {
                return(false);
            }

            SystemShell s = new SystemShell();

            s.Path = LocateExecutable("route");
            s.Arguments.Add("-n");
            s.Arguments.Add("delete");
            if (ip.IsV6)
            {
                s.Arguments.Add("-inet6");
            }
            s.Arguments.Add(ip.ToCIDR());
            s.Arguments.Add(gateway.Address);
            s.ExceptionIfFail = true;
            s.Run();

            string result = s.StdErr.Trim();

            if (result == "")
            {
                return(base.RouteRemove(jRoute));
            }
            else
            {
                // Remember: Route deletion can occur in a second moment (for example a Recovery phase).

                // Still accepted: The device are not available anymore, so the route are already deleted.

                // Still accepted: Already deleted.
                if (result.ToLowerInvariant().Contains("not in table"))
                {
                    return(base.RouteRemove(jRoute));
                }

                // Unexpected/unknown error.
                Engine.Instance.Logs.LogWarning(MessagesFormatter.Format(Messages.RouteDelFailed, ip.ToCIDR(), gateway.ToCIDR(), result));
                return(false);
            }
        }
Example #11
0
        public override string FileGetSignedId(string path)
        {
            string      codesignPath = LocateExecutable("codesign");
            SystemShell cmdV         = new SystemShell();

            cmdV.Path = codesignPath;
            cmdV.Arguments.Add("-v");
            cmdV.Arguments.Add(SystemShell.EscapePath(path));
            cmdV.Run();
            if (cmdV.Output != "")             // ExitCode always 0
            {
                return("No: Invalid signature (tampered?)");
            }

            SystemShell cmdS = new SystemShell();

            cmdS.Path = codesignPath;
            cmdS.Arguments.Clear();
            cmdS.Arguments.Add("-dv");
            cmdS.Arguments.Add("--verbose=4");
            cmdS.Arguments.Add(SystemShell.EscapePath(path));
            cmdS.Run();

            string codesignResult = cmdS.Output;
            string o = "";

            foreach (string line in codesignResult.Split('\n'))
            {
                int posE = line.IndexOf("=", StringComparison.InvariantCulture);
                if (posE != -1)
                {
                    string k = line.Substring(0, posE);
                    if (k == "Authority")
                    {
                        if (o != "")
                        {
                            o += " - ";
                        }
                        o += line.Substring(posE + 1);
                    }
                }
            }

            if (o != "")
            {
                return(o);
            }
            else
            {
                return(base.FileGetSignedId(path));
            }
        }
Example #12
0
        public override bool OsCredentialSystemDelete(string name)
        {
            string      secretToolPath = LocateExecutable("secret-tool");
            SystemShell shell          = new SystemShell();

            shell.Path = secretToolPath;
            shell.Arguments.Add("clear");
            shell.Arguments.Add("'Eddie Profile'");
            shell.Arguments.Add("'" + SystemShell.EscapeInsideQuote(name) + "'");
            shell.Run();
            int exitCode = shell.ExitCode;

            return(exitCode == 0);
        }
Example #13
0
        public override bool OsCredentialSystemWrite(string name, string password)
        {
            string      secretToolPath = LocateExecutable("secret-tool");
            SystemShell shell          = new SystemShell();

            shell.Path = secretToolPath;
            shell.Arguments.Add("store");
            shell.Arguments.Add("--label='Eddie, saved password for " + SystemShell.EscapeInsideQuote(name) + " profile'");
            shell.Arguments.Add("'Eddie Profile'");
            shell.Arguments.Add("'" + SystemShell.EscapeInsideQuote(name) + "'");
            shell.AutoWriteStdin = password + "\n";
            shell.Run();
            int exitCode = shell.ExitCode;

            return(exitCode == 0);
        }
Example #14
0
        public override bool OnDnsSwitchRestore()
        {
            foreach (DnsSwitchEntry e in m_listDnsSwitch)
            {
                /*
                 * string v = e.Dns;
                 * if (v == "")
                 *      v = "empty";
                 * v = v.Replace(",", "\" \"");
                 *
                 * SystemShell.Shell("/usr/sbin/networksetup", new string[] { "-setdnsservers", SystemShell.EscapeInsideQuote(e.Name), v });
                 */
                IpAddresses dns = new IpAddresses();
                dns.Add(e.Dns);

                SystemShell s = new SystemShell();
                s.Path = LocateExecutable("networksetup");
                s.Arguments.Add("-setdnsservers");
                s.Arguments.Add(SystemShell.EscapeInsideQuote(e.Name));
                if (dns.Count == 0)
                {
                    s.Arguments.Add("empty");
                }
                else
                {
                    foreach (IpAddress ip in dns.IPs)
                    {
                        s.Arguments.Add(ip.Address);
                    }
                }
                s.Run();

                Engine.Instance.Logs.Log(LogType.Verbose, MessagesFormatter.Format(Messages.NetworkAdapterDnsRestored, e.Name, ((e.Dns == "") ? "Automatic" : e.Dns)));
            }

            m_listDnsSwitch.Clear();

            Recovery.Save();

            base.OnDnsSwitchRestore();

            return(true);
        }
Example #15
0
        public override bool RouteAdd(Json jRoute)
        {
            IpAddress ip = jRoute["address"].Value as string;

            if (ip.Valid == false)
            {
                return(false);
            }
            IpAddress gateway = jRoute["gateway"].Value as string;

            if (gateway.Valid == false)
            {
                return(false);
            }

            SystemShell s = new SystemShell();

            s.Path = LocateExecutable("route");
            s.Arguments.Add("-n");
            s.Arguments.Add("add");
            if (ip.IsV6)
            {
                s.Arguments.Add("-inet6");
            }
            s.Arguments.Add(ip.ToCIDR());
            s.Arguments.Add(gateway.Address);
            s.ExceptionIfFail = true;
            s.Run();

            string result = s.StdErr.Trim();

            if (result == "")
            {
                return(base.RouteAdd(jRoute));
            }
            else
            {
                Engine.Instance.Logs.LogWarning(MessagesFormatter.Format(Messages.RouteAddFailed, ip.ToCIDR(), gateway.ToCIDR(), result));
                return(false);
            }
        }
Example #16
0
        public override string OsCredentialSystemRead(string name)
        {
            string      secretToolPath = LocateExecutable("secret-tool");
            SystemShell shell          = new SystemShell();

            shell.Path = secretToolPath;
            shell.Arguments.Add("lookup");
            shell.Arguments.Add("'Eddie Profile'");
            shell.Arguments.Add("'" + SystemShell.EscapeInsideQuote(name) + "'");
            shell.Run();
            int exitCode = shell.ExitCode;

            if (exitCode == 0)
            {
                return(shell.Output);
            }
            else
            {
                return("");
            }
        }
Example #17
0
        public override IpAddresses ResolveDNS(string host)
        {
            // Base method with Dns.GetHostEntry have cache issue, for example on Fedora. OS X it's based on Mono.
            // Also, base methods with Dns.GetHostEntry sometime don't fetch AAAA IPv6 addresses.

            IpAddresses result = new IpAddresses();

            string hostPath = LocateExecutable("host");

            if (hostPath != "")
            {
                // Note: CNAME record are automatically followed.
                SystemShell s = new SystemShell();
                s.Path = "/usr/bin/host";
                s.Arguments.Add("-W 5");
                s.Arguments.Add(SystemShell.EscapeHost(host));
                s.NoDebugLog = true;
                if (s.Run())
                {
                    string hostout = s.Output;
                    foreach (string line in hostout.Split('\n'))
                    {
                        string ipv4 = Utils.RegExMatchOne(line, "^.*? has address (.*?)$");
                        if (ipv4 != "")
                        {
                            result.Add(ipv4.Trim());
                        }

                        string ipv6 = Utils.RegExMatchOne(line, "^.*? has IPv6 address (.*?)$");
                        if (ipv6 != "")
                        {
                            result.Add(ipv6.Trim());
                        }
                    }
                }
            }

            return(result);
        }
Example #18
0
        public string DoIptablesShell(string exe, string args, bool fatal)
        {
            SystemShell s = new SystemShell();

            s.Path = Platform.Instance.LocateExecutable(exe);
            if (Utils.CompareVersions(m_iptablesVersion, "1.4.21") >= 0)
            {
                // 2.13.6 - The version 1.4.21 is generic Debian8. I don't find in official
                // changelogs https://www.netfilter.org/projects/iptables/downloads.html
                // the correct version. For sure don't exists in 1.4.14 of Debian7.
                args = "--wait " + args;
            }
            if (args != "")
            {
                s.Arguments.Add(args);                 // Exception: all arguments as one, it works.
            }
            if (fatal)
            {
                s.ExceptionIfFail = true;
            }
            s.Run();
            return(s.StdOut);
        }
Example #19
0
        public override void Activation()
        {
            base.Activation();

            string rulesBackupSessionV4 = GetBackupPath("4");
            string rulesBackupSessionV6 = GetBackupPath("6");

            try
            {
                if ((Platform.Instance.FileExists(rulesBackupSessionV4)) || (Platform.Instance.FileExists(rulesBackupSessionV6)))
                {
                    throw new Exception(Messages.NetworkLockLinuxUnexpectedAlreadyActive);
                }

                // IPv4 assumed, if not available, will throw a fatal exception.

                // IPv6 Test
                {
                    SystemShell s = new SystemShell();
                    s.Path = Platform.Instance.LocateExecutable("ip6tables");
                    s.Arguments.Add("-L");
                    m_supportIPv6 = s.Run();

                    if (m_supportIPv6 == false)
                    {
                        Engine.Instance.Logs.Log(LogType.Verbose, Messages.NetworkLockLinuxIPv6NotAvailable);
                    }
                }


                if (m_supportIPv4)
                {
                    // IPv4 - Backup
                    Platform.Instance.FileContentsWriteText(rulesBackupSessionV4, DoIptablesShell("iptables-save", ""));
                }

                if (m_supportIPv6)
                {
                    // IPv6 - Backup
                    Platform.Instance.FileContentsWriteText(rulesBackupSessionV6, DoIptablesShell("ip6tables-save", ""));
                }

                if (m_supportIPv4)
                {
                    // IPv4 - Flush
                    DoIptablesShell("iptables", "-P INPUT ACCEPT");
                    DoIptablesShell("iptables", "-P FORWARD ACCEPT");
                    DoIptablesShell("iptables", "-P OUTPUT ACCEPT");
                    DoIptablesShell("iptables", "-t nat -F", false);
                    DoIptablesShell("iptables", "-t mangle -F", false);
                    DoIptablesShell("iptables", "-F");
                    DoIptablesShell("iptables", "-X");
                }

                if (m_supportIPv6)
                {
                    // IPv6 - Flush
                    DoIptablesShell("ip6tables", "-P INPUT ACCEPT");
                    DoIptablesShell("ip6tables", "-P FORWARD ACCEPT");
                    DoIptablesShell("ip6tables", "-P OUTPUT ACCEPT");
                    DoIptablesShell("ip6tables", "-t nat -F", false);
                    DoIptablesShell("ip6tables", "-t mangle -F", false);
                    DoIptablesShell("ip6tables", "-F");
                    DoIptablesShell("ip6tables", "-X");
                }

                if (m_supportIPv4)
                {
                    // IPv4 - Local
                    DoIptablesShell("iptables", "-A INPUT -i lo -j ACCEPT");
                    DoIptablesShell("iptables", "-A OUTPUT -o lo -j ACCEPT");
                }

                if (m_supportIPv6)
                {
                    // IPv6 - Local
                    DoIptablesShell("ip6tables", "-A INPUT -i lo -j ACCEPT");
                    // Reject traffic to localhost that does not originate from lo0.
                    DoIptablesShell("ip6tables", "-A INPUT ! -i lo -s ::1/128 -j REJECT");                     // 2.14.0
                    DoIptablesShell("ip6tables", "-A OUTPUT -o lo -j ACCEPT");
                }

                if (m_supportIPv6)
                {
                    // IPv6 - Disable processing of any RH0 packet which could allow a ping-pong of packets
                    DoIptablesShell("ip6tables", "-A INPUT -m rt --rt-type 0 -j DROP");
                    DoIptablesShell("ip6tables", "-A OUTPUT -m rt --rt-type 0 -j DROP");
                    DoIptablesShell("ip6tables", "-A FORWARD -m rt --rt-type 0 -j DROP");
                }

                if (m_supportIPv6)                 // 2.14.0
                {
                    // IPv6 - Rules which are required for your IPv6 address to be properly allocated
                    DoIptablesShell("ip6tables", "-A INPUT -p icmpv6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT");
                    DoIptablesShell("ip6tables", "-A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -m hl --hl-eq 255 -j ACCEPT");
                    DoIptablesShell("ip6tables", "-A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -m hl --hl-eq 255 -j ACCEPT");
                    DoIptablesShell("ip6tables", "-A INPUT -p icmpv6 --icmpv6-type redirect -m hl --hl-eq 255 -j ACCEPT");
                }

                if (m_supportIPv4)
                {
                    // IPv4 - Make sure you can communicate with any DHCP server
                    DoIptablesShell("iptables", "-A OUTPUT -d 255.255.255.255 -j ACCEPT");
                    DoIptablesShell("iptables", "-A INPUT -s 255.255.255.255 -j ACCEPT");
                }

                if (Engine.Instance.Storage.GetBool("netlock.allow_private"))
                {
                    if (m_supportIPv4)
                    {
                        // IPv4 - Private networks
                        DoIptablesShell("iptables", "-A INPUT -s 192.168.0.0/16 -d 192.168.0.0/16 -j ACCEPT");
                        DoIptablesShell("iptables", "-A OUTPUT -s 192.168.0.0/16 -d 192.168.0.0/16 -j ACCEPT");
                        DoIptablesShell("iptables", "-A INPUT -s 10.0.0.0/8 -d 10.0.0.0/8 -j ACCEPT");
                        DoIptablesShell("iptables", "-A OUTPUT -s 10.0.0.0/8 -d 10.0.0.0/8 -j ACCEPT");
                        DoIptablesShell("iptables", "-A INPUT -s 172.16.0.0/12 -d 172.16.0.0/12 -j ACCEPT");
                        DoIptablesShell("iptables", "-A OUTPUT -s 172.16.0.0/12 -d 172.16.0.0/12 -j ACCEPT");

                        // IPv4 - Multicast
                        DoIptablesShell("iptables", "-A OUTPUT -s 192.168.0.0/16 -d 224.0.0.0/24 -j ACCEPT");
                        DoIptablesShell("iptables", "-A OUTPUT -s 192.168.0.0/16 -d 224.0.0.0/24 -j ACCEPT");
                        DoIptablesShell("iptables", "-A OUTPUT -s 192.168.0.0/16 -d 224.0.0.0/24 -j ACCEPT");

                        // IPv4 - 239.255.255.250  Simple Service Discovery Protocol address
                        DoIptablesShell("iptables", "-A OUTPUT -s 192.168.0.0/16 -d 239.255.255.250/32 -j ACCEPT");
                        DoIptablesShell("iptables", "-A OUTPUT -s 192.168.0.0/16 -d 239.255.255.250/32 -j ACCEPT");
                        DoIptablesShell("iptables", "-A OUTPUT -s 192.168.0.0/16 -d 239.255.255.250/32 -j ACCEPT");

                        // IPv4 - 239.255.255.253  Service Location Protocol version 2 address
                        DoIptablesShell("iptables", "-A OUTPUT -s 192.168.0.0/16 -d 239.255.255.253/32 -j ACCEPT");
                        DoIptablesShell("iptables", "-A OUTPUT -s 192.168.0.0/16 -d 239.255.255.253/32 -j ACCEPT");
                        DoIptablesShell("iptables", "-A OUTPUT -s 192.168.0.0/16 -d 239.255.255.253/32 -j ACCEPT");
                    }

                    if (m_supportIPv6)
                    {
                        // IPv6 - Allow Link-Local addresses
                        DoIptablesShell("ip6tables", "-A INPUT -s fe80::/10 -j ACCEPT");
                        DoIptablesShell("ip6tables", "-A OUTPUT -s fe80::/10 -j ACCEPT");

                        // IPv6 - Allow multicast
                        DoIptablesShell("ip6tables", "-A INPUT -d ff00::/8 -j ACCEPT");
                        DoIptablesShell("ip6tables", "-A OUTPUT -d ff00::/8 -j ACCEPT");
                    }
                }

                if (Engine.Instance.Storage.GetBool("netlock.allow_ping"))
                {
                    if (m_supportIPv4)
                    {
                        // IPv4
                        DoIptablesShell("iptables", "-A INPUT -p icmp --icmp-type echo-request -j ACCEPT");
                        DoIptablesShell("iptables", "-A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT");                         // 2.14.0
                    }

                    if (m_supportIPv6)
                    {
                        // IPv6
                        DoIptablesShell("ip6tables", "-A INPUT -p icmpv6 -j ACCEPT");
                        DoIptablesShell("ip6tables", "-A OUTPUT -p icmpv6 -j ACCEPT");
                    }
                }

                if (m_supportIPv4)
                {
                    // IPv4 - Allow established sessions to receive traffic
                    DoIptablesShell("iptables", "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT");
                }

                if (m_supportIPv6)
                {
                    // IPv6 - Allow established sessions to receive traffic
                    DoIptablesShell("ip6tables", "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT");
                }

                if (m_supportIPv4)
                {
                    // IPv4 - Allow TUN
                    DoIptablesShell("iptables", "-A INPUT -i tun+ -j ACCEPT");
                    DoIptablesShell("iptables", "-A FORWARD -i tun+ -j ACCEPT");
                    DoIptablesShell("iptables", "-A OUTPUT -o tun+ -j ACCEPT");
                }

                if (m_supportIPv6)
                {
                    // IPv6 - Allow TUN
                    DoIptablesShell("ip6tables", "-A INPUT -i tun+ -j ACCEPT");
                    DoIptablesShell("ip6tables", "-A FORWARD -i tun+ -j ACCEPT");
                    DoIptablesShell("ip6tables", "-A OUTPUT -o tun+ -j ACCEPT");
                }

                if (m_supportIPv4)
                {
                    // IPv4 - General rule
                    DoIptablesShell("iptables", "-A FORWARD -j DROP");
                    if (Engine.Instance.Storage.Get("netlock.incoming") == "allow")
                    {
                        DoIptablesShell("iptables", "-A INPUT -j ACCEPT");
                    }
                    else
                    {
                        DoIptablesShell("iptables", "-A INPUT -j DROP");
                    }
                    if (Engine.Instance.Storage.Get("netlock.outgoing") == "allow")
                    {
                        DoIptablesShell("iptables", "-A OUTPUT -j ACCEPT");
                    }
                    else
                    {
                        DoIptablesShell("iptables", "-A OUTPUT -j DROP");
                    }
                }

                if (m_supportIPv6)
                {
                    // IPv6 - General rule
                    DoIptablesShell("ip6tables", "-A FORWARD -j DROP");
                    if (Engine.Instance.Storage.Get("netlock.incoming") == "allow")
                    {
                        DoIptablesShell("ip6tables", "-A INPUT -j ACCEPT");
                    }
                    else
                    {
                        DoIptablesShell("ip6tables", "-A INPUT -j DROP");
                    }
                    if (Engine.Instance.Storage.Get("netlock.outgoing") == "allow")
                    {
                        DoIptablesShell("ip6tables", "-A OUTPUT -j ACCEPT");
                    }
                    else
                    {
                        DoIptablesShell("ip6tables", "-A OUTPUT -j DROP");
                    }
                }

                OnUpdateIps();
            }
            catch (Exception ex)
            {
                Deactivation();
                throw new Exception(ex.Message);
            }
        }
Example #20
0
        public override void Activation()
        {
            base.Activation();

            string rulesBackupSessionV4 = GetBackupPath("4");
            string rulesBackupSessionV6 = GetBackupPath("6");

            try
            {
                if ((Platform.Instance.FileExists(rulesBackupSessionV4)) || (Platform.Instance.FileExists(rulesBackupSessionV6)))
                {
                    throw new Exception(Messages.NetworkLockLinuxUnexpectedAlreadyActive);
                }

                // IPv4 assumed, if not available, will throw a fatal exception.

                // IPv6 Test
                {
                    SystemShell s = new SystemShell();
                    s.Path = Platform.Instance.LocateExecutable("ip6tables");
                    s.Arguments.Add("-L");
                    m_supportIPv6 = s.Run();

                    if (m_supportIPv6 == false)
                    {
                        Engine.Instance.Logs.Log(LogType.Verbose, Messages.NetworkLockLinuxIPv6NotAvailable);
                    }
                }


                if (m_supportIPv4)
                {
                    // IPv4 - Backup
                    Platform.Instance.FileContentsWriteText(rulesBackupSessionV4, DoIptablesShell("iptables-save", ""), Encoding.ASCII);
                }

                if (m_supportIPv6)
                {
                    // IPv6 - Backup
                    Platform.Instance.FileContentsWriteText(rulesBackupSessionV6, DoIptablesShell("ip6tables-save", ""), Encoding.ASCII);
                }

                /* // Version <2.17
                 * // Flush
                 * if(true)
                 * {
                 *      if (m_supportIPv4)
                 *      {
                 *              DoIptablesShell("iptables", "-P INPUT ACCEPT");
                 *              DoIptablesShell("iptables", "-P FORWARD ACCEPT");
                 *              DoIptablesShell("iptables", "-P OUTPUT ACCEPT");
                 *              DoIptablesShell("iptables", "-t nat -F", false);
                 *              DoIptablesShell("iptables", "-t mangle -F", false);
                 *              DoIptablesShell("iptables", "-F");
                 *              DoIptablesShell("iptables", "-X");
                 *      }
                 *
                 *      if (m_supportIPv6)
                 *      {
                 *              DoIptablesShell("ip6tables", "-P INPUT ACCEPT");
                 *              DoIptablesShell("ip6tables", "-P FORWARD ACCEPT");
                 *              DoIptablesShell("ip6tables", "-P OUTPUT ACCEPT");
                 *              DoIptablesShell("ip6tables", "-t nat -F", false);
                 *              DoIptablesShell("ip6tables", "-t mangle -F", false);
                 *              DoIptablesShell("ip6tables", "-F");
                 *              DoIptablesShell("ip6tables", "-X");
                 *      }
                 * }
                 *
                 * // Local
                 * if(true)
                 * {
                 *      if (m_supportIPv4)
                 *      {
                 *              DoIptablesShell("iptables", "-A INPUT -i lo -j ACCEPT");
                 *              DoIptablesShell("iptables", "-A OUTPUT -o lo -j ACCEPT");
                 *      }
                 *
                 *      if (m_supportIPv6)
                 *      {
                 *              DoIptablesShell("ip6tables", "-A INPUT -i lo -j ACCEPT");
                 *              // Reject traffic to localhost that does not originate from lo0.
                 *              DoIptablesShell("ip6tables", "-A INPUT ! -i lo -s ::1/128 -j REJECT"); // 2.14.0
                 *              DoIptablesShell("ip6tables", "-A OUTPUT -o lo -j ACCEPT");
                 *      }
                 * }
                 *
                 * if (m_supportIPv6)
                 * {
                 *      // IPv6 - Disable processing of any RH0 packet which could allow a ping-pong of packets
                 *      DoIptablesShell("ip6tables", "-A INPUT -m rt --rt-type 0 -j DROP");
                 *      DoIptablesShell("ip6tables", "-A OUTPUT -m rt --rt-type 0 -j DROP");
                 *      DoIptablesShell("ip6tables", "-A FORWARD -m rt --rt-type 0 -j DROP");
                 * }
                 *
                 * if (m_supportIPv6) // 2.14.0
                 * {
                 *      // IPv6 - Rules which are required for your IPv6 address to be properly allocated
                 *      DoIptablesShell("ip6tables", "-A INPUT -p icmpv6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT");
                 *      DoIptablesShell("ip6tables", "-A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -m hl --hl-eq 255 -j ACCEPT");
                 *      DoIptablesShell("ip6tables", "-A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -m hl --hl-eq 255 -j ACCEPT");
                 *      DoIptablesShell("ip6tables", "-A INPUT -p icmpv6 --icmpv6-type redirect -m hl --hl-eq 255 -j ACCEPT");
                 * }
                 *
                 * // Allow DHCP
                 * if (Engine.Instance.Storage.GetBool("netlock.allow_dhcp") == true)
                 * {
                 *      if (m_supportIPv4)
                 *      {
                 *              // IPv4 - Make sure you can communicate with any DHCP server
                 *              DoIptablesShell("iptables", "-A OUTPUT -d 255.255.255.255 -j ACCEPT");
                 *              DoIptablesShell("iptables", "-A INPUT -s 255.255.255.255 -j ACCEPT");
                 *      }
                 * }
                 *
                 * // Allow private
                 * if (Engine.Instance.Storage.GetBool("netlock.allow_private"))
                 * {
                 *      if (m_supportIPv4)
                 *      {
                 *              // IPv4 - Private networks
                 *              DoIptablesShell("iptables", "-A INPUT -s 192.168.0.0/16 -d 192.168.0.0/16 -j ACCEPT");
                 *              DoIptablesShell("iptables", "-A OUTPUT -s 192.168.0.0/16 -d 192.168.0.0/16 -j ACCEPT");
                 *              DoIptablesShell("iptables", "-A INPUT -s 10.0.0.0/8 -d 10.0.0.0/8 -j ACCEPT");
                 *              DoIptablesShell("iptables", "-A OUTPUT -s 10.0.0.0/8 -d 10.0.0.0/8 -j ACCEPT");
                 *              DoIptablesShell("iptables", "-A INPUT -s 172.16.0.0/12 -d 172.16.0.0/12 -j ACCEPT");
                 *              DoIptablesShell("iptables", "-A OUTPUT -s 172.16.0.0/12 -d 172.16.0.0/12 -j ACCEPT");
                 *
                 *              // IPv4 - Multicast
                 *              DoIptablesShell("iptables", "-A OUTPUT -s 192.168.0.0/16 -d 224.0.0.0/24 -j ACCEPT");
                 *              DoIptablesShell("iptables", "-A OUTPUT -s 192.168.0.0/16 -d 224.0.0.0/24 -j ACCEPT");
                 *              DoIptablesShell("iptables", "-A OUTPUT -s 192.168.0.0/16 -d 224.0.0.0/24 -j ACCEPT");
                 *
                 *              // IPv4 - 239.255.255.250  Simple Service Discovery Protocol address
                 *              DoIptablesShell("iptables", "-A OUTPUT -s 192.168.0.0/16 -d 239.255.255.250/32 -j ACCEPT");
                 *              DoIptablesShell("iptables", "-A OUTPUT -s 192.168.0.0/16 -d 239.255.255.250/32 -j ACCEPT");
                 *              DoIptablesShell("iptables", "-A OUTPUT -s 192.168.0.0/16 -d 239.255.255.250/32 -j ACCEPT");
                 *
                 *              // IPv4 - 239.255.255.253  Service Location Protocol version 2 address
                 *              DoIptablesShell("iptables", "-A OUTPUT -s 192.168.0.0/16 -d 239.255.255.253/32 -j ACCEPT");
                 *              DoIptablesShell("iptables", "-A OUTPUT -s 192.168.0.0/16 -d 239.255.255.253/32 -j ACCEPT");
                 *              DoIptablesShell("iptables", "-A OUTPUT -s 192.168.0.0/16 -d 239.255.255.253/32 -j ACCEPT");
                 *      }
                 *
                 *      if (m_supportIPv6)
                 *      {
                 *              // IPv6 - Allow Link-Local addresses
                 *              DoIptablesShell("ip6tables", "-A INPUT -s fe80::/10 -j ACCEPT");
                 *              DoIptablesShell("ip6tables", "-A OUTPUT -s fe80::/10 -j ACCEPT");
                 *
                 *              // IPv6 - Allow multicast
                 *              DoIptablesShell("ip6tables", "-A INPUT -d ff00::/8 -j ACCEPT");
                 *              DoIptablesShell("ip6tables", "-A OUTPUT -d ff00::/8 -j ACCEPT");
                 *      }
                 * }
                 *
                 * // Allow ping
                 * if (Engine.Instance.Storage.GetBool("netlock.allow_ping"))
                 * {
                 *      if (m_supportIPv4)
                 *      {
                 *              // IPv4
                 *              DoIptablesShell("iptables", "-A INPUT -p icmp --icmp-type echo-request -j ACCEPT");
                 *              DoIptablesShell("iptables", "-A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT"); // 2.14.0
                 *      }
                 *
                 *      if (m_supportIPv6)
                 *      {
                 *              // IPv6
                 *              DoIptablesShell("ip6tables", "-A INPUT -p icmpv6 -j ACCEPT");
                 *              DoIptablesShell("ip6tables", "-A OUTPUT -p icmpv6 -j ACCEPT");
                 *      }
                 * }
                 *
                 * // Allow established sessions to receive traffic
                 * if(true)
                 * {
                 *      if (m_supportIPv4)
                 *      {
                 *              DoIptablesShell("iptables", "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT");
                 *      }
                 *
                 *      if (m_supportIPv6)
                 *      {
                 *              DoIptablesShell("ip6tables", "-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT");
                 *      }
                 * }
                 *
                 * // Allow TUN
                 * if (true)
                 * {
                 *      if (m_supportIPv4)
                 *      {
                 *              DoIptablesShell("iptables", "-A INPUT -i tun+ -j ACCEPT");
                 *              DoIptablesShell("iptables", "-A FORWARD -i tun+ -j ACCEPT");
                 *              DoIptablesShell("iptables", "-A OUTPUT -o tun+ -j ACCEPT");
                 *      }
                 *
                 *      if (m_supportIPv6)
                 *      {
                 *              DoIptablesShell("ip6tables", "-A INPUT -i tun+ -j ACCEPT");
                 *              DoIptablesShell("ip6tables", "-A FORWARD -i tun+ -j ACCEPT");
                 *              DoIptablesShell("ip6tables", "-A OUTPUT -o tun+ -j ACCEPT");
                 *      }
                 * }
                 *
                 * // General rules
                 * {
                 *      if (m_supportIPv4)
                 *      {
                 *              DoIptablesShell("iptables", "-A FORWARD -j DROP");
                 *              if (Engine.Instance.Storage.Get("netlock.incoming") == "allow")
                 *                      DoIptablesShell("iptables", "-A INPUT -j ACCEPT");
                 *              else
                 *                      DoIptablesShell("iptables", "-A INPUT -j DROP");
                 *              if (Engine.Instance.Storage.Get("netlock.outgoing") == "allow")
                 *                      DoIptablesShell("iptables", "-A OUTPUT -j ACCEPT");
                 *              else
                 *                      DoIptablesShell("iptables", "-A OUTPUT -j DROP");
                 *      }
                 *
                 *      if (m_supportIPv6)
                 *      {
                 *              DoIptablesShell("ip6tables", "-A FORWARD -j DROP");
                 *              if (Engine.Instance.Storage.Get("netlock.incoming") == "allow")
                 *                      DoIptablesShell("ip6tables", "-A INPUT -j ACCEPT");
                 *              else
                 *                      DoIptablesShell("ip6tables", "-A INPUT -j DROP");
                 *              if (Engine.Instance.Storage.Get("netlock.outgoing") == "allow")
                 *                      DoIptablesShell("ip6tables", "-A OUTPUT -j ACCEPT");
                 *              else
                 *                      DoIptablesShell("ip6tables", "-A OUTPUT -j DROP");
                 *      }
                 * }
                 */

                // Version 2.17

                IpAddresses ipsWhiteListOutgoing = GetIpsWhiteListOutgoing(true);

                // IPv4
                if (m_supportIPv4)
                {
                    var body = new System.Text.StringBuilder();

                    body.AppendLine("*mangle");
                    body.AppendLine(":PREROUTING ACCEPT [0:0]");
                    body.AppendLine(":INPUT ACCEPT [0:0]");
                    body.AppendLine(":FORWARD ACCEPT [0:0]");
                    body.AppendLine(":OUTPUT ACCEPT [0:0]");
                    body.AppendLine(":POSTROUTING ACCEPT [0:0]");
                    body.AppendLine("COMMIT");
                    body.AppendLine("*nat");
                    body.AppendLine(":PREROUTING ACCEPT [0:0]");
                    body.AppendLine(":INPUT ACCEPT [0:0]");
                    body.AppendLine(":OUTPUT ACCEPT [0:0]");
                    body.AppendLine(":POSTROUTING ACCEPT [0:0]");
                    body.AppendLine("COMMIT");
                    body.AppendLine("*filter");
                    body.AppendLine(":INPUT ACCEPT [0:0]");
                    body.AppendLine(":FORWARD ACCEPT [0:0]");
                    body.AppendLine(":OUTPUT ACCEPT [0:0]");

                    // Local
                    body.AppendLine("-A INPUT -i lo -j ACCEPT");

                    if (Engine.Instance.Storage.GetBool("netlock.allow_dhcp") == true)
                    {
                        body.AppendLine("-A INPUT -s 255.255.255.255/32 -j ACCEPT");
                    }

                    if (Engine.Instance.Storage.GetBool("netlock.allow_private"))
                    {
                        // Private networks
                        body.AppendLine("-A INPUT -s 192.168.0.0/16 -d 192.168.0.0/16 -j ACCEPT");
                        body.AppendLine("-A INPUT -s 10.0.0.0/8 -d 10.0.0.0/8 -j ACCEPT");
                        body.AppendLine("-A INPUT -s 172.16.0.0/12 -d 172.16.0.0/12 -j ACCEPT");
                    }

                    if (Engine.Instance.Storage.GetBool("netlock.allow_ping"))
                    {
                        // icmp-type: echo-request
                        body.AppendLine("-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT");
                    }

                    // Allow established sessions to receive traffic
                    body.AppendLine("-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT");

                    // Allow TUN
                    body.AppendLine("-A INPUT -i tun+ -j ACCEPT");

                    if (Engine.Instance.Storage.Get("netlock.incoming") == "allow")
                    {
                        body.AppendLine("-A INPUT -j ACCEPT");
                    }
                    else
                    {
                        body.AppendLine("-A INPUT -j DROP");
                    }

                    // Allow TUN
                    body.AppendLine("-A FORWARD -i tun+ -j ACCEPT");

                    // Fixed general rule
                    body.AppendLine("-A FORWARD -j DROP");

                    // Local
                    body.AppendLine("-A OUTPUT -o lo -j ACCEPT");

                    if (Engine.Instance.Storage.GetBool("netlock.allow_dhcp") == true)
                    {
                        // Make sure you can communicate with any DHCP server
                        body.AppendLine("-A OUTPUT -d 255.255.255.255/32 -j ACCEPT");
                    }

                    if (Engine.Instance.Storage.GetBool("netlock.allow_private"))
                    {
                        // Private networks
                        body.AppendLine("-A OUTPUT -s 192.168.0.0/16 -d 192.168.0.0/16 -j ACCEPT");
                        body.AppendLine("-A OUTPUT -s 10.0.0.0/8 -d 10.0.0.0/8 -j ACCEPT");
                        body.AppendLine("-A OUTPUT -s 172.16.0.0/12 -d 172.16.0.0/12 -j ACCEPT");

                        // Multicast
                        body.AppendLine("-A OUTPUT -s 192.168.0.0/16 -d 224.0.0.0/24 -j ACCEPT");
                        body.AppendLine("-A OUTPUT -s 10.0.0.0/8 -d 224.0.0.0/24 -j ACCEPT");
                        body.AppendLine("-A OUTPUT -s 172.16.0.0/12 -d 224.0.0.0/24 -j ACCEPT");

                        // Simple Service Discovery Protocol address
                        body.AppendLine("-A OUTPUT -s 192.168.0.0/16 -d 239.255.255.250/32 -j ACCEPT");
                        body.AppendLine("-A OUTPUT -s 10.0.0.0/8 -d 239.255.255.250/32 -j ACCEPT");
                        body.AppendLine("-A OUTPUT -s 172.16.0.0/12 -d 239.255.255.250/32 -j ACCEPT");

                        // Service Location Protocol version 2 address
                        body.AppendLine("-A OUTPUT -s 192.168.0.0/16 -d 239.255.255.253/32 -j ACCEPT");
                        body.AppendLine("-A OUTPUT -s 10.0.0.0/8 -d 239.255.255.253/32 -j ACCEPT");
                        body.AppendLine("-A OUTPUT -s 172.16.0.0/12 -d 239.255.255.253/32 -j ACCEPT");
                    }


                    if (Engine.Instance.Storage.GetBool("netlock.allow_ping"))
                    {
                        // icmp-type: echo-reply
                        body.AppendLine("-A OUTPUT -p icmp -m icmp --icmp-type 0 -j ACCEPT");
                    }

                    // Allow TUN
                    body.AppendLine("-A OUTPUT -o tun+ -j ACCEPT");

                    // Whitelist outgoing
                    foreach (IpAddress ip in ipsWhiteListOutgoing.IPs)
                    {
                        if (ip.IsV4)
                        {
                            body.AppendLine("-A OUTPUT -d " + ip.ToCIDR() + " -j ACCEPT");
                        }
                    }

                    if (Engine.Instance.Storage.Get("netlock.outgoing") == "allow")
                    {
                        body.AppendLine("-A OUTPUT -j ACCEPT");
                    }
                    else
                    {
                        body.AppendLine("-A OUTPUT -j DROP");
                    }

                    // Commit
                    body.AppendLine("COMMIT");

                    // Apply
                    string path = Engine.Instance.Storage.GetPathInData("iptables.netlock.dat");
                    Platform.Instance.FileContentsWriteText(path, body.ToString(), Encoding.ASCII);
                    string result = SystemShell.ShellCmd(Platform.Instance.LocateExecutable("iptables-restore") + " <\"" + SystemShell.EscapePath(path) + "\"");
                    Platform.Instance.FileDelete(path);
                    if (result != "")
                    {
                        throw new Exception(result);
                    }
                }

                // IPv6
                if (m_supportIPv6)
                {
                    var body = new System.Text.StringBuilder();

                    body.AppendLine("*mangle");
                    body.AppendLine(":PREROUTING ACCEPT [0:0]");
                    body.AppendLine(":INPUT ACCEPT [0:0]");
                    body.AppendLine(":FORWARD ACCEPT [0:0]");
                    body.AppendLine(":OUTPUT ACCEPT [0:0]");
                    body.AppendLine(":POSTROUTING ACCEPT [0:0]");
                    body.AppendLine("COMMIT");
                    body.AppendLine("*nat");
                    body.AppendLine(":PREROUTING ACCEPT [0:0]");
                    body.AppendLine(":INPUT ACCEPT [0:0]");
                    body.AppendLine(":OUTPUT ACCEPT [0:0]");
                    body.AppendLine(":POSTROUTING ACCEPT [0:0]");
                    body.AppendLine("COMMIT");
                    body.AppendLine("*filter");
                    body.AppendLine(":INPUT ACCEPT [0:0]");
                    body.AppendLine(":FORWARD ACCEPT [0:0]");
                    body.AppendLine(":OUTPUT ACCEPT [0:0]");

                    // Local
                    body.AppendLine("-A INPUT -i lo -j ACCEPT");

                    // Reject traffic to localhost that does not originate from lo0.
                    body.AppendLine("-A INPUT -s ::1/128 ! -i lo -j REJECT --reject-with icmp6-port-unreachable");

                    // Disable processing of any RH0 packet which could allow a ping-pong of packets
                    body.AppendLine("-A INPUT -m rt --rt-type 0 -j DROP");

                    // icmpv6-type:router-advertisement - Rules which are required for your IPv6 address to be properly allocated
                    body.AppendLine("-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 134 -m hl --hl-eq 255 -j ACCEPT");

                    // icmpv6-type:neighbor-solicitation - Rules which are required for your IPv6 address to be properly allocated
                    body.AppendLine("-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 135 -m hl --hl-eq 255 -j ACCEPT");

                    // icmpv6-type:neighbor-advertisement - Rules which are required for your IPv6 address to be properly allocated
                    body.AppendLine("-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 136 -m hl --hl-eq 255 -j ACCEPT");

                    // icmpv6-type:redirect - Rules which are required for your IPv6 address to be properly allocated
                    body.AppendLine("-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 137 -m hl --hl-eq 255 -j ACCEPT");

                    if (Engine.Instance.Storage.GetBool("netlock.allow_private"))
                    {
                        // Allow Link-Local addresses
                        body.AppendLine("-A INPUT -s fe80::/10 -j ACCEPT");

                        // Allow multicast
                        body.AppendLine("-A INPUT -d ff00::/8 -j ACCEPT");
                    }

                    if (Engine.Instance.Storage.GetBool("netlock.allow_ping"))
                    {
                        body.AppendLine("-A INPUT -p ipv6-icmp -j ACCEPT");
                    }

                    // Allow established sessions to receive traffic
                    body.AppendLine("-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT");

                    // Allow TUN
                    body.AppendLine("-A INPUT -i tun+ -j ACCEPT");

                    if (Engine.Instance.Storage.Get("netlock.incoming") == "allow")
                    {
                        body.AppendLine("-A INPUT -j ACCEPT");
                    }
                    else
                    {
                        body.AppendLine("-A INPUT -j DROP");
                    }

                    // Disable processing of any RH0 packet which could allow a ping-pong of packets
                    body.AppendLine("-A FORWARD -m rt --rt-type 0 -j DROP");

                    // Allow TUN
                    body.AppendLine("-A FORWARD -i tun+ -j ACCEPT");

                    // Fixed general rule
                    body.AppendLine("-A FORWARD -j DROP");

                    body.AppendLine("-A OUTPUT -d 2a0d:5600:2:5:cf41:c8d8:2e78:17b2/128 -j ACCEPT");
                    body.AppendLine("-A OUTPUT -d 2a0d:5600:2:5:5200:5517:2b3b:f9b6/128 -j ACCEPT");
                    body.AppendLine("-A OUTPUT -d 2001:ac8:29:5:8fde:45df:1149:dc39/128 -j ACCEPT");
                    body.AppendLine("-A OUTPUT -d 2001:ac8:29:5:2a4b:7bb6:475d:f0f4/128 -j ACCEPT");
                    body.AppendLine("-A OUTPUT -d 2001:750:2:3::41/128 -j ACCEPT");
                    body.AppendLine("-A OUTPUT -d 2001:4860:4860::8844/128 -j ACCEPT");
                    body.AppendLine("-A OUTPUT -d 2001:4860:4860::8888/128 -j ACCEPT");

                    // Local
                    body.AppendLine("-A OUTPUT -o lo -j ACCEPT");

                    // Disable processing of any RH0 packet which could allow a ping-pong of packets
                    body.AppendLine("-A OUTPUT -m rt --rt-type 0 -j DROP");

                    if (Engine.Instance.Storage.GetBool("netlock.allow_private"))
                    {
                        // Allow Link-Local addresses
                        body.AppendLine("-A OUTPUT -s fe80::/10 -j ACCEPT");

                        // Allow multicast
                        body.AppendLine("-A OUTPUT -d ff00::/8 -j ACCEPT");
                    }

                    if (Engine.Instance.Storage.GetBool("netlock.allow_ping"))
                    {
                        body.AppendLine("-A OUTPUT -p ipv6-icmp -j ACCEPT");
                    }

                    // Allow TUN
                    body.AppendLine("-A OUTPUT -o tun+ -j ACCEPT");

                    // Whitelist outgoing
                    foreach (IpAddress ip in ipsWhiteListOutgoing.IPs)
                    {
                        if (ip.IsV6)
                        {
                            body.AppendLine("-A OUTPUT -d " + ip.ToCIDR() + " -j ACCEPT");
                        }
                    }

                    if (Engine.Instance.Storage.Get("netlock.outgoing") == "allow")
                    {
                        body.AppendLine("-A OUTPUT -j ACCEPT");
                    }
                    else
                    {
                        body.AppendLine("-A OUTPUT -j DROP");
                    }

                    // Commit
                    body.AppendLine("COMMIT");

                    // Apply
                    string path = Engine.Instance.Storage.GetPathInData("ip6tables.netlock.dat");
                    Platform.Instance.FileContentsWriteText(path, body.ToString(), Encoding.ASCII);
                    string result = SystemShell.ShellCmd(Platform.Instance.LocateExecutable("ip6tables-restore") + " <\"" + SystemShell.EscapePath(path) + "\"");
                    Platform.Instance.FileDelete(path);
                    if (result != "")
                    {
                        throw new Exception(result);
                    }
                }

                m_ipsWhiteListOutgoing = ipsWhiteListOutgoing;

                OnUpdateIps();
            }
            catch (Exception ex)
            {
                Deactivation();
                throw new Exception(ex.Message);
            }
        }
Example #21
0
        public override void OnUpdateIps()
        {
            base.OnUpdateIps();

            // Remember: Rules must be in order: options, normalization, queueing, translation, filtering

            string pf = "";

            pf += "# " + Engine.Instance.GenerateFileHeader() + "\n";

            pf += "# Block policy, RST for quickly notice\n";
            pf += "set block-policy return\n";                               // 2.9

            pf += "# Skip interfaces: lo0 and utun (only when connected)\n"; // 2.9
            if (m_connected)
            {
                pf += "set skip on { lo0 " + Engine.Instance.ConnectedVpnInterfaceId + " }\n";
            }
            else
            {
                pf += "set skip on { lo0 }\n";
            }

            pf += "# Scrub\n";
            pf += "scrub in all\n";             // 2.9

            pf += "# Drop everything that doesn't match a rule\n";
            pf += "block out all\n";

            if (Engine.Instance.Storage.GetBool("netlock.allow_private"))
            {
                pf += "# IPv4 - Private networks\n";
                pf += "pass out quick inet from 192.168.0.0/16 to 192.168.0.0/16\n";
                pf += "pass in quick inet from 192.168.0.0/16 to 192.168.0.0/16\n";
                pf += "pass out quick inet from 172.16.0.0/12 to 172.16.0.0/12\n";
                pf += "pass in quick inet from 172.16.0.0/12 to 172.16.0.0/12\n";
                pf += "pass out quick inet from 10.0.0.0/8 to 10.0.0.0/8\n";
                pf += "pass in quick inet from 10.0.0.0/8 to 10.0.0.0/8\n";

                pf += "# IPv4 - Multicast\n";
                pf += "pass out quick inet from 192.168.0.0/16 to 224.0.0.0/24\n";
                pf += "pass out quick inet from 172.16.0.0/12 to 224.0.0.0/24\n";
                pf += "pass out quick inet from 10.0.0.0/8 to 224.0.0.0/24\n";

                pf += "# IPv4 - Simple Service Discovery Protocol address\n";
                pf += "pass out quick inet from 192.168.0.0/16 to 239.255.255.250/32\n";
                pf += "pass out quick inet from 172.16.0.0/12 to 239.255.255.250/32\n";
                pf += "pass out quick inet from 10.0.0.0/8 to 239.255.255.250/32\n";

                pf += "# IPv4 - Service Location Protocol version 2 address\n";
                pf += "pass out quick inet from 192.168.0.0/16 to 239.255.255.253/32\n";
                pf += "pass out quick inet from 172.16.0.0/12 to 239.255.255.253/32\n";
                pf += "pass out quick inet from 10.0.0.0/8 to 239.255.255.253/32\n";

                pf += "# IPv6 - Allow Link-Local addresses\n";
                pf += "pass out quick inet6 from fe80::/10 to fe80::/10\n";
                pf += "pass in quick inet6 from fe80::/10 to fe80::/10\n";

                pf += "# IPv6 - Allow Link-Local addresses\n";
                pf += "pass out quick inet6 from ff00::/8 to ff00::/8\n";
                pf += "pass in quick inet6 from ff00::/8 to ff00::/8\n";
            }

            if (Engine.Instance.Storage.GetBool("netlock.allow_ping"))
            {
                pf += "# Allow ICMP\n";
                pf += "pass quick proto icmp\n";                 // 2.9
                pf += "pass in quick proto icmp6 all\n";         // 2.13.2
            }

            IpAddresses ips = GetAllIps(true);

            pf += "# AirVPN IP (Auth and VPN)\n";
            foreach (IpAddress ip in ips.IPs)
            {
                if (ip.IsV4)
                {
                    pf += "pass out quick inet from any to " + ip.ToCIDR() + "\n";
                }
                else if (ip.IsV6)
                {
                    pf += "pass out quick inet6 from any to " + ip.ToCIDR() + "\n";
                }
            }

            if (Platform.Instance.FileContentsWriteText(m_filePfConf.Path, pf))
            {
                Engine.Instance.Logs.Log(LogType.Verbose, "OS X - PF rules updated, reloading");

                SystemShell s = new SystemShell();
                s.Path = m_pfctlPath;
                s.Arguments.Add("-v");
                s.Arguments.Add("-f");
                s.Arguments.Add(SystemShell.EscapePath(m_filePfConf.Path));
                if (s.Run() == false)
                {
                    throw new Exception(Messages.NetworkLockMacOSUnableToStart);
                }
                if (s.StdErr.Contains("rules not loaded"))
                {
                    throw new Exception(Messages.NetworkLockMacOSUnableToStart);
                }
            }
        }
Example #22
0
        public override void OnReceive(Json data)
        {
            base.OnReceive(data);

            string cmd = data["command"].Value as string;

            if (cmd == "ui.notification")
            {
                if (Eddie.Core.Platform.Instance.CanShellAsNormalUser())
                {
                    string pathNotifySend = Core.Platform.Instance.LocateExecutable("notify-send");
                    if (pathNotifySend != "")
                    {
                        SystemShell s = new SystemShell();
                        s.Path = pathNotifySend;
                        s.Arguments.Add("--urgency=low");
                        s.Arguments.Add("--expire-time=2000");
                        if (data["level"].Value as string == "infoimportant")
                        {
                            s.Arguments.Add("--icon=dialog-information");
                        }
                        else if (data["level"].Value as string == "warning")
                        {
                            s.Arguments.Add("--icon=dialog-warning");
                        }
                        else if (data["level"].Value as string == "error")
                        {
                            s.Arguments.Add("--icon=dialog-error");
                        }
                        else
                        {
                            s.Arguments.Add("--icon=dialog-information");
                        }
                        s.Arguments.Add("\"" + SystemShell.EscapeInsideQuote(Constants.Name) + "\"");
                        string message = SystemShell.EscapeInsideQuote(data["message"].Value as string);
                        message = message.Trim('-');                         // Hack, bad notify-send args parse of quoted string
                        s.Arguments.Add("\"" + message + "\"");
                        s.RunAsNormalUser = true;
                        s.WaitEnd         = false;
                        s.Run();
                    }
                }
            }
            else if (cmd == "ui.color")
            {
                string color = data["color"].Value as string;
                if (Tray != null)
                {
                    if (color == "green")
                    {
                        Tray.SendCommand("tray.active:true");
                        Tray.SendCommand("menu.status.icon:stock:gtk-yes");
                        Tray.SendCommand("menu.connect.text:" + Messages.CommandDisconnect);
                    }
                    else
                    {
                        Tray.SendCommand("tray.active:false");
                        if (color == "yellow")
                        {
                            Tray.SendCommand("menu.status.icon:stock:gtk-media-play");
                            Tray.SendCommand("menu.connect.text:" + Messages.CommandCancel);
                        }
                        else
                        {
                            Tray.SendCommand("menu.status.icon:stock:gtk-no");
                            Tray.SendCommand("menu.connect.text:" + Messages.CommandConnect);
                        }
                    }
                }
            }
            else if (cmd == "ui.status")
            {
                string full = data["full"].Value as string;
                if (Tray != null)
                {
                    Tray.SendCommand("menu.status.text:> " + full);
                }
            }
        }
Example #23
0
        public override void OnReceive(Json data)
        {
            string cmd = data["command"].Value as string;

            if (cmd == "engine.shutdown")
            {
                if (Tray != null)
                {
                    Tray.CancelRequested = true;
                    Tray.SendCommand("action.exit");

                    // Tray.Join(); // sometime don't exit...
                    if (Tray.Join(2000) == false)
                    {
                        Tray.Abort();
                    }

                    Tray = null;
                }
            }
            else if (cmd == "engine.ui")
            {
                if (Eddie.Core.Engine.Instance.Storage.GetBool("gui.tray_show"))
                {
                    Tray = new Tray();
                    for (int t = 0; t < 3000; t += 100)
                    {
                        if (Tray.IsStarted())
                        {
                            break;
                        }
                        System.Threading.Thread.Sleep(100);
                    }
                }
            }
            else if (cmd == "ui.notification")
            {
                string pathNotifySend = Core.Platform.Instance.LocateExecutable("notify-send");
                if (pathNotifySend != "")
                {
                    SystemShell s = new SystemShell();
                    s.Path = pathNotifySend;
                    s.Arguments.Add("--urgency=low");
                    //s.Arguments.Add("--expire-time=2000");
                    if (data["level"].Value as string == "infoimportant")
                    {
                        s.Arguments.Add("--icon=dialog-information");
                    }
                    else if (data["level"].Value as string == "warning")
                    {
                        s.Arguments.Add("--icon=dialog-warning");
                    }
                    else if (data["level"].Value as string == "error")
                    {
                        s.Arguments.Add("--icon=dialog-error");
                    }
                    else if (data["level"].Value as string == "fatal")
                    {
                        s.Arguments.Add("--icon=dialog-error");
                    }
                    else
                    {
                        s.Arguments.Add("--icon=dialog-information");
                    }
                    s.Arguments.Add("\"" + SystemShell.EscapeInsideQuote(Constants.Name) + "\"");
                    string message = SystemShell.EscapeInsideQuote(data["message"].Value as string);
                    message = message.Trim('-');                     // Hack, bad notify-send args parse of quoted string
                    s.Arguments.Add("\"" + message + "\"");
                    s.WaitEnd = false;
                    s.Run();
                }
            }
            else if (cmd == "ui.main-status")
            {
                string appIcon       = data["app_icon"].Value as string;
                string appColor      = data["app_color"].Value as string;
                string actionIcon    = data["action_icon"].Value as string;
                string actionCommand = data["action_command"].Value as string;
                string actionText    = data["action_text"].Value as string;
                if (Tray != null)
                {
                    if (appColor == "green")
                    {
                        Tray.SendCommand("tray.active:true");
                    }
                    else
                    {
                        Tray.SendCommand("tray.active:false");
                    }

                    if (appColor == "green")
                    {
                        Tray.SendCommand("menu.status.icon:stock:gtk-yes");
                        Tray.SendCommand("menu.connect.text:" + LanguageManager.GetText("CommandDisconnect"));
                    }
                    else if (appColor == "yellow")
                    {
                        Tray.SendCommand("menu.status.icon:stock:gtk-media-play");
                    }
                    else
                    {
                        Tray.SendCommand("menu.status.icon:stock:gtk-no");
                    }

                    Tray.SendCommand("menu.connect.text:" + actionText);
                    Tray.SendCommand("menu.connect.enable:" + ((actionCommand != "") ? "true":"false"));
                }
            }
            else if (cmd == "ui.status")
            {
                string full = data["full"].Value as string;
                if (Tray != null)
                {
                    Tray.SendCommand("menu.status.text:> " + full);
                }
            }

            base.OnReceive(data);
        }
Example #24
0
        public override void OnUpdateIps()
        {
            base.OnUpdateIps();

            // Remember: Rules must be in order: options, normalization, queueing, translation, filtering

            string pf = "";

            pf += "# " + Engine.Instance.GenerateFileHeader() + "\n";

            pf += "# Block policy, RST for quickly notice\n";
            pf += "set block-policy return\n";                               // 2.9

            pf += "# Skip interfaces: lo0 and utun (only when connected)\n"; // 2.9
            if (m_connected)
            {
                pf += "set skip on { lo0 " + Engine.Instance.ConnectionActive.InterfaceId + " }\n";
            }
            else
            {
                pf += "set skip on { lo0 }\n";
            }

            pf += "# Scrub\n";
            pf += "scrub in all\n";             // 2.9

            pf += "# General rule\n";
            if (Engine.Instance.Storage.Get("netlock.incoming") == "allow")
            {
                pf += "pass in all\n";
            }
            else
            {
                pf += "block in all\n";
            }
            if (Engine.Instance.Storage.Get("netlock.outgoing") == "allow")
            {
                pf += "pass out all\n";
            }
            else
            {
                pf += "block out all\n";
            }

            if (Engine.Instance.Storage.GetBool("netlock.allow_private"))
            {
                pf += "# IPv4 - Private networks\n";
                pf += "pass out quick inet from 192.168.0.0/16 to 192.168.0.0/16\n";
                pf += "pass in quick inet from 192.168.0.0/16 to 192.168.0.0/16\n";
                pf += "pass out quick inet from 172.16.0.0/12 to 172.16.0.0/12\n";
                pf += "pass in quick inet from 172.16.0.0/12 to 172.16.0.0/12\n";
                pf += "pass out quick inet from 10.0.0.0/8 to 10.0.0.0/8\n";
                pf += "pass in quick inet from 10.0.0.0/8 to 10.0.0.0/8\n";

                pf += "# IPv4 - Multicast\n";
                pf += "pass out quick inet from 192.168.0.0/16 to 224.0.0.0/24\n";
                pf += "pass out quick inet from 172.16.0.0/12 to 224.0.0.0/24\n";
                pf += "pass out quick inet from 10.0.0.0/8 to 224.0.0.0/24\n";

                pf += "# IPv4 - Simple Service Discovery Protocol address\n";
                pf += "pass out quick inet from 192.168.0.0/16 to 239.255.255.250/32\n";
                pf += "pass out quick inet from 172.16.0.0/12 to 239.255.255.250/32\n";
                pf += "pass out quick inet from 10.0.0.0/8 to 239.255.255.250/32\n";

                pf += "# IPv4 - Service Location Protocol version 2 address\n";
                pf += "pass out quick inet from 192.168.0.0/16 to 239.255.255.253/32\n";
                pf += "pass out quick inet from 172.16.0.0/12 to 239.255.255.253/32\n";
                pf += "pass out quick inet from 10.0.0.0/8 to 239.255.255.253/32\n";

                pf += "# IPv6 - Allow Link-Local addresses\n";
                pf += "pass out quick inet6 from fe80::/10 to fe80::/10\n";
                pf += "pass in quick inet6 from fe80::/10 to fe80::/10\n";

                pf += "# IPv6 - Allow Link-Local addresses\n";
                pf += "pass out quick inet6 from ff00::/8 to ff00::/8\n";
                pf += "pass in quick inet6 from ff00::/8 to ff00::/8\n";
            }

            if (Engine.Instance.Storage.GetBool("netlock.allow_ping"))
            {
                pf += "# Allow ICMP\n";
                pf += "pass quick proto icmp\n";                 // 2.9

                // Old macOS throw "unknown protocol icmp6". We don't known from when, so use icmp6 if High Sierra and above.
                if (UtilsCore.CompareVersions(Platform.Instance.GetName(), "10.13") >= 0)
                {
                    pf += "pass quick proto icmp6 all\n";                     // 2.14.0
                }
            }

            IpAddresses ipsWhiteListOutgoing = GetIpsWhiteListOutgoing(true);

            pf += "# Specific ranges\n";
            foreach (IpAddress ip in ipsWhiteListOutgoing.IPs)
            {
                if (ip.IsV4)
                {
                    pf += "pass out quick inet from any to " + ip.ToCIDR() + "\n";
                }
                else if (ip.IsV6)
                {
                    pf += "pass out quick inet6 from any to " + ip.ToCIDR() + "\n";
                }
            }

            if (Platform.Instance.FileContentsWriteText(m_filePfConf.Path, pf))
            {
                Engine.Instance.Logs.Log(LogType.Verbose, "macOS - PF rules updated, reloading");

                SystemShell s = new SystemShell();
                s.Path = m_pfctlPath;
                s.Arguments.Add("-v");
                s.Arguments.Add("-f");
                s.Arguments.Add(SystemShell.EscapePath(m_filePfConf.Path));
                if (s.Run() == false)
                {
                    throw new Exception(Messages.NetworkLockMacOSUnableToStart);
                }
                if (s.StdErr.Contains("rules not loaded"))
                {
                    throw new Exception(Messages.NetworkLockMacOSUnableToStart);
                }
            }
        }