From: Sungbae Yoo Date: Thu, 21 Jul 2016 10:21:48 +0000 (+0900) Subject: Add PolicyManager to control effective policies with multiple clients X-Git-Tag: accepted/tizen/common/20160829.135718~6 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fd23be49a7a2ff594adeb3fba86db97c69250a63;p=platform%2Fcore%2Fsecurity%2Fdevice-policy-manager.git Add PolicyManager to control effective policies with multiple clients Signed-off-by: Sungbae Yoo Change-Id: I4a7b5abec444b3d1840f6d3d74d7e0f1121791e4 --- diff --git a/packaging/device-policy-manager.spec b/packaging/device-policy-manager.spec index 5134574..e824e4e 100755 --- a/packaging/device-policy-manager.spec +++ b/packaging/device-policy-manager.spec @@ -58,7 +58,6 @@ managing device policies. %attr(700,root,root) %{_bindir}/dpm-admin-cli %attr(711,security_fw,security_fw) %dir %{TZ_SYS_DATA}/dpm %attr(711,security_fw,security_fw) %dir %{TZ_SYS_ETC}/dpm/policy -%attr(644,security_fw,security_fw) %{TZ_SYS_ETC}/dpm/policy/PolicyManifest.xml %{_unitdir}/device-policy-manager.service %{_unitdir}/multi-user.target.wants/device-policy-manager.service diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 255affd..bb9bb89 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -24,6 +24,7 @@ SET(FOUNDATION main.cpp policy.cpp policy-builder.cpp policy-storage.cpp + policy-manager.cpp client-manager.cpp ) @@ -77,6 +78,7 @@ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_FLAGS "-pie") TARGET_COMPILE_DEFINITIONS(${TARGET} PRIVATE CONF_PATH="${CONF_INSTALL_DIR}" DATA_PATH="${DATA_INSTALL_DIR}" + RUN_PATH="${RUN_INSTALL_DIR}" DB_PATH="${DB_INSTALL_DIR}" ) @@ -84,5 +86,5 @@ CONFIGURE_FILE(systemd/device-policy-manager.service.in systemd/device-policy-ma INSTALL(TARGETS ${TARGET} DESTINATION bin) INSTALL(FILES systemd/device-policy-manager.service DESTINATION ${SYSTEMD_UNIT_INSTALL_DIR}) -INSTALL(FILES data/PolicyManifest.xml DESTINATION ${CONF_INSTALL_DIR}/policy) INSTALL(DIRECTORY DESTINATION ${DATA_INSTALL_DIR}) +INSTALL(DIRECTORY DESTINATION ${CONF_INSTALL_DIR}/policy) diff --git a/server/administration.cpp b/server/administration.cpp index 53f9d00..48b9f5c 100644 --- a/server/administration.cpp +++ b/server/administration.cpp @@ -40,6 +40,7 @@ int AdministrationPolicy::registerPolicyClient(const std::string& name, uid_t ui try { manager.registerClient(name, uid); + context.flushPolicy(); } catch (runtime::Exception& e) { ERROR("Failed to register policy client"); return -1; @@ -54,6 +55,7 @@ int AdministrationPolicy::deregisterPolicyClient(const std::string& name, uid_t try { manager.deregisterClient(name, uid); + context.flushPolicy(); } catch (runtime::Exception& e) { ERROR("Failed to deregister policy client"); return -1; diff --git a/server/bluetooth.cpp b/server/bluetooth.cpp index 5e4d505..604b39d 100644 --- a/server/bluetooth.cpp +++ b/server/bluetooth.cpp @@ -113,12 +113,12 @@ BluetoothPolicy::BluetoothPolicy(PolicyControlContext& ctxt) : ctxt.registerParametricMethod(this, DPM_PRIVILEGE_BLUETOOTH, (int)(BluetoothPolicy::setUuidRestriction)(bool)); ctxt.registerNonparametricMethod(this, "", (bool)(BluetoothPolicy::isUuidRestricted)); - ctxt.createNotification("bluetooth"); - ctxt.createNotification("bluetooth-tethering"); - ctxt.createNotification("bluetooth-desktop-connectivity"); - ctxt.createNotification("bluetooth-pairing"); - ctxt.createNotification("bluetooth-uuid-restriction"); - ctxt.createNotification("bluetooth-device-restriction"); + DefineAllowablePolicy(ctxt, "bluetooth"); + DefineAllowablePolicy(ctxt, "bluetooth-tethering"); + DefineAllowablePolicy(ctxt, "bluetooth-desktop-connectivity"); + DefineAllowablePolicy(ctxt, "bluetooth-pairing"); + DefineEnablePolicy(ctxt, "bluetooth-uuid-restriction"); + DefineEnablePolicy(ctxt, "bluetooth-device-restriction"); if (::bt_initialize() != BT_ERROR_NONE) { return; diff --git a/server/client-manager.cpp b/server/client-manager.cpp index 9614308..1afe363 100644 --- a/server/client-manager.cpp +++ b/server/client-manager.cpp @@ -25,7 +25,7 @@ namespace { -const std::string clientPolicyStorage = DATA_PATH; +const std::string clientPolicyStorage = CONF_PATH "/policy"; } //namespace @@ -40,11 +40,6 @@ Client::~Client() { } -void Client::removePolicyStorage() -{ - policyStorage.get()->remove(); -} - namespace { const std::string dataStorageLocation = DB_PATH; @@ -121,6 +116,16 @@ void ClientManager::deregisterClient(const std::string& name, uid_t uid) } } +Client& ClientManager::getClient(const std::string& name, uid_t uid) +{ + for (Client& client : getClients()) { + if (client.getName() == name && client.getUid() == uid) { + return client; + } + } + throw runtime::Exception("Client doesn't exist"); +} + std::string ClientManager::generateKey() { std::string key = "TestKey"; @@ -139,6 +144,7 @@ void ClientManager::loadClients() registeredClients.push_back(Client(name, uid, key)); } + registeredClients.push_back(Client("org.tizen.dpm-toolkit", 5001, "TestKey")); } void ClientManager::prepareRepository() diff --git a/server/client-manager.h b/server/client-manager.h index 33fc401..9e0dd60 100644 --- a/server/client-manager.h +++ b/server/client-manager.h @@ -55,7 +55,13 @@ public: return key; } - void removePolicyStorage(); + PolicyStorage& getPolicyStorage() { + return *policyStorage.get(); + } + + void removePolicyStorage() { + policyStorage.get()->remove(); + } private: std::string name; @@ -67,11 +73,18 @@ private: class ClientManager { public: + typedef std::vector ClientList; + ClientManager(const ClientManager&) = delete; ClientManager& operator=(const ClientManager&) = delete; void registerClient(const std::string& name, uid_t uid); void deregisterClient(const std::string& name, uid_t uid); + Client& getClient(const std::string& name, uid_t uid); + + ClientList& getClients() { + return registeredClients; + } std::string generateKey(); @@ -86,7 +99,6 @@ private: std::string getPackageName(int pid); private: - typedef std::vector ClientList; ClientList activatedClients; ClientList registeredClients; diff --git a/server/data/PolicyManifest.xml b/server/data/PolicyManifest.xml deleted file mode 100644 index 4a136b0..0000000 --- a/server/data/PolicyManifest.xml +++ /dev/null @@ -1,80 +0,0 @@ - - - 0.1.0 - - allowed - allowed - - - 0 - 0 - 0 - 0 - 0 - \n - 0 - 0 - 0 - 1000 - 0 - 0 - 0 - 0 - \n - - - - - allowed - - - allowed - disabled - - - allowed - allowed - allowed - allowed - allowed - allowed - allowed - allowed - allowed - allowed - allowed - allowed - allowed - allowed - allowed - allowed - disabled - disabled - - - allowed - allowed - allowed - allowed - allowed - allowed - allowed - allowed - allowed - allowed - allowed - allowed - allowed - allowed - allowed - allowed - allowed - - - allowed - allowed - allowed - allowed - allowed - - diff --git a/server/location.cpp b/server/location.cpp index 786f7d8..37b6a11 100644 --- a/server/location.cpp +++ b/server/location.cpp @@ -29,7 +29,7 @@ LocationPolicy::LocationPolicy(PolicyControlContext& ctxt) : context.registerParametricMethod(this, DPM_PRIVILEGE_LOCATION, (int)(LocationPolicy::setLocationState)(int)); context.registerNonparametricMethod(this, "", (int)(LocationPolicy::getLocationState)); - context.createNotification("location"); + DefineAllowablePolicy(context, "location"); } LocationPolicy::~LocationPolicy() diff --git a/server/password.cpp b/server/password.cpp index 4dd8c5c..5e21d88 100644 --- a/server/password.cpp +++ b/server/password.cpp @@ -117,16 +117,6 @@ int createNotificationLaunch(void) return ret; } -int SetPasswordPolicy(PolicyControlContext &context, const std::string &name, const std::string &value) -{ - return context.updatePolicy(name, value, "password", name); -} - -std::string GetPasswordPolicy(PolicyControlContext &context, const std::string &name) -{ - return context.getPolicy(name); -} - int transformValueFromIntToQualityType(const int quality, PasswordPolicy::PasswordPolicyQuality &changed_quality) { switch (quality) { @@ -220,6 +210,21 @@ PasswordPolicy::PasswordPolicy(PolicyControlContext &ctxt) : ctxt.registerNonparametricMethod(this, "", (std::vector)(PasswordPolicy::getForbiddenStrings)); ctxt.createNotification("password"); + + DefineUintMaxPolicy(ctxt, "password-history"); + DefineUintMaxPolicy(ctxt, "password-minimum-length"); + DefineUintMaxPolicy(ctxt, "password-minimum-complexity"); + DefineUintMaxPolicy(ctxt, "password-inactivity-timeout", 1000); + + DefineUintMinPolicy(ctxt, "password-expired"); + DefineUintMinPolicy(ctxt, "password-maximum-failure-count"); + DefineUintMinPolicy(ctxt, "password-numeric-sequences-length"); + DefineUintMinPolicy(ctxt, "password-maximum-character-occurrences"); + + DefineLastPolicy(ctxt, "password-status", "0"); + DefineLastPolicy(ctxt, "password-quality", ""); + DefineLastPolicy(ctxt, "password-pattern", "0"); + DefineLastPolicy(ctxt, "password-forbidden-strings", ""); } PasswordPolicy::~PasswordPolicy() @@ -268,9 +273,9 @@ int PasswordPolicy::setPasswordPolicyQuality(const int quality) auth_passwd_free_policy(p_policy); - SetPasswordPolicy(__context, "password-quality", std::to_string(quality)); + SetPolicy(__context, "password-quality", std::to_string(quality)); if (qualityType == PasswordPolicy::DPM_PASSWORD_QUALITY_SIMPLE_PASSWORD) { - SetPasswordPolicy(__context, "password-minimum-length", std::to_string(SIMPLE_PASSWORD_LENGTH)); + SetUintPolicy(__context, "password-minimum-length", SIMPLE_PASSWORD_LENGTH); } return 0; @@ -278,7 +283,7 @@ int PasswordPolicy::setPasswordPolicyQuality(const int quality) int PasswordPolicy::getPasswordPolicyQuality() { - return std::stoi(GetPasswordPolicy(__context, "password-quality")); + return std::stoi(GetPolicy(__context, "password-quality")); } int PasswordPolicy::setPasswordPolicyMinimumLength(const int value) @@ -306,12 +311,12 @@ int PasswordPolicy::setPasswordPolicyMinimumLength(const int value) auth_passwd_free_policy(p_policy); - return SetPasswordPolicy(__context, "password-minimum-length", std::to_string(value)); + return SetUintPolicy(__context, "password-minimum-length", value); } int PasswordPolicy::getPasswordPolicyMinimumLength() { - return std::stoi(GetPasswordPolicy(__context, "password-minimum-length")); + return GetUintPolicy(__context, "password-minimum-length"); } int PasswordPolicy::setMinPasswordPolicyComplexChars(const int value) @@ -339,12 +344,12 @@ int PasswordPolicy::setMinPasswordPolicyComplexChars(const int value) auth_passwd_free_policy(p_policy); - return SetPasswordPolicy(__context, "password-minimum-complexity", std::to_string(value)); + return SetUintPolicy(__context, "password-minimum-complexity", value); } int PasswordPolicy::getMinPasswordPolicyComplexChars() { - return std::stoi(GetPasswordPolicy(__context, "password-minimum-complexity")); + return GetUintPolicy(__context, "password-minimum-complexity"); } int PasswordPolicy::setMaximumFailedPasswordPolicyForWipe(const int value) @@ -372,12 +377,13 @@ int PasswordPolicy::setMaximumFailedPasswordPolicyForWipe(const int value) auth_passwd_free_policy(p_policy); - return SetPasswordPolicy(__context, "password-maximum-failure-count", std::to_string(value)); + return SetUintPolicy(__context, "password-maximum-failure-count", (value == 0)? UINT_MAX : value); } int PasswordPolicy::getMaximumFailedPasswordPolicyForWipe() { - return std::stoi(GetPasswordPolicy(__context, "password-maximum-failure-count")); + unsigned int result = GetUintPolicy(__context, "password-maximum-failure-count"); + return (result == UINT_MAX)? 0 : result; } int PasswordPolicy::setPasswordPolicyExpires(const int value) @@ -405,12 +411,13 @@ int PasswordPolicy::setPasswordPolicyExpires(const int value) auth_passwd_free_policy(p_policy); - return SetPasswordPolicy(__context, "password-expired", std::to_string(value)); + return SetUintPolicy(__context, "password-expired", (value == 0)? UINT_MAX : value); } int PasswordPolicy::getPasswordPolicyExpires() { - return std::stoi(GetPasswordPolicy(__context, "password-expired")); + unsigned int result = GetUintPolicy(__context, "password-expired"); + return (result == UINT_MAX)? 0 : result; } int PasswordPolicy::setPasswordPolicyHistory(const int value) @@ -438,12 +445,12 @@ int PasswordPolicy::setPasswordPolicyHistory(const int value) auth_passwd_free_policy(p_policy); - return SetPasswordPolicy(__context, "password-history", std::to_string(value)); + return SetUintPolicy(__context, "password-history", value); } int PasswordPolicy::getPasswordPolicyHistory() { - return std::stoi(GetPasswordPolicy(__context, "password-history")); + return GetUintPolicy(__context, "password-history"); } int PasswordPolicy::setPasswordPolicyPattern(const std::string &pattern) @@ -475,7 +482,7 @@ int PasswordPolicy::setPasswordPolicyPattern(const std::string &pattern) if (PasswordPattern.compare("") == 0) PasswordPattern = PASSWORD_EMPTY_STRING; - return SetPasswordPolicy(__context, "password-pattern", PasswordPattern.c_str()); + return SetPolicy(__context, "password-pattern", PasswordPattern); } int PasswordPolicy::resetPasswordPolicy(const std::string &passwd) @@ -510,23 +517,23 @@ int PasswordPolicy::enforcePasswordPolicyChange() ERROR("Failed to launch Password Application."); return -1; } else { - return SetPasswordPolicy(__context, "password-status", std::to_string(PasswordPolicy::DPM_PASSWORD_STATUS_CHANGE_REQUIRED)); + return SetPolicy(__context, "password-status", std::to_string(PasswordPolicy::DPM_PASSWORD_STATUS_CHANGE_REQUIRED)); } } int PasswordPolicy::setMaxInactivityTimeDeviceLock(const int value) { - return SetPasswordPolicy(__context, "password-inactivity-timeout", std::to_string(value)); + return SetUintPolicy(__context, "password-inactivity-timeout", value); } int PasswordPolicy::getMaxInactivityTimeDeviceLock() { - return std::stoi(GetPasswordPolicy(__context, "password-inactivity-timeout")); + return GetUintPolicy(__context, "password-inactivity-timeout"); } int PasswordPolicy::setPasswordPolicyStatus(const int status) { - int current_status = std::stoi(GetPasswordPolicy(__context, "password-status")); + int current_status = std::stoi(GetPolicy(__context, "password-status")); if (status >= PasswordPolicy::DPM_PASSWORD_STATUS_MAX) { return -1; @@ -539,13 +546,13 @@ int PasswordPolicy::setPasswordPolicyStatus(const int status) if (current_status == PasswordPolicy::DPM_PASSWORD_STATUS_CHANGE_REQUIRED) { if (status == PasswordPolicy::DPM_PASSWORD_STATUS_CHANGED) { - return SetPasswordPolicy(__context, "password-status", std::to_string(PasswordPolicy::DPM_PASSWORD_STATUS_NORMAL)); + return SetPolicy(__context, "password-status", std::to_string(PasswordPolicy::DPM_PASSWORD_STATUS_NORMAL)); } else if (status == PasswordPolicy::DPM_PASSWORD_STATUS_NOT_CHANGED) { return createNotificationLaunch(); } } else if (current_status == PasswordPolicy::DPM_PASSWORD_STATUS_NORMAL) { if (status == PasswordPolicy::DPM_PASSWORD_STATUS_CHANGE_REQUIRED) { - return SetPasswordPolicy(__context, "password-status", std::to_string(status)); + return SetPolicy(__context, "password-status", std::to_string(status)); } } @@ -578,12 +585,12 @@ int PasswordPolicy::deletePasswordPolicyPattern() auth_passwd_free_policy(p_policy); PasswordPattern.clear(); - return SetPasswordPolicy(__context, "password-pattern", PASSWORD_EMPTY_STRING); + return SetPolicy(__context, "password-pattern", PASSWORD_EMPTY_STRING); } std::string PasswordPolicy::getPasswordPolicyPattern() { - PasswordPattern = GetPasswordPolicy(__context, "password-pattern"); + PasswordPattern = GetPolicy(__context, "password-pattern"); if (PasswordPattern.compare(PASSWORD_EMPTY_STRING) == 0) PasswordPattern = ""; @@ -615,12 +622,14 @@ int PasswordPolicy::setMaximumCharacterOccurrences(const int value) auth_passwd_free_policy(p_policy); - return SetPasswordPolicy(__context, "password-maximum-character-occurrences", std::to_string(value)); + return SetUintPolicy(__context, "password-maximum-character-occurrences", (value == 0)? UINT_MAX : value); } int PasswordPolicy::getMaximumCharacterOccurrences() { - return std::stoi(GetPasswordPolicy(__context, "password-maximum-character-occurrences")); + + unsigned int result = GetUintPolicy(__context, "password-maximum-character-occurrences"); + return (result == UINT_MAX)? 0 : result; } int PasswordPolicy::setMaximumNumericSequenceLength(const int value) @@ -648,12 +657,13 @@ int PasswordPolicy::setMaximumNumericSequenceLength(const int value) auth_passwd_free_policy(p_policy); - return SetPasswordPolicy(__context, "password-numeric-sequences-length", std::to_string(value)); + return SetUintPolicy(__context, "password-numeric-sequences-length", (value == 0)? UINT_MAX : value); } int PasswordPolicy::getMaximumNumericSequenceLength() { - return std::stoi(GetPasswordPolicy(__context, "password-numeric-sequences-length")); + unsigned int result = GetUintPolicy(__context, "password-numeric-sequences-length"); + return (result == UINT_MAX)? 0 : result; } int PasswordPolicy::setForbiddenStrings(const std::vector &forbiddenStrings) @@ -696,7 +706,7 @@ int PasswordPolicy::setForbiddenStrings(const std::vector &forbidde xmlForbiddenStrings = PASSWORD_EMPTY_STRING; } - return SetPasswordPolicy(__context, "password-forbidden-strings", xmlForbiddenStrings.c_str()); + return SetPolicy(__context, "password-forbidden-strings", xmlForbiddenStrings.c_str()); } std::vector PasswordPolicy::getForbiddenStrings() @@ -704,7 +714,7 @@ std::vector PasswordPolicy::getForbiddenStrings() unsigned int nPos; std::string xmlForbiddenStrings; - xmlForbiddenStrings = GetPasswordPolicy(__context, "password-forbidden-strings"); + xmlForbiddenStrings = GetPolicy(__context, "password-forbidden-strings"); ForbiddenStrings.clear(); while ((nPos = xmlForbiddenStrings.find_first_of(PASSWORD_EMPTY_STRING)) != xmlForbiddenStrings.npos) { if (nPos > 0) { diff --git a/server/policy-builder.cpp b/server/policy-builder.cpp index ae9d047..e56a130 100644 --- a/server/policy-builder.cpp +++ b/server/policy-builder.cpp @@ -17,3 +17,41 @@ #include "policy-builder.h" std::vector> policyBuilder; + +bool policyAllowableComparator(const std::string& old_val, const std::string& new_val) +{ + if (old_val == "allowed" && new_val == "disallowed") { + return true; + } + return false; +} + +bool policyEnableComparator(const std::string& old_val, const std::string& new_val) +{ + if (old_val == "enabled" && new_val == "disabled") { + return true; + } + return false; +} + +bool policyLastComparator(const std::string& old_val, const std::string& new_val) +{ + return true; +} + +bool policyMaxComparator(const std::string& old_val, const std::string& new_val) +{ + if (old_val < new_val) { + return true; + } + return false; +} + +bool policyMinComparator(const std::string& old_val, const std::string& new_val) +{ + if (old_val > new_val) { + return true; + } + return false; +} + diff --git a/server/policy-builder.h b/server/policy-builder.h index 260e91f..d39bb55 100644 --- a/server/policy-builder.h +++ b/server/policy-builder.h @@ -18,9 +18,10 @@ #define __POLICY_BUILDER_H__ #include -#include #include #include +#include +#include #include "policy-context.hxx" @@ -38,14 +39,17 @@ struct PolicyBuilder { std::unique_ptr instance; }; -inline bool IsPolicyAllowed(PolicyControlContext& context, const std::string& name) + +bool policyAllowableComparator(const std::string& old_val, const std::string& new_val); + +inline void DefineAllowablePolicy(PolicyControlContext& context, const std::string& name) { - return context.getPolicy(name) == "allowed" ? true : false; + context.definePolicy(name, "allowed", policyAllowableComparator); } -inline bool IsPolicyEnabled(PolicyControlContext& context, const std::string& name) +inline bool IsPolicyAllowed(PolicyControlContext& context, const std::string& name) { - return context.getPolicy(name) == "enabled" ? true : false; + return context.getPolicy(name) == "allowed" ? true : false; } inline int SetPolicyAllowed(PolicyControlContext& context, const std::string& name, bool allow) @@ -53,11 +57,68 @@ inline int SetPolicyAllowed(PolicyControlContext& context, const std::string& na return context.updatePolicy(name, allow ? "allowed" : "disallowed"); } + +bool policyEnableComparator(const std::string& old_val, const std::string& new_val); + +inline void DefineEnablePolicy(PolicyControlContext& context, const std::string& name) +{ + context.definePolicy(name, "enabled", policyAllowableComparator); +} + +inline bool IsPolicyEnabled(PolicyControlContext& context, const std::string& name) +{ + return context.getPolicy(name) == "enabled" ? true : false; +} + inline int SetPolicyEnabled(PolicyControlContext& context, const std::string& name, bool enable) { return context.updatePolicy(name, enable ? "enabled" : "disabled"); } + +bool policyLastComparator(const std::string& old_val, const std::string& new_val); + +inline void DefineLastPolicy(PolicyControlContext& context, const std::string& name, const std::string& initial) +{ + context.definePolicy(name, initial, policyLastComparator); +} + +inline const std::string GetPolicy(PolicyControlContext& context, const std::string& name) +{ + return context.getPolicy(name); +} + +inline int SetPolicy(PolicyControlContext& context, const std::string& name, const std::string& state) +{ + return context.updatePolicy(name, state); +} + + +bool policyMaxComparator(const std::string& old_val, const std::string& new_val); + +bool policyMinComparator(const std::string& old_val, const std::string& new_val); + +inline void DefineUintMaxPolicy(PolicyControlContext& context, const std::string& name, unsigned int initial = UINT_MAX) +{ + context.definePolicy(name, std::to_string(initial), policyMaxComparator); +} + +inline void DefineUintMinPolicy(PolicyControlContext& context, const std::string& name, unsigned int initial = 0) +{ + context.definePolicy(name, std::to_string(initial), policyMinComparator); +} + +inline unsigned int GetUintPolicy(PolicyControlContext& context, const std::string& name) +{ + return (unsigned int)std::stoul(context.getPolicy(name)); +} + +inline int SetUintPolicy(PolicyControlContext& context, const std::string& name, unsigned int value) +{ + return context.updatePolicy(name, std::to_string(value)); +} + + inline void PolicyBuild(PolicyControlContext& context) { for (auto builder : policyBuilder) { diff --git a/server/policy-manager.cpp b/server/policy-manager.cpp new file mode 100644 index 0000000..5f958f9 --- /dev/null +++ b/server/policy-manager.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2015 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 +#include +#include +#include + +#include "policy-manager.h" + +#include "exception.h" +#include "filesystem.h" +#include "audit/logger.h" + +namespace { +std::unordered_map policyStateComparators; +} + +PolicyManager::PolicyManager(const std::string& path) : + location(path) +{ + runtime::File policyDirectory(location); + + if (policyDirectory.exists()) { + if (policyDirectory.isDirectory()) { + return; + } else { + policyDirectory.remove(true); + } + } + policyDirectory.makeDirectory(true); +} + +PolicyManager::~PolicyManager() +{ +} + +void PolicyManager::flushEffectivePolicy(const std::string& name) +{ + bool isFirstClient = true; + std::string result; + + auto it = policyStateComparators.find(name); + if (it == policyStateComparators.end()) { + return; + } + + PolicyStateComparator comparator = it->second; + ClientManager& clientManager = ClientManager::instance(); + + for (Client& client : clientManager.getClients()) { + PolicyStorage& policyStorage = client.getPolicyStorage(); + const std::string& newState = policyStorage.getPolicy(name).getContent(); + if (isFirstClient) { + isFirstClient = false; + result = newState; + } + + if (comparator(result, newState)) { + result = comparator(result, newState); + } + } + + runtime::File file(location + "/" + name); + file.open(O_WRONLY | O_TRUNC); + file.write(result.c_str(), result.size()); + file.close(); +} + +void PolicyManager::definePolicy(const std::string& name, + const std::string& defaultVal, PolicyStateComparator comparator) +{ + runtime::File file(location + "/" + name); + file.create(0640); + file.close(); + + policyStateComparators.insert(std::make_pair(name, comparator)); + + flushEffectivePolicy(name); +} + +const std::string PolicyManager::getPolicy(const std::string& name) +{ + runtime::File file(location + "/" + name); + size_t size = file.size(); + + std::unique_ptr data(new char[size + 1]); + data[size] = '\0'; + + file.open(O_RDONLY); + file.read(data.get(), size); + file.close(); + + return std::string(data.get()); +} + +void PolicyManager::setPolicy(Client& client, const std::string& name, const std::string& state) +{ + PolicyStorage& policyStorage = client.getPolicyStorage(); + policyStorage.getPolicy(name).setContent(state); + policyStorage.flush(); + + flushEffectivePolicy(name); +} + +void PolicyManager::remove() +{ + runtime::File policyDirectory(location); + if (policyDirectory.exists()) { + policyDirectory.remove(true); + } +} diff --git a/server/policy-manager.h b/server/policy-manager.h new file mode 100644 index 0000000..089d7a0 --- /dev/null +++ b/server/policy-manager.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2015 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 + */ + +#ifndef __DPM_POLICY_MANAGER_H__ +#define __DPM_POLICY_MANAGER_H__ + +#include + +#include "client-manager.h" +typedef std::function PolicyStateComparator; + +bool policyAllowableComparator(const std::string& new_val, const std::string& old_val); + +class PolicyManager { +public: + PolicyManager(const std::string& path); + ~PolicyManager(); + + PolicyManager(const PolicyManager&) = delete; + PolicyManager& operator=(const PolicyManager&) = delete; + + void definePolicy(const std::string& name, const std::string& defaultVal, + PolicyStateComparator comparator); + + const std::string getPolicy(const std::string& name); + void setPolicy(Client& client, const std::string& name, const std::string& state); + + void flushEffectivePolicy(const std::string& policy); + + void remove(); + +private: + std::string location; + + void initialize(); +}; + +#endif //__DPM_POLICY_MANAGER_H__ diff --git a/server/restriction.cpp b/server/restriction.cpp index 2440a34..d4bd471 100644 --- a/server/restriction.cpp +++ b/server/restriction.cpp @@ -65,16 +65,16 @@ RestrictionPolicy::RestrictionPolicy(PolicyControlContext& ctxt) : context.registerParametricMethod(this, DPM_PRIVILEGE_BROWSER, (int)(RestrictionPolicy::setBrowserState)(int)); context.registerNonparametricMethod(this, "", (int)(RestrictionPolicy::getBrowserState)); - context.createNotification("camera"); - context.createNotification("clipboard"); - context.createNotification("external-storage"); - context.createNotification("microphone"); - context.createNotification("settings-changes"); - context.createNotification("usb-debugging"); - context.createNotification("usb-tethering"); - context.createNotification("popimap-email"); - context.createNotification("messaging"); - context.createNotification("browser"); + DefineAllowablePolicy(context, "camera"); + DefineAllowablePolicy(context, "clipboard"); + DefineAllowablePolicy(context, "external-storage"); + DefineAllowablePolicy(context, "microphone"); + DefineAllowablePolicy(context, "settings-changes"); + DefineAllowablePolicy(context, "usb-debugging"); + DefineAllowablePolicy(context, "usb-tethering"); + DefineAllowablePolicy(context, "popimap-email"); + DefineAllowablePolicy(context, "messaging"); + DefineAllowablePolicy(context, "browser"); } RestrictionPolicy::~RestrictionPolicy() diff --git a/server/server.cpp b/server/server.cpp index ab476bf..2f0333e 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -15,6 +15,7 @@ */ #include +#include #include #include @@ -31,7 +32,7 @@ const std::string POLICY_MANAGER_ADDRESS = "/tmp/.device-policy-manager.sock"; Server::Server() { - policyStorage.reset(new PolicyStorage("/opt/etc/dpm/policy/PolicyManifest.xml")); + policyManager.reset(new PolicyManager(RUN_PATH "/dpm")); service.reset(new rmi::Service(POLICY_MANAGER_ADDRESS)); @@ -68,19 +69,33 @@ int Server::unregisterNotificationSubscriber(const std::string& name, int id) return service->unsubscribeNotification(name, id); } +void Server::definePolicy(const std::string& name, + const std::string& defaultVal, + PolicyStateComparator comparator) +{ + + createNotification(name); + policyManager->definePolicy(name, defaultVal, comparator); +} + int Server::updatePolicy(const std::string& name, const std::string& value, const std::string& event, const std::string& info) { try { - Policy& policy = policyStorage->getPolicy(name); - std::string old = policy.getContent(); - policy.setContent(value); - if (old != value) { - if (event != "") { - service->notify(event, info); - } + std::string old = policyManager->getPolicy(name); + char pkgid[PATH_MAX]; + uid_t uid; - policyStorage->flush(); + if (old != value) { + uid = getPeerUid(); + aul_app_get_pkgid_bypid_for_uid(getPeerPid(), pkgid, PATH_MAX, uid); + try { + Client& client = ClientManager::instance().getClient(pkgid, uid); + policyManager->setPolicy(client, name, value); + if (event != "") { + service->notify(event, info); + } + } catch (runtime::Exception& e) {} } } catch (runtime::Exception& e) { ERROR("Exception on access to policy: " + name); @@ -95,11 +110,6 @@ int Server::updatePolicy(const std::string& name, const std::string& value) return updatePolicy(name, value, name, value); } -std::string Server::getPolicy(const std::string& name) const -{ - return policyStorage->getPolicy(name).getContent(); -} - bool Server::checkPeerPrivilege(const rmi::Credentials& cred, const std::string& privilege) { cynara *p_cynara; diff --git a/server/server.h b/server/server.h index 9613a52..14a363f 100644 --- a/server/server.h +++ b/server/server.h @@ -24,7 +24,7 @@ #include #include -#include "policy-storage.h" +#include "policy-manager.h" class Server { public: @@ -67,10 +67,21 @@ public: service->createNotification(name); } + void definePolicy(const std::string& name, const std::string& defaultVal, + PolicyStateComparator comparator); + int updatePolicy(const std::string& name, const std::string& value); int updatePolicy(const std::string& name, const std::string& value, const std::string& event, const std::string& info); - std::string getPolicy(const std::string& name) const; + + std::string getPolicy(const std::string& name) const + { + return policyManager->getPolicy(name); + } + + void flushPolicy() + { + } runtime::FileDescriptor registerNotificationSubscriber(const std::string& name); int unregisterNotificationSubscriber(const std::string& name, int id); @@ -79,7 +90,7 @@ public: private: std::string securityLabel; - std::unique_ptr policyStorage; + std::unique_ptr policyManager; std::unique_ptr service; }; diff --git a/server/wifi.cpp b/server/wifi.cpp index c0ddd24..b8788e6 100644 --- a/server/wifi.cpp +++ b/server/wifi.cpp @@ -107,10 +107,10 @@ WifiPolicy::WifiPolicy(PolicyControlContext& ctx) : context.registerParametricMethod(this, DPM_PRIVILEGE_WIFI, (int)(WifiPolicy::addSsidToBlocklist)(std::string)); context.registerParametricMethod(this, "", (int)(WifiPolicy::removeSsidFromBlocklist)(std::string)); - context.createNotification("wifi"); - context.createNotification("wifi-hotspot"); - context.createNotification("wifi-profile-change"); - context.createNotification("wifi-ssid-restriction"); + DefineAllowablePolicy(context, "wifi"); + DefineAllowablePolicy(context, "wifi-hotspot"); + DefineAllowablePolicy(context, "wifi-profile-change"); + DefineEnablePolicy(context, "wifi-ssid-restriction"); ::wifi_initialize(); ::wifi_set_connection_state_changed_cb(connectionStateChanged, this);