b3d7e4afef054a7238dabfde9fc8d27accffec6a
[platform/framework/web/wrt-installer.git] / src / 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/log/log.h>
30 #include <dpl/foreach.h>
31
32 #include <widget_install/widget_install_context.h>
33 #include <widget_install/widget_install_errors.h>
34 #include <widget_install/job_widget_install.h>
35
36 #include <dpl/wrt-dao-rw/widget_dao.h>
37 #include <ace_api_install.h>
38
39 namespace Jobs {
40 namespace WidgetInstall {
41 TaskAceCheck::TaskAceCheck(InstallerContext& context) :
42     DPL::TaskDecl<TaskAceCheck>(this),
43     m_context(context)
44 {
45     AddStep(&TaskAceCheck::StepPrepareForAce);
46     AddStep(&TaskAceCheck::StepAceCheck);
47     AddStep(&TaskAceCheck::StepProcessAceResponse);
48     AddStep(&TaskAceCheck::StepCheckAceResponse);
49 }
50
51 void TaskAceCheck::StepPrepareForAce()
52 {
53     m_context.featureLogic =
54         FeatureLogicPtr(new FeatureLogic(m_context.widgetConfig.tzAppid));
55     m_context.job->UpdateProgress(
56         InstallerContext::INSTALL_ACE_PREPARE,
57         "Widget Access Control Check Prepared");
58 }
59
60 void TaskAceCheck::StepAceCheck()
61 {
62     WrtDB::WidgetDAO dao(m_context.widgetConfig.tzAppid);
63     LogInfo("StepAceCheck!");
64     // This widget does not use any device cap
65     if (m_context.featureLogic->isDone()) {
66         return;
67     }
68
69     LogInfo("StepAceCheck!");
70     DPL::String deviceCap = m_context.featureLogic->getDevice();
71
72     LogInfo("StepAceCheck!");
73     LogInfo("DevCap is : " << deviceCap);
74
75     std::string devCapStr = DPL::ToUTF8String(deviceCap);
76     ace_policy_result_t policyResult = ACE_DENY;
77
78     //TODO: remove dao.getHandle()
79     if (m_context.mode.installTime == InstallMode::InstallTime::PRELOAD) {
80         LogDebug("This widget is prealoaded. So ace check will be skiped");
81         policyResult = ACE_PERMIT;
82     } else {
83         ace_return_t ret = ace_get_policy_result(
84                 const_cast<const ace_resource_t>(devCapStr.c_str()),
85                 dao.getHandle(),
86                 &policyResult);
87         if (ACE_OK != ret) {
88             ThrowMsg(Exceptions::AceCheckFailed, "Instalation failure. "
89                     "ACE check failure");
90         }
91     }
92
93     LogInfo("PolicyResult is : " << static_cast<int>(policyResult));
94     m_context.staticPermittedDevCaps.insert(std::make_pair(deviceCap,
95                                                            policyResult ==
96                                                            ACE_PERMIT));
97
98     m_context.featureLogic->setAceResponse(policyResult != ACE_DENY);
99 }
100
101 void TaskAceCheck::StepProcessAceResponse()
102 {
103     WrtDB::WidgetDAO dao(m_context.widgetConfig.tzAppid);
104     if (m_context.widgetConfig.packagingType ==
105         WrtDB::PKG_TYPE_HOSTED_WEB_APP)
106     {
107         return;
108     }
109
110     LogInfo("StepProcessAceResponse");
111     m_context.featureLogic->next();
112
113     // No device caps left to process
114     if (m_context.featureLogic->isDone()) {
115         LogInfo("All responses has been received from ACE.");
116         // Data to convert to C API
117         std::vector<std::string> devCaps;
118         std::vector<bool> devCapsSmack;
119         // Saving static dev cap permissions
120         FOREACH(cap, m_context.staticPermittedDevCaps) {
121             LogInfo("staticPermittedDevCaps : " << cap->first
122                                                 << " smack: " << cap->second);
123             std::string devCapStr = DPL::ToUTF8String(cap->first);
124             devCaps.push_back(devCapStr);
125             devCapsSmack.push_back(cap->second);
126         }
127         ace_requested_dev_cap_list_t list;
128         list.count = devCaps.size();
129         list.items = new ace_requested_dev_cap_t[list.count];
130
131         for (unsigned int i = 0; i < devCaps.size(); ++i) {
132             list.items[i].device_capability =
133                 const_cast<const ace_resource_t>(devCaps[i].c_str());
134             list.items[i].smack_granted =
135                 devCapsSmack[i] ? ACE_TRUE : ACE_FALSE;
136         }
137         //TODO: remove dao.getHandle()
138         ace_return_t ret = ace_set_requested_dev_caps(dao.getHandle(),
139                                                       &list);
140         if (ACE_OK != ret) {
141             ThrowMsg(Exceptions::AceCheckFailed, "Instalation failure. "
142                                              "ACE failure");
143         }
144         delete[] list.items;
145
146         std::set<std::string> acceptedFeature;
147         auto it = m_context.featureLogic->resultBegin();
148         for (; it != m_context.featureLogic->resultEnd(); ++it) {
149             if (!(it->rejected)) {
150                 acceptedFeature.insert(DPL::ToUTF8String(it->name));
151             }
152         }
153         ace_feature_list_t featureList;
154         featureList.count = acceptedFeature.size();
155         featureList.items = new ace_string_t[featureList.count];
156
157         size_t i = 0;
158         for (std::set<std::string>::const_iterator iter = acceptedFeature.begin();
159              iter != acceptedFeature.end(); ++iter)
160         {
161             LogDebug("Accepted feature item: " << iter->c_str());
162             featureList.items[i] = const_cast<char *>(iter->c_str());
163             i++;
164         }
165
166         //TODO: remove dao.getHandle()
167         ret = ace_set_accepted_feature(dao.getHandle(), &featureList);
168
169         delete[] featureList.items;
170
171         if (ACE_OK != ret) {
172             LogError("Error in ace_set_feature");
173             ThrowMsg(Exceptions::AceCheckFailed, "Instalation failure. "
174                                              "ace_set_feature failure.");
175         }
176         return;
177     }
178
179     LogInfo("Next device cap.");
180     // Process next device cap
181     SwitchToStep(&TaskAceCheck::StepAceCheck);
182 }
183
184 void TaskAceCheck::StepCheckAceResponse()
185 {
186     LogInfo("Checking ACE response");
187     if (m_context.featureLogic->isRejected()) {
188         LogError("Installation failure. Some devCap was not accepted by ACE.");
189         ThrowMsg(
190             Exceptions::PrivilegeLevelViolation,
191             "Instalation failure. "
192             "Some deviceCap was not accepted by ACE.");
193     }
194     LogInfo("Updating \"feature reject status\" in database!");
195     auto it = m_context.featureLogic->resultBegin();
196     auto end = m_context.featureLogic->resultEnd();
197     for (; it != end; ++it) {
198         LogInfo(
199             "  |-  Feature: " << it->name << " has reject status: " <<
200             it->rejected);
201         if (it->rejected) {
202             WrtDB::WidgetDAO dao(m_context.widgetConfig.tzAppid);
203             dao.updateFeatureRejectStatus(*it);
204         }
205     }
206     LogInfo("Installation continues...");
207
208     m_context.job->UpdateProgress(
209         InstallerContext::INSTALL_ACE_CHECK,
210         "Widget Access Control Check Finished");
211 }
212 } //namespace WidgetInstall
213 } //namespace Jobs