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::EndStep);
68 AddAbortStep(&TaskSmack::StepAbortSmack);
71 void TaskSmack::StepSetInstall()
73 _D("----------------> SMACK: StepStartSetSmack()");
74 #ifdef WRT_SMACK_ENABLED
75 std::string pkg = DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
76 m_pkgId = (char*)calloc(1, pkg.length() + 1);
77 snprintf(m_pkgId, pkg.length() + 1, "%s", pkg.c_str());
79 if (m_context.widgetConfig.packagingType !=
80 WrtDB::PkgType::PKG_TYPE_HYBRID_WEB_APP)
82 if (PC_OPERATION_SUCCESS != perm_app_install(m_pkgId)) {
84 ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
85 "failure in creating smack rules file.");
91 void TaskSmack::StepSmackFolderLabeling()
93 _D("----------------> SMACK:\
94 Jobs::WidgetInstall::TaskSmack::SmackFolderLabelingStep()");
95 #ifdef WRT_SMACK_ENABLED
96 /* /opt/usr/apps/[pkgid] directory's label is "_" */
97 if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId,
98 m_context.locations->getPackageInstallationDir().c_str(),
99 APP_PATH_ANY_LABEL, "_")) {
100 _W("Add label to %s", m_context.locations->getPackageInstallationDir().c_str());
104 if (m_context.mode.installTime == InstallMode::InstallTime::PRELOAD &&
105 m_context.mode.extension != InstallMode::ExtensionType::DIR)
107 if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId,
108 m_context.locations->getUserDataRootDir().c_str(),
109 APP_PATH_ANY_LABEL, "_")) {
114 std::string resDir = m_context.locations->getPackageInstallationDir() +
117 if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId, resDir.c_str(),
119 _W("Add label to %s", resDir.c_str());
123 if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId,
124 m_context.locations->getPrivateStorageDir().c_str(),
126 _W("Add label to %s", m_context.locations->getPrivateStorageDir().c_str());
130 if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId,
131 m_context.locations->getPrivateTempStorageDir().c_str(),
134 _W("Add label to %s", m_context.locations->getPrivateTempStorageDir().c_str());
138 if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId,
139 m_context.locations->getBinaryDir().c_str(),
141 _W("Add label to %s", m_context.locations->getBinaryDir().c_str());
144 if(!setLabelForSharedDir(m_pkgId)) {
145 _W("Add label to shared directory");
150 /* TODO : set label at wrt-client */
154 void TaskSmack::StepSmackPrivilege()
156 _D("----------------> SMACK:\
157 Jobs::WidgetInstall::TaskSmack::SmackPrivilegeStep()");
158 #ifdef WRT_SMACK_ENABLED
160 std::string id = DPL::ToUTF8String(m_context.widgetConfig.tzAppid);
162 std::string id = DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
164 appId = (char*)calloc(1, id.length() + 1);
165 snprintf(appId, id.length() + 1, "%s", id.c_str());
167 WrtDB::ConfigParserData::PrivilegeList privileges =
168 m_context.widgetConfig.configInfo.privilegeList;
170 char** perm_list = new char*[privileges.size() + 1];
172 FOREACH(it, privileges) {
173 _D("Permission : %ls", it->name.c_str());
174 int length = DPL::ToUTF8String(it->name).length();
175 char *priv = new char[length + 1];
176 snprintf(priv, length + 1, "%s",
177 DPL::ToUTF8String(it->name).c_str());
178 perm_list[index++] = priv;
180 perm_list[index] = NULL;
182 if (PC_OPERATION_SUCCESS != perm_app_enable_permissions(appId, APP_TYPE_WGT,
183 const_cast<const char **>(perm_list), true)) {
184 _W("failure in contructing smack rules based on perm_list");
189 while (NULL != perm_list[index]) {
190 delete [] perm_list[index++];
194 m_context.job->UpdateProgress(
195 InstallerContext::INSTALL_SMACK_ENABLE,
196 "Widget SMACK Enabled");
200 void TaskSmack::StepRevokeForUpdate()
202 _D("----------------> SMACK:\
203 Jobs::WidgetInstall::TaskSmack::StepRevokePrivilegeForUpdate()");
204 #ifdef WRT_SMACK_ENABLED
205 if (PC_OPERATION_SUCCESS != perm_app_revoke_permissions(m_pkgId)) {
206 _W("failure in revoking smack permissions");
211 void TaskSmack::StepAbortSmack()
213 _D("----------------> SMACK:\
214 Jobs::WidgetInstall::TaskSmack::StepAbortSmack()");
215 #ifdef WRT_SMACK_ENABLED
217 if (PC_OPERATION_SUCCESS != perm_app_revoke_permissions(m_pkgId)) {
218 _W("failure in revoking smack permissions");
221 if (PC_OPERATION_SUCCESS != perm_app_uninstall(m_pkgId)) {
222 _W("failure in removing smack rules file");
228 bool TaskSmack::setLabelForSharedDir(const char* pkgId)
230 /* /shared directory */
231 if (PC_OPERATION_SUCCESS != perm_app_setup_path(pkgId,
232 m_context.locations->getSharedRootDir().c_str(),
233 APP_PATH_ANY_LABEL, "_")) {
234 _W("Add label to %s", m_context.locations->getUserDataRootDir().c_str());
237 /* /shared/res directory */
238 if (PC_OPERATION_SUCCESS != perm_app_setup_path(pkgId,
239 m_context.locations->getSharedResourceDir().c_str(),
240 APP_PATH_ANY_LABEL, "_")) {
241 _W("Add label to %s", m_context.locations->getSharedResourceDir().c_str());
244 /* /shared/trusted directory */
245 CertificatePtr rootCert = m_context.widgetSecurity.getAuthorCertificatePtr();
246 if (rootCert.Get() != NULL) {
247 ValidationCore::Crypto::Hash::SHA1 sha1;
248 sha1.Append(rootCert->getDER());
250 std::string sha1String = sha1.ToBase64String();
251 size_t iPos = sha1String.find("/");
252 while(iPos < std::string::npos) {
253 sha1String.replace(iPos, 1, "#");
254 iPos = sha1String.find("/");
257 _D("sha1 label string : %s", sha1String.c_str());
259 if (PC_OPERATION_SUCCESS != perm_app_setup_path(pkgId,
260 m_context.locations->getSharedTrustedDir().c_str(),
261 APP_PATH_GROUP_RW, sha1String.c_str())) {
262 _W("Add label to %s", m_context.locations->getBinaryDir().c_str());
266 /* /shared/data directory */
267 if (PC_OPERATION_SUCCESS != perm_app_setup_path(pkgId,
268 m_context.locations->getSharedDataDir().c_str(),
269 APP_PATH_PUBLIC_RO)) {
270 _W("Add label to %s", m_context.locations->getSharedDataDir().c_str());
276 void TaskSmack::StartStep()
278 _D("--------- <TaskSmack> : START ----------");
279 if (PC_OPERATION_SUCCESS != perm_begin()) {
280 _E("Failed to smack transaction begin.");
281 ThrowMsg(Exceptions::SmackTransactionFailed, "Failed to smack transaction begin");
285 void TaskSmack::EndStep()
287 _D("--------- <TaskSmack> : END ----------");
288 if (PC_OPERATION_SUCCESS != perm_end()) {
289 _E("Failed to smack transaction end.");
290 ThrowMsg(Exceptions::SmackTransactionFailed, "Failed to smack transaction end");
293 } //namespace WidgetInstall