Add to parse metadata
[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 :__isSmackEnable(false)
43 {
44         if (IsSmackEnable() == true)
45         {
46                 __isSmackEnable = true;
47         }
48 }
49
50 SmackManager::~SmackManager(void)
51 {
52 }
53
54 bool
55 SmackManager::AddLabelDir(const String& label, const String& dirPath, bool rootDirectory)
56 {
57         if (__isSmackEnable == false)
58         {
59                 return true;
60         }
61
62         int res = 0;
63         String realPath;
64
65         std::unique_ptr<char[]> pPath(_StringConverter::CopyToCharArrayN(dirPath));
66         TryReturn(pPath, false, "pPath is null.");
67
68         if (InstallerUtil::IsSymlink(dirPath) == true)
69         {
70                 res = AddLabelDir("_", pPath.get());
71                 InstallerUtil::GetRealPath(dirPath, realPath);
72         }
73         else
74         {
75                 realPath = dirPath;
76         }
77
78         std::unique_ptr<char[]> pRealPath(_StringConverter::CopyToCharArrayN(realPath));
79         TryReturn(pRealPath, false, "pRealPath is null");
80
81         if (rootDirectory == true)
82         {
83                 res = AddLabelDir("_", pRealPath.get());
84         }
85         else if (dirPath.Contains(L"shared") == true)
86         {
87                 res = AddLabelDir("*", pRealPath.get());
88         }
89         else
90         {
91                 std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(label));
92                 TryReturn(pPackageId, false, "pPackageId is null");
93
94                 res = AddLabelDir(pPackageId.get(), pRealPath.get());
95         }
96
97         return true;
98 }
99
100 bool
101 SmackManager::AddLabelSharedDir(const PackageId& packageId, const String& dirPath, InstallationContext* pContext)
102 {
103         if (__isSmackEnable == false)
104         {
105                 return true;
106         }
107
108         if (pContext->__isVerificationMode == false)
109         {
110                 AppLog("VerificationMode is off.");
111                 return true;
112         }
113
114         int res = 0;
115         String label = packageId;
116
117         std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(packageId));
118         TryReturn(pPackageId, false, "pPackageId is null.");
119
120         std::unique_ptr<char[]> pPath(_StringConverter::CopyToCharArrayN(dirPath));
121         TryReturn(pPath, false, "pPath is null.");
122
123         if (dirPath.Contains(L"shared/data") == true)
124         {
125                 label = L"*";
126                 //label.Append("_shareddata");
127         }
128         else if (dirPath.Contains(L"shared/res") == true)
129         {
130                 label = L"*";
131                 //label.Append("_sharedres");
132         }
133         else if (dirPath.Contains(L"shared/trusted") == true)
134         {
135                 Sha1Hash hash;
136                 String base64Value;
137
138                 X509CertificatePath* pAuthorCertPath = pContext->GetAuthorCertPath();
139                 TryReturn(pAuthorCertPath, false, "pAuthorCertPath is null.");
140
141                 std::unique_ptr<ICertificate> pEntity(pAuthorCertPath->GetCertificateN(0));
142                 TryReturn(pEntity, false, "pEntity is null.");
143
144                 std::unique_ptr<ByteBuffer> pEncodedData(pEntity->GetEncodedDataN());
145                 TryReturn(pEncodedData, false, "pEncodedData is null.");
146
147                 std::unique_ptr<ByteBuffer> pHashValue(hash.GetHashN(*pEncodedData.get()));
148                 TryReturn(pHashValue, false, "pHashValue is null.");
149
150                 StringUtil::EncodeToBase64String(*pHashValue, base64Value);
151
152                 std::unique_ptr<char[]> pHashEncodedValue(_StringConverter::CopyToCharArrayN(base64Value));
153                 TryReturn(pHashEncodedValue, false, "pHashEncodedValue is null.");
154
155                 label = pHashEncodedValue.get();
156                 AppLog("pHashEncodedValue = [%s]", pHashEncodedValue.get());
157         }
158         else
159         {
160                 AppLog("Invalid Directory = [%ls]", dirPath.GetPointer());
161                 return false;
162         }
163
164         std::unique_ptr<char[]> pLabel(_StringConverter::CopyToCharArrayN(label));
165         TryReturn(pLabel, false, "pLabel is null.");
166
167         res = AddLabelSharedDir(pPackageId.get(), pLabel.get(), pPath.get());
168
169         return true;
170 }
171
172 bool
173 SmackManager::AddPermissions(const PackageId& packageId)
174 {
175         if (__isSmackEnable == false)
176         {
177                 return true;
178         }
179
180         int res = 0;
181         const char* pList[] = {"OSP", null};
182         String script("/usr/bin/smackload-app.sh");
183         bool exist = File::IsFileExist(script);
184
185         script.Append(L" ");
186         script.Append(packageId);
187
188         std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(packageId));
189         TryReturn(pPackageId, false, "pPackageId is null.");
190
191         std::unique_ptr<char[]> pScript(_StringConverter::CopyToCharArrayN(script));
192         TryReturn(pScript, false, "pScript is null.");
193
194         res = AddPermissions(pPackageId.get(), pList);
195
196         if (exist == true)
197         {
198                 res = system(pScript.get());
199                 AppLog("[smack] system(%s), result = [%d]", pScript.get(), res);
200         }
201         else
202         {
203                 AppLog("[%ls] not found", script.GetPointer());
204         }
205
206         return true;
207 }
208
209 bool
210 SmackManager::RevokePermissions(const PackageId& packageId)
211 {
212         if (__isSmackEnable == false)
213         {
214                 return true;
215         }
216
217         int res = 0;
218
219         std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(packageId));
220         TryReturn(pPackageId, false, "pPackageId is null.");
221
222         res = RevokePermissions(pPackageId.get());
223
224         return true;
225 }
226
227 bool
228 SmackManager::IsSmackEnable()
229 {
230         result r;
231         Registry reg;
232         String section(L"feature");
233         String entry(L"smack");
234         String value;
235
236         r = reg.Construct(CONFIG_PATH, "r");
237         TryReturn(!IsFailed(r), false, "CONFIG file is not found.");
238
239         r = reg.GetValue(section, entry, value);
240         TryReturn(!IsFailed(r), false, "GetValue is failed. entry = [%ls]", entry.GetPointer());
241
242         AppLog("[%ls is %ls.]", entry.GetPointer(), value.GetPointer());
243
244         if (value == L"on")
245         {
246                 return true;
247         }
248
249         return false;
250 }
251
252 int
253 SmackManager::AddLabelDir(const char* pLabel, const char* pDirPath)
254 {
255         int ret = 0;
256         void* pHandle = null;
257         char* pErrorMsg = null;
258         int (*app_label_dir)(const char*, const char*) = null;
259
260         pHandle = dlopen("libprivilege-control.so.0", RTLD_LAZY | RTLD_GLOBAL);
261         if (!pHandle)
262         {
263                 AppLog("AddLabelDir(): dlopen() failed. [%s]", dlerror());
264                 return -1;
265         }
266
267         app_label_dir = reinterpret_cast <int (*)(const char*, const char*)>(dlsym(pHandle, "app_label_dir"));
268         pErrorMsg = dlerror();
269         if (pErrorMsg != null)
270         {
271                 AppLog("AddLabelDir(): dlsym() failed. [%s]", pErrorMsg);
272                 dlclose(pHandle);
273                 return -1;
274         }
275
276         ret = app_label_dir(pLabel, pDirPath);
277         AppLog("[smack] app_label_dir(%s, %s), result = [%d]", pLabel, pDirPath, ret);
278
279         dlclose(pHandle);
280
281         return 0;
282 }
283
284 int
285 SmackManager::AddLabelSharedDir(const char* pLabel, const char* pSharedLabel, const char* pDirPath)
286 {
287         int ret = 0;
288         void* pHandle = null;
289         char* pErrorMsg = null;
290         int (*app_label_shared_dir)(const char*, const char*, const char*) = null;
291
292         pHandle = dlopen("libprivilege-control.so.0", RTLD_LAZY | RTLD_GLOBAL);
293         if (!pHandle)
294         {
295                 AppLog("AddLabelSharedDir(): dlopen() failed. [%s]", dlerror());
296                 return -1;
297         }
298
299         app_label_shared_dir = reinterpret_cast <int (*)(const char*, const char*, const char*)>(dlsym(pHandle, "app_label_shared_dir"));
300         pErrorMsg = dlerror();
301         if (pErrorMsg != null)
302         {
303                 AppLog("AddLabelSharedDir(): dlsym() failed. [%s]", pErrorMsg);
304                 dlclose(pHandle);
305                 return -1;
306         }
307
308         ret = app_label_shared_dir(pLabel, pSharedLabel, pDirPath);
309         AppLog("[smack] app_label_shared_dir(%s, %s, %s), result = [%d]", pLabel, pSharedLabel, pDirPath, ret);
310
311         dlclose(pHandle);
312
313         return 0;
314 }
315
316 int
317 SmackManager::AddPermissions(const char* pPackageId, const char** ppPermissions)
318 {
319         int ret = 0;
320         void* pHandle = null;
321         char* pErrorMsg = null;
322         int (*app_add_permissions)(const char*, const char**) = null;
323
324         pHandle = dlopen("libprivilege-control.so.0", RTLD_LAZY | RTLD_GLOBAL);
325         if (!pHandle)
326         {
327                 AppLog("AddPermissions(): dlopen() failed. [%s][%s]", pPackageId, dlerror());
328                 return -1;
329         }
330
331         app_add_permissions = reinterpret_cast <int (*)(const char*, const char**)>(dlsym(pHandle, "app_add_permissions"));
332         pErrorMsg = dlerror();
333         if (pErrorMsg != null)
334         {
335                 AppLog("AddPermissions(): dlsym() failed. [%s][%s]", pPackageId, pErrorMsg);
336                 dlclose(pHandle);
337                 return -1;
338         }
339
340         ret = app_add_permissions(pPackageId, ppPermissions);
341         AppLog("[smack] app_add_permissions(%s), result = [%d]", pPackageId, ret);
342
343         dlclose(pHandle);
344
345         return 0;
346 }
347
348 int
349 SmackManager::RevokePermissions(const char* pPackageId)
350 {
351         int ret = 0;
352         void* pHandle = null;
353         char* pErrorMsg = null;
354         int (*app_revoke_permissions)(const char*) = null;
355
356         pHandle = dlopen("libprivilege-control.so.0", RTLD_LAZY | RTLD_GLOBAL);
357         if (!pHandle)
358         {
359                 AppLog("RevokePermissions(): dlopen() failed. [%s][%s]", pPackageId, dlerror());
360                 return -1;
361         }
362
363         app_revoke_permissions = reinterpret_cast <int (*)(const char*)>(dlsym(pHandle, "app_revoke_permissions"));
364         pErrorMsg = dlerror();
365         if (pErrorMsg != null)
366         {
367                 AppLog("RevokePermissions(): dlsym() failed. [%s][%s]", pPackageId, pErrorMsg);
368                 dlclose(pHandle);
369                 return -1;
370         }
371
372         ret = app_revoke_permissions(pPackageId);
373         AppLog("[smack] app_revoke_permissions(%s), result = [%d]", pPackageId, ret);
374
375         dlclose(pHandle);
376
377         return 0;
378 }