From 9f2e28f23bc5c5829de331fa4bb12aadd0b9ecb0 Mon Sep 17 00:00:00 2001 From: Sangwan Kwon Date: Fri, 17 Jul 2020 15:22:20 +0900 Subject: [PATCH] Redesign policy management logic [AS-IS] - Policy Schema: Struct-based schema - Policy Provider: Plugin Loader - Policy Management: Virtual Table (static) [TO-BE] - Policy Schema: Struct-based schema - Policy Provider & Management: Dynamic Virtual Table Change-Id: I705ffee9e0d3368ac187c5498bd102f8d942a7d8 Signed-off-by: Sangwan Kwon --- CMake/Definition.cmake | 8 +- CMakeLists.txt | 6 +- packaging/vist.spec | 2 + src/vist/CMakeLists.txt | 1 + src/vist/common/dynamic-loader.cpp | 9 +- src/vist/policy/api.cpp | 5 + src/vist/policy/api.hpp | 4 + src/vist/policy/policy-manager.cpp | 25 ++++- src/vist/policy/policy-manager.hpp | 4 +- src/vist/policy/tests/core.cpp | 12 +-- src/vist/service/tests/core.cpp | 14 +-- src/vist/service/vistd.cpp | 39 +++++-- src/vist/service/vistd.hpp | 3 + src/vist/table/CMakeLists.txt | 9 +- .../{bluetooth.hpp => dynamic-table.hpp} | 11 +- src/vist/table/{ => policy}/policy-admin.cpp | 0 src/vist/table/{ => policy}/policy-admin.hpp | 0 src/vist/table/{ => policy}/policy.cpp | 0 src/vist/table/{ => policy}/policy.hpp | 0 .../vist/table/policy/sample}/CMakeLists.txt | 15 ++- .../sample/sample.cpp} | 83 +++++++------- src/vist/table/policy/sample/sample.hpp | 102 ++++++++++++++++++ 22 files changed, 260 insertions(+), 92 deletions(-) rename src/vist/table/{bluetooth.hpp => dynamic-table.hpp} (74%) rename src/vist/table/{ => policy}/policy-admin.cpp (100%) rename src/vist/table/{ => policy}/policy-admin.hpp (100%) rename src/vist/table/{ => policy}/policy.cpp (100%) rename src/vist/table/{ => policy}/policy.hpp (100%) rename {plugins => src/vist/table/policy/sample}/CMakeLists.txt (58%) rename src/vist/table/{bluetooth.cpp => policy/sample/sample.cpp} (52%) create mode 100644 src/vist/table/policy/sample/sample.hpp diff --git a/CMake/Definition.cmake b/CMake/Definition.cmake index a210f32..52bfa5a 100644 --- a/CMake/Definition.cmake +++ b/CMake/Definition.cmake @@ -25,12 +25,14 @@ SET(VIST_RW_DIR "${RW_DIR}/vist") SET(VIST_DB_DIR "${VIST_RW_DIR}/db") SET(VIST_PLUGIN_DIR "${VIST_RO_DIR}/plugin") +SET(VIST_TABLE_DIR "${VIST_RO_DIR}/table") SET(VIST_SCRIPT_DIR "${VIST_RO_DIR}/script") SET(DEFAULT_POLICY_ADMIN "vist-cli") -SET(DB_INSTALL_DIR "${VIST_DB_DIR}") -SET(PLUGIN_INSTALL_DIR "${VIST_PLUGIN_DIR}") -SET(SCRIPT_INSTALL_DIR "${VIST_SCRIPT_DIR}") +SET(DB_INSTALL_DIR "${VIST_DB_DIR}") +SET(PLUGIN_INSTALL_DIR "${VIST_PLUGIN_DIR}") +SET(TABLE_INSTALL_DIR "${VIST_TABLE_DIR}") +SET(SCRIPT_INSTALL_DIR "${VIST_SCRIPT_DIR}") EXECUTE_PROCESS(COMMAND mkdir -p "${VIST_DB_DIR}") EXECUTE_PROCESS(COMMAND mkdir -p "${VIST_PLUGIN_DIR}") diff --git a/CMakeLists.txt b/CMakeLists.txt index 5714bc4..995e690 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,11 @@ IF(NOT CMAKE_BUILD_TYPE) SET(CMAKE_BUILD_TYPE "DEBUG") ENDIF(NOT CMAKE_BUILD_TYPE) +message("CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}") +message("CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}") +message("CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}") +message("CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}") + SET(CMAKE_CXX_FLAGS_DEBUG "-g -std=c++1z -O0 -ggdb -Wp,-U_FORTIFY_SOURCE") SET(CMAKE_CXX_FLAGS_RELEASE "-g -std=c++1z -O2 -DNDEBUG") @@ -45,7 +50,6 @@ ENABLE_TESTING() ADD_SUBDIRECTORY(data) ADD_SUBDIRECTORY(src) -ADD_SUBDIRECTORY(plugins) IF(DEFINED GBS_BUILD) ADD_SUBDIRECTORY(systemd) diff --git a/packaging/vist.spec b/packaging/vist.spec index 535d8f0..e28e684 100644 --- a/packaging/vist.spec +++ b/packaging/vist.spec @@ -38,6 +38,7 @@ Requires: libsystemd %global vist_db_dir %{vist_rw_dir}/db %global vist_plugin_dir %{vist_ro_dir}/plugin +%global vist_table_dir %{vist_ro_dir}/table %global vist_script_dir %{vist_ro_dir}/script %description @@ -67,6 +68,7 @@ cp %SOURCE1 . -DDEFAULT_POLICY_ADMIN=vist-cli \ -DDB_INSTALL_DIR:PATH=%{vist_db_dir} \ -DPLUGIN_INSTALL_DIR:PATH=%{vist_plugin_dir} \ + -DTABLE_INSTALL_DIR:PATH=%{vist_table_dir} \ -DSCRIPT_INSTALL_DIR:PATH=%{vist_script_dir} \ -DSYSTEMD_UNIT_DIR:PATH=%{_unitdir} diff --git a/src/vist/CMakeLists.txt b/src/vist/CMakeLists.txt index 6bd80e7..b96f0e4 100644 --- a/src/vist/CMakeLists.txt +++ b/src/vist/CMakeLists.txt @@ -35,6 +35,7 @@ INCLUDE_DIRECTORIES(SYSTEM . common ${VIST_COMMON_DEPS_INCLUDE_DIRS}) ADD_DEFINITIONS(-DDB_PATH="${DB_INSTALL_DIR}/.vist.db" -DDEFAULT_POLICY_ADMIN="${DEFAULT_POLICY_ADMIN}" -DPLUGIN_INSTALL_DIR="${PLUGIN_INSTALL_DIR}" + -DTABLE_INSTALL_DIR="${TABLE_INSTALL_DIR}" -DSCRIPT_INSTALL_DIR="${SCRIPT_INSTALL_DIR}") ADD_DEFINITIONS("-Werror") diff --git a/src/vist/common/dynamic-loader.cpp b/src/vist/common/dynamic-loader.cpp index 92a7177..11113ba 100644 --- a/src/vist/common/dynamic-loader.cpp +++ b/src/vist/common/dynamic-loader.cpp @@ -39,11 +39,14 @@ DynamicLoader::ScopedHandle DynamicLoader::init(const std::string& path, int fla return handle; }; - auto close = [&](void* handle) { + auto close = [&](void* /*handle*/) { ::dlerror(); - if (::dlclose(handle) != 0) - THROW(ErrCode::RuntimeError) << "Failed to close library: " << ::dlerror(); +// Calling symbol & code after dlclose() makes SEGFAULT. +// TODO: Sync dynamic loading's life-cycle with program. +// +// if (::dlclose(handle) != 0) +// THROW(ErrCode::RuntimeError) << "Failed to close library: " << ::dlerror(); }; return ScopedHandle(open(), close); diff --git a/src/vist/policy/api.cpp b/src/vist/policy/api.cpp index 98e6b6b..90ae565 100644 --- a/src/vist/policy/api.cpp +++ b/src/vist/policy/api.cpp @@ -56,6 +56,11 @@ void API::Admin::Disenroll(const std::string& admin) PolicyManager::Instance().disenroll(admin); } +void API::Admin::AddProvider(std::shared_ptr&& provider) +{ + PolicyManager::Instance().addProvider(std::move(provider)); +} + void API::Admin::Activate(const std::string& admin, bool state) { PolicyManager::Instance().activate(admin, state); diff --git a/src/vist/policy/api.hpp b/src/vist/policy/api.hpp index 2998c1f..80b03f2 100644 --- a/src/vist/policy/api.hpp +++ b/src/vist/policy/api.hpp @@ -16,8 +16,10 @@ #pragma once +#include #include +#include #include #include @@ -37,6 +39,8 @@ struct API { static void Activate(const std::string& admin, bool state = true); static bool IsActivated(); + static void AddProvider(std::shared_ptr&& provider); + static std::unordered_map GetAll(); }; }; diff --git a/src/vist/policy/policy-manager.cpp b/src/vist/policy/policy-manager.cpp index 7a63afb..8a67a35 100644 --- a/src/vist/policy/policy-manager.cpp +++ b/src/vist/policy/policy-manager.cpp @@ -32,8 +32,6 @@ PolicyManager::PolicyManager() : storage(DB_PATH) loadProviders(PLUGIN_INSTALL_DIR); int cnt = loadPolicies(); INFO(VIST) << std::to_string(cnt) << "-policies loaded"; - - this->storage.enroll(DEFAULT_POLICY_ADMIN); } std::pair PolicyManager::loadProviders(const std::string& path) @@ -75,6 +73,27 @@ std::pair PolicyManager::loadProviders(const std::string& path) return std::make_pair(passed, failed); } +void PolicyManager::addProvider(std::shared_ptr&& provider) +{ + for (const auto& p : this->providers) { + if (p->getName() == provider->getName()) { + INFO(VIST) << "Previous added provider: " << provider->getName(); + return; + } + } + + for (const auto& [name, policy] : provider->policies) { + this->policies[name] = provider->getName(); + + if (!storage.exists(name)) + storage.define(name, policy->getInitial()); + } + + INFO(VIST) << "Added " << provider->policies.size() + << "-policies from " << provider->getName(); + this->providers.emplace_back(std::move(provider)); +} + int PolicyManager::loadPolicies() { /// Make policy-provider map for performance @@ -151,7 +170,7 @@ const std::shared_ptr& PolicyManager::getPolicy(const std::string& auto provider = this->policies[name]; auto iter = std::find_if(this->providers.begin(), this->providers.end(), - [&provider](const std::unique_ptr& p) { + [&provider](const std::shared_ptr& p) { return p->getName() == provider; }); if (iter == this->providers.end()) diff --git a/src/vist/policy/policy-manager.hpp b/src/vist/policy/policy-manager.hpp index 3eda4d7..ea46d94 100644 --- a/src/vist/policy/policy-manager.hpp +++ b/src/vist/policy/policy-manager.hpp @@ -51,6 +51,8 @@ public: void activate(const std::string& admin, bool state); bool isActivated(); + void addProvider(std::shared_ptr&& provider); + void set(const std::string& policy, const PolicyValue& value, const std::string& admin); @@ -67,7 +69,7 @@ private: int loadPolicies(); PolicyStorage storage; - std::vector> providers; + std::vector> providers; const std::shared_ptr& getPolicy(const std::string& name); diff --git a/src/vist/policy/tests/core.cpp b/src/vist/policy/tests/core.cpp index 083ea95..98b5d5b 100644 --- a/src/vist/policy/tests/core.cpp +++ b/src/vist/policy/tests/core.cpp @@ -33,17 +33,17 @@ TEST(PolicyCoreTests, policy_set_get_int) { auto& manager = PolicyManager::Instance(); manager.enroll("testAdmin"); - manager.set("sample-int-policy", PolicyValue(5), "testAdmin"); + manager.set("sample_int_policy", PolicyValue(5), "testAdmin"); /// Default Admin's policy is more strict. (Because of initial value: 7) - auto policy = manager.get("sample-int-policy"); + auto policy = manager.get("sample_int_policy"); EXPECT_EQ(static_cast(policy), 7); manager.enroll("testAdmin1"); - manager.set("sample-int-policy", PolicyValue(10), "testAdmin1"); + manager.set("sample_int_policy", PolicyValue(10), "testAdmin1"); /// Manager should return the strongest policy. - policy = manager.get("sample-int-policy"); + policy = manager.get("sample_int_policy"); EXPECT_EQ(static_cast(policy), 10); manager.disenroll("testAdmin"); @@ -80,8 +80,8 @@ TEST(PolicyCoreTests, policy_get_all) TEST(PolicyCoreTests, policy_get_policy) { auto& manager = PolicyManager::Instance(); - const auto& policy = manager.getPolicy("sample-int-policy"); - EXPECT_EQ(policy->getName(), "sample-int-policy"); + const auto& policy = manager.getPolicy("sample_int_policy"); + EXPECT_EQ(policy->getName(), "sample_int_policy"); bool raised = false; try { diff --git a/src/vist/service/tests/core.cpp b/src/vist/service/tests/core.cpp index 83d6f73..7b5c505 100644 --- a/src/vist/service/tests/core.cpp +++ b/src/vist/service/tests/core.cpp @@ -32,27 +32,29 @@ TEST_F(CoreTests, query_select) EXPECT_TRUE(rows.size() > 0); - std::string statement = "SELECT * FROM policy WHERE name = 'sample-int-policy'"; + std::string statement = "SELECT * FROM policy WHERE name = 'sample_int_policy'"; rows = Vistd::Query(statement); - EXPECT_EQ(rows.size(), 1); - EXPECT_EQ(rows[0]["name"], "sample-int-policy"); + if (rows.size() == 1) + EXPECT_EQ(rows[0]["name"], "sample_int_policy"); + else + EXPECT_TRUE(false); } TEST_F(CoreTests, query_update) { policy::API::Admin::Enroll("vist-test"); - std::string statement = "SELECT * FROM policy WHERE name = 'sample-int-policy'"; + std::string statement = "SELECT * FROM policy WHERE name = 'sample_int_policy'"; auto rows = Vistd::Query(statement); /// Initial policy value EXPECT_EQ(rows[0]["value"], "I/7"); - statement = "UPDATE policy SET value = 'I/10' WHERE name = 'sample-int-policy'"; + statement = "UPDATE policy SET value = 'I/10' WHERE name = 'sample_int_policy'"; rows = Vistd::Query(statement); EXPECT_EQ(rows.size(), 0); - statement = "SELECT * FROM policy WHERE name = 'sample-int-policy'"; + statement = "SELECT * FROM policy WHERE name = 'sample_int_policy'"; rows = Vistd::Query(statement); EXPECT_EQ(rows[0]["value"], "I/10"); diff --git a/src/vist/service/vistd.cpp b/src/vist/service/vistd.cpp index 695dc53..c2fffbb 100644 --- a/src/vist/service/vistd.cpp +++ b/src/vist/service/vistd.cpp @@ -16,18 +16,22 @@ #include "vistd.hpp" +#include #include #include +#include #include #include -#include -#include -#include +#include +#include +#include #include #include +#include + namespace { const std::string SOCK_ADDR = "/tmp/.vist"; } // anonymous namespace @@ -38,9 +42,10 @@ Vistd::Vistd() { osquery::registryAndPluginInit(); - table::BluetoothTable::Init(); - table::PolicyAdminTable::Init(); - table::PolicyTable::Init(); + this->loadStaticTable(); + this->loadDynamicTable(); + + policy::API::Admin::Enroll(DEFAULT_POLICY_ADMIN); } void Vistd::start() @@ -71,6 +76,7 @@ void Vistd::start() Rows Vistd::query(const std::string& statement) { + DEBUG(VIST) << "Excute query: " << statement; osquery::SQL sql(statement, true); if (!sql.ok()) THROW(ErrCode::RuntimeError) << "Faild to execute query: " << sql.getMessageString(); @@ -78,4 +84,25 @@ Rows Vistd::query(const std::string& statement) return sql.rows(); } +void Vistd::loadStaticTable() +{ + table::PolicyAdminTable::Init(); + table::PolicyTable::Init(); +} + +void Vistd::loadDynamicTable() +{ + for (auto& iter : std::filesystem::directory_iterator(TABLE_INSTALL_DIR)) { + DEBUG(VIST) << "Load dynamic table: " << iter.path(); + DynamicLoader loader(iter.path()); + auto factory = loader.load("DynamicTableFactory"); + if (auto table = (*factory)(); table != nullptr) { + table->init(); + delete table; + } else { + ERROR(VIST) << "Failed to load table."; + } + } +} + } // namespace vist diff --git a/src/vist/service/vistd.hpp b/src/vist/service/vistd.hpp index 818684a..87c5162 100644 --- a/src/vist/service/vistd.hpp +++ b/src/vist/service/vistd.hpp @@ -58,6 +58,9 @@ private: ~Vistd() = default; void start(); + + void loadStaticTable(); + void loadDynamicTable(); }; } // namespace vist diff --git a/src/vist/table/CMakeLists.txt b/src/vist/table/CMakeLists.txt index 77e5f50..f05ce01 100644 --- a/src/vist/table/CMakeLists.txt +++ b/src/vist/table/CMakeLists.txt @@ -12,6 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License -ADD_VIST_LIBRARY(vist_table bluetooth.cpp - policy-admin.cpp - policy.cpp) +## static virtual table +ADD_VIST_LIBRARY(vist_table policy/policy-admin.cpp + policy/policy.cpp) + +## dynamic virtual table +ADD_SUBDIRECTORY(policy/sample) diff --git a/src/vist/table/bluetooth.hpp b/src/vist/table/dynamic-table.hpp similarity index 74% rename from src/vist/table/bluetooth.hpp rename to src/vist/table/dynamic-table.hpp index 883468a..b04de07 100644 --- a/src/vist/table/bluetooth.hpp +++ b/src/vist/table/dynamic-table.hpp @@ -19,16 +19,11 @@ namespace vist { namespace table { -using namespace osquery; - -class BluetoothTable final : public TablePlugin { +class DynamicTable : public osquery::TablePlugin { public: - static void Init(); + using FactoryType = DynamicTable* (*)(); -private: - TableColumns columns() const override; - TableRows generate(QueryContext&) override; - QueryData update(QueryContext&, const PluginRequest& request) override; + virtual void init() = 0; }; } // namespace table diff --git a/src/vist/table/policy-admin.cpp b/src/vist/table/policy/policy-admin.cpp similarity index 100% rename from src/vist/table/policy-admin.cpp rename to src/vist/table/policy/policy-admin.cpp diff --git a/src/vist/table/policy-admin.hpp b/src/vist/table/policy/policy-admin.hpp similarity index 100% rename from src/vist/table/policy-admin.hpp rename to src/vist/table/policy/policy-admin.hpp diff --git a/src/vist/table/policy.cpp b/src/vist/table/policy/policy.cpp similarity index 100% rename from src/vist/table/policy.cpp rename to src/vist/table/policy/policy.cpp diff --git a/src/vist/table/policy.hpp b/src/vist/table/policy/policy.hpp similarity index 100% rename from src/vist/table/policy.hpp rename to src/vist/table/policy/policy.hpp diff --git a/plugins/CMakeLists.txt b/src/vist/table/policy/sample/CMakeLists.txt similarity index 58% rename from plugins/CMakeLists.txt rename to src/vist/table/policy/sample/CMakeLists.txt index 09d1fe8..d97eea6 100644 --- a/plugins/CMakeLists.txt +++ b/src/vist/table/policy/sample/CMakeLists.txt @@ -1,10 +1,10 @@ -# Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved +# Copyright (c) 2019-present 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 +# 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, @@ -12,12 +12,11 @@ # See the License for the specific language governing permissions and # limitations under the License. # +SET(TARGET "vist-plugin-sample") -SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,noexecstack") +INCLUDE_DIRECTORIES(SYSTEM) -ADD_SUBDIRECTORY(sample) +ADD_LIBRARY(${TARGET} SHARED sample.cpp) +TARGET_LINK_LIBRARIES(${TARGET} vist-common ${TARGET_VIST_POLICY_LIB}) -IF(DEFINED GBS_BUILD) - ADD_SUBDIRECTORY(bluetooth) - ADD_SUBDIRECTORY(wifi) -ENDIF(DEFINED GBS_BUILD) +INSTALL(TARGETS ${TARGET} DESTINATION ${TABLE_INSTALL_DIR}) diff --git a/src/vist/table/bluetooth.cpp b/src/vist/table/policy/sample/sample.cpp similarity index 52% rename from src/vist/table/bluetooth.cpp rename to src/vist/table/policy/sample/sample.cpp index 25cf78f..f5d02a2 100644 --- a/src/vist/table/bluetooth.cpp +++ b/src/vist/table/policy/sample/sample.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-present Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2019-present 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. @@ -14,68 +14,64 @@ * limitations under the License */ -#include "bluetooth.hpp" +#include "sample.hpp" + +#include +#include +#include -#include -#include #include #include #include #include -#include -#include -#include +extern "C" vist::table::DynamicTable* DynamicTableFactory() +{ + return new vist::table::SamplePolicyTable; +} namespace vist { namespace table { -namespace { +using namespace osquery; -std::map ALIAS = { - { "state", "bluetooth" }, - { "desktopConnectivity", "bluetooth-desktop-connectivity" }, - { "pairing", "bluetooth-pairing" }, - { "tethering", "bluetooth-tethering"} -}; - -void setPolicy(const std::string& name, int value) +void SamplePolicyTable::init() { - vist::policy::API::Admin::Set(name, vist::policy::PolicyValue(value)); -} + // Register virtual table to sqlite3 + auto tables = RegistryFactory::get().registry("table"); + tables->add("sample_policy", std::make_shared()); -} // anonymous namespace + // Register policy to policy-manager + auto provider = std::make_shared("sample-provider"); + provider->add(std::make_shared()); + provider->add(std::make_shared()); -void BluetoothTable::Init() -{ - auto tables = RegistryFactory::get().registry("table"); - tables->add("bluetooth", std::make_shared()); + policy::API::Admin::AddProvider(std::move(provider)); + + INFO(VIST_PLUGIN) << "Sample plugin loaded."; } -TableColumns BluetoothTable::columns() const +TableColumns SamplePolicyTable::columns() const { return { - std::make_tuple("state", INTEGER_TYPE, ColumnOptions::DEFAULT), - std::make_tuple("desktopConnectivity", INTEGER_TYPE, ColumnOptions::DEFAULT), - std::make_tuple("pairing", INTEGER_TYPE, ColumnOptions::DEFAULT), - std::make_tuple("tethering", INTEGER_TYPE, ColumnOptions::DEFAULT), + std::make_tuple("sample_int_policy", INTEGER_TYPE, ColumnOptions::DEFAULT), + std::make_tuple("sample_str_policy", TEXT_TYPE, ColumnOptions::DEFAULT), }; } -TableRows BluetoothTable::generate(QueryContext&) try +TableRows SamplePolicyTable::generate(QueryContext&) try { - INFO(VIST) << "Select query about bluetooth table."; - - QueryData results; + INFO(VIST) << "Select query about sample-policy table."; Row row; + int intPolicy = vist::policy::API::Get("sample_int_policy"); + row["sample_int_policy"] = std::to_string(intPolicy); - for (const auto&[schemaName, policyName] : ALIAS) { - int value = vist::policy::API::Get(policyName); - row[schemaName] = std::to_string(value); - } + std::string strPolicy = vist::policy::API::Get("sample_str_policy"); + row["sample_str_policy"] = strPolicy; + QueryData results; results.emplace_back(std::move(row)); return osquery::tableRowsFromQueryData(std::move(results)); @@ -91,23 +87,22 @@ TableRows BluetoothTable::generate(QueryContext&) try return osquery::tableRowsFromQueryData({ r }); } -QueryData BluetoothTable::update(QueryContext&, const PluginRequest& request) try +QueryData SamplePolicyTable::update(QueryContext&, const PluginRequest& request) try { - INFO(VIST) << "Update query about bluetooth table."; + INFO(VIST) << "Update query about sample-policy table."; if (request.count("json_values") == 0) throw std::runtime_error("Wrong request format. Not found json value."); DEBUG(VIST) << "Request values: " << request.at("json_values"); json::Json document = json::Json::Parse(request.at("json_values")); json::Array values = document.get("values"); - if (values.size() != 4) + if (values.size() != 2) throw std::runtime_error("Wrong request format."); - /// TODO(Sangwan): Sync vtab schema with policy definition - setPolicy("bluetooth", static_cast(values.at(0))); - setPolicy("bluetooth-desktop-connectivity", static_cast(values.at(1))); - setPolicy("bluetooth-pairing", static_cast(values.at(2))); - setPolicy("bluetooth-tethering", static_cast(values.at(3))); + policy::API::Admin::Set("sample_int_policy", + policy::PolicyValue(static_cast(values.at(0)))); + policy::API::Admin::Set("sample_str_policy", + policy::PolicyValue(static_cast(values.at(1)))); Row r; r["status"] = "success"; diff --git a/src/vist/table/policy/sample/sample.hpp b/src/vist/table/policy/sample/sample.hpp new file mode 100644 index 0000000..3b241f5 --- /dev/null +++ b/src/vist/table/policy/sample/sample.hpp @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2020-present 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 + */ +/* + * Query example + * - SELECT * FROM sample_policy + * - UPDATE sample_policy SET sample_int_policy = 99 + * - UPDATE sample_policy SET sample_str_policy = 'TEST_VALUE' + */ + +#include +#include + +#include +#include +#include + +#include + +#include +#include + +namespace vist { +namespace policy { + +class SampleIntPolicy : public PolicyModel { +public: + SampleIntPolicy() : PolicyModel("sample_int_policy", PolicyValue(7)) + { + } + + void onChanged(const PolicyValue& value) override + { + INFO(VIST_PLUGIN) << "sample_int_policy is changed to " + << static_cast(value); + } +}; + +class SampleStrPolicy : public PolicyModel { +public: + SampleStrPolicy() : PolicyModel("sample_str_policy", PolicyValue("TEST")) + { + } + + void onChanged(const PolicyValue& value) override + { + INFO(VIST_PLUGIN) << "sample_str_policy is changed to " + << static_cast(value); + } + + int compare(const PolicyValue& lhs, const PolicyValue& rhs) const override + { + std::string lvalue = lhs; + std::string rvalue = rhs; + + INFO(VIST_PLUGIN) << "Custom compare method is called with [" << lvalue + << "], [" << rvalue << "]"; + + return lvalue.compare(rvalue); + } +}; + +class Sample : public PolicyProvider { +public: + Sample(const std::string& name) : PolicyProvider(name) + { + } + + ~Sample() + { + } +}; +} // namespace policy + +namespace table { + +using namespace osquery; + +class SamplePolicyTable final : public DynamicTable { +public: + void init(); + +private: + TableColumns columns() const override; + TableRows generate(QueryContext&) override; + QueryData update(QueryContext&, const PluginRequest& request) override; +}; + +} // namespace table +} // namespace vist -- 2.34.1