${CYNARA_SERVICE_PATH}/logic/Logic.cpp
${CYNARA_SERVICE_PATH}/main/Cynara.cpp
${CYNARA_SERVICE_PATH}/main/main.cpp
+ ${CYNARA_SERVICE_PATH}/plugin/PluginManager.cpp
${CYNARA_SERVICE_PATH}/sockets/Descriptor.cpp
${CYNARA_SERVICE_PATH}/sockets/SocketManager.cpp
)
INCLUDE_DIRECTORIES(
${CYNARA_SERVICE_PATH}
${CYNARA_PATH}
+ ${CYNARA_PATH}/include
)
ADD_EXECUTABLE(${TARGET_CYNARA} ${CYNARA_SOURCES})
${CYNARA_DEP_LIBRARIES}
${TARGET_CYNARA_COMMON}
${TARGET_LIB_CYNARA_STORAGE}
+ dl
)
INSTALL(TARGETS ${TARGET_CYNARA} DESTINATION ${BIN_INSTALL_DIR})
LOGD("check of policy key <%s> returned DENY", key.toString().c_str());
return true;
}
- //todo pass question to proper plugin that:
- // 1) returns false when answer has to be waited for (UI)
- // 2) returns true if Response is to be generated
- // In case 1) context should be saved in plugin in order to return answer when ready.
- //in case no proper plugin is found
- throw PluginNotFoundException(result);
+ ExternalPluginPtr plugin = m_pluginManager->getPlugin(result.policyType());
+ if (!plugin) {
+ throw PluginNotFoundException(result);
+ }
+
+ AgentType requiredAgent;
+ PluginData pluginData;
+
+ auto ret = plugin->check(key.client().toString(), key.user().toString(),
+ key.privilege().toString(), result, requiredAgent, pluginData);
+
+ switch (ret) {
+ case ExternalPluginInterface::PluginStatus::ANSWER_READY:
+ return true;
+ case ExternalPluginInterface::PluginStatus::ANSWER_NOTREADY:
+ //todo send request to agent
+ //context should be saved in plugin in order to return answer when ready
+ return false;
+ default:
+ //todo make additional class
+ throw std::runtime_error("Plugin error");
+ }
}
void Logic::execute(RequestContextPtr context, InsertOrUpdateBucketRequestPtr request) {
#include <types/PolicyResult.h>
#include <main/pointers.h>
+#include <plugin/PluginManager.h>
#include <request/pointers.h>
#include <request/RequestTaker.h>
Logic();
virtual ~Logic();
+ void bindPluginManager(PluginManagerPtr pluginManager) {
+ m_pluginManager = pluginManager;
+ }
+
void bindStorage(StoragePtr storage) {
m_storage = storage;
}
}
void unbindAll(void) {
+ m_pluginManager.reset();
m_storage.reset();
m_socketManager.reset();
}
virtual void execute(RequestContextPtr context, SignalRequestPtr request);
private:
+ PluginManagerPtr m_pluginManager;
StoragePtr m_storage;
SocketManagerPtr m_socketManager;
#include <exceptions/InitException.h>
#include <logic/Logic.h>
+#include <plugin/PluginManager.h>
#include <sockets/SocketManager.h>
#include <storage/InMemoryStorageBackend.h>
#include <storage/Storage.h>
return dir;
}
+const std::string Cynara::pluginDir(void) {
+ std::string dir("/usr/lib/cynara/");
+
+#ifdef CYNARA_LIB_PATH
+ dir = CYNARA_LIB_PATH;
+#else
+ LOGW("Cynara compiled without CYNARA_LIB_PATH flag. Using default plugin directory.");
+#endif
+ dir += "plugin/";
+ LOGI("Cynara plugin path <%s>", dir.c_str());
+ return dir;
+}
+
void Cynara::init(void) {
m_logic = std::make_shared<Logic>();
+ m_pluginManager = std::make_shared<PluginManager>(pluginDir());
m_socketManager = std::make_shared<SocketManager>();
m_storageBackend = std::make_shared<InMemoryStorageBackend>(storageDir());
m_storage = std::make_shared<Storage>(*m_storageBackend);
+ m_logic->bindPluginManager(m_pluginManager);
m_logic->bindStorage(m_storage);
m_logic->bindSocketManager(m_socketManager);
}
m_logic.reset();
+ m_pluginManager.reset();
m_socketManager.reset();
m_storageBackend.reset();
m_storage.reset();
class Cynara {
private:
LogicPtr m_logic;
+ PluginManagerPtr m_pluginManager;
SocketManagerPtr m_socketManager;
StoragePtr m_storage;
StorageBackendPtr m_storageBackend;
+ static const std::string pluginDir(void);
static const std::string storageDir(void);
public:
class Logic;
typedef std::shared_ptr<Logic> LogicPtr;
+class PluginManager;
+typedef std::shared_ptr<PluginManager> PluginManagerPtr;
+
class SocketManager;
typedef std::shared_ptr<SocketManager> SocketManagerPtr;
--- /dev/null
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed 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.
+ */
+/**
+ * @file src/service/plugin/PluginManager.cpp
+ * @author Zofia Abramowska <z.abramowska@samsung.com>
+ * @version 1.0
+ * @brief Definition of PluginManager class
+ */
+
+#define _BSD_SOURCE_
+
+#include <cinttypes>
+#include <cstdlib>
+#include <dirent.h>
+#include <dlfcn.h>
+#include <functional>
+
+#include <log/log.h>
+
+#include "PluginManager.h"
+
+
+namespace {
+ int pluginFilter(const struct dirent *ent) {
+#ifdef _DIRENT_HAVE_D_TYPE
+ if (ent->d_type != DT_REG) {
+ return 0;
+ }
+#endif
+ if (ent->d_name[0] == '.') {
+ return 0;
+ }
+ return 1;
+ }
+}
+
+namespace Cynara {
+
+PluginManager::PluginManager(const std::string &pluginDir) : m_dir(pluginDir) {
+ loadPlugins();
+}
+
+ExternalPluginPtr PluginManager::getPlugin(PolicyType pType) {
+ return m_plugins[pType];
+}
+
+void PluginManager::loadPlugins(void) {
+ struct dirent **nameList = NULL;
+ int fileAmount = scandir(m_dir.c_str(), &nameList, pluginFilter, alphasort);
+
+ if (fileAmount < 0) {
+ auto error = strerror(errno);
+ LOGE("Couldn't scan for plugins in <%s> : <%s>", m_dir.c_str(), error);
+ return;
+ }
+
+ std::unique_ptr<dirent*, std::function<void(dirent**)>> direntPtr(nameList,
+ [fileAmount](dirent** dirs) {
+ for (int i = 0; i < fileAmount; i++) {
+ free(dirs[i]);
+ }
+ free(dirs);
+ });
+ for (int i = 0; i < fileAmount; i++) {
+ openPlugin(m_dir + nameList[i]->d_name);
+ }
+}
+
+void PluginManager::openPlugin(const std::string &path) {
+ void *handle = dlopen(path.c_str(), RTLD_LAZY);
+
+ if (!handle) {
+ LOGW("File could not be dlopened <%s> : <%s>", path.c_str(), dlerror());
+ return;
+ }
+ PluginLibPtr handlePtr(handle, std::ptr_fun(dlclose));
+
+ //Flush any previous errors
+ dlerror();
+ createPlugin func = reinterpret_cast<createPlugin>(dlsym(handle, "create"));
+
+ char *error;
+ if ((error = dlerror()) != NULL) {
+ LOGE("Couldn't resolve symbol <create> from lib <%s> : <%s>", path.c_str(), error);
+ return;
+ }
+
+ ExternalPluginPtr pluginPtr(func());
+
+ if (!pluginPtr) {
+ LOGE("Couldn't create plugin for <%s>", path.c_str());
+ return;
+ }
+
+ PolicyTypes policies = pluginPtr->getSupportedPolicyTypes();
+ if (policies.empty()) {
+ LOGE("Plugin <%s> does not support any type!", path.c_str());
+ return;
+ }
+ for (auto type : policies) {
+ if (!m_plugins.insert(std::make_pair(type, pluginPtr)).second) {
+ LOGW("policyType [%" PRIu16 "] was already supported.", type);
+ }
+ }
+
+ m_pluginLibs.push_back(std::move(handlePtr));
+}
+
+} // namespace Cynara
+
--- /dev/null
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed 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.
+ */
+/**
+ * @file src/service/plugin/PluginManager.h
+ * @author Zofia Abramowska <z.abramowska@samsung.com>
+ * @version 1.0
+ * @brief Declaration of PluginManager class
+ */
+
+#ifndef SRC_SERVICE_PLUGIN_PLUGINMANAGER_H_
+#define SRC_SERVICE_PLUGIN_PLUGINMANAGER_H_
+
+#include <list>
+#include <map>
+#include <memory>
+#include <string>
+
+#include <cynara-plugin.h>
+
+namespace Cynara {
+typedef std::shared_ptr<ExternalPluginInterface> ExternalPluginPtr;
+
+class PluginManager {
+public:
+ PluginManager(const std::string &pluginDir);
+ ExternalPluginPtr getPlugin(PolicyType pType);
+ ~PluginManager() {}
+
+private:
+ typedef std::unique_ptr<void, std::function<void (void*)>> PluginLibPtr;
+ typedef std::list<PluginLibPtr> PluginLibs;
+
+ std::string m_dir;
+ std::map<PolicyType, ExternalPluginPtr> m_plugins;
+ PluginLibs m_pluginLibs;
+
+ void loadPlugins(void);
+ void openPlugin(const std::string &path);
+};
+
+} // namespace Cynara
+#endif /* SRC_SERVICE_PLUGIN_PLUGINMANAGER_H_ */