7285492ce13528314cdf4cad86d81dae4a3fec0a
[framework/web/wrt-installer.git] / src_wearable / jobs / widget_install / task_ace_check.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 /*
17  * @file    task_ace_check.cpp
18  * @author  Pawel Sikorski (p.sikorski@samsung.com)
19  * @version 1.0
20  * @brief   Implementation file for installer task ace check
21  */
22
23 #include <utility>
24 #include <vector>
25 #include <string>
26
27 #include <widget_install/task_ace_check.h>
28 #include <dpl/assert.h>
29 #include <dpl/foreach.h>
30
31 #include <widget_install/widget_install_context.h>
32 #include <widget_install/widget_install_errors.h>
33 #include <widget_install/job_widget_install.h>
34
35 #include <dpl/wrt-dao-rw/widget_dao.h>
36 #include <ace_api_install.h>
37
38 #include <installer_log.h>
39
40 namespace Jobs {
41 namespace WidgetInstall {
42 TaskAceCheck::TaskAceCheck(InstallerContext& context) :
43     DPL::TaskDecl<TaskAceCheck>(this),
44     m_context(context)
45 {
46     AddStep(&TaskAceCheck::StartStep);
47     AddStep(&TaskAceCheck::StepPrepareForAce);
48     AddStep(&TaskAceCheck::StepAceCheck);
49     AddStep(&TaskAceCheck::StepProcessAceResponse);
50     AddStep(&TaskAceCheck::StepCheckAceResponse);
51     AddStep(&TaskAceCheck::EndStep);
52 }
53
54 void TaskAceCheck::StepPrepareForAce()
55 {
56     m_context.featureLogic =
57         FeatureLogicPtr(new FeatureLogic(m_context.widgetConfig.tzAppid));
58     m_context.job->UpdateProgress(
59         InstallerContext::INSTALL_ACE_PREPARE,
60         "Widget Access Control Check Prepared");
61 }
62
63 void TaskAceCheck::StepAceCheck()
64 {
65     WrtDB::WidgetDAO dao(m_context.widgetConfig.tzAppid);
66     _D("StepAceCheck!");
67     // This widget does not use any device cap
68     if (m_context.featureLogic->isDone()) {
69         return;
70     }
71
72     _D("StepAceCheck!");
73     DPL::String deviceCap = m_context.featureLogic->getDevice();
74
75     _D("StepAceCheck!");
76     _D("DevCap is : %ls", deviceCap.c_str());
77
78     std::string devCapStr = DPL::ToUTF8String(deviceCap);
79     ace_policy_result_t policyResult = ACE_DENY;
80
81     if (m_context.mode.installTime == InstallMode::InstallTime::PRELOAD) {
82         _D("This widget is preloaded. So ace check will be skiped");
83         policyResult = ACE_PERMIT;
84     } else {
85         ace_return_t ret = ace_get_policy_result(
86                 const_cast<const ace_resource_t>(devCapStr.c_str()),
87                 dao.getHandle(),
88                 &policyResult);
89         if (ACE_OK != ret) {
90             ThrowMsg(Exceptions::AceCheckFailed, "Instalation failure. "
91                     "ACE check failure");
92         }
93     }
94
95     _D("PolicyResult is : %d", static_cast<int>(policyResult));
96     m_context.staticPermittedDevCaps.insert(std::make_pair(deviceCap,
97                                                            policyResult ==
98                                                            ACE_PERMIT));
99
100     m_context.featureLogic->setAceResponse(policyResult != ACE_DENY);
101 }
102
103 void TaskAceCheck::StepProcessAceResponse()
104 {
105     if (m_context.widgetConfig.packagingType ==
106         WrtDB::PKG_TYPE_HOSTED_WEB_APP)
107     {
108         return;
109     }
110
111     _D("StepProcessAceResponse");
112     m_context.featureLogic->next();
113
114     // No device caps left to process
115     if (m_context.featureLogic->isDone()) {
116         WrtDB::WidgetDAO dao(m_context.widgetConfig.tzAppid);
117 #ifdef SERVICE_ENABLED
118         std::list<WrtDB::DbWidgetHandle> serviceList;
119         FOREACH(it , m_context.widgetConfig.configInfo.serviceAppInfoList){
120              WrtDB::WidgetDAO serviceDao(it->serviceId);
121              serviceList.push_back(serviceDao.getHandle());
122         }
123 #endif
124         _D("All responses has been received from ACE.");
125         // Data to convert to C API
126         std::vector<std::string> devCaps;
127         std::vector<bool> devCapsSmack;
128         // Saving static dev cap permissions
129         FOREACH(cap, m_context.staticPermittedDevCaps) {
130             _D("staticPermittedDevCaps : %ls smack: %d", cap->first.c_str(), cap->second);
131             std::string devCapStr = DPL::ToUTF8String(cap->first);
132             devCaps.push_back(devCapStr);
133             devCapsSmack.push_back(cap->second);
134         }
135         ace_requested_dev_cap_list_t list;
136         list.count = devCaps.size();
137         list.items = new ace_requested_dev_cap_t[list.count];
138
139         for (unsigned int i = 0; i < devCaps.size(); ++i) {
140             list.items[i].device_capability =
141                 const_cast<const ace_resource_t>(devCaps[i].c_str());
142             list.items[i].smack_granted =
143                 devCapsSmack[i] ? ACE_TRUE : ACE_FALSE;
144         }
145         //TODO: remove dao.getHandle()
146         int ret = ace_set_requested_dev_caps(dao.getHandle(), &list);
147 #ifdef SERVICE_ENABLED
148         FOREACH(it, serviceList){
149             ret |= ace_set_requested_dev_caps(*it, &list);
150         }
151 #endif
152         delete[] list.items;
153
154         if (ACE_OK != static_cast<ace_return_t>(ret)) {
155             ThrowMsg(Exceptions::AceCheckFailed, "Instalation failure. "
156                                              "ACE failure");
157         }
158
159         std::set<std::string> acceptedFeature;
160         auto it = m_context.featureLogic->resultBegin();
161         for (; it != m_context.featureLogic->resultEnd(); ++it) {
162             if (!(it->rejected)) {
163                 acceptedFeature.insert(DPL::ToUTF8String(it->name));
164             }
165         }
166         ace_feature_list_t featureList;
167         featureList.count = acceptedFeature.size();
168         featureList.items = new ace_string_t[featureList.count];
169
170         size_t i = 0;
171         for (std::set<std::string>::const_iterator iter = acceptedFeature.begin();
172              iter != acceptedFeature.end(); ++iter)
173         {
174             _D("Accepted feature item: %s", iter->c_str());
175             featureList.items[i] = const_cast<char *>(iter->c_str());
176             i++;
177         }
178
179         //TODO: remove dao.getHandle()
180         ret = ace_set_accepted_feature(dao.getHandle(), &featureList);
181 #ifdef SERVICE_ENABLED
182         FOREACH(it, serviceList){
183             ret |= ace_set_accepted_feature(*it, &featureList);
184         }
185 #endif
186         delete[] featureList.items;
187
188         if (ACE_OK != static_cast<ace_return_t>(ret)) {
189             _E("Error in ace_set_feature");
190             ThrowMsg(Exceptions::AceCheckFailed, "Instalation failure. "
191                                              "ace_set_feature failure.");
192         }
193         return;
194     }
195
196     _D("Next device cap.");
197     // Process next device cap
198     SwitchToStep(&TaskAceCheck::StepAceCheck);
199 }
200
201 void TaskAceCheck::StepCheckAceResponse()
202 {
203     _D("Checking ACE response");
204     if (m_context.featureLogic->isRejected()) {
205         _E("Installation failure. Some devCap was not accepted by ACE.");
206         ThrowMsg(
207             Exceptions::PrivilegeLevelViolation,
208             "Instalation failure. "
209             "Some deviceCap was not accepted by ACE.");
210     }
211     _D("Updating \"feature reject status\" in database!");
212     auto it = m_context.featureLogic->resultBegin();
213     auto end = m_context.featureLogic->resultEnd();
214     for (; it != end; ++it) {
215         _D("  |-  Feature: %ls has reject status: %d", it->name.c_str(), it->rejected);
216         if (it->rejected) {
217             WrtDB::WidgetDAO dao(m_context.widgetConfig.tzAppid);
218             dao.updateFeatureRejectStatus(*it);
219
220 #ifdef SERVICE_ENABLED
221             FOREACH( svcApp , m_context.widgetConfig.configInfo.serviceAppInfoList){
222                 WrtDB::WidgetDAO dao(svcApp->serviceId);
223                 dao.updateFeatureRejectStatus(*it);
224             }
225 #endif
226         }
227     }
228     _D("Installation continues...");
229 }
230
231 void TaskAceCheck::StartStep()
232 {
233     LOGD("--------- <TaskAceCheck> : START ----------");
234 }
235
236 void TaskAceCheck::EndStep()
237 {
238     m_context.job->UpdateProgress(
239         InstallerContext::INSTALL_ACE_CHECK,
240         "Widget Access Control Check Finished");
241
242     LOGD("--------- <TaskAceCheck> : END ----------");
243 }
244 } //namespace WidgetInstall
245 } //namespace Jobs