Example #1
0
        protected override void OpenDirectoryInFileManagerEx(string path)
        {
            // TOFIX Don't work well on all distro
            string args = " - " + m_logname + " -c 'xdg-open \"" + SystemShell.EscapePath(path) + "\"'"; // IJTF2 // TOCHECK

            Shell("su", args, false);
        }
Example #2
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 #3
0
        public override bool FileImmutableGet(string path)
        {
            // We don't find a better direct method in Mono/Posix without adding ioctl references
            // The list of flags can be different between Linux distro (for example 16 on Debian, 19 on Manjaro)

            if (FileExists(path) == false)
            {
                return(false);
            }

            string result = ShellCmd("lsattr \"" + SystemShell.EscapePath(path) + "\"", true); // noDebugLog=true to avoid log recursion.

            /* // < 2.11.11
             * if (result.IndexOf(' ') != 16)
             *  return false;
             * if (result[4] == 'i')
             *  return true;
             */

            if (result.StartsWith("lsattr: ")) // Generic error
            {
                return(false);
            }

            if (result.IndexOf(' ') != -1)
            {
                result = result.Substring(0, result.IndexOf(' '));
            }

            return(result.IndexOf("-i-") != -1);
        }
Example #4
0
 public override void FileImmutableSet(string path, bool value)
 {
     if (FileExists(path))
     {
         string flag = (value ? "+i" : "-i");
         ShellCmd("chattr " + flag + " \"" + SystemShell.EscapePath(path) + "\"");
     }
 }
Example #5
0
        public override void EnsureExecutablePermissions(string path)
        {
            if ((path == "") || (Platform.Instance.FileExists(path) == false))
            {
                return;
            }

            ShellCmd("chmod +x \"" + SystemShell.EscapePath(path) + "\"");
        }
Example #6
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 #7
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 #8
0
        public override string GetExecutableReport(string path)
        {
            string otoolPath = LocateExecutable("otool");

            if (otoolPath != "")
            {
                return(SystemShell.Shell2(otoolPath, "-L", SystemShell.EscapePath(path)));
            }
            else
            {
                return("'otool' " + LanguageManager.GetText("NotFound"));
            }
        }
Example #9
0
        public override string GetExecutableReport(string path)
        {
            string lddPath = LocateExecutable("ldd");

            if (lddPath != "")
            {
                return(SystemShell.Shell1(lddPath, SystemShell.EscapePath(path)));
            }
            else
            {
                return("'ldd' " + Messages.NotFound);
            }
        }
Example #10
0
        public override string GetExecutableReport(string path)
        {
            string otoolPath = LocateExecutable("otool");

            if (otoolPath != "")
            {
                return(SystemShell.Shell2(otoolPath, "-L", SystemShell.EscapePath(path)));
            }
            else
            {
                return("'otool' " + Messages.NotFound);
            }
        }
Example #11
0
        public override string GetExecutableReport(string path)
        {
            string lddPath = LocateExecutable("ldd");

            if (lddPath != "")
            {
                return(SystemShell.Shell1(lddPath, SystemShell.EscapePath(path)));
            }
            else
            {
                return("'ldd' " + LanguageManager.GetText("NotFound"));
            }
        }
        public override void Deactivation()
        {
            base.Deactivation();

            // IPV4
            string rulesBackupSessionV4 = GetBackupPath("4");

            if (Platform.Instance.FileExists(rulesBackupSessionV4))
            {
                // Flush
                Exec("iptables -F");
                Exec("iptables -t nat -F");
                Exec("iptables -t mangle -F");

                // Backup
                Exec("iptables-restore <\"" + SystemShell.EscapePath(rulesBackupSessionV4) + "\"");

                Platform.Instance.FileDelete(rulesBackupSessionV4);
            }

            // IPV6
            string rulesBackupSessionV6 = GetBackupPath("6");

            if (Platform.Instance.FileExists(rulesBackupSessionV6))
            {
                // Flush
                Exec("ip6tables -F");
                Exec("ip6tables -t nat -F");
                Exec("ip6tables -t mangle -F");

                // Backup
                Exec("ip6tables-restore <\"" + SystemShell.EscapePath(rulesBackupSessionV6) + "\"");

                Platform.Instance.FileDelete(rulesBackupSessionV6);
            }

            // IPS
            m_currentList.Clear();
        }
Example #13
0
        public override void Deactivation()
        {
            base.Deactivation();

            // IPv4
            string rulesBackupSessionV4 = GetBackupPath("4");

            if (Platform.Instance.FileExists(rulesBackupSessionV4))
            {
                // 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");

                // Restore backup - Exception: ShellCmd because ip6tables-restore accept only stdin
                SystemShell.ShellCmd(Platform.Instance.LocateExecutable("iptables-restore") + " <\"" + SystemShell.EscapePath(rulesBackupSessionV4) + "\"");

                Platform.Instance.FileDelete(rulesBackupSessionV4);
            }

            // IPv6
            string rulesBackupSessionV6 = GetBackupPath("6");

            if (Platform.Instance.FileExists(rulesBackupSessionV6))
            {
                // Restore
                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");

                // Restore backup - Exception: ShellCmd because ip6tables-restore accept only stdin
                SystemShell.ShellCmd(Platform.Instance.LocateExecutable("ip6tables-restore") + " <\"" + SystemShell.EscapePath(rulesBackupSessionV6) + "\"");

                Platform.Instance.FileDelete(rulesBackupSessionV6);
            }

            // IPS
            m_ipsWhiteListOutgoing.Clear();
        }
Example #14
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 drop out all\n";

            // TOCHECK: block drop above is also for ipv6?
            // pf += "# Drop ipv6\n";
            // pf += "block quick inet6\n";

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

                // Multicast
                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";

                // 239.255.255.250  Simple Service Discovery Protocol address
                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";

                // 239.255.255.253  Service Location Protocol version 2 address
                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";
            }

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

            List <IpAddressRange> ips = GetAllIps(true);

            pf += "# AirVPN IP (Auth and VPN)\n";
            foreach (IpAddressRange ip in ips)
            {
                //pf += "pass out quick inet from 192.168.0.0/16 to " + ip.ToString() + " flags S/SA keep state\n";
                pf += "pass out quick inet from any to " + ip.ToCIDR() + " flags S/SA keep state\n";
            }

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

                Exec("pfctl -v -f \"" + SystemShell.EscapePath(m_filePfConf.Path) + "\"");
            }
        }
Example #15
0
        public HttpResponse Fetch(HttpRequest request)
        {
            HttpResponse response = new HttpResponse();

            ExceptionIfRequired();

            ProgramScope programScope = new ProgramScope(this.GetPath(), "curl");

            // Don't use proxy if connected to the VPN, or in special cases (checking) during connection.
            bool bypassProxy = request.BypassProxy;

            if (bypassProxy == false)
            {
                bypassProxy = Engine.Instance.IsConnected();
            }

            string dataParameters = "";

            if (request.Parameters.Count > 0)
            {
                foreach (string k in request.Parameters.Keys)
                {
                    if (dataParameters != "")
                    {
                        dataParameters += "&";
                    }
                    dataParameters += SystemShell.EscapeAlphaNumeric(k) + "=" + Uri.EscapeUriString(request.Parameters[k]);
                }
            }

            string args = "";

            if (bypassProxy == false)
            {
                string proxyMode     = Engine.Instance.Storage.GetLower("proxy.mode");
                string proxyWhen     = Engine.Instance.Storage.GetLower("proxy.when");
                string proxyHost     = Engine.Instance.Storage.Get("proxy.host");
                int    proxyPort     = Engine.Instance.Storage.GetInt("proxy.port");
                string proxyAuth     = Engine.Instance.Storage.Get("proxy.auth").ToLowerInvariant();
                string proxyLogin    = Engine.Instance.Storage.Get("proxy.login");
                string proxyPassword = Engine.Instance.Storage.Get("proxy.password");

                if ((proxyWhen == "none") || (proxyWhen == "openvpn"))
                {
                    proxyMode = "none";
                }

                if (proxyMode == "detect")
                {
                    throw new Exception(Messages.ProxyDetectDeprecated);
                }

                if (proxyMode == "tor")
                {
                    proxyMode     = "socks";
                    proxyAuth     = "none";
                    proxyLogin    = "";
                    proxyPassword = "";
                }

                if (proxyMode == "http")
                {
                    args += " --proxy http://" + SystemShell.EscapeHost(proxyHost) + ":" + proxyPort.ToString();
                }
                else if (proxyMode == "socks")
                {
                    // curl support different types of proxy. OpenVPN not, only socks5. So, it's useless to support other kind of proxy here.
                    args += " --proxy socks5://" + SystemShell.EscapeHost(proxyHost) + ":" + proxyPort.ToString();
                }

                if ((proxyMode != "none") && (proxyAuth != "none"))
                {
                    if (proxyAuth == "basic")
                    {
                        args += " --proxy-basic";
                    }
                    else if (proxyAuth == "ntlm")
                    {
                        args += " --proxy-ntlm";
                    }

                    if (SystemShell.EscapeInsideQuoteAcceptable(proxyLogin) == false)
                    {
                        throw new Exception(MessagesFormatter.Format(Messages.UnacceptableCharacters, "Proxy Login"));
                    }

                    if (SystemShell.EscapeInsideQuoteAcceptable(proxyPassword) == false)
                    {
                        throw new Exception(MessagesFormatter.Format(Messages.UnacceptableCharacters, "Proxy Password"));
                    }

                    if ((proxyLogin != "") && (proxyPassword != ""))
                    {
                        args += " --proxy-user \"" + SystemShell.EscapeInsideQuote(proxyLogin) + "\":\"" + SystemShell.EscapeInsideQuote(proxyPassword) + "\"";
                    }
                }
            }

            args += " \"" + SystemShell.EscapeUrl(request.Url) + "\"";
            args += " -sS";             // -s Silent mode, -S with errors
            args += " --max-time " + Engine.Instance.Storage.GetInt("tools.curl.max-time").ToString();

            string pathCacert = Engine.Instance.LocateResource("cacert.pem");

            if (pathCacert != "")
            {
                args += " --cacert \"" + SystemShell.EscapePath(pathCacert) + "\"";
            }

            if (request.ForceResolve != "")
            {
                args += " --resolve " + request.ForceResolve;
            }

            if (dataParameters != "")
            {
                args += " --data \"" + dataParameters + "\"";
            }

            if (request.IpLayer == "4")
            {
                args += " -4";
            }
            if (request.IpLayer == "6")
            {
                args += " -6";
            }

            args += " -i";

            string error = "";

            try
            {
                using (Process p = new Process())
                {
                    p.StartInfo.FileName         = SystemShell.EscapePath(this.GetPath());
                    p.StartInfo.Arguments        = args;
                    p.StartInfo.WorkingDirectory = "";

                    p.StartInfo.CreateNoWindow         = true;
                    p.StartInfo.WindowStyle            = System.Diagnostics.ProcessWindowStyle.Hidden;
                    p.StartInfo.UseShellExecute        = false;
                    p.StartInfo.RedirectStandardOutput = true;
                    p.StartInfo.RedirectStandardError  = true;

                    p.Start();

                    {
                        using (System.IO.MemoryStream Stream = new System.IO.MemoryStream())
                        {
                            using (System.IO.MemoryStream StreamHeader = new System.IO.MemoryStream())
                            {
                                using (System.IO.MemoryStream StreamBody = new System.IO.MemoryStream())
                                {
                                    byte[] buffer = new byte[4096];
                                    int    read;
                                    while ((read = p.StandardOutput.BaseStream.Read(buffer, 0, buffer.Length)) > 0)
                                    {
                                        Stream.Write(buffer, 0, read);
                                    }

                                    if (Stream.Length >= 4)
                                    {
                                        byte[] buffer2 = Stream.ToArray();
                                        int    i       = 0;
                                        for (; i < Stream.Length - 4; i++)
                                        {
                                            if ((buffer2[i] == 13) && (buffer2[i + 1] == 10) && (buffer2[i + 2] == 13) && (buffer2[i + 3] == 10))
                                            {
                                                StreamHeader.Write(buffer2, 0, i);
                                                StreamBody.Write(buffer2, i + 4, (int)Stream.Length - i - 4);
                                                break;
                                            }
                                        }

                                        if (StreamHeader.Length == 0)
                                        {
                                            StreamHeader.Write(buffer2, 0, (int)Stream.Length);
                                        }
                                    }
                                    else
                                    {
                                        StreamHeader.Write(Stream.ToArray(), 0, (int)Stream.Length);
                                    }

                                    response.BufferHeader = StreamHeader.ToArray();
                                    response.BufferData   = StreamBody.ToArray();
                                }
                            }

                            string   headers      = System.Text.Encoding.ASCII.GetString(response.BufferHeader);
                            string[] headersLines = headers.Split('\n');
                            for (int l = 0; l < headersLines.Length; l++)
                            {
                                string line = headersLines[l];
                                if (l == 0)
                                {
                                    response.StatusLine = line;
                                }
                                int posSep = line.IndexOf(":");
                                if (posSep != -1)
                                {
                                    string k = line.Substring(0, posSep);
                                    string v = line.Substring(posSep + 1);
                                    response.Headers.Add(new KeyValuePair <string, string>(k.ToLowerInvariant().Trim(), v.Trim()));
                                }
                            }
                        }
                    }

                    error = p.StandardError.ReadToEnd();

                    p.WaitForExit();

                    response.ExitCode = p.ExitCode;
                }
            }
            catch (Exception e)
            {
                error = e.Message;
            }

            programScope.End();

            if (error != "")
            {
                throw new Exception(error.Trim());
            }

            return(response);
        }
Example #16
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 #17
0
        public byte[] FetchUrlEx(string url, System.Collections.Specialized.NameValueCollection parameters, string title, bool forceBypassProxy, string resolve)
        {
            if (Available() == false)
            {
                throw new Exception(Messages.ToolsCurlRequired);
            }

            if (Utils.CompareVersions(Version, minVersionRequired) == -1)
            {
                throw new Exception(GetRequiredVersionMessage());
            }

            ProgramScope programScope = new ProgramScope(this.GetPath(), "curl");

            // Don't use proxy if connected to the VPN, or in special cases (checking) during connection.
            bool bypassProxy = forceBypassProxy;

            if (bypassProxy == false)
            {
                bypassProxy = Engine.Instance.IsConnected();
            }

            string dataParameters = "";

            if (parameters != null)
            {
                foreach (string k in parameters.Keys)
                {
                    if (dataParameters != "")
                    {
                        dataParameters += "&";
                    }
                    dataParameters += SystemShell.EscapeAlphaNumeric(k) + "=" + Uri.EscapeUriString(parameters[k]);
                }
            }

            string args = "";

            if (bypassProxy == false)
            {
                string proxyMode     = Engine.Instance.Storage.Get("proxy.mode").ToLowerInvariant();
                string proxyHost     = Engine.Instance.Storage.Get("proxy.host");
                int    proxyPort     = Engine.Instance.Storage.GetInt("proxy.port");
                string proxyAuth     = Engine.Instance.Storage.Get("proxy.auth").ToLowerInvariant();
                string proxyLogin    = Engine.Instance.Storage.Get("proxy.login");
                string proxyPassword = Engine.Instance.Storage.Get("proxy.password");

                if (proxyMode == "detect")
                {
                    throw new Exception(Messages.ProxyDetectDeprecated);
                }

                if (proxyMode == "tor")
                {
                    proxyMode     = "socks";
                    proxyAuth     = "none";
                    proxyLogin    = "";
                    proxyPassword = "";
                }

                if (proxyMode == "http")
                {
                    args += " --proxy http://" + SystemShell.EscapeHost(proxyHost) + ":" + proxyPort.ToString();
                }
                else if (proxyMode == "socks")
                {
                    // curl support different types of proxy. OpenVPN not, only socks5. So, it's useless to support other kind of proxy here.
                    args += " --proxy socks5://" + SystemShell.EscapeHost(proxyHost) + ":" + proxyPort.ToString();
                }

                if ((proxyMode != "none") && (proxyAuth != "none"))
                {
                    if (proxyAuth == "basic")
                    {
                        args += " --proxy-basic";
                    }
                    else if (proxyAuth == "ntlm")
                    {
                        args += " --proxy-ntlm";
                    }

                    if (SystemShell.EscapeInsideQuoteAcceptable(proxyLogin) == false)
                    {
                        throw new Exception(MessagesFormatter.Format(Messages.UnacceptableCharacters, "Proxy Login"));
                    }

                    if (SystemShell.EscapeInsideQuoteAcceptable(proxyPassword) == false)
                    {
                        throw new Exception(MessagesFormatter.Format(Messages.UnacceptableCharacters, "Proxy Password"));
                    }

                    if ((proxyLogin != "") && (proxyPassword != ""))
                    {
                        args += " --proxy-user \"" + SystemShell.EscapeInsideQuote(proxyLogin) + "\":\"" + SystemShell.EscapeInsideQuote(proxyPassword) + "\"";
                    }
                }
            }

            args += " \"" + SystemShell.EscapeUrl(url) + "\"";
            args += " -sS"; // -s Silent mode, -S with errors
            args += " --max-time " + Engine.Instance.Storage.GetInt("tools.curl.max-time").ToString();

            Tool cacertTool = Software.GetTool("cacert.pem");

            if (cacertTool.Available())
            {
                args += " --cacert \"" + SystemShell.EscapePath(cacertTool.Path) + "\"";
            }

            if (resolve != "")
            {
                args += " --resolve " + resolve;
            }

            if (dataParameters != "")
            {
                args += " --data \"" + dataParameters + "\"";
            }

            string error = "";

            byte[] output   = default(byte[]);
            int    exitcode = -1;

            try
            {
                /*
                 * if ((Engine.Instance != null) && (Engine.Instance.Storage != null) && (Engine.Instance.Storage.GetBool("log.level.debug")))
                 * {
                 *  string message = "curl " + this.GetPath() + " " + args;
                 *  message = Utils.RegExReplace(message, "[a-zA-Z0-9+/]{30,}=", "{base64-omissis}");
                 *  Engine.Instance.Logs.Log(LogType.Verbose, message);
                 * }
                 */

                Process p = new Process();

                p.StartInfo.FileName         = SystemShell.EscapePath(this.GetPath());
                p.StartInfo.Arguments        = args;
                p.StartInfo.WorkingDirectory = "";

                p.StartInfo.CreateNoWindow         = true;
                p.StartInfo.WindowStyle            = System.Diagnostics.ProcessWindowStyle.Hidden;
                p.StartInfo.UseShellExecute        = false;
                p.StartInfo.RedirectStandardOutput = true;
                p.StartInfo.RedirectStandardError  = true;

                p.Start();

                using (var memoryStream = new System.IO.MemoryStream())
                {
                    //p.StandardOutput.BaseStream.CopyTo(memstream); // .Net 4 only
                    Utils.CopyStream(p.StandardOutput.BaseStream, memoryStream);
                    output = memoryStream.ToArray();
                }

                error = p.StandardError.ReadToEnd();

                p.WaitForExit();

                exitcode = p.ExitCode;
            }
            catch (Exception e)
            {
                error  = e.Message;
                output = default(byte[]);
            }

            programScope.End();

            if (error != "")
            {
                throw new Exception(error.Trim());
            }

            return(output);
        }
        public override void AllowProgram(string path, string name, string guid)
        {
            base.AllowProgram(path, name, guid);

            if (path == Software.GetTool("curl").Path)
            {
                return;
            }

            // Windows Firewall don't work with logical path (a path that contain hardlink)
            string physicalPath = Platform.Instance.FileGetPhysicalPath(path);

            SystemShell.ShellCmd("netsh advfirewall firewall add rule name=\"Eddie - Out - AllowProgram - " + guid + "\" dir=out action=allow program=\"" + SystemShell.EscapePath(physicalPath) + "\" enable=yes");
        }
Example #19
0
File: Tray.cs Project: nir94/Eddie
        public override void OnRun()
        {
            try
            {
                for (; ;)
                {
                    //string controlReadPath = Core.Engine.Instance.Storage.GetPathInData("eddie_tray_r.tmp");
                    //string controlWritePath = Core.Engine.Instance.Storage.GetPathInData("eddie_tray_w.tmp");
                    //string controlReadPath = Path.GetTempPath() + "eddie_tray_r.tmp";
                    //string controlWritePath = Path.GetTempPath() + "eddie_tray_w.tmp";
                    string controlReadPath  = Core.Platform.Instance.FileTempName("eddie_tray_r.tmp");
                    string controlWritePath = Core.Platform.Instance.FileTempName("eddie_tray_w.tmp");

                    string pathRes = Core.Engine.Instance.GetPathResources();
                    string pathExe = Core.Engine.Instance.GetPathTools() + "/eddie-tray";

                    if (Core.Platform.Instance.FileExists(pathExe) == false)
                    {
                        return;
                    }

                    List <string> arguments = new List <string>();
                    arguments.Add("-r " + controlReadPath);
                    arguments.Add("-w " + controlWritePath);
                    arguments.Add("-p " + pathRes);

                    string[] arguments2 = arguments.ToArray();

                    Process processTray;
                    processTray = new Process();

                    processTray.StartInfo.FileName         = SystemShell.EscapePath(pathExe);
                    processTray.StartInfo.Arguments        = String.Join(" ", arguments2);
                    processTray.StartInfo.WorkingDirectory = "";

                    processTray.StartInfo.CreateNoWindow  = true;
                    processTray.StartInfo.WindowStyle     = System.Diagnostics.ProcessWindowStyle.Hidden;
                    processTray.StartInfo.UseShellExecute = false;

                    processTray.Start();

                    if (processTray.HasExited) // If can't start, for example missing appindicator library.
                    {
                        break;
                    }

                    // Wait until control file is ready
                    for (; ;)
                    {
                        if (CancelRequested)
                        {
                            break;
                        }

                        if (Core.Platform.Instance.FileExists(controlWritePath))
                        {
                            break;
                        }

                        Sleep(100);
                    }

                    m_pathWrite = controlReadPath;

                    try
                    {
                        for (; ;)
                        {
                            using (StreamReader streamRead = new StreamReader(controlWritePath))
                            {
                                string cmd = streamRead.ReadLine();

                                if (cmd == null) // Closed
                                {
                                    break;
                                }

                                if (m_oneStart == false)
                                {
                                    m_oneStart = true;
                                }

                                if (UiClient.Instance.MainWindow != null)
                                {
                                    if (cmd == "menu.status")
                                    {
                                        UiClient.Instance.MainWindow.OnMenuStatus();
                                    }
                                    else if (cmd == "menu.connect")
                                    {
                                        UiClient.Instance.MainWindow.OnMenuConnect();
                                    }
                                    else if (cmd == "menu.preferences")
                                    {
                                        UiClient.Instance.MainWindow.OnShowPreferences();
                                    }
                                    else if (cmd == "menu.about")
                                    {
                                        UiClient.Instance.MainWindow.OnShowAbout();
                                    }
                                    else if (cmd == "menu.restore")
                                    {
                                        UiClient.Instance.MainWindow.OnMenuRestore();
                                    }
                                    else if (cmd == "menu.exit")
                                    {
                                        UiClient.Instance.MainWindow.OnMenuExit();
                                    }
                                }
                            }
                        }
                    }
                    catch
                    {
                    }

                    m_pathWrite = "";

                    if (m_oneStart == false)
                    {
                        break;
                    }

                    if (this.CancelRequested)
                    {
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                Eddie.Core.Engine.Instance.Logs.LogVerbose("Issue with the tray icon: " + ex.Message);

                m_pathWrite = "";
            }
        }
        public override void Activation()
        {
            base.Activation();

            // Service
            {
                ServiceController service = null;
                try
                {
                    service         = new ServiceController("MpsSvc");
                    m_serviceStatus = (service.Status == ServiceControllerStatus.Running);
                    if (m_serviceStatus == false)
                    {
                        TimeSpan timeout = TimeSpan.FromMilliseconds(10000);
                        service.Start();
                        service.WaitForStatus(ServiceControllerStatus.Running, timeout);
                    }
                }
                catch (Exception e)
                {
                    if (e.Message.Contains("MpsSvc"))
                    {
                        throw new Exception(Messages.NetworkLockWindowsFirewallUnableToStartService);
                    }
                    else
                    {
                        throw e;
                    }
                }
                finally
                {
                    if (service != null)
                    {
                        service.Dispose();
                    }
                }
            }

            // If 'winfirewall_rules_original.airvpn' doesn't exists, create it. It's a general backup of the first time.
            // We create this kind of file in Windows System directory, because it's system critical data, and to allow it to survive between re-installation of the software.
            string rulesBackupFirstTime = Engine.Instance.Storage.GetPathInData("winfirewall_rules_original.wfw");

            if (Platform.Instance.FileExists(rulesBackupFirstTime) == false)
            {
                SystemShell.ShellCmd("netsh advfirewall export \"" + SystemShell.EscapePath(rulesBackupFirstTime) + "\"");
            }

            string rulesBackupSession = Engine.Instance.Storage.GetPathInData("winfirewall_rules_backup.wfw");

            if (Platform.Instance.FileExists(rulesBackupSession))
            {
                Platform.Instance.FileDelete(rulesBackupSession);
            }
            SystemShell.ShellCmd("netsh advfirewall export \"" + SystemShell.EscapePath(rulesBackupSession) + "\"");
            if (Platform.Instance.FileExists(rulesBackupSession) == false)
            {
                throw new Exception(Messages.NetworkLockWindowsFirewallBackupFailed);
            }

            foreach (NetworkLockWindowsFirewallProfile profile in Profiles)
            {
                profile.Fetch();
            }

            foreach (NetworkLockWindowsFirewallProfile profile in Profiles)
            {
                if (profile.State == false)
                {
                    profile.StateOn();
                }

                /*
                 * if (profile.Notifications == true)
                 * {
                 *      profile.NotifyOff();
                 * }
                 */
            }

            // Disable all notifications
            SystemShell.ShellCmd("netsh advfirewall set allprofiles settings inboundusernotification disable");

            SystemShell.ShellCmd("netsh advfirewall firewall delete rule name=all");

            // Windows Firewall don't work with logical path (a path that contain hardlink)
            SystemShell.ShellCmd("netsh advfirewall firewall add rule name=\"Eddie - Out - Program Eddie\" dir=out action=allow program=\"" + SystemShell.EscapePath(Platform.Instance.FileGetPhysicalPath(Platform.Instance.GetExecutablePath())) + "\" enable=yes");

            // Adding rules are slow, so force at least curl
            SystemShell.ShellCmd("netsh advfirewall firewall add rule name=\"Eddie - Out - Program curl\" dir=out action=allow program=\"" + SystemShell.EscapePath(Platform.Instance.FileGetPhysicalPath(Software.GetTool("curl").Path)) + "\" enable=yes");

            if (Engine.Instance.Storage.GetBool("netlock.allow_ping") == true)
            {
                SystemShell.ShellCmd("netsh advfirewall firewall add rule name=\"Eddie - In - ICMP IPv4\" dir=in action=allow protocol=icmpv4:8,any");
                SystemShell.ShellCmd("netsh advfirewall firewall add rule name=\"Eddie - In - ICMP IPv6\" dir=in action=allow protocol=icmpv6:8,any");
                SystemShell.ShellCmd("netsh advfirewall firewall add rule name=\"Eddie - Out - ICMP IPv4\" dir=out action=allow protocol=icmpv4:8,any");
                SystemShell.ShellCmd("netsh advfirewall firewall add rule name=\"Eddie - Out - ICMP IPv6\" dir=out action=allow protocol=icmpv6:8,any");
            }

            // Exec("netsh advfirewall firewall add rule name=\"Eddie - IPv6 Block - Low\" dir=out remoteip=0000::/1 action=allow");
            // Exec("netsh advfirewall firewall add rule name=\"Eddie - IPv6 Block - High\" dir=out remoteip=8000::/1 action=allow");

            if (Engine.Instance.Storage.GetBool("netlock.allow_private") == true)
            {
                SystemShell.ShellCmd("netsh advfirewall firewall add rule name=\"Eddie - In - AllowLocal\" dir=in action=allow remoteip=LocalSubnet");
                SystemShell.ShellCmd("netsh advfirewall firewall add rule name=\"Eddie - Out - AllowLocal\" dir=out action=allow remoteip=LocalSubnet");

                SystemShell.ShellCmd("netsh advfirewall firewall add rule name=\"Eddie - Out - AllowMulticast\" dir=out action=allow remoteip=224.0.0.0/24");
                SystemShell.ShellCmd("netsh advfirewall firewall add rule name=\"Eddie - Out - AllowSimpleServiceDiscoveryProtocol\" dir=out action=allow remoteip=239.255.255.250/32");
                SystemShell.ShellCmd("netsh advfirewall firewall add rule name=\"Eddie - Out - ServiceLocationProtocol\" dir=out action=allow remoteip=239.255.255.253/32");
            }

            // This is not optimal, it maybe also allow LAN traffic, but we can't find a better alternative (interfacetype=ras don't work) and WinFirewall method must be deprecated.
            SystemShell.ShellCmd("netsh advfirewall firewall add rule name=\"Eddie - In - AllowVPN\" dir=in action=allow localip=10.0.0.0/8");
            SystemShell.ShellCmd("netsh advfirewall firewall add rule name=\"Eddie - Out - AllowVPN\" dir=out action=allow localip=10.0.0.0/8");

            // Without this, Windows stay in 'Identifying network...' and OpenVPN in 'Waiting TUN to come up'.
            SystemShell.ShellCmd("netsh advfirewall firewall add rule name=\"Eddie - Out - DHCP\" dir=out action=allow protocol=UDP localport=68 remoteport=67 program=\"%SystemRoot%\\system32\\svchost.exe\" service=\"dhcp\"");

            string cmd = "netsh advfirewall set allprofiles firewallpolicy ";

            if (Engine.Instance.Storage.Get("netlock.incoming") == "allow")
            {
                cmd += "allowinbound";
            }
            else
            {
                cmd += "blockinbound";
            }
            cmd += ",";
            if (Engine.Instance.Storage.Get("netlock.outgoing") == "allow")
            {
                cmd += "allowoutbound";
            }
            else
            {
                cmd += "blockoutbound";
            }
            SystemShell.ShellCmd(cmd);

            m_activated = true;             // To avoid OnUpdateIps before this moment

            OnUpdateIps();
        }
        public override void Deactivation()
        {
            base.Deactivation();

            foreach (NetworkLockWindowsFirewallProfile profile in Profiles)
            {
                profile.RestorePolicy();
            }

            // Not need, already restored in after import
            // Exec("netsh advfirewall firewall delete rule name=\"Eddie - In - AllowLocal\"");
            // Exec("netsh advfirewall firewall delete rule name=\"Eddie - Out - AllowLocal\"");
            // Exec("netsh advfirewall firewall delete rule name=\"Eddie - Out - AllowVPN\"");
            // Exec("netsh advfirewall firewall delete rule name=\"Eddie - Out - AllowAirIPS\"");
            // Exec("netsh advfirewall firewall delete rule name=\"Eddie - Out - DHCP\"");

            // >2.9.1 edition
            {
                string rulesBackupSession = Engine.Instance.Storage.GetPathInData("winfirewall_rules_backup.wfw");
                if (Platform.Instance.FileExists(rulesBackupSession))
                {
                    SystemShell.ShellCmd("netsh advfirewall import \"" + SystemShell.EscapePath(rulesBackupSession) + "\"");
                    Platform.Instance.FileDelete(rulesBackupSession);
                }
            }

            // Old <2.8 edition
            {
                string rulesBackupSession = Engine.Instance.Storage.GetPathInData("winfirewallrules.wfw");
                if (Platform.Instance.FileExists(rulesBackupSession))
                {
                    SystemShell.ShellCmd("netsh advfirewall import \"" + SystemShell.EscapePath(rulesBackupSession) + "\"");
                    Platform.Instance.FileDelete(rulesBackupSession);
                }
            }

            // Old 2.9.0 edition, recover
            {
                string rulesBackupSession = Environment.SystemDirectory + Platform.Instance.DirSep + "winfirewall_rules_original.airvpn";
                if (Platform.Instance.FileExists(rulesBackupSession))
                {
                    SystemShell.ShellCmd("netsh advfirewall import \"" + SystemShell.EscapePath(rulesBackupSession) + "\"");
                    Platform.Instance.FileDelete(rulesBackupSession);
                }
            }

            foreach (NetworkLockWindowsFirewallProfile profile in Profiles)
            {
                if (profile.State == false)
                {
                    profile.StateOff();
                }
                // <2.11 Not need, already restored in below import
                // >=2.11 Restored, otherwise are not correctly restored in nt-domain environment.
                if (profile.Notifications == true)
                {
                    profile.NotifyOn();
                }
            }

            // Service
            if (m_serviceStatus == false)
            {
                ServiceController service = null;
                try
                {
                    service = new ServiceController("MpsSvc");
                    TimeSpan timeout = TimeSpan.FromMilliseconds(30000);
                    service.Stop();
                    service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
                }
                finally
                {
                    if (service != null)
                    {
                        service.Dispose();
                    }
                }
            }

            m_lastestIpsWhiteListOutgoing = "";
        }
Example #22
0
 public override string GetExecutableReport(string path)
 {
     return(ShellCmd("ldd \"" + SystemShell.EscapePath(path) + "\""));
 }
Example #23
0
        public override void Activation()
        {
            base.Activation();

            // Service
            try
            {
                ServiceController service = new ServiceController("MpsSvc");
                m_serviceStatus = (service.Status == ServiceControllerStatus.Running);
                if (m_serviceStatus == false)
                {
                    TimeSpan timeout = TimeSpan.FromMilliseconds(10000);
                    service.Start();
                    service.WaitForStatus(ServiceControllerStatus.Running, timeout);
                }
            }
            catch (Exception e)
            {
                if (e.Message.Contains("MpsSvc"))
                {
                    throw new Exception(Messages.NetworkLockUnableToStartService);
                }
                else
                {
                    throw e;
                }
            }

            // If 'winfirewall_rules_original.airvpn' doesn't exists, create it. It's a general backup of the first time.
            // We create this kind of file in Windows System directory, because it's system critical data, and to allow it to survive between re-installation of the software.
            string rulesBackupFirstTime = Storage.DataPath + Platform.Instance.DirSep + "winfirewall_rules_original.wfw";

            if (Platform.Instance.FileExists(rulesBackupFirstTime) == false)
            {
                Exec("netsh advfirewall export \"" + SystemShell.EscapePath(rulesBackupFirstTime) + "\"");
            }

            string rulesBackupSession = Storage.DataPath + Platform.Instance.DirSep + "winfirewall_rules_backup.wfw";

            if (Platform.Instance.FileExists(rulesBackupSession))
            {
                Platform.Instance.FileDelete(rulesBackupSession);
            }
            Exec("netsh advfirewall export \"" + SystemShell.EscapePath(rulesBackupSession) + "\"");
            if (Platform.Instance.FileExists(rulesBackupSession) == false)
            {
                throw new Exception(Messages.NetworkLockWindowsFirewallBackupFailed);
            }

            foreach (NetworkLockWindowsFirewallProfile profile in Profiles)
            {
                profile.Fetch();
            }

            foreach (NetworkLockWindowsFirewallProfile profile in Profiles)
            {
                if (profile.State == false)
                {
                    profile.StateOn();
                }

                /*
                 *              if (profile.Notifications == true)
                 *              {
                 *                      profile.NotifyOff();
                 *              }
                 */
            }

            // Disable all notifications
            Exec("netsh advfirewall set allprofiles settings inboundusernotification disable");

            Exec("netsh advfirewall firewall delete rule name=all");

            if (Engine.Instance.Storage.GetBool("netlock.allow_ping") == true)
            {
                Exec("netsh advfirewall firewall add rule name=\"Eddie - ICMP V4\" dir=in action=allow protocol=icmpv4");
            }

            // Exec("netsh advfirewall firewall add rule name=\"Eddie - IpV6 Block - Low\" dir=out remoteip=0000::/1 action=allow");
            // Exec("netsh advfirewall firewall add rule name=\"Eddie - IpV6 Block - High\" dir=out remoteip=8000::/1 action=allow");

            if (Engine.Instance.Storage.GetBool("netlock.allow_private") == true)
            {
                Exec("netsh advfirewall firewall add rule name=\"Eddie - In - AllowLocal\" dir=in action=allow remoteip=LocalSubnet");
                Exec("netsh advfirewall firewall add rule name=\"Eddie - Out - AllowLocal\" dir=out action=allow remoteip=LocalSubnet");

                Exec("netsh advfirewall firewall add rule name=\"Eddie - Out - AllowMulticast\" dir=out action=allow remoteip=224.0.0.0/24");
                Exec("netsh advfirewall firewall add rule name=\"Eddie - Out - AllowSimpleServiceDiscoveryProtocol\" dir=out action=allow remoteip=239.255.255.250/32");
                Exec("netsh advfirewall firewall add rule name=\"Eddie - Out - ServiceLocationProtocol\" dir=out action=allow remoteip=239.255.255.253/32");
            }

            Exec("netsh advfirewall firewall add rule name=\"Eddie - In - AllowVPN\" dir=in action=allow localip=10.4.0.0/16,10.5.0.0/16,10.6.0.0/16,10.7.0.0/16,10.8.0.0/16,10.9.0.0/16,10.30.0.0/16,10.50.0.0/16");
            Exec("netsh advfirewall firewall add rule name=\"Eddie - Out - AllowVPN\" dir=out action=allow localip=10.4.0.0/16,10.5.0.0/16,10.6.0.0/16,10.7.0.0/16,10.8.0.0/16,10.9.0.0/16,10.30.0.0/16,10.50.0.0/16");

            // Without this, Windows stay in 'Identifying network...' and OpenVPN in 'Waiting TUN to come up'.
            Exec("netsh advfirewall firewall add rule name=\"Eddie - Out - DHCP\" dir=out action=allow protocol=UDP localport=68 remoteport=67 program=\"%SystemRoot%\\system32\\svchost.exe\" service=\"dhcp\"");

            Exec("netsh advfirewall set allprofiles firewallpolicy BlockInbound,BlockOutbound");

            m_activated = true;             // To avoid OnUpdateIps before this moment

            OnUpdateIps();
        }
Example #24
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);
            }
        }
        public override void Activation()
        {
            base.Activation();

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

            if ((Platform.Instance.FileExists(rulesBackupSessionV4)) || (Platform.Instance.FileExists(rulesBackupSessionV6)))
            {
                Engine.Instance.Logs.Log(LogType.Warning, Messages.NetworkLockLinuxUnexpectedAlreadyActive);
                Deactivation();
            }

            // Backup V4
            Exec("iptables-save >\"" + SystemShell.EscapePath(rulesBackupSessionV4) + "\"");

            // Backup V6
            Exec("ip6tables-save >\"" + SystemShell.EscapePath(rulesBackupSessionV6) + "\"");

            // Flush V4
            Exec("iptables -F");
            Exec("iptables -t nat -F");
            Exec("iptables -t mangle -F");

            // Flush V6
            Exec("ip6tables -F");
            Exec("ip6tables -t nat -F");
            Exec("ip6tables -t mangle -F");

            // Local V4
            Exec("iptables -A INPUT -i lo -j ACCEPT");
            Exec("iptables -A OUTPUT -o lo -j ACCEPT");

            // Local V6
            Exec("ip6tables -A INPUT -i lo -j ACCEPT");
            Exec("ip6tables -A OUTPUT -o lo -j ACCEPT");

            // Make sure you can communicate with any DHCP server
            Exec("iptables -A OUTPUT -d 255.255.255.255 -j ACCEPT");
            Exec("iptables -A INPUT -s 255.255.255.255 -j ACCEPT");

            if (Engine.Instance.Storage.GetBool("netlock.allow_private"))
            {
                // Make sure that you can communicate within your own private networks
                Exec("iptables -A INPUT -s 192.168.0.0/16 -d 192.168.0.0/16 -j ACCEPT");
                Exec("iptables -A OUTPUT -s 192.168.0.0/16 -d 192.168.0.0/16 -j ACCEPT");
                Exec("iptables -A INPUT -s 10.0.0.0/8 -d 10.0.0.0/8 -j ACCEPT");
                Exec("iptables -A OUTPUT -s 10.0.0.0/8 -d 10.0.0.0/8 -j ACCEPT");
                Exec("iptables -A INPUT -s 172.16.0.0/12 -d 172.16.0.0/12 -j ACCEPT");
                Exec("iptables -A OUTPUT -s 172.16.0.0/12 -d 172.16.0.0/12 -j ACCEPT");

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

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

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

            if (Engine.Instance.Storage.GetBool("netlock.allow_ping"))
            {
                // Allow incoming pings (can be disabled)
                Exec("iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT");
            }

            // Allow established sessions to receive traffic:
            Exec("iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT");

            // Allow TUN
            Exec("iptables -A INPUT -i tun+ -j ACCEPT");
            Exec("iptables -A FORWARD -i tun+ -j ACCEPT");
            Exec("iptables -A OUTPUT -o tun+ -j ACCEPT");

            // Block All V4
            Exec("iptables -A OUTPUT -j DROP");
            Exec("iptables -A INPUT -j DROP");
            Exec("iptables -A FORWARD -j DROP");

            // Block All V6
            Exec("ip6tables -A OUTPUT -j DROP");
            Exec("ip6tables -A INPUT -j DROP");
            Exec("ip6tables -A FORWARD -j DROP");

            OnUpdateIps();
        }
Example #26
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);
                }
            }
        }