SET(${TARGET_VIST_LIB}_SRCS ${${TARGET_VIST_LIB}_SRCS} PARENT_SCOPE)
ENDMACRO(ADD_VIST_LIBRARY)
+MACRO(ADD_VIST_CLIENT_LIBRARY TARGET)
+ ADD_LIBRARY(${TARGET} OBJECT ${ARGN})
+ LIST(APPEND ${TARGET_VIST_CLIENT_LIB}_SRCS $<TARGET_OBJECTS:${TARGET}>)
+ SET(${TARGET_VIST_LIB}_SRCS ${${TARGET_VIST_CLIENT_LIB}_SRCS} PARENT_SCOPE)
+ENDMACRO(ADD_VIST_CLIENT_LIBRARY)
+
MACRO(ADD_VIST_POLICY_LIBRARY TARGET)
ADD_LIBRARY(${TARGET} OBJECT ${ARGN})
LIST(APPEND ${TARGET_VIST_POLICY_LIB}_SRCS $<TARGET_OBJECTS:${TARGET}>)
-DUSER_NAME=%{user_name} \
-DGROUP_NAME=%{group_name} \
-DSMACK_LABEL=%{smack_label} \
+ -DDEFAULT_ADMIN_PATH=%{_bindir}/vist-cli \
-DDB_INSTALL_DIR:PATH=%{vist_db_dir} \
-DPLUGIN_INSTALL_DIR:PATH=%{vist_plugin_dir} \
-DSCRIPT_INSTALL_DIR:PATH=%{vist_script_dir}
%license LICENSE-Apache-2.0
%license LICENSE-GPL-2.0
%license LICENSE-MIT
+%{_bindir}/vist-cli
%{_bindir}/vistd
%{vist_script_dir}/*.sql
%dir %attr(-, %{user_name}, %{group_name}) %{vist_db_dir}
# limitations under the License
SET(TARGET_OSQUERY_LIB osquery)
-SET(TARGET_VIST_POLICY_LIB vist-policy)
+SET(TARGET_VIST_CLIENT_LIB vist-client)
SET(TARGET_VIST_LIB vist)
+SET(TARGET_VIST_POLICY_LIB vist-policy)
ADD_SUBDIRECTORY(osquery)
# See the License for the specific language governing permissions and
# limitations under the License
+SET(TARGET_VIST_CLI vist-cli)
SET(TARGET_VIST_DAEMON vistd)
SET(TARGET_VIST_TEST vist-test)
SET(${TARGET_VIST_LIB}_SRCS "")
SET(${TARGET_VIST_LIB}_TESTS "")
-SET(DEPENDENCY klay dlog)
+SET(DEPENDENCY klay dlog gflags)
PKG_CHECK_MODULES(VIST_DEPS REQUIRED ${DEPENDENCY})
INCLUDE_DIRECTORIES(SYSTEM . common ${VIST_DEPS_INCLUDE_DIRS})
ADD_DEFINITIONS(-DDB_PATH="${DB_INSTALL_DIR}/.vist.db"
+ -DDEFAULT_ADMIN_PATH="${DEFAULT_ADMIN_PATH}"
-DPLUGIN_INSTALL_DIR="${PLUGIN_INSTALL_DIR}"
-DSCRIPT_INSTALL_DIR="${SCRIPT_INSTALL_DIR}")
WORLD_READ
WORLD_EXECUTE)
+ADD_EXECUTABLE(${TARGET_VIST_CLI} main/cli.cpp)
+TARGET_LINK_LIBRARIES(${TARGET_VIST_CLI} ${TARGET_VIST_CLIENT_LIB})
+SET_TARGET_PROPERTIES(${TARGET_VIST_CLI} PROPERTIES COMPILE_FLAGS "-fPIE")
+SET_TARGET_PROPERTIES(${TARGET_VIST_CLI} PROPERTIES LINK_FLAGS "-pie")
+INSTALL(TARGETS ${TARGET_VIST_CLI}
+ DESTINATION ${CMAKE_INSTALL_BINDIR}
+ PERMISSIONS OWNER_READ
+ OWNER_WRITE
+ OWNER_EXECUTE
+ GROUP_READ
+ GROUP_EXECUTE
+ WORLD_READ
+ WORLD_EXECUTE)
+
FILE(GLOB COMMON_TESTS "tests/*.cpp")
ADD_VIST_TEST(${COMMON_TESTS})
# See the License for the specific language governing permissions and
# limitations under the License
-ADD_VIST_LIBRARY(vist_client query.cpp
- virtual-table.cpp)
+SET(${TARGET_VIST_CLIENT_LIB}_SRCS "")
+
+PKG_CHECK_MODULES(VIST_CLIENT_DEPS REQUIRED gflags klay dlog)
+
+INCLUDE_DIRECTORIES(SYSTEM . ${VIST_CLIENT_DEPS_INCLUDE_DIRS})
+
+ADD_VIST_CLIENT_LIBRARY(vist_client query.cpp
+ virtual-table.cpp)
FILE(GLOB CLIENT_TESTS "tests/*.cpp")
ADD_VIST_TEST(${CLIENT_TESTS})
+
+ADD_LIBRARY(${TARGET_VIST_CLIENT_LIB} STATIC ${${TARGET_VIST_CLIENT_LIB}_SRCS})
+TARGET_LINK_LIBRARIES(${TARGET_VIST_CLIENT_LIB} ${VIST_CLIENT_DEPS_LIBRARIES}
+ pthread)
}
TEST(ClientTests, admin_enrollment) {
- auto rows = Query::Execute("INSERT INTO policy_admin (name) VALUES ('testAdmin')");
+ /// Default policy admin is always exist.
+ auto rows = Query::Execute("SELECT * FROM policy_admin");
+ EXPECT_EQ(rows.size(), 1);
+
+ rows = Query::Execute("INSERT INTO policy_admin (name) VALUES ('testAdmin')");
EXPECT_EQ(rows.size(), 0);
rows = Query::Execute("SELECT * FROM policy_admin");
- EXPECT_EQ(rows.size(), 1);
+ EXPECT_EQ(rows.size(), 2);
Query::Execute("INSERT INTO policy_admin (name) VALUES ('testAdmin2')");
rows = Query::Execute("SELECT * FROM policy_admin");
- EXPECT_EQ(rows.size(), 2);
+ EXPECT_EQ(rows.size(), 3);
rows = Query::Execute("DELETE FROM policy_admin WHERE name = 'testAdmin'");
EXPECT_EQ(rows.size(), 0);
rows = Query::Execute("SELECT * FROM policy_admin");
- EXPECT_EQ(rows.size(), 1);
+ EXPECT_EQ(rows.size(), 2);
Query::Execute("DELETE FROM policy_admin WHERE name = 'testAdmin2'");
rows = Query::Execute("SELECT * FROM policy_admin");
- EXPECT_EQ(rows.size(), 0);
+ EXPECT_EQ(rows.size(), 1);
}
--- /dev/null
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+#include <vist/client/query.hpp>
+#include <vist/exception.hpp>
+
+#include <gflags/gflags.h>
+
+#include <cstdlib>
+#include <iostream>
+#include <string>
+
+using namespace vist;
+
+DEFINE_string(query, "", "Query statement to execute.");
+
+int main(int argc, char *argv[]) try {
+ gflags::SetUsageMessage("ViST default admin program.");
+ gflags::ParseCommandLineFlags(&argc, &argv, true);
+
+ if (!FLAGS_query.empty()) {
+ auto rows = Query::Execute(FLAGS_query);
+
+ std::cout << "Success to query." << std::endl;
+
+ for (const auto& row : rows) {
+ std::cout << "\tRow info >> ";
+ for (const auto& col : row)
+ std::cout << "Column[" << col.first << "] = " << col.second << ", ";
+ std::cout << std::endl;
+ }
+
+ std::cout << "Total " << rows.size() << "-rows." << std::endl;
+ }
+ return EXIT_SUCCESS;
+} catch(const Exception<ErrCode>& e) {
+ std::cout << "Failed message: " << e.what() << std::endl;
+ return EXIT_FAILURE;
+} catch(const std::exception& e) {
+ std::cout << "Failed message: " << e.what() << std::endl;
+ return EXIT_FAILURE;
+}
loadProviders(PLUGIN_INSTALL_DIR);
int cnt = loadPolicies();
INFO(VIST) << std::to_string(cnt) << "-policies loaded";
+
+ this->storage.enroll(DEFAULT_ADMIN_PATH);
}
std::pair<int, int> PolicyManager::loadProviders(const std::string& path)
this->definitions.emplace(pd.name, std::move(pd));
}
- DEBUG(VIST) << definitions.size() << "- policies synced.";
+ DEBUG(VIST) << definitions.size() << "-policies synced.";
}
void PolicyStorage::syncAdmin()
this->activatedPolicies.emplace(pa.policy, std::move(pa));
}
- DEBUG(VIST) << activatedPolicies.size() << "- activated-policies synced.";
+ DEBUG(VIST) << activatedPolicies.size() << "-activated-policies synced.";
}
std::string PolicyStorage::getScript(const std::string& name)
}
std::string query = adminTable.insert(&Admin::name);
- DEBUG(VIST) << "Enroll admin query statement: " << query;
database::Statement stmt(*database, query);
stmt.bind(1, name);
if (!stmt.exec())
void PolicyStorage::disenroll(const std::string& name)
{
+ if (name == DEFAULT_ADMIN_PATH)
+ THROW(ErrCode::RuntimeError) << "Cannot disenroll default admin.";
+
INFO(VIST) << "Disenroll admin: " << name;
auto iter = std::find(admins.begin(), admins.end(), name);
if (iter == admins.end()) {
int policyValue = value;
std::string query = polActivatedTable.update(&PolicyActivated::value)
- .where(expr(&PolicyActivated::admin) == admin &&
- expr(&PolicyActivated::policy) == policy);
+ .where(expr(&PolicyActivated::admin) == admin &&
+ expr(&PolicyActivated::policy) == policy);
database::Statement stmt(*database, query);
stmt.bind(1, policyValue);
stmt.bind(2, admin);
syncPolicyActivated();
}
+/// TODO(sangwan.kwon) Re-design strictest logic
PolicyValue PolicyStorage::strictest(const std::string& policy)
{
if (definitions.find(policy) == definitions.end())
std::shared_ptr<PolicyValue> strictestPtr = nullptr;
auto range = activatedPolicies.equal_range(policy);
for (auto iter = range.first; iter != range.second; iter++) {
+ DEBUG(VIST) << "Admin: " << iter->second.admin << ", "
+ << "Policy: " << iter->second.policy << ", "
+ << "Value: " << std::to_string(iter->second.value);
+
int value = iter->second.value;
if (strictestPtr == nullptr)
strictestPtr = std::make_shared<PolicyValue>(value);
else
- strictestPtr->value = (*strictestPtr < value) ? strictestPtr->value : value;
-
- DEBUG(VIST) << "The strictest of policy[" << policy
- << "] : " + std::to_string(strictestPtr->value);
+ strictestPtr->value = (strictestPtr->value > value) ? strictestPtr->value : value;
}
if (strictestPtr == nullptr)
THROW(ErrCode::RuntimeError) << "Not exist managed policy: " << policy;
+ DEBUG(VIST) << "The strictest value of [" << policy
+ << "] is " << std::to_string(strictestPtr->value);
+
return std::move(*strictestPtr);
}
/// DB Cache objects
/// TODO(Sangwan): add locking mechanism
std::vector<std::string> admins;
- std::unordered_map<std::string, PolicyActivated> activatedPolicies;
+ std::unordered_multimap<std::string, PolicyActivated> activatedPolicies;
std::unordered_map<std::string, PolicyDefinition> definitions;
};
/// Manager should return the strongest policy.
policy = manager.get("bluetooth");
- EXPECT_EQ(policy.value, 5);
+ EXPECT_EQ(policy.value, 10);
manager.disenroll("testAdmin");
manager.disenroll("testAdmin1");
try {
// DB is maden at run-time
PolicyStorage storage("/tmp/dummy");
- } catch (const std::exception&) {
+ } catch (const std::exception& e) {
isRaised = true;
}
TEST_F(PolicyStorageTests, enrollment)
{
auto storage = getStorage();
- EXPECT_FALSE(storage->isActivated());
+ /// Since default admin exists, storage is always activated.
+ EXPECT_TRUE(storage->isActivated());
storage->enroll("testAdmin0");
storage->enroll("testAdmin1");
EXPECT_TRUE(storage->isActivated());
storage->disenroll("testAdmin1");
- EXPECT_FALSE(storage->isActivated());
+ EXPECT_TRUE(storage->isActivated());
}
TEST_F(PolicyStorageTests, update)
EXPECT_TRUE(isRaised);
auto policy = storage->strictest("bluetooth");
- EXPECT_EQ(policy.value, 3);
+ EXPECT_EQ(policy.value, 6);
storage->disenroll("testAdmin0");
storage->disenroll("testAdmin1");
auto storage = getStorage();
auto admins = storage->getAdmins();
- EXPECT_EQ(admins.size(), 0);
+ EXPECT_EQ(admins.size(), 1);
storage->enroll("testAdmin1");
admins = storage->getAdmins();
- EXPECT_EQ(admins.size(), 1);
+ EXPECT_EQ(admins.size(), 2);
storage->enroll("testAdmin2");
admins = storage->getAdmins();
- EXPECT_EQ(admins.size(), 2);
+ EXPECT_EQ(admins.size(), 3);
storage->disenroll("testAdmin2");
admins = storage->getAdmins();
- EXPECT_EQ(admins.size(), 1);
+ EXPECT_EQ(admins.size(), 2);
storage->disenroll("testAdmin1");
admins = storage->getAdmins();
- EXPECT_EQ(admins.size(), 0);
+ EXPECT_EQ(admins.size(), 1);
+}
+
+TEST_F(PolicyStorageTests, default_admin)
+{
+ auto storage = getStorage();
+ bool isRaised = false;
+
+ /// Cannot disenroll default admin
+ try {
+ storage->disenroll(DEFAULT_ADMIN_PATH);
+ } catch (const std::exception& e) {
+ isRaised = true;
+ }
+
+ EXPECT_TRUE(isRaised);
}