Initialize Tizen 2.3
[framework/web/wrt-installer.git] / src_mobile / jobs / widget_install / task_smack.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_smack.cpp
18  * @author  Piotr Kozbial (p.kozbial@samsung.com)
19  * @version 1.0
20  * @brief   Implementation file for installer task smack
21  */
22
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>
36 #endif
37 #include <sstream>
38 #include <installer_log.h>
39 #include <privilege-control.h>
40
41 using namespace WrtDB;
42 using namespace ValidationCore;
43
44 namespace {
45 const int MAX_BUF_SIZE = 128;
46 void freeList(const char** list) {
47     for (int i = 0; list[i] != NULL; i++)
48     {
49         delete(list[i]);
50     }
51     delete[] list;
52 }
53 }
54
55 namespace Jobs {
56 namespace WidgetInstall {
57 TaskSmack::TaskSmack(InstallerContext& context) :
58     DPL::TaskDecl<TaskSmack>(this),
59     m_context(context),
60     m_pkgId(NULL)
61 {
62     AddStep(&TaskSmack::StartStep);
63     AddStep(&TaskSmack::StepSetInstall);
64     AddStep(&TaskSmack::StepSmackFolderLabeling);
65     AddStep(&TaskSmack::StepSmackPrivilege);
66     AddStep(&TaskSmack::StepAddLabelNPRuntime);
67     AddStep(&TaskSmack::EndStep);
68
69     AddAbortStep(&TaskSmack::StepAbortSmack);
70 }
71
72 void TaskSmack::StepSetInstall()
73 {
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());
79
80     if (m_context.widgetConfig.packagingType !=
81             WrtDB::PkgType::PKG_TYPE_HYBRID_WEB_APP)
82     {
83             if (PC_OPERATION_SUCCESS != perm_app_install(m_pkgId)) {
84             free(m_pkgId);
85             ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
86                     "failure in creating smack rules file.");
87         }
88     }
89 #endif
90 }
91
92 void TaskSmack::StepSmackFolderLabeling()
93 {
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());
102     }
103
104     /* for prelaod */
105     if (m_context.mode.installTime == InstallMode::InstallTime::PRELOAD &&
106             m_context.mode.extension != InstallMode::ExtensionType::DIR)
107     {
108         if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId,
109                     m_context.locations->getUserDataRootDir().c_str(),
110                     APP_PATH_ANY_LABEL, "_")) {
111         }
112     }
113
114     /* res directory */
115     std::string resDir = m_context.locations->getPackageInstallationDir() +
116         "/res";
117
118     if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId, resDir.c_str(),
119                 APP_PATH_PRIVATE)) {
120         _W("Add label to %s", resDir.c_str());
121     }
122
123     /* data directory */
124     if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId,
125                 m_context.locations->getPrivateStorageDir().c_str(),
126                 APP_PATH_PRIVATE)) {
127         _W("Add label to %s", m_context.locations->getPrivateStorageDir().c_str());
128     }
129
130     /* tmp directory */
131     if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId,
132                 m_context.locations->getPrivateTempStorageDir().c_str(),
133                 APP_PATH_PRIVATE))
134     {
135         _W("Add label to %s", m_context.locations->getPrivateTempStorageDir().c_str());
136     }
137
138     /* bin directory */
139     if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId,
140                 m_context.locations->getBinaryDir().c_str(),
141                 APP_PATH_PRIVATE)) {
142         _W("Add label to %s", m_context.locations->getBinaryDir().c_str());
143     }
144
145     if(!setLabelForSharedDir(m_pkgId)) {
146         _W("Add label to shared directory");
147     }
148
149     free(m_pkgId);
150
151     /* TODO : set label at wrt-client */
152 #endif
153 }
154
155 void TaskSmack::StepSmackPrivilege()
156 {
157     _D("----------------> SMACK:\
158         Jobs::WidgetInstall::TaskSmack::SmackPrivilegeStep()");
159 #ifdef WRT_SMACK_ENABLED
160     /* TODO :
161     std::string id = DPL::ToUTF8String(m_context.widgetConfig.tzAppid);
162     */
163     std::string id = DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
164     char* appId = NULL;
165     appId = (char*)calloc(1, id.length() + 1);
166     snprintf(appId, id.length() + 1, "%s", id.c_str());
167
168     WrtDB::ConfigParserData::PrivilegeList privileges =
169         m_context.widgetConfig.configInfo.privilegeList;
170
171     char** perm_list = new char*[privileges.size() + 1];
172     int index = 0;
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;
180     }
181     perm_list[index] = NULL;
182
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");
186     }
187
188     free(appId);
189     index = 0;
190     while (NULL != perm_list[index]) {
191         delete [] perm_list[index++];
192     }
193     delete [] perm_list;
194
195     m_context.job->UpdateProgress(
196         InstallerContext::INSTALL_SMACK_ENABLE,
197         "Widget SMACK Enabled");
198 #endif
199 }
200
201 void TaskSmack::StepAddLabelNPRuntime()
202 {
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());
212         }
213     }
214 }
215
216 void TaskSmack::StepRevokeForUpdate()
217 {
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");
223     }
224 #endif
225 }
226
227 void TaskSmack::StepAbortSmack()
228 {
229     _D("----------------> SMACK:\
230             Jobs::WidgetInstall::TaskSmack::StepAbortSmack()");
231 #ifdef WRT_SMACK_ENABLED
232
233     if (PC_OPERATION_SUCCESS != perm_app_revoke_permissions(m_pkgId)) {
234         _W("failure in revoking smack permissions");
235     }
236
237     if (PC_OPERATION_SUCCESS != perm_app_uninstall(m_pkgId)) {
238         _W("failure in removing smack rules file");
239     }
240     free(m_pkgId);
241 #endif
242 }
243
244 bool TaskSmack::setLabelForSharedDir(const char* pkgId)
245 {
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());
251     }
252
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());
258     }
259
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());
265         sha1.Finish();
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("/");
271         }
272
273         _D("sha1 label string : %s", sha1String.c_str());
274
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());
279         }
280     }
281
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());
287     }
288
289     return true;
290 }
291
292 void TaskSmack::StartStep()
293 {
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");
298     }
299 }
300
301 void TaskSmack::EndStep()
302 {
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");
307     }
308 }
309 } //namespace WidgetInstall
310 } //namespace Jobs