33#include <unordered_map>
36#include "AllowedHosts.h"
37#include "TheBESKeys.h"
39#include "BESInternalError.h"
44#include "CredentialsManager.h"
48#define prolog std::string("CredentialsManager::").append(__func__).append("() - ")
55const char *CredentialsManager::ENV_ID_KEY =
"CMAC_ID";
56const char *CredentialsManager::ENV_ACCESS_KEY =
"CMAC_ACCESS_KEY";
57const char *CredentialsManager::ENV_REGION_KEY =
"CMAC_REGION";
58const char *CredentialsManager::ENV_URL_KEY =
"CMAC_URL";
60const char *CredentialsManager::USE_ENV_CREDS_KEY_VALUE =
"ENV_CREDS";
82 const char *cstr = getenv(key.c_str());
85 BESDEBUG(CREDS, prolog <<
"From system environment - " << key <<
": " << value << endl);
106void CredentialsManager::initialize_instance() {
110 atexit(delete_instance);
114CredentialsManager::~CredentialsManager() {
115 for (
auto &item: creds) {
124void CredentialsManager::delete_instance() {
138 std::lock_guard<std::recursive_mutex> lock_me(d_lock_mutex);
140 creds.insert(std::pair<std::string, AccessCredentials *>(key, ac));
141 BESDEBUG(HTTP_MODULE, prolog <<
"Added AccessCredentials to CredentialsManager.\n");
142 BESDEBUG(CREDS, prolog <<
"Credentials: \n" << ac->to_json() <<
"\n");
155 std::lock_guard<std::recursive_mutex> lock_me(d_lock_mutex);
158 std::string best_key;
160 if (
url->protocol() == HTTP_PROTOCOL ||
url->protocol() == HTTPS_PROTOCOL) {
161 for (
auto &item: creds) {
162 const std::string &key = item.first;
163 if ((
url->str().rfind(key, 0) == 0) && (key.size() > best_key.size())) {
166 best_match = item.second;
177 const auto protocol =
url.substr(0,
url.find(
':'));
178 if (
url.find(HTTP_PROTOCOL) != 0 &&
url.find(HTTPS_PROTOCOL) != 0)
183 std::lock_guard<std::recursive_mutex> lock_me(d_lock_mutex);
186 for (
auto &item: creds) {
187 std::string best_key;
188 const std::string &key = item.first;
189 if ((
url.rfind(key, 0) == 0) && (key.size() > best_key.size())) {
192 best_match = item.second;
206 struct stat buffer{};
207 return (stat(filename.c_str(), &buffer) == 0);
232 if (stat(filename.c_str(), &st) != 0) {
234 err.append(
"file_is_secured() Unable to access file ");
235 err.append(filename).append(
" strerror: ").append(strerror(errno));
239 mode_t perm = st.st_mode;
241 status = (perm & S_IRUSR) && !(
250 BESDEBUG(HTTP_MODULE,
251 prolog <<
"file_is_secured() " << filename <<
" secured: " << (status ?
"true" :
"false") << endl);
289void CredentialsManager::load_credentials() {
291 bool found_key =
true;
294 BESDEBUG(HTTP_MODULE, prolog <<
"The BES key " << CATALOG_MANAGER_CREDENTIALS
295 <<
" was not found in the BES configuration tree. No AccessCredentials were loaded"
301 if (config_file ==
string(CredentialsManager::USE_ENV_CREDS_KEY_VALUE)) {
303 auto *accessCredentials = load_credentials_from_env();
304 if (accessCredentials) {
307 string url = accessCredentials->get(AccessCredentials::URL_KEY);
308 add(url, accessCredentials);
318 string err{prolog +
"CredentialsManager config file "};
319 err += config_file +
" was specified but is not present.\n";
321 BESDEBUG(HTTP_MODULE, err);
326 string err{prolog +
"CredentialsManager config file "};
327 err += config_file +
" is not secured! Set the access permissions to -rw------- (600) and try again.\n";
329 BESDEBUG(HTTP_MODULE, err);
333 BESDEBUG(HTTP_MODULE, prolog <<
"The config file '" << config_file <<
"' is secured." << endl);
335 unordered_map<string, vector<string> > keystore;
337 kvp::load_keys(config_file, keystore);
338 map<string, AccessCredentials *> credential_sets;
339 AccessCredentials *accessCredentials =
nullptr;
340 for (
const auto &key: keystore) {
341 string creds_name = key.first;
342 const vector<string> &credentials_entries = key.second;
343 map<string, AccessCredentials *>::iterator mit;
344 mit = credential_sets.find(creds_name);
345 if (mit != credential_sets.end()) {
347 accessCredentials = mit->second;
350 accessCredentials =
new AccessCredentials(creds_name);
351 credential_sets.insert(pair<string, AccessCredentials *>(creds_name, accessCredentials));
354 for (
const auto &entry: credentials_entries) {
355 size_t index = entry.find(
':');
357 string key_name = entry.substr(0, index);
358 string value = entry.substr(index + 1);
359 BESDEBUG(HTTP_MODULE, prolog << creds_name <<
":" << key_name <<
"=" << value << endl);
360 accessCredentials->add(key_name, value);
365 BESDEBUG(HTTP_MODULE, prolog <<
"Loaded " << credential_sets.size() <<
" AccessCredentials" << endl);
366 vector<AccessCredentials *> bad_creds;
368 for (
const auto &acit: credential_sets) {
369 accessCredentials = acit.second;
370 string url = accessCredentials->get(AccessCredentials::URL_KEY);
372 add(url, accessCredentials);
374 bad_creds.push_back(acit.second);
378 if (!bad_creds.empty()) {
380 err <<
"Encountered " << bad_creds.size() <<
" AccessCredentials "
381 <<
" definitions missing an associated URL. offenders: ";
383 for (
auto &bc: bad_creds) {
384 err << bc->name() <<
" ";
385 credential_sets.erase(bc->name());
388 ERROR_LOG(err.str());
389 BESDEBUG(HTTP_MODULE, err.str());
392 BESDEBUG(HTTP_MODULE, prolog <<
"Successfully ingested " << size() <<
" AccessCredentials" << endl);
405 std::lock_guard<std::recursive_mutex> lock_me(d_lock_mutex);
407 string env_id{
get_env_value(CredentialsManager::ENV_ID_KEY)};
408 string env_access_key{
get_env_value(CredentialsManager::ENV_ACCESS_KEY)};
409 string env_region{
get_env_value(CredentialsManager::ENV_REGION_KEY)};
410 string env_url{
get_env_value(CredentialsManager::ENV_URL_KEY)};
413 if (!(env_url.empty() || env_id.empty() || env_access_key.empty() || env_region.empty())) {
414 auto ac = make_unique<AccessCredentials>();
415 ac->add(AccessCredentials::URL_KEY, env_url);
416 ac->add(AccessCredentials::ID_KEY, env_id);
417 ac->add(AccessCredentials::KEY_KEY, env_access_key);
418 ac->add(AccessCredentials::REGION_KEY, env_region);
exception thrown if internal error encountered
void get_value(const std::string &s, std::string &val, bool &found)
Retrieve the value of a given key, if set.
static TheBESKeys * TheKeys()
Access to the singleton.
static CredentialsManager * theCM()
Returns the singleton instance of the CredentialsManager.
AccessCredentials * get(const std::shared_ptr< http::url > &url)
void add(const std::string &url, AccessCredentials *ac)
static CredentialsManager * theMngr
Our singleton instance.
Parse a URL into the protocol, host, path and query parts.
utility class for the HTTP catalog module
std::once_flag d_cmac_init_once
Run once_flag for initializing the singleton instance.
bool file_is_secured(const string &filename)
std::string get_env_value(const string &key)
bool file_exists(const string &filename)