From 80f4a118586f1a76d80ef05694aaae1134df6a22 Mon Sep 17 00:00:00 2001 From: Lai Zenan Date: Sat, 23 Mar 2024 06:14:54 +0800 Subject: [PATCH 1/7] feat: add hysteria & hysteria 2 support --- src/generator/config/subexport.cpp | 194 ++++++++++++++++++++++++-- src/parser/config/proxy.h | 30 +++- src/parser/subparser.cpp | 214 +++++++++++++++++++++++++++++ src/parser/subparser.h | 34 +++++ 4 files changed, 461 insertions(+), 11 deletions(-) diff --git a/src/generator/config/subexport.cpp b/src/generator/config/subexport.cpp index f4f8f4077..20c8a265e 100644 --- a/src/generator/config/subexport.cpp +++ b/src/generator/config/subexport.cpp @@ -116,15 +116,19 @@ bool applyMatcher(const std::string &rule, std::string &real_rule, const Proxy & std::string target, ret_real_rule; static const std::string groupid_regex = R"(^!!(?:GROUPID|INSERT)=([\d\-+!,]+)(?:!!(.*))?$)", group_regex = R"(^!!(?:GROUP)=(.+?)(?:!!(.*))?$)"; static const std::string type_regex = R"(^!!(?:TYPE)=(.+?)(?:!!(.*))?$)", port_regex = R"(^!!(?:PORT)=(.+?)(?:!!(.*))?$)", server_regex = R"(^!!(?:SERVER)=(.+?)(?:!!(.*))?$)"; - static const std::map types = {{ProxyType::Shadowsocks, "SS"}, - {ProxyType::ShadowsocksR, "SSR"}, - {ProxyType::VMess, "VMESS"}, - {ProxyType::Trojan, "TROJAN"}, - {ProxyType::Snell, "SNELL"}, - {ProxyType::HTTP, "HTTP"}, - {ProxyType::HTTPS, "HTTPS"}, - {ProxyType::SOCKS5, "SOCKS5"}, - {ProxyType::WireGuard, "WIREGUARD"}}; + static const std::map types = { + {ProxyType::Shadowsocks, "SS"}, + {ProxyType::ShadowsocksR, "SSR"}, + {ProxyType::VMess, "VMESS"}, + {ProxyType::Trojan, "TROJAN"}, + {ProxyType::Snell, "SNELL"}, + {ProxyType::HTTP, "HTTP"}, + {ProxyType::HTTPS, "HTTPS"}, + {ProxyType::SOCKS5, "SOCKS5"}, + {ProxyType::WireGuard, "WIREGUARD"}, + {ProxyType::Hysteria, "HYSTERIA"}, + {ProxyType::Hysteria2, "HYSTERIA2"} + }; if(startsWith(rule, "!!GROUP=")) { regGetMatch(rule, group_regex, 3, 0, &target, &ret_real_rule); @@ -478,6 +482,77 @@ void proxyToClash(std::vector &nodes, YAML::Node &yamlnode, const ProxyGr if(x.Mtu > 0) singleproxy["mtu"] = x.Mtu; break; + case ProxyType::Hysteria: + singleproxy["type"] = "hysteria"; + if (!x.Ports.empty()) + singleproxy["ports"] = x.Ports; + if (!x.Protocol.empty()) + singleproxy["protocol"] = x.Protocol; + if (!x.OBFSParam.empty()) + singleproxy["obfs-protocol"] = x.OBFSParam; + if (!x.Up.empty()) + singleproxy["up"] = x.Up; + if (x.UpSpeed) + singleproxy["up-speed"] = x.UpSpeed; + if (!x.Down.empty()) + singleproxy["down"] = x.Down; + if (x.DownSpeed) + singleproxy["down-speed"] = x.DownSpeed; + if (!x.AuthStr.empty()) + { + singleproxy["auth-str"] = x.AuthStr; + singleproxy["auth"] = base64Encode(x.AuthStr); + } + if (!x.OBFS.empty()) + singleproxy["obfs"] = x.OBFS; + if (!x.SNI.empty()) + singleproxy["sni"] = x.SNI; + if (!scv.is_undef()) + singleproxy["skip-cert-verify"] = scv.get(); + if (!x.Fingerprint.empty()) + singleproxy["fingerprint"] = x.Fingerprint; + if (!x.Alpn.empty()) + singleproxy["alpn"] = x.Alpn; + if (!x.Ca.empty()) + singleproxy["ca-str"] = fileGet(x.Ca); + if (!x.CaStr.empty()) + singleproxy["ca-str"] = x.CaStr; + if (x.RecvWindowConn) + singleproxy["recv-window-conn"] = x.RecvWindowConn; + if (x.RecvWindow) + singleproxy["recv-window"] = x.RecvWindow; + if (!x.DisableMtuDiscovery.is_undef()) + singleproxy["disable-mtu-discovery"] = x.DisableMtuDiscovery.get(); + if (!x.TCPFastOpen.is_undef()) + singleproxy["fast-open"] = x.TCPFastOpen.get(); + if (x.HopInterval) + singleproxy["hop-interval"] = x.HopInterval; + break; + case ProxyType::Hysteria2: + singleproxy["type"] = "hysteria2"; + if (!x.Up.empty()) + singleproxy["up"] = x.UpSpeed; + if (!x.Down.empty()) + singleproxy["down"] = x.DownSpeed; + if (!x.Password.empty()) + singleproxy["password"] = x.Password; + if (!x.OBFS.empty()) + singleproxy["obfs"] = x.OBFS; + if (!x.OBFSParam.empty()) + singleproxy["obfs-password"] = x.OBFSParam; + if (!x.SNI.empty()) + singleproxy["sni"] = x.SNI; + if (!scv.is_undef()) + singleproxy["skip-cert-verify"] = scv.get(); + if (!x.Alpn.empty()) + singleproxy["alpn"] = x.Alpn; + if (!x.Ca.empty()) + singleproxy["ca-str"] = fileGet(x.Ca); + if (!x.CaStr.empty()) + singleproxy["ca-str"] = x.CaStr; + if (x.CWND) + singleproxy["cwnd"] = x.CWND; + break; default: continue; } @@ -852,6 +927,20 @@ std::string proxyToSurge(std::vector &nodes, const std::string &base_conf ini.set(real_section, "keepalive", std::to_string(x.KeepAlive)); ini.set(real_section, "peer", "(" + generatePeer(x) + ")"); break; + case ProxyType::Hysteria2: + if(surge_ver < 4) + continue; + proxy = "hysteria, " + hostname + ", " + port + ", password=" + password; + if(x.DownSpeed) + proxy += ", download-bandwidth=" + x.DownSpeed; + + if(!scv.is_undef()) + proxy += ",skip-cert-verify=" + std::string(scv.get() ? "true" : "false"); + if(!x.Fingerprint.empty()) + proxy += ",server-cert-fingerprint-sha256=" + x.Fingerprint; + if(!x.SNI.empty()) + proxy += ",sni=" + x.SNI; + break; default: continue; } @@ -2156,7 +2245,6 @@ void proxyToSingBox(std::vector &nodes, rapidjson::Document &json, std::v udp.define(x.UDP); tfo.define(x.TCPFastOpen); scv.define(x.AllowInsecure); - rapidjson::Value proxy(rapidjson::kObjectType); switch (x.Type) { @@ -2243,6 +2331,92 @@ void proxyToSingBox(std::vector &nodes, rapidjson::Document &json, std::v proxy.AddMember("mtu", x.Mtu, allocator); break; } + case ProxyType::Hysteria: + { + addSingBoxCommonMembers(proxy, x, "hysteria", allocator); + if (!x.Up.empty()) + proxy.AddMember("up_mbps", x.UpSpeed, allocator); + if (!x.Down.empty()) + proxy.AddMember("down_mbps", x.DownSpeed, allocator); + if (!x.OBFS.empty()) + { + proxy.AddMember("obfs", rapidjson::StringRef(x.OBFS.c_str()), allocator); + } + + if (!x.AuthStr.empty()) + { + proxy.AddMember("auth_str", rapidjson::StringRef(x.AuthStr.c_str()), allocator); + rapidjson::Value auth_str; + auth_str.SetString(base64Encode(x.AuthStr).c_str(), allocator); + proxy.AddMember("auth", auth_str, allocator); + } + if (x.RecvWindowConn) + proxy.AddMember("recv_window_conn", x.RecvWindowConn, allocator); + if (x.RecvWindow) + proxy.AddMember("recv_window", x.RecvWindow, allocator); + if (!x.DisableMtuDiscovery.is_undef()) + proxy.AddMember("disable_mtu_discovery", x.DisableMtuDiscovery.get(), allocator); + + rapidjson::Value tls(rapidjson::kObjectType); + tls.AddMember("enabled", true, allocator); + if (!scv.is_undef()) + tls.AddMember("insecure", scv.get(), allocator); + if (!x.Alpn.empty()) + { + rapidjson::Value alpn(rapidjson::kArrayType); + alpn.PushBack(rapidjson::StringRef(x.Alpn[0].c_str()), allocator); + tls.AddMember("alpn", alpn, allocator); + } + if (!x.Ca.empty()) + { + rapidjson::Value ca_str; + ca_str.SetString(fileGet(x.Ca).c_str(), allocator); + tls.AddMember("certificate", ca_str, allocator); + } + if (!x.CaStr.empty()) + tls.AddMember("certificate", rapidjson::StringRef(x.CaStr.c_str()), allocator); + proxy.AddMember("tls", tls, allocator); + break; + } + case ProxyType::Hysteria2: + { + addSingBoxCommonMembers(proxy, x, "hysteria2", allocator); + if (!x.Up.empty()) + proxy.AddMember("up_mbps", x.UpSpeed, allocator); + if (!x.Down.empty()) + proxy.AddMember("down_mbps", x.DownSpeed, allocator); + if (!x.OBFS.empty()) + { + rapidjson::Value obfs(rapidjson::kObjectType); + obfs.AddMember("type", rapidjson::StringRef(x.OBFS.c_str()), allocator); + if (!x.OBFSParam.empty()) + obfs.AddMember("password", rapidjson::StringRef(x.OBFSParam.c_str()), allocator); + proxy.AddMember("obfs", obfs, allocator); + } + if (!x.Password.empty()) + proxy.AddMember("password", rapidjson::StringRef(x.Password.c_str()), allocator); + + rapidjson::Value tls(rapidjson::kObjectType); + tls.AddMember("enabled", true, allocator); + if (!scv.is_undef()) + tls.AddMember("insecure", scv.get(), allocator); + if (!x.Alpn.empty()) + { + rapidjson::Value alpn(rapidjson::kArrayType); + alpn.PushBack(rapidjson::StringRef(x.Alpn[0].c_str()), allocator); + tls.AddMember("alpn", alpn, allocator); + } + if (!x.Ca.empty()) + { + rapidjson::Value ca_str(rapidjson::kStringType); + ca_str.SetString(fileGet(x.Ca).c_str(), allocator); + tls.AddMember("certificate", ca_str, allocator); + } + if (!x.CaStr.empty()) + tls.AddMember("certificate", rapidjson::StringRef(x.CaStr.c_str()), allocator); + proxy.AddMember("tls", tls, allocator); + break; + } case ProxyType::HTTP: case ProxyType::HTTPS: { diff --git a/src/parser/config/proxy.h b/src/parser/config/proxy.h index fd0f94f09..928cb1f1a 100644 --- a/src/parser/config/proxy.h +++ b/src/parser/config/proxy.h @@ -20,7 +20,9 @@ enum class ProxyType HTTP, HTTPS, SOCKS5, - WireGuard + WireGuard, + Hysteria, + Hysteria2 }; inline String getProxyTypeName(ProxyType type) @@ -43,6 +45,12 @@ inline String getProxyTypeName(ProxyType type) return "HTTPS"; case ProxyType::SOCKS5: return "SOCKS5"; + case ProxyType::WireGuard: + return "WireGuard"; + case ProxyType::Hysteria: + return "Hysteria"; + case ProxyType::Hysteria2: + return "Hysteria2"; default: return "Unknown"; } @@ -99,6 +107,24 @@ struct Proxy uint16_t KeepAlive = 0; String TestUrl; String ClientId; + + String Ports; + String Up; + uint32_t UpSpeed; + String Down; + uint32_t DownSpeed; + String AuthStr; + String SNI; + String Fingerprint; + String Ca; + String CaStr; + uint32_t RecvWindowConn; + uint32_t RecvWindow; + tribool DisableMtuDiscovery; + uint32_t HopInterval; + StringArray Alpn; + + uint32_t CWND = 0; }; #define SS_DEFAULT_GROUP "SSProvider" @@ -109,5 +135,7 @@ struct Proxy #define TROJAN_DEFAULT_GROUP "TrojanProvider" #define SNELL_DEFAULT_GROUP "SnellProvider" #define WG_DEFAULT_GROUP "WireGuardProvider" +#define HYSTERIA_DEFAULT_GROUP "HysteriaProvider" +#define HYSTERIA2_DEFAULT_GROUP "Hysteria2Provider" #endif // PROXY_H_INCLUDED diff --git a/src/parser/subparser.cpp b/src/parser/subparser.cpp index 9f85692b5..3ac0312a9 100644 --- a/src/parser/subparser.cpp +++ b/src/parser/subparser.cpp @@ -130,6 +130,100 @@ void wireguardConstruct(Proxy &node, const std::string &group, const std::string node.ClientId = clientId; } +void hysteriaConstruct( + Proxy &node, + const std::string &group, + const std::string &remarks, + const std::string &server, + const std::string &port, + const std::string &ports, + const std::string &protocol, + const std::string &obfs_protocol, + const std::string &up, + const std::string &up_speed, + const std::string &down, + const std::string &down_speed, + const std::string &auth, + const std::string &auth_str, + const std::string &obfs, + const std::string &sni, + const std::string &fingerprint, + const std::string &ca, + const std::string &ca_str, + const std::string &recv_window_conn, + const std::string &recv_window, + const std::string &disable_mtu_discovery, + const std::string &hop_interval, + const std::string &alpn, + tribool tfo, + tribool scv +) { + commonConstruct(node, ProxyType::Hysteria, group, remarks, server, port, tribool(), tfo, scv, tribool()); + node.Ports = ports; + node.Protocol = protocol; + node.OBFSParam = obfs_protocol; + if (!up.empty()) + { + if (up.length() > 4 && up.find("bps") == up.length() - 3) + + node.Up = up; + else if (to_int(up)) + { + node.UpSpeed = to_int(up); + node.Up = up + " Mbps"; + } + } + if (!up_speed.empty()) + node.UpSpeed = to_int(up_speed); + if (!down.empty()) + { + if (down.length() > 4 && down.find("bps") == down.length() - 3) + node.Down = down; + else if (to_int(down)) + { + node.DownSpeed = to_int(down); + node.Down = down + " Mbps"; + } + } + if (!down_speed.empty()) + node.DownSpeed = to_int(down_speed); + node.AuthStr = auth_str; + if (!auth.empty()) + node.AuthStr = base64Decode(auth); + node.OBFS = obfs; + node.SNI = sni; + node.Fingerprint = fingerprint; + node.Ca = ca; + node.CaStr = ca_str; + node.RecvWindowConn = to_int(recv_window_conn); + node.RecvWindow = to_int(recv_window); + node.DisableMtuDiscovery = disable_mtu_discovery; + node.HopInterval = to_int(hop_interval); + if (!alpn.empty()) + { + node.Alpn = StringArray {alpn}; + } +} + +void hysteria2Construct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server, const std::string &port,const std::string &up, const std::string &down, const std::string &password, const std::string &obfs, const std::string &obfs_password, const std::string &sni, const std::string &fingerprint, const std::string &alpn, const std::string &ca, const std::string &ca_str, const std::string &cwnd, tribool tfo, tribool scv) { + commonConstruct(node, ProxyType::Hysteria2, group, remarks, server, port, tribool(), tfo, scv, tribool()); + node.UpSpeed = to_int(up); + node.DownSpeed = to_int(down); + node.Password = password; + node.OBFS = obfs; + node.OBFSParam = obfs_password; + node.SNI = sni; + node.Fingerprint = fingerprint; + if (!alpn.empty()) + { + node.Alpn = StringArray {alpn}; + } + node.Ca = ca; + node.CaStr = ca_str; + node.CWND = to_int(cwnd); + +} + void explodeVmess(std::string vmess, Proxy &node) { std::string version, ps, add, port, type, id, aid, net, path, host, tls, sni; @@ -979,6 +1073,8 @@ void explodeClash(Node yamlnode, std::vector &nodes) std::string protocol, protoparam, obfs, obfsparam; //ssr std::string user; //socks std::string ip, ipv6, private_key, public_key, mtu; //wireguard + std::string ports, obfs_protocol, up, up_speed, down, down_speed, auth, auth_str,/* obfs, sni,*/ fingerprint, ca, ca_str, recv_window_conn, recv_window, disable_mtu_discovery, hop_interval, alpn; //hysteria + std::string obfs_password, cwnd; //hysteria2 string_array dns_server; tribool udp, tfo, scv; Node singleproxy; @@ -995,6 +1091,7 @@ void explodeClash(Node yamlnode, std::vector &nodes) if(port.empty() || port == "0") continue; udp = safe_as(singleproxy["udp"]); + tfo = safe_as(singleproxy["fast-open"]); scv = safe_as(singleproxy["skip-cert-verify"]); switch(hash_(proxytype)) { @@ -1190,6 +1287,59 @@ void explodeClash(Node yamlnode, std::vector &nodes) wireguardConstruct(node, group, ps, server, port, ip, ipv6, private_key, public_key, password, dns_server, mtu, "0", "", "", udp); break; + case "hysteria"_hash: + group = HYSTERIA_DEFAULT_GROUP; + singleproxy["ports"] >>= ports; + singleproxy["protocol"] >>= protocol; + singleproxy["obfs-protocol"] >>= obfs_protocol; + singleproxy["up"] >>= up; + singleproxy["up-speed"] >>= up_speed; + singleproxy["down"] >>= down; + singleproxy["down-speed"] >>= down_speed; + singleproxy["auth"] >>= auth; + singleproxy["auth-str"] >>= auth_str; + if (auth_str.empty()) + singleproxy["auth_str"] >>= auth_str; + singleproxy["obfs"] >>= obfs; + singleproxy["sni"] >>= sni; + singleproxy["fingerprint"] >>= fingerprint; + if (singleproxy["alpn"].IsSequence()) + singleproxy["alpn"][0] >>= alpn; + else + singleproxy["alpn"] >>= alpn; + singleproxy["ca"] >>= ca; + singleproxy["ca-str"] >>= ca_str; + singleproxy["recv-window-conn"] >>= recv_window_conn; + singleproxy["recv-window"] >>= recv_window; + singleproxy["disable-mtu-discovery"] >>= disable_mtu_discovery; + if (disable_mtu_discovery.empty()) + singleproxy["disable_mtu_discovery"] >>= disable_mtu_discovery; + singleproxy["hop-interval"] >>= hop_interval; + + hysteriaConstruct(node, group, ps, server, port, ports, protocol, obfs_protocol, up, up_speed, down, down_speed, auth, auth_str, obfs, sni, fingerprint, ca, ca_str, recv_window_conn, recv_window, disable_mtu_discovery, hop_interval, alpn, tfo, scv); + break; + case "hysteria2"_hash: + group = HYSTERIA2_DEFAULT_GROUP; + singleproxy["up"] >>= up; + singleproxy["down"] >>= down; + singleproxy["password"] >>= password; + if (password.empty()) + singleproxy["auth"] >>= password; + singleproxy["obfs"] >>= obfs; + singleproxy["obfs-password"] >>= obfs_password; + singleproxy["sni"] >>= sni; + singleproxy["fingerprint"] >>= fingerprint; + if (singleproxy["alpn"].IsSequence()) + singleproxy["alpn"][0] >>= alpn; + else + singleproxy["alpn"] >>= alpn; + singleproxy["ca"] >>= ca; + singleproxy["ca-str"] >>= ca_str; + singleproxy["cwnd"] >>= cwnd; + + hysteria2Construct(node, group, ps, server, port, up, down, password, obfs, obfs_password, sni, fingerprint, alpn, ca, ca_str, cwnd, tfo, scv ); + break; + default: continue; } @@ -1325,6 +1475,68 @@ void explodeKitsunebi(std::string kit, Proxy &node) vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, add, port, type, id, aid, net, cipher, path, host, "", tls, ""); } + +void explodeStdHysteria2(std::string hysteria2, Proxy &node) { + std::string add, port, password, host, insecure, up, down, alpn, obfs, obfs_password, remarks, sni, fingerprint; + std::string addition; + tribool scv; + hysteria2 = hysteria2.substr(12); + string_size pos; + + pos = hysteria2.rfind("#"); + if (pos != hysteria2.npos) { + remarks = urlDecode(hysteria2.substr(pos + 1)); + hysteria2.erase(pos); + } + + pos = hysteria2.rfind("?"); + if (pos != hysteria2.npos) { + addition = hysteria2.substr(pos + 1); + hysteria2.erase(pos); + } + + if (strFind(hysteria2, "@")) { + if (regGetMatch(hysteria2, R"(^(.*?)@(.*)[:](\d+)$)", 4, 0, &password, &add, &port)) + return; + } else { + password = getUrlArg(addition, "password"); + if (password.empty()) + return; + + if (!strFind(hysteria2, ":")) + return; + + if (regGetMatch(hysteria2, R"(^(.*)[:](\d+)$)", 3, 0, &add, &port)) + return; + } + + scv = getUrlArg(addition, "insecure"); + up = getUrlArg(addition, "up"); + down = getUrlArg(addition, "down"); + // the alpn is not supported officially yet + alpn = getUrlArg(addition, "alpn"); + obfs = getUrlArg(addition, "obfs"); + obfs_password = getUrlArg(addition, "obfs-password"); + sni = getUrlArg(addition, "sni"); + fingerprint = getUrlArg(addition, "pinSHA256"); + if (remarks.empty()) + remarks = add + ":" + port; + + hysteria2Construct(node, HYSTERIA2_DEFAULT_GROUP, remarks, add, port, up, down, password, obfs, obfs_password, sni, fingerprint, "", "", "", "", tribool(), scv); + return; +} + +void explodeHysteria2(std::string hysteria2, Proxy &node) { + hysteria2 = regReplace(hysteria2, "(hysteria2|hy2)://", "hysteria2://"); + + // replace /? with ? + hysteria2 = regReplace(hysteria2, "/\\?", "?", true, false); + if (regMatch(hysteria2, "hysteria2://(.*?)[:](.*)")) { + explodeStdHysteria2(hysteria2, node); + return; + } +} + // peer = (public-key = bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=, allowed-ips = "0.0.0.0/0, ::/0", endpoint = engage.cloudflareclient.com:2408, client-id = 139/184/125),(public-key = bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=, endpoint = engage.cloudflareclient.com:2408) void parsePeers(Proxy &node, const std::string &data) { @@ -2220,6 +2432,8 @@ void explode(const std::string &link, Proxy &node) explodeNetch(link, node); else if(startsWith(link, "trojan://")) explodeTrojan(link, node); + else if (strFind(link, "hysteria2://") || strFind(link, "hy2://")) + explodeHysteria2(link, node); else if(isLink(link)) explodeHTTPSub(link, node); } diff --git a/src/parser/subparser.h b/src/parser/subparser.h index 5d236a901..9a7c82be8 100644 --- a/src/parser/subparser.h +++ b/src/parser/subparser.h @@ -27,6 +27,38 @@ void socksConstruct(Proxy &node, const std::string &group, const std::string &re void httpConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &username, const std::string &password, bool tls, tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool()); void trojanConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &password, const std::string &network, const std::string &host, const std::string &path, bool tlssecure, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool()); void snellConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &password, const std::string &obfs, const std::string &host, uint16_t version = 0, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool()); + +void hysteriaConstruct( + Proxy &node, + const std::string &group, + const std::string &remarks, + const std::string &server, + const std::string &port, + const std::string &ports, + const std::string &protocol, + const std::string &obfs_protocol, + const std::string &up, + const std::string &up_speed, + const std::string &down, + const std::string &down_speed, + const std::string &auth, + const std::string &auth_str, + const std::string &obfs, + const std::string &sni, + const std::string &fingerprint, + const std::string &ca, + const std::string &ca_str, + const std::string &recv_window_conn, + const std::string &recv_window, + const std::string &disable_mtu_discovery, + const std::string &hop_interval, + const string_array &alpn, + tribool tfo, + tribool scv +); + +void hysteria2Construct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server, const std::string &port,const std::string &up, const std::string &down, const std::string &password, const std::string &obfs, const std::string &obfs_password, const std::string &sni, const std::string &fingerprint, const string_array &alpn, const std::string &ca, const std::string &caStr, const std::string &cwnd, tribool tfo, tribool scv); + void explodeVmess(std::string vmess, Proxy &node); void explodeSSR(std::string ssr, Proxy &node); void explodeSS(std::string ss, Proxy &node); @@ -35,6 +67,8 @@ void explodeQuan(const std::string &quan, Proxy &node); void explodeStdVMess(std::string vmess, Proxy &node); void explodeShadowrocket(std::string kit, Proxy &node); void explodeKitsunebi(std::string kit, Proxy &node); +void explodeHysteria2(std::string hysteria2, Proxy &node); + /// Parse a link void explode(const std::string &link, Proxy &node); void explodeSSD(std::string link, std::vector &nodes); From a5976cf7d32c66cabdd913f933b66fe23d183b6b Mon Sep 17 00:00:00 2001 From: Lai Zenan Date: Mon, 9 Sep 2024 04:25:16 +0800 Subject: [PATCH 2/7] fix: remove fileGet in subexport.cpp for security issue --- scripts/build.windows.release.sh | 2 +- src/generator/config/subexport.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/build.windows.release.sh b/scripts/build.windows.release.sh index 5de4c8dc3..159cfb6f5 100644 --- a/scripts/build.windows.release.sh +++ b/scripts/build.windows.release.sh @@ -38,7 +38,7 @@ cmake -DRAPIDJSON_BUILD_DOC=OFF -DRAPIDJSON_BUILD_EXAMPLES=OFF -DRAPIDJSON_BUILD make install -j4 cd .. -git clone https://github.com/ToruNiina/toml11 --depth=1 +git clone https://github.com/ToruNiina/toml11 --branch v3.8.1 --depth=1 cd toml11 cmake -DCMAKE_INSTALL_PREFIX="$MINGW_PREFIX" -G "Unix Makefiles" -DCMAKE_CXX_STANDARD=11 . make install -j4 diff --git a/src/generator/config/subexport.cpp b/src/generator/config/subexport.cpp index 20c8a265e..58be7fb9c 100644 --- a/src/generator/config/subexport.cpp +++ b/src/generator/config/subexport.cpp @@ -514,7 +514,7 @@ void proxyToClash(std::vector &nodes, YAML::Node &yamlnode, const ProxyGr if (!x.Alpn.empty()) singleproxy["alpn"] = x.Alpn; if (!x.Ca.empty()) - singleproxy["ca-str"] = fileGet(x.Ca); + singleproxy["ca"] = x.Ca; if (!x.CaStr.empty()) singleproxy["ca-str"] = x.CaStr; if (x.RecvWindowConn) @@ -547,7 +547,7 @@ void proxyToClash(std::vector &nodes, YAML::Node &yamlnode, const ProxyGr if (!x.Alpn.empty()) singleproxy["alpn"] = x.Alpn; if (!x.Ca.empty()) - singleproxy["ca-str"] = fileGet(x.Ca); + singleproxy["ca"] = x.Ca; if (!x.CaStr.empty()) singleproxy["ca-str"] = x.CaStr; if (x.CWND) From 7b54498e56982d7087fbba88a693e4438ff85d52 Mon Sep 17 00:00:00 2001 From: Lai Zenan Date: Mon, 9 Sep 2024 04:25:16 +0800 Subject: [PATCH 3/7] fix: remove fileGet in subexport.cpp for security issue --- src/generator/config/subexport.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/generator/config/subexport.cpp b/src/generator/config/subexport.cpp index 58be7fb9c..03916200e 100644 --- a/src/generator/config/subexport.cpp +++ b/src/generator/config/subexport.cpp @@ -2370,7 +2370,7 @@ void proxyToSingBox(std::vector &nodes, rapidjson::Document &json, std::v if (!x.Ca.empty()) { rapidjson::Value ca_str; - ca_str.SetString(fileGet(x.Ca).c_str(), allocator); + ca_str.SetString(x.Ca.c_str(), allocator); tls.AddMember("certificate", ca_str, allocator); } if (!x.CaStr.empty()) @@ -2409,7 +2409,7 @@ void proxyToSingBox(std::vector &nodes, rapidjson::Document &json, std::v if (!x.Ca.empty()) { rapidjson::Value ca_str(rapidjson::kStringType); - ca_str.SetString(fileGet(x.Ca).c_str(), allocator); + ca_str.SetString(x.Ca.c_str(), allocator); tls.AddMember("certificate", ca_str, allocator); } if (!x.CaStr.empty()) From f648b5880848642ac8d19d3447c26d2568ef2302 Mon Sep 17 00:00:00 2001 From: Tindy X <49061470+tindy2013@users.noreply.github.com> Date: Fri, 29 Nov 2024 00:27:56 +0800 Subject: [PATCH 4/7] Fix build error --- scripts/build.macos.release.sh | 2 +- src/parser/subparser.cpp | 13 +++++++------ src/parser/subparser.h | 5 +++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/scripts/build.macos.release.sh b/scripts/build.macos.release.sh index 529f7c131..e554c9964 100644 --- a/scripts/build.macos.release.sh +++ b/scripts/build.macos.release.sh @@ -41,7 +41,7 @@ sudo install -d /usr/local/include/date/ sudo install -m644 libcron/externals/date/include/date/* /usr/local/include/date/ cd .. -git clone https://github.com/ToruNiina/toml11 --depth=1 +git clone https://github.com/ToruNiina/toml11 --branch="v3.7.1" --depth=1 cd toml11 cmake -DCMAKE_CXX_STANDARD=11 . sudo make install -j6 > /dev/null diff --git a/src/parser/subparser.cpp b/src/parser/subparser.cpp index f2546fe71..45c41f137 100644 --- a/src/parser/subparser.cpp +++ b/src/parser/subparser.cpp @@ -158,9 +158,10 @@ void hysteriaConstruct( const std::string &hop_interval, const std::string &alpn, tribool tfo, - tribool scv + tribool scv, + const std::string &underlying_proxy = "" ) { - commonConstruct(node, ProxyType::Hysteria, group, remarks, server, port, tribool(), tfo, scv, tribool()); + commonConstruct(node, ProxyType::Hysteria, group, remarks, server, port, tribool(), tfo, scv, tribool(), underlying_proxy); node.Ports = ports; node.Protocol = protocol; node.OBFSParam = obfs_protocol; @@ -207,8 +208,8 @@ void hysteriaConstruct( } } -void hysteria2Construct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server, const std::string &port,const std::string &up, const std::string &down, const std::string &password, const std::string &obfs, const std::string &obfs_password, const std::string &sni, const std::string &fingerprint, const std::string &alpn, const std::string &ca, const std::string &ca_str, const std::string &cwnd, tribool tfo, tribool scv) { - commonConstruct(node, ProxyType::Hysteria2, group, remarks, server, port, tribool(), tfo, scv, tribool()); +void hysteria2Construct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server, const std::string &port,const std::string &up, const std::string &down, const std::string &password, const std::string &obfs, const std::string &obfs_password, const std::string &sni, const std::string &fingerprint, const std::string &alpn, const std::string &ca, const std::string &ca_str, const std::string &cwnd, tribool tfo, tribool scv, const std::string &underlying_proxy) { + commonConstruct(node, ProxyType::Hysteria2, group, remarks, server, port, tribool(), tfo, scv, tribool(), underlying_proxy); node.UpSpeed = to_int(up); node.DownSpeed = to_int(down); node.Password = password; @@ -1319,7 +1320,7 @@ void explodeClash(Node yamlnode, std::vector &nodes) singleproxy["disable_mtu_discovery"] >>= disable_mtu_discovery; singleproxy["hop-interval"] >>= hop_interval; - hysteriaConstruct(node, group, ps, server, port, ports, protocol, obfs_protocol, up, up_speed, down, down_speed, auth, auth_str, obfs, sni, fingerprint, ca, ca_str, recv_window_conn, recv_window, disable_mtu_discovery, hop_interval, alpn, tfo, scv); + hysteriaConstruct(node, group, ps, server, port, ports, protocol, obfs_protocol, up, up_speed, down, down_speed, auth, auth_str, obfs, sni, fingerprint, ca, ca_str, recv_window_conn, recv_window, disable_mtu_discovery, hop_interval, alpn, tfo, scv, underlying_proxy); break; case "hysteria2"_hash: group = HYSTERIA2_DEFAULT_GROUP; @@ -1340,7 +1341,7 @@ void explodeClash(Node yamlnode, std::vector &nodes) singleproxy["ca-str"] >>= ca_str; singleproxy["cwnd"] >>= cwnd; - hysteria2Construct(node, group, ps, server, port, up, down, password, obfs, obfs_password, sni, fingerprint, alpn, ca, ca_str, cwnd, tfo, scv ); + hysteria2Construct(node, group, ps, server, port, up, down, password, obfs, obfs_password, sni, fingerprint, alpn, ca, ca_str, cwnd, tfo, scv, underlying_proxy); break; default: diff --git a/src/parser/subparser.h b/src/parser/subparser.h index 0f54f1203..53e1d6ccf 100644 --- a/src/parser/subparser.h +++ b/src/parser/subparser.h @@ -54,10 +54,11 @@ void hysteriaConstruct( const std::string &hop_interval, const string_array &alpn, tribool tfo, - tribool scv + tribool scv, + const std::string &underlying_proxy = "" ); -void hysteria2Construct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server, const std::string &port,const std::string &up, const std::string &down, const std::string &password, const std::string &obfs, const std::string &obfs_password, const std::string &sni, const std::string &fingerprint, const string_array &alpn, const std::string &ca, const std::string &caStr, const std::string &cwnd, tribool tfo, tribool scv); +void hysteria2Construct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &server, const std::string &port,const std::string &up, const std::string &down, const std::string &password, const std::string &obfs, const std::string &obfs_password, const std::string &sni, const std::string &fingerprint, const string_array &alpn, const std::string &ca, const std::string &caStr, const std::string &cwnd, tribool tfo, tribool scv, const std::string &underlying_proxy = ""); void explodeVmess(std::string vmess, Proxy &node); void explodeSSR(std::string ssr, Proxy &node); From b9e08ccccf95021b4ccd6af8e5ba6219e435234e Mon Sep 17 00:00:00 2001 From: Tindy X <49061470+tindy2013@users.noreply.github.com> Date: Fri, 29 Nov 2024 00:41:22 +0800 Subject: [PATCH 5/7] Fix build error --- scripts/build.alpine.release.sh | 2 +- scripts/build.windows.release.sh | 2 +- src/parser/subparser.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/build.alpine.release.sh b/scripts/build.alpine.release.sh index c159737a1..2dba424fe 100644 --- a/scripts/build.alpine.release.sh +++ b/scripts/build.alpine.release.sh @@ -4,7 +4,7 @@ set -xe apk add gcc g++ build-base linux-headers cmake make autoconf automake libtool python2 python3 apk add mbedtls-dev mbedtls-static zlib-dev rapidjson-dev zlib-static pcre2-dev -git clone https://github.com/curl/curl --depth=1 --branch curl-8_4_0 +git clone https://github.com/curl/curl --depth=1 --branch curl-8_6_0 cd curl cmake -DCURL_USE_MBEDTLS=ON -DHTTP_ONLY=ON -DBUILD_TESTING=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_USE_LIBSSH2=OFF -DBUILD_CURL_EXE=OFF . > /dev/null make install -j2 > /dev/null diff --git a/scripts/build.windows.release.sh b/scripts/build.windows.release.sh index 159cfb6f5..2b3e49bb6 100644 --- a/scripts/build.windows.release.sh +++ b/scripts/build.windows.release.sh @@ -1,7 +1,7 @@ #!/bin/bash set -xe -git clone https://github.com/curl/curl --depth=1 --branch curl-8_4_0 +git clone https://github.com/curl/curl --depth=1 --branch curl-8_6_0 cd curl cmake -DCMAKE_BUILD_TYPE=Release -DCURL_USE_LIBSSH2=OFF -DHTTP_ONLY=ON -DCURL_USE_SCHANNEL=ON -DBUILD_SHARED_LIBS=OFF -DBUILD_CURL_EXE=OFF -DCMAKE_INSTALL_PREFIX="$MINGW_PREFIX" -G "Unix Makefiles" -DHAVE_LIBIDN2=OFF -DCURL_USE_LIBPSL=OFF . make install -j4 diff --git a/src/parser/subparser.cpp b/src/parser/subparser.cpp index 45c41f137..3db01ba9d 100644 --- a/src/parser/subparser.cpp +++ b/src/parser/subparser.cpp @@ -1526,7 +1526,7 @@ void explodeStdHysteria2(std::string hysteria2, Proxy &node) { if (remarks.empty()) remarks = add + ":" + port; - hysteria2Construct(node, HYSTERIA2_DEFAULT_GROUP, remarks, add, port, up, down, password, obfs, obfs_password, sni, fingerprint, "", "", "", "", tribool(), scv); + hysteria2Construct(node, HYSTERIA2_DEFAULT_GROUP, remarks, add, port, up, down, password, obfs, obfs_password, sni, fingerprint, "", "", "", "", tribool(), scv, "", ""); return; } From 5fc78b98e5d848a62008ec46ef85b3b87b7a5aad Mon Sep 17 00:00:00 2001 From: Tindy X <49061470+tindy2013@users.noreply.github.com> Date: Fri, 29 Nov 2024 00:45:44 +0800 Subject: [PATCH 6/7] Fix build error --- src/parser/subparser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parser/subparser.cpp b/src/parser/subparser.cpp index 3db01ba9d..ca29ecec1 100644 --- a/src/parser/subparser.cpp +++ b/src/parser/subparser.cpp @@ -1526,7 +1526,7 @@ void explodeStdHysteria2(std::string hysteria2, Proxy &node) { if (remarks.empty()) remarks = add + ":" + port; - hysteria2Construct(node, HYSTERIA2_DEFAULT_GROUP, remarks, add, port, up, down, password, obfs, obfs_password, sni, fingerprint, "", "", "", "", tribool(), scv, "", ""); + hysteria2Construct(node, HYSTERIA2_DEFAULT_GROUP, remarks, add, port, up, down, password, obfs, obfs_password, sni, fingerprint, "", "", "", "", tribool(), scv, ""); return; } From 2dbab6f55dae66f334f1fe75f8be1b264193a1d2 Mon Sep 17 00:00:00 2001 From: Tindy X <49061470+tindy2013@users.noreply.github.com> Date: Fri, 29 Nov 2024 00:48:05 +0800 Subject: [PATCH 7/7] Remove deleted rules repository --- scripts/rules_config.conf | 5 ----- 1 file changed, 5 deletions(-) diff --git a/scripts/rules_config.conf b/scripts/rules_config.conf index 7cc677072..65a3b0d86 100644 --- a/scripts/rules_config.conf +++ b/scripts/rules_config.conf @@ -12,11 +12,6 @@ match=Clash/config/** dest=base/config/ keep_tree=false -[DivineEngine] -url=https://github.com/DivineEngine/Profiles -commit=f4d75f7d48a3f42129e030bef751d4d22bca02da -match=Surge/Ruleset/** - [NobyDa] url=https://github.com/NobyDa/Script branch=master