Remove boost dependency
[platform/core/appfw/app-installers.git] / src / common / step / security / step_privacy_privilege.cc
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.
4
5 #include "common/step/security/step_privacy_privilege.h"
6
7 #include <map>
8 #include <string>
9 #include <vector>
10
11 #include "common/privileges.h"
12 #include "common/utils/glist_range.h"
13
14 namespace ci = common_installer;
15
16 namespace {
17
18 std::string GetAPIVersion(manifest_x* m, bool is_web) {
19   std::string api_version;
20   for (auto& app : GListRange<application_x*>(m->application)) {
21     if ((is_web && strcmp(app->type, "webapp") != 0) ||
22         (!is_web && strcmp(app->type, "webapp") == 0))
23       continue;
24     api_version = app->api_version;
25     break;
26   }
27   if (api_version.empty())
28     // fallback if api-version not found. In case of addon package,
29     // application does not included in package.
30     api_version = m->api_version;
31   return api_version;
32 }
33
34 }  // namespace
35
36 namespace common_installer {
37 namespace security {
38
39 GList* StepPrivacyPrivilege::GetPrivilege(
40     GList* privileges, privilege_manager_package_type_e type) {
41   GList* privilege = NULL;
42   if (type == PRVMGR_PACKAGE_TYPE_CORE)
43     privilege = ci::PrivilegeXToPrivilege(privileges,
44                                           ci::kNativePrivilegeType);
45   else
46     privilege = ci::PrivilegeXToPrivilege(privileges,
47                                           ci::kWebPrivilegeType);
48
49   return privilege;
50 }
51
52 bool StepPrivacyPrivilege::SetPrivacyPrivilege(
53     const uid_t uid, const char* pkgid,
54     manifest_x* manifest, GList* privileges) {
55
56   std::map<privilege_manager_package_type_e, std::string> pType = {
57     {PRVMGR_PACKAGE_TYPE_CORE, GetAPIVersion(manifest, false)},
58     {PRVMGR_PACKAGE_TYPE_WRT, GetAPIVersion(manifest, true)}
59   };
60
61   for (auto& type : pType) {
62     GList *privilege = GetPrivilege(privileges, type.first);
63     if (privilege) {
64       int ret = privilege_package_info_set_privacy_privilege(uid, pkgid,
65           type.first, type.second.c_str(), privilege);
66       if (ret != PRVMGR_ERR_NONE) {
67         LOG(ERROR) << "Failed to set privacy_privilege";
68         g_list_free_full(privilege, free);
69         return false;
70       }
71       g_list_free_full(privilege, free);
72     }
73   }
74
75   return true;
76 }
77
78 Step::Status StepPrivacyPrivilege::precheck() {
79   if (!context_->manifest_data.get()) {
80     LOG(ERROR) << "manifest_data attribute is empty";
81     return Step::Status::INVALID_VALUE;
82   }
83
84   if (context_->pkg_type.get().empty()) {
85     LOG(ERROR) << "pkg_type attribute is empty";
86     return Step::Status::INVALID_VALUE;
87   }
88
89   if (context_->pkgid.get().empty()) {
90     LOG(ERROR) << "pkgid attribute is empty";
91     return Step::Status::INVALID_VALUE;
92   }
93
94   return Step::Status::OK;
95 }
96
97 Step::Status StepPrivacyPrivilege::process() {
98   int ret = privilege_package_info_unset_package_privilege_info(
99       context_->uid.get(), context_->pkgid.get().c_str());
100   if (ret != PRVMGR_ERR_NONE) {
101     LOG(ERROR) << "Failed to unset privacy privilege";
102     return Status::SECURITY_ERROR;
103   }
104
105   if (type_ != ActionType::Uninstall) {
106     manifest_x* manifest = context_->manifest_data.get();
107     if (!SetPrivacyPrivilege(context_->uid.get(),
108                              context_->pkgid.get().c_str(),
109                              manifest,
110                              manifest->privileges)) {
111       LOG(ERROR) << "Failed undo privacy privilege";
112       return Step::Status::SECURITY_ERROR;
113     }
114   }
115
116   return Step::Status::OK;
117 }
118
119 Step::Status StepPrivacyPrivilege::undo() {
120   if (type_ == ActionType::Uninstall)
121     return Step::Status::OK;
122
123   int ret = privilege_package_info_unset_package_privilege_info(
124       context_->uid.get(), context_->pkgid.get().c_str());
125   if (ret != PRVMGR_ERR_NONE) {
126     LOG(ERROR) << "Failed to unset privacy privilege";
127     return Status::SECURITY_ERROR;
128   }
129
130   if (context_->old_manifest_data.get()) {
131     manifest_x* old_manifest = context_->old_manifest_data.get();
132     if (!SetPrivacyPrivilege(context_->uid.get(),
133                              context_->pkgid.get().c_str(),
134                              old_manifest,
135                              old_manifest->privileges)) {
136       LOG(ERROR) << "Failed undo privacy privilege";
137       return Step::Status::SECURITY_ERROR;
138     }
139   }
140
141   return Step::Status::OK;
142 }
143
144 }  // namespace security
145 }  // namespace common_installer