lib/Authentication.cc (173 lines of code) (raw):

/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #include <dlfcn.h> #include <pulsar/Authentication.h> #include <boost/algorithm/string.hpp> #include <mutex> #include <string> #include <vector> #include "LogUtils.h" #include "auth/AuthAthenz.h" #include "auth/AuthBasic.h" #include "auth/AuthOauth2.h" #include "auth/AuthTls.h" #include "auth/AuthToken.h" DECLARE_LOG_OBJECT() using namespace pulsar; AuthenticationDataProvider::AuthenticationDataProvider() {} AuthenticationDataProvider::~AuthenticationDataProvider() {} bool AuthenticationDataProvider::hasDataForTls() { return false; } std::string AuthenticationDataProvider::getTlsCertificates() { return "none"; } std::string AuthenticationDataProvider::getTlsPrivateKey() { return "none"; } bool AuthenticationDataProvider::hasDataForHttp() { return false; } std::string AuthenticationDataProvider::getHttpAuthType() { return "none"; } std::string AuthenticationDataProvider::getHttpHeaders() { return "none"; } bool AuthenticationDataProvider::hasDataFromCommand() { return false; } std::string AuthenticationDataProvider::getCommandData() { return "none"; } Authentication::Authentication() {} Authentication::~Authentication() {} ParamMap Authentication::parseDefaultFormatAuthParams(const std::string& authParamsString) { ParamMap paramMap; if (!authParamsString.empty()) { std::vector<std::string> params; boost::algorithm::split(params, authParamsString, boost::is_any_of(",")); for (int i = 0; i < params.size(); i++) { std::vector<std::string> kv; boost::algorithm::split(kv, params[i], boost::is_any_of(":")); if (kv.size() == 2) { paramMap[kv[0]] = kv[1]; } } } return paramMap; } class AuthDisabledData : public AuthenticationDataProvider { public: AuthDisabledData(ParamMap& params) {} }; class AuthDisabled : public Authentication { public: AuthDisabled(AuthenticationDataPtr& authData) { authData_ = authData; } static AuthenticationPtr create(ParamMap& params) { AuthenticationDataPtr authData = AuthenticationDataPtr(new AuthDisabledData(params)); return AuthenticationPtr(new AuthDisabled(authData)); } const std::string getAuthMethodName() const { return "none"; } }; AuthenticationPtr AuthFactory::Disabled() { ParamMap params; return AuthDisabled::create(params); } AuthenticationPtr AuthFactory::create(const std::string& pluginNameOrDynamicLibPath) { ParamMap params; return AuthFactory::create(pluginNameOrDynamicLibPath, params); } std::mutex mutex; std::vector<void*> AuthFactory::loadedLibrariesHandles_; bool AuthFactory::isShutdownHookRegistered_ = false; void AuthFactory::release_handles() { std::lock_guard<std::mutex> lock(mutex); for (std::vector<void*>::iterator ite = AuthFactory::loadedLibrariesHandles_.begin(); ite != AuthFactory::loadedLibrariesHandles_.end(); ite++) { dlclose(*ite); } loadedLibrariesHandles_.clear(); } AuthenticationPtr tryCreateBuiltinAuth(const std::string& pluginName, ParamMap& paramMap) { if (boost::iequals(pluginName, TLS_PLUGIN_NAME) || boost::iequals(pluginName, TLS_JAVA_PLUGIN_NAME)) { return AuthTls::create(paramMap); } else if (boost::iequals(pluginName, TOKEN_PLUGIN_NAME) || boost::iequals(pluginName, TOKEN_JAVA_PLUGIN_NAME)) { return AuthToken::create(paramMap); } else if (boost::iequals(pluginName, ATHENZ_PLUGIN_NAME) || boost::iequals(pluginName, ATHENZ_JAVA_PLUGIN_NAME)) { return AuthAthenz::create(paramMap); } else if (boost::iequals(pluginName, OAUTH2_TOKEN_PLUGIN_NAME) || boost::iequals(pluginName, OAUTH2_TOKEN_JAVA_PLUGIN_NAME)) { return AuthOauth2::create(paramMap); } else if (boost::iequals(pluginName, DEFAULT_BASIC_METHOD_NAME) || boost::iequals(pluginName, BASIC_JAVA_PLUGIN_NAME)) { return AuthBasic::create(paramMap); } else { return AuthenticationPtr(); } } AuthenticationPtr tryCreateBuiltinAuth(const std::string& pluginName, const std::string& authParamsString) { if (boost::iequals(pluginName, TLS_PLUGIN_NAME) || boost::iequals(pluginName, TLS_JAVA_PLUGIN_NAME)) { return AuthTls::create(authParamsString); } else if (boost::iequals(pluginName, TOKEN_PLUGIN_NAME) || boost::iequals(pluginName, TOKEN_JAVA_PLUGIN_NAME)) { return AuthToken::create(authParamsString); } else if (boost::iequals(pluginName, ATHENZ_PLUGIN_NAME) || boost::iequals(pluginName, ATHENZ_JAVA_PLUGIN_NAME)) { return AuthAthenz::create(authParamsString); } else if (boost::iequals(pluginName, OAUTH2_TOKEN_PLUGIN_NAME) || boost::iequals(pluginName, OAUTH2_TOKEN_JAVA_PLUGIN_NAME)) { return AuthOauth2::create(authParamsString); } else if (boost::iequals(pluginName, DEFAULT_BASIC_METHOD_NAME) || boost::iequals(pluginName, BASIC_JAVA_PLUGIN_NAME)) { return AuthBasic::create(authParamsString); } else { return AuthenticationPtr(); } } AuthenticationPtr AuthFactory::create(const std::string& pluginNameOrDynamicLibPath, const std::string& authParamsString) { { std::lock_guard<std::mutex> lock(mutex); if (!AuthFactory::isShutdownHookRegistered_) { atexit(release_handles); AuthFactory::isShutdownHookRegistered_ = true; } } AuthenticationPtr authPtr = tryCreateBuiltinAuth(pluginNameOrDynamicLibPath, authParamsString); if (authPtr) { return authPtr; } Authentication* auth = NULL; void* handle = dlopen(pluginNameOrDynamicLibPath.c_str(), RTLD_LAZY); if (handle != NULL) { { std::lock_guard<std::mutex> lock(mutex); loadedLibrariesHandles_.push_back(handle); } Authentication* (*createAuthentication)(const std::string&); *(void**)(&createAuthentication) = dlsym(handle, "create"); if (createAuthentication != NULL) { auth = createAuthentication(authParamsString); } else { ParamMap paramMap = Authentication::parseDefaultFormatAuthParams(authParamsString); return AuthFactory::create(pluginNameOrDynamicLibPath, paramMap); } } if (!auth) { LOG_WARN("Couldn't load auth plugin " << pluginNameOrDynamicLibPath); } return AuthenticationPtr(auth); } AuthenticationPtr AuthFactory::create(const std::string& pluginNameOrDynamicLibPath, ParamMap& params) { { std::lock_guard<std::mutex> lock(mutex); if (!AuthFactory::isShutdownHookRegistered_) { atexit(release_handles); AuthFactory::isShutdownHookRegistered_ = true; } } AuthenticationPtr authPtr = tryCreateBuiltinAuth(pluginNameOrDynamicLibPath, params); if (authPtr) { return authPtr; } Authentication* auth = NULL; void* handle = dlopen(pluginNameOrDynamicLibPath.c_str(), RTLD_LAZY); if (handle != NULL) { std::lock_guard<std::mutex> lock(mutex); loadedLibrariesHandles_.push_back(handle); Authentication* (*createAuthentication)(ParamMap&); *(void**)(&createAuthentication) = dlsym(handle, "createFromMap"); if (createAuthentication != NULL) { auth = createAuthentication(params); } } if (!auth) { LOG_WARN("Couldn't load auth plugin " << pluginNameOrDynamicLibPath); } return AuthenticationPtr(auth); }