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>
39 using namespace WrtDB;
40 using namespace ValidationCore;
43 const int MAX_BUF_SIZE = 128;
44 void freeList(const char** list) {
45 for (int i = 0; list[i] != NULL; i++)
54 namespace WidgetInstall {
55 TaskSmack::TaskSmack(InstallerContext& context) :
56 DPL::TaskDecl<TaskSmack>(this),
59 AddStep(&TaskSmack::SmackFolderLabelingStep);
60 AddStep(&TaskSmack::SmackPrivilegeStep);
61 AddStep(&TaskSmack::SetEndofInstallation);
63 AddAbortStep(&TaskSmack::StepAbortSmack);
66 void TaskSmack::SmackFolderLabelingStep()
68 LogInfo("----------------> SMACK:\
69 Jobs::WidgetInstall::TaskSmack::SmackFolderLabelingStep()");
70 #ifdef WRT_SMACK_ENABLED
71 std::string pkg = DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
73 pkgId = (char*)calloc(1, pkg.length() + 1);
74 snprintf(pkgId, pkg.length() + 1, "%s", pkg.c_str());
76 if (m_context.widgetConfig.packagingType !=
77 WrtDB::PkgType::PKG_TYPE_HYBRID_WEB_APP)
79 if (PC_OPERATION_SUCCESS != app_install(pkgId)) {
81 ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
82 "failure in creating smack rules file.");
86 /* /opt/usr/apps/[pkgid] directory's label is "_" */
87 if (PC_OPERATION_SUCCESS != app_label_dir("_",
88 m_context.locations->getPackageInstallationDir().c_str())) {
90 ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
95 std::string resDir = m_context.locations->getPackageInstallationDir() +
97 if (PC_OPERATION_SUCCESS != app_label_dir(pkgId,
100 ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
101 "Add Label failure");
105 if (m_context.mode.installTime == InstallMode::InstallTime::PRELOAD)
107 if (PC_OPERATION_SUCCESS != app_label_dir("_",
108 m_context.locations->getUserDataRootDir().c_str())) {
110 ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
111 "Add Label failure");
116 if (PC_OPERATION_SUCCESS != app_label_dir(pkgId,
117 m_context.locations->getPrivateStorageDir().c_str())) {
119 ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
120 "Add Label failure");
124 if (PC_OPERATION_SUCCESS != app_label_dir(pkgId,
125 m_context.locations->getBinaryDir().c_str())) {
127 ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
128 "Add Label failure");
131 if(!setLabelForSharedDir(pkgId)) {
132 ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
133 "Add Label failure");
138 /* TODO : set label at wrt-client
140 std::string app = DPL::ToUTF8String(m_context.widgetConfig.tzAppid);
142 appId = (char*)calloc(1, app.length() + 1);
143 snprintf(appId, app.length() + 1, "%s", app.c_str());
145 if (0 != smack_lsetlabel(m_context.locations->getExecFile().c_str(),
146 appId, SMACK_LABEL_ACCESS)) {
149 ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
150 "Add ACESS Label for binary failure");
153 if (0 != smack_lsetlabel(m_context.locations->getExecFile().c_str(),
154 appId, SMACK_LABEL_EXEC)) {
157 ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
158 "Add EXEC Label for binary failure");
161 if (PC_OPERATION_SUCCESS != app_add_friend(pkgId, appId)) {
164 ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
165 "Add friend failure");
168 if (PC_OPERATION_SUCCESS != app_label_shared_dir(appId, pkgId,
169 m_context.locations->getBinaryDir().c_str())) {
172 ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
173 "Add Label failure");
179 void TaskSmack::SmackPrivilegeStep()
181 LogInfo("----------------> SMACK:\
182 Jobs::WidgetInstall::TaskSmack::SmackPrivilegeStep()");
183 #ifdef WRT_SMACK_ENABLED
185 std::string id = DPL::ToUTF8String(m_context.widgetConfig.tzAppid);
187 std::string id = DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
189 appId = (char*)calloc(1, id.length() + 1);
190 snprintf(appId, id.length() + 1, "%s", id.c_str());
192 WrtDB::ConfigParserData::PrivilegeList privileges =
193 m_context.widgetConfig.configInfo.privilegeList;
195 const char** perm_list = new const char*[privileges.size() + 1];
197 FOREACH(it, privileges) {
198 LogInfo("Permission : " << it->name);
199 int length = DPL::ToUTF8String(it->name).length();
200 char *priv = (char*) calloc(1, (sizeof(char) * length) + 1);
201 snprintf(priv, length + 1, "%s",
202 DPL::ToUTF8String(it->name).c_str());
203 perm_list[index++] = priv;
205 perm_list[index] = NULL;
207 if (PC_OPERATION_SUCCESS != app_enable_permissions(appId, APP_TYPE_WGT,
209 LogError("failure in contructing smack rules based on perm_list");
214 m_context.job->UpdateProgress(
215 InstallerContext::INSTALL_SMACK_ENABLE,
216 "Widget SMACK Enabled");
220 void TaskSmack::StepAbortSmack()
222 LogInfo("----------------> SMACK:\
223 Jobs::WidgetInstall::TaskSmack::StepAbortSmack()");
224 #ifdef WRT_SMACK_ENABLED
226 std::string id = DPL::ToUTF8String(m_context.widgetConfig.tzAppid);
227 std::string id = DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
229 appId = (char*)calloc(1, id.length() + 1);
230 snprintf(appId, id.length() + 1, "%s", id.c_str());
233 std::string pkg = DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
235 pkgId = (char*)calloc(1, pkg.length() + 1);
236 snprintf(pkgId, pkg.length() + 1, "%s", pkg.c_str());
238 if (PC_OPERATION_SUCCESS != app_revoke_permissions(pkgId)) {
239 LogError("failure in revoking smack permissions");
242 if (PC_OPERATION_SUCCESS != app_uninstall(pkgId)) {
243 LogError("failure in removing smack rules file");
249 void TaskSmack::SetEndofInstallation()
251 m_context.job->UpdateProgress(
252 InstallerContext::INSTALL_END,
256 bool TaskSmack::setLabelForSharedDir(const char* pkgId)
258 /* shared directory */
259 if (PC_OPERATION_SUCCESS != app_label_dir("*",
260 m_context.locations->getSharedRootDir().c_str())) {
264 /* shared/res directory */
265 if (PC_OPERATION_SUCCESS != app_label_dir("_",
266 m_context.locations->getSharedResourceDir().c_str())) {
270 /* shared/trusted directory */
271 CertificatePtr rootCert = m_context.wacSecurity.getAuthorCertificatePtr();
272 if (rootCert.Get() != NULL) {
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 LogDebug("sha1 label string : " << sha1String);
285 if (PC_OPERATION_SUCCESS != app_label_shared_dir(pkgId,
287 m_context.locations->getSharedTrustedDir().c_str())) {
292 /* shared/data directory */
293 std::string dataLabel = std::string(pkgId) + "_shareddata";
294 TizenPkgIdList pkgList = WidgetDAOReadOnly::getTizenPkgidList();
295 const char** pList = new (std::nothrow) const char*[pkgList.size() + 1];
298 FOREACH(app, pkgList) {
299 std::string id = DPL::ToUTF8String(*app);
300 char *pId = new char[id.size() + 1];
301 snprintf(pId, id.length() + 1, "%s", id.c_str());
302 pList[index++] = pId;
306 if (PC_OPERATION_SUCCESS != app_label_shared_dir(pkgId,
308 m_context.locations->getSharedDataDir().c_str())) {
312 if (PC_OPERATION_SUCCESS != add_shared_dir_readers(dataLabel.c_str(), pList)) {
316 if (PC_OPERATION_SUCCESS != app_label_shared_dir(pkgId,
318 m_context.locations->getSharedDataDir().c_str())) {
325 } //namespace WidgetInstall