Browse Source

Enhancements

Add 1MB file download size limit to prevent feeding a large file to the processor.
Add file scope limit to rule_base options in external config to prevent loading sensitive files as rule base.
Add support for generating Clash DOMAIN/IP-CIDR rule-providers.
Optimize codes.
Tindy X 5 năm trước cách đây
mục cha
commit
40bb4276d7
5 tập tin đã thay đổi với 76 bổ sung24 xóa
  1. 1 0
      base/pref-new.yml
  2. 3 0
      base/pref.ini
  3. 57 22
      src/interfaces.cpp
  4. 5 1
      src/misc.h
  5. 10 1
      src/webget.cpp

+ 1 - 0
base/pref-new.yml

@@ -6,6 +6,7 @@ common:
   exclude_remarks: ["(到期|剩余流量|时间|官网|产品)"]
   include_remarks: []
   default_external_config: "" # config/example_external_config.yml
+  base_path: base
   clash_rule_base: base/all_base.tpl
   surge_rule_base: base/all_base.tpl
   surfboard_rule_base: base/all_base.tpl

+ 3 - 0
base/pref.ini

@@ -21,6 +21,9 @@ exclude_remarks=(到期|剩余流量|时间|官网|产品)
 ;Setting an external config file as default when none is specified, supports local files/URL
 ;default_external_config=config/example_external_config.ini
 
+;The file scope limit of the 'rule_base' options in external configs.
+base_path=base
+
 ;Clash config base used by the generator, supports local files/URL
 clash_rule_base=base/all_base.tpl
 

+ 57 - 22
src/interfaces.cpp

@@ -28,13 +28,13 @@ std::string listen_address = "127.0.0.1", default_url, insert_url, managed_confi
 int listen_port = 25500, max_pending_connections = 10, max_concurrent_threads = 4;
 bool api_mode = true, write_managed_config = false, enable_rule_generator = true, update_ruleset_on_request = false, overwrite_original_rules = true;
 bool print_debug_info = false, cfw_child_process = false, append_userinfo = true, enable_base_gen = false, async_fetch_ruleset = false;
-std::string access_token;
+std::string access_token, base_path = "base";
 extern std::string custom_group;
 extern int global_log_level;
 string_map aliases_map;
 
 //global variables for template
-std::string template_path;
+std::string template_path = "templates";
 string_map global_vars;
 
 //generator settings
