From 01b3cded50ed52d6106e42b26649abb279cbbb6a Mon Sep 17 00:00:00 2001 From: Sangwan Kwon Date: Wed, 25 Sep 2019 20:07:26 +0900 Subject: [PATCH] Add policy-storage to policy-core Signed-off-by: Sangwan Kwon --- Makefile | 2 +- src/policyd/CMakeLists.txt | 2 +- src/policyd/core/CMakeLists.txt | 1 + src/policyd/core/db-schema.h | 46 ++++++++++++ src/policyd/core/policy-manager.cpp | 23 +++++- src/policyd/core/policy-manager.h | 12 +++- src/policyd/core/policy-storage.cpp | 118 +++++++++++++++++++++++++++++++ src/policyd/core/policy-storage.h | 54 ++++++++++++++ src/policyd/core/tests/core-tests.cpp | 5 +- src/policyd/core/tests/storage-tests.cpp | 44 ++++++++++++ src/policyd/sdk/policy-provider.h | 2 + 11 files changed, 304 insertions(+), 5 deletions(-) create mode 100644 src/policyd/core/db-schema.h create mode 100644 src/policyd/core/policy-storage.cpp create mode 100644 src/policyd/core/policy-storage.h create mode 100644 src/policyd/core/tests/storage-tests.cpp diff --git a/Makefile b/Makefile index 5cb33f7..5413cd2 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ docker_run: docker run --rm -it --net=host --privileged -v $(shell pwd):/usr/src tizen-osquery gbs_run: - gbs lb -A armv7l --include-all -P standard + gbs lb -A armv7l --include-all --define="build_type DEBUG" -P standard %:: mkdir -p build diff --git a/src/policyd/CMakeLists.txt b/src/policyd/CMakeLists.txt index 7764632..03fbbea 100644 --- a/src/policyd/CMakeLists.txt +++ b/src/policyd/CMakeLists.txt @@ -26,7 +26,7 @@ INCLUDE_DIRECTORIES(SYSTEM . ${POLICYD_DEPS_INCLUDE_DIRS}) ADD_DEFINITIONS(-DDATA_PATH="${DATA_INSTALL_DIR}" -DRUN_PATH="${RUN_INSTALL_DIR}" - -DDB_PATH="${DB_INSTALL_DIR}" + -DDB_PATH="${DB_INSTALL_DIR}/.dpm.db" -DPLUGIN_INSTALL_DIR="${PLUGIN_INSTALL_DIR}" -DEVENT_CONFIGURE_DIR="${EVENT_CONFIGURE_DIR}") ADD_DEFINITIONS(-DUG_WAYLAND) diff --git a/src/policyd/core/CMakeLists.txt b/src/policyd/core/CMakeLists.txt index d608072..85dbb0e 100644 --- a/src/policyd/core/CMakeLists.txt +++ b/src/policyd/core/CMakeLists.txt @@ -15,6 +15,7 @@ ADD_POLICYD_LIBRARY(policyd_core policy-manager.cpp policy-loader.cpp + policy-storage.cpp logger.cpp) FILE(GLOB SDK_TESTS "tests/*.cpp") diff --git a/src/policyd/core/db-schema.h b/src/policyd/core/db-schema.h new file mode 100644 index 0000000..19bccf9 --- /dev/null +++ b/src/policyd/core/db-schema.h @@ -0,0 +1,46 @@ +/* + * 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 + +namespace policyd { +namespace schema { + +struct Admin { + int id; + std::string pkg; + int uid; + std::string key; + int removable; +}; + +struct ManagedPolicy { + int id; + int aid; + int pid; + int value; +}; + +struct PolicyDefinition { + int id; + int scope; + std::string name; + int ivalue; +}; + +} // namespace schema +} // namespace policyd diff --git a/src/policyd/core/policy-manager.cpp b/src/policyd/core/policy-manager.cpp index 7ab04d3..2bb55e2 100644 --- a/src/policyd/core/policy-manager.cpp +++ b/src/policyd/core/policy-manager.cpp @@ -22,7 +22,8 @@ namespace policyd { -std::pair PolicyManager::loadPolicy(const std::string& path) { +std::pair PolicyManager::loadProviders(const std::string& path) +{ INFO(DPM, "Load policies from :" << path); klay::File dir(path); if (!dir.exists() || !dir.isDirectory()) @@ -51,4 +52,24 @@ std::pair PolicyManager::loadPolicy(const std::string& path) { return std::make_pair(passed, failed); } +int PolicyManager::loadPolicies() +{ + for (const auto& p : providers) { + this->global.insert(p->global.cbegin(), p->global.cend()); + this->domain.insert(p->domain.cbegin(), p->domain.cend()); + } + + for (const auto& g : global) { + if (!storage.exists(g.first)) + throw std::runtime_error("Policy does not exist.: " + g.first); + } + + for (const auto& d : domain) { + if (!storage.exists(d.first)) + throw std::runtime_error("Policy does not exist.: " + d.first); + } + + return global.size() + domain.size(); +} + } // namespace policyd diff --git a/src/policyd/core/policy-manager.h b/src/policyd/core/policy-manager.h index a3b31ca..63736b0 100644 --- a/src/policyd/core/policy-manager.h +++ b/src/policyd/core/policy-manager.h @@ -18,6 +18,8 @@ #include +#include "policy-storage.h" + #include #include #include @@ -27,9 +29,17 @@ namespace policyd { class PolicyManager final { public: - std::pair loadPolicy(const std::string& path); + explicit PolicyManager() : storage(DB_PATH) {} + + std::pair loadProviders(const std::string& path); + int loadPolicies(); +private: + PolicyStorage storage; std::vector> providers; + + std::unordered_map> global; + std::unordered_map> domain; }; } // namespace policyd diff --git a/src/policyd/core/policy-storage.cpp b/src/policyd/core/policy-storage.cpp new file mode 100644 index 0000000..3e86b15 --- /dev/null +++ b/src/policyd/core/policy-storage.cpp @@ -0,0 +1,118 @@ +/* + * 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 "logger.h" + +#include +#include +#include +#include + +using namespace query_builder; +using namespace policyd::schema; + +namespace { + +auto _admin = 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 _managedPolicy = 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 _policyDefinition = make_table("policy_definition", + make_column("id", &PolicyDefinition::id), + make_column("scope", &PolicyDefinition::scope), + make_column("name", &PolicyDefinition::name), + make_column("ivalue", &PolicyDefinition::ivalue)); + +auto _dpm = make_database("dpm", _admin, _managedPolicy, _policyDefinition); + +} // anonymous namespace + +namespace policyd { + +PolicyStorage::PolicyStorage(const std::string& path) : + database(std::make_shared(path, + database::Connection::ReadWrite | + database::Connection::Create)) +{ + sync(); +} + +void PolicyStorage::sync() +{ + DEBUG(DPM, "Sync policy storage to cache object."); + syncPolicyDefinition(); + syncAdmin(); + syncManagedPolicy(); +} + +void PolicyStorage::syncPolicyDefinition() +{ + std::string query = _policyDefinition.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(DPM, "Sync policy:" + pd.name); + this->definitions.emplace(pd.name, std::move(pd)); + } +} + +void PolicyStorage::syncAdmin() +{ + std::string query = _admin.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); + this->admins.emplace_back(std::move(admin)); + } +} + +void PolicyStorage::syncManagedPolicy() +{ + std::string query = _managedPolicy.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_back(std::move(mp)); + } +} + +} // namespace policyd diff --git a/src/policyd/core/policy-storage.h b/src/policyd/core/policy-storage.h new file mode 100644 index 0000000..6269061 --- /dev/null +++ b/src/policyd/core/policy-storage.h @@ -0,0 +1,54 @@ +/* + * 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 "db-schema.h" + +#include +#include +#include + +#include + +namespace policyd { + +using namespace schema; + +class PolicyStorage final { +public: + explicit PolicyStorage(const std::string& path); + + void sync(); + + inline bool exists(const std::string& policy) noexcept { + return definitions.find(policy) != definitions.end(); + } + +private: + void syncPolicyDefinition(); + void syncAdmin(); + void syncManagedPolicy(); + + std::shared_ptr database; + + /// DB Cache objects + std::unordered_map definitions; + std::vector admins; + std::vector managedPolicies; +}; + +} // namespace policyd diff --git a/src/policyd/core/tests/core-tests.cpp b/src/policyd/core/tests/core-tests.cpp index 6a56487..f3a8913 100644 --- a/src/policyd/core/tests/core-tests.cpp +++ b/src/policyd/core/tests/core-tests.cpp @@ -24,8 +24,11 @@ class PolicyCoreTests : public testing::Test {}; TEST_F(PolicyCoreTests, policy_loader) { PolicyManager pm; - auto result = pm.loadPolicy(PLUGIN_INSTALL_DIR); + auto result = pm.loadProviders(PLUGIN_INSTALL_DIR); EXPECT_TRUE(result.first > 0); EXPECT_TRUE(result.second == 0); + + auto size = pm.loadPolicies(); + EXPECT_TRUE(size > 0); } diff --git a/src/policyd/core/tests/storage-tests.cpp b/src/policyd/core/tests/storage-tests.cpp new file mode 100644 index 0000000..6cf74a3 --- /dev/null +++ b/src/policyd/core/tests/storage-tests.cpp @@ -0,0 +1,44 @@ +/* + * 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 + +#include "../policy-storage.h" + +using namespace policyd; + +class PolicyStorageTests : public testing::Test {}; + +TEST_F(PolicyStorageTests, policy_storage) { + bool isRaised = false; + + try { + PolicyStorage storage(DB_PATH); + } catch (const std::exception&) { + isRaised = true; + } + + EXPECT_TRUE(!isRaised); + + isRaised = false; + try { + PolicyStorage storage("/tmp/dummy"); + } catch (const std::exception&) { + isRaised = true; + } + + EXPECT_TRUE(isRaised); +} diff --git a/src/policyd/sdk/policy-provider.h b/src/policyd/sdk/policy-provider.h index 0ebe5a3..8dd319b 100644 --- a/src/policyd/sdk/policy-provider.h +++ b/src/policyd/sdk/policy-provider.h @@ -53,6 +53,8 @@ private: std::string name; std::unordered_map> global; std::unordered_map> domain; + + friend class PolicyManager; }; } // namespace policyd -- 2.7.4