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/global_config.h>
30 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
31 #include <dpl/utils/bash_utils.h>
32 #include <dpl/utils/path.h>
33 #include <vcore/Certificate.h>
34 #include <vcore/CryptoHash.h>
35 #include <vcore/SignatureFinder.h>
36 #include <privilege-control.h>
37 #include <sys/smack.h>
39 #include <installer_log.h>
40 #include <privilege-control.h>
42 using namespace WrtDB;
43 using namespace ValidationCore;
46 const int MAX_BUF_SIZE = 128;
47 void freeList(const char** list) {
48 for (int i = 0; list[i] != NULL; i++)
57 namespace WidgetInstall {
58 TaskSmack::TaskSmack(InstallerContext& context) :
59 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::StepLabelSignatureFiles);
68 AddStep(&TaskSmack::EndStep);
70 AddAbortStep(&TaskSmack::StepAbortSmack);
73 void TaskSmack::StepSetInstall()
75 _D("----------------> SMACK: StepStartSetSmack()");
77 m_pkgId = DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
79 if (PC_OPERATION_SUCCESS != perm_app_install(m_pkgId.c_str())) {
80 ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
81 "failure in creating smack rules file.");
85 void TaskSmack::StepSmackFolderLabeling()
87 _D("----------------> SMACK:\
88 Jobs::WidgetInstall::TaskSmack::SmackFolderLabelingStep()");
90 /* /opt/usr/apps/[pkgid] directory's label is "_" */
91 if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId.c_str(),
92 m_context.locations->getPackageInstallationDir().c_str(),
93 APP_PATH_ANY_LABEL, "_")) {
94 _W("Add label to %s", m_context.locations->getPackageInstallationDir().c_str());
98 if (m_context.mode.installTime == InstallMode::InstallTime::PRELOAD) {
99 if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId.c_str(),
100 m_context.locations->getUserDataRootDir().c_str(),
101 APP_PATH_ANY_LABEL, "_")) {
106 std::string resDir = m_context.locations->getPackageInstallationDir() +
109 if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId.c_str(), resDir.c_str(),
111 _W("Add label to %s", resDir.c_str());
115 if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId.c_str(),
116 m_context.locations->getPrivateStorageDir().c_str(),
118 _W("Add label to %s", m_context.locations->getPrivateStorageDir().c_str());
122 if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId.c_str(),
123 m_context.locations->getPrivateTempStorageDir().c_str(),
126 _W("Add label to %s", m_context.locations->getPrivateTempStorageDir().c_str());
130 if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId.c_str(),
131 m_context.locations->getBinaryDir().c_str(),
133 _W("Add label to %s", m_context.locations->getBinaryDir().c_str());
136 if(!setLabelForSharedDir(m_pkgId.c_str())) {
137 _W("Add label to shared directory");
140 /* TODO : set label at wrt-client */
143 void TaskSmack::StepSmackPrivilege()
145 _D("----------------> SMACK:\
146 Jobs::WidgetInstall::TaskSmack::SmackPrivilegeStep()");
148 std::string id = DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
150 appId = (char*)calloc(1, id.length() + 1);
151 snprintf(appId, id.length() + 1, "%s", id.c_str());
153 WrtDB::ConfigParserData::PrivilegeList privileges =
154 m_context.widgetConfig.configInfo.privilegeList;
156 char** perm_list = new char*[privileges.size() + 1];
158 FOREACH(it, privileges) {
159 _D("Permission : %ls", it->name.c_str());
160 int length = DPL::ToUTF8String(it->name).length();
161 char *priv = new char[length + 1];
162 snprintf(priv, length + 1, "%s",
163 DPL::ToUTF8String(it->name).c_str());
164 perm_list[index++] = priv;
166 perm_list[index] = NULL;
168 if (PC_OPERATION_SUCCESS != perm_app_enable_permissions(appId, APP_TYPE_WGT,
169 const_cast<const char **>(perm_list), true)) {
170 _W("failure in contructing smack rules based on perm_list");
175 while (NULL != perm_list[index]) {
176 delete [] perm_list[index++];
180 m_context.job->UpdateProgress(
181 InstallerContext::INSTALL_SMACK_ENABLE,
182 "Widget SMACK Enabled");
185 void TaskSmack::StepAddLabelNPRuntime()
187 _D("----------------> SMACK:\
188 Jobs::WidgetInstall::TaskSmack::StepAddLabelNPRuntime()");
190 if (0 == access(m_context.locations->getNPPluginsDir().c_str(), F_OK)) {
191 if (PC_OPERATION_SUCCESS !=
192 perm_app_setup_path(DPL::ToUTF8String(m_context.widgetConfig.tzPkgid).c_str(),
193 m_context.locations->getNPPluginsExecFile().c_str(),
194 PERM_APP_PATH_NPRUNTIME)) {
195 _E("failed to set smack execute label to %s",
196 m_context.locations->getNPPluginsExecFile().c_str());
202 void TaskSmack::StepLabelSignatureFiles()
204 _D("----------------> SMACK:\
205 Jobs::WidgetInstall::TaskSmack::StepLabelSignatureFiles()");
207 DPL::Utils::Path widgetPath{
208 m_context.locations->getPackageInstallationDir()};
209 widgetPath /= WrtDB::GlobalConfig::GetWidgetSrcPath();
211 SignatureFileInfoSet signatureFiles;
212 SignatureFinder signatureFinder(widgetPath.Fullpath());
213 if (SignatureFinder::NO_ERROR != signatureFinder.find(signatureFiles)) {
214 ThrowMsg(Exceptions::SignatureNotFound,
215 "Error while discovering signature files.");
218 for (auto it = signatureFiles.cbegin(); it != signatureFiles.cend(); ++it) {
219 auto sigPath = widgetPath / it->getFileName();
221 _D("Setting label to %s", sigPath.Fullpath().c_str());
222 if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId.c_str(),
223 sigPath.Fullpath().c_str(),
224 APP_PATH_ANY_LABEL, "_")) {
225 _W("Failed to set label to %s", sigPath.Fullpath().c_str());
230 void TaskSmack::StepRevokeForUpdate()
232 _D("----------------> SMACK:\
233 Jobs::WidgetInstall::TaskSmack::StepRevokePrivilegeForUpdate()");
235 if (PC_OPERATION_SUCCESS != perm_app_revoke_permissions(m_pkgId.c_str())) {
236 _W("failure in revoking smack permissions");
240 void TaskSmack::StepAbortSmack()
242 _D("----------------> SMACK:\
243 Jobs::WidgetInstall::TaskSmack::StepAbortSmack()");
245 if (PC_OPERATION_SUCCESS != perm_app_revoke_permissions(m_pkgId.c_str())) {
246 _W("failure in revoking smack permissions");
249 if (PC_OPERATION_SUCCESS != perm_app_uninstall(m_pkgId.c_str())) {
250 _W("failure in removing smack rules file");
254 bool TaskSmack::setLabelForSharedDir(const char* pkgId)
256 /* /shared directory */
257 if (PC_OPERATION_SUCCESS != perm_app_setup_path(pkgId,
258 m_context.locations->getSharedRootDir().c_str(),
259 APP_PATH_ANY_LABEL, "_")) {
260 _W("Add label to %s", m_context.locations->getUserDataRootDir().c_str());
263 /* /shared/res directory */
264 if (PC_OPERATION_SUCCESS != perm_app_setup_path(pkgId,
265 m_context.locations->getSharedResourceDir().c_str(),
266 APP_PATH_ANY_LABEL, "_")) {
267 _W("Add label to %s", m_context.locations->getSharedResourceDir().c_str());
270 /* /shared/trusted directory */
271 CertificatePtr rootCert = m_context.widgetSecurity.getAuthorCertificatePtr();
273 ValidationCore::Crypto::Hash::SHA1 sha1;
274 sha1.Append(rootCert->getDER());
276 std::string sha1String = sha1.ToBase64String();
277 size_t iPos = sha1String.find("/");
278 while(iPos < std::string::npos) {
279 sha1String.replace(iPos, 1, "#");
280 iPos = sha1String.find("/");
283 _D("sha1 label string : %s", sha1String.c_str());
285 if (PC_OPERATION_SUCCESS != perm_app_setup_path(pkgId,
286 m_context.locations->getSharedTrustedDir().c_str(),
287 APP_PATH_GROUP_RW, sha1String.c_str())) {
288 _W("Add label to %s", m_context.locations->getBinaryDir().c_str());
292 /* /shared/data directory */
293 if (PC_OPERATION_SUCCESS != perm_app_setup_path(pkgId,
294 m_context.locations->getSharedDataDir().c_str(),
295 APP_PATH_PUBLIC_RO)) {
296 _W("Add label to %s", m_context.locations->getSharedDataDir().c_str());
302 void TaskSmack::StartStep()
304 LOGD("--------- <TaskSmack> : START ----------");
305 if (PC_OPERATION_SUCCESS != perm_begin()) {
306 LOGE("Failed to smack transaction begin.");
307 ThrowMsg(Exceptions::SmackTransactionFailed, "Failed to smack transaction begin");
311 void TaskSmack::EndStep()
313 LOGD("--------- <TaskSmack> : END ----------");
314 if (PC_OPERATION_SUCCESS != perm_end()) {
315 LOGE("Failed to smack transaction end.");
316 ThrowMsg(Exceptions::SmackTransactionFailed, "Failed to smack transaction end");
319 } //namespace WidgetInstall