2 * Copyright (c) 2016-2017 Samsung Electronics Co.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
17 * @file src/agent/main/Policy.cpp
18 * @author Zofia Abramowska <z.abramowska@samsung.com>
19 * @brief Implementation of Policy wrappers
25 #include <security-manager.h>
27 #include <exception/Exception.h>
32 #include "PrivilegeInfo.h"
37 inline void throwOnSMError(std::string err, int ret)
39 if (ret != SECURITY_MANAGER_SUCCESS)
40 throw AskUser::Exception("SM error : " + err + " : " + std::to_string(ret));
43 inline void throwOnSMNullptr(std::string err, const char *ret)
46 throw AskUser::Exception("SM returned null : " + err);
49 } // namespace anonymous
51 PolicyEntryCopy::PolicyEntryCopy(policy_entry *entry) {
53 throwOnSMNullptr("security_manager_policy_entry_get_application",
54 app = security_manager_policy_entry_get_application(entry));
58 throwOnSMNullptr("security_manager_policy_entry_get_user",
59 user = security_manager_policy_entry_get_user(entry));
62 const char *privilege;
63 throwOnSMNullptr("security_manager_policy_entry_get_privilege",
64 privilege = security_manager_policy_entry_get_privilege(entry));
65 m_privilege = privilege;
68 throwOnSMNullptr("security_manager_policy_entry_get_level",
69 level = security_manager_policy_entry_get_level(entry));
73 Policy getMinimumPolicy(const std::vector<Policy> &policies) {
74 Policy minimumPolicy = "Allow";
76 for (auto &policy : policies) {
77 if (policy == "Deny") {
78 minimumPolicy = "Deny";
80 } else if (policy != minimumPolicy && policy == "Ask user") {
81 minimumPolicy = "Ask user";
87 Policy calculatePolicyForPrivacy(const std::string &appId, const Privacy &privacy) {
88 ALOGD("Calculating privacy " << privacy);
89 std::vector<Policy> privsPolicies;
90 auto privileges = PrivilegeInfo::getPrivacyPrivileges(privacy);
91 for (const auto &privilege : privileges) {
92 ALOGD("Calculating policy for privilege " << privilege);
94 std::string policyLevel = getPrivilegePolicy(appId, privilege);
96 if (policyLevel.empty()) {
97 ALOGE("Couldn't get policy level, skipping");
101 ALOGD("Fetched policy level : " << policyLevel);
102 privsPolicies.push_back(std::move(policyLevel));
104 return getMinimumPolicy(privsPolicies);
107 Policy getPrivilegePolicy(const std::string &appId, const Privilege &privilege) {
109 filter.setApp(appId);
110 filter.setUser(std::to_string(geteuid()));
111 filter.setPrivilege(privilege);
113 PolicyFetchRequest fetch(std::move(filter));
114 auto policies = fetch.fetchPolicy();
115 if (policies.size() == 0) {
116 ALOGD("No policy for given privilege " << privilege);
119 if (policies.size() > 1) {
120 ALOGW("Something went wrong, there should be no more than one policy for specific filter");
121 // FIXME : don't really know what to do with it. Lets ignore it for now.
124 return policies[0].getLevel();
127 Policy getPrivaciesPolicy(const std::string &appId, const std::vector<Privacy> &privacies) {
128 std::vector<Policy> policies;
129 for (auto &privacy : privacies) {
130 policies.push_back(calculatePolicyForPrivacy(appId, privacy));
132 return getMinimumPolicy(policies);
135 void identifyApp(const std::string &client, std::string &appId, std::string &pkgLabel)
137 char *pkgName = nullptr;
138 char *appName = nullptr;
140 int ret = security_manager_identify_app_from_cynara_client(client.c_str(), &pkgName, &appName);
141 std::unique_ptr<char, decltype(free)*> pkg_name_p(pkgName, free);
142 std::unique_ptr<char, decltype(free)*> app_name_p(appName, free);
143 throwOnSMError("security_manager_identify_app_from_cynara_client", ret);
146 ALOGE("Couldn't identify clients package id");
150 PkgInfo pkgInfo(pkgName, geteuid());
152 appId = pkgInfo.mainAppId();
154 pkgLabel = pkgInfo.pkgLabel();
157 Policy getPrivilegeMappedPolicy(const std::string &appId, const std::string &privilege) {
158 std::vector<Privacy> privacies = PrivilegeInfo::getPrivilegePrivaciesMapping(appId, privilege);
159 if (privacies.empty()) {
160 ALOGE("Privilege doesn't map to any privacy");
164 return getPrivaciesPolicy(appId, privacies);
167 std::string getOwnAppId()
169 char *pkgName = nullptr;
170 char *appName = nullptr;
172 int ret = security_manager_identify_app_from_pid(getpid(), &pkgName, &appName);
173 std::unique_ptr<char, decltype(free)*> pkg_name_p(pkgName, free);
174 std::unique_ptr<char, decltype(free)*> app_name_p(appName, free);
175 throwOnSMError("security_manager_identify_app_from_pid", ret);
177 PkgInfo pkgInfo(pkgName, geteuid());
179 return pkgInfo.mainAppId();
181 return std::string();
184 PolicyEntry::PolicyEntry() : m_entry(nullptr) {
185 throwOnSMError("security_manager_policy_entry_new",
186 security_manager_policy_entry_new(&m_entry));
189 PolicyEntry::PolicyEntry(PolicyEntry &&other) : m_entry(std::move(other.m_entry)) {
190 other.m_entry = nullptr;
193 PolicyEntry::~PolicyEntry() {
194 security_manager_policy_entry_free(m_entry);
197 void PolicyEntry::setApp(const std::string &appId) {
198 throwOnSMError("security_manager_policy_entry_set_application",
199 security_manager_policy_entry_set_application(m_entry, appId.c_str()));
202 std::string PolicyEntry::getAppId() {
204 throwOnSMNullptr("security_manager_policy_entry_get_application",
205 app = security_manager_policy_entry_get_application(m_entry));
209 void PolicyEntry::setUser(const std::string &user) {
210 throwOnSMError("security_manager_policy_entry_set_user",
211 security_manager_policy_entry_set_user(m_entry, user.c_str()));
214 std::string PolicyEntry::getUser() {
216 throwOnSMNullptr("security_manager_policy_entry_get_user",
217 user = security_manager_policy_entry_get_user(m_entry));
221 void PolicyEntry::setPrivilege(const std::string &privilege) {
222 throwOnSMError("security_manager_policy_entry_set_privilege",
223 security_manager_policy_entry_set_privilege(m_entry, privilege.c_str()));
226 std::string PolicyEntry::getPrivilege() {
227 const char *privilege;
228 throwOnSMNullptr("security_manager_policy_entry_get_privilege",
229 privilege = security_manager_policy_entry_get_privilege(m_entry));
233 void PolicyEntry::setLevel(const std::string &level) {
234 throwOnSMError("security_manager_policy_entry_admin_set_level",
235 security_manager_policy_entry_set_level(m_entry, level.c_str()));
238 std::string PolicyEntry::getLevel() {
240 throwOnSMNullptr("security_manager_policy_entry_get_level",
241 level = security_manager_policy_entry_get_level(m_entry));
242 ALOGD("Level : " << level);
247 PolicyRequest::PolicyRequest() {
248 throwOnSMError("security_manager_policy_update_req_new",
249 security_manager_policy_update_req_new(&m_req));
252 PolicyRequest::~PolicyRequest() {
254 security_manager_policy_update_req_free(m_req);
257 void PolicyRequest::addEntry(PolicyEntry &&entry) {
258 throwOnSMError("security_manager_policy_update_req_add_entry",
259 security_manager_policy_update_req_add_entry(m_req, entry.get()));
260 m_entries.emplace_back(std::move(entry));
263 void PolicyRequest::updatePolicy() {
264 throwOnSMError("security_manager_policy_update_send",
265 security_manager_policy_update_send(m_req));
269 std::vector<PolicyEntryCopy> PolicyFetchRequest::fetchPolicy() {
270 policy_entry **pp_entries;
272 throwOnSMError("security_manager_get_configured_policy_for_self",
273 security_manager_get_configured_policy_for_self(m_filter.get(), &pp_entries, &p_size));
274 std::unique_ptr<policy_entry *, std::function<void(policy_entry **)>> ppPtr(pp_entries,
275 [p_size](policy_entry **p) {
276 security_manager_policy_entries_free(p, p_size);
279 std::vector<PolicyEntryCopy> entries;
280 for (size_t i = 0; i < p_size; i++) {
281 entries.emplace_back(PolicyEntryCopy(pp_entries[i]));
286 } /* namespace AskUser */