33#include "BESCatalog.h"
34#include "BESCatalogList.h"
35#include "BESCatalogUtils.h"
37#include "TheBESKeys.h"
38#include "BESInternalError.h"
40#include "BESNotFoundError.h"
41#include "BESForbiddenError.h"
47#include "AllowedHosts.h"
53#define prolog string("AllowedHosts::").append(__func__).append("() - ")
61static std::once_flag d_ah_init_once;
70 std::call_once(d_ah_init_once, AllowedHosts::initialize_instance);
74AllowedHosts::AllowedHosts() {
76 string key = ALLOWED_HOSTS_BES_KEY;
79 throw BESInternalError(
string(
"The allowed hosts key, '") + ALLOWED_HOSTS_BES_KEY
80 +
"' has not been configured.", __FILE__, __LINE__);
87void AllowedHosts::initialize_instance() {
88 d_instance =
new AllowedHosts();
90 atexit(delete_instance);
97void AllowedHosts::delete_instance() {
119 BESDEBUG(MODULE, prolog <<
"BEGIN candidate_url: " << candidate_url->str() << endl);
120 bool isAllowed =
false;
124 if (candidate_url->protocol() == FILE_PROTOCOL) {
129 string file_path = candidate_url->path();
130 BESDEBUG(MODULE, prolog <<
" file_path: '" << file_path <<
131 "' (length: " << file_path.length() <<
" size: " << file_path.size() <<
")" <<endl);
135 BESDEBUG(MODULE, prolog <<
"Searching for catalog named: '" << default_catalog_name <<
"'" << endl);
136 BESCatalog *bcat = bcl->find_catalog(default_catalog_name);
138 BESDEBUG(MODULE, prolog <<
"Found catalog named: '" << bcat->
get_catalog_name() <<
"'" << endl);
140 string error_msg =
"INTERNAL_ERROR: Unable to locate default catalog. Check BES configuration.";
141 BESDEBUG(MODULE, prolog << error_msg << endl);
145 string catalog_root = bcat->
get_root();
146 BESDEBUG(MODULE, prolog <<
"catalog_root: '" << catalog_root <<
147 "' (length: " << catalog_root.length() <<
" size: " << catalog_root.size() <<
")" << endl);
149 string relative_path;
150 if (file_path[0] ==
'/') {
151 if (file_path.length() < catalog_root.length()) {
153 why_not =
"Path is out of scope from configuration.";
156 BESDEBUG(MODULE, prolog <<
"file_path: " << file_path << endl);
157 BESDEBUG(MODULE, prolog <<
"catalog_root: " << catalog_root << endl);
158 size_t ret = file_path.find(catalog_root);
159 BESDEBUG(MODULE, prolog <<
"file_path.find(catalog_root): " << ret << endl);
160 isAllowed = (ret == 0);
161 relative_path = file_path.substr(catalog_root.length());
162 BESDEBUG(MODULE, prolog <<
"relative_path: " << relative_path << endl);
163 BESDEBUG(MODULE, prolog <<
"isAllowed: " << (isAllowed?
"true":
"false") << endl);
167 BESDEBUG(MODULE, prolog <<
"Relative path detected");
168 relative_path = file_path;
191 BESDEBUG(MODULE, prolog <<
"File Access Allowed: " << (isAllowed ?
"true " :
"false ") << endl);
192 }
else if(candidate_url->protocol() == HTTPS_PROTOCOL || candidate_url->protocol() == HTTP_PROTOCOL ){
194 isAllowed = candidate_url->is_trusted() || check(candidate_url->str());
196 if (candidate_url->is_trusted()) {
197 INFO_LOG(prolog <<
"Candidate URL is marked trusted, allowing. url: " << candidate_url->str() << endl);
199 BESDEBUG(MODULE, prolog <<
"HTTP Access Allowed: " << (isAllowed ?
"true " :
"false ") << endl);
203 ss <<
"The candidate_url utilizes an unsupported protocol '" << candidate_url->protocol() <<
"'" ;
204 BESDEBUG(MODULE, prolog << ss.str() << endl);
207 BESDEBUG(MODULE, prolog <<
"END Access Allowed: " << (isAllowed ?
"true " :
"false ") << endl);
213bool AllowedHosts::check(
const std::string &url){
214 bool isAllowed=
false;
215 auto it = d_allowed_hosts.begin();
216 auto end_it = d_allowed_hosts.end();
217 for (; it != end_it && !isAllowed; it++) {
218 string a_regex_pattern = *it;
219 BESRegex reg_expr(a_regex_pattern.c_str());
220 int match_result = reg_expr.match(url.c_str(), url.length());
221 if (match_result >= 0) {
222 auto match_length = (
unsigned int) match_result;
223 if (match_length == url.length()) {
225 prolog <<
"FULL MATCH. pattern: " << a_regex_pattern <<
" url: " << url << endl);
229 prolog <<
"No Match. pattern: " << a_regex_pattern <<
" url: " << url << endl);
List of all registered catalogs.
virtual std::string default_catalog_name() const
The name of the default catalog.
static BESCatalogList * TheCatalogList()
Get the singleton BESCatalogList instance.
Catalogs provide a hierarchical organization for data.
virtual std::string get_root() const =0
virtual BESCatalogUtils * get_catalog_utils() const
Get a pointer to the utilities, customized for this catalog.
virtual std::string get_catalog_name() const
Get the name for this catalog.
std::string get_message() const
get the error message for this exception
error thrown if the BES is not allowed to access the resource requested
exception thrown if internal error encountered
error thrown if the resource requested cannot be found
Regular expression matching.
static void check_path(const std::string &path, const std::string &root, bool follow_sym_links)
Is the combination of root + path a pathname the BES can/should access?
static TheBESKeys * TheKeys()
void get_values(const std::string &s, std::vector< std::string > &vals, bool &found)
Retrieve the values of a given key, if set.
Can a given URL be dereferenced given the BES's configuration?
bool is_allowed(std::shared_ptr< http::url > candidate_url)
static AllowedHosts * theHosts()
Static accessor for the singleton.
utility class for the HTTP catalog module