Fix the crash while installing of ServiceApp
[platform/framework/native/installer.git] / src / Manager / SmackManager.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 /**
18  * @file        SmackManager.cpp
19  * @brief       This is the implementation file for %SmackManager class.
20  */
21
22 #include <dlfcn.h>
23 #include <unique_ptr.h>
24
25 #include <FIoFile.h>
26 #include <FIoRegistry.h>
27 #include <FSecCryptoSha1Hash.h>
28 #include <FBase_StringConverter.h>
29
30 #include "SmackManager.h"
31 #include "InstallerDefs.h"
32 #include "InstallerUtil.h"
33
34 using namespace Tizen::App;
35 using namespace Tizen::Base;
36 using namespace Tizen::Base::Utility;
37 using namespace Tizen::Security::Cert;
38 using namespace Tizen::Security::Crypto;
39 using namespace Tizen::Io;
40
41 SmackManager::SmackManager(void)
42 :__pContext(null)
43 ,__isSmackEnable(false)
44 {
45         if (IsSmackEnable() == true)
46         {
47                 __isSmackEnable = true;
48         }
49 }
50
51 SmackManager::~SmackManager(void)
52 {
53 }
54
55 bool
56 SmackManager::Construct(InstallationContext* pContext)
57 {
58         __pContext = pContext;
59
60         return true;
61 }
62
63 bool
64 SmackManager::AddLabelDir(const String& label, const String& dirPath, bool rootDirectory)
65 {
66         if (__isSmackEnable == false)
67         {
68                 return true;
69         }
70
71         int res = 0;
72         String realPath;
73
74         std::unique_ptr<char[]> pPath(_StringConverter::CopyToCharArrayN(dirPath));
75         TryReturn(pPath, false, "pPath is null.");
76
77         if (InstallerUtil::IsSymlink(dirPath) == true)
78         {
79                 res = AddLabelDir("_", pPath.get());
80                 InstallerUtil::GetRealPath(dirPath, realPath);
81         }
82         else
83         {
84                 realPath = dirPath;
85         }
86
87         std::unique_ptr<char[]> pRealPath(_StringConverter::CopyToCharArrayN(realPath));
88         TryReturn(pRealPath, false, "pRealPath is null");
89
90         if (rootDirectory == true)
91         {
92                 res = AddLabelDir("_", pRealPath.get());
93         }
94         else if (dirPath.Contains(L"shared") == true)
95         {
96                 res = AddLabelDir("*", pRealPath.get());
97         }
98         else
99         {
100                 std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(label));
101                 TryReturn(pPackageId, false, "pPackageId is null");
102
103                 res = AddLabelDir(pPackageId.get(), pRealPath.get());
104         }
105
106         return true;
107 }
108
109 bool
110 SmackManager::AddLabelSharedDir(const PackageId& packageId, const String& dirPath)
111 {
112         if (__isSmackEnable == false)
113         {
114                 return true;
115         }
116
117         TryReturn(__pContext, false, "__pContext is null");
118
119         if (__pContext->__isVerificationMode == false)
120         {
121                 AppLog("VerificationMode is off.");
122                 return true;
123         }
124
125         int res = 0;
126         String label = packageId;
127
128         std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(packageId));
129         TryReturn(pPackageId, false, "pPackageId is null.");
130
131         std::unique_ptr<char[]> pPath(_StringConverter::CopyToCharArrayN(dirPath));
132         TryReturn(pPath, false, "pPath is null.");
133
134         if (dirPath.Contains(L"shared/data") == true)
135         {
136                 label = L"*";
137                 //label.Append("_shareddata");
138         }
139         else if (dirPath.Contains(L"shared/res") == true)
140         {
141                 label = L"*";
142                 //label.Append("_sharedres");
143         }
144         else if (dirPath.Contains(L"shared/trusted") == true)
145         {
146                 Sha1Hash hash;
147                 String base64Value;
148
149                 X509CertificatePath* pAuthorCertPath = __pContext->GetAuthorCertPath();
150                 TryReturn(pAuthorCertPath, false, "pAuthorCertPath is null.");
151
152                 std::unique_ptr<ICertificate> pEntity(pAuthorCertPath->GetCertificateN(0));
153                 TryReturn(pEntity, false, "pEntity is null.");
154
155                 std::unique_ptr<ByteBuffer> pEncodedData(pEntity->GetEncodedDataN());
156                 TryReturn(pEncodedData, false, "pEncodedData is null.");
157
158                 std::unique_ptr<ByteBuffer> pHashValue(hash.GetHashN(*pEncodedData.get()));
159                 TryReturn(pHashValue, false, "pHashValue is null.");
160
161                 StringUtil::EncodeToBase64String(*pHashValue, base64Value);
162
163                 std::unique_ptr<char[]> pHashEncodedValue(_StringConverter::CopyToCharArrayN(base64Value));
164                 TryReturn(pHashEncodedValue, false, "pHashEncodedValue is null.");
165
166                 label = pHashEncodedValue.get();
167                 AppLog("pHashEncodedValue = [%s]", pHashEncodedValue.get());
168         }
169         else
170         {
171                 AppLog("Invalid Directory = [%ls]", dirPath.GetPointer());
172                 return false;
173         }
174
175         std::unique_ptr<char[]> pLabel(_StringConverter::CopyToCharArrayN(label));
176         TryReturn(pLabel, false, "pLabel is null.");
177
178         res = AddLabelSharedDir(pPackageId.get(), pLabel.get(), pPath.get());
179
180         return true;
181 }
182
183 bool
184 SmackManager::AddPermissions(const PackageId& packageId)
185 {
186         if (__isSmackEnable == false)
187         {
188                 return true;
189         }
190
191         TryReturn(__pContext, false, "__pContext is null");
192
193         int res = 0;
194         String script("/usr/bin/smackload-app.sh");
195         bool exist = File::IsFileExist(script);
196
197         script.Append(L" ");
198         script.Append(packageId);
199
200         std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(packageId));
201         TryReturn(pPackageId, false, "pPackageId is null.");
202
203         std::unique_ptr<char[]> pScript(_StringConverter::CopyToCharArrayN(script));
204         TryReturn(pScript, false, "pScript is null.");
205
206         int count = __pContext->__pPrivilegeList->GetCount();
207
208         const char** pList = new (std::nothrow) const char*[count+1];
209         TryReturn(pList, false, "pList is null.");
210
211         for (int i = 0; i < count; i++)
212         {
213                 String* pPrivilege = dynamic_cast < String* >(__pContext->__pPrivilegeList->GetAt(i));
214                 if (pPrivilege)
215                 {
216                         char* pPrivilegeString = _StringConverter::CopyToCharArrayN(*pPrivilege);
217                         TryReturn(pPrivilegeString, false, "pPrivilegeString is null.");
218
219                         pList[i] = pPrivilegeString;
220                 }
221          }
222
223         pList[count] = null;
224
225         res = AddPermissions(pPackageId.get(), pList);
226
227         if (exist == true)
228         {
229                 res = system(pScript.get());
230                 AppLog("[smack] system(%s), result = [%d]", pScript.get(), res);
231         }
232         else
233         {
234                 AppLog("[%ls] not found", script.GetPointer());
235         }
236
237         for (int i = 0; pList[i] != null; i++)
238         {
239                 AppLog("delete Privilege - [%s]", pList[i]);
240                 delete[] pList[i];
241          }
242         delete[] pList;
243
244         return true;
245 }
246
247 bool
248 SmackManager::RevokePermissions(const PackageId& packageId)
249 {
250         if (__isSmackEnable == false)
251         {
252                 return true;
253         }
254
255         int res = 0;
256
257         std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(packageId));
258         TryReturn(pPackageId, false, "pPackageId is null.");
259
260         res = RevokePermissions(pPackageId.get());
261
262         return true;
263 }
264
265 bool
266 SmackManager::IsSmackEnable()
267 {
268         result r;
269         Registry reg;
270         String section(L"feature");
271         String entry(L"smack");
272         String value;
273
274         r = reg.Construct(CONFIG_PATH, "r");
275         TryReturn(!IsFailed(r), false, "CONFIG file is not found.");
276
277         r = reg.GetValue(section, entry, value);
278         TryReturn(!IsFailed(r), false, "GetValue is failed. entry = [%ls]", entry.GetPointer());
279
280         AppLog("[%ls is %ls.]", entry.GetPointer(), value.GetPointer());
281
282         if (value == L"on")
283         {
284                 return true;
285         }
286
287         return false;
288 }
289
290 int
291 SmackManager::AddLabelDir(const char* pLabel, const char* pDirPath)
292 {
293         int ret = 0;
294         void* pHandle = null;
295         char* pErrorMsg = null;
296         int (*app_label_dir)(const char*, const char*) = null;
297
298         pHandle = dlopen("libprivilege-control.so.0", RTLD_LAZY | RTLD_GLOBAL);
299         if (!pHandle)
300         {
301                 AppLog("AddLabelDir(): dlopen() failed. [%s]", dlerror());
302                 return -1;
303         }
304
305         app_label_dir = reinterpret_cast <int (*)(const char*, const char*)>(dlsym(pHandle, "app_label_dir"));
306         pErrorMsg = dlerror();
307         if (pErrorMsg != null)
308         {
309                 AppLog("AddLabelDir(): dlsym() failed. [%s]", pErrorMsg);
310                 dlclose(pHandle);
311                 return -1;
312         }
313
314         ret = app_label_dir(pLabel, pDirPath);
315         AppLog("[smack] app_label_dir(%s, %s), result = [%d]", pLabel, pDirPath, ret);
316
317         dlclose(pHandle);
318
319         return 0;
320 }
321
322 int
323 SmackManager::AddLabelSharedDir(const char* pLabel, const char* pSharedLabel, const char* pDirPath)
324 {
325         int ret = 0;
326         void* pHandle = null;
327         char* pErrorMsg = null;
328         int (*app_label_shared_dir)(const char*, const char*, const char*) = null;
329
330         pHandle = dlopen("libprivilege-control.so.0", RTLD_LAZY | RTLD_GLOBAL);
331         if (!pHandle)
332         {
333                 AppLog("AddLabelSharedDir(): dlopen() failed. [%s]", dlerror());
334                 return -1;
335         }
336
337         app_label_shared_dir = reinterpret_cast <int (*)(const char*, const char*, const char*)>(dlsym(pHandle, "app_label_shared_dir"));
338         pErrorMsg = dlerror();
339         if (pErrorMsg != null)
340         {
341                 AppLog("AddLabelSharedDir(): dlsym() failed. [%s]", pErrorMsg);
342                 dlclose(pHandle);
343                 return -1;
344         }
345
346         ret = app_label_shared_dir(pLabel, pSharedLabel, pDirPath);
347         AppLog("[smack] app_label_shared_dir(%s, %s, %s), result = [%d]", pLabel, pSharedLabel, pDirPath, ret);
348
349         dlclose(pHandle);
350
351         return 0;
352 }
353
354 int
355 SmackManager::AddPermissions(const char* pPackageId, const char** ppPermissions)
356 {
357         int ret = 0;
358         void* pHandle = null;
359         char* pErrorMsg = null;
360         int (*app_add_permissions)(const char*, const char**) = null;
361
362         pHandle = dlopen("libprivilege-control.so.0", RTLD_LAZY | RTLD_GLOBAL);
363         if (!pHandle)
364         {
365                 AppLog("AddPermissions(): dlopen() failed. [%s][%s]", pPackageId, dlerror());
366                 return -1;
367         }
368
369         app_add_permissions = reinterpret_cast <int (*)(const char*, const char**)>(dlsym(pHandle, "app_add_permissions"));
370         pErrorMsg = dlerror();
371         if (pErrorMsg != null)
372         {
373                 AppLog("AddPermissions(): dlsym() failed. [%s][%s]", pPackageId, pErrorMsg);
374                 dlclose(pHandle);
375                 return -1;
376         }
377
378         for (int i = 0; ppPermissions[i] != null; i++)
379         {
380                 AppLog("Privilege - [%s]", ppPermissions[i]);
381          }
382
383         ret = app_add_permissions(pPackageId, ppPermissions);
384         AppLog("[smack] app_add_permissions(%s), result = [%d]", pPackageId, ret);
385
386         dlclose(pHandle);
387
388         return 0;
389 }
390
391 int
392 SmackManager::RevokePermissions(const char* pPackageId)
393 {
394         int ret = 0;
395         void* pHandle = null;
396         char* pErrorMsg = null;
397         int (*app_revoke_permissions)(const char*) = null;
398
399         pHandle = dlopen("libprivilege-control.so.0", RTLD_LAZY | RTLD_GLOBAL);
400         if (!pHandle)
401         {
402                 AppLog("RevokePermissions(): dlopen() failed. [%s][%s]", pPackageId, dlerror());
403                 return -1;
404         }
405
406         app_revoke_permissions = reinterpret_cast <int (*)(const char*)>(dlsym(pHandle, "app_revoke_permissions"));
407         pErrorMsg = dlerror();
408         if (pErrorMsg != null)
409         {
410                 AppLog("RevokePermissions(): dlsym() failed. [%s][%s]", pPackageId, pErrorMsg);
411                 dlclose(pHandle);
412                 return -1;
413         }
414
415         ret = app_revoke_permissions(pPackageId);
416         AppLog("[smack] app_revoke_permissions(%s), result = [%d]", pPackageId, ret);
417
418         dlclose(pHandle);
419
420         return 0;
421 }