From e83315b8c075c453ce296318dc5de739b2fc3373 Mon Sep 17 00:00:00 2001 From: Sangwan Kwon Date: Fri, 24 Jul 2020 13:38:25 +0900 Subject: [PATCH] Refactor virtual table Change-Id: If7d0fa01547a3734254fc89b981c9ff00ae59ba3 Signed-off-by: Sangwan Kwon --- src/osquery/core/tables.cpp | 3 +- src/osquery/include/osquery/tables.h | 5 +- src/osquery/sql/tests/sql.cpp | 12 +- src/osquery/sql/tests/virtual_table.cpp | 89 +++++++-------- src/osquery/sql/virtual_table.cpp | 2 +- src/vist/table/CMakeLists.txt | 3 +- src/vist/table/builder.hpp | 59 ++++++++++ src/vist/table/dynamic-table.hpp | 12 +- src/vist/table/parser.hpp | 48 ++++++++ src/vist/table/policy/bluetooth/table.cpp | 70 ++++-------- src/vist/table/policy/bluetooth/table.hpp | 2 +- src/vist/table/policy/policy-admin.cpp | 133 ++++++---------------- src/vist/table/policy/policy-admin.hpp | 2 +- src/vist/table/policy/policy.cpp | 64 ++++------- src/vist/table/policy/policy.hpp | 2 +- src/vist/table/policy/sample/table.cpp | 69 ++++------- src/vist/table/policy/sample/table.hpp | 2 +- src/vist/table/util.cpp | 47 ++++++++ src/vist/table/util.hpp | 38 +++++++ 19 files changed, 355 insertions(+), 307 deletions(-) create mode 100644 src/vist/table/builder.hpp create mode 100644 src/vist/table/parser.hpp create mode 100644 src/vist/table/util.cpp create mode 100644 src/vist/table/util.hpp diff --git a/src/osquery/core/tables.cpp b/src/osquery/core/tables.cpp index 48ced6c..18bfa80 100644 --- a/src/osquery/core/tables.cpp +++ b/src/osquery/core/tables.cpp @@ -138,8 +138,7 @@ Status TablePlugin::call(const PluginRequest& request, if (action == "generate") { auto context = getContextFromRequest(request); - TableRows result = generate(context); - response = tableRowsToPluginResponse(result); + response = generate(context); } else if (action == "delete") { auto context = getContextFromRequest(request); response = delete_(context, request); diff --git a/src/osquery/include/osquery/tables.h b/src/osquery/include/osquery/tables.h index 091cb65..5cf05da 100644 --- a/src/osquery/include/osquery/tables.h +++ b/src/osquery/include/osquery/tables.h @@ -748,10 +748,9 @@ public: * @param context A query context filled in by SQLite's virtual table API. * @return The result rows for this table, given the query context. */ - virtual TableRows generate(QueryContext& context) + virtual QueryData generate(QueryContext&) { - (void)context; - return TableRows(); + return QueryData(); } /// Callback for DELETE statements diff --git a/src/osquery/sql/tests/sql.cpp b/src/osquery/sql/tests/sql.cpp index c520c45..9543bf0 100644 --- a/src/osquery/sql/tests/sql.cpp +++ b/src/osquery/sql/tests/sql.cpp @@ -37,20 +37,18 @@ private: }; } - TableRows generate(QueryContext& ctx) + QueryData generate(QueryContext& ctx) { - TableRows results; + QueryData results; if (ctx.constraints["test_int"].existsAndMatches("1")) { - results.push_back( - make_table_row({{"test_int", "1"}, {"test_text", "0"}})); + results.push_back({{"test_int", "1"}, {"test_text", "0"}}); } else { - results.push_back( - make_table_row({{"test_int", "0"}, {"test_text", "1"}})); + results.push_back({{"test_int", "0"}, {"test_text", "1"}}); } auto ints = ctx.constraints["test_int"].getAll(EQUALS); for (const auto& int_match : ints) { - results.push_back(make_table_row({{"test_int", INTEGER(int_match)}})); + results.push_back({{"test_int", INTEGER(int_match)}}); } return results; diff --git a/src/osquery/sql/tests/virtual_table.cpp b/src/osquery/sql/tests/virtual_table.cpp index f7cef0d..bec6d6c 100644 --- a/src/osquery/sql/tests/virtual_table.cpp +++ b/src/osquery/sql/tests/virtual_table.cpp @@ -225,11 +225,11 @@ private: } public: - TableRows generate(QueryContext&) override + QueryData generate(QueryContext&) override { - TableRows tr; - tr.push_back(make_table_row({{"x", "1"}, {"y", "2"}})); - tr.push_back(make_table_row({{"x", "2"}, {"y", "1"}})); + QueryData tr; + tr.push_back({{"x", "1"}, {"y", "2"}}); + tr.push_back({{"x", "2"}, {"y", "1"}}); return tr; } @@ -248,11 +248,11 @@ private: } public: - TableRows generate(QueryContext&) override + QueryData generate(QueryContext&) override { - TableRows tr; - tr.push_back(make_table_row({{"x", "1"}, {"z", "2"}})); - tr.push_back(make_table_row({{"x", "2"}, {"z", "1"}})); + QueryData tr; + tr.push_back({{"x", "1"}, {"z", "2"}}); + tr.push_back({{"x", "2"}, {"z", "1"}}); return tr; } @@ -353,10 +353,10 @@ private: } public: - TableRows generate(QueryContext&) override + QueryData generate(QueryContext&) override { - TableRows results; - results.push_back(make_table_row({{"data", "{\"test\": 1}"}})); + QueryData results; + results.push_back({{"data", "{\"test\": 1}"}}); return results; } @@ -431,16 +431,14 @@ private: } public: - TableRows generate(QueryContext& context) override + QueryData generate(QueryContext& context) override { - TableRows results; + QueryData results; if (context.isCached("awesome_data")) { // There is cache entry for awesome data. - results.push_back(make_table_row({{"data", "more_awesome_data"}})); + results.push_back({{"data", "more_awesome_data"}}); } else { - auto tr = make_table_row({{"data", "awesome_data"}}); - context.setCache("awesome_data", static_cast < TableRowHolder && >(tr)); - results.push_back(std::move(tr)); + results.push_back({{"data", "awesome_data"}}); } return results; } @@ -490,18 +488,13 @@ public: return TableAttributes::CACHEABLE; } - TableRows generate(QueryContext& ctx) override + QueryData generate(QueryContext& ctx) override { - if (isCached(60, ctx)) { - return getCache(); - } - generates_++; - auto r = make_table_row(); + Row r; r["i"] = "1"; - TableRows result; + QueryData result; result.push_back(std::move(r)); - setCache(60, 1, ctx, result); return result; } @@ -574,15 +567,15 @@ private: } public: - TableRows generate(QueryContext& context) override + QueryData generate(QueryContext& context) override { - TableRows results; + QueryData results; // To test, we'll move all predicate constraints into the result set. // First we'll move constrains for the column `i` using operands =, LIKE. auto i = context.constraints["i"].getAll(EQUALS); for (const auto& constraint : i) { - auto r = make_table_row(); + Row r; r["i"] = constraint; r["op"] = "EQUALS"; results.push_back(std::move(r)); @@ -590,7 +583,7 @@ public: i = context.constraints["i"].getAll(LIKE); for (const auto& constraint : i) { - auto r = make_table_row(); + Row r; r["i"] = constraint; r["op"] = "LIKE"; results.push_back(std::move(r)); @@ -685,20 +678,20 @@ private: } public: - TableRows generate(QueryContext& context) override + QueryData generate(QueryContext& context) override { scans++; - TableRows results; + QueryData results; auto indexes = context.constraints["i"].getAll(EQUALS); for (const auto& i : indexes) { - results.push_back(make_table_row( - {{"i", INTEGER(i)}, {"j", INTEGER(i * 10)}, {"text", "none"}})); + results.push_back( + {{"i", INTEGER(i)}, {"j", INTEGER(i * 10)}, {"text", "none"}}); } if (indexes.empty()) { for (size_t i = 0; i < 100; i++) { - results.push_back(make_table_row( - {{"i", INTEGER(i)}, {"j", INTEGER(i * 10)}, {"text", "some"}})); + results.push_back( + {{"i", INTEGER(i)}, {"j", INTEGER(i * 10)}, {"text", "some"}}); } } return results; @@ -719,19 +712,19 @@ private: } public: - TableRows generate(QueryContext& context) override + QueryData generate(QueryContext& context) override { scans++; - TableRows results; + QueryData results; auto indexes = context.constraints["j"].getAll(EQUALS); for (const auto& j : indexes) { - results.push_back(make_table_row({{"j", INTEGER(j)}, {"text", "none"}})); + results.push_back({{"j", INTEGER(j)}, {"text", "none"}}); } if (indexes.empty()) { for (size_t j = 0; j < 100; j++) { results.push_back( - make_table_row({{"j", INTEGER(j)}, {"text", "some"}})); + {{"j", INTEGER(j)}, {"text", "some"}}); } } return results; @@ -752,13 +745,13 @@ private: } public: - TableRows generate(QueryContext& context) override + QueryData generate(QueryContext& context) override { scans++; - TableRows results; + QueryData results; for (size_t i = 0; i < 10; i++) { - results.push_back(make_table_row({{"i", INTEGER(i)}, {"text", "some"}})); + results.push_back({{"i", INTEGER(i)}, {"text", "some"}}); } return results; } @@ -786,9 +779,9 @@ private: } public: - TableRows generate(QueryContext& context) override + QueryData generate(QueryContext& context) override { - auto r = make_table_row(); + Row r; if (context.isColumnUsed("col1")) { r["col1"] = "value1"; } @@ -798,7 +791,7 @@ public: if (context.isColumnUsed("col3")) { r["col3"] = "value3"; } - TableRows result; + QueryData result; result.push_back(std::move(r)); return result; } @@ -868,10 +861,10 @@ private: } public: - TableRows generate(QueryContext& context) override + QueryData generate(QueryContext& context) override { - TableRows results; - auto r = make_table_row(); + QueryData results; + Row r; if (context.isAnyColumnUsed(UsedColumnsBitset(0x1))) { r["col1"] = "value1"; } diff --git a/src/osquery/sql/virtual_table.cpp b/src/osquery/sql/virtual_table.cpp index 9221842..511d2d7 100644 --- a/src/osquery/sql/virtual_table.cpp +++ b/src/osquery/sql/virtual_table.cpp @@ -923,7 +923,7 @@ static int xFilter(sqlite3_vtab_cursor* pVtabCursor, if (Registry::get().exists("table", pVtab->content->name, true)) { auto plugin = Registry::get().plugin("table", pVtab->content->name); auto table = std::dynamic_pointer_cast(plugin); - pCur->rows = table->generate(context); + pCur->rows = tableRowsFromQueryData(table->generate(context)); } else { PluginRequest request = {{"action", "generate"}}; TablePlugin::setRequestFromContext(context, request); diff --git a/src/vist/table/CMakeLists.txt b/src/vist/table/CMakeLists.txt index aefd1ef..e17acc0 100644 --- a/src/vist/table/CMakeLists.txt +++ b/src/vist/table/CMakeLists.txt @@ -13,7 +13,8 @@ # limitations under the License ## static virtual table -ADD_VIST_LIBRARY(vist_table policy/policy-admin.cpp +ADD_VIST_LIBRARY(vist_table util.cpp + policy/policy-admin.cpp policy/policy.cpp) ## dynamic virtual table diff --git a/src/vist/table/builder.hpp b/src/vist/table/builder.hpp new file mode 100644 index 0000000..f3e70a8 --- /dev/null +++ b/src/vist/table/builder.hpp @@ -0,0 +1,59 @@ +/* + * 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 + */ + +#pragma once + +#include + +#include +#include +#include +#include + +#include +#include +#include + +using namespace osquery; + +namespace vist { +namespace table { + +template struct dependent_false : std::false_type {}; + +struct Builder { + template + static void table(const std::string& name) + { + // Register virtual table to sqlite3 + auto tables = RegistryFactory::get().registry("table"); + tables->add(name, std::make_shared()); + } + + template + static std::tuple column(const std::string& name) + { + if constexpr(std::is_same_v) + return std::tuple(name, INTEGER_TYPE, ColumnOptions::DEFAULT); + else if constexpr(std::is_same_v) + return std::tuple(name, TEXT_TYPE, ColumnOptions::DEFAULT); + else + static_assert(dependent_false::value, "Not supported column type."); + } +}; + +} // namespace table +} // namespace vist diff --git a/src/vist/table/dynamic-table.hpp b/src/vist/table/dynamic-table.hpp index 7b82781..dbe6d1e 100644 --- a/src/vist/table/dynamic-table.hpp +++ b/src/vist/table/dynamic-table.hpp @@ -14,10 +14,8 @@ * limitations under the License */ -#include +#pragma once -#include -#include #include using namespace osquery; @@ -30,14 +28,6 @@ public: using FactoryType = DynamicTable* (*)(); virtual void init() = 0; - - template - static void Register(const std::string& name, std::shared_ptr&& table) - { - // Register virtual table to sqlite3 - auto tables = RegistryFactory::get().registry("table"); - tables->add(name, std::move(table)); - } }; } // namespace table diff --git a/src/vist/table/parser.hpp b/src/vist/table/parser.hpp new file mode 100644 index 0000000..0c8f08f --- /dev/null +++ b/src/vist/table/parser.hpp @@ -0,0 +1,48 @@ +/* + * 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 + */ + +#pragma once + +#include +#include + +#include + +using namespace osquery; + +namespace vist { +namespace table { + +struct Parser { + + template + static auto column(const PluginRequest& request, std::size_t index) -> T + { + if (request.count("json_values") == 0) + THROW(ErrCode::LogicError) << "Wrong request format. Not found json value."; + + json::Json document = json::Json::Parse(request.at("json_values")); + json::Array values = document.get("values"); + if (values.size() < index) + THROW(ErrCode::LogicError) << "Wrong index."; + + return static_cast(values.at(index)); + } + +}; + +} // namespace table +} // namespace vist diff --git a/src/vist/table/policy/bluetooth/table.cpp b/src/vist/table/policy/bluetooth/table.cpp index 4af0a16..ade0c1a 100644 --- a/src/vist/table/policy/bluetooth/table.cpp +++ b/src/vist/table/policy/bluetooth/table.cpp @@ -18,9 +18,11 @@ #include "table.hpp" #include -#include #include #include +#include +#include +#include extern "C" vist::table::DynamicTable* DynamicTableFactory() { @@ -48,7 +50,7 @@ void setPolicy(const std::string& name, int value) void BluetoothTable::init() { - DynamicTable::Register("bluetooth", std::make_shared()); + Builder::table("bluetooth"); auto provider = std::make_shared("bluetooth"); provider->add(std::make_shared()); @@ -64,15 +66,17 @@ void BluetoothTable::init() 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), + Builder::column("state"), + Builder::column("desktopConnectivity"), + Builder::column("pairing"), + Builder::column("tethering") }; } -TableRows BluetoothTable::generate(QueryContext&) try +QueryData BluetoothTable::generate(QueryContext&) { + TABLE_EXCEPTION_GUARD_START + INFO(VIST) << "Select query about bluetooth table."; Row row; @@ -84,50 +88,26 @@ TableRows BluetoothTable::generate(QueryContext&) try 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 }); + return results; + + TABLE_EXCEPTION_GUARD_END } -QueryData BluetoothTable::update(QueryContext&, const PluginRequest& request) try +QueryData BluetoothTable::update(QueryContext&, const PluginRequest& request) { - INFO(VIST) << "Update query about bluetooth table."; - if (request.count("json_values") == 0) - throw std::runtime_error("Wrong request format. Not found json value."); + TABLE_EXCEPTION_GUARD_START - 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."); + INFO(VIST) << "Update query about bluetooth table."; /// 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 }; + setPolicy("bluetooth", Parser::column(request, 0)); + setPolicy("bluetooth-desktop-connectivity", Parser::column(request, 1)); + setPolicy("bluetooth-pairing", Parser::column(request, 2)); + setPolicy("bluetooth-tethering", Parser::column(request, 3)); + + return success(); + + TABLE_EXCEPTION_GUARD_END } } // namespace table diff --git a/src/vist/table/policy/bluetooth/table.hpp b/src/vist/table/policy/bluetooth/table.hpp index 67996b0..5695f14 100644 --- a/src/vist/table/policy/bluetooth/table.hpp +++ b/src/vist/table/policy/bluetooth/table.hpp @@ -31,7 +31,7 @@ public: private: TableColumns columns() const override; - TableRows generate(QueryContext&) override; + QueryData generate(QueryContext&) override; QueryData update(QueryContext&, const PluginRequest& request) override; }; diff --git a/src/vist/table/policy/policy-admin.cpp b/src/vist/table/policy/policy-admin.cpp index 9edc0d0..3f7b705 100644 --- a/src/vist/table/policy/policy-admin.cpp +++ b/src/vist/table/policy/policy-admin.cpp @@ -17,62 +17,47 @@ #include "policy-admin.hpp" #include -#include #include #include - -#include -#include - -#include -#include -#include +#include +#include +#include namespace vist { namespace table { namespace { -std::string getValue(std::string&& alias, const std::string& key) +std::string removeAlias(std::string&& alias) { auto pos = alias.find(";"); auto token = alias.substr(0, pos); - if (token == key) + if (token == "name") 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()); + Builder::table("policy_admin"); } TableColumns PolicyAdminTable::columns() const { return { - std::make_tuple("name", TEXT_TYPE, ColumnOptions::DEFAULT), - std::make_tuple("activated", INTEGER_TYPE, ColumnOptions::DEFAULT), + Builder::column("name"), + Builder::column("activated"), }; } -TableRows PolicyAdminTable::generate(QueryContext& context) try +QueryData PolicyAdminTable::generate(QueryContext& context) { + TABLE_EXCEPTION_GUARD_START + INFO(VIST) << "Select query about policy-admin table."; QueryData results; @@ -104,101 +89,55 @@ TableRows PolicyAdminTable::generate(QueryContext& context) try } } - 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 }); + return results; + + TABLE_EXCEPTION_GUARD_END } -QueryData PolicyAdminTable::insert(QueryContext&, const PluginRequest& request) try +QueryData PolicyAdminTable::insert(QueryContext&, const PluginRequest& request) { + TABLE_EXCEPTION_GUARD_START + 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."); + auto admin = Parser::column(request, 0); - 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 }; + return success(); + + TABLE_EXCEPTION_GUARD_END } -QueryData PolicyAdminTable::delete_(QueryContext&, const PluginRequest& request) try +QueryData PolicyAdminTable::delete_(QueryContext&, const PluginRequest& request) { + TABLE_EXCEPTION_GUARD_START + 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."); + auto admin = removeAlias(Parser::column(request, 0)); - 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 }; + return success(); + + TABLE_EXCEPTION_GUARD_END } -QueryData PolicyAdminTable::update(QueryContext&, const PluginRequest& request) try +QueryData PolicyAdminTable::update(QueryContext&, const PluginRequest& request) { - 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."); + TABLE_EXCEPTION_GUARD_START - 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."); + INFO(VIST) << "Update query about policy-admin table."; - std::string name = static_cast(values.at(0)); - int activated = static_cast(values.at(1)); + auto name = Parser::column(request, 0); + auto activated = Parser::column(request, 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 }; + return success(); + + TABLE_EXCEPTION_GUARD_END } } // namespace tables diff --git a/src/vist/table/policy/policy-admin.hpp b/src/vist/table/policy/policy-admin.hpp index d8a8a7e..ff701e5 100644 --- a/src/vist/table/policy/policy-admin.hpp +++ b/src/vist/table/policy/policy-admin.hpp @@ -27,7 +27,7 @@ public: private: TableColumns columns() const override; - TableRows generate(QueryContext&) override; + QueryData generate(QueryContext&) override; QueryData delete_(QueryContext&, const PluginRequest& request) override; QueryData insert(QueryContext&, const PluginRequest& request) override; QueryData update(QueryContext&, const PluginRequest& request) override; diff --git a/src/vist/table/policy/policy.cpp b/src/vist/table/policy/policy.cpp index ca0060b..849bb09 100644 --- a/src/vist/table/policy/policy.cpp +++ b/src/vist/table/policy/policy.cpp @@ -17,12 +17,11 @@ #include "policy.hpp" #include -#include #include #include - -#include -#include +#include +#include +#include #include #include @@ -46,20 +45,21 @@ Row convert(const std::string& name, const vist::policy::PolicyValue& value) void PolicyTable::Init() { - auto tables = RegistryFactory::get().registry("table"); - tables->add("policy", std::make_shared()); + Builder::table("policy"); } TableColumns PolicyTable::columns() const { return { - std::make_tuple("name", TEXT_TYPE, ColumnOptions::DEFAULT), - std::make_tuple("value", TEXT_TYPE, ColumnOptions::DEFAULT), + Builder::column("name"), + Builder::column("value") }; } -TableRows PolicyTable::generate(QueryContext& context) try +QueryData PolicyTable::generate(QueryContext& context) { + TABLE_EXCEPTION_GUARD_START + INFO(VIST) << "Select query about policy table."; QueryData results; @@ -80,49 +80,25 @@ TableRows PolicyTable::generate(QueryContext& context) try } } - 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 }); + return results; + + TABLE_EXCEPTION_GUARD_END } -QueryData PolicyTable::update(QueryContext&, const PluginRequest& request) try +QueryData PolicyTable::update(QueryContext&, const PluginRequest& request) { - INFO(VIST) << "Update query about policy table."; - if (request.count("json_values") == 0) - throw std::runtime_error("Wrong request format. Not found json value."); + TABLE_EXCEPTION_GUARD_START - 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."); + INFO(VIST) << "Update query about policy table."; - std::string name = static_cast(values.at(0)); - std::string dumpedValue = static_cast(values.at(1)); + auto name = Parser::column(request, 0); + auto dumpedValue = Parser::column(request, 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 }; + return success(); + + TABLE_EXCEPTION_GUARD_END } } // namespace table diff --git a/src/vist/table/policy/policy.hpp b/src/vist/table/policy/policy.hpp index f96c473..5ef6f71 100644 --- a/src/vist/table/policy/policy.hpp +++ b/src/vist/table/policy/policy.hpp @@ -27,7 +27,7 @@ public: private: TableColumns columns() const override; - TableRows generate(QueryContext&) override; + QueryData generate(QueryContext&) override; QueryData update(QueryContext&, const PluginRequest& request) override; }; diff --git a/src/vist/table/policy/sample/table.cpp b/src/vist/table/policy/sample/table.cpp index 3fc8019..487d9f9 100644 --- a/src/vist/table/policy/sample/table.cpp +++ b/src/vist/table/policy/sample/table.cpp @@ -18,9 +18,11 @@ #include "table.hpp" #include -#include #include #include +#include +#include +#include extern "C" vist::table::DynamicTable* DynamicTableFactory() { @@ -32,7 +34,7 @@ namespace table { void SamplePolicyTable::init() { - DynamicTable::Register("sample_policy", std::make_shared()); + Builder::table("sample_policy"); // Register policy to policy-manager using namespace policy; @@ -48,13 +50,15 @@ void SamplePolicyTable::init() 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), + Builder::column("sample_int_policy"), + Builder::column("sample_str_policy") }; } -TableRows SamplePolicyTable::generate(QueryContext&) try +QueryData SamplePolicyTable::generate(QueryContext&) { + TABLE_EXCEPTION_GUARD_START + INFO(VIST) << "Select query about sample-policy table."; Row row; @@ -67,49 +71,26 @@ TableRows SamplePolicyTable::generate(QueryContext&) try 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 }); + return results; + + TABLE_EXCEPTION_GUARD_END } -QueryData SamplePolicyTable::update(QueryContext&, const PluginRequest& request) try +QueryData SamplePolicyTable::update(QueryContext&, const PluginRequest& request) { + TABLE_EXCEPTION_GUARD_START + 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 }; + + auto intPolicy = Parser::column(request, 0); + auto strPolicy = Parser::column(request, 1); + + policy::API::Admin::Set("sample_int_policy", policy::PolicyValue(intPolicy)); + policy::API::Admin::Set("sample_str_policy", policy::PolicyValue(strPolicy)); + + return success(); + + TABLE_EXCEPTION_GUARD_END } } // namespace table diff --git a/src/vist/table/policy/sample/table.hpp b/src/vist/table/policy/sample/table.hpp index ff80992..1934e9b 100644 --- a/src/vist/table/policy/sample/table.hpp +++ b/src/vist/table/policy/sample/table.hpp @@ -32,7 +32,7 @@ public: private: TableColumns columns() const override; - TableRows generate(QueryContext&) override; + QueryData generate(QueryContext&) override; QueryData update(QueryContext&, const PluginRequest& request) override; }; diff --git a/src/vist/table/util.cpp b/src/vist/table/util.cpp new file mode 100644 index 0000000..aa6ebdb --- /dev/null +++ b/src/vist/table/util.cpp @@ -0,0 +1,47 @@ +/* + * 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 "util.hpp" + +#include + +namespace vist { +namespace table { + +QueryData exception_guard(const std::function& func) try +{ + return func(); +} catch (const vist::Exception& e) +{ + ERROR(VIST) << "Failed while excuting query: " << e.what(); + Row r; + return { r }; +} catch (...) +{ + ERROR(VIST) << "Failed to query with unknown exception."; + Row r; + return { r }; +} + +QueryData success() +{ + Row r; + r["status"] = "success"; + return QueryData { r }; +} + +} // namespace table +} // namespace vist diff --git a/src/vist/table/util.hpp b/src/vist/table/util.hpp new file mode 100644 index 0000000..a221e7c --- /dev/null +++ b/src/vist/table/util.hpp @@ -0,0 +1,38 @@ +/* + * 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 + */ + +#pragma once + +#include + +#include + +#include + +using namespace osquery; + +#define TABLE_EXCEPTION_GUARD_START return vist::table::exception_guard([&]() { +#define TABLE_EXCEPTION_GUARD_END }); + +namespace vist { +namespace table { + +QueryData exception_guard(const std::function&); + +QueryData success(); + +} // namespace table +} // namespace vist -- 2.34.1