bes  Updated for version 3.20.5
WhiteList.cc
1 // RemoteAccess.cc
2 
3 // -*- mode: c++; c-basic-offset:4 -*-
4 
5 // This file is part of the OPeNDAP Back-End Server (BES)
6 // and embodies a whitelist of remote system that may be
7 // accessed by the server as part of it's routine operation.
8 
9 // Copyright (c) 2018 OPeNDAP, Inc.
10 // Author: Nathan D. Potter <ndp@opendap.org>
11 //
12 // This library is free software; you can redistribute it and/or
13 // modify it under the terms of the GNU Lesser General Public
14 // License as published by the Free Software Foundation; either
15 // version 2.1 of the License, or (at your option) any later version.
16 //
17 // This library is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 // Lesser General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public
23 // License along with this library; if not, write to the Free Software
24 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 //
26 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
27 
28 #include "config.h"
29 
30 #include <BESUtil.h>
31 #include <BESCatalog.h>
32 #include <BESCatalogList.h>
33 #include <BESCatalogUtils.h>
34 #include <BESRegex.h>
35 #include <TheBESKeys.h>
36 #include <BESInternalError.h>
37 #include <BESSyntaxUserError.h>
38 #include <BESDebug.h>
39 #include <BESForbiddenError.h>
40 
41 #include "WhiteList.h"
42 
43 using namespace std;
44 using namespace bes;
45 
46 WhiteList *WhiteList::d_instance = 0;
47 
53 WhiteList *
54 WhiteList::get_white_list()
55 {
56  if (d_instance) return d_instance;
57  d_instance = new WhiteList;
58  return d_instance;
59 }
60 
61 WhiteList::WhiteList()
62 {
63  bool found = false;
64  string key = REMOTE_ACCESS_WHITELIST;
65  TheBESKeys::TheKeys()->get_values(REMOTE_ACCESS_WHITELIST, d_white_list, found);
66  if(!found){
67  throw BESInternalError(string("The remote access whitelist, '")+REMOTE_ACCESS_WHITELIST
68  +"' has not been configured.", __FILE__, __LINE__);
69  }
70 }
71 
86 bool WhiteList::is_white_listed(const std::string &url)
87 {
88  bool whitelisted = false;
89  const string file_url("file://");
90  const string http_url("http://");
91  const string https_url("https://");
92 
93  // Special case: This allows any file: URL to pass if the URL starts with the default
94  // catalog's path.
95  if (url.compare(0, file_url.size(), file_url) == 0 /*equals a file url*/) {
96 
97  // Ensure that the file path starts with the catalog root dir.
98  string file_path = url.substr(file_url.size());
99  BESDEBUG("bes", "WhiteList::Is_Whitelisted() - file_path: "<< file_path << endl);
100 
101  BESCatalog *bcat = BESCatalogList::TheCatalogList()->find_catalog(BES_DEFAULT_CATALOG);
102  if (bcat) {
103  BESDEBUG("bes", "WhiteList::Is_Whitelisted() - Found catalog: "<< bcat->get_catalog_name() << endl);
104  }
105  else {
106  string msg = "OUCH! Unable to locate default catalog!";
107  BESDEBUG("bes", "WhiteList::Is_Whitelisted() - " << msg << endl);
108  throw BESInternalError(msg, __FILE__, __LINE__);
109  }
110 
111  string catalog_root = bcat->get_root();
112  BESDEBUG("bes", "WhiteList::Is_Whitelisted() - Catalog root: "<< catalog_root << endl);
113 
114  whitelisted = file_path.compare(0, catalog_root.size(), catalog_root) == 0;
115  BESDEBUG("bes", "WhiteList::Is_Whitelisted() - Is_Whitelisted: "<< (whitelisted?"true":"false") << endl);
116  }
117  else {
118  // This checks HTTP and HTTPS URLs against the whitelist patterns.
119  if (url.compare(0, http_url.size(), http_url) == 0 /*equals http url */
120  || url.compare(0, https_url.size(), https_url) == 0 /*equals https url */) {
121 
122  vector<string>::const_iterator i = d_white_list.begin();
123  vector<string>::const_iterator e = d_white_list.end();
124  for (; i != e && !whitelisted; i++) {
125  if ((*i).length() <= url.length()) {
126  if (url.substr(0, (*i).length()) == (*i)) {
127  whitelisted = true;
128  }
129  }
130  }
131  }
132  else {
133  string msg;
134  msg = "WhiteList - ERROR! Unknown URL protocol! Only " + http_url + ", " + https_url + ", and " + file_url + " are supported.";
135  BESDEBUG("bes", msg << endl);
136  throw BESForbiddenError(msg, __FILE__, __LINE__);
137  }
138  }
139 
140  return whitelisted;
141 }
142 
virtual std::string get_catalog_name() const
Get the name for this catalog.
Definition: BESCatalog.h:103
virtual std::string get_root() const =0
exception thrown if inernal error encountered
static TheBESKeys * TheKeys()
Definition: TheBESKeys.cc:61
void get_values(const std::string &s, std::vector< std::string > &vals, bool &found)
Retrieve the values of a given key, if set.
Definition: TheBESKeys.cc:451
Catalogs provide a hierarchical organization for data.
Definition: BESCatalog.h:51
error thrown if the BES is not allowed to access the resource requested
Can a given URL be dereferenced given the BES's configuration?
Definition: WhiteList.h:51
static BESCatalogList * TheCatalogList()
Get the singleton BESCatalogList instance.