From: Sangwan Kwon Date: Fri, 11 Oct 2019 07:59:03 +0000 (+0900) Subject: Support update feature with policyd X-Git-Tag: submit/tizen/20200810.073515~186 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=342bfe17dd390c2e3e4aa8936caeddab5feb0a83;p=platform%2Fcore%2Fsecurity%2Fvist.git Support update feature with policyd Example: UPDATE policy SET value = '3' WHERE name = 'bluetooth' Signed-off-by: Sangwan Kwon --- diff --git a/specs/tizen/policy.table b/specs/tizen/policy.table index cb22e61..b51be81 100644 --- a/specs/tizen/policy.table +++ b/specs/tizen/policy.table @@ -5,6 +5,8 @@ schema([ Column("value", TEXT, "Policy value"), ]) implementation("tizen/policy@genPolicy") +implementation_update("tizen/policy@updatePolicy") examples([ "select * from policy where name = 'bluetooth'", + "update policy set value = 1 where name = 'bluetooth'", ]) diff --git a/src/apix/manager/tests/manager_tests.cpp b/src/apix/manager/tests/manager_tests.cpp index 1a4ff23..b1b266e 100644 --- a/src/apix/manager/tests/manager_tests.cpp +++ b/src/apix/manager/tests/manager_tests.cpp @@ -21,6 +21,8 @@ #include #include +#include + using namespace osquery; class ManagerTests : public testing::Test {}; @@ -59,6 +61,27 @@ TEST_F(ManagerTests, test_manager_execute_policy) { EXPECT_EQ(rows.size(), 1); } +TEST_F(ManagerTests, test_manager_execute_policy_update) { + auto& manager = policyd::PolicyManager::Instance(); + manager.enroll("admin", 0); + + std::string query = "SELECT * FROM policy WHERE name = 'bluetooth'"; + auto rows = OsqueryManager::execute(query); + /// Initial policy value + EXPECT_EQ(rows[0]["value"], std::to_string(1)); + + query = "UPDATE policy SET value = '3' WHERE name = 'bluetooth'"; + rows = OsqueryManager::execute(query); + EXPECT_EQ(rows.size(), 0); + + query = "SELECT * FROM policy WHERE name = 'bluetooth'"; + rows = OsqueryManager::execute(query); + /// Initial policy value + EXPECT_EQ(rows[0]["value"], std::to_string(3)); + + manager.disenroll("admin", 0); +} + TEST_F(ManagerTests, test_manager_subscribe) { int called = 0; auto callback = [&](const Row& row) { diff --git a/src/osquery/CMakeLists.txt b/src/osquery/CMakeLists.txt index fdee170..660bf29 100644 --- a/src/osquery/CMakeLists.txt +++ b/src/osquery/CMakeLists.txt @@ -65,8 +65,13 @@ ADD_LIBRARY(${TARGET_OSQUERY_LIB} STATIC $ $ ${${TARGET_OSQUERY_LIB}_SRCS}) -TARGET_LINK_LIBRARIES(${TARGET_OSQUERY_LIB} ${${TARGET_OSQUERY_LIB}_DEPS} - ${TARGET_POLICYD_LIB}) + +TARGET_LINK_LIBRARIES(${TARGET_OSQUERY_LIB} ${${TARGET_OSQUERY_LIB}_DEPS}) + +IF(DEFINED GBS_BUILD) +TARGET_LINK_LIBRARIES(${TARGET_OSQUERY_LIB} ${TARGET_POLICYD_LIB}) +ENDIF(DEFINED GBS_BUILD) + SET_TARGET_PROPERTIES(${TARGET_OSQUERY_LIB} PROPERTIES OUTPUT_NAME ${TARGET_OSQUERY_LIB}) ADD_EXECUTABLE(${TARGET_OSQUERY_TEST} main/tests.cpp diff --git a/src/osquery/sql/virtual_table.cpp b/src/osquery/sql/virtual_table.cpp index 5198466..ee2d414 100644 --- a/src/osquery/sql/virtual_table.cpp +++ b/src/osquery/sql/virtual_table.cpp @@ -944,6 +944,7 @@ struct sqlite3_module* getVirtualTableModule(const std::string& table_name, sqlite_module_map[table_name].xEof = tables::sqlite::xEof; sqlite_module_map[table_name].xColumn = tables::sqlite::xColumn; sqlite_module_map[table_name].xRowid = tables::sqlite::xRowid; + sqlite_module_map[table_name].xUpdate = tables::sqlite::xUpdate; // Allow the table to receive INSERT/UPDATE/DROP events if it is // implemented from an extension and is overwriting the right methods diff --git a/src/osquery/tables/tizen/policy.cpp b/src/osquery/tables/tizen/policy.cpp index b355f7d..c6bd1d1 100644 --- a/src/osquery/tables/tizen/policy.cpp +++ b/src/osquery/tables/tizen/policy.cpp @@ -62,8 +62,34 @@ QueryData genPolicy(QueryContext& context) try { return results; } catch (...) { -// TODO(Sangwan): Resolve duplicated "ERROR" macro with DPM -// LOG(ERROR) << "Exception occured"; + Row r; + return { r }; +} + +QueryData updatePolicy(QueryContext& context, const PluginRequest& request) try { + if (request.count("json_value_array") == 0) + throw std::runtime_error("Wrong request format. Not found json value."); + + std::string str = request.at("json_value_array"); + rapidjson::Document document; + document.Parse(str.c_str()); + if (document.HasParseError() || !document.IsArray()) + throw std::runtime_error("Cannot parse request."); + + if (document.Size() != 2) + throw std::runtime_error("Wrong request format."); + + std::string name = document[0].GetString(); + int value = std::stoi(document[1].GetString()); + + /// TODO(Sangwan): Get admin name from policyd + auto& manager = PolicyManager::Instance(); + manager.set(name, PolicyValue(value), "admin"); + + Row r; + r["status"] = "success"; + return { r }; +} catch (...) { Row r; return { r }; } diff --git a/tools/codegen/gentable.py b/tools/codegen/gentable.py index e9f9995..12895d2 100755 --- a/tools/codegen/gentable.py +++ b/tools/codegen/gentable.py @@ -196,6 +196,7 @@ class TableState(Singleton): self.header = "" self.impl = "" self.function = "" + self.function_update = "" self.class_name = "" self.description = "" self.attributes = {} @@ -283,6 +284,7 @@ class TableState(Singleton): header=self.header, impl=self.impl, function=self.function, + function_update=self.function_update, class_name=self.class_name, attributes=self.attributes, examples=self.examples, @@ -440,6 +442,20 @@ def implementation(impl_string, generator=False): table.table_name, BIGINT))) sys.exit(1) +# patched +def implementation_update(impl_string, generator=False): + if impl_string is None: + table.function_update = "" + else: + filename, function_update = impl_string.split("@") + class_parts = function_update.split("::")[::-1] + function_update = class_parts[0] + class_name = class_parts[1] if len(class_parts) > 1 else "" + impl = "%s.cpp" % filename + table.impl = impl + table.function_update = function_update + table.class_name = class_name + table.generator = generator def main(): parser = argparse.ArgumentParser( diff --git a/tools/codegen/templates/default.cpp.in b/tools/codegen/templates/default.cpp.in index 1d3c7d6..61c26bb 100644 --- a/tools/codegen/templates/default.cpp.in +++ b/tools/codegen/templates/default.cpp.in @@ -24,9 +24,28 @@ namespace tables { void {{function}}(RowYield& yield, QueryContext& context); {% elif strongly_typed_rows %}\ osquery::TableRows {{function}}(QueryContext& context); + +/// patch start +{% if function_update != "" %}\ +osquery::QueryData {{function_update}}(QueryContext& context, + const PluginRequest& request); +/// patch end + +{% endif %}\ + {% else %}\ osquery::QueryData {{function}}(QueryContext& context); + +/// patch start +{% if function_update != "" %}\ +osquery::QueryData {{function_update}}(QueryContext& context, + const PluginRequest& request); +/// patch end + {% endif %}\ + +{% endif %}\ + {% else %} class {{class_name}} { public: @@ -127,6 +146,16 @@ class {{table_name_cc}}TablePlugin : public TablePlugin { {% endif %} return results; } + +/// patch start +{% if function_update != "" %}\ + QueryData update(QueryContext& context, + const PluginRequest& request) override { + return tables::{{function_update}}(context, request); + } +{% endif %}\ +/// patch end + {% endif %}\ };