SET(${TARGET_OSQUERY_LIB}_DEPS ${${TARGET_OSQUERY_LIB}_DEPS} PARENT_SCOPE)
ENDMACRO(ADD_OSQUERY_LINK)
-## VIST #####################
+## ViST #####################
MACRO(ADD_VIST_LIBRARY TARGET)
ADD_LIBRARY(${TARGET} OBJECT ${ARGN})
LIST(APPEND ${TARGET_VIST_LIB}_SRCS $<TARGET_OBJECTS:${TARGET}>)
SET(${TARGET_VIST_LIB}_SRCS ${${TARGET_VIST_LIB}_SRCS} PARENT_SCOPE)
ENDMACRO(ADD_VIST_LIBRARY)
+MACRO(ADD_VIST_POLICY_LIBRARY TARGET)
+ ADD_LIBRARY(${TARGET} OBJECT ${ARGN})
+ LIST(APPEND ${TARGET_VIST_POLICY_LIB}_SRCS $<TARGET_OBJECTS:${TARGET}>)
+ SET(${TARGET_VIST_POLICY_LIB}_SRCS ${${TARGET_VIST_POLICY_LIB}_SRCS} PARENT_SCOPE)
+ENDMACRO(ADD_VIST_LIBRARY)
+
MACRO(ADD_VIST_TEST)
LIST(APPEND ${TARGET_VIST_LIB}_TESTS ${ARGN})
SET(${TARGET_VIST_LIB}_TESTS ${${TARGET_VIST_LIB}_TESTS} PARENT_SCOPE)
ENDMACRO(ADD_VIST_TEST)
-MACRO(ADD_VIST_LINK)
- LIST(APPEND ${TARGET_VIST_LIB}_DEPS ${ARGN})
- SET(${TARGET_VIST_LIB}_DEPS ${${TARGET_VIST_LIB}_DEPS} PARENT_SCOPE)
-ENDMACRO(ADD_VIST_LINK)
-
-## policyd #####################
-MACRO(ADD_POLICYD_LIBRARY TARGET)
- ADD_LIBRARY(${TARGET} OBJECT ${ARGN})
- LIST(APPEND ${TARGET_POLICYD_LIB}_SRCS $<TARGET_OBJECTS:${TARGET}>)
- SET(${TARGET_POLICYD_LIB}_SRCS ${${TARGET_POLICYD_LIB}_SRCS} PARENT_SCOPE)
-ENDMACRO(ADD_POLICYD_LIBRARY)
-
-MACRO(ADD_POLICYD_TEST)
- LIST(APPEND ${TARGET_POLICYD_LIB}_TESTS ${ARGN})
- SET(${TARGET_POLICYD_LIB}_TESTS ${${TARGET_POLICYD_LIB}_TESTS} PARENT_SCOPE)
-ENDMACRO(ADD_POLICYD_TEST)
-
## common #############################
MACRO(TARGET_LINK_WHOLE TARGET LIBRARY)
TARGET_LINK_LIBRARIES(${TARGET} "-Wl,-whole-archive")
%files test
%{_bindir}/osquery-test
%{_bindir}/vist-test
-%{_bindir}/policyd-test
## ViST Plugins - ###########################################################
%package plugins
#include <bluetooth-api.h>
#include <bluetooth_internal.h>
-#include <policyd/sdk/global-policy.h>
-#include <policyd/sdk/policy-provider.h>
+#include <vist/policy/sdk/global-policy.h>
+#include <vist/policy/sdk/policy-provider.h>
#include <memory>
((int)(enable) ? BLUETOOTH_DPM_BT_ALLOWED : \
BLUETOOTH_DPM_BT_RESTRICTED)
-using namespace policyd;
+using namespace vist::policy;
class ModeChange : public GlobalPolicy {
public:
#include <arpa/inet.h>
#include <wifi-manager.h>
-#include <policyd/sdk/global-policy.h>
-#include <policyd/sdk/policy-provider.h>
+#include <vist/policy/sdk/global-policy.h>
+#include <vist/policy/sdk/policy-provider.h>
#include <klay/dbus/connection.h>
"/net/netconfig/network", \
"net.netconfig.network"
-using namespace policyd;
+using namespace vist::policy;
class ModeChange : public GlobalPolicy {
public:
# limitations under the License
SET(TARGET_OSQUERY_LIB osquery)
-SET(TARGET_POLICYD_LIB policyd)
+SET(TARGET_VIST_POLICY_LIB vist-policy)
SET(TARGET_VIST_LIB vist)
ADD_SUBDIRECTORY(osquery)
IF(DEFINED GBS_BUILD)
ADD_SUBDIRECTORY(vist)
- ADD_SUBDIRECTORY(policyd)
ENDIF(DEFINED GBS_BUILD)
TARGET_LINK_LIBRARIES(${TARGET_OSQUERY_LIB} ${${TARGET_OSQUERY_LIB}_DEPS})
IF(DEFINED GBS_BUILD)
-TARGET_LINK_LIBRARIES(${TARGET_OSQUERY_LIB} ${TARGET_POLICYD_LIB})
+TARGET_LINK_LIBRARIES(${TARGET_OSQUERY_LIB} ${TARGET_VIST_POLICY_LIB})
ENDIF(DEFINED GBS_BUILD)
SET_TARGET_PROPERTIES(${TARGET_OSQUERY_LIB} PROPERTIES OUTPUT_NAME ${TARGET_OSQUERY_LIB})
#include <stdexcept>
#include <osquery/sql.h>
-#include <osquery/logger.h>
#include <osquery/tables.h>
-#include <policyd/api.h>
+#include <vist/policy/api.h>
+#include <vist/common/audit/logger.h>
namespace osquery {
namespace tables {
QueryData genPolicy(QueryContext& context) try {
+ INFO(VIST, "Select query about policy table.");
+
QueryData results;
if (context.constraints["name"].exists(EQUALS)) { /// where clause
auto names = context.constraints["name"].getAll(EQUALS);
for (const auto& name : names) {
- auto ret = policyd::API::Get(name);
+ auto ret = vist::policy::API::Get(name);
Row r;
r["name"] = TEXT(name);
results.emplace_back(std::move(r));
}
} else { /// select *;
- auto policies = policyd::API::GetAll();
+ auto policies = vist::policy::API::GetAll();
for (auto& policy : policies) {
Row r;
r["name"] = TEXT(policy.first);
return results;
} catch (...) {
+ ERROR(VIST, "Failed to select query on policy.");
Row r;
return { r };
}
QueryData updatePolicy(QueryContext& context, const PluginRequest& request) try {
+ INFO(VIST, "Update query about policy table.");
if (request.count("json_value_array") == 0)
throw std::runtime_error("Wrong request format. Not found json value.");
std::string name = document[0].GetString();
int value = std::stoi(document[1].GetString());
- policyd::API::Admin::Set(name, policyd::PolicyValue(value));
+ vist::policy::API::Admin::Set(name, vist::policy::PolicyValue(value));
Row r;
r["status"] = "success";
#include <osquery/sql.h>
#include <osquery/tables.h>
-#include <policyd/api.h>
+#include <vist/policy/api.h>
#include <vist/common/audit/logger.h>
namespace {
namespace tables {
QueryData genPolicyAdmin(QueryContext& context) try {
- INFO(VIST, "Select query about policy-admin.");
+ INFO(VIST, "Select query about policy-admin table.");
QueryData results;
- auto admins = policyd::API::Admin::GetAll();
+ auto admins = vist::policy::API::Admin::GetAll();
for (auto& admin : admins) {
Row r;
}
QueryData insertPolicyAdmin(QueryContext& context, const PluginRequest& request) try {
- INFO(VIST, "Insert query about policy-admin.");
+ INFO(VIST, "Insert query about policy-admin table.");
if (request.count("json_value_array") == 0)
throw std::runtime_error("Wrong request format. Not found json value.");
auto admin = parseAdmin(request.at("json_value_array"));
DEBUG(VIST, "Admin info [name]: " << admin.first << ", [uid]: " << admin.second);
- policyd::API::Admin::Enroll(admin.first, admin.second);
+ vist::policy::API::Admin::Enroll(admin.first, admin.second);
Row r;
r["status"] = "success";
}
QueryData deletePolicyAdmin(QueryContext& context, const PluginRequest& request) try {
- INFO(VIST, "Delete query about policy-admin.");
+ INFO(VIST, "Delete query about policy-admin table.");
if (request.count("json_value_array") == 0)
throw std::runtime_error("Wrong request format. Not found json value.");
auto admin = parseAdmin(request.at("json_value_array"), false);
DEBUG(VIST, "Admin info [name]: " << admin.first << ", [uid]: " << admin.second);
- policyd::API::Admin::Disenroll(admin.first, admin.second);
+ vist::policy::API::Admin::Disenroll(admin.first, admin.second);
Row r;
r["status"] = "success";
#include <gtest/gtest.h>
-#include <policyd/api.h>
+#include <vist/policy/api.h>
+
+using namespace vist;
class PolicyTests : public testing::Test {};
TEST_F(PolicyTests, get_all) {
- auto policies = policyd::API::GetAll();
+ auto policies = policy::API::GetAll();
EXPECT_TRUE(policies.size() > 0);
}
TEST_F(PolicyTests, get_admin_all) {
- auto admins = policyd::API::Admin::GetAll();
+ auto admins = policy::API::Admin::GetAll();
EXPECT_EQ(admins.size(), 0);
- policyd::API::Admin::Enroll("testAdmin", 0);
- admins = policyd::API::Admin::GetAll();
+ policy::API::Admin::Enroll("testAdmin", 0);
+ admins = policy::API::Admin::GetAll();
EXPECT_EQ(admins.size(), 1);
- policyd::API::Admin::Enroll("testAdmin", 1);
- admins = policyd::API::Admin::GetAll();
+ policy::API::Admin::Enroll("testAdmin", 1);
+ admins = policy::API::Admin::GetAll();
EXPECT_EQ(admins.size(), 2);
- policyd::API::Admin::Disenroll("testAdmin", 0);
- admins = policyd::API::Admin::GetAll();
+ policy::API::Admin::Disenroll("testAdmin", 0);
+ admins = policy::API::Admin::GetAll();
EXPECT_EQ(admins.size(), 1);
- policyd::API::Admin::Disenroll("testAdmin", 1);
- admins = policyd::API::Admin::GetAll();
+ policy::API::Admin::Disenroll("testAdmin", 1);
+ admins = policy::API::Admin::GetAll();
EXPECT_EQ(admins.size(), 0);
}
+++ /dev/null
-# Copyright (c) 2019 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.
-#
-
-SET(TARGET_POLICYD_TEST policyd-test)
-
-SET(${TARGET_POLICYD_LIB}_SRCS "")
-SET(${TARGET_POLICYD_LIB}_TESTS "")
-
-SET(DEPENDENCY klay)
-
-PKG_CHECK_MODULES(POLICYD_DEPS REQUIRED ${DEPENDENCY})
-
-INCLUDE_DIRECTORIES(SYSTEM . ${POLICYD_DEPS_INCLUDE_DIRS})
-
-ADD_DEFINITIONS(-DDB_PATH="${DB_INSTALL_DIR}/.vist.db"
- -DPLUGIN_INSTALL_DIR="${PLUGIN_INSTALL_DIR}"
- -DSCRIPT_INSTALL_DIR="${SCRIPT_INSTALL_DIR}")
-
-ADD_SUBDIRECTORY(core)
-ADD_SUBDIRECTORY(sdk)
-
-ADD_LIBRARY(${TARGET_POLICYD_LIB} STATIC ${${TARGET_POLICYD_LIB}_SRCS})
-
-TARGET_LINK_LIBRARIES(${TARGET_POLICYD_LIB} ${POLICYD_DEPS_LIBRARIES} pthread dl)
-
-SET_TARGET_PROPERTIES(${TARGET_POLICYD_LIB} PROPERTIES COMPILE_FLAGS "-fPIE")
-SET_TARGET_PROPERTIES(${TARGET_POLICYD_LIB} PROPERTIES LINK_FLAGS "-pie")
-
-ADD_EXECUTABLE(${TARGET_POLICYD_TEST} ../vist/main/tests.cpp
- ${${TARGET_POLICYD_LIB}_TESTS})
-
-TARGET_LINK_LIBRARIES(${TARGET_POLICYD_TEST} ${TARGET_POLICYD_LIB}
- gtest
- pthread)
-ADD_TEST(${TARGET_POLICYD_TEST} ${TARGET_POLICYD_TEST})
-INSTALL(TARGETS ${TARGET_POLICYD_TEST}
- DESTINATION ${CMAKE_INSTALL_BINDIR}
- PERMISSIONS OWNER_READ
- OWNER_WRITE
- OWNER_EXECUTE
- GROUP_READ
- GROUP_EXECUTE
- WORLD_READ
- WORLD_EXECUTE)
+++ /dev/null
-/*
- * Copyright (c) 2019 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
- */
-
-#pragma once
-
-#include <policyd/sdk/policy-value.h>
-
-#include <string>
-#include <map>
-#include <unordered_map>
-
-namespace policyd {
-
-struct API {
- static PolicyValue Get(const std::string& policy);
- static std::unordered_map<std::string, PolicyValue> GetAll();
-
- struct Admin {
- static void Set(const std::string& policy, const PolicyValue& value);
-
- static void Enroll(const std::string& admin, uid_t uid);
- static void Disenroll(const std::string& admin, uid_t uid);
-
- static std::multimap<std::string, int> GetAll();
- };
-};
-
-} // namespace policyd
+++ /dev/null
-# Copyright (c) 2019 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.
-#
-
-ADD_POLICYD_LIBRARY(policyd_core api.cpp
- policy-manager.cpp
- policy-loader.cpp
- policy-storage.cpp)
-
-FILE(GLOB SDK_TESTS "tests/*.cpp")
-ADD_POLICYD_TEST(${SDK_TESTS})
+++ /dev/null
-/*
- * Copyright (c) 2019 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
- */
-
-#include <policyd/api.h>
-
-#include "policy-manager.h"
-
-namespace policyd {
-
-PolicyValue API::Get(const std::string& policy)
-{
- return PolicyManager::Instance().get(policy);
-}
-
-std::unordered_map<std::string, PolicyValue> API::GetAll()
-{
- return PolicyManager::Instance().getAll();
-}
-
-void API::Admin::Set(const std::string& policy, const PolicyValue& value)
-{
- // TODO(Sangwan): Get admin name from peer PID
- PolicyManager::Instance().set(policy, value, "admin");
-}
-
-void API::Admin::Enroll(const std::string& admin, uid_t uid)
-{
- PolicyManager::Instance().enroll(admin, uid);
-}
-
-void API::Admin::Disenroll(const std::string& admin, uid_t uid)
-{
- PolicyManager::Instance().disenroll(admin, uid);
-}
-
-std::multimap<std::string, int> API::Admin::GetAll()
-{
- return PolicyManager::Instance().getAdmins();
-}
-
-} // namespace policyd
+++ /dev/null
-/*
- * Copyright (c) 2019 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
- */
-#pragma once
-
-#include <string>
-
-namespace policyd {
-namespace schema {
-
-struct Admin {
- int id = -1;
- std::string pkg;
- int uid = -1;
- std::string key;
- int removable = -1;
-};
-
-struct ManagedPolicy {
- int id = -1;
- int aid = -1;
- int pid = -1;
- int value = -1;
-};
-
-struct PolicyDefinition {
- int id = -1;
- int scope = -1;
- std::string name;
- int ivalue = -1;
-};
-
-} // namespace schema
-} // namespace policyd
+++ /dev/null
-/*
- * Copyright (c) 2019 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
- */
-
-#include "policy-loader.h"
-
-namespace policyd {
-
-PolicyProvider* PolicyLoader::load(const std::string& path)
-{
- PluginLoader loader(path);
- PolicyProvider::FactoryType factory = nullptr;
- loader.load(PolicyProvider::getFactoryName(), factory);
- if (factory == nullptr)
- std::runtime_error("Failed to load symbol. " + PolicyProvider::getFactoryName());
-
- auto provider = (*factory)();
- if (provider == nullptr)
- std::runtime_error("Failed to make provider. " + PolicyProvider::getFactoryName());
-
- return provider;
-}
-
-PluginLoader::PluginLoader(const std::string& path, int flag)
- : handle(::dlopen(path.c_str(), flag), [](void*)->int{return 0;})
-// Cleaning object after dlclose() makes SEGFAULT.
-// TODO: Sync dynamic loading's life-cycle with program.(PluginManager)
-// : handle(::dlopen(path.c_str(), flag), ::dlclose)
-{
- if (handle == nullptr)
- throw std::invalid_argument("Failed to open: " + path);
-}
-
-} // namespace policyd
+++ /dev/null
-/*
- * Copyright (c) 2019 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
- */
-
-#pragma once
-
-#include <policyd/sdk/policy-provider.h>
-
-#include <stdexcept>
-#include <string>
-#include <memory>
-
-#include <dlfcn.h>
-
-namespace policyd {
-
-struct PolicyLoader final {
- static PolicyProvider* load(const std::string& path);
-};
-
-class PluginLoader final {
-public:
- explicit PluginLoader(const std::string& path, int flag = RTLD_LAZY);
-
- template<typename T>
- void load(const std::string& name, T& symbol);
-
-private:
- using Handle = std::unique_ptr<void, int(*)(void*)>;
- Handle handle;
-};
-
-template<typename T>
-void PluginLoader::load(const std::string& name, T& symbol)
-{
- symbol = reinterpret_cast<T>(::dlsym(handle.get(), name.c_str()));
- if (symbol == nullptr)
- throw std::runtime_error("Failed to load: " + name);
-}
-
-} // namespace policyd
+++ /dev/null
-/*
- * Copyright (c) 2019 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
- */
-
-#include "policy-manager.h"
-#include "policy-loader.h"
-
-#include <vist/common/audit/logger.h>
-
-#include <klay/filesystem.h>
-
-namespace policyd {
-
-PolicyManager::PolicyManager() : storage(DB_PATH)
-{
- loadProviders(PLUGIN_INSTALL_DIR);
- int cnt = loadPolicies();
- INFO(VIST, std::to_string(cnt) + "-policies loaded");
-}
-
-std::pair<int, int> PolicyManager::loadProviders(const std::string& path)
-{
- INFO(VIST, "Load policies from :" << path);
- klay::File dir(path);
- if (!dir.exists() || !dir.isDirectory())
- throw std::invalid_argument("Plugin directory is wrong.: " + path);
-
- int passed = 0, failed = 0;
- klay::DirectoryIterator end;
- for (klay::DirectoryIterator iter(path); iter != end; ++iter) {
- if (!iter->isFile())
- continue;
-
- try {
- auto provider = PolicyLoader::load(iter->getPath());
- DEBUG(VIST, "Loaded provider: " << provider->getName());
-
- bool exist = false;
- for (const auto& p : this->providers) {
- if (p->getName() == provider->getName()) {
- exist = true;
- break;
- }
- }
-
- if (!exist)
- this->providers.emplace_back(std::move(provider));
- } catch (const std::exception& e) {
- ++failed;
- ERROR(VIST, "Failed to load: " << iter->getPath() << e.what());
- continue;
- }
-
- ++passed;
- }
-
- INFO(VIST, "Loaded result >> passed: " << passed << ", failed: " << failed);
- return std::make_pair(passed, failed);
-}
-
-int PolicyManager::loadPolicies()
-{
- bool changed = false;
-
- /// Make policy-provider map for performance
- for (const auto& provider : providers) {
- for (const auto& pair : provider->global) {
- policies[pair.first] = provider->getName();
-
- /// Check the policy is defined on policy-storage
- if (!storage.exists(pair.first)) {
- INFO(VIST, "Define global policy: " << pair.first);
- storage.define(0, pair.first, pair.second->getInitial().value);
- changed = true;
- }
- }
-
- for (const auto& pair : provider->domain) {
- policies[pair.first] = provider->getName();
-
- if (!storage.exists(pair.first)) {
- INFO(VIST, "Define domain policy: " << pair.first);
- storage.define(1, pair.first, pair.second->getInitial().value);
- changed = true;
- }
- }
- }
-
- if (changed)
- storage.syncPolicyDefinition();
-
- return policies.size();
-}
-
-void PolicyManager::enroll(const std::string& admin, uid_t uid)
-{
- this->storage.enroll(admin, uid);
-}
-
-void PolicyManager::disenroll(const std::string& admin, uid_t uid)
-{
- this->storage.disenroll(admin, uid);
-}
-
-void PolicyManager::set(const std::string& policy, const PolicyValue& value,
- const std::string& admin, uid_t uid)
-{
- if (policies.find(policy) == policies.end())
- std::runtime_error("Not exist policy: " + policy);
-
- storage.update(admin, uid, policy, value);
-
- for (auto& p : providers) {
- if (p->getName() != policies[policy])
- continue;
-
- if (p->global.find(policy) != p->global.end()) {
- p->global[policy]->set(value);
- return;
- }
-
- if (p->domain.find(policy) != p->domain.end()) {
- p->domain[policy]->set(uid, value);
- return;
- }
- }
-}
-
-PolicyValue PolicyManager::get(const std::string& policy, uid_t uid)
-{
- return storage.strictest(policy, uid);
-}
-
-std::unordered_map<std::string, PolicyValue> PolicyManager::getAll(uid_t uid)
-{
- return storage.strictest(uid);
-}
-
-std::multimap<std::string, int> PolicyManager::getAdmins()
-{
- return storage.getAdmins();
-}
-
-} // namespace policyd
+++ /dev/null
-/*
- * Copyright (c) 2019 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
- */
-
-#pragma once
-
-#include <policyd/sdk/policy-provider.h>
-#include <policyd/sdk/policy-value.h>
-
-#include "policy-storage.h"
-
-#include <exception>
-#include <map>
-#include <memory>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-#include <gtest/gtest_prod.h>
-
-namespace policyd {
-
-class PolicyManager final {
-public:
- PolicyManager(const PolicyManager&) = delete;
- PolicyManager& operator=(const PolicyManager&) = delete;
-
- PolicyManager(PolicyManager&&) = delete;
- PolicyManager& operator=(PolicyManager&&) = delete;
-
- static PolicyManager& Instance() {
- static PolicyManager manager;
- return manager;
- }
-
- void enroll(const std::string& admin, uid_t uid);
- void disenroll(const std::string& admin, uid_t uid);
-
- void set(const std::string& policy, const PolicyValue& value,
- const std::string& admin, uid_t uid = 0);
- PolicyValue get(const std::string& policy, uid_t uid = 0);
- std::unordered_map<std::string, PolicyValue> getAll(uid_t uid = 0);
-
- std::multimap<std::string, int> getAdmins();
-
-private:
- explicit PolicyManager();
- ~PolicyManager() = default;
-
- std::pair<int, int> loadProviders(const std::string& path);
- int loadPolicies();
-
- PolicyStorage storage;
- std::vector<std::unique_ptr<PolicyProvider>> providers;
-
- /// Policy-Provider
- std::unordered_map<std::string, std::string> policies;
-
- FRIEND_TEST(PolicyCoreTests, policy_loader);
-};
-
-} // namespace policyd
+++ /dev/null
-/*
- * Copyright (c) 2019 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
- */
-
-#include "policy-storage.h"
-
-#include <vist/common/audit/logger.h>
-
-#include <klay/db/column.h>
-#include <klay/db/query-builder.h>
-#include <klay/db/statement.h>
-#include <klay/exception.h>
-
-#include <fstream>
-
-using namespace query_builder;
-using namespace policyd::schema;
-
-namespace {
-
-auto adminTable = make_table("admin",
- make_column("id", &Admin::id),
- make_column("pkg", &Admin::pkg),
- make_column("uid", &Admin::uid),
- make_column("key", &Admin::key),
- make_column("removable", &Admin::removable));
-
-auto managedPolTable = make_table("managed_policy",
- make_column("id", &ManagedPolicy::id),
- make_column("aid", &ManagedPolicy::aid),
- make_column("pid", &ManagedPolicy::pid),
- make_column("value", &ManagedPolicy::value));
-
-auto definitionTable = make_table("policy_definition",
- make_column("id", &PolicyDefinition::id),
- make_column("scope", &PolicyDefinition::scope),
- make_column("name", &PolicyDefinition::name),
- make_column("ivalue", &PolicyDefinition::ivalue));
-
-const std::string SCRIPT_BASE = SCRIPT_INSTALL_DIR;
-const std::string SCRIPT_CREATE_SCHEMA = "create_schema";
-
-} // anonymous namespace
-
-namespace policyd {
-
-PolicyStorage::PolicyStorage(const std::string& path) :
- database(std::make_shared<database::Connection>(path,
- database::Connection::ReadWrite |
- database::Connection::Create))
-{
- database->exec("PRAGMA foreign_keys = ON;");
- database->exec(getScript(SCRIPT_CREATE_SCHEMA));
-
- sync();
-}
-
-void PolicyStorage::sync()
-{
- DEBUG(VIST, "Sync policy storage to cache object.");
- syncPolicyDefinition();
- syncAdmin();
- syncManagedPolicy();
-}
-
-void PolicyStorage::syncPolicyDefinition()
-{
- this->definitions.clear();
- std::string query = definitionTable.selectAll();
- database::Statement stmt(*database, query);
-
- while (stmt.step()) {
- PolicyDefinition pd;
- pd.id = stmt.getColumn(0);
- pd.scope = stmt.getColumn(1);
- pd.name = std::string(stmt.getColumn(2));
- pd.ivalue = stmt.getColumn(3);
- DEBUG(VIST, "Defined policy:" + pd.name);
- this->definitions.emplace(pd.name, std::move(pd));
- }
-}
-
-void PolicyStorage::syncAdmin()
-{
- this->admins.clear();
- std::string query = adminTable.selectAll();
- database::Statement stmt(*database, query);
-
- while (stmt.step()) {
- Admin admin;
- admin.id = stmt.getColumn(0);
- admin.pkg = std::string(stmt.getColumn(1));
- admin.uid = stmt.getColumn(2);
- admin.key = std::string(stmt.getColumn(3));
- admin.removable = stmt.getColumn(4);
-
- std::string alias = getAlias(admin.pkg, admin.uid);
- this->admins.emplace(alias, std::move(admin));
- }
-}
-
-void PolicyStorage::syncManagedPolicy()
-{
- this->managedPolicies.clear();
- std::string query = managedPolTable.selectAll();
- database::Statement stmt(*database, query);
-
- while (stmt.step()) {
- ManagedPolicy mp;
- mp.id = stmt.getColumn(0);
- mp.aid = stmt.getColumn(1);
- mp.pid = stmt.getColumn(2);
- mp.value = stmt.getColumn(3);
- this->managedPolicies.emplace(mp.pid, std::move(mp));
- }
-}
-
-std::string PolicyStorage::getScript(const std::string& name)
-{
- std::string path = SCRIPT_BASE + "/" + name + ".sql";
- std::ifstream is(path);
- if (is.fail())
- throw std::invalid_argument("Failed to open script: " + path);
-
- std::istreambuf_iterator<char> begin(is), end;
- auto content = std::string(begin, end);
- if (content.empty())
- throw std::runtime_error("Failed to read script: " + path);
-
- return content;
-}
-
-void PolicyStorage::define(int scope, const std::string& policy, int ivalue)
-{
- if (definitions.find(policy) != definitions.end()) {
- INFO(VIST, "Policy is already defined: " + policy);
- return;
- }
-
- PolicyDefinition pd;
- pd.scope = scope;
- pd.name = policy;
- pd.ivalue = ivalue;
-
- std::string insertQuery = definitionTable.insert(&PolicyDefinition::scope,
- &PolicyDefinition::name,
- &PolicyDefinition::ivalue);
- database::Statement stmt(*database, insertQuery);
- stmt.bind(1, pd.scope);
- stmt.bind(2, pd.name);
- stmt.bind(3, pd.ivalue);
- if (!stmt.exec())
- throw std::runtime_error("Failed to define policy: " + pd.name);
-}
-
-void PolicyStorage::enroll(const std::string& name, uid_t uid)
-{
- std::string alias = getAlias(name, uid);
- INFO(VIST, "Enroll admin: " + alias);
- if (admins.find(alias) != admins.end()) {
- ERROR(VIST, "Admin is aleady enrolled.: " + alias);
- return;
- }
-
- Admin admin;
- admin.pkg = name;
- admin.uid = static_cast<int>(uid);
- admin.key = "Not supported";
- admin.removable = true;
-
- std::string insertQuery = adminTable.insert(&Admin::pkg, &Admin::uid,
- &Admin::key, &Admin::removable);
- database::Statement stmt(*database, insertQuery);
- stmt.bind(1, admin.pkg);
- stmt.bind(2, admin.uid);
- stmt.bind(3, admin.key);
- stmt.bind(4, admin.removable);
- if (!stmt.exec())
- throw std::runtime_error("Failed to enroll admin: " + admin.pkg);
-
- /// Sync admin for getting admin ID.
- syncAdmin();
- /// ManagedPolicy is triggered by enrolling admin.
- syncManagedPolicy();
-
- int count = managedPolicies.size() / admins.size();
- INFO(VIST, "Admin[" + alias + "] manages " + std::to_string(count) + "-policies.");
-}
-
-void PolicyStorage::disenroll(const std::string& name, uid_t uid)
-{
- std::string alias = getAlias(name, uid);
- INFO(VIST, "Disenroll admin: " + alias);
- if (admins.find(alias) == admins.end()) {
- ERROR(VIST, "Not exist admin: " + alias);
- return;
- } else {
- admins.erase(alias);
- }
-
- int iUid = static_cast<int>(uid);
- std::string query = adminTable.remove().where(expr(&Admin::pkg) == name &&
- expr(&Admin::uid) == iUid);
- database::Statement stmt(*database, query);
- stmt.bind(1, name);
- stmt.bind(2, iUid);
- if (!stmt.exec())
- throw std::runtime_error("Failed to disenroll admin: " + name);
-}
-
-void PolicyStorage::update(const std::string& name, uid_t uid,
- const std::string& policy, const PolicyValue& value)
-{
- std::string alias = getAlias(name, uid);
- if (admins.find(alias) == admins.end())
- throw std::runtime_error("Not exist admin: " + alias);
-
- if (definitions.find(policy) == definitions.end())
- throw std::runtime_error("Not exist policy: " + policy);
-
- DEBUG(VIST, "Policy-update is called by admin: " + alias + ", about: " + policy +
- ", value: " + std::to_string(value));
-
- int policyId = definitions[policy].id;
- int policyValue = value;
- int adminId = admins[alias].id;
- std::string query = managedPolTable.update(&ManagedPolicy::value)
- .where(expr(&ManagedPolicy::pid) == policyId &&
- expr(&ManagedPolicy::aid) == adminId);
- database::Statement stmt(*database, query);
- stmt.bind(1, policyValue);
- stmt.bind(2, policyId);
- stmt.bind(3, adminId);
- if (!stmt.exec())
- throw runtime::Exception("Failed to update policy:" + policy);
-
- syncManagedPolicy();
-}
-
-PolicyValue PolicyStorage::strictest(const std::string& policy, uid_t uid)
-{
- if (definitions.find(policy) == definitions.end())
- throw std::runtime_error("Not exist policy: " + policy);
-
- // There is no enrolled admins.
- if (managedPolicies.size() == 0)
- return PolicyValue(definitions[policy].ivalue);
-
- std::shared_ptr<PolicyValue> strictest = nullptr;
- int policyId = definitions[policy].id;
- auto range = managedPolicies.equal_range(policyId);
- for (auto iter = range.first; iter != range.second; iter++) {
- if (uid != 0) {
- int ret = getUid(iter->second.aid);
- if (ret == -1 || ret != static_cast<int>(uid))
- continue;
- }
-
- int value = iter->second.value;
- if (strictest == nullptr)
- strictest = std::make_shared<PolicyValue>(value);
- else
- strictest->value = (*strictest < value) ? strictest->value : value;
-
- DEBUG(VIST, "The strictest of policy[" + policy +
- "] : " + std::to_string(strictest->value));
- }
-
- if (strictest == nullptr)
- throw std::runtime_error("Not exist managed policy: " + policy);
-
- return std::move(*strictest);
-}
-
-std::unordered_map<std::string, PolicyValue> PolicyStorage::strictest(uid_t uid)
-{
- std::unordered_map<std::string, PolicyValue> policies;
- for (const auto& pair : definitions) {
- std::string name = pair.first;
- auto value = this->strictest(name, uid);
-
- policies.emplace(std::move(name), std::move(value));
- }
-
- return policies;
-}
-
-std::multimap<std::string, int> PolicyStorage::getAdmins()
-{
- std::multimap<std::string, int> admins;
- for (const auto& pair : this->admins) {
- std::string alias = pair.first;
- int uid = pair.second.uid;
- /// Erase uid from alias(name + uid)
- std::size_t pos = alias.rfind(std::to_string(uid));
- alias.erase(pos, std::to_string(uid).size());
-
- admins.emplace(std::move(alias), uid);
- }
-
- return admins;
-}
-
-std::string PolicyStorage::getAlias(const std::string& name, uid_t uid) const noexcept
-{
- return name + std::to_string(uid);
-}
-
-int PolicyStorage::getUid(int adminId) const noexcept
-{
- for (const auto& a : admins)
- if (a.second.id == adminId)
- return a.second.uid;
-
- return -1;
-}
-
-} // namespace policyd
+++ /dev/null
-/*
- * Copyright (c) 2019 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
- *
- * ttp://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
- */
-
-#pragma once
-
-#include <policyd/sdk/policy-value.h>
-
-#include "db-schema.h"
-
-#include <map>
-#include <memory>
-#include <unordered_map>
-#include <vector>
-
-#include <klay/db/connection.h>
-
-namespace policyd {
-
-using namespace schema;
-
-class PolicyStorage final {
-public:
- explicit PolicyStorage(const std::string& path);
-
- /// TODO(Sangwan): Consider to support lazy sync
- void sync();
-
- void syncPolicyDefinition();
- void syncAdmin();
- void syncManagedPolicy();
-
- inline bool exists(const std::string& policy) const noexcept {
- return definitions.find(policy) != definitions.end();
- }
-
- inline bool isActivated() const noexcept {
- return admins.size() > 0 && managedPolicies.size() > 0;
- }
-
- void enroll(const std::string& admin, uid_t uid);
- void disenroll(const std::string& admin, uid_t uid);
-
- void define(int scope, const std::string& policy, int ivalue);
- void update(const std::string& admin, uid_t uid,
- const std::string& policy, const PolicyValue& value);
-
- PolicyValue strictest(const std::string& policy, uid_t uid = 0);
- /// Return all strictest policy values
- std::unordered_map<std::string, PolicyValue> strictest(uid_t uid = 0);
-
- /// Admin name can be duplicated
- std::multimap<std::string, int> getAdmins();
-
-private:
- std::string getScript(const std::string& name);
- std::string getAlias(const std::string& name, uid_t uid) const noexcept;
- int getUid(int adminId) const noexcept;
-
- std::shared_ptr<klay::database::Connection> database;
-
- /// DB Cache objects
- /// TODO(Sangwan): add locking mechanism
- std::unordered_map<std::string, PolicyDefinition> definitions;
- std::unordered_map<std::string, Admin> admins;
- std::unordered_multimap<int, ManagedPolicy> managedPolicies;
-};
-
-} // namespace policyd
+++ /dev/null
-/*
- * Copyright (c) 2019 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
- */
-
-#include <gtest/gtest.h>
-
-#include "../policy-manager.h"
-
-namespace policyd {
-
-class PolicyCoreTests : public testing::Test {};
-
-TEST_F(PolicyCoreTests, policy_loader) {
- auto& manager = PolicyManager::Instance();
-
- EXPECT_TRUE(manager.providers.size() > 0);
- EXPECT_TRUE(manager.policies.size() > 0);
-}
-
-TEST_F(PolicyCoreTests, policy_set_get) {
- auto& manager = PolicyManager::Instance();
- manager.enroll("testAdmin", 0);
- manager.set("bluetooth", PolicyValue(5), "testAdmin", 0);
-
- auto policy = manager.get("bluetooth", 0);
- EXPECT_EQ(policy.value, 5);
-
- manager.enroll("testAdmin1", 0);
- manager.set("bluetooth", PolicyValue(10), "testAdmin1", 0);
-
- /// Manager should return the strongest policy.
- policy = manager.get("bluetooth", 0);
- EXPECT_EQ(policy.value, 5);
-
- manager.disenroll("testAdmin", 0);
- manager.disenroll("testAdmin1", 0);
-}
-
-} // namespace policyd
+++ /dev/null
-/*
- * Copyright (c) 2019 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
- */
-
-#include <gtest/gtest.h>
-
-#include <memory>
-
-#include "../policy-storage.h"
-
-using namespace policyd;
-
-class PolicyStorageTests : public testing::Test {
-public:
- void SetUp() override {
- /// TODO(Sangwan KWon): Change to test db
- this->storage = std::make_shared<PolicyStorage>(DB_PATH);
- }
-
- std::shared_ptr<PolicyStorage> getStorage() {
- return this->storage;
- }
-
-private:
- std::shared_ptr<PolicyStorage> storage = nullptr;
-};
-
-TEST_F(PolicyStorageTests, initialize) {
- bool isRaised = false;
-
- try {
- // DB is maden at run-time
- PolicyStorage storage("/tmp/dummy");
- } catch (const std::exception&) {
- isRaised = true;
- }
-
- EXPECT_FALSE(isRaised);
-}
-
-TEST_F(PolicyStorageTests, enrollment) {
- auto storage = getStorage();
- EXPECT_FALSE(storage->isActivated());
-
- storage->enroll("testAdmin", 0);
- storage->enroll("testAdmin", 1);
- EXPECT_TRUE(storage->isActivated());
-
- storage->disenroll("testAdmin", 0);
- EXPECT_TRUE(storage->isActivated());
-
- storage->disenroll("testAdmin", 1);
- EXPECT_FALSE(storage->isActivated());
-}
-
-TEST_F(PolicyStorageTests, update) {
- auto storage = getStorage();
- storage->enroll("testAdmin", 0);
-
- bool isRaised = false;
- try {
- storage->update("testAdmin", 1, "bluetooth", PolicyValue(0));
- } catch (const std::exception&) {
- isRaised = true;
- }
-
- isRaised = false;
- try {
- storage->update("testAdmin", 0, "bluetooth", PolicyValue(0));
- } catch (const std::exception&) {
- isRaised = true;
- }
- EXPECT_FALSE(isRaised);
-
- isRaised = false;
- try {
- storage->update("testAdmin", 0, "FakePolicy", PolicyValue(0));
- } catch (const std::exception&) {
- isRaised = true;
- }
- EXPECT_TRUE(isRaised);
-
- storage->disenroll("testAdmin", 0);
-}
-
-TEST_F(PolicyStorageTests, strictest) {
- auto storage = getStorage();
- storage->enroll("testAdmin", 0);
- storage->enroll("testAdmin", 1);
-
- storage->update("testAdmin", 0, "bluetooth", PolicyValue(3));
- storage->update("testAdmin", 1, "bluetooth", PolicyValue(6));
-
- bool isRaised = false;
- try {
- auto value = storage->strictest("FakePolicy", 3);
- } catch (const std::exception&) {
- isRaised = true;
- }
- EXPECT_TRUE(isRaised);
-
- /// as global policy
- auto policy = storage->strictest("bluetooth");
- EXPECT_EQ(policy.value, 3);
-
- /// as domain policy
- policy = storage->strictest("bluetooth", 1);
- EXPECT_EQ(policy.value, 6);
-
- storage->disenroll("testAdmin", 0);
- storage->disenroll("testAdmin", 1);
-}
-
-TEST_F(PolicyStorageTests, strictest_all) {
- auto storage = getStorage();
- storage->enroll("testAdmin", 1);
-
- /// as global policy
- auto policies = storage->strictest();
- EXPECT_TRUE(policies.size() > 0);
-
- /// as domain policy
- policies = storage->strictest(1);
- EXPECT_TRUE(policies.size() > 0);
-
- storage->disenroll("testAdmin", 1);
-}
-
-TEST_F(PolicyStorageTests, admin_list) {
- auto storage = getStorage();
-
- auto admins = storage->getAdmins();
- EXPECT_EQ(admins.size(), 0);
-
- storage->enroll("testAdmin", 1);
- admins = storage->getAdmins();
- EXPECT_EQ(admins.size(), 1);
-
- storage->enroll("testAdmin", 2);
- admins = storage->getAdmins();
- EXPECT_EQ(admins.size(), 2);
-
- storage->disenroll("testAdmin", 2);
- admins = storage->getAdmins();
- EXPECT_EQ(admins.size(), 1);
-
- storage->disenroll("testAdmin", 1);
- admins = storage->getAdmins();
- EXPECT_EQ(admins.size(), 0);
-}
+++ /dev/null
-# Copyright (c) 2019 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(GLOB SDK_TESTS "tests/*.cpp")
-ADD_POLICYD_TEST(${SDK_TESTS})
+++ /dev/null
-/*
- * Copyright (c) 2019 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
- */
-
-#pragma once
-
-#include "policy-model.h"
-
-#include <exception>
-#include <string>
-#include <unordered_map>
-
-#include <sys/types.h>
-
-namespace policyd {
-
-class DomainPolicy : public PolicyModel {
-public:
- explicit DomainPolicy(std::string name, PolicyValue initial) noexcept :
- PolicyModel(std::move(name), std::move(initial)) {}
- virtual ~DomainPolicy() = default;
-
- DomainPolicy(DomainPolicy&&) = default;
- DomainPolicy& operator=(DomainPolicy&&) = default;
-
- inline void set(uid_t domain, const PolicyValue& value) {
- current[domain] = value;
-
- try {
- this->onChanged(domain, value);
- } catch (const std::exception& e) {
- current.erase(domain);
- std::rethrow_exception(std::current_exception());
- }
- }
-
- inline const PolicyValue& get(uid_t domain) const {
- if (!current.count(domain))
- throw std::runtime_error("Policy value should be set once before use.");
-
- return current.at(domain);
- }
-
- virtual void onChanged(uid_t domain, const PolicyValue& value) = 0;
-
-private:
- std::unordered_map<uid_t, PolicyValue> current;
-};
-
-} // namespace policyd
+++ /dev/null
-/*
- * Copyright (c) 2019 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
- */
-
-#pragma once
-
-#include "policy-model.h"
-
-#include <stdexcept>
-#include <string>
-
-namespace policyd {
-
-class GlobalPolicy : public PolicyModel {
-public:
- explicit GlobalPolicy(std::string name, PolicyValue initial) noexcept :
- PolicyModel(std::move(name), std::move(initial)) {}
- virtual ~GlobalPolicy() = default;
-
- GlobalPolicy(GlobalPolicy&&) = default;
- GlobalPolicy& operator=(GlobalPolicy&&) = default;
-
- inline void set(const PolicyValue& value) {
- current = value;
- ready = true;
-
- try {
- this->onChanged(value);
- } catch (const std::exception& e) {
- ready = false;
- std::rethrow_exception(std::current_exception());
- }
- }
-
- inline const PolicyValue& get() const {
- if (!ready)
- throw std::runtime_error("Policy value should be set once before use.");
-
- return current;
- }
-
- virtual void onChanged(const PolicyValue& value) = 0;
-
-private:
- PolicyValue current;
- bool ready = false;
-};
-
-} // namespace policyd
+++ /dev/null
-/*
- * Copyright (c) 2019 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
- */
-
-#pragma once
-
-#include"policy-value.h"
-
-#include <string>
-
-namespace policyd {
-
-class PolicyModel {
-public:
- explicit PolicyModel(std::string name, PolicyValue initial) noexcept :
- name(std::move(name)), initial(std::move(initial)) {}
- virtual ~PolicyModel() = default;
-
- PolicyModel(const PolicyModel&) = delete;
- PolicyModel& operator=(const PolicyModel&) = delete;
-
- PolicyModel(PolicyModel&&) = default;
- PolicyModel& operator=(PolicyModel&&) = default;
-
- const std::string& getName() const noexcept { return name; }
- const PolicyValue& getInitial() const noexcept { return initial; }
-
-protected:
- std::string name;
- PolicyValue initial;
-};
-
-} // namespace policyd
+++ /dev/null
-/*
- * Copyright (c) 2019 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
- */
-
-#pragma once
-
-#include "domain-policy.h"
-#include "global-policy.h"
-
-#include <cstddef>
-#include <memory>
-#include <unordered_map>
-
-namespace policyd {
-
-class PolicyProvider {
-public:
- using FactoryType = PolicyProvider* (*)();
-
- explicit PolicyProvider(std::string name) noexcept : name(std::move(name)) {}
- virtual ~PolicyProvider() = default;
-
- inline void add(const std::shared_ptr<GlobalPolicy>& policy) {
- global[policy->getName()] = policy;
- }
-
- inline void add(const std::shared_ptr<DomainPolicy>& policy) {
- domain[policy->getName()] = policy;
- }
-
- inline const std::string& getName() const noexcept { return name; }
- static const std::string& getFactoryName() noexcept {
- static std::string name = "PolicyFactory";
- return name;
- }
-
- std::size_t gsize() { return global.size(); }
- std::size_t dsize() { return domain.size(); }
-
-private:
- std::string name;
- std::unordered_map<std::string, std::shared_ptr<GlobalPolicy>> global;
- std::unordered_map<std::string, std::shared_ptr<DomainPolicy>> domain;
-
- friend class PolicyManager;
-};
-
-} // namespace policyd
+++ /dev/null
-/*
- * Copyright (c) 2019 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
- */
-
-#pragma once
-
-namespace policyd {
-
-// TODO: Support various value type
-struct PolicyValue final {
- explicit PolicyValue(int value) noexcept : value(value) {}
- explicit PolicyValue() noexcept = default;
- ~PolicyValue() = default;
-
- PolicyValue(const PolicyValue&) noexcept = default;
- PolicyValue& operator=(const PolicyValue&) noexcept = default;
-
- PolicyValue(PolicyValue&&) noexcept = default;
- PolicyValue& operator=(PolicyValue&&) noexcept = default;
-
- PolicyValue& operator=(int val) {
- value = val;
- return *this;
- }
-
- operator int() const { return value; }
- bool operator==(const PolicyValue& rhs) const { return value == rhs.value; }
- bool operator!=(const PolicyValue& rhs) const { return value != rhs.value; }
- bool operator<(const PolicyValue& rhs) const { return value < rhs.value; }
-
- int value = -1;
-};
-
-} // namespace policyd
+++ /dev/null
-/*
- * Copyright (c) 2019 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
- */
-
-#include <gtest/gtest.h>
-
-#include "../domain-policy.h"
-#include "../global-policy.h"
-#include "../policy-provider.h"
-
-#include <exception>
-
-namespace {
- int g_value = -1;
- int d_value = -1;
- uid_t d_uid = 0;
-} // anonymous namespace
-
-using namespace policyd;
-
-class PolicySDKTests : public testing::Test {};
-
-class TestGlobalPolicy : public GlobalPolicy {
-public:
- TestGlobalPolicy() : GlobalPolicy("test_policy", PolicyValue(1)) {}
-
- virtual void onChanged(const PolicyValue& value) {
- g_value = value;
- }
-};
-
-TEST_F(PolicySDKTests, global_policy) {
- TestGlobalPolicy policy;
-
- EXPECT_EQ(policy.getName(), "test_policy");
- EXPECT_EQ(policy.getInitial(), 1);
-
- // Policy value should be set once before use
- bool isRaised = false;
- try {
- auto value = policy.get();
- } catch (const std::exception&) {
- isRaised = true;
- }
-
- EXPECT_TRUE(isRaised);
-
- policy.set(PolicyValue(3));
- EXPECT_EQ(3, g_value);
- EXPECT_EQ(3, policy.get());
-}
-
-class TestDomainPolicy : public DomainPolicy {
-public:
- TestDomainPolicy() : DomainPolicy("test_policy", PolicyValue(1)) {}
-
- virtual void onChanged(uid_t domain, const PolicyValue& value) {
- d_uid = domain;
- d_value = value;
- }
-};
-
-TEST_F(PolicySDKTests, domain_policy) {
- TestDomainPolicy policy;
- uid_t domain = 5001;
-
- EXPECT_EQ(policy.getName(), "test_policy");
- EXPECT_EQ(policy.getInitial(), 1);
-
- // Policy value should be set once before use
- bool isRaised = false;
- try {
- auto value = policy.get(domain);
- } catch (const std::exception&) {
- isRaised = true;
- }
-
- EXPECT_TRUE(isRaised);
-
- policy.set(domain, PolicyValue(3));
- EXPECT_EQ(d_uid, domain);
- EXPECT_EQ(3, policy.get(domain));
-}
-
-TEST_F(PolicySDKTests, policy_provider) {
- PolicyProvider provider("testProvider");
- provider.add(std::make_shared<TestGlobalPolicy>());
- provider.add(std::make_shared<TestDomainPolicy>());
-
- EXPECT_EQ(1, provider.gsize());
- EXPECT_EQ(1, provider.dsize());
-}
SET(TARGET_VIST_TEST vist-test)
SET(${TARGET_VIST_LIB}_SRCS "")
-SET(${TARGET_VIST_LIB}_DEPS "")
SET(${TARGET_VIST_LIB}_TESTS "")
-INCLUDE_DIRECTORIES(. common)
+SET(DEPENDENCY klay)
+
+PKG_CHECK_MODULES(VIST_DEPS REQUIRED ${DEPENDENCY})
+
+INCLUDE_DIRECTORIES(SYSTEM . common ${VIST_DEPS_INCLUDE_DIRS})
+
+ADD_DEFINITIONS(-DDB_PATH="${DB_INSTALL_DIR}/.vist.db"
+ -DPLUGIN_INSTALL_DIR="${PLUGIN_INSTALL_DIR}"
+ -DSCRIPT_INSTALL_DIR="${SCRIPT_INSTALL_DIR}")
ADD_SUBDIRECTORY(client)
ADD_SUBDIRECTORY(common)
ADD_SUBDIRECTORY(notification)
+ADD_SUBDIRECTORY(policy)
ADD_SUBDIRECTORY(service)
ADD_LIBRARY(${TARGET_VIST_LIB} STATIC ${${TARGET_VIST_LIB}_SRCS})
-TARGET_LINK_LIBRARIES(${TARGET_VIST_LIB} ${${TARGET_VIST_LIB}_DEPS}
+TARGET_LINK_LIBRARIES(${TARGET_VIST_LIB} ${VSIT_DEPS_LIBRARIES}
+ ${TARGET_VIST_POLICY_LIB}
${TARGET_OSQUERY_LIB})
ADD_EXECUTABLE(${TARGET_VIST_DAEMON} main/main.cpp)
TARGET_LINK_LIBRARIES(${TARGET_VIST_DAEMON} ${TARGET_VIST_LIB})
TARGET_LINK_WHOLE(${TARGET_VIST_DAEMON} ${TARGET_OSQUERY_LIB})
+SET_TARGET_PROPERTIES(${TARGET_VIST_DAEMON} PROPERTIES COMPILE_FLAGS "-fPIE")
+SET_TARGET_PROPERTIES(${TARGET_VIST_DAEMON} PROPERTIES LINK_FLAGS "-pie")
INSTALL(TARGETS ${TARGET_VIST_DAEMON}
DESTINATION ${CMAKE_INSTALL_BINDIR}
PERMISSIONS OWNER_READ
ADD_EXECUTABLE(${TARGET_VIST_TEST} main/tests.cpp
${${TARGET_VIST_LIB}_TESTS})
TARGET_LINK_LIBRARIES(${TARGET_VIST_TEST} ${TARGET_VIST_LIB}
- gtest)
+ gtest)
TARGET_LINK_WHOLE(${TARGET_VIST_TEST} ${TARGET_OSQUERY_LIB})
ADD_TEST(${TARGET_VIST_TEST} ${TARGET_VIST_TEST})
INSTALL(TARGETS ${TARGET_VIST_TEST}
--- /dev/null
+/*
+ * Copyright (c) 2019 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
+ */
+
+#include <gtest/gtest.h>
+
+#include "../query.h"
+
+#include <chrono>
+#include <thread>
+
+using namespace vist;
+
+class ClientTests : public testing::Test {};
+
+TEST_F(ClientTests, query) {
+ auto rows = Query::Execute("SELECT * FROM policy");
+
+ EXPECT_TRUE(rows.size() > 0);
+}
+
+TEST_F(ClientTests, admin_enrollment) {
+ auto rows = Query::Execute("INSERT INTO policy_admin (name, uid) "
+ "VALUES ('testAdmin', 0)");
+ EXPECT_EQ(rows.size(), 0);
+
+ rows = Query::Execute("SELECT * FROM policy_admin");
+ EXPECT_EQ(rows.size(), 1);
+
+ Query::Execute("INSERT INTO policy_admin (name, uid) VALUES ('testAdmin', 1)");
+ rows = Query::Execute("SELECT * FROM policy_admin");
+ EXPECT_EQ(rows.size(), 2);
+
+ rows = Query::Execute("DELETE FROM policy_admin WHERE uid = 0 AND name = 'testAdmin'");
+ EXPECT_EQ(rows.size(), 0);
+
+ rows = Query::Execute("SELECT * FROM policy_admin");
+ EXPECT_EQ(rows.size(), 1);
+
+ Query::Execute("DELETE FROM policy_admin WHERE name = 'testAdmin' AND uid = 1");
+ rows = Query::Execute("SELECT * FROM policy_admin");
+ EXPECT_EQ(rows.size(), 0);
+}
+++ /dev/null
-/*
- * Copyright (c) 2019 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
- */
-
-#include <gtest/gtest.h>
-
-#include "../query.h"
-
-#include <chrono>
-#include <thread>
-
-using namespace vist;
-
-class ClientTests : public testing::Test {};
-
-TEST_F(ClientTests, query) {
- auto rows = Query::Execute("SELECT * FROM policy");
-
- EXPECT_TRUE(rows.size() > 0);
-}
-
-TEST_F(ClientTests, admin_enrollment) {
- auto rows = Query::Execute("INSERT INTO policy_admin (name, uid) "
- "VALUES ('testAdmin', 0)");
- EXPECT_EQ(rows.size(), 0);
-
- rows = Query::Execute("SELECT * FROM policy_admin");
- EXPECT_EQ(rows.size(), 1);
-
- Query::Execute("INSERT INTO policy_admin (name, uid) VALUES ('testAdmin', 1)");
- rows = Query::Execute("SELECT * FROM policy_admin");
- EXPECT_EQ(rows.size(), 2);
-
- rows = Query::Execute("DELETE FROM policy_admin WHERE uid = 0 AND name = 'testAdmin'");
- EXPECT_EQ(rows.size(), 0);
-
- rows = Query::Execute("SELECT * FROM policy_admin");
- EXPECT_EQ(rows.size(), 1);
-
- Query::Execute("DELETE FROM policy_admin WHERE name = 'testAdmin' AND uid = 1");
- rows = Query::Execute("SELECT * FROM policy_admin");
- EXPECT_EQ(rows.size(), 0);
-}
--- /dev/null
+/*
+ * Copyright (c) 2019 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
+ */
+
+#include <gtest/gtest.h>
+
+#include "../virtual-table.h"
+
+#include "../schema/time.h"
+#include "../schema/policy.h"
+#include "../schema/processes.h"
+
+#include <vist/common/audit/logger.h>
+
+using namespace vist;
+using namespace vist::schema;
+
+class VirtualTableTests : public testing::Test {};
+
+TEST_F(VirtualTableTests, time_row_at) {
+ Time result = { -1, -1, -1 };
+
+ VirtualRow<Time> time;
+ result.hour = time.at(&Time::hour);
+ result.minutes = time.at(&Time::minutes);
+ result.seconds = time.at(&Time::seconds);
+
+ /// Once query execution
+ INFO(VIST_CLIENT, "[Test] time table:");
+ INFO(VIST_CLIENT, "\t hour: " << result.hour);
+ INFO(VIST_CLIENT, "\t minutes: " << result.minutes);
+ INFO(VIST_CLIENT, "\t seconds: " << result.seconds);
+
+ /// Each query execution
+ INFO(VIST_CLIENT, "[Test] time table:");
+ INFO(VIST_CLIENT, "\t hour: " << VirtualRow<Time>().at(&Time::hour));
+ INFO(VIST_CLIENT, "\t minutes: " << VirtualRow<Time>().at(&Time::minutes));
+ INFO(VIST_CLIENT, "\t seconds: " << VirtualRow<Time>().at(&Time::seconds));
+
+ EXPECT_NE(result.hour, -1);
+ EXPECT_NE(result.minutes, -1);
+ EXPECT_NE(result.seconds, -1);
+}
+
+TEST_F(VirtualTableTests, time_row_arry_op) {
+ Time result = { -1, -1, -1 };
+
+ VirtualRow<Time> time;
+ result.hour = time[&Time::hour];
+ result.minutes = time[&Time::minutes];
+ result.seconds = time[&Time::seconds];
+
+ /// Once query execution
+ INFO(VIST_CLIENT, "[Test] time table:");
+ INFO(VIST_CLIENT, "\t hour: " << result.hour);
+ INFO(VIST_CLIENT, "\t minutes: " << result.minutes);
+ INFO(VIST_CLIENT, "\t seconds: " << result.seconds);
+
+ EXPECT_NE(result.hour, -1);
+ EXPECT_NE(result.minutes, -1);
+ EXPECT_NE(result.seconds, -1);
+}
+
+TEST_F(VirtualTableTests, processes_table) {
+ Processes result;
+ VirtualTable<Processes> processes;
+ EXPECT_TRUE(processes.size() > 0);
+
+ for(auto& p : processes) {
+ EXPECT_TRUE(p.size() > 0);
+ result.pid = p.at(&Processes::pid);
+ result.name = p.at(&Processes::name);
+ result.path = p.at(&Processes::path);
+ result.cmdline = p.at(&Processes::cmdline);
+ result.uid = p.at(&Processes::uid);
+ result.gid = p.at(&Processes::gid);
+ result.euid = p.at(&Processes::euid);
+ result.egid = p.at(&Processes::egid);
+ result.on_disk = p.at(&Processes::on_disk);
+ result.parent = p.at(&Processes::parent);
+
+ INFO(VIST_CLIENT, "[Test] Processes table:");
+ INFO(VIST_CLIENT, "\t pid: " << result.pid);
+ INFO(VIST_CLIENT, "\t name: " << result.name);
+ INFO(VIST_CLIENT, "\t path: " << result.path);
+ INFO(VIST_CLIENT, "\t cmdline: " << result.cmdline);
+ INFO(VIST_CLIENT, "\t uid: " << result.uid);
+ INFO(VIST_CLIENT, "\t gid: " << result.gid);
+ INFO(VIST_CLIENT, "\t euid: " << result.euid);
+ INFO(VIST_CLIENT, "\t egid: " << result.egid);
+ INFO(VIST_CLIENT, "\t on_disk: " << result.on_disk);
+ INFO(VIST_CLIENT, "\t parent: " << result.parent);
+ }
+}
+
+TEST_F(VirtualTableTests, policy_table) {
+ VirtualTable<Policy> table;
+ EXPECT_TRUE(table.size() > 0);
+
+ for(const auto& row : table) {
+ Policy policy = { row[&Policy::name], row[&Policy::value] };
+
+ INFO(VIST_CLIENT, "[Test] Policy table:");
+ INFO(VIST_CLIENT, "\t name: " << policy.name);
+ INFO(VIST_CLIENT, "\t value: " << policy.value);
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2019 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
- */
-
-#include <gtest/gtest.h>
-
-#include "../virtual-table.h"
-
-#include "../schema/time.h"
-#include "../schema/policy.h"
-#include "../schema/processes.h"
-
-#include <vist/common/audit/logger.h>
-
-using namespace vist;
-using namespace vist::schema;
-
-class VirtualTableTests : public testing::Test {};
-
-TEST_F(VirtualTableTests, time_row_at) {
- Time result = { -1, -1, -1 };
-
- VirtualRow<Time> time;
- result.hour = time.at(&Time::hour);
- result.minutes = time.at(&Time::minutes);
- result.seconds = time.at(&Time::seconds);
-
- /// Once query execution
- INFO(VIST_CLIENT, "[Test] time table:");
- INFO(VIST_CLIENT, "\t hour: " << result.hour);
- INFO(VIST_CLIENT, "\t minutes: " << result.minutes);
- INFO(VIST_CLIENT, "\t seconds: " << result.seconds);
-
- /// Each query execution
- INFO(VIST_CLIENT, "[Test] time table:");
- INFO(VIST_CLIENT, "\t hour: " << VirtualRow<Time>().at(&Time::hour));
- INFO(VIST_CLIENT, "\t minutes: " << VirtualRow<Time>().at(&Time::minutes));
- INFO(VIST_CLIENT, "\t seconds: " << VirtualRow<Time>().at(&Time::seconds));
-
- EXPECT_NE(result.hour, -1);
- EXPECT_NE(result.minutes, -1);
- EXPECT_NE(result.seconds, -1);
-}
-
-TEST_F(VirtualTableTests, time_row_arry_op) {
- Time result = { -1, -1, -1 };
-
- VirtualRow<Time> time;
- result.hour = time[&Time::hour];
- result.minutes = time[&Time::minutes];
- result.seconds = time[&Time::seconds];
-
- /// Once query execution
- INFO(VIST_CLIENT, "[Test] time table:");
- INFO(VIST_CLIENT, "\t hour: " << result.hour);
- INFO(VIST_CLIENT, "\t minutes: " << result.minutes);
- INFO(VIST_CLIENT, "\t seconds: " << result.seconds);
-
- EXPECT_NE(result.hour, -1);
- EXPECT_NE(result.minutes, -1);
- EXPECT_NE(result.seconds, -1);
-}
-
-TEST_F(VirtualTableTests, processes_table) {
- Processes result;
- VirtualTable<Processes> processes;
- EXPECT_TRUE(processes.size() > 0);
-
- for(auto& p : processes) {
- EXPECT_TRUE(p.size() > 0);
- result.pid = p.at(&Processes::pid);
- result.name = p.at(&Processes::name);
- result.path = p.at(&Processes::path);
- result.cmdline = p.at(&Processes::cmdline);
- result.uid = p.at(&Processes::uid);
- result.gid = p.at(&Processes::gid);
- result.euid = p.at(&Processes::euid);
- result.egid = p.at(&Processes::egid);
- result.on_disk = p.at(&Processes::on_disk);
- result.parent = p.at(&Processes::parent);
-
- INFO(VIST_CLIENT, "[Test] Processes table:");
- INFO(VIST_CLIENT, "\t pid: " << result.pid);
- INFO(VIST_CLIENT, "\t name: " << result.name);
- INFO(VIST_CLIENT, "\t path: " << result.path);
- INFO(VIST_CLIENT, "\t cmdline: " << result.cmdline);
- INFO(VIST_CLIENT, "\t uid: " << result.uid);
- INFO(VIST_CLIENT, "\t gid: " << result.gid);
- INFO(VIST_CLIENT, "\t euid: " << result.euid);
- INFO(VIST_CLIENT, "\t egid: " << result.egid);
- INFO(VIST_CLIENT, "\t on_disk: " << result.on_disk);
- INFO(VIST_CLIENT, "\t parent: " << result.parent);
- }
-}
-
-TEST_F(VirtualTableTests, policy_table) {
- VirtualTable<Policy> table;
- EXPECT_TRUE(table.size() > 0);
-
- for(const auto& row : table) {
- Policy policy = { row[&Policy::name], row[&Policy::value] };
-
- INFO(VIST_CLIENT, "[Test] Policy table:");
- INFO(VIST_CLIENT, "\t name: " << policy.name);
- INFO(VIST_CLIENT, "\t value: " << policy.value);
- }
-}
+++ /dev/null
-# Copyright (c) 2019 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(GLOB COMMON_TESTS "ipc/tests/*.cpp")
-ADD_VIST_TEST(${COMMON_TESTS})
} else if (pid == 0) {
TestServer server;
server.init();
-
}
std::this_thread::sleep_for(std::chrono::seconds(1));
--- /dev/null
+/*
+ * Copyright (c) 2019 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
+ */
+
+#include <gtest/gtest.h>
+
+#include "../notification.h"
+#include <osquery/logger.h>
+
+using namespace vist;
+
+class NotificationTests : public testing::Test {};
+
+TEST_F(NotificationTests, test_add_positive) {
+ auto& notifier = Notification::instance();
+
+ auto callback = [](const Row& row) {
+ LOG(INFO) << "NotifyCallback called:";
+ for (const auto& r : row)
+ LOG(INFO) << "\t" << r.first << " : " << r.second;
+ };
+
+ auto s = notifier.add("test", std::move(callback));
+ EXPECT_TRUE(s.ok());
+}
+
+TEST_F(NotificationTests, test_add_negative) {
+ auto& notifier = Notification::instance();
+
+ auto callback = [](const Row& row) {
+ LOG(INFO) << "NotifyCallback called:";
+ for (const auto& r : row)
+ LOG(INFO) << "\t" << r.first << " : " << r.second;
+ };
+
+ auto s = notifier.add("", std::move(callback));
+ EXPECT_FALSE(s.ok());
+}
+
+TEST_F(NotificationTests, test_emit_positive) {
+ auto& notifier = Notification::instance();
+
+ int called = 0;
+ auto callback = [&](const Row& row) {
+ LOG(INFO) << "NotifyCallback called:";
+ for (const auto& r : row)
+ LOG(INFO) << "\t" << r.first << " : " << r.second;
+ called++;
+ };
+
+ auto s = notifier.add("test2", std::move(callback));
+ EXPECT_TRUE(s.ok());
+
+ Row row;
+ row["foo"] = "bar";
+ s = notifier.emit("test2", row);
+
+ EXPECT_TRUE(s.ok());
+ EXPECT_EQ(called, 1);
+}
+++ /dev/null
-/*
- * Copyright (c) 2019 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
- */
-
-#include <gtest/gtest.h>
-
-#include "../notification.h"
-#include <osquery/logger.h>
-
-using namespace vist;
-
-class NotificationTests : public testing::Test {};
-
-TEST_F(NotificationTests, test_add_positive) {
- auto& notifier = Notification::instance();
-
- auto callback = [](const Row& row) {
- LOG(INFO) << "NotifyCallback called:";
- for (const auto& r : row)
- LOG(INFO) << "\t" << r.first << " : " << r.second;
- };
-
- auto s = notifier.add("test", std::move(callback));
- EXPECT_TRUE(s.ok());
-}
-
-TEST_F(NotificationTests, test_add_negative) {
- auto& notifier = Notification::instance();
-
- auto callback = [](const Row& row) {
- LOG(INFO) << "NotifyCallback called:";
- for (const auto& r : row)
- LOG(INFO) << "\t" << r.first << " : " << r.second;
- };
-
- auto s = notifier.add("", std::move(callback));
- EXPECT_FALSE(s.ok());
-}
-
-TEST_F(NotificationTests, test_emit_positive) {
- auto& notifier = Notification::instance();
-
- int called = 0;
- auto callback = [&](const Row& row) {
- LOG(INFO) << "NotifyCallback called:";
- for (const auto& r : row)
- LOG(INFO) << "\t" << r.first << " : " << r.second;
- called++;
- };
-
- auto s = notifier.add("test2", std::move(callback));
- EXPECT_TRUE(s.ok());
-
- Row row;
- row["foo"] = "bar";
- s = notifier.emit("test2", row);
-
- EXPECT_TRUE(s.ok());
- EXPECT_EQ(called, 1);
-}
--- /dev/null
+# Copyright (c) 2019 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.
+#
+
+SET(${TARGET_VIST_POLICY_LIB}_SRCS "")
+
+ADD_VIST_POLICY_LIBRARY(vist_policy_core core/api.cpp
+ core/policy-manager.cpp
+ core/policy-loader.cpp
+ core/policy-storage.cpp)
+
+FILE(GLOB POLICY_CORE_TESTS "core/tests/*.cpp")
+ADD_VIST_TEST(${POLICY_CORE_TESTS})
+
+FILE(GLOB POLICY_SDK_TESTS "sdk/tests/*.cpp")
+ADD_VIST_TEST(${POLICY_SDK_TESTS})
+
+ADD_LIBRARY(${TARGET_VIST_POLICY_LIB} STATIC ${${TARGET_VIST_POLICY_LIB}_SRCS})
+TARGET_LINK_LIBRARIES(${TARGET_VIST_POLICY_LIB} pthread dl)
--- /dev/null
+/*
+ * Copyright (c) 2019 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
+ */
+
+#pragma once
+
+#include <vist/policy/sdk/policy-value.h>
+
+#include <string>
+#include <map>
+#include <unordered_map>
+
+namespace vist {
+namespace policy {
+
+struct API {
+ static PolicyValue Get(const std::string& policy);
+ static std::unordered_map<std::string, PolicyValue> GetAll();
+
+ struct Admin {
+ static void Set(const std::string& policy, const PolicyValue& value);
+
+ static void Enroll(const std::string& admin, uid_t uid);
+ static void Disenroll(const std::string& admin, uid_t uid);
+
+ static std::multimap<std::string, int> GetAll();
+ };
+};
+
+} // namespace policy
+} // namespace vist
--- /dev/null
+/*
+ * Copyright (c) 2019 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
+ */
+
+#include <vist/policy/api.h>
+
+#include "policy-manager.h"
+
+namespace vist {
+namespace policy {
+
+PolicyValue API::Get(const std::string& policy)
+{
+ return PolicyManager::Instance().get(policy);
+}
+
+std::unordered_map<std::string, PolicyValue> API::GetAll()
+{
+ return PolicyManager::Instance().getAll();
+}
+
+void API::Admin::Set(const std::string& policy, const PolicyValue& value)
+{
+ // TODO(Sangwan): Get admin name from peer PID
+ PolicyManager::Instance().set(policy, value, "admin");
+}
+
+void API::Admin::Enroll(const std::string& admin, uid_t uid)
+{
+ PolicyManager::Instance().enroll(admin, uid);
+}
+
+void API::Admin::Disenroll(const std::string& admin, uid_t uid)
+{
+ PolicyManager::Instance().disenroll(admin, uid);
+}
+
+std::multimap<std::string, int> API::Admin::GetAll()
+{
+ return PolicyManager::Instance().getAdmins();
+}
+
+} // namespace policy
+} // namespace vist
--- /dev/null
+/*
+ * Copyright (c) 2019 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
+ */
+#pragma once
+
+#include <string>
+
+namespace vist {
+namespace policy {
+namespace schema {
+
+struct Admin {
+ int id = -1;
+ std::string pkg;
+ int uid = -1;
+ std::string key;
+ int removable = -1;
+};
+
+struct ManagedPolicy {
+ int id = -1;
+ int aid = -1;
+ int pid = -1;
+ int value = -1;
+};
+
+struct PolicyDefinition {
+ int id = -1;
+ int scope = -1;
+ std::string name;
+ int ivalue = -1;
+};
+
+} // namespace schema
+} // namespace policy
+} // namespace vist
--- /dev/null
+/*
+ * Copyright (c) 2019 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
+ */
+
+#include "policy-loader.h"
+
+namespace vist {
+namespace policy {
+
+PolicyProvider* PolicyLoader::load(const std::string& path)
+{
+ PluginLoader loader(path);
+ PolicyProvider::FactoryType factory = nullptr;
+ loader.load(PolicyProvider::getFactoryName(), factory);
+ if (factory == nullptr)
+ std::runtime_error("Failed to load symbol. " + PolicyProvider::getFactoryName());
+
+ auto provider = (*factory)();
+ if (provider == nullptr)
+ std::runtime_error("Failed to make provider. " + PolicyProvider::getFactoryName());
+
+ return provider;
+}
+
+PluginLoader::PluginLoader(const std::string& path, int flag)
+ : handle(::dlopen(path.c_str(), flag), [](void*)->int{return 0;})
+// Cleaning object after dlclose() makes SEGFAULT.
+// TODO: Sync dynamic loading's life-cycle with program.(PluginManager)
+// : handle(::dlopen(path.c_str(), flag), ::dlclose)
+{
+ if (handle == nullptr)
+ throw std::invalid_argument("Failed to open: " + path);
+}
+
+} // namespace policy
+} // namespace vist
--- /dev/null
+/*
+ * Copyright (c) 2019 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
+ */
+
+#pragma once
+
+#include <vist/policy/sdk/policy-provider.h>
+
+#include <stdexcept>
+#include <string>
+#include <memory>
+
+#include <dlfcn.h>
+
+namespace vist {
+namespace policy {
+
+struct PolicyLoader final {
+ static PolicyProvider* load(const std::string& path);
+};
+
+class PluginLoader final {
+public:
+ explicit PluginLoader(const std::string& path, int flag = RTLD_LAZY);
+
+ template<typename T>
+ void load(const std::string& name, T& symbol);
+
+private:
+ using Handle = std::unique_ptr<void, int(*)(void*)>;
+ Handle handle;
+};
+
+template<typename T>
+void PluginLoader::load(const std::string& name, T& symbol)
+{
+ symbol = reinterpret_cast<T>(::dlsym(handle.get(), name.c_str()));
+ if (symbol == nullptr)
+ throw std::runtime_error("Failed to load: " + name);
+}
+
+} // namespace policy
+} // namespace vist
--- /dev/null
+/*
+ * Copyright (c) 2019 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
+ */
+
+#include "policy-manager.h"
+#include "policy-loader.h"
+
+#include <vist/common/audit/logger.h>
+
+#include <klay/filesystem.h>
+
+namespace vist {
+namespace policy {
+
+PolicyManager::PolicyManager() : storage(DB_PATH)
+{
+ loadProviders(PLUGIN_INSTALL_DIR);
+ int cnt = loadPolicies();
+ INFO(VIST, std::to_string(cnt) + "-policies loaded");
+}
+
+std::pair<int, int> PolicyManager::loadProviders(const std::string& path)
+{
+ INFO(VIST, "Load policies from :" << path);
+ klay::File dir(path);
+ if (!dir.exists() || !dir.isDirectory())
+ throw std::invalid_argument("Plugin directory is wrong.: " + path);
+
+ int passed = 0, failed = 0;
+ klay::DirectoryIterator end;
+ for (klay::DirectoryIterator iter(path); iter != end; ++iter) {
+ if (!iter->isFile())
+ continue;
+
+ try {
+ auto provider = PolicyLoader::load(iter->getPath());
+ DEBUG(VIST, "Loaded provider: " << provider->getName());
+
+ bool exist = false;
+ for (const auto& p : this->providers) {
+ if (p->getName() == provider->getName()) {
+ exist = true;
+ break;
+ }
+ }
+
+ if (!exist)
+ this->providers.emplace_back(std::move(provider));
+ } catch (const std::exception& e) {
+ ++failed;
+ ERROR(VIST, "Failed to load: " << iter->getPath() << e.what());
+ continue;
+ }
+
+ ++passed;
+ }
+
+ INFO(VIST, "Loaded result >> passed: " << passed << ", failed: " << failed);
+ return std::make_pair(passed, failed);
+}
+
+int PolicyManager::loadPolicies()
+{
+ bool changed = false;
+
+ /// Make policy-provider map for performance
+ for (const auto& provider : providers) {
+ for (const auto& pair : provider->global) {
+ policies[pair.first] = provider->getName();
+
+ /// Check the policy is defined on policy-storage
+ if (!storage.exists(pair.first)) {
+ INFO(VIST, "Define global policy: " << pair.first);
+ storage.define(0, pair.first, pair.second->getInitial().value);
+ changed = true;
+ }
+ }
+
+ for (const auto& pair : provider->domain) {
+ policies[pair.first] = provider->getName();
+
+ if (!storage.exists(pair.first)) {
+ INFO(VIST, "Define domain policy: " << pair.first);
+ storage.define(1, pair.first, pair.second->getInitial().value);
+ changed = true;
+ }
+ }
+ }
+
+ if (changed)
+ storage.syncPolicyDefinition();
+
+ return policies.size();
+}
+
+void PolicyManager::enroll(const std::string& admin, uid_t uid)
+{
+ this->storage.enroll(admin, uid);
+}
+
+void PolicyManager::disenroll(const std::string& admin, uid_t uid)
+{
+ this->storage.disenroll(admin, uid);
+}
+
+void PolicyManager::set(const std::string& policy, const PolicyValue& value,
+ const std::string& admin, uid_t uid)
+{
+ if (policies.find(policy) == policies.end())
+ std::runtime_error("Not exist policy: " + policy);
+
+ storage.update(admin, uid, policy, value);
+
+ for (auto& p : providers) {
+ if (p->getName() != policies[policy])
+ continue;
+
+ if (p->global.find(policy) != p->global.end()) {
+ p->global[policy]->set(value);
+ return;
+ }
+
+ if (p->domain.find(policy) != p->domain.end()) {
+ p->domain[policy]->set(uid, value);
+ return;
+ }
+ }
+}
+
+PolicyValue PolicyManager::get(const std::string& policy, uid_t uid)
+{
+ return storage.strictest(policy, uid);
+}
+
+std::unordered_map<std::string, PolicyValue> PolicyManager::getAll(uid_t uid)
+{
+ return storage.strictest(uid);
+}
+
+std::multimap<std::string, int> PolicyManager::getAdmins()
+{
+ return storage.getAdmins();
+}
+
+} // namespace policy
+} // namespace vist
--- /dev/null
+/*
+ * Copyright (c) 2019 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
+ */
+
+#pragma once
+
+#include <vist/policy/sdk/policy-provider.h>
+#include <vist/policy/sdk/policy-value.h>
+
+#include "policy-storage.h"
+
+#include <exception>
+#include <map>
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include <gtest/gtest_prod.h>
+
+namespace vist {
+namespace policy {
+
+class PolicyManager final {
+public:
+ PolicyManager(const PolicyManager&) = delete;
+ PolicyManager& operator=(const PolicyManager&) = delete;
+
+ PolicyManager(PolicyManager&&) = delete;
+ PolicyManager& operator=(PolicyManager&&) = delete;
+
+ static PolicyManager& Instance() {
+ static PolicyManager manager;
+ return manager;
+ }
+
+ void enroll(const std::string& admin, uid_t uid);
+ void disenroll(const std::string& admin, uid_t uid);
+
+ void set(const std::string& policy, const PolicyValue& value,
+ const std::string& admin, uid_t uid = 0);
+ PolicyValue get(const std::string& policy, uid_t uid = 0);
+ std::unordered_map<std::string, PolicyValue> getAll(uid_t uid = 0);
+
+ std::multimap<std::string, int> getAdmins();
+
+private:
+ explicit PolicyManager();
+ ~PolicyManager() = default;
+
+ std::pair<int, int> loadProviders(const std::string& path);
+ int loadPolicies();
+
+ PolicyStorage storage;
+ std::vector<std::unique_ptr<PolicyProvider>> providers;
+
+ /// Policy-Provider
+ std::unordered_map<std::string, std::string> policies;
+
+ FRIEND_TEST(PolicyCoreTests, policy_loader);
+};
+
+} // namespace policy
+} // namespace vist
--- /dev/null
+/*
+ * Copyright (c) 2019 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
+ */
+
+#include "policy-storage.h"
+
+#include <vist/common/audit/logger.h>
+
+#include <klay/db/column.h>
+#include <klay/db/query-builder.h>
+#include <klay/db/statement.h>
+#include <klay/exception.h>
+
+#include <fstream>
+
+using namespace query_builder;
+using namespace vist::policy::schema;
+
+namespace {
+
+auto adminTable = make_table("admin",
+ make_column("id", &Admin::id),
+ make_column("pkg", &Admin::pkg),
+ make_column("uid", &Admin::uid),
+ make_column("key", &Admin::key),
+ make_column("removable", &Admin::removable));
+
+auto managedPolTable = make_table("managed_policy",
+ make_column("id", &ManagedPolicy::id),
+ make_column("aid", &ManagedPolicy::aid),
+ make_column("pid", &ManagedPolicy::pid),
+ make_column("value", &ManagedPolicy::value));
+
+auto definitionTable = make_table("policy_definition",
+ make_column("id", &PolicyDefinition::id),
+ make_column("scope", &PolicyDefinition::scope),
+ make_column("name", &PolicyDefinition::name),
+ make_column("ivalue", &PolicyDefinition::ivalue));
+
+const std::string SCRIPT_BASE = SCRIPT_INSTALL_DIR;
+const std::string SCRIPT_CREATE_SCHEMA = "create_schema";
+
+} // anonymous namespace
+
+namespace vist {
+namespace policy {
+
+PolicyStorage::PolicyStorage(const std::string& path) :
+ database(std::make_shared<database::Connection>(path,
+ database::Connection::ReadWrite |
+ database::Connection::Create))
+{
+ database->exec("PRAGMA foreign_keys = ON;");
+ database->exec(getScript(SCRIPT_CREATE_SCHEMA));
+
+ sync();
+}
+
+void PolicyStorage::sync()
+{
+ DEBUG(VIST, "Sync policy storage to cache object.");
+ syncPolicyDefinition();
+ syncAdmin();
+ syncManagedPolicy();
+}
+
+void PolicyStorage::syncPolicyDefinition()
+{
+ this->definitions.clear();
+ std::string query = definitionTable.selectAll();
+ database::Statement stmt(*database, query);
+
+ while (stmt.step()) {
+ PolicyDefinition pd;
+ pd.id = stmt.getColumn(0);
+ pd.scope = stmt.getColumn(1);
+ pd.name = std::string(stmt.getColumn(2));
+ pd.ivalue = stmt.getColumn(3);
+ DEBUG(VIST, "Defined policy:" + pd.name);
+ this->definitions.emplace(pd.name, std::move(pd));
+ }
+}
+
+void PolicyStorage::syncAdmin()
+{
+ this->admins.clear();
+ std::string query = adminTable.selectAll();
+ database::Statement stmt(*database, query);
+
+ while (stmt.step()) {
+ Admin admin;
+ admin.id = stmt.getColumn(0);
+ admin.pkg = std::string(stmt.getColumn(1));
+ admin.uid = stmt.getColumn(2);
+ admin.key = std::string(stmt.getColumn(3));
+ admin.removable = stmt.getColumn(4);
+
+ std::string alias = getAlias(admin.pkg, admin.uid);
+ this->admins.emplace(alias, std::move(admin));
+ }
+}
+
+void PolicyStorage::syncManagedPolicy()
+{
+ this->managedPolicies.clear();
+ std::string query = managedPolTable.selectAll();
+ database::Statement stmt(*database, query);
+
+ while (stmt.step()) {
+ ManagedPolicy mp;
+ mp.id = stmt.getColumn(0);
+ mp.aid = stmt.getColumn(1);
+ mp.pid = stmt.getColumn(2);
+ mp.value = stmt.getColumn(3);
+ this->managedPolicies.emplace(mp.pid, std::move(mp));
+ }
+}
+
+std::string PolicyStorage::getScript(const std::string& name)
+{
+ std::string path = SCRIPT_BASE + "/" + name + ".sql";
+ std::ifstream is(path);
+ if (is.fail())
+ throw std::invalid_argument("Failed to open script: " + path);
+
+ std::istreambuf_iterator<char> begin(is), end;
+ auto content = std::string(begin, end);
+ if (content.empty())
+ throw std::runtime_error("Failed to read script: " + path);
+
+ return content;
+}
+
+void PolicyStorage::define(int scope, const std::string& policy, int ivalue)
+{
+ if (definitions.find(policy) != definitions.end()) {
+ INFO(VIST, "Policy is already defined: " + policy);
+ return;
+ }
+
+ PolicyDefinition pd;
+ pd.scope = scope;
+ pd.name = policy;
+ pd.ivalue = ivalue;
+
+ std::string insertQuery = definitionTable.insert(&PolicyDefinition::scope,
+ &PolicyDefinition::name,
+ &PolicyDefinition::ivalue);
+ database::Statement stmt(*database, insertQuery);
+ stmt.bind(1, pd.scope);
+ stmt.bind(2, pd.name);
+ stmt.bind(3, pd.ivalue);
+ if (!stmt.exec())
+ throw std::runtime_error("Failed to define policy: " + pd.name);
+}
+
+void PolicyStorage::enroll(const std::string& name, uid_t uid)
+{
+ std::string alias = getAlias(name, uid);
+ INFO(VIST, "Enroll admin: " + alias);
+ if (admins.find(alias) != admins.end()) {
+ ERROR(VIST, "Admin is aleady enrolled.: " + alias);
+ return;
+ }
+
+ Admin admin;
+ admin.pkg = name;
+ admin.uid = static_cast<int>(uid);
+ admin.key = "Not supported";
+ admin.removable = true;
+
+ std::string insertQuery = adminTable.insert(&Admin::pkg, &Admin::uid,
+ &Admin::key, &Admin::removable);
+ database::Statement stmt(*database, insertQuery);
+ stmt.bind(1, admin.pkg);
+ stmt.bind(2, admin.uid);
+ stmt.bind(3, admin.key);
+ stmt.bind(4, admin.removable);
+ if (!stmt.exec())
+ throw std::runtime_error("Failed to enroll admin: " + admin.pkg);
+
+ /// Sync admin for getting admin ID.
+ syncAdmin();
+ /// ManagedPolicy is triggered by enrolling admin.
+ syncManagedPolicy();
+
+ int count = managedPolicies.size() / admins.size();
+ INFO(VIST, "Admin[" + alias + "] manages " + std::to_string(count) + "-policies.");
+}
+
+void PolicyStorage::disenroll(const std::string& name, uid_t uid)
+{
+ std::string alias = getAlias(name, uid);
+ INFO(VIST, "Disenroll admin: " + alias);
+ if (admins.find(alias) == admins.end()) {
+ ERROR(VIST, "Not exist admin: " + alias);
+ return;
+ } else {
+ admins.erase(alias);
+ }
+
+ int iUid = static_cast<int>(uid);
+ std::string query = adminTable.remove().where(expr(&Admin::pkg) == name &&
+ expr(&Admin::uid) == iUid);
+ database::Statement stmt(*database, query);
+ stmt.bind(1, name);
+ stmt.bind(2, iUid);
+ if (!stmt.exec())
+ throw std::runtime_error("Failed to disenroll admin: " + name);
+}
+
+void PolicyStorage::update(const std::string& name, uid_t uid,
+ const std::string& policy, const PolicyValue& value)
+{
+ std::string alias = getAlias(name, uid);
+ if (admins.find(alias) == admins.end())
+ throw std::runtime_error("Not exist admin: " + alias);
+
+ if (definitions.find(policy) == definitions.end())
+ throw std::runtime_error("Not exist policy: " + policy);
+
+ DEBUG(VIST, "Policy-update is called by admin: " + alias + ", about: " + policy +
+ ", value: " + std::to_string(value));
+
+ int policyId = definitions[policy].id;
+ int policyValue = value;
+ int adminId = admins[alias].id;
+ std::string query = managedPolTable.update(&ManagedPolicy::value)
+ .where(expr(&ManagedPolicy::pid) == policyId &&
+ expr(&ManagedPolicy::aid) == adminId);
+ database::Statement stmt(*database, query);
+ stmt.bind(1, policyValue);
+ stmt.bind(2, policyId);
+ stmt.bind(3, adminId);
+ if (!stmt.exec())
+ throw runtime::Exception("Failed to update policy:" + policy);
+
+ syncManagedPolicy();
+}
+
+PolicyValue PolicyStorage::strictest(const std::string& policy, uid_t uid)
+{
+ if (definitions.find(policy) == definitions.end())
+ throw std::runtime_error("Not exist policy: " + policy);
+
+ // There is no enrolled admins.
+ if (managedPolicies.size() == 0)
+ return PolicyValue(definitions[policy].ivalue);
+
+ std::shared_ptr<PolicyValue> strictest = nullptr;
+ int policyId = definitions[policy].id;
+ auto range = managedPolicies.equal_range(policyId);
+ for (auto iter = range.first; iter != range.second; iter++) {
+ if (uid != 0) {
+ int ret = getUid(iter->second.aid);
+ if (ret == -1 || ret != static_cast<int>(uid))
+ continue;
+ }
+
+ int value = iter->second.value;
+ if (strictest == nullptr)
+ strictest = std::make_shared<PolicyValue>(value);
+ else
+ strictest->value = (*strictest < value) ? strictest->value : value;
+
+ DEBUG(VIST, "The strictest of policy[" + policy +
+ "] : " + std::to_string(strictest->value));
+ }
+
+ if (strictest == nullptr)
+ throw std::runtime_error("Not exist managed policy: " + policy);
+
+ return std::move(*strictest);
+}
+
+std::unordered_map<std::string, PolicyValue> PolicyStorage::strictest(uid_t uid)
+{
+ std::unordered_map<std::string, PolicyValue> policies;
+ for (const auto& pair : definitions) {
+ std::string name = pair.first;
+ auto value = this->strictest(name, uid);
+
+ policies.emplace(std::move(name), std::move(value));
+ }
+
+ return policies;
+}
+
+std::multimap<std::string, int> PolicyStorage::getAdmins()
+{
+ std::multimap<std::string, int> admins;
+ for (const auto& pair : this->admins) {
+ std::string alias = pair.first;
+ int uid = pair.second.uid;
+ /// Erase uid from alias(name + uid)
+ std::size_t pos = alias.rfind(std::to_string(uid));
+ alias.erase(pos, std::to_string(uid).size());
+
+ admins.emplace(std::move(alias), uid);
+ }
+
+ return admins;
+}
+
+std::string PolicyStorage::getAlias(const std::string& name, uid_t uid) const noexcept
+{
+ return name + std::to_string(uid);
+}
+
+int PolicyStorage::getUid(int adminId) const noexcept
+{
+ for (const auto& a : admins)
+ if (a.second.id == adminId)
+ return a.second.uid;
+
+ return -1;
+}
+
+} // namespace policy
+} // namespace vist
--- /dev/null
+/*
+ * Copyright (c) 2019 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
+ *
+ * ttp://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
+ */
+
+#pragma once
+
+#include <vist/policy/sdk/policy-value.h>
+
+#include "db-schema.h"
+
+#include <map>
+#include <memory>
+#include <unordered_map>
+#include <vector>
+
+#include <klay/db/connection.h>
+
+namespace vist {
+namespace policy {
+
+using namespace schema;
+
+class PolicyStorage final {
+public:
+ explicit PolicyStorage(const std::string& path);
+
+ /// TODO(Sangwan): Consider to support lazy sync
+ void sync();
+
+ void syncPolicyDefinition();
+ void syncAdmin();
+ void syncManagedPolicy();
+
+ inline bool exists(const std::string& policy) const noexcept {
+ return definitions.find(policy) != definitions.end();
+ }
+
+ inline bool isActivated() const noexcept {
+ return admins.size() > 0 && managedPolicies.size() > 0;
+ }
+
+ void enroll(const std::string& admin, uid_t uid);
+ void disenroll(const std::string& admin, uid_t uid);
+
+ void define(int scope, const std::string& policy, int ivalue);
+ void update(const std::string& admin, uid_t uid,
+ const std::string& policy, const PolicyValue& value);
+
+ PolicyValue strictest(const std::string& policy, uid_t uid = 0);
+ /// Return all strictest policy values
+ std::unordered_map<std::string, PolicyValue> strictest(uid_t uid = 0);
+
+ /// Admin name can be duplicated
+ std::multimap<std::string, int> getAdmins();
+
+private:
+ std::string getScript(const std::string& name);
+ std::string getAlias(const std::string& name, uid_t uid) const noexcept;
+ int getUid(int adminId) const noexcept;
+
+ std::shared_ptr<klay::database::Connection> database;
+
+ /// DB Cache objects
+ /// TODO(Sangwan): add locking mechanism
+ std::unordered_map<std::string, PolicyDefinition> definitions;
+ std::unordered_map<std::string, Admin> admins;
+ std::unordered_multimap<int, ManagedPolicy> managedPolicies;
+};
+
+} // namespace policy
+} // namespace vist
--- /dev/null
+/*
+ * Copyright (c) 2019 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
+ */
+
+#include <gtest/gtest.h>
+
+#include "../policy-manager.h"
+
+namespace vist {
+namespace policy {
+
+class PolicyCoreTests : public testing::Test {};
+
+TEST_F(PolicyCoreTests, policy_loader) {
+ auto& manager = PolicyManager::Instance();
+
+ EXPECT_TRUE(manager.providers.size() > 0);
+ EXPECT_TRUE(manager.policies.size() > 0);
+}
+
+TEST_F(PolicyCoreTests, policy_set_get) {
+ auto& manager = PolicyManager::Instance();
+ manager.enroll("testAdmin", 0);
+ manager.set("bluetooth", PolicyValue(5), "testAdmin", 0);
+
+ auto policy = manager.get("bluetooth", 0);
+ EXPECT_EQ(policy.value, 5);
+
+ manager.enroll("testAdmin1", 0);
+ manager.set("bluetooth", PolicyValue(10), "testAdmin1", 0);
+
+ /// Manager should return the strongest policy.
+ policy = manager.get("bluetooth", 0);
+ EXPECT_EQ(policy.value, 5);
+
+ manager.disenroll("testAdmin", 0);
+ manager.disenroll("testAdmin1", 0);
+}
+
+} // namespace policy
+} // namespace vist
--- /dev/null
+/*
+ * Copyright (c) 2019 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
+ */
+
+#include <gtest/gtest.h>
+
+#include <memory>
+
+#include "../policy-storage.h"
+
+using namespace vist::policy;
+
+class PolicyStorageTests : public testing::Test {
+public:
+ void SetUp() override {
+ /// TODO(Sangwan KWon): Change to test db
+ this->storage = std::make_shared<PolicyStorage>(DB_PATH);
+ }
+
+ std::shared_ptr<PolicyStorage> getStorage() {
+ return this->storage;
+ }
+
+private:
+ std::shared_ptr<PolicyStorage> storage = nullptr;
+};
+
+TEST_F(PolicyStorageTests, initialize) {
+ bool isRaised = false;
+
+ try {
+ // DB is maden at run-time
+ PolicyStorage storage("/tmp/dummy");
+ } catch (const std::exception&) {
+ isRaised = true;
+ }
+
+ EXPECT_FALSE(isRaised);
+}
+
+TEST_F(PolicyStorageTests, enrollment) {
+ auto storage = getStorage();
+ EXPECT_FALSE(storage->isActivated());
+
+ storage->enroll("testAdmin", 0);
+ storage->enroll("testAdmin", 1);
+ EXPECT_TRUE(storage->isActivated());
+
+ storage->disenroll("testAdmin", 0);
+ EXPECT_TRUE(storage->isActivated());
+
+ storage->disenroll("testAdmin", 1);
+ EXPECT_FALSE(storage->isActivated());
+}
+
+TEST_F(PolicyStorageTests, update) {
+ auto storage = getStorage();
+ storage->enroll("testAdmin", 0);
+
+ bool isRaised = false;
+ try {
+ storage->update("testAdmin", 1, "bluetooth", PolicyValue(0));
+ } catch (const std::exception&) {
+ isRaised = true;
+ }
+
+ isRaised = false;
+ try {
+ storage->update("testAdmin", 0, "bluetooth", PolicyValue(0));
+ } catch (const std::exception&) {
+ isRaised = true;
+ }
+ EXPECT_FALSE(isRaised);
+
+ isRaised = false;
+ try {
+ storage->update("testAdmin", 0, "FakePolicy", PolicyValue(0));
+ } catch (const std::exception&) {
+ isRaised = true;
+ }
+ EXPECT_TRUE(isRaised);
+
+ storage->disenroll("testAdmin", 0);
+}
+
+TEST_F(PolicyStorageTests, strictest) {
+ auto storage = getStorage();
+ storage->enroll("testAdmin", 0);
+ storage->enroll("testAdmin", 1);
+
+ storage->update("testAdmin", 0, "bluetooth", PolicyValue(3));
+ storage->update("testAdmin", 1, "bluetooth", PolicyValue(6));
+
+ bool isRaised = false;
+ try {
+ auto value = storage->strictest("FakePolicy", 3);
+ } catch (const std::exception&) {
+ isRaised = true;
+ }
+ EXPECT_TRUE(isRaised);
+
+ /// as global policy
+ auto policy = storage->strictest("bluetooth");
+ EXPECT_EQ(policy.value, 3);
+
+ /// as domain policy
+ policy = storage->strictest("bluetooth", 1);
+ EXPECT_EQ(policy.value, 6);
+
+ storage->disenroll("testAdmin", 0);
+ storage->disenroll("testAdmin", 1);
+}
+
+TEST_F(PolicyStorageTests, strictest_all) {
+ auto storage = getStorage();
+ storage->enroll("testAdmin", 1);
+
+ /// as global policy
+ auto policies = storage->strictest();
+ EXPECT_TRUE(policies.size() > 0);
+
+ /// as domain policy
+ policies = storage->strictest(1);
+ EXPECT_TRUE(policies.size() > 0);
+
+ storage->disenroll("testAdmin", 1);
+}
+
+TEST_F(PolicyStorageTests, admin_list) {
+ auto storage = getStorage();
+
+ auto admins = storage->getAdmins();
+ EXPECT_EQ(admins.size(), 0);
+
+ storage->enroll("testAdmin", 1);
+ admins = storage->getAdmins();
+ EXPECT_EQ(admins.size(), 1);
+
+ storage->enroll("testAdmin", 2);
+ admins = storage->getAdmins();
+ EXPECT_EQ(admins.size(), 2);
+
+ storage->disenroll("testAdmin", 2);
+ admins = storage->getAdmins();
+ EXPECT_EQ(admins.size(), 1);
+
+ storage->disenroll("testAdmin", 1);
+ admins = storage->getAdmins();
+ EXPECT_EQ(admins.size(), 0);
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 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
+ */
+
+#pragma once
+
+#include "policy-model.h"
+
+#include <exception>
+#include <string>
+#include <unordered_map>
+
+#include <sys/types.h>
+
+namespace vist {
+namespace policy {
+
+class DomainPolicy : public PolicyModel {
+public:
+ explicit DomainPolicy(std::string name, PolicyValue initial) noexcept :
+ PolicyModel(std::move(name), std::move(initial)) {}
+ virtual ~DomainPolicy() = default;
+
+ DomainPolicy(DomainPolicy&&) = default;
+ DomainPolicy& operator=(DomainPolicy&&) = default;
+
+ inline void set(uid_t domain, const PolicyValue& value) {
+ current[domain] = value;
+
+ try {
+ this->onChanged(domain, value);
+ } catch (const std::exception& e) {
+ current.erase(domain);
+ std::rethrow_exception(std::current_exception());
+ }
+ }
+
+ inline const PolicyValue& get(uid_t domain) const {
+ if (!current.count(domain))
+ throw std::runtime_error("Policy value should be set once before use.");
+
+ return current.at(domain);
+ }
+
+ virtual void onChanged(uid_t domain, const PolicyValue& value) = 0;
+
+private:
+ std::unordered_map<uid_t, PolicyValue> current;
+};
+
+} // namespace policy
+} // namespace vist
--- /dev/null
+/*
+ * Copyright (c) 2019 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
+ */
+
+#pragma once
+
+#include "policy-model.h"
+
+#include <stdexcept>
+#include <string>
+
+namespace vist {
+namespace policy {
+
+class GlobalPolicy : public PolicyModel {
+public:
+ explicit GlobalPolicy(std::string name, PolicyValue initial) noexcept :
+ PolicyModel(std::move(name), std::move(initial)) {}
+ virtual ~GlobalPolicy() = default;
+
+ GlobalPolicy(GlobalPolicy&&) = default;
+ GlobalPolicy& operator=(GlobalPolicy&&) = default;
+
+ inline void set(const PolicyValue& value) {
+ current = value;
+ ready = true;
+
+ try {
+ this->onChanged(value);
+ } catch (const std::exception& e) {
+ ready = false;
+ std::rethrow_exception(std::current_exception());
+ }
+ }
+
+ inline const PolicyValue& get() const {
+ if (!ready)
+ throw std::runtime_error("Policy value should be set once before use.");
+
+ return current;
+ }
+
+ virtual void onChanged(const PolicyValue& value) = 0;
+
+private:
+ PolicyValue current;
+ bool ready = false;
+};
+
+} // namespace policy
+} // namespace vist
--- /dev/null
+/*
+ * Copyright (c) 2019 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
+ */
+
+#pragma once
+
+#include"policy-value.h"
+
+#include <string>
+
+namespace vist {
+namespace policy {
+
+class PolicyModel {
+public:
+ explicit PolicyModel(std::string name, PolicyValue initial) noexcept :
+ name(std::move(name)), initial(std::move(initial)) {}
+ virtual ~PolicyModel() = default;
+
+ PolicyModel(const PolicyModel&) = delete;
+ PolicyModel& operator=(const PolicyModel&) = delete;
+
+ PolicyModel(PolicyModel&&) = default;
+ PolicyModel& operator=(PolicyModel&&) = default;
+
+ const std::string& getName() const noexcept { return name; }
+ const PolicyValue& getInitial() const noexcept { return initial; }
+
+protected:
+ std::string name;
+ PolicyValue initial;
+};
+
+} // namespace policy
+} // namespace vist
--- /dev/null
+/*
+ * Copyright (c) 2019 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
+ */
+
+#pragma once
+
+#include "domain-policy.h"
+#include "global-policy.h"
+
+#include <cstddef>
+#include <memory>
+#include <unordered_map>
+
+namespace vist {
+namespace policy {
+
+class PolicyProvider {
+public:
+ using FactoryType = PolicyProvider* (*)();
+
+ explicit PolicyProvider(std::string name) noexcept : name(std::move(name)) {}
+ virtual ~PolicyProvider() = default;
+
+ inline void add(const std::shared_ptr<GlobalPolicy>& policy) {
+ global[policy->getName()] = policy;
+ }
+
+ inline void add(const std::shared_ptr<DomainPolicy>& policy) {
+ domain[policy->getName()] = policy;
+ }
+
+ inline const std::string& getName() const noexcept { return name; }
+ static const std::string& getFactoryName() noexcept {
+ static std::string name = "PolicyFactory";
+ return name;
+ }
+
+ std::size_t gsize() { return global.size(); }
+ std::size_t dsize() { return domain.size(); }
+
+private:
+ std::string name;
+ std::unordered_map<std::string, std::shared_ptr<GlobalPolicy>> global;
+ std::unordered_map<std::string, std::shared_ptr<DomainPolicy>> domain;
+
+ friend class PolicyManager;
+};
+
+} // namespace policy
+} // namespace vist
--- /dev/null
+/*
+ * Copyright (c) 2019 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
+ */
+
+#pragma once
+
+namespace vist {
+namespace policy {
+
+// TODO: Support various value type
+struct PolicyValue final {
+ explicit PolicyValue(int value) noexcept : value(value) {}
+ explicit PolicyValue() noexcept = default;
+ ~PolicyValue() = default;
+
+ PolicyValue(const PolicyValue&) noexcept = default;
+ PolicyValue& operator=(const PolicyValue&) noexcept = default;
+
+ PolicyValue(PolicyValue&&) noexcept = default;
+ PolicyValue& operator=(PolicyValue&&) noexcept = default;
+
+ PolicyValue& operator=(int val) {
+ value = val;
+ return *this;
+ }
+
+ operator int() const { return value; }
+ bool operator==(const PolicyValue& rhs) const { return value == rhs.value; }
+ bool operator!=(const PolicyValue& rhs) const { return value != rhs.value; }
+ bool operator<(const PolicyValue& rhs) const { return value < rhs.value; }
+
+ int value = -1;
+};
+
+} // namespace policy
+} // namespace vist
--- /dev/null
+/*
+ * Copyright (c) 2019 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
+ */
+
+#include <gtest/gtest.h>
+
+#include "../domain-policy.h"
+#include "../global-policy.h"
+#include "../policy-provider.h"
+
+#include <exception>
+
+namespace {
+ int g_value = -1;
+ int d_value = -1;
+ uid_t d_uid = 0;
+} // anonymous namespace
+
+using namespace vist::policy;
+
+class PolicySDKTests : public testing::Test {};
+
+class TestGlobalPolicy : public GlobalPolicy {
+public:
+ TestGlobalPolicy() : GlobalPolicy("test_policy", PolicyValue(1)) {}
+
+ virtual void onChanged(const PolicyValue& value) {
+ g_value = value;
+ }
+};
+
+TEST_F(PolicySDKTests, global_policy) {
+ TestGlobalPolicy policy;
+
+ EXPECT_EQ(policy.getName(), "test_policy");
+ EXPECT_EQ(policy.getInitial(), 1);
+
+ // Policy value should be set once before use
+ bool isRaised = false;
+ try {
+ auto value = policy.get();
+ } catch (const std::exception&) {
+ isRaised = true;
+ }
+
+ EXPECT_TRUE(isRaised);
+
+ policy.set(PolicyValue(3));
+ EXPECT_EQ(3, g_value);
+ EXPECT_EQ(3, policy.get());
+}
+
+class TestDomainPolicy : public DomainPolicy {
+public:
+ TestDomainPolicy() : DomainPolicy("test_policy", PolicyValue(1)) {}
+
+ virtual void onChanged(uid_t domain, const PolicyValue& value) {
+ d_uid = domain;
+ d_value = value;
+ }
+};
+
+TEST_F(PolicySDKTests, domain_policy) {
+ TestDomainPolicy policy;
+ uid_t domain = 5001;
+
+ EXPECT_EQ(policy.getName(), "test_policy");
+ EXPECT_EQ(policy.getInitial(), 1);
+
+ // Policy value should be set once before use
+ bool isRaised = false;
+ try {
+ auto value = policy.get(domain);
+ } catch (const std::exception&) {
+ isRaised = true;
+ }
+
+ EXPECT_TRUE(isRaised);
+
+ policy.set(domain, PolicyValue(3));
+ EXPECT_EQ(d_uid, domain);
+ EXPECT_EQ(3, policy.get(domain));
+}
+
+TEST_F(PolicySDKTests, policy_provider) {
+ PolicyProvider provider("testProvider");
+ provider.add(std::make_shared<TestGlobalPolicy>());
+ provider.add(std::make_shared<TestDomainPolicy>());
+
+ EXPECT_EQ(1, provider.gsize());
+ EXPECT_EQ(1, provider.dsize());
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 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
+ */
+
+#include <gtest/gtest.h>
+
+#include "../vist.h"
+
+#include <iostream>
+#include <chrono>
+#include <thread>
+
+#include <vist/policy/core/policy-manager.h>
+
+using namespace vist;
+
+class CoreTests : public testing::Test {};
+
+TEST_F(CoreTests, query_select) {
+ auto rows = Vist::Query("SELECT * FROM policy");
+
+ EXPECT_TRUE(rows.size() > 0);
+
+ std::string statement = "SELECT * FROM policy WHERE name = 'bluetooth'";
+ rows = Vist::Query(statement);
+
+ EXPECT_EQ(rows.size(), 1);
+ EXPECT_EQ(rows[0]["name"], "bluetooth");
+}
+
+TEST_F(CoreTests, query_update) {
+ auto& manager = policy::PolicyManager::Instance();
+ manager.enroll("admin", 0);
+
+ std::string statement = "SELECT * FROM policy WHERE name = 'bluetooth'";
+ auto rows = Vist::Query(statement);
+ /// Initial policy value
+ EXPECT_EQ(rows[0]["value"], std::to_string(1));
+
+ statement = "UPDATE policy SET value = '3' WHERE name = 'bluetooth'";
+ rows = Vist::Query(statement);
+ EXPECT_EQ(rows.size(), 0);
+
+ statement = "SELECT * FROM policy WHERE name = 'bluetooth'";
+ rows = Vist::Query(statement);
+ EXPECT_EQ(rows[0]["value"], std::to_string(3));
+
+ manager.disenroll("admin", 0);
+}
+++ /dev/null
-/*
- * Copyright (c) 2019 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
- */
-
-#include <gtest/gtest.h>
-
-#include "../vist.h"
-
-#include <iostream>
-#include <chrono>
-#include <thread>
-
-#include <policyd/core/policy-manager.h>
-
-using namespace vist;
-
-class CoreTests : public testing::Test {};
-
-TEST_F(CoreTests, query_select) {
- auto rows = Vist::Query("SELECT * FROM policy");
-
- EXPECT_TRUE(rows.size() > 0);
-
- std::string statement = "SELECT * FROM policy WHERE name = 'bluetooth'";
- rows = Vist::Query(statement);
-
- EXPECT_EQ(rows.size(), 1);
- EXPECT_EQ(rows[0]["name"], "bluetooth");
-}
-
-TEST_F(CoreTests, query_update) {
- auto& manager = policyd::PolicyManager::Instance();
- manager.enroll("admin", 0);
-
- std::string statement = "SELECT * FROM policy WHERE name = 'bluetooth'";
- auto rows = Vist::Query(statement);
- /// Initial policy value
- EXPECT_EQ(rows[0]["value"], std::to_string(1));
-
- statement = "UPDATE policy SET value = '3' WHERE name = 'bluetooth'";
- rows = Vist::Query(statement);
- EXPECT_EQ(rows.size(), 0);
-
- statement = "SELECT * FROM policy WHERE name = 'bluetooth'";
- rows = Vist::Query(statement);
- EXPECT_EQ(rows[0]["value"], std::to_string(3));
-
- manager.disenroll("admin", 0);
-}