Fix installing privileges of hybrid package
[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 <boost/scope_exit.hpp>
8
9 #include <map>
10 #include <vector>
11
12 #include "common/privileges.h"
13 #include "common/utils/glist_range.h"
14
15 namespace ci = common_installer;
16
17 namespace {
18
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))
24       continue;
25     api_version = app->api_version;
26     break;
27   }
28   return api_version;
29 }
30
31 }  // namespace
32
33 namespace common_installer {
34 namespace security {
35
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);
42   else
43     privilege = ci::PrivilegeXToPrivilege(privileges,
44                                           ci::kWebPrivilegeType);
45
46   return privilege;
47 }
48
49 bool StepPrivacyPrivilege::SetPrivacyPrivilege(
50     const uid_t uid, const char* pkgid,
51     manifest_x* manifest, GList* privileges) {
52
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)}
56   };
57
58   for (auto& type : pType) {
59     GList *privilege = GetPrivilege(privileges, type.first);
60     if (privilege) {
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);
66         return false;
67       }
68       g_list_free_full(privilege, free);
69     }
70   }
71
72   return true;
73 }
74
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;
79   }
80
81   if (context_->pkg_type.get().empty()) {
82     LOG(ERROR) << "pkg_type attribute is empty";
83     return Step::Status::INVALID_VALUE;
84   }
85
86   if (context_->pkgid.get().empty()) {
87     LOG(ERROR) << "pkgid attribute is empty";
88     return Step::Status::INVALID_VALUE;
89   }
90
91   return Step::Status::OK;
92 }
93
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;
100   }
101
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(),
106                              manifest,
107                              manifest->privileges)) {
108       LOG(ERROR) << "Failed undo privacy privilege";
109       return Step::Status::SECURITY_ERROR;
110     }
111   }
112
113   return Step::Status::OK;
114 }
115
116 Step::Status StepPrivacyPrivilege::undo() {
117   if (type_ == ActionType::Uninstall)
118     return Step::Status::OK;
119
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;
125   }
126
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(),
131                              old_manifest,
132                              old_manifest->privileges)) {
133       LOG(ERROR) << "Failed undo privacy privilege";
134       return Step::Status::SECURITY_ERROR;
135     }
136   }
137
138   return Step::Status::OK;
139 }
140
141 }  // namespace security
142 }  // namespace common_installer