2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * @file task_smack.cpp
18 * @author Piotr Kozbial (p.kozbial@samsung.com)
20 * @brief Implementation file for installer task smack
23 #include <widget_install/task_smack.h>
24 #include <widget_install/widget_install_context.h>
25 #include <widget_install/widget_install_errors.h>
26 #include <widget_install/job_widget_install.h>
27 #include <dpl/wrt-dao-ro/common_dao_types.h>
28 #include <dpl/foreach.h>
29 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
30 #include <dpl/utils/bash_utils.h>
31 #include <vcore/Certificate.h>
32 #include <vcore/CryptoHash.h>
33 #ifdef WRT_SMACK_ENABLED
34 #include <privilege-control.h>
35 #include <sys/smack.h>
38 #include <installer_log.h>
39 #include <privilege-control.h>
41 using namespace WrtDB;
42 using namespace ValidationCore;
45 const int MAX_BUF_SIZE = 128;
46 void freeList(const char** list) {
47 for (int i = 0; list[i] != NULL; i++)
56 namespace WidgetInstall {
57 TaskSmack::TaskSmack(InstallerContext& context) :
58 DPL::TaskDecl<TaskSmack>(this),
62 AddStep(&TaskSmack::StartStep);
63 AddStep(&TaskSmack::StepSetInstall);
64 AddStep(&TaskSmack::StepSmackFolderLabeling);
65 AddStep(&TaskSmack::StepSmackPrivilege);
66 AddStep(&TaskSmack::StepAddLabelNPRuntime);
67 AddStep(&TaskSmack::EndStep);
69 AddAbortStep(&TaskSmack::StepAbortSmack);
72 void TaskSmack::StepSetInstall()
74 _D("----------------> SMACK: StepStartSetSmack()");
75 #ifdef WRT_SMACK_ENABLED
76 std::string pkg = DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
77 m_pkgId = (char*)calloc(1, pkg.length() + 1);
78 snprintf(m_pkgId, pkg.length() + 1, "%s", pkg.c_str());
80 if (m_context.widgetConfig.packagingType !=
81 WrtDB::PkgType::PKG_TYPE_HYBRID_WEB_APP)
83 if (PC_OPERATION_SUCCESS != perm_app_install(m_pkgId)) {
85 ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
86 "failure in creating smack rules file.");
92 void TaskSmack::StepSmackFolderLabeling()
94 _D("----------------> SMACK:\
95 Jobs::WidgetInstall::TaskSmack::SmackFolderLabelingStep()");
96 #ifdef WRT_SMACK_ENABLED
97 /* /opt/usr/apps/[pkgid] directory's label is "_" */
98 if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId,
99 m_context.locations->getPackageInstallationDir().c_str(),
100 APP_PATH_ANY_LABEL, "_")) {
101 _W("Add label to %s", m_context.locations->getPackageInstallationDir().c_str());
105 if (m_context.mode.installTime == InstallMode::InstallTime::PRELOAD &&
106 m_context.mode.extension != InstallMode::ExtensionType::DIR)
108 if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId,
109 m_context.locations->getUserDataRootDir().c_str(),
110 APP_PATH_ANY_LABEL, "_")) {
115 std::string resDir = m_context.locations->getPackageInstallationDir() +
118 if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId, resDir.c_str(),
120 _W("Add label to %s", resDir.c_str());
124 if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId,
125 m_context.locations->getPrivateStorageDir().c_str(),
127 _W("Add label to %s", m_context.locations->getPrivateStorageDir().c_str());
131 if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId,
132 m_context.locations->getPrivateTempStorageDir().c_str(),
135 _W("Add label to %s", m_context.locations->getPrivateTempStorageDir().c_str());
139 if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId,
140 m_context.locations->getBinaryDir().c_str(),
142 _W("Add label to %s", m_context.locations->getBinaryDir().c_str());
145 if(!setLabelForSharedDir(m_pkgId)) {
146 _W("Add label to shared directory");
151 /* TODO : set label at wrt-client */
155 void TaskSmack::StepSmackPrivilege()
157 _D("----------------> SMACK:\
158 Jobs::WidgetInstall::TaskSmack::SmackPrivilegeStep()");
159 #ifdef WRT_SMACK_ENABLED
161 std::string id = DPL::ToUTF8String(m_context.widgetConfig.tzAppid);
163 std::string id = DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
165 appId = (char*)calloc(1, id.length() + 1);
166 snprintf(appId, id.length() + 1, "%s", id.c_str());
168 WrtDB::ConfigParserData::PrivilegeList privileges =
169 m_context.widgetConfig.configInfo.privilegeList;
171 char** perm_list = new char*[privileges.size() + 1];
173 FOREACH(it, privileges) {
174 _D("Permission : %ls", it->name.c_str());
175 int length = DPL::ToUTF8String(it->name).length();
176 char *priv = new char[length + 1];
177 snprintf(priv, length + 1, "%s",
178 DPL::ToUTF8String(it->name).c_str());
179 perm_list[index++] = priv;
181 perm_list[index] = NULL;
183 if (PC_OPERATION_SUCCESS != perm_app_enable_permissions(appId, APP_TYPE_WGT,
184 const_cast<const char **>(perm_list), true)) {
185 _W("failure in contructing smack rules based on perm_list");
190 while (NULL != perm_list[index]) {
191 delete [] perm_list[index++];
195 m_context.job->UpdateProgress(
196 InstallerContext::INSTALL_SMACK_ENABLE,
197 "Widget SMACK Enabled");
201 void TaskSmack::StepAddLabelNPRuntime()
203 _D("----------------> SMACK:\
204 Jobs::WidgetInstall::TaskSmack::StepAddLabelNPRuntime()");
205 if (0 == access(m_context.locations->getNPPluginsDir().c_str(), F_OK)) {
206 if (PC_OPERATION_SUCCESS !=
207 perm_app_setup_path(DPL::ToUTF8String(m_context.widgetConfig.tzPkgid).c_str(),
208 m_context.locations->getNPPluginsExecFile().c_str(),
209 PERM_APP_PATH_NPRUNTIME)) {
210 _E("failed to set smack execute label to %s",
211 m_context.locations->getNPPluginsExecFile().c_str());
216 void TaskSmack::StepRevokeForUpdate()
218 _D("----------------> SMACK:\
219 Jobs::WidgetInstall::TaskSmack::StepRevokePrivilegeForUpdate()");
220 #ifdef WRT_SMACK_ENABLED
221 if (PC_OPERATION_SUCCESS != perm_app_revoke_permissions(m_pkgId)) {
222 _W("failure in revoking smack permissions");
227 void TaskSmack::StepAbortSmack()
229 _D("----------------> SMACK:\
230 Jobs::WidgetInstall::TaskSmack::StepAbortSmack()");
231 #ifdef WRT_SMACK_ENABLED
233 if (PC_OPERATION_SUCCESS != perm_app_revoke_permissions(m_pkgId)) {
234 _W("failure in revoking smack permissions");
237 if (PC_OPERATION_SUCCESS != perm_app_uninstall(m_pkgId)) {
238 _W("failure in removing smack rules file");
244 bool TaskSmack::setLabelForSharedDir(const char* pkgId)
246 /* /shared directory */
247 if (PC_OPERATION_SUCCESS != perm_app_setup_path(pkgId,
248 m_context.locations->getSharedRootDir().c_str(),
249 APP_PATH_ANY_LABEL, "_")) {
250 _W("Add label to %s", m_context.locations->getUserDataRootDir().c_str());
253 /* /shared/res directory */
254 if (PC_OPERATION_SUCCESS != perm_app_setup_path(pkgId,
255 m_context.locations->getSharedResourceDir().c_str(),
256 APP_PATH_ANY_LABEL, "_")) {
257 _W("Add label to %s", m_context.locations->getSharedResourceDir().c_str());
260 /* /shared/trusted directory */
261 CertificatePtr rootCert = m_context.widgetSecurity.getAuthorCertificatePtr();
262 if (rootCert.Get() != NULL) {
263 ValidationCore::Crypto::Hash::SHA1 sha1;
264 sha1.Append(rootCert->getDER());
266 std::string sha1String = sha1.ToBase64String();
267 size_t iPos = sha1String.find("/");
268 while(iPos < std::string::npos) {
269 sha1String.replace(iPos, 1, "#");
270 iPos = sha1String.find("/");
273 _D("sha1 label string : %s", sha1String.c_str());
275 if (PC_OPERATION_SUCCESS != perm_app_setup_path(pkgId,
276 m_context.locations->getSharedTrustedDir().c_str(),
277 APP_PATH_GROUP_RW, sha1String.c_str())) {
278 _W("Add label to %s", m_context.locations->getBinaryDir().c_str());
282 /* /shared/data directory */
283 if (PC_OPERATION_SUCCESS != perm_app_setup_path(pkgId,
284 m_context.locations->getSharedDataDir().c_str(),
285 APP_PATH_PUBLIC_RO)) {
286 _W("Add label to %s", m_context.locations->getSharedDataDir().c_str());
292 void TaskSmack::StartStep()
294 _D("--------- <TaskSmack> : START ----------");
295 if (PC_OPERATION_SUCCESS != perm_begin()) {
296 _E("Failed to smack transaction begin.");
297 ThrowMsg(Exceptions::SmackTransactionFailed, "Failed to smack transaction begin");
301 void TaskSmack::EndStep()
303 _D("--------- <TaskSmack> : END ----------");
304 if (PC_OPERATION_SUCCESS != perm_end()) {
305 _E("Failed to smack transaction end.");
306 ThrowMsg(Exceptions::SmackTransactionFailed, "Failed to smack transaction end");
309 } //namespace WidgetInstall