From: Sangwan Kwon Date: Tue, 17 Sep 2019 06:03:23 +0000 (+0900) Subject: Apply template-method-pattern to policy-model X-Git-Tag: submit/tizen/20200810.073515~197 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a249d9d47c8b064e2cd8df910a787ce38d785c20;p=platform%2Fcore%2Fsecurity%2Fvist.git Apply template-method-pattern to policy-model Signed-off-by: Sangwan Kwon --- diff --git a/plugins/bluetooth/bluetooth.cpp b/plugins/bluetooth/bluetooth.cpp index 553ae3b..f9df95c 100644 --- a/plugins/bluetooth/bluetooth.cpp +++ b/plugins/bluetooth/bluetooth.cpp @@ -18,11 +18,12 @@ #include #include -#include -#include +#include #include #include +#include + #include "../dlog.h" #define BT_FAILED(ret) \ @@ -46,14 +47,14 @@ inline int canonicalize(int value) } // namespace -class ModeChange : public GlobalPolicy { +class ModeChange : public GlobalPolicy { public: ModeChange() : GlobalPolicy("bluetooth") { PolicyEventNotifier::create("bluetooth"); } - bool apply(const DataType& value) + bool apply(const DataSetInt& value, uid_t) { int ret = bluetooth_dpm_set_allow_mode(STATE_CHANGE_IS_ALLOWED(value)); if (!BT_FAILED(ret)) { @@ -65,14 +66,14 @@ public: } }; -class DesktopConnectivity : public GlobalPolicy { +class DesktopConnectivity : public GlobalPolicy { public: DesktopConnectivity() : GlobalPolicy("bluetooth-desktop-connectivity") { PolicyEventNotifier::create("bluetooth_desktop_connectivity"); } - bool apply(const DataType & value) + bool apply(const DataSetInt & value, uid_t) { int ret = bluetooth_dpm_set_desktop_connectivity_state(POLICY_IS_ALLOWED(value)); if (!BT_FAILED(ret)) { @@ -85,14 +86,14 @@ public: } }; -class Pairing: public GlobalPolicy { +class Pairing: public GlobalPolicy { public: Pairing() : GlobalPolicy("bluetooth-pairing") { PolicyEventNotifier::create("bluetooth_pairing"); } - bool apply(const DataType& value) + bool apply(const DataSetInt& value, uid_t) { int ret = bluetooth_dpm_set_pairing_state(POLICY_IS_ALLOWED(value)); if (!BT_FAILED(ret)) { @@ -105,14 +106,14 @@ public: } }; -class Tethering: public GlobalPolicy { +class Tethering: public GlobalPolicy { public: Tethering() : GlobalPolicy("bluetooth-tethering") { PolicyEventNotifier::create("bluetooth_tethering"); } - bool apply(const DataType& value) + bool apply(const DataSetInt& value, uid_t) { int enable = value; PolicyEventNotifier::emit("bluetooth_tethering", @@ -126,34 +127,19 @@ public: Bluetooth(); ~Bluetooth(); - int setModeChangeState(bool enable); - bool getModeChangeState(); - int setDesktopConnectivityState(bool enable); - bool getDesktopConnectivityState(); - int setTetheringState(bool enable); - bool getTetheringState(); - int setPairingState(bool enable); - bool getPairingState(); - private: static void onStateChanged(int result, bt_adapter_state_e state, void *user_data); - -private: - ModeChange modeChange; - DesktopConnectivity connectivity; - Pairing pairing; - Tethering tethering; }; Bluetooth::Bluetooth() { if (::bt_initialize() != BT_ERROR_NONE) { - ERROR(PLUGINS, "Bluetooth framework was not initilaized"); + ERROR(PLUGINS,"Bluetooth framework was not initilaized"); return; } if (::bt_adapter_set_state_changed_cb(onStateChanged, this) != BT_ERROR_NONE) { - ERROR(PLUGINS, "Failed to register Bluetooth callback"); + ERROR(PLUGINS,"Failed to register Bluetooth callback"); return; } } @@ -174,96 +160,3 @@ void Bluetooth::onStateChanged(int result, bt_adapter_state_e state, void *user_ // pimpl->uuidRestriction.enforce(); } } - -int Bluetooth::setModeChangeState(bool enable) -{ - try { - modeChange.set(enable); - } catch (runtime::Exception& e) { - ERROR(PLUGINS, "Exception: " << e.what()); - return -1; - } - - return 0; -} - -bool Bluetooth::getModeChangeState() -{ - return modeChange.get(); -} - -int Bluetooth::setDesktopConnectivityState(bool enable) -{ - try { - connectivity.set(enable); - } catch (runtime::Exception& e) { - ERROR(PLUGINS, "Exception: " << e.what()); - return -1; - } - - return 0; -} - -bool Bluetooth::getDesktopConnectivityState() -{ - return connectivity.get(); -} - -int Bluetooth::setPairingState(bool enable) -{ - try { - pairing.set(enable); - } catch (runtime::Exception& e) { - ERROR(PLUGINS, "Exception: " << e.what()); - return -1; - } - - return 0; -} - -bool Bluetooth::getPairingState() -{ - return pairing.get(); -} - -int Bluetooth::setTetheringState(bool enable) -{ - try { - tethering.set(enable); - } catch (runtime::Exception& e) { - ERROR(PLUGINS, "Exception " << e.what()); - return -1; - } - - return 0; -} - -bool Bluetooth::getTetheringState() -{ - return tethering.get(); -} - - -extern "C" { - -#define PRIVILEGE "http://tizen.org/privilege/dpm.bluetooth" - -AbstractPolicyProvider *PolicyFactory(PolicyControlContext& context) -{ - INFO(PLUGINS, "Bluetooth plugin loaded"); - Bluetooth *policy = new Bluetooth(); - - context.expose(policy, PRIVILEGE, (int)(Bluetooth::setModeChangeState)(bool)); - context.expose(policy, PRIVILEGE, (int)(Bluetooth::setDesktopConnectivityState)(bool)); - context.expose(policy, PRIVILEGE, (int)(Bluetooth::setTetheringState)(bool)); - context.expose(policy, PRIVILEGE, (int)(Bluetooth::setPairingState)(bool)); - - context.expose(policy, "", (bool)(Bluetooth::getModeChangeState)()); - context.expose(policy, "", (bool)(Bluetooth::getDesktopConnectivityState)()); - context.expose(policy, "", (bool)(Bluetooth::getTetheringState)()); - context.expose(policy, "", (bool)(Bluetooth::getPairingState)()); - - return policy; -} - -} // extern "C" diff --git a/src/policyd/pil/CMakeLists.txt b/src/policyd/pil/CMakeLists.txt index 6756bb4..4cf1a88 100644 --- a/src/policyd/pil/CMakeLists.txt +++ b/src/policyd/pil/CMakeLists.txt @@ -32,7 +32,6 @@ SET(PAPIS app-bundle.h logger.h packman.h policy-event.h - policy-context.h policy-admin.h policy-client.h policy-model.h @@ -40,27 +39,28 @@ SET(PAPIS app-bundle.h status.h observer.h) -SET(PIL_DEPENDENCY klay - glib-2.0 - gio-2.0 - sqlite3 - bundle - aul - appsvc - pkgmgr - pkgmgr-info - syspopup-caller - deviced - libtzplatform-config - security-privilege-manager - capi-system-info - capi-base-common - capi-system-system-settings - cynara-client - notification - cynara-session) +SET(DEPENDENCY klay + glib-2.0 + gio-2.0 + sqlite3 + bundle + aul + appsvc + pkgmgr + pkgmgr-info + vconf + syspopup-caller + deviced + libtzplatform-config + security-privilege-manager + capi-system-info + capi-base-common + capi-system-system-settings + notification + cynara-client + cynara-session) -PKG_CHECK_MODULES(PIL_DEPS REQUIRED ${PIL_DEPENDENCY}) +PKG_CHECK_MODULES(PIL_DEPS REQUIRED ${DEPENDENCY}) INCLUDE_DIRECTORIES(SYSTEM "${PIL_DEPS_INCLUDE_DIRS}") diff --git a/src/policyd/pil/domain-policy.h b/src/policyd/pil/domain-policy.h new file mode 100644 index 0000000..87bfca1 --- /dev/null +++ b/src/policyd/pil/domain-policy.h @@ -0,0 +1,76 @@ +/* + * 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 + */ + +#pragma once + +#include +#include + +#include + +#include "policy-model.h" + +class DomainPolicy : public AbstractPolicy { +public: + DomainPolicy(const std::string& name) : AbstractPolicy(name) {} + virtual ~DomainPolicy() = default; + + DomainPolicy(const DomainPolicy&) = delete; + DomainPolicy& operator=(const DomainPolicy&) = delete; + + DomainPolicy(DomainPolicy&&) = default; + DomainPolicy& operator=(DomainPolicy&&) = default; + + inline void set(const DataSetInt& val) override + { + PolicyAdmin admin(rmi::Service::getPeerPid(), rmi::Service::getPeerUid()); + PolicyStorage::update(id, admin.getName(), admin.getUid(), val); + + std::lock_guard mtxGuard(mtx); + this->enforce(admin.getUid()); + } + + inline DataSetInt get() override + { + uid_t domain = rmi::Service::getPeerUid(); + + std::lock_guard mtxGuard(mtx); + if (!current.count(domain)) + enforce(domain); + + return current[domain].value; + } + +private: + inline void enforce(uid_t domain) override + { + auto value = initial; + if (!ready[domain]) + current[domain] = initial; + + PolicyStorage::strictize(id, value, domain); + if (current[domain] != value) { + apply(value, domain); + current[domain] = value; + } + + ready[domain] = true; + } + +private: + std::unordered_map current; + std::unordered_map ready; +}; diff --git a/src/policyd/pil/global-policy.h b/src/policyd/pil/global-policy.h new file mode 100644 index 0000000..a99198b --- /dev/null +++ b/src/policyd/pil/global-policy.h @@ -0,0 +1,70 @@ +/* + * 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 + */ + +#pragma once + +#include +#include + +#include + +#include "policy-model.h" + +class GlobalPolicy : public AbstractPolicy { +public: + GlobalPolicy(const std::string& name) : AbstractPolicy(name) {} + virtual ~GlobalPolicy() = default; + + GlobalPolicy(const GlobalPolicy&) = delete; + GlobalPolicy& operator=(const GlobalPolicy&) = delete; + + GlobalPolicy(GlobalPolicy&&) = default; + GlobalPolicy& operator=(GlobalPolicy&&) = default; + + inline void set(const DataSetInt& val) override + { + PolicyAdmin admin(rmi::Service::getPeerPid(), rmi::Service::getPeerUid()); + PolicyStorage::update(id, admin.getName(), admin.getUid(), val); + + std::lock_guard mtxGuard(mtx); + enforce(-1); + } + + inline DataSetInt get() override + { + std::lock_guard mtxGuard(mtx); + if (!ready) { + enforce(-1); + ready = true; + } + return current.value; + } + +private: + inline void enforce(uid_t) override + { + auto value = initial; + PolicyStorage::strictize(id, value); + if (current != value) { + apply(value); + current = value; + } + } + +private: + DataSetInt current; + bool ready = false; +}; diff --git a/src/policyd/pil/policy-model.h b/src/policyd/pil/policy-model.h index c9df02c..2f0580a 100644 --- a/src/policyd/pil/policy-model.h +++ b/src/policyd/pil/policy-model.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * 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. @@ -14,13 +14,12 @@ * limitations under the License */ -#ifndef __DPM_POLICY_MODEL_H__ -#define __DPM_POLICY_MODEL_H__ +#pragma once + #include #include -#include -#include #include +#include #include @@ -28,187 +27,52 @@ #include "policy-admin.h" #include "observer.h" -class AbstractPolicyProvider { -public: +class AbstractPolicy; + +struct AbstractPolicyProvider { AbstractPolicyProvider() {} virtual ~AbstractPolicyProvider() {} + + std::vector> policies; }; -template -class DomainPolicy : public Observer { +class AbstractPolicy : public Observer { public: - typedef Type DataType; - - DomainPolicy(const std::string& name); - virtual ~DomainPolicy(); - - void set(const Type& value); - DataType get(); - - void onEvent(uid_t domain); - - virtual bool apply(const Type& value, uid_t domain) + explicit AbstractPolicy(const std::string& name) : name(name) { - return true; - } + this->id = PolicyStorage::define(name, initial); + if (id < 0) + throw runtime::Exception("Failed to define policy"); -private: - void enforce(uid_t domid); - -private: - int id; - Type initial; - std::unordered_map current; - std::unordered_map ready; - std::mutex mtx; -}; - -template -DomainPolicy::DomainPolicy(const std::string& name) : - id(-1), current() -{ - id = PolicyStorage::define(name, initial); - if (id < 0) { - throw runtime::Exception("Failed to define policy"); + PolicyStorage::subscribeEvent(this); } - PolicyStorage::subscribeEvent(this); -} - -template -DomainPolicy::~DomainPolicy() -{ -} - -template -void DomainPolicy::enforce(uid_t domid) -{ - Type value = initial; - if (!ready[domid]) - current[domid] = initial; - - PolicyStorage::strictize(id, value, domid); - if (current[domid] != value) { - apply(value, domid); - current[domid] = value; - } + ~AbstractPolicy() = default; - ready[domid] = true; -} + AbstractPolicy(const AbstractPolicy&) = delete; + AbstractPolicy& operator=(const AbstractPolicy&) = delete; -template -void DomainPolicy::set(const DataType& val) -{ - PolicyAdmin admin(rmi::Service::getPeerPid(), rmi::Service::getPeerUid()); - PolicyStorage::update(id, admin.getName(), admin.getUid(), val); + AbstractPolicy(AbstractPolicy&&) = default; + AbstractPolicy& operator=(AbstractPolicy&&) = default; - std::lock_guard mtxGuard(mtx); - enforce(admin.getUid()); -} + virtual void set(const DataSetInt& value) = 0; + virtual DataSetInt get() = 0; -template -Type DomainPolicy::get() -{ - uid_t domain = rmi::Service::getPeerUid(); + virtual bool apply(const DataSetInt& value, uid_t domain = 0) = 0; - std::lock_guard mtxGuard(mtx); - if (!current.count(domain)) { + inline void onEvent(uid_t domain) + { + std::lock_guard mtxGuard(mtx); enforce(domain); } - return current[domain].value; -} + std::string name; -template -void DomainPolicy::onEvent(uid_t domain) -{ - std::lock_guard mtxGuard(mtx); - enforce(domain); -} - -template -class GlobalPolicy : public Observer { -public: - typedef Type DataType; - - GlobalPolicy(const std::string& name); - virtual ~GlobalPolicy(); - - void set(const Type& value); - Type get(); - - void onEvent(uid_t domain); - - virtual bool apply(const Type& value) - { - return true; - } - -private: - void enforce(); +protected: + int id = -1; + std::mutex mtx; + DataSetInt initial; private: - int id; - Type initial; - Type current; - bool ready; - std::mutex mtx; + virtual void enforce(uid_t domain = 0) = 0; }; - -template -GlobalPolicy::GlobalPolicy(const std::string& name) : - id(-1), current(), ready(false) -{ - id = PolicyStorage::define(name, initial); - if (id < 0) { - throw runtime::Exception("Failed to define policy"); - } - - current = initial; - PolicyStorage::subscribeEvent(this); -} - -template -GlobalPolicy::~GlobalPolicy() -{ -} - -template -void GlobalPolicy::enforce() -{ - Type value = initial; - PolicyStorage::strictize(id, value); - if (current != value) { - apply(value); - current = value; - } -} - -template -void GlobalPolicy::set(const Type& val) -{ - PolicyAdmin admin(rmi::Service::getPeerPid(), rmi::Service::getPeerUid()); - PolicyStorage::update(id, admin.getName(), admin.getUid(), val); - - std::lock_guard mtxGuard(mtx); - enforce(); -} - -template -Type GlobalPolicy::get() -{ - std::lock_guard mtxGuard(mtx); - if (!ready) { - enforce(); - ready = true; - } - return current.value; -} - -template -void GlobalPolicy::onEvent(uid_t domain) -{ - std::lock_guard mtxGuard(mtx); - enforce(); -} -#endif //__DPM_POLICY_MODEL_H__ diff --git a/src/policyd/server/CMakeLists.txt b/src/policyd/server/CMakeLists.txt index e0872ca..7d179be 100644 --- a/src/policyd/server/CMakeLists.txt +++ b/src/policyd/server/CMakeLists.txt @@ -55,4 +55,4 @@ TARGET_LINK_LIBRARIES(${TARGET} dl pthread sqlite3 dpm-pil ${TARGET_SERVER_LIB}) SET_TARGET_PROPERTIES(${TARGET} PROPERTIES COMPILE_FLAGS "-fPIE") SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_FLAGS "-pie") -INSTALL(TARGETS ${TARGET} DESTINATION ${CMAKE_INSTALL_BINDIR}) +INSTALL(TARGETS ${TARGET} DESTINATION bin) diff --git a/src/policyd/server/plugin.cpp b/src/policyd/server/plugin.cpp index 6fae176..34e218d 100644 --- a/src/policyd/server/plugin.cpp +++ b/src/policyd/server/plugin.cpp @@ -53,7 +53,7 @@ PolicyLoader::PolicyLoader(const std::string& base) : { } -AbstractPolicyProvider* PolicyLoader::instantiate(const std::string& name, PolicyControlContext& context) +std::shared_ptr PolicyLoader::instantiate(const std::string& name) { PluginMap::iterator iter = pluginMap.find(name); if (iter == pluginMap.end()) { @@ -72,7 +72,8 @@ AbstractPolicyProvider* PolicyLoader::instantiate(const std::string& name, Polic pluginMap[name] = std::move(plguin); - return (*factory)(context); + auto provider = (*factory)(); + return std::shared_ptr(provider); } return nullptr; diff --git a/src/policyd/server/plugin.h b/src/policyd/server/plugin.h index a709fc7..7fe3013 100644 --- a/src/policyd/server/plugin.h +++ b/src/policyd/server/plugin.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved + * 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. @@ -14,13 +14,13 @@ * limitations under the License */ -#ifndef __DPM_PLUGIN_H__ -#define __DPM_PLUGIN_H__ +#pragma once + #include #include #include +#include -#include "pil/policy-context.h" #include "pil/policy-model.h" class Plugin { @@ -48,10 +48,10 @@ private: class PolicyLoader { public: - typedef AbstractPolicyProvider* (*PolicyFactory)(PolicyControlContext& context); + typedef AbstractPolicyProvider* (*PolicyFactory)(); PolicyLoader(const std::string& base); - AbstractPolicyProvider* instantiate(const std::string& name, rmi::Service& context); + std::shared_ptr instantiate(const std::string& name); private: typedef std::unordered_map PluginMap; @@ -59,5 +59,3 @@ private: std::string basename; PluginMap pluginMap; }; - -#endif /*!__DPM_PLUGIN_H__*/ diff --git a/src/policyd/server/server.cpp b/src/policyd/server/server.cpp index ff932e1..c5894f8 100644 --- a/src/policyd/server/server.cpp +++ b/src/policyd/server/server.cpp @@ -94,7 +94,7 @@ std::pair DevicePolicyManager::loadPolicyPlugins() continue; } - auto instance = policyLoader->instantiate(iter->getName(), *this); + auto instance = policyLoader->instantiate(iter->getName()); if (instance == nullptr) { ERROR(DPM, "Failed to instantiate.: " << iter->getName()); ++failed; @@ -102,7 +102,7 @@ std::pair DevicePolicyManager::loadPolicyPlugins() continue; } - policyList.push_back(instance); + providerList.emplace_back(std::move(instance)); ++passed; ++iter; } diff --git a/src/policyd/server/server.h b/src/policyd/server/server.h index 38931e2..bd4cd99 100644 --- a/src/policyd/server/server.h +++ b/src/policyd/server/server.h @@ -44,6 +44,12 @@ public: void run(int activation, int timeout); + // Temporary debug method + inline std::vector>& getProviderList() + { + return this->providerList; + } + private: void initPolicyStorage(); @@ -60,7 +66,7 @@ private: typedef std::unordered_map ClientRegistry; ClientRegistry clientRegistry; - std::vector policyList; + std::vector> providerList; std::unique_ptr policyLoader; std::thread policyApplyThread; diff --git a/src/policyd/tests/CMakeLists.txt b/src/policyd/tests/CMakeLists.txt index e60c3e8..0d63b83 100644 --- a/src/policyd/tests/CMakeLists.txt +++ b/src/policyd/tests/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved +# 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. diff --git a/src/policyd/tests/test-server.cpp b/src/policyd/tests/test-server.cpp index a1b30bb..bd8d5ea 100644 --- a/src/policyd/tests/test-server.cpp +++ b/src/policyd/tests/test-server.cpp @@ -18,10 +18,22 @@ #include +#include + TESTCASE(LOAD_PLUGINS) { DevicePolicyManager manager; auto result = manager.loadPolicyPlugins(); + + // Temporary debug method + auto providers = manager.getProviderList(); + for (const auto& provider : providers) { + for (const auto& policy : provider->policies) { + std::cout << "Policy Lists:" << std::endl; + std::cout << "\t" << policy->name << std::endl; + } + } + TEST_EXPECT(true, result.first > 0); TEST_EXPECT(true, result.second == 0); }