Add policy-storage to policy-core
authorSangwan Kwon <sangwan.kwon@samsung.com>
Wed, 25 Sep 2019 11:07:26 +0000 (20:07 +0900)
committer권상완/Security 2Lab(SR)/Engineer/삼성전자 <sangwan.kwon@samsung.com>
Thu, 10 Oct 2019 06:26:21 +0000 (15:26 +0900)
Signed-off-by: Sangwan Kwon <sangwan.kwon@samsung.com>
Makefile
src/policyd/CMakeLists.txt
src/policyd/core/CMakeLists.txt
src/policyd/core/db-schema.h [new file with mode: 0644]
src/policyd/core/policy-manager.cpp
src/policyd/core/policy-manager.h
src/policyd/core/policy-storage.cpp [new file with mode: 0644]
src/policyd/core/policy-storage.h [new file with mode: 0644]
src/policyd/core/tests/core-tests.cpp
src/policyd/core/tests/storage-tests.cpp [new file with mode: 0644]
src/policyd/sdk/policy-provider.h

index 5cb33f723081dc6436983ec3321c69d079d40c2d..5413cd2eb2cee86439788e38a6e0a1234e94f70a 100644 (file)
--- 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
index 7764632f45263608c821e0a10017f0a00011ad37..03fbbeaf727e6cae2dbf0febe5f46248c877859a 100644 (file)
@@ -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)
index d6080727925f17c23269fc277fee903e9b3e1cac..85dbb0e1d8daa0a1d3d6cd61dfcc4afa236fc041 100644 (file)
@@ -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 (file)
index 0000000..19bccf9
--- /dev/null
@@ -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 <string>
+
+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
index 7ab04d358f75eb872846ba4a0f8ef5ff21083d8a..2bb55e2d186388dd4b6475a6153888738fd82d8c 100644 (file)
@@ -22,7 +22,8 @@
 
 namespace policyd {
 
-std::pair<int, int> PolicyManager::loadPolicy(const std::string& path) {
+std::pair<int, int> 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<int, int> 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
index a3b31ca4854aaa6bf7df36c20758d67fde9fd80c..63736b0e56a5de79e21d500bf89b1dc21d5e290b 100644 (file)
@@ -18,6 +18,8 @@
 
 #include <policyd/sdk/policy-provider.h>
 
+#include "policy-storage.h"
+
 #include <string>
 #include <exception>
 #include <memory>
@@ -27,9 +29,17 @@ namespace policyd {
 
 class PolicyManager final {
 public:
-       std::pair<int, int> loadPolicy(const std::string& path);
+       explicit PolicyManager() : storage(DB_PATH) {}
+
+       std::pair<int, int> loadProviders(const std::string& path);
+       int loadPolicies();
 
+private:
+       PolicyStorage storage;
        std::vector<std::shared_ptr<PolicyProvider>> providers;
+
+       std::unordered_map<std::string, std::shared_ptr<GlobalPolicy>> global;
+       std::unordered_map<std::string, std::shared_ptr<DomainPolicy>> domain;
 };
 
 } // namespace policyd
diff --git a/src/policyd/core/policy-storage.cpp b/src/policyd/core/policy-storage.cpp
new file mode 100644 (file)
index 0000000..3e86b15
--- /dev/null
@@ -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 <klay/db/column.h>
+#include <klay/db/query-builder.h>
+#include <klay/db/statement.h>
+#include <klay/exception.h>
+
+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<database::Connection>(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 (file)
index 0000000..6269061
--- /dev/null
@@ -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 <memory>
+#include <vector>
+#include <unordered_map>
+
+#include <klay/db/connection.h>
+
+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<klay::database::Connection> database;
+
+       /// DB Cache objects
+       std::unordered_map<std::string, PolicyDefinition> definitions;
+       std::vector<Admin> admins;
+       std::vector<ManagedPolicy> managedPolicies;
+};
+
+} // namespace policyd
index 6a564871a9ccce3e316429350c087b6f2809efab..f3a8913ef96c038c208b2615d67e224ee3c2bc14 100644 (file)
@@ -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 (file)
index 0000000..6cf74a3
--- /dev/null
@@ -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 <gtest/gtest.h>
+
+#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);
+}
index 0ebe5a3316d843ba7a1b9e82e1a945fd7fd3c419..8dd319bc6422c8bb958ee02ba5cd5fc990cfce88 100644 (file)
@@ -53,6 +53,8 @@ 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