@@ -96,11 +96,12 @@ const string_array quanx_rule_type = {basic_types, "USER-AGENT", "HOST", "HOST-S
 
 std::string getRuleset(RESPONSE_CALLBACK_ARGS)
 {
+    /// type: 1 for Surge, 2 for Quantumult X, 3 for Clash domain rule-provider, 4 for Clash ipcidr rule-provider
     std::string url = urlsafe_base64_decode(getUrlArg(argument, "url")), type = getUrlArg(argument, "type"), group = urlsafe_base64_decode(getUrlArg(argument, "group"));
     std::string output_content, dummy;
     int type_int = to_int(type, 0);
 
-    if(!url.size() || !type.size() || (type_int == 2 && !group.size()) || (type_int != 1 && type_int != 2))
+    if(!url.size() || !type.size() || (type_int == 2 && !group.size()) || (type_int < 1 && type_int > 4))
     {
         *status_code = 400;
         return "Invalid request!";
@@ -125,15 +126,49 @@ std::string getRuleset(RESPONSE_CALLBACK_ARGS)
 
     output_content.clear();
 
+    if(type_int == 3 || type_int == 4)
+        output_content = "payload:\n";
+
+    string_array vArray;
     while(getline(ss, strLine, delimiter))
     {
-        if(type_int == 2)
+        switch(type_int)
         {
+        case 2:
             if(!std::any_of(quanx_rule_type.begin(), quanx_rule_type.end(), [&strLine](std::string type){return startsWith(strLine, type);}) || startsWith(strLine, "IP-CIDR6"))
                 continue;
-        }
-        else if(!std::any_of(surge_rule_type.begin(), surge_rule_type.end(), [&strLine](std::string type){return startsWith(strLine, type);}))
+            break;
+        case 1:
+            if(!std::any_of(surge_rule_type.begin(), surge_rule_type.end(), [&strLine](std::string type){return startsWith(strLine, type);}))
+                continue;
+            break;
+        case 3:
+            if(!startsWith(strLine, "DOMAIN-SUFFIX,") && !startsWith(strLine, "DOMAIN,"))
+                continue;
+            vArray = split(strLine, ",");
+            if(vArray.size() < 2)
+                continue;
+            vArray[1] = regTrim(vArray[1]);
+            switch(hash_(vArray[0]))
+            {
+            case "DOMAIN-SUFFIX"_hash:
+                strLine = " - '." + vArray[1] + "'";
+                break;
+            case "DOMAIN"_hash:
+                strLine = " - '" + vArray[1] + "'";
+                break;
+            }
+            output_content += strLine + "\n";
+            continue;
+        case 4:
+            if(!startsWith(strLine, "IP-CIDR,") && !startsWith(strLine, "IP-CIDR6,"))
+                continue;
+            vArray = split(strLine, ",");
+            if(vArray.size() < 2)
+                continue;
+            output_content += " - " + vArray[1] + "\n";
             continue;
+        }
 
         lineSize = strLine.size();
         if(lineSize && strLine[lineSize - 1] == '\r') //remove line break
@@ -438,6 +473,7 @@ void readYAMLConf(YAML::Node &node)
         section["exclude_remarks"] >> def_exclude_remarks;
     if(section["include_remarks"].IsSequence())
         section["include_remarks"] >> def_include_remarks;
+    section["base_path"] >> base_path;
     section["clash_rule_base"] >> clash_rule_base;
     section["surge_rule_base"] >> surge_rule_base;
     section["surfboard_rule_base"] >> surfboard_rule_base;
@@ -667,6 +703,7 @@ void readConf()
         ini.GetAll("exclude_remarks", def_exclude_remarks);
     if(ini.ItemPrefixExist("include_remarks"))
         ini.GetAll("include_remarks", def_include_remarks);
+    ini.GetIfExist("base_path", base_path);
     ini.GetIfExist("clash_rule_base", clash_rule_base);
     ini.GetIfExist("surge_rule_base", surge_rule_base);
     ini.GetIfExist("surfboard_rule_base", surfboard_rule_base);
@@ -990,6 +1027,12 @@ int loadExternalConfig(std::string &path, ExternalConfig &ext)
     return 0;
 }
 
+void checkExternalBase(const std::string &path, std::string &dest)
+{
+    if(startsWith(path, "https://") || startsWith(path, "http://") || startsWith(path, "data:") || (startsWith(path, base_path) && fileExist(path)))
+        dest = path;
+}
+
 void generateBase()
 {
     if(!enable_base_gen)
@@ -1134,22 +1177,14 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS)
         loadExternalConfig(config, extconf);
         if(!ext.nodelist)
         {
-            if(extconf.clash_rule_base.size())
-                ext_clash_base = extconf.clash_rule_base;
-            if(extconf.surge_rule_base.size())
-                ext_surge_base = extconf.surge_rule_base;
-            if(extconf.surfboard_rule_base.size())
-                ext_surfboard_base = extconf.surfboard_rule_base;
-            if(extconf.mellow_rule_base.size())
-                ext_mellow_base = extconf.mellow_rule_base;
-            if(extconf.quan_rule_base.size())
-                ext_quan_base = extconf.quan_rule_base;
-            if(extconf.quanx_rule_base.size())
-                ext_quanx_base = extconf.quanx_rule_base;
-            if(extconf.loon_rule_base.size())
-                ext_loon_base = extconf.loon_rule_base;
-            if(extconf.sssub_rule_base.size())
-                ext_sssub_base = extconf.sssub_rule_base;
+            checkExternalBase(extconf.clash_rule_base, ext_clash_base);
+            checkExternalBase(extconf.surge_rule_base, ext_surge_base);
+            checkExternalBase(extconf.surfboard_rule_base, ext_surfboard_base);
+            checkExternalBase(extconf.mellow_rule_base, ext_mellow_base);
+            checkExternalBase(extconf.quan_rule_base, ext_quan_base);
+            checkExternalBase(extconf.quanx_rule_base, ext_quanx_base);
+            checkExternalBase(extconf.loon_rule_base, ext_loon_base);
+            checkExternalBase(extconf.sssub_rule_base, ext_sssub_base);
         }
         if(extconf.rename.size())
             ext.rename_array = extconf.rename;

+ 5 - 1
src/misc.h

@@ -16,6 +16,10 @@
 #define PATH_SLASH "//"
 #endif // _WIN32
 
+#define concat(a,b) a ## b
+#define do_concat(a,b) concat(a,b)
+#define defer(x) std::shared_ptr<void> do_concat(__defer_deleter_,__LINE__) (nullptr, [&](...){x});
+
 typedef std::string::size_type string_size;
 typedef std::vector<std::string> string_array;
 typedef std::map<std::string, std::string> string_map;
@@ -58,7 +62,7 @@ std::string speedCalc(double speed);
 std::string getMD5(const std::string &data);
 bool isIPv4(const std::string &address);
 bool isIPv6(const std::string &address);
-void urlParse(const std::string &url, std::string &host, std::string &path, int &port, bool &isTLS);
+void urlParse(std::string &url, std::string &host, std::string &path, int &port, bool &isTLS);
 void removeUTF8BOM(std::string &data);
 int shortAssemble(unsigned short num_a, unsigned short num_b);
 void shortDisassemble(int source, unsigned short &num_a, unsigned short &num_b);

+ 10 - 1
src/webget.cpp

@@ -45,17 +45,26 @@ static int writer(char *data, size_t size, size_t nmemb, std::string *writerData
     return size * nmemb;
 }
 
+static int size_checker(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
+{
+    if(dltotal > 1048576.0)
+        return 1;
+    return 0;
+}
+
 static inline void curl_set_common_options(CURL *curl_handle, const char *url)
 {
     curl_easy_setopt(curl_handle, CURLOPT_URL, url);
     curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, global_log_level == LOG_LEVEL_VERBOSE ? 1L : 0L);
-    curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1L);
+    curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 0L);
     curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1L);
     curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L);
     curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L);
     curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0L);
     curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, 15L);
     curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, user_agent_str.data());
+    curl_easy_setopt(curl_handle, CURLOPT_MAXFILESIZE, 1048576L);
+    curl_easy_setopt(curl_handle, CURLOPT_PROGRESSFUNCTION, size_checker);
 }
 
 static std::string curlGet(const std::string &url, const std::string &proxy, std::string &response_headers, CURLcode &return_code)