1 // Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by a apache 2.0 license that can be
3 // found in the LICENSE file.
5 #include "common/step/security/step_privacy_privilege.h"
7 #include <boost/scope_exit.hpp>
12 #include "common/privileges.h"
13 #include "common/utils/glist_range.h"
15 namespace ci = common_installer;
19 std::string GetAPIVersion(manifest_x* m, bool is_web) {
20 std::string api_version;
21 for (auto& app : GListRange<application_x*>(m->application)) {
22 if ((is_web && strcmp(app->type, "webapp") != 0) ||
23 (!is_web && strcmp(app->type, "webapp") == 0))
25 api_version = app->api_version;
33 namespace common_installer {
36 GList* StepPrivacyPrivilege::GetPrivilege(
37 GList* privileges, privilege_manager_package_type_e type) {
38 GList* privilege = NULL;
39 if (type == PRVMGR_PACKAGE_TYPE_CORE)
40 privilege = ci::PrivilegeXToPrivilege(privileges,
41 ci::kNativePrivilegeType);
43 privilege = ci::PrivilegeXToPrivilege(privileges,
44 ci::kWebPrivilegeType);
49 bool StepPrivacyPrivilege::SetPrivacyPrivilege(
50 const uid_t uid, const char* pkgid,
51 manifest_x* manifest, GList* privileges) {
53 std::map<privilege_manager_package_type_e, std::string> pType = {
54 {PRVMGR_PACKAGE_TYPE_CORE, GetAPIVersion(manifest, false)},
55 {PRVMGR_PACKAGE_TYPE_WRT, GetAPIVersion(manifest, true)}
58 for (auto& type : pType) {
59 GList *privilege = GetPrivilege(privileges, type.first);
61 int ret = privilege_package_info_set_privacy_privilege(uid, pkgid,
62 type.first, type.second.c_str(), privilege);
63 if (ret != PRVMGR_ERR_NONE) {
64 LOG(ERROR) << "Failed to set privacy_privilege";
65 g_list_free_full(privilege, free);
68 g_list_free_full(privilege, free);
75 Step::Status StepPrivacyPrivilege::precheck() {
76 if (!context_->manifest_data.get()) {
77 LOG(ERROR) << "manifest_data attribute is empty";
78 return Step::Status::INVALID_VALUE;
81 if (context_->pkg_type.get().empty()) {
82 LOG(ERROR) << "pkg_type attribute is empty";
83 return Step::Status::INVALID_VALUE;
86 if (context_->pkgid.get().empty()) {
87 LOG(ERROR) << "pkgid attribute is empty";
88 return Step::Status::INVALID_VALUE;
91 return Step::Status::OK;
94 Step::Status StepPrivacyPrivilege::process() {
95 int ret = privilege_package_info_unset_package_privilege_info(
96 context_->uid.get(), context_->pkgid.get().c_str());
97 if (ret != PRVMGR_ERR_NONE) {
98 LOG(ERROR) << "Failed to unset privacy privilege";
99 return Status::SECURITY_ERROR;
102 if (type_ != ActionType::Uninstall) {
103 manifest_x* manifest = context_->manifest_data.get();
104 if (!SetPrivacyPrivilege(context_->uid.get(),
105 context_->pkgid.get().c_str(),
107 manifest->privileges)) {
108 LOG(ERROR) << "Failed undo privacy privilege";
109 return Step::Status::SECURITY_ERROR;
113 return Step::Status::OK;
116 Step::Status StepPrivacyPrivilege::undo() {
117 if (type_ == ActionType::Uninstall)
118 return Step::Status::OK;
120 int ret = privilege_package_info_unset_package_privilege_info(
121 context_->uid.get(), context_->pkgid.get().c_str());
122 if (ret != PRVMGR_ERR_NONE) {
123 LOG(ERROR) << "Failed to unset privacy privilege";
124 return Status::SECURITY_ERROR;
127 if (context_->old_manifest_data.get()) {
128 manifest_x* old_manifest = context_->old_manifest_data.get();
129 if (!SetPrivacyPrivilege(context_->uid.get(),
130 context_->pkgid.get().c_str(),
132 old_manifest->privileges)) {
133 LOG(ERROR) << "Failed undo privacy privilege";
134 return Step::Status::SECURITY_ERROR;
138 return Step::Status::OK;
141 } // namespace security
142 } // namespace common_installer