diff --git a/doc/admin-guide/plugins/maxmind_acl.en.rst b/doc/admin-guide/plugins/maxmind_acl.en.rst index bf56a86d947..ab1d9d86719 100644 --- a/doc/admin-guide/plugins/maxmind_acl.en.rst +++ b/doc/admin-guide/plugins/maxmind_acl.en.rst @@ -62,7 +62,8 @@ Rules You can mix and match the allow rules and deny rules, however deny rules will always take precedence so in the above case ``127.0.0.1`` would be denied. The IP rules can take either single IPs or cidr formatted rules. It will also accept IPv6 IP and ranges. -The regex portion can be added to both the allow and deny sections for creating allowable or deniable regexes. Each regex takes a country code first and a regex second. +The regex portion can be added to both the allow and deny sections for creating allowable or deniable regexes. Each regex takes a country code first and a regex second. The regex +operates on the entire original request URL, the pre-remapped fqdn and path. In the above example all requests from the US would be allowed except for those on ``txt`` and ``mp3`` files. More rules should be added as pairs, not as additions to existing lists. Currently the only rules available are ``country``, ``ip``, and ``regex``, though more can easily be added if needed. Each config file does require a top level diff --git a/plugins/experimental/maxmind_acl/mmdb.cc b/plugins/experimental/maxmind_acl/mmdb.cc index 1f80e0d7497..0fd1bb08f4e 100644 --- a/plugins/experimental/maxmind_acl/mmdb.cc +++ b/plugins/experimental/maxmind_acl/mmdb.cc @@ -517,10 +517,22 @@ Acl::eval(TSRemapRequestInfo *rri, TSHttpTxn txnp) #endif MMDB_entry_data_s entry_data; - int path_len = 0; - const char *path = nullptr; + std::string url; if (!allow_regex.empty() || !deny_regex.empty()) { - path = TSUrlPathGet(rri->requestBufp, rri->requestUrl, &path_len); + TSMBuffer mbuf; + TSMLoc ul; + TSReturnCode rc = TSHttpTxnPristineUrlGet(txnp, &mbuf, &ul); + if (rc != TS_SUCCESS) { + TSDebug(PLUGIN_NAME, "Failed call to TSHttpTxnPristineUrlGet()"); + return false; + } + int host_len = 0, path_len = 0; + auto host = TSUrlHostGet(mbuf, ul, &host_len); + auto path = TSUrlPathGet(mbuf, ul, &path_len); + url.assign(host, host_len); + url.append("/"); + url.append(path, path_len); + TSHandleMLocRelease(mbuf, TS_NULL_MLOC, ul); } // Test for country code if (!allow_country.empty() || !allow_regex.empty() || !deny_regex.empty()) { @@ -530,7 +542,7 @@ Acl::eval(TSRemapRequestInfo *rri, TSHttpTxn txnp) return false; } if (entry_data.has_data) { - ret = eval_country(&entry_data, path, path_len); + ret = eval_country(&entry_data, url); } } else { // Country map is empty as well as regexes, use our default rejection @@ -670,7 +682,7 @@ Acl::eval_anonymous(MMDB_entry_s *entry) // allowable country code from our map. // False otherwise bool -Acl::eval_country(MMDB_entry_data_s *entry_data, const char *path, int path_len) +Acl::eval_country(MMDB_entry_data_s *entry_data, const std::string &url) { bool ret = false; bool allow = default_allow; @@ -694,10 +706,11 @@ Acl::eval_country(MMDB_entry_data_s *entry_data, const char *path, int path_len) ret = true; } - if (nullptr != path && 0 != path_len) { + if (!url.empty()) { + TSDebug(PLUGIN_NAME, "saw url not empty: %s, %ld", url.c_str(), url.length()); if (!allow_regex[output].empty()) { for (auto &i : allow_regex[output]) { - if (PCRE_ERROR_NOMATCH != pcre_exec(i._rex, i._extra, path, path_len, 0, PCRE_NOTEMPTY, nullptr, 0)) { + if (PCRE_ERROR_NOMATCH != pcre_exec(i._rex, i._extra, url.c_str(), url.length(), 0, PCRE_NOTEMPTY, nullptr, 0)) { TSDebug(PLUGIN_NAME, "Got a regex allow hit on regex: %s, country: %s", i._regex_s.c_str(), output); ret = true; } @@ -705,7 +718,7 @@ Acl::eval_country(MMDB_entry_data_s *entry_data, const char *path, int path_len) } if (!deny_regex[output].empty()) { for (auto &i : deny_regex[output]) { - if (PCRE_ERROR_NOMATCH != pcre_exec(i._rex, i._extra, path, path_len, 0, PCRE_NOTEMPTY, nullptr, 0)) { + if (PCRE_ERROR_NOMATCH != pcre_exec(i._rex, i._extra, url.c_str(), url.length(), 0, PCRE_NOTEMPTY, nullptr, 0)) { TSDebug(PLUGIN_NAME, "Got a regex deny hit on regex: %s, country: %s", i._regex_s.c_str(), output); ret = false; } diff --git a/plugins/experimental/maxmind_acl/mmdb.h b/plugins/experimental/maxmind_acl/mmdb.h index e406d88e6ce..2bdb9df00d1 100644 --- a/plugins/experimental/maxmind_acl/mmdb.h +++ b/plugins/experimental/maxmind_acl/mmdb.h @@ -114,7 +114,7 @@ class Acl bool loaddeny(const YAML::Node &denyNode); void loadhtml(const YAML::Node &htmlNode); bool loadanonymous(const YAML::Node &anonNode); - bool eval_country(MMDB_entry_data_s *entry_data, const char *path, int path_len); + bool eval_country(MMDB_entry_data_s *entry_data, const std::string &url); bool eval_anonymous(MMDB_entry_s *entry_data); void parseregex(const YAML::Node ®ex, bool allow); ipstate eval_ip(const sockaddr *sock) const;