Fix policy-storage to save stringfied value
authorSangwan Kwon <sangwan.kwon@samsung.com>
Wed, 20 Nov 2019 10:47:10 +0000 (19:47 +0900)
committer권상완/Security 2Lab(SR)/Engineer/삼성전자 <sangwan.kwon@samsung.com>
Fri, 22 Nov 2019 01:52:17 +0000 (10:52 +0900)
If policy type is int, policy storage save the value as 'I/value'.
If policy type is string, policy storage save the value as 'S/value'.

Signed-off-by: Sangwan Kwon <sangwan.kwon@samsung.com>
data/script/create-schema.sql
src/vist/policy/db-schema.hpp
src/vist/policy/policy-manager.cpp
src/vist/policy/policy-storage.cpp
src/vist/policy/policy-storage.hpp
src/vist/sdk/policy-value.hpp

index 2f2f6ef156c60e9a51cb9b91e84a31b28339950b..010eaff6d342664b3b6751e59b2181c73321df3a 100644 (file)
@@ -22,7 +22,7 @@ CREATE TABLE IF NOT EXISTS ADMIN (
 
 CREATE TABLE IF NOT EXISTS POLICY_DEFINITION (
        name TEXT NOT NULL,
-       ivalue INTEGER NOT NULL,
+       ivalue TEXT NOT NULL,
 
        PRIMARY KEY(name)
 );
@@ -30,7 +30,7 @@ CREATE TABLE IF NOT EXISTS POLICY_DEFINITION (
 CREATE TABLE IF NOT EXISTS POLICY_ACTIVATED (
        admin TEXT NOT NULL,
        policy TEXT NOT NULL,
-       value INTEGER NOT NULL,
+       value TEXT NOT NULL,
 
        PRIMARY KEY(admin, policy),
        FOREIGN KEY(admin) REFERENCES ADMIN(name),
index 2bdf75b779997486375f665d3be7e6b1870e40c7..2ae1eaf3ee6010d33c649a13e0afc00ff667a953 100644 (file)
@@ -29,12 +29,12 @@ struct Admin {
 struct PolicyActivated {
        std::string admin;
        std::string policy;
-       int value = -1;
+       std::string value;
 };
 
 struct PolicyDefinition {
        std::string name;
-       int ivalue = -1;
+       std::string ivalue;
 };
 
 } // namespace schema
index 5c6670159ae97d4377d186c846ab609a99b5c072..8743388537b6fa6e9a2b0a71dd7081efbd5bc6b0 100644 (file)
@@ -76,27 +76,20 @@ std::pair<int, int> PolicyManager::loadProviders(const std::string& path)
 
 int PolicyManager::loadPolicies()
 {
-       bool changed = false;
-
        /// Make policy-provider map for performance
        for (const auto& provider : providers) {
                for (const auto& pair : provider->policies) {
-                       policies[pair.first] = provider->getName();
+                       std::string policy = pair.first;
+                       this->policies[policy] = provider->getName();
 
                        /// Check the policy is defined on policy-storage
                        if (!storage.exists(pair.first)) {
-                               INFO(VIST) << "Define policy: " << pair.first;
-                               int value = pair.second->getInitial();
-                               storage.define(pair.first, value);
-                               changed = true;
+                               storage.define(pair.first, pair.second->getInitial());
                        }
                }
        }
 
-       if (changed)
-               storage.syncPolicyDefinition();
-
-       return policies.size();
+       return this->policies.size();
 }
 
 void PolicyManager::enroll(const std::string& admin)
@@ -114,14 +107,15 @@ void PolicyManager::set(const std::string& policy,
                                                const std::string& admin)
 {
        if (this->policies.find(policy) == this->policies.end())
-               std::runtime_error("Not exist policy: " + policy);
+               THROW(ErrCode::RuntimeError) << "Not exist policy: " << policy;
 
-       storage.update(admin, policy, value);
+       this->storage.update(admin, policy, value);
 
        for (auto& p : providers) {
                if (p->getName() != this->policies[policy])
                        continue;
 
+               /// dispatch callback written by provider
                if (p->policies.find(policy) != p->policies.end()) {
                        p->policies[policy]->set(value);
                        return;
@@ -131,6 +125,9 @@ void PolicyManager::set(const std::string& policy,
 
 PolicyValue PolicyManager::get(const std::string& policy)
 {
+       if (this->policies.find(policy) == this->policies.end())
+               THROW(ErrCode::RuntimeError) << "Not exist policy: " << policy;
+
        return storage.strictest(policy);
 }
 
index 22fb7f34b84e5dc8e7ba442c8fb39f4250490edc..ad32e5a12c7d86630cd82f9f5c8e6c32043da2e9 100644 (file)
@@ -79,7 +79,7 @@ void PolicyStorage::syncPolicyDefinition()
        while (stmt.step()) {
                PolicyDefinition pd;
                pd.name = std::string(stmt.getColumn(0));
-               pd.ivalue = stmt.getColumn(1);
+               pd.ivalue = std::string(stmt.getColumn(1));
                DEBUG(VIST) << "Defined policy:" << pd.name;
                this->definitions.emplace(pd.name, std::move(pd));
        }
@@ -109,7 +109,7 @@ void PolicyStorage::syncPolicyActivated()
                PolicyActivated pa;
                pa.admin = std::string(stmt.getColumn(0));
                pa.policy = std::string(stmt.getColumn(1));
-               pa.value = stmt.getColumn(2);
+               pa.value = std::string(stmt.getColumn(2));
                this->activatedPolicies.emplace(pa.policy, std::move(pa));
        }
 
@@ -121,26 +121,26 @@ std::string PolicyStorage::getScript(const std::string& name)
        std::string path = SCRIPT_BASE + "/" + name + ".sql";
        std::ifstream is(path);
        if (is.fail())
-               THROW(ErrCode::LogicError) << "Failed to open script: " << path; 
+               THROW(ErrCode::LogicError) << "Failed to open script: " << path;
 
        std::istreambuf_iterator<char> begin(is), end;
        auto content = std::string(begin, end);
        if (content.empty())
-               THROW(ErrCode::LogicError) << "Failed to read script: " << path; 
+               THROW(ErrCode::LogicError) << "Failed to read script: " << path;
 
        return content;
 }
 
-void PolicyStorage::define(const std::string& policy, int ivalue)
+void PolicyStorage::define(const std::string& policy, const PolicyValue& ivalue)
 {
-       if (definitions.find(policy) != definitions.end()) {
+       if (this->definitions.find(policy) != this->definitions.end()) {
                INFO(VIST) << "Policy is already defined: " << policy;
                return;
        }
 
        PolicyDefinition pd;
        pd.name = policy;
-       pd.ivalue = ivalue;
+       pd.ivalue = ivalue.dump();
 
        std::string query = polDefinitionTable.insert(&PolicyDefinition::name,
                                                                                                  &PolicyDefinition::ivalue);
@@ -149,6 +149,9 @@ void PolicyStorage::define(const std::string& policy, int ivalue)
        stmt.bind(2, pd.ivalue);
        if (!stmt.exec())
                THROW(ErrCode::RuntimeError) << "Failed to define policy: " << pd.name;
+
+       INFO(VIST) << "Policy defined >> name: " << pd.name << ", ivalue" << pd.ivalue;
+       this->definitions.emplace(pd.name, std::move(pd));
 }
 
 void PolicyStorage::enroll(const std::string& name)
@@ -199,53 +202,55 @@ void PolicyStorage::update(const std::string& admin,
                                                   const std::string& policy,
                                                   const PolicyValue& value)
 {
-       int policyValue = value;
        DEBUG(VIST) << "Policy-update is called by admin: " << admin
-                               << ", about: " << policy << ", value: " << policyValue;
+                               << ", about: " << policy << ", value: " << value.dump();
 
-       if (std::find(admins.begin(), admins.end(), admin) == admins.end())
+       if (std::find(this->admins.begin(), this->admins.end(), admin) == this->admins.end())
                THROW(ErrCode::LogicError) << "Not exist admin: " << admin;
 
-       if (definitions.find(policy) == definitions.end())
+       if (this->definitions.find(policy) == this->definitions.end())
                THROW(ErrCode::LogicError) << "Not exist policy: " << policy;
 
        std::string query = polActivatedTable.update(&PolicyActivated::value)
                                                                                 .where(expr(&PolicyActivated::admin) == admin &&
                                                                                  expr(&PolicyActivated::policy) == policy);
-       database::Statement stmt(*database, query);
-       stmt.bind(1, policyValue);
+       database::Statement stmt(*this->database, query);
+       stmt.bind(1, value.dump());
        stmt.bind(2, admin);
        stmt.bind(3, policy);
        if (!stmt.exec())
                THROW(ErrCode::RuntimeError) << "Failed to update policy:" << policy;
 
-       syncPolicyActivated();
+       /// TODO: Fix to sync without db i/o
+       this->syncPolicyActivated();
 }
 
-/// TODO(sangwan.kwon) Re-design strictest logic  
+/// TODO(sangwan.kwon) Re-design strictest logic
+/// PolicyValue PolicyStorage::strictest(const PolicyValue& policy)
 PolicyValue PolicyStorage::strictest(const std::string& policy)
 {
-       if (definitions.find(policy) == definitions.end())
+       if (this->definitions.find(policy) == this->definitions.end())
                THROW(ErrCode::LogicError) << "Not exist policy: " << policy;
 
-       // There is no enrolled admins.
-       if (activatedPolicies.size() == 0)
-               return PolicyValue(definitions[policy].ivalue);
+       /// There is no enrolled admins.
+       /// Make PolicyValue by dumped string.
+       if (this->activatedPolicies.size() == 0)
+               return PolicyValue(definitions[policy].ivalue, true);
 
        std::shared_ptr<PolicyValue> strictestPtr = nullptr;
        auto range = activatedPolicies.equal_range(policy);
        for (auto iter = range.first; iter != range.second; iter++) {
-               int value = iter->second.value;
                DEBUG(VIST) << "Admin: " << iter->second.admin << ", "
                                        << "Policy: " << iter->second.policy  << ", "
-                                       << "Value: " << value;
+                                       << "Value: " << iter->second.value;
 
                if (strictestPtr == nullptr) {
-                       strictestPtr = std::make_shared<PolicyValue>(value);
+                       strictestPtr = std::make_shared<PolicyValue>(iter->second.value, true);
                } else {
+                       /// TODO: Support String type
                        int strictestValue = *strictestPtr;
-                       if (strictestValue < value)
-                               strictestPtr.reset(new PolicyValue(value));
+                       if (strictestValue < PolicyValue(iter->second.value, true))
+                               strictestPtr.reset(new PolicyValue(iter->second.value, true));
                }
        }
 
index 938b90d89c6988b6af221271b90889248f1ceb58..9def0b1bee7b8e2cfab092963b17aab5784a9021 100644 (file)
@@ -55,7 +55,7 @@ public:
        void enroll(const std::string& admin);
        void disenroll(const std::string& admin);
 
-       void define(const std::string& policy, int ivalue);
+       void define(const std::string& policy, const PolicyValue& ivalue);
        void update(const std::string& admin,
                                const std::string& policy,
                                const PolicyValue& value);
index a8d2003374cb0b7692951548595df0c4f6a27b70..98269a09955a8f7b2a8a6bfece2fa52e14447c1a 100644 (file)
@@ -26,7 +26,8 @@ namespace policy {
 struct PolicyValue final {
        explicit PolicyValue() noexcept = default;
        explicit PolicyValue(int value) : stringfied(Stringfy::Dump(value)) {}
-       explicit PolicyValue(const std::string& value) : stringfied(Stringfy::Dump(value)) {}
+       explicit PolicyValue(const std::string& value, bool dumped = false)
+               : stringfied(dumped ? value : Stringfy::Dump(value)) {}
        ~PolicyValue() = default;
 
        PolicyValue(const PolicyValue&) = default;