Ejemplo n.º 1
0
        public static List <Models.Server> Parse(string text)
        {
            var list = new List <Models.Server>();

            try
            {
                if (text.StartsWith("tg://socks?") || text.StartsWith("https://t.me/socks?"))
                {
                    var data = new Models.Server();
                    data.Type = "Socks5";

                    var dict = new Dictionary <string, string>();
                    foreach (var str in text.Replace("tg://socks?", "").Replace("https://t.me/socks?", "").Split('&'))
                    {
                        var splited = str.Split('=');

                        dict.Add(splited[0], splited[1]);
                    }

                    if (!dict.ContainsKey("server") || !dict.ContainsKey("port"))
                    {
                        return(null);
                    }

                    data.Hostname = dict["server"];
                    data.Port     = int.Parse(dict["port"]);
                    if (dict.ContainsKey("user") && !String.IsNullOrWhiteSpace(dict["user"]))
                    {
                        data.Username = dict["user"];
                    }
                    if (dict.ContainsKey("pass") && !String.IsNullOrWhiteSpace(dict["pass"]))
                    {
                        data.Password = dict["pass"];
                    }

                    list.Add(data);
                }
                else if (text.StartsWith("ss://"))
                {
                    var data = new Models.Server();
                    data.Type = "SS";

                    /*
                     * try
                     * {
                     *  if(!text.Contains("/?"))
                     *  {
                     *      var finder = new Regex(@"ss://(?<base64>[A-Za-z0-9+-/=_]+)(?:#(?<tag>\S+))?", RegexOptions.IgnoreCase);
                     *      var parser = new Regex(@"^((?<method>.+?):(?<password>.*)@(?<hostname>.+?):(?<port>\d+?))$", RegexOptions.IgnoreCase);
                     *      var match = finder.Match(text);
                     *      if (!match.Success)
                     *      {
                     *          throw new FormatException();
                     *      }
                     *
                     *      var base64 = match.Groups["base64"].Value.TrimEnd('/');
                     *      var tag = match.Groups["tag"].Value;
                     *      if (!String.IsNullOrEmpty(tag))
                     *      {
                     *          data.Remark = HttpUtility.UrlDecode(tag);
                     *      }
                     *
                     *      match = parser.Match(URLSafeBase64Decode(base64));
                     *      if (!match.Success)
                     *      {
                     *          throw new FormatException();
                     *      }
                     *
                     *      data.Address = match.Groups["hostname"].Value;
                     *      data.Port = int.Parse(match.Groups["port"].Value);
                     *      data.Password = match.Groups["password"].Value;
                     *      data.EncryptMethod = match.Groups["method"].Value;
                     *  }
                     *  else
                     *  {
                     *      if (text.Contains("#"))
                     *      {
                     *          data.Remark = HttpUtility.UrlDecode(text.Split('#')[1]);
                     *          text = text.Split('#')[0];
                     *      }
                     *      var finder = new Regex(@"ss://(?<base64>.+?)@(?<server>.+?):(?<port>\d+?)/\?plugin=(?<plugin>.+)");
                     *      var parser = new Regex(@"^(?<method>.+?):(?<password>.+)$");
                     *      var match = finder.Match(text);
                     *      if (!match.Success)
                     *      {
                     *          throw new FormatException();
                     *      }
                     *
                     *      data.Address = match.Groups["server"].Value;
                     *      data.Port = int.Parse(match.Groups["port"].Value);
                     *      var plugins = HttpUtility.UrlDecode(match.Groups["plugin"].Value).Split(';');
                     *      if (plugins[0] == "obfs-local")
                     *          plugins[0] = "simple-obfs";
                     *
                     *      var base64 = URLSafeBase64Decode(match.Groups["base64"].Value);
                     *      match = parser.Match(base64);
                     *      if (!match.Success)
                     *      {
                     *          throw new FormatException();
                     *      }
                     *
                     *      data.EncryptMethod = match.Groups["method"].Value;
                     *      data.Password = match.Groups["password"].Value;
                     *      data.Plugin = plugins[0];
                     *      data.PluginOption = plugins[1];
                     *  }
                     *
                     *  if (!Global.EncryptMethods.SS.Contains(data.EncryptMethod))
                     *  {
                     *      Logging.Info(String.Format("不支持的 SS 加密方式:{0}", data.EncryptMethod));
                     *      return null;
                     *  }
                     *
                     *  list.Add(data);
                     * }
                     * catch (FormatException)
                     * {
                     *  try
                     *  {
                     *      var uri = new Uri(text);
                     *      var userinfo = URLSafeBase64Decode(uri.UserInfo).Split(new char[] { ':' }, 2);
                     *      if (userinfo.Length != 2)
                     *      {
                     *          return null;
                     *      }
                     *
                     *      data.Remark = uri.GetComponents(UriComponents.Fragment, UriFormat.Unescaped);
                     *      data.Address = uri.IdnHost;
                     *      data.Port = uri.Port;
                     *      data.Password = userinfo[1];
                     *      data.EncryptMethod = userinfo[0];
                     *
                     *      if (!Global.EncryptMethods.SS.Contains(data.EncryptMethod))
                     *      {
                     *          Logging.Info(String.Format("不支持的 SS 加密方式:{0}", data.EncryptMethod));
                     *          return null;
                     *      }
                     *
                     *      list.Add(data);
                     *  }
                     *  catch (UriFormatException)
                     *  {
                     *      return null;
                     *  }
                     * }
                     */
                    text = text.Replace("/?", "?");
                    try
                    {
                        if (text.Contains("#"))
                        {
                            data.Remark = HttpUtility.UrlDecode(text.Split('#')[1]);
                            text        = text.Split('#')[0];
                        }
                        if (text.Contains("?"))
                        {
                            var finder = new Regex(@"^(?<data>.+?)\?(.+)$");
                            var match  = finder.Match(text);

                            if (match.Success)
                            {
                                var plugins    = HttpUtility.UrlDecode(HttpUtility.ParseQueryString(new Uri(text).Query).Get("plugin"));
                                var plugin     = plugins.Substring(0, plugins.IndexOf(";"));
                                var pluginopts = plugins.Substring(plugins.IndexOf(";") + 1);
                                if (plugin == "obfs-local" || plugin == "simple-obfs")
                                {
                                    plugin = "simple-obfs";
                                    if (!pluginopts.Contains("obfs="))
                                    {
                                        pluginopts = "obfs=http;obfs-host=" + pluginopts;
                                    }
                                }
                                else if (plugin == "simple-obfs-tls")
                                {
                                    plugin = "simple-obfs";
                                    if (!pluginopts.Contains("obfs="))
                                    {
                                        pluginopts = "obfs=tls;obfs-host=" + pluginopts;
                                    }
                                }

                                data.Plugin       = plugin;
                                data.PluginOption = pluginopts;
                                text = match.Groups["data"].Value;
                            }
                            else
                            {
                                throw new FormatException();
                            }
                        }
                        if (text.Contains("@"))
                        {
                            var finder = new Regex(@"^ss://(?<base64>.+?)@(?<server>.+):(?<port>\d+)");
                            var parser = new Regex(@"^(?<method>.+?):(?<password>.+)$");
                            var match  = finder.Match(text);
                            if (!match.Success)
                            {
                                throw new FormatException();
                            }

                            data.Hostname = match.Groups["server"].Value;
                            data.Port     = int.Parse(match.Groups["port"].Value);

                            var base64 = URLSafeBase64Decode(match.Groups["base64"].Value);
                            match = parser.Match(base64);
                            if (!match.Success)
                            {
                                throw new FormatException();
                            }

                            data.EncryptMethod = match.Groups["method"].Value;
                            data.Password      = match.Groups["password"].Value;
                        }
                        else
                        {
                            var parser = new Regex(@"^((?<method>.+?):(?<password>.+)@(?<server>.+):(?<port>\d+))");
                            var match  = parser.Match(URLSafeBase64Decode(text.Replace("ss://", "")));
                            if (!match.Success)
                            {
                                throw new FormatException();
                            }

                            data.Hostname      = match.Groups["server"].Value;
                            data.Port          = int.Parse(match.Groups["port"].Value);
                            data.EncryptMethod = match.Groups["method"].Value;
                            data.Password      = match.Groups["password"].Value;
                        }

                        if (!Global.EncryptMethods.SS.Contains(data.EncryptMethod))
                        {
                            Logging.Info(String.Format("不支持的 SS 加密方式:{0}", data.EncryptMethod));
                            return(null);
                        }

                        list.Add(data);
                    }
                    catch (FormatException)
                    {
                        return(null);
                    }
                }
                else if (text.StartsWith("ssd://"))
                {
                    var json = Newtonsoft.Json.JsonConvert.DeserializeObject <Models.SSD.Main>(URLSafeBase64Decode(text.Substring(6)));

                    foreach (var server in json.servers)
                    {
                        var data = new Models.Server();
                        data.Type = "SS";

                        data.Remark        = server.remarks;
                        data.Hostname      = server.server;
                        data.Port          = (server.port != 0) ? server.port : json.port;
                        data.Password      = (server.password != null) ? server.password : json.password;
                        data.EncryptMethod = (server.encryption != null) ? server.encryption : json.encryption;
                        data.Plugin        = (String.IsNullOrEmpty(json.plugin)) ? (String.IsNullOrEmpty(server.plugin) ? null : server.plugin) : json.plugin;
                        data.PluginOption  = (String.IsNullOrEmpty(json.plugin_options)) ? (String.IsNullOrEmpty(server.plugin_options) ? null : server.plugin_options) : json.plugin_options;

                        if (Global.EncryptMethods.SS.Contains(data.EncryptMethod))
                        {
                            list.Add(data);
                        }
                    }
                }
                else if (text.StartsWith("ssr://"))
                {
                    var data = new Models.Server();
                    data.Type = "SSR";

                    text = text.Substring(6);

                    /*
                     * var shadowsocksr = URLSafeBase64Decode(text).Split(':');
                     *
                     * if (shadowsocksr.Length > 6)
                     * {
                     *  var buff = "";
                     *
                     *  for (int i = 0; i < shadowsocksr.Length - 5; i++)
                     *  {
                     *      buff += shadowsocksr[i];
                     *      buff += ":";
                     *  }
                     *
                     *  data.Address = buff.Substring(0, buff.Length - 1).Trim();
                     * }
                     * else
                     * {
                     *  data.Address = shadowsocksr[0];
                     * }
                     * data.Port = int.Parse(shadowsocksr[shadowsocksr.Length - 5]);
                     * data.Protocol = shadowsocksr[shadowsocksr.Length - 4];
                     * if (!Global.Protocols.Contains(data.Protocol))
                     * {
                     *  Logging.Info(String.Format("不支持的 SSR 协议:{0}", data.Protocol));
                     *  return null;
                     * }
                     *
                     * data.EncryptMethod = shadowsocksr[shadowsocksr.Length - 3];
                     * if (!Global.EncryptMethods.SSR.Contains(data.EncryptMethod))
                     * {
                     *  Logging.Info(String.Format("不支持的 SSR 加密方式:{0}", data.EncryptMethod));
                     *  return null;
                     * }
                     *
                     * data.OBFS = shadowsocksr[shadowsocksr.Length - 2];
                     * if (!Global.OBFSs.Contains(data.OBFS))
                     * {
                     *  Logging.Info(String.Format("不支持的 SSR 混淆:{0}", data.OBFS));
                     *  return null;
                     * }
                     *
                     * var info = shadowsocksr[shadowsocksr.Length - 1].Split('/');
                     * data.Password = URLSafeBase64Decode(info[0]);
                     *
                     * var dict = new Dictionary<string, string>();
                     * if (info.Length > 1 && info[1].Length > 1)
                     * {
                     *  foreach (var str in info[1].Substring(1).Split('&'))
                     *  {
                     *      var splited = str.Split('=');
                     *
                     *      dict.Add(splited[0], splited[1]);
                     *  }
                     * }
                     *
                     * if (dict.ContainsKey("remarks"))
                     * {
                     *  data.Remark = URLSafeBase64Decode(dict["remarks"]);
                     * }
                     *
                     * if (dict.ContainsKey("protoparam"))
                     * {
                     *  data.ProtocolParam = URLSafeBase64Decode(dict["protoparam"]);
                     * }
                     *
                     * if (dict.ContainsKey("obfsparam"))
                     * {
                     *  data.OBFSParam = URLSafeBase64Decode(dict["obfsparam"]);
                     * }
                     *
                     * if (data.EncryptMethod != "none" && data.Protocol == "origin" && data.OBFS == "plain")
                     * {
                     *  data.Type = "SS";
                     * }
                     */
                    var parser = new Regex(@"^(?<server>.+):(?<port>\d+?):(?<protocol>.+?):(?<method>.+?):(?<obfs>.+?):(?<password>.+?)/\?(?<info>.*)$");
                    var match  = parser.Match(URLSafeBase64Decode(text));

                    if (match.Success)
                    {
                        data.Hostname = match.Groups["server"].Value;
                        data.Port     = int.Parse(match.Groups["port"].Value);
                        data.Password = URLSafeBase64Decode(match.Groups["password"].Value);

                        data.EncryptMethod = match.Groups["method"].Value;
                        if (!Global.EncryptMethods.SSR.Contains(data.EncryptMethod))
                        {
                            Logging.Info(String.Format("不支持的 SSR 加密方式:{0}", data.EncryptMethod));
                            return(null);
                        }

                        data.Protocol = match.Groups["protocol"].Value;
                        if (!Global.Protocols.Contains(data.Protocol))
                        {
                            Logging.Info(String.Format("不支持的 SSR 协议:{0}", data.Protocol));
                            return(null);
                        }

                        data.OBFS = match.Groups["obfs"].Value;
                        if (!Global.OBFSs.Contains(data.OBFS))
                        {
                            Logging.Info(String.Format("不支持的 SSR 混淆:{0}", data.OBFS));
                            return(null);
                        }

                        var info = match.Groups["info"].Value;
                        var dict = new Dictionary <string, string>();
                        foreach (var str in info.Split('&'))
                        {
                            var splited = str.Split('=');
                            dict.Add(splited[0], splited[1]);
                        }

                        if (dict.ContainsKey("remarks"))
                        {
                            data.Remark = URLSafeBase64Decode(dict["remarks"]);
                        }

                        if (dict.ContainsKey("protoparam"))
                        {
                            data.ProtocolParam = URLSafeBase64Decode(dict["protoparam"]);
                        }

                        if (dict.ContainsKey("obfsparam"))
                        {
                            data.OBFSParam = URLSafeBase64Decode(dict["obfsparam"]);
                        }

                        if (Global.EncryptMethods.SS.Contains(data.EncryptMethod) && data.Protocol == "origin" && data.OBFS == "plain")
                        {
                            data.OBFS = "";
                            data.Type = "SS";
                        }
                    }

                    list.Add(data);
                }
                else if (text.StartsWith("vmess://"))
                {
                    var data = new Models.Server();
                    data.Type = "VMess";

                    text = text.Substring(8);
                    var vmess = Newtonsoft.Json.JsonConvert.DeserializeObject <Models.VMess>(URLSafeBase64Decode(text));

                    data.Remark   = vmess.ps;
                    data.Hostname = vmess.add;
                    data.Port     = vmess.port;
                    data.UserID   = vmess.id;
                    data.AlterID  = vmess.aid;

                    data.TransferProtocol = vmess.net;
                    if (!Global.TransferProtocols.Contains(data.TransferProtocol))
                    {
                        Logging.Info(String.Format("不支持的 VMess 传输协议:{0}", data.TransferProtocol));
                        return(null);
                    }

                    data.FakeType = vmess.type;
                    if (!Global.FakeTypes.Contains(data.FakeType))
                    {
                        Logging.Info(String.Format("不支持的 VMess 伪装类型:{0}", data.FakeType));
                        return(null);
                    }

                    if (vmess.v == null || vmess.v == "1")
                    {
                        var info = vmess.host.Split(';');
                        if (info.Length == 2)
                        {
                            vmess.host = info[0];
                            vmess.path = info[1];
                        }
                    }
                    if (data.TransferProtocol == "quic")
                    {
                        if (!Global.EncryptMethods.VMessQUIC.Contains(vmess.host))
                        {
                            Logging.Info(String.Format("不支持的 VMess QUIC 加密方式:{0}", vmess.host));
                            return(null);
                        }
                        else
                        {
                            data.QUICSecure = vmess.host;
                            data.QUICSecret = vmess.path;
                        }
                    }
                    else
                    {
                        data.Host = vmess.host;
                        data.Path = vmess.path;
                    }
                    data.TLSSecure = vmess.tls == "tls";

                    data.EncryptMethod = "auto"; // V2Ray 加密方式不包括在链接中,主动添加一个

                    list.Add(data);
                }
                else if (text.StartsWith("Netch://"))
                {
                    text = text.Substring(8);
                    var NetchLink = Newtonsoft.Json.JsonConvert.DeserializeObject <Models.Server>(URLSafeBase64Decode(text));
                    if (!String.IsNullOrEmpty(NetchLink.Hostname) || NetchLink.Port > 65536 || NetchLink.Port > 0)
                    {
                        return(null);
                    }

                    switch (NetchLink.Type)
                    {
                    case "Socks5":
                        list.Add(NetchLink);
                        break;

                    case "SS":
                        if (!Global.EncryptMethods.SS.Contains(NetchLink.EncryptMethod))
                        {
                            Logging.Info($"不支持的 SS 加密方式:{NetchLink.EncryptMethod}");
                            return(null);
                        }
                        break;

                    case "SSR":
                        if (!Global.EncryptMethods.SSR.Contains(NetchLink.EncryptMethod))
                        {
                            Logging.Info($"不支持的 SSR 加密方式:{NetchLink.EncryptMethod}");
                            return(null);
                        }
                        if (!Global.Protocols.Contains(NetchLink.Protocol))
                        {
                            Logging.Info($"不支持的 SSR 协议:{NetchLink.Protocol}");
                            return(null);
                        }
                        if (!Global.OBFSs.Contains(NetchLink.OBFS))
                        {
                            Logging.Info($"不支持的 SSR 混淆:{NetchLink.OBFS}");
                            return(null);
                        }
                        break;

                    case "VMess":
                        if (!Global.TransferProtocols.Contains(NetchLink.TransferProtocol))
                        {
                            Logging.Info($"不支持的 VMess 传输协议:{NetchLink.TransferProtocol}");
                            return(null);
                        }
                        if (!Global.FakeTypes.Contains(NetchLink.FakeType))
                        {
                            Logging.Info($"不支持的 VMess 伪装类型:{NetchLink.FakeType}");
                            return(null);
                        }
                        if (NetchLink.TransferProtocol == "quic")
                        {
                            if (!Global.EncryptMethods.VMessQUIC.Contains(NetchLink.QUICSecure))
                            {
                                Logging.Info($"不支持的 VMess QUIC 加密方式:{NetchLink.QUICSecure}");
                                return(null);
                            }
                        }
                        break;

                    default:
                        return(null);
                    }
                    list.Add(NetchLink);
                }

                else
                {
                    System.Windows.Forms.MessageBox.Show("未找到可导入的链接!", "错误", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Exclamation);
                    return(null);
                }
            }
            catch (Exception e)
            {
                Logging.Info(e.ToString());
                return(null);
            }

            return(list);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 根据程序名统计流量
        /// </summary>
        /// <param name="ProcessName"></param>
        public static void NetTraffic(Server server, Mode mode, MainController mainController)
        {
            var counterLock = new object();
            //int sent = 0;

            //var processList = Process.GetProcessesByName(ProcessName).Select(p => p.Id).ToHashSet();
            var processList = new List <int>();

            if (server.Type.Equals("Socks5") && mainController.pHTTPController != null)
            {
                processList.Add(mainController.pHTTPController.pPrivoxyController.Instance.Id);
            }
            else if (server.Type.Equals("SS") && Global.Settings.BootShadowsocksFromDLL)
            {
                processList.Add(Process.GetCurrentProcess().Id);
            }
            else if (server.Type.Equals("SS") && mainController.pSSController != null)
            {
                processList.Add(mainController.pSSController.Instance.Id);
            }
            else if (server.Type.Equals("SSR") && mainController.pSSRController != null)
            {
                processList.Add(mainController.pSSRController.Instance.Id);
            }
            else if (server.Type.Equals("VMess") && mainController.pVMessController != null)
            {
                processList.Add(mainController.pVMessController.Instance.Id);
            }
            else if (server.Type.Equals("TR") && mainController.pTrojanController != null)
            {
                processList.Add(mainController.pTrojanController.Instance.Id);
            }
            else if (mainController.pTUNTAPController != null)
            {
                processList.Add(mainController.pTUNTAPController.Instance.Id);
            }
            else if (mainController.pNFController != null)
            {
                processList.Add(mainController.pNFController.Instance.Id);
            }
            Logging.Info("启动流量统计 PID:" + string.Join(",", processList.ToArray()));

            Task.Run(() =>
            {
                using (var session = new TraceEventSession("KernelAndClrEventsSession"))
                {
                    session.EnableKernelProvider(KernelTraceEventParser.Keywords.NetworkTCPIP);

                    //这玩意儿上传和下载得到的data是一样的:)
                    //所以暂时没办法区分上传下载流量
                    session.Source.Kernel.TcpIpRecv += data =>
                    {
                        if (processList.Contains(data.ProcessID))
                        {
                            lock (counterLock)
                                received += data.size;
                            //Logging.Info($"TcpIpRecv: {Compute(data.size)}");
                        }
                    };
                    session.Source.Kernel.UdpIpRecv += data =>
                    {
                        if (processList.Contains(data.ProcessID))
                        {
                            lock (counterLock)
                                received += data.size;
                            //Logging.Info($"UdpIpRecv: {Compute(data.size)}");
                        }
                    };

                    session.Source.Process();
                }
            });

            //if ((Convert.ToInt32(MainForm.Instance.LastDownloadBandwidth) - Convert.ToInt32(received)) == 0)
            //{
            //    MainForm.Instance.OnBandwidthUpdated(0);
            //    received = 0;
            //}
            //while (MainForm.Instance.State != State.Stopped)
            //{
            //    Task.Delay(1000).Wait();
            //    lock (counterLock)
            //    {
            //        MainForm.Instance.OnBandwidthUpdated(Convert.ToInt64(received));
            //    }
            //}
        }
Ejemplo n.º 3
0
        /// <summary>
        ///		搜索出口
        /// </summary>
        public static bool SearchOutbounds()
        {
            Logging.Info("正在搜索出口中");

            if (Win32Native.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse("114.114.114.114").GetAddressBytes(), 0), 0, out var pRoute) == 0)
            {
                Global.Adapter.Index   = pRoute.dwForwardIfIndex;
                Global.Adapter.Gateway = new IPAddress(pRoute.dwForwardNextHop);
                Logging.Info($"当前 网关 地址:{Global.Adapter.Gateway}");
            }
            else
            {
                Logging.Info("GetBestRoute 搜索失败");
                return(false);
            }

            Logging.Info($"搜索适配器index:{Global.Adapter.Index}");
            var AddressGot = false;

            foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces())
            {
                try
                {
                    var adapterProperties = adapter.GetIPProperties();
                    var p = adapterProperties.GetIPv4Properties();
                    Logging.Info($"检测适配器:{adapter.Name} {adapter.Id} {adapter.Description}, index: {p.Index}");

                    // 通过索引查找对应适配器的 IPv4 地址
                    if (p.Index == Global.Adapter.Index)
                    {
                        var AdapterIPs = "";

                        foreach (var ip in adapterProperties.UnicastAddresses)
                        {
                            if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
                            {
                                AddressGot             = true;
                                Global.Adapter.Address = ip.Address;
                                Logging.Info($"当前出口 IPv4 地址:{Global.Adapter.Address}");
                                break;
                            }
                            AdapterIPs = $"{ip.Address} | ";
                        }

                        if (!AddressGot)
                        {
                            if (AdapterIPs.Length > 3)
                            {
                                AdapterIPs = AdapterIPs.Substring(0, AdapterIPs.Length - 3);
                                Logging.Info($"所有出口地址:{AdapterIPs}");
                            }
                            Logging.Info("出口无 IPv4 地址,当前只支持 IPv4 地址");
                            return(false);
                        }
                        break;
                    }
                }
                catch (Exception)
                { }
            }

            if (!AddressGot)
            {
                Logging.Info("无法找到当前使用适配器");
                return(false);
            }

            // 搜索 TUN/TAP 适配器的索引
            Global.TUNTAP.ComponentID = TUNTAP.GetComponentID();
            if (string.IsNullOrEmpty(Global.TUNTAP.ComponentID))
            {
                Logging.Info("未找到可用 TUN/TAP 适配器");
                if (MessageBox.Show(i18N.Translate("TUN/TAP driver is not detected. Is it installed now?"), i18N.Translate("Information"), MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.OK)
                {
                    addtap();
                    //给点时间,不然立马安装完毕就查找适配器可能会导致找不到适配器ID
                    Thread.Sleep(1000);
                    Global.TUNTAP.ComponentID = TUNTAP.GetComponentID();
                }
                else
                {
                    return(false);
                }
                //MessageBox.Show(i18N.Translate("Please install TAP-Windows and create an TUN/TAP adapter manually"), i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
                // return false;
            }

            foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces())
            {
                if (adapter.Id == Global.TUNTAP.ComponentID)
                {
                    Global.TUNTAP.Adapter = adapter;
                    Global.TUNTAP.Index   = adapter.GetIPProperties().GetIPv4Properties().Index;

                    Logging.Info($"找到适配器:{adapter.Id}");

                    return(true);
                }
            }

            Logging.Info("无法找到出口");
            return(false);
        }
Ejemplo n.º 4
0
        /// <summary>
        ///		搜索出口
        /// </summary>
        public static bool SearchOutbounds()
        {
            Logging.Info("正在搜索出口中");

            if (Win32Native.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse("114.114.114.114").GetAddressBytes(), 0), 0, out var pRoute) == 0)
            {
                Global.Adapter.Index   = pRoute.dwForwardIfIndex;
                Global.Adapter.Gateway = new IPAddress(pRoute.dwForwardNextHop);
                Logging.Info($"当前 网关 地址:{Global.Adapter.Gateway}");
            }
            else
            {
                Logging.Info("GetBestRoute 搜索失败");
                return(false);
            }

            foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces())
            {
                var adapterProperties = adapter.GetIPProperties();
                var p = adapterProperties.GetIPv4Properties();

                // 通过索引查找对应适配器的 IPv4 地址
                if (p.Index == Global.Adapter.Index)
                {
                    var AddressGot = false;
                    var AdapterIPs = "";

                    foreach (var ip in adapterProperties.UnicastAddresses)
                    {
                        if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
                        {
                            AddressGot             = true;
                            Global.Adapter.Address = ip.Address;
                            Logging.Info($"当前出口 IPv4 地址:{Global.Adapter.Address}");
                            break;
                        }
                        AdapterIPs = $"{ip.Address} | ";
                    }

                    if (!AddressGot)
                    {
                        if (AdapterIPs.Length > 3)
                        {
                            AdapterIPs = AdapterIPs.Substring(0, AdapterIPs.Length - 3);
                            Logging.Info($"所有出口地址:{AdapterIPs}");
                        }
                        Logging.Info("出口无 IPv4 地址,当前只支持 IPv4 地址");
                        return(false);
                    }
                    break;
                }
            }

            // 搜索 TUN/TAP 适配器的索引
            Global.TUNTAP.ComponentID = TUNTAP.GetComponentID();
            if (string.IsNullOrEmpty(Global.TUNTAP.ComponentID))
            {
                if (MessageBox.Show(i18N.Translate("TUN/TAP driver is not detected. Is it installed now?"), i18N.Translate("Information"), MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.OK)
                {
                    //安装Tap Driver
                    Process installProcess = new Process();
                    installProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                    installProcess.StartInfo.FileName    = Path.Combine("bin/tap-driver", "install.bat");
                    installProcess.Start();
                    installProcess.WaitForExit();
                    installProcess.Close();

                    Global.TUNTAP.ComponentID = TUNTAP.GetComponentID();
                }
                else
                {
                    return(false);
                }
                //MessageBox.Show(i18N.Translate("Please install TAP-Windows and create an TUN/TAP adapter manually"), i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
                // return false;
            }

            foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces())
            {
                if (adapter.Id == Global.TUNTAP.ComponentID)
                {
                    Global.TUNTAP.Adapter = adapter;
                    Global.TUNTAP.Index   = adapter.GetIPProperties().GetIPv4Properties().Index;

                    return(true);
                }
            }

            Logging.Info("无法找到出口");
            return(false);
        }
Ejemplo n.º 5
0
        /// <summary>
        ///		搜索出口
        /// </summary>
        public static bool SearchOutbounds()
        {
            Logging.Info("正在搜索出口中");

            if (Win32Native.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse("114.114.114.114").GetAddressBytes(), 0), 0, out var pRoute) == 0)
            {
                Global.Adapter.Index   = pRoute.dwForwardIfIndex;
                Global.Adapter.Gateway = new IPAddress(pRoute.dwForwardNextHop);
                Logging.Info($"当前 网关 地址:{Global.Adapter.Gateway}");
            }
            else
            {
                Logging.Info($"GetBestRoute 搜索失败");
                return(false);
            }

            foreach (NetworkInterface adapter in NetworkInterface.GetAllNetworkInterfaces())
            {
                IPInterfaceProperties   adapterProperties = adapter.GetIPProperties();
                IPv4InterfaceProperties p = adapterProperties.GetIPv4Properties();

                // 通过索引查找对应适配器的 IPv4 地址
                if (p.Index == Global.Adapter.Index)
                {
                    var    AddressGot = false;
                    String AdapterIPs = "";

                    foreach (UnicastIPAddressInformation ip in adapterProperties.UnicastAddresses)
                    {
                        if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
                        {
                            AddressGot             = true;
                            Global.Adapter.Address = ip.Address;
                            Logging.Info($"当前出口 IPv4 地址:{Global.Adapter.Address}");
                            break;
                        }
                        AdapterIPs = $"{ip.Address.ToString()} | ";
                    }

                    if (!AddressGot)
                    {
                        if (AdapterIPs.Length > 3)
                        {
                            AdapterIPs = AdapterIPs.Substring(0, AdapterIPs.Length - 3);
                            Logging.Info($"所有出口地址:{AdapterIPs}");
                        }
                        Logging.Info($"出口无 IPv4 地址,当前只支持 IPv4 地址");
                        return(false);
                    }
                    break;
                }
            }

            // 搜索 TUN/TAP 适配器的索引
            Global.TUNTAP.ComponentID = TUNTAP.GetComponentID();
            if (String.IsNullOrEmpty(Global.TUNTAP.ComponentID))
            {
                MessageBox.Show(i18N.Translate("Please install TAP-Windows and create an TUN/TAP adapter manually"), i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
                return(false);
            }

            var name = TUNTAP.GetName(Global.TUNTAP.ComponentID);

            foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces())
            {
                if (adapter.Name == name)
                {
                    Global.TUNTAP.Adapter = adapter;
                    Global.TUNTAP.Index   = adapter.GetIPProperties().GetIPv4Properties().Index;

                    break;
                }
            }
            return(true);
        }
Ejemplo n.º 6
0
        private static IEnumerable <Server> ParseLine(string text)
        {
            var list = new List <Server>();

            try
            {
                if (text.StartsWith("tg://socks?") || text.StartsWith("https://t.me/socks?"))
                {
                    var data = new Server();
                    data.Type = "Socks5";

                    var dict = new Dictionary <string, string>();
                    foreach (var str in text.Replace("tg://socks?", "").Replace("https://t.me/socks?", "").Split('&'))
                    {
                        var splited = str.Split('=');

                        dict.Add(splited[0], splited[1]);
                    }

                    if (!dict.ContainsKey("server") || !dict.ContainsKey("port"))
                    {
                        return(null);
                    }

                    data.Hostname = dict["server"];
                    data.Port     = int.Parse(dict["port"]);
                    if (dict.ContainsKey("user") && !string.IsNullOrWhiteSpace(dict["user"]))
                    {
                        data.Username = dict["user"];
                    }
                    if (dict.ContainsKey("pass") && !string.IsNullOrWhiteSpace(dict["pass"]))
                    {
                        data.Password = dict["pass"];
                    }

                    list.Add(data);
                }
                else if (text.StartsWith("ss://"))
                {
                    var data = new Server();
                    data.Type = "SS";

                    text = text.Replace("/?", "?");
                    try
                    {
                        if (text.Contains("#"))
                        {
                            data.Remark = HttpUtility.UrlDecode(text.Split('#')[1]);
                            text        = text.Split('#')[0];
                        }
                        if (text.Contains("?"))
                        {
                            var finder = new Regex(@"^(?<data>.+?)\?(.+)$");
                            var match  = finder.Match(text);

                            if (match.Success)
                            {
                                var plugins = HttpUtility.UrlDecode(HttpUtility.ParseQueryString(new Uri(text).Query).Get("plugin"));
                                if (plugins != null)
                                {
                                    var plugin     = plugins.Substring(0, plugins.IndexOf(";", StringComparison.Ordinal));
                                    var pluginopts = plugins.Substring(plugins.IndexOf(";", StringComparison.Ordinal) + 1);
                                    if (plugin == "obfs-local" || plugin == "simple-obfs")
                                    {
                                        plugin = "simple-obfs";
                                        if (!pluginopts.Contains("obfs="))
                                        {
                                            pluginopts = "obfs=http;obfs-host=" + pluginopts;
                                        }
                                    }
                                    else if (plugin == "simple-obfs-tls")
                                    {
                                        plugin = "simple-obfs";
                                        if (!pluginopts.Contains("obfs="))
                                        {
                                            pluginopts = "obfs=tls;obfs-host=" + pluginopts;
                                        }
                                    }

                                    data.Plugin       = plugin;
                                    data.PluginOption = pluginopts;
                                }

                                text = match.Groups["data"].Value;
                            }
                            else
                            {
                                throw new FormatException();
                            }
                        }
                        if (text.Contains("@"))
                        {
                            var finder = new Regex(@"^ss://(?<base64>.+?)@(?<server>.+):(?<port>\d+)");
                            var parser = new Regex(@"^(?<method>.+?):(?<password>.+)$");
                            var match  = finder.Match(text);
                            if (!match.Success)
                            {
                                throw new FormatException();
                            }

                            data.Hostname = match.Groups["server"].Value;
                            data.Port     = int.Parse(match.Groups["port"].Value);

                            var base64 = URLSafeBase64Decode(match.Groups["base64"].Value);
                            match = parser.Match(base64);
                            if (!match.Success)
                            {
                                throw new FormatException();
                            }

                            data.EncryptMethod = match.Groups["method"].Value;
                            data.Password      = match.Groups["password"].Value;
                        }
                        else
                        {
                            var parser = new Regex(@"^((?<method>.+?):(?<password>.+)@(?<server>.+):(?<port>\d+))");
                            var match  = parser.Match(URLSafeBase64Decode(text.Replace("ss://", "")));
                            if (!match.Success)
                            {
                                throw new FormatException();
                            }

                            data.Hostname      = match.Groups["server"].Value;
                            data.Port          = int.Parse(match.Groups["port"].Value);
                            data.EncryptMethod = match.Groups["method"].Value;
                            data.Password      = match.Groups["password"].Value;
                        }

                        if (!Global.EncryptMethods.SS.Contains(data.EncryptMethod))
                        {
                            Logging.Info(string.Format("不支持的 SS 加密方式:{0}", data.EncryptMethod));
                            return(null);
                        }

                        list.Add(data);
                    }
                    catch (FormatException)
                    {
                        return(null);
                    }
                }
                else if (text.StartsWith("ssd://"))
                {
                    var json = JsonConvert.DeserializeObject <Models.SSD.Main>(URLSafeBase64Decode(text.Substring(6)));

                    foreach (var server in json.servers)
                    {
                        var data = new Server();
                        data.Type = "SS";

                        data.Remark        = server.remarks;
                        data.Hostname      = server.server;
                        data.Port          = server.port != 0 ? server.port : json.port;
                        data.Password      = server.password != null ? server.password : json.password;
                        data.EncryptMethod = server.encryption != null ? server.encryption : json.encryption;
                        data.Plugin        = string.IsNullOrEmpty(json.plugin) ? string.IsNullOrEmpty(server.plugin) ? null : server.plugin : json.plugin;
                        data.PluginOption  = string.IsNullOrEmpty(json.plugin_options) ? string.IsNullOrEmpty(server.plugin_options) ? null : server.plugin_options : json.plugin_options;

                        if (Global.EncryptMethods.SS.Contains(data.EncryptMethod))
                        {
                            list.Add(data);
                        }
                    }
                }
                else if (text.StartsWith("ssr://"))
                {
                    var data = new Server();
                    data.Type = "SSR";

                    text = text.Substring(6);

                    var parser = new Regex(@"^(?<server>.+):(?<port>(-?\d+?)):(?<protocol>.+?):(?<method>.+?):(?<obfs>.+?):(?<password>.+?)/\?(?<info>.*)$");
                    var match  = parser.Match(URLSafeBase64Decode(text));

                    if (match.Success)
                    {
                        data.Hostname = match.Groups["server"].Value;
                        data.Port     = int.Parse(match.Groups["port"].Value);
                        if (data.Port < 0)
                        {
                            data.Port += 65536;
                        }
                        data.Password = URLSafeBase64Decode(match.Groups["password"].Value);

                        data.EncryptMethod = match.Groups["method"].Value;
                        if (!Global.EncryptMethods.SSR.Contains(data.EncryptMethod))
                        {
                            Logging.Info(string.Format("不支持的 SSR 加密方式:{0}", data.EncryptMethod));
                            return(null);
                        }

                        data.Protocol = match.Groups["protocol"].Value;
                        if (!Global.Protocols.Contains(data.Protocol))
                        {
                            Logging.Info(string.Format("不支持的 SSR 协议:{0}", data.Protocol));
                            return(null);
                        }

                        data.OBFS = match.Groups["obfs"].Value;
                        if (data.OBFS == @"tls1.2_ticket_fastauth")
                        {
                            data.OBFS = @"tls1.2_ticket_auth";
                        }
                        if (!Global.OBFSs.Contains(data.OBFS))
                        {
                            Logging.Info(string.Format("不支持的 SSR 混淆:{0}", data.OBFS));
                            return(null);
                        }

                        var info = match.Groups["info"].Value;
                        var dict = new Dictionary <string, string>();
                        foreach (var str in info.Split('&'))
                        {
                            var splited = str.Split('=');
                            dict.Add(splited[0], splited[1]);
                        }

                        if (dict.ContainsKey("remarks"))
                        {
                            data.Remark = URLSafeBase64Decode(dict["remarks"]);
                        }

                        if (dict.ContainsKey("protoparam"))
                        {
                            data.ProtocolParam = URLSafeBase64Decode(dict["protoparam"]);
                        }

                        if (dict.ContainsKey("obfsparam"))
                        {
                            data.OBFSParam = URLSafeBase64Decode(dict["obfsparam"]);
                        }

                        if (Global.EncryptMethods.SS.Contains(data.EncryptMethod) && data.Protocol == "origin" && data.OBFS == "plain")
                        {
                            data.OBFS = "";
                            data.Type = "SS";
                        }
                    }

                    list.Add(data);
                }
                else if (text.StartsWith("vmess://"))
                {
                    var data = new Server();
                    data.Type = "VMess";

                    text = text.Substring(8);
                    var vmess = JsonConvert.DeserializeObject <VMess>(URLSafeBase64Decode(text));

                    data.Remark   = vmess.ps;
                    data.Hostname = vmess.add;
                    data.Port     = vmess.port;
                    data.UserID   = vmess.id;
                    data.AlterID  = vmess.aid;

                    data.TransferProtocol = vmess.net;
                    if (!Global.TransferProtocols.Contains(data.TransferProtocol))
                    {
                        Logging.Info(string.Format("不支持的 VMess 传输协议:{0}", data.TransferProtocol));
                        return(null);
                    }

                    data.FakeType = vmess.type;
                    if (!Global.FakeTypes.Contains(data.FakeType))
                    {
                        Logging.Info(string.Format("不支持的 VMess 伪装类型:{0}", data.FakeType));
                        return(null);
                    }

                    if (vmess.v == null || vmess.v == "1")
                    {
                        var info = vmess.host.Split(';');
                        if (info.Length == 2)
                        {
                            vmess.host = info[0];
                            vmess.path = info[1];
                        }
                    }
                    if (data.TransferProtocol == "quic")
                    {
                        if (!Global.EncryptMethods.VMessQUIC.Contains(vmess.host))
                        {
                            Logging.Info(string.Format("不支持的 VMess QUIC 加密方式:{0}", vmess.host));
                            return(null);
                        }

                        data.QUICSecure = vmess.host;
                        data.QUICSecret = vmess.path;
                    }
                    else
                    {
                        data.Host = vmess.host;
                        data.Path = vmess.path;
                    }
                    data.TLSSecure = vmess.tls == "tls";

                    if (vmess.mux == null)
                    {
                        data.UseMux = false;
                    }
                    else
                    {
                        if (vmess.mux.enabled is bool enabled)
                        {
                            data.UseMux = enabled;
                        }
                        else if (vmess.mux.enabled is string muxEnabled)
                        {
                            data.UseMux = muxEnabled == "true";  // 针对使用字符串当作布尔值的情况
                        }
                        else
                        {
                            data.UseMux = false;
                        }
                    }

                    data.EncryptMethod = "auto"; // V2Ray 加密方式不包括在链接中,主动添加一个

                    list.Add(data);
                }
                else if (text.StartsWith("Netch://"))
                {
                    text = text.Substring(8);
                    var NetchLink = JsonConvert.DeserializeObject <Server>(URLSafeBase64Decode(text));
                    if (!string.IsNullOrEmpty(NetchLink.Hostname) || NetchLink.Port > 65536 || NetchLink.Port > 0)
                    {
                        return(null);
                    }

                    switch (NetchLink.Type)
                    {
                    case "Socks5":
                        list.Add(NetchLink);
                        break;

                    case "SS":
                        if (!Global.EncryptMethods.SS.Contains(NetchLink.EncryptMethod))
                        {
                            Logging.Info($"不支持的 SS 加密方式:{NetchLink.EncryptMethod}");
                            return(null);
                        }
                        break;

                    case "SSR":
                        if (!Global.EncryptMethods.SSR.Contains(NetchLink.EncryptMethod))
                        {
                            Logging.Info($"不支持的 SSR 加密方式:{NetchLink.EncryptMethod}");
                            return(null);
                        }
                        if (!Global.Protocols.Contains(NetchLink.Protocol))
                        {
                            Logging.Info($"不支持的 SSR 协议:{NetchLink.Protocol}");
                            return(null);
                        }
                        if (!Global.OBFSs.Contains(NetchLink.OBFS))
                        {
                            Logging.Info($"不支持的 SSR 混淆:{NetchLink.OBFS}");
                            return(null);
                        }
                        break;

                    case "VMess":
                        if (!Global.TransferProtocols.Contains(NetchLink.TransferProtocol))
                        {
                            Logging.Info($"不支持的 VMess 传输协议:{NetchLink.TransferProtocol}");
                            return(null);
                        }
                        if (!Global.FakeTypes.Contains(NetchLink.FakeType))
                        {
                            Logging.Info($"不支持的 VMess 伪装类型:{NetchLink.FakeType}");
                            return(null);
                        }
                        if (NetchLink.TransferProtocol == "quic")
                        {
                            if (!Global.EncryptMethods.VMessQUIC.Contains(NetchLink.QUICSecure))
                            {
                                Logging.Info($"不支持的 VMess QUIC 加密方式:{NetchLink.QUICSecure}");
                                return(null);
                            }
                        }
                        break;

                    default:
                        return(null);
                    }
                    list.Add(NetchLink);
                }
            }
            catch (Exception e)
            {
                Logging.Info(e.ToString());
                return(null);
            }

            return(list);
        }