From: Sangwan Kwon Date: Fri, 17 Jul 2020 06:22:20 +0000 (+0900) Subject: Redesign policy management logic X-Git-Tag: submit/tizen/20200810.073515~6 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9f2e28f23bc5c5829de331fa4bb12aadd0b9ecb0;p=platform%2Fcore%2Fsecurity%2Fvist.git 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 --- 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/plugins/CMakeLists.txt b/plugins/CMakeLists.txt deleted file mode 100644 index 09d1fe8..0000000 --- a/plugins/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -# 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(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,noexecstack") - -ADD_SUBDIRECTORY(sample) - -IF(DEFINED GBS_BUILD) - ADD_SUBDIRECTORY(bluetooth) - ADD_SUBDIRECTORY(wifi) -ENDIF(DEFINED GBS_BUILD) 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.cpp b/src/vist/table/bluetooth.cpp deleted file mode 100644 index 25cf78f..0000000 --- a/src/vist/table/bluetooth.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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 - */ - -#include "bluetooth.hpp" - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -namespace vist { -namespace table { - -namespace { - -std::map ALIAS = { - { "state", "bluetooth" }, - { "desktopConnectivity", "bluetooth-desktop-connectivity" }, - { "pairing", "bluetooth-pairing" }, - { "tethering", "bluetooth-tethering"} -}; - -void setPolicy(const std::string& name, int value) -{ - vist::policy::API::Admin::Set(name, vist::policy::PolicyValue(value)); -} - -} // anonymous namespace - -void BluetoothTable::Init() -{ - auto tables = RegistryFactory::get().registry("table"); - tables->add("bluetooth", std::make_shared()); -} - -TableColumns BluetoothTable::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), - }; -} - -TableRows BluetoothTable::generate(QueryContext&) try -{ - INFO(VIST) << "Select query about bluetooth table."; - - QueryData results; - - Row row; - - for (const auto&[schemaName, policyName] : ALIAS) { - int value = vist::policy::API::Get(policyName); - row[schemaName] = std::to_string(value); - } - - results.emplace_back(std::move(row)); - - return osquery::tableRowsFromQueryData(std::move(results)); -} catch (const vist::Exception& e) -{ - ERROR(VIST) << "Failed to query: " << e.what(); - Row r; - return osquery::tableRowsFromQueryData({ r }); -} catch (...) -{ - ERROR(VIST) << "Failed to query with unknown exception."; - Row r; - return osquery::tableRowsFromQueryData({ r }); -} - -QueryData BluetoothTable::update(QueryContext&, const PluginRequest& request) try -{ - INFO(VIST) << "Update query about bluetooth 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) - 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))); - - Row r; - r["status"] = "success"; - return { r }; -} catch (const vist::Exception& e) -{ - ERROR(VIST) << "Failed to query: " << e.what(); - Row r; - return { r }; -} catch (...) -{ - ERROR(VIST) << "Failed to query with unknown exception."; - Row r; - return { r }; -} - -} // namespace table -} // namespace vist diff --git a/src/vist/table/bluetooth.hpp b/src/vist/table/bluetooth.hpp deleted file mode 100644 index 883468a..0000000 --- a/src/vist/table/bluetooth.hpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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 - */ - -#include - -namespace vist { -namespace table { - -using namespace osquery; - -class BluetoothTable final : public TablePlugin { -public: - static void Init(); - -private: - TableColumns columns() const override; - TableRows generate(QueryContext&) override; - QueryData update(QueryContext&, const PluginRequest& request) override; -}; - -} // namespace table -} // namespace vist diff --git a/src/vist/table/dynamic-table.hpp b/src/vist/table/dynamic-table.hpp new file mode 100644 index 0000000..b04de07 --- /dev/null +++ b/src/vist/table/dynamic-table.hpp @@ -0,0 +1,30 @@ +/* + * 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 + */ + +#include + +namespace vist { +namespace table { + +class DynamicTable : public osquery::TablePlugin { +public: + using FactoryType = DynamicTable* (*)(); + + virtual void init() = 0; +}; + +} // namespace table +} // namespace vist diff --git a/src/vist/table/policy-admin.cpp b/src/vist/table/policy-admin.cpp deleted file mode 100644 index 9edc0d0..0000000 --- a/src/vist/table/policy-admin.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/* - * 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 - * - * 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-admin.hpp" - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -namespace vist { -namespace table { - -namespace { - -std::string getValue(std::string&& alias, const std::string& key) -{ - auto pos = alias.find(";"); - auto token = alias.substr(0, pos); - - if (token == key) - return alias.erase(0, pos + 1); - else - return std::string(); -} - -std::string parseAdmin(const std::string& request, bool insert = true) -{ - json::Json document = json::Json::Parse(request); - json::Array values = document.get("values"); - - if (insert) - return values.at(0); - else - return getValue(values.at(0), "name"); -} - -} // anonymous namespace - -void PolicyAdminTable::Init() -{ - auto tables = RegistryFactory::get().registry("table"); - tables->add("policy_admin", std::make_shared()); -} - -TableColumns PolicyAdminTable::columns() const -{ - return { - std::make_tuple("name", TEXT_TYPE, ColumnOptions::DEFAULT), - std::make_tuple("activated", INTEGER_TYPE, ColumnOptions::DEFAULT), - }; -} - -TableRows PolicyAdminTable::generate(QueryContext& context) try -{ - INFO(VIST) << "Select query about policy-admin table."; - - QueryData results; - auto admins = vist::policy::API::Admin::GetAll(); - - for (auto& admin : admins) { - if (context.constraints["name"].exists(EQUALS)) { /// where clause - auto names = context.constraints["name"].getAll(EQUALS); - for (const auto& name : names) { - if (name == admin.first) { - Row row; - row["name"] = admin.first; - row["activated"] = std::to_string(admin.second); - - DEBUG(VIST) << "Admin info [name]: " << row["name"] - << ", [activated]:" << row["activated"]; - - results.emplace_back(std::move(row)); - } - } - } else { /// select *; - Row row; - row["name"] = admin.first; - row["activated"] = std::to_string(admin.second); - - DEBUG(VIST) << "Admin info [name]: " << row["name"] - << ", [activated]:" << row["activated"]; - results.emplace_back(std::move(row)); - } - } - - return osquery::tableRowsFromQueryData(std::move(results)); -} catch (const vist::Exception& e) -{ - ERROR(VIST) << "Failed to query: " << e.what(); - Row r; - return osquery::tableRowsFromQueryData({ r }); -} catch (...) -{ - ERROR(VIST) << "Failed to query with unknown exception."; - Row r; - return osquery::tableRowsFromQueryData({ r }); -} - -QueryData PolicyAdminTable::insert(QueryContext&, const PluginRequest& request) try -{ - INFO(VIST) << "Insert query about policy-admin 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"); - auto admin = parseAdmin(request.at("json_values")); - DEBUG(VIST) << "Admin info [name]: " << admin; - vist::policy::API::Admin::Enroll(admin); - - Row r; - r["status"] = "success"; - return { r }; -} catch (const vist::Exception& e) -{ - ERROR(VIST) << "Failed to query: " << e.what(); - Row r; - return { r }; -} catch (...) -{ - ERROR(VIST) << "Failed to query with unknown exception."; - Row r; - return { r }; -} - -QueryData PolicyAdminTable::delete_(QueryContext&, const PluginRequest& request) try -{ - INFO(VIST) << "Delete query about policy-admin 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"); - auto admin = parseAdmin(request.at("json_values"), false); - DEBUG(VIST) << "Admin info [name]: " << admin; - vist::policy::API::Admin::Disenroll(admin); - - Row r; - r["status"] = "success"; - return { r }; -} catch (const vist::Exception& e) -{ - ERROR(VIST) << "Failed to query: " << e.what(); - Row r; - return { r }; -} catch (...) -{ - ERROR(VIST) << "Failed to query with unknown exception."; - Row r; - return { r }; -} - -QueryData PolicyAdminTable::update(QueryContext&, const PluginRequest& request) try -{ - INFO(VIST) << "Update query about policy-admin 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() != 2) - throw std::runtime_error("Wrong request format."); - - std::string name = static_cast(values.at(0)); - int activated = static_cast(values.at(1)); - - vist::policy::API::Admin::Activate(name, activated); - - Row r; - r["status"] = "success"; - return { r }; -} catch (const vist::Exception& e) -{ - ERROR(VIST) << "Failed to query: " << e.what(); - Row r; - return { r }; -} catch (...) -{ - ERROR(VIST) << "Failed to query with unknown exception."; - Row r; - return { r }; -} - -} // namespace tables -} // namespace osquery diff --git a/src/vist/table/policy-admin.hpp b/src/vist/table/policy-admin.hpp deleted file mode 100644 index d8a8a7e..0000000 --- a/src/vist/table/policy-admin.hpp +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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 - */ - -#include - -namespace vist { -namespace table { - -using namespace osquery; - -class PolicyAdminTable final : public TablePlugin { -public: - static void Init(); - -private: - TableColumns columns() const override; - TableRows generate(QueryContext&) override; - QueryData delete_(QueryContext&, const PluginRequest& request) override; - QueryData insert(QueryContext&, const PluginRequest& request) override; - QueryData update(QueryContext&, const PluginRequest& request) override; -}; - -} // namespace table -} // namespace vist diff --git a/src/vist/table/policy.cpp b/src/vist/table/policy.cpp deleted file mode 100644 index ca0060b..0000000 --- a/src/vist/table/policy.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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 - * - * 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.hpp" - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -namespace vist { -namespace table { - -namespace { - -Row convert(const std::string& name, const vist::policy::PolicyValue& value) -{ - Row r; - r["name"] = name; - r["value"] = value.dump(); - - return r; -} - -} // anonymous namespace - -void PolicyTable::Init() -{ - auto tables = RegistryFactory::get().registry("table"); - tables->add("policy", std::make_shared()); -} - -TableColumns PolicyTable::columns() const -{ - return { - std::make_tuple("name", TEXT_TYPE, ColumnOptions::DEFAULT), - std::make_tuple("value", TEXT_TYPE, ColumnOptions::DEFAULT), - }; -} - -TableRows PolicyTable::generate(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 value = vist::policy::API::Get(name); - auto row = convert(name, value); - - results.emplace_back(std::move(row)); - } - } else { /// select *; - auto policies = vist::policy::API::GetAll(); - for (auto& policy : policies) { - auto row = convert(policy.first, policy.second); - - results.emplace_back(std::move(row)); - } - } - - return osquery::tableRowsFromQueryData(std::move(results)); -} catch (const vist::Exception& e) -{ - ERROR(VIST) << "Failed to query: " << e.what(); - Row r; - return osquery::tableRowsFromQueryData({ r }); -} catch (...) -{ - ERROR(VIST) << "Failed to query with unknown exception."; - Row r; - return osquery::tableRowsFromQueryData({ r }); -} - -QueryData PolicyTable::update(QueryContext&, const PluginRequest& request) try -{ - INFO(VIST) << "Update query about 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() != 2) - throw std::runtime_error("Wrong request format."); - - std::string name = static_cast(values.at(0)); - std::string dumpedValue = static_cast(values.at(1)); - - vist::policy::API::Admin::Set(name, vist::policy::PolicyValue(dumpedValue, true)); - - Row r; - r["status"] = "success"; - return { r }; -} catch (const vist::Exception& e) -{ - ERROR(VIST) << "Failed to query: " << e.what(); - Row r; - return { r }; -} catch (...) -{ - ERROR(VIST) << "Failed to query with unknown exception."; - Row r; - return { r }; -} - -} // namespace table -} // namespace vist diff --git a/src/vist/table/policy.hpp b/src/vist/table/policy.hpp deleted file mode 100644 index f96c473..0000000 --- a/src/vist/table/policy.hpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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 - */ - -#include - -namespace vist { -namespace table { - -using namespace osquery; - -class PolicyTable final : public TablePlugin { -public: - static void Init(); - -private: - TableColumns columns() const override; - TableRows generate(QueryContext&) override; - QueryData update(QueryContext&, const PluginRequest& request) override; -}; - -} // namespace table -} // namespace vist diff --git a/src/vist/table/policy/policy-admin.cpp b/src/vist/table/policy/policy-admin.cpp new file mode 100644 index 0000000..9edc0d0 --- /dev/null +++ b/src/vist/table/policy/policy-admin.cpp @@ -0,0 +1,205 @@ +/* + * 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 + * + * 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-admin.hpp" + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +namespace vist { +namespace table { + +namespace { + +std::string getValue(std::string&& alias, const std::string& key) +{ + auto pos = alias.find(";"); + auto token = alias.substr(0, pos); + + if (token == key) + return alias.erase(0, pos + 1); + else + return std::string(); +} + +std::string parseAdmin(const std::string& request, bool insert = true) +{ + json::Json document = json::Json::Parse(request); + json::Array values = document.get("values"); + + if (insert) + return values.at(0); + else + return getValue(values.at(0), "name"); +} + +} // anonymous namespace + +void PolicyAdminTable::Init() +{ + auto tables = RegistryFactory::get().registry("table"); + tables->add("policy_admin", std::make_shared()); +} + +TableColumns PolicyAdminTable::columns() const +{ + return { + std::make_tuple("name", TEXT_TYPE, ColumnOptions::DEFAULT), + std::make_tuple("activated", INTEGER_TYPE, ColumnOptions::DEFAULT), + }; +} + +TableRows PolicyAdminTable::generate(QueryContext& context) try +{ + INFO(VIST) << "Select query about policy-admin table."; + + QueryData results; + auto admins = vist::policy::API::Admin::GetAll(); + + for (auto& admin : admins) { + if (context.constraints["name"].exists(EQUALS)) { /// where clause + auto names = context.constraints["name"].getAll(EQUALS); + for (const auto& name : names) { + if (name == admin.first) { + Row row; + row["name"] = admin.first; + row["activated"] = std::to_string(admin.second); + + DEBUG(VIST) << "Admin info [name]: " << row["name"] + << ", [activated]:" << row["activated"]; + + results.emplace_back(std::move(row)); + } + } + } else { /// select *; + Row row; + row["name"] = admin.first; + row["activated"] = std::to_string(admin.second); + + DEBUG(VIST) << "Admin info [name]: " << row["name"] + << ", [activated]:" << row["activated"]; + results.emplace_back(std::move(row)); + } + } + + return osquery::tableRowsFromQueryData(std::move(results)); +} catch (const vist::Exception& e) +{ + ERROR(VIST) << "Failed to query: " << e.what(); + Row r; + return osquery::tableRowsFromQueryData({ r }); +} catch (...) +{ + ERROR(VIST) << "Failed to query with unknown exception."; + Row r; + return osquery::tableRowsFromQueryData({ r }); +} + +QueryData PolicyAdminTable::insert(QueryContext&, const PluginRequest& request) try +{ + INFO(VIST) << "Insert query about policy-admin 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"); + auto admin = parseAdmin(request.at("json_values")); + DEBUG(VIST) << "Admin info [name]: " << admin; + vist::policy::API::Admin::Enroll(admin); + + Row r; + r["status"] = "success"; + return { r }; +} catch (const vist::Exception& e) +{ + ERROR(VIST) << "Failed to query: " << e.what(); + Row r; + return { r }; +} catch (...) +{ + ERROR(VIST) << "Failed to query with unknown exception."; + Row r; + return { r }; +} + +QueryData PolicyAdminTable::delete_(QueryContext&, const PluginRequest& request) try +{ + INFO(VIST) << "Delete query about policy-admin 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"); + auto admin = parseAdmin(request.at("json_values"), false); + DEBUG(VIST) << "Admin info [name]: " << admin; + vist::policy::API::Admin::Disenroll(admin); + + Row r; + r["status"] = "success"; + return { r }; +} catch (const vist::Exception& e) +{ + ERROR(VIST) << "Failed to query: " << e.what(); + Row r; + return { r }; +} catch (...) +{ + ERROR(VIST) << "Failed to query with unknown exception."; + Row r; + return { r }; +} + +QueryData PolicyAdminTable::update(QueryContext&, const PluginRequest& request) try +{ + INFO(VIST) << "Update query about policy-admin 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() != 2) + throw std::runtime_error("Wrong request format."); + + std::string name = static_cast(values.at(0)); + int activated = static_cast(values.at(1)); + + vist::policy::API::Admin::Activate(name, activated); + + Row r; + r["status"] = "success"; + return { r }; +} catch (const vist::Exception& e) +{ + ERROR(VIST) << "Failed to query: " << e.what(); + Row r; + return { r }; +} catch (...) +{ + ERROR(VIST) << "Failed to query with unknown exception."; + Row r; + return { r }; +} + +} // namespace tables +} // namespace osquery diff --git a/src/vist/table/policy/policy-admin.hpp b/src/vist/table/policy/policy-admin.hpp new file mode 100644 index 0000000..d8a8a7e --- /dev/null +++ b/src/vist/table/policy/policy-admin.hpp @@ -0,0 +1,37 @@ +/* + * 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 + */ + +#include + +namespace vist { +namespace table { + +using namespace osquery; + +class PolicyAdminTable final : public TablePlugin { +public: + static void Init(); + +private: + TableColumns columns() const override; + TableRows generate(QueryContext&) override; + QueryData delete_(QueryContext&, const PluginRequest& request) override; + QueryData insert(QueryContext&, const PluginRequest& request) override; + QueryData update(QueryContext&, const PluginRequest& request) override; +}; + +} // namespace table +} // namespace vist diff --git a/src/vist/table/policy/policy.cpp b/src/vist/table/policy/policy.cpp new file mode 100644 index 0000000..ca0060b --- /dev/null +++ b/src/vist/table/policy/policy.cpp @@ -0,0 +1,129 @@ +/* + * 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 + * + * 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.hpp" + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +namespace vist { +namespace table { + +namespace { + +Row convert(const std::string& name, const vist::policy::PolicyValue& value) +{ + Row r; + r["name"] = name; + r["value"] = value.dump(); + + return r; +} + +} // anonymous namespace + +void PolicyTable::Init() +{ + auto tables = RegistryFactory::get().registry("table"); + tables->add("policy", std::make_shared()); +} + +TableColumns PolicyTable::columns() const +{ + return { + std::make_tuple("name", TEXT_TYPE, ColumnOptions::DEFAULT), + std::make_tuple("value", TEXT_TYPE, ColumnOptions::DEFAULT), + }; +} + +TableRows PolicyTable::generate(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 value = vist::policy::API::Get(name); + auto row = convert(name, value); + + results.emplace_back(std::move(row)); + } + } else { /// select *; + auto policies = vist::policy::API::GetAll(); + for (auto& policy : policies) { + auto row = convert(policy.first, policy.second); + + results.emplace_back(std::move(row)); + } + } + + return osquery::tableRowsFromQueryData(std::move(results)); +} catch (const vist::Exception& e) +{ + ERROR(VIST) << "Failed to query: " << e.what(); + Row r; + return osquery::tableRowsFromQueryData({ r }); +} catch (...) +{ + ERROR(VIST) << "Failed to query with unknown exception."; + Row r; + return osquery::tableRowsFromQueryData({ r }); +} + +QueryData PolicyTable::update(QueryContext&, const PluginRequest& request) try +{ + INFO(VIST) << "Update query about 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() != 2) + throw std::runtime_error("Wrong request format."); + + std::string name = static_cast(values.at(0)); + std::string dumpedValue = static_cast(values.at(1)); + + vist::policy::API::Admin::Set(name, vist::policy::PolicyValue(dumpedValue, true)); + + Row r; + r["status"] = "success"; + return { r }; +} catch (const vist::Exception& e) +{ + ERROR(VIST) << "Failed to query: " << e.what(); + Row r; + return { r }; +} catch (...) +{ + ERROR(VIST) << "Failed to query with unknown exception."; + Row r; + return { r }; +} + +} // namespace table +} // namespace vist diff --git a/src/vist/table/policy/policy.hpp b/src/vist/table/policy/policy.hpp new file mode 100644 index 0000000..f96c473 --- /dev/null +++ b/src/vist/table/policy/policy.hpp @@ -0,0 +1,35 @@ +/* + * 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 + */ + +#include + +namespace vist { +namespace table { + +using namespace osquery; + +class PolicyTable final : public TablePlugin { +public: + static void Init(); + +private: + TableColumns columns() const override; + TableRows generate(QueryContext&) override; + QueryData update(QueryContext&, const PluginRequest& request) override; +}; + +} // namespace table +} // namespace vist diff --git a/src/vist/table/policy/sample/CMakeLists.txt b/src/vist/table/policy/sample/CMakeLists.txt new file mode 100644 index 0000000..d97eea6 --- /dev/null +++ b/src/vist/table/policy/sample/CMakeLists.txt @@ -0,0 +1,22 @@ +# 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 +# +# 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-plugin-sample") + +INCLUDE_DIRECTORIES(SYSTEM) + +ADD_LIBRARY(${TARGET} SHARED sample.cpp) +TARGET_LINK_LIBRARIES(${TARGET} vist-common ${TARGET_VIST_POLICY_LIB}) + +INSTALL(TARGETS ${TARGET} DESTINATION ${TABLE_INSTALL_DIR}) diff --git a/src/vist/table/policy/sample/sample.cpp b/src/vist/table/policy/sample/sample.cpp new file mode 100644 index 0000000..f5d02a2 --- /dev/null +++ b/src/vist/table/policy/sample/sample.cpp @@ -0,0 +1,123 @@ +/* + * 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 + * + * 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 "sample.hpp" + +#include +#include +#include + +#include +#include + +#include +#include + +extern "C" vist::table::DynamicTable* DynamicTableFactory() +{ + return new vist::table::SamplePolicyTable; +} + +namespace vist { +namespace table { + +using namespace osquery; + +void SamplePolicyTable::init() +{ + // Register virtual table to sqlite3 + auto tables = RegistryFactory::get().registry("table"); + tables->add("sample_policy", std::make_shared()); + + // Register policy to policy-manager + auto provider = std::make_shared("sample-provider"); + provider->add(std::make_shared()); + provider->add(std::make_shared()); + + policy::API::Admin::AddProvider(std::move(provider)); + + INFO(VIST_PLUGIN) << "Sample plugin loaded."; +} + +TableColumns SamplePolicyTable::columns() const +{ + return { + std::make_tuple("sample_int_policy", INTEGER_TYPE, ColumnOptions::DEFAULT), + std::make_tuple("sample_str_policy", TEXT_TYPE, ColumnOptions::DEFAULT), + }; +} + +TableRows SamplePolicyTable::generate(QueryContext&) try +{ + 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); + + 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)); +} catch (const vist::Exception& e) +{ + ERROR(VIST) << "Failed to query: " << e.what(); + Row r; + return osquery::tableRowsFromQueryData({ r }); +} catch (...) +{ + ERROR(VIST) << "Failed to query with unknown exception."; + Row r; + return osquery::tableRowsFromQueryData({ r }); +} + +QueryData SamplePolicyTable::update(QueryContext&, const PluginRequest& request) try +{ + 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() != 2) + throw std::runtime_error("Wrong request format."); + + 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"; + return { r }; +} catch (const vist::Exception& e) +{ + ERROR(VIST) << "Failed to query: " << e.what(); + Row r; + return { r }; +} catch (...) +{ + ERROR(VIST) << "Failed to query with unknown exception."; + Row r; + return { r }; +} + +} // namespace table +} // namespace vist 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