Fix GetPrivilegeListN method to retrieve the Privilege string with URI
[platform/framework/native/appfw.git] / src / security / FSec_PrivilegeManager.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 /**
19  * @file                FSec_PrivilegeManager.cpp
20  * @brief               This is the implementation for the _PrivilegeManager class.
21  */
22
23 #include <stdlib.h>
24 #include <pthread.h>
25 #include <unique_ptr.h>
26 #include <FAppPkg_PackageInfoImpl.h>
27 #include <FAppPkg_PackageManagerImpl.h>
28 #include <FBaseString.h>
29 #include <FBaseSysLog.h>
30 #include <FIo_IpcClient.h>
31 #include "FSec_AccessControlTypes.h"
32 #include "FSec_PrivilegeManager.h"
33 #include "FSec_PrivilegeManagerMessage.h"
34 #include "FSec_PrivilegeCache.h"
35 #include "FSec_PrivilegeInfo.h"
36
37 using namespace Tizen::App;
38 using namespace Tizen::App::Package;
39 using namespace Tizen::Base;
40 using namespace Tizen::Base::Collection;
41 using namespace Tizen::Io;
42
43 namespace Tizen { namespace Security
44 {
45
46 _PrivilegeManager* _PrivilegeManager::__pPrivilegeManagerInstance  = null;
47
48 _PrivilegeManager::_PrivilegeManager(void)
49         : __pPrivilegeCache(null)
50 {
51         return;
52 }
53
54 _PrivilegeManager::~_PrivilegeManager(void)
55 {
56         delete __pPrivilegeCache;
57         return;
58 }
59
60 result
61 _PrivilegeManager::Construct(void)
62 {
63         result r = E_SUCCESS;
64
65         _PackageManagerImpl* pPackageManagerImpl = null;
66
67         pPackageManagerImpl = _PackageManagerImpl::GetInstance();
68         SysTryReturnResult(NID_SEC, pPackageManagerImpl != null, E_SYSTEM, "An unexpected system error occurred.");
69
70         //pPackageManagerImpl->RemoveEventListener(this);
71         r = pPackageManagerImpl->AddEventListener(this);
72         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
73
74         __pPrivilegeCache = new (std::nothrow) _PrivilegeCache();
75         SysTryReturnResult(NID_SEC, __pPrivilegeCache != null, E_OUT_OF_MEMORY, "Memory allocation is failed.");
76
77         r = __pPrivilegeCache->Construct();
78         SysTryCatch(NID_SEC, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
79
80         return r;
81
82 CATCH:
83
84         delete __pPrivilegeCache;
85         return r;
86 }
87
88 void
89 _PrivilegeManager::InitInstance(void)
90 {
91         result r = E_SUCCESS;
92         static _PrivilegeManager instance;
93
94         ClearLastResult();
95
96         r = instance.Construct();
97         SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
98
99         __pPrivilegeManagerInstance = &instance;
100
101         return;
102 }
103
104 _PrivilegeManager*
105 _PrivilegeManager::GetInstance(void)
106 {
107         result r = E_SUCCESS;
108         static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
109
110         ClearLastResult();
111
112     if (__pPrivilegeManagerInstance == null)
113     {
114         pthread_once(&onceBlock, InitInstance);
115
116         r = GetLastResult();
117         if (IsFailed(r))
118         {
119             onceBlock = PTHREAD_ONCE_INIT;
120         }
121     }
122
123     return __pPrivilegeManagerInstance;
124 }
125
126
127 IList*
128 _PrivilegeManager::GetPrivilegeListN(const AppId& appId)
129 {
130         result r = E_SUCCESS;
131         _PrivilegeInfo privilegeInfo;
132         byte* pTargetBitwisePrivilege = null;
133         IList* pReturnPrivilegeList = null;
134         String encryptedPrivileges;
135         String checksum;
136         ArrayList* pPrivilegeList = null;
137
138         ClearLastResult();
139
140         r = RetrieveCipherPrivilegeN(appId, encryptedPrivileges, checksum, pPrivilegeList);
141         if (r == E_DATA_NOT_FOUND)
142         {
143                 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
144                 return null;
145         }
146         SysTryReturn(NID_SEC, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
147
148         r = privilegeInfo.Construct(appId, encryptedPrivileges, checksum, pPrivilegeList);
149         SysTryCatch(NID_SEC, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
150
151         r = privilegeInfo.GetBitwisePrivilegeN(pTargetBitwisePrivilege);
152         SysTryCatch(NID_SEC, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
153
154         pReturnPrivilegeList = UnpackPrivilegeN(pTargetBitwisePrivilege);
155         SysTryCatch(NID_SEC,  pReturnPrivilegeList != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
156
157         // fall through
158
159 CATCH:
160
161         if (pPrivilegeList != null)
162         {
163                 pPrivilegeList->RemoveAll(true);
164                 delete pPrivilegeList;
165         }
166
167         if (pTargetBitwisePrivilege)
168         {
169                 free(pTargetBitwisePrivilege);
170                 pTargetBitwisePrivilege = null;
171         }
172
173         return pReturnPrivilegeList;
174 }
175
176 result
177 _PrivilegeManager::RetrieveCipherPrivilegeN(const AppId& appId, Tizen::Base::String& encryptedPrivileges, Tizen::Base::String& checksum, ArrayList*& pPrivilegeList)
178 {
179         result r = E_SUCCESS;
180         ArrayList tempPrivilegeList;
181
182         encryptedPrivileges.Clear();
183         checksum.Clear();
184
185         r = tempPrivilegeList.Construct();
186         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
187
188         _PackageInfoImpl infoImpl;
189         r = infoImpl.Construct(appId);
190         if (r == E_APP_NOT_INSTALLED)
191         {
192                 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
193                 return E_DATA_NOT_FOUND;
194         }
195         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
196
197         r = infoImpl.GetPrivileges(encryptedPrivileges, checksum, tempPrivilegeList);
198         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
199         SysTryReturnResult(NID_SEC, encryptedPrivileges.IsEmpty() != true, E_DATA_NOT_FOUND, "The privilege information does not exist.");
200         SysTryReturnResult(NID_SEC, checksum.IsEmpty() != true, E_SYSTEM, "An unexpected system error occurred.");
201
202         pPrivilegeList = new ArrayList;
203         r = pPrivilegeList->Construct();
204
205         IEnumerator* pEnum = tempPrivilegeList.GetEnumeratorN();
206         while (pEnum->MoveNext() == E_SUCCESS)
207         {
208                 String* tempString = static_cast< String* >(pEnum->GetCurrent());
209                 pPrivilegeList->Add(new String(*tempString));
210         }
211
212         tempPrivilegeList.RemoveAll(true);
213         return r;
214 }
215
216 result
217 _PrivilegeManager::RetrieveCipherPrivilegeExN(const AppId& appId, Tizen::Base::String& encryptedPrivileges, Tizen::Base::String& checksum, ArrayList*& pPrivilegeList)
218 {
219         result r = E_SUCCESS;
220
221         encryptedPrivileges.Clear();
222         checksum.Clear();
223
224         String tempEncryptedPrivileges;
225         String tempChecksum;
226         ArrayList tempPrivilegeList;
227
228         r = tempPrivilegeList.Construct();
229         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
230
231         _PackageInfoImpl infoImpl;
232         r = infoImpl.Construct(appId);
233         if (r == E_APP_NOT_INSTALLED)
234         {
235                 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
236                 return E_DATA_NOT_FOUND;
237         }
238         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
239
240         r = infoImpl.GetPrivileges(tempEncryptedPrivileges, tempChecksum, tempPrivilegeList);
241         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
242         SysTryReturnResult(NID_SEC, tempEncryptedPrivileges.IsEmpty() != true, E_DATA_NOT_FOUND, "The privilege information does not exist.");
243         SysTryReturnResult(NID_SEC, tempChecksum.IsEmpty() != true, E_SYSTEM, "An unexpected system error occurred.");
244
245         _PrivilegeInfo privilegeInfo;
246
247         r = privilegeInfo.Construct(appId, tempEncryptedPrivileges, tempChecksum, &tempPrivilegeList);
248         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
249
250         r = privilegeInfo.GetEncryptedBitwise(encryptedPrivileges);
251         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
252
253         r = privilegeInfo.GetChecksum(checksum);
254         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
255
256         pPrivilegeList = new ArrayList;
257         r = pPrivilegeList->Construct();
258
259         IEnumerator* pEnum = tempPrivilegeList.GetEnumeratorN();
260         while (pEnum->MoveNext() == E_SUCCESS)
261         {
262                 String* tempString = static_cast< String* >(pEnum->GetCurrent());
263                 pPrivilegeList->Add(new String(*tempString));
264         }
265
266         tempPrivilegeList.RemoveAll(true);
267         return r;
268 }
269
270 _PrivilegeInfo*
271 _PrivilegeManager::RetrievePrivilegeInfoN(const AppId& appId) const
272 {
273         result r = E_SUCCESS;
274
275         String encryptedPrivileges;
276         String checksum;
277         std::unique_ptr<_PrivilegeInfo> pPrivilegeInfo(null);
278         _PackageInfoImpl infoImpl;
279         ArrayList* pPrivilegeList = null;
280
281         ClearLastResult();
282
283         pPrivilegeInfo.reset(__pPrivilegeCache->GetPrivilegeInfoN(appId));
284         r = GetLastResult();
285
286         if (r == E_SUCCESS)
287         {
288                 // nothing to do.
289         }
290         else if (r == E_DATA_NOT_FOUND)
291         {
292                 r = RetrieveCipherPrivilegeN(appId, encryptedPrivileges, checksum, pPrivilegeList);
293                 if (r == E_DATA_NOT_FOUND)
294                 {
295                         SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
296                         return null;
297                 }
298                 SysTryReturn(NID_SEC, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
299
300                 pPrivilegeInfo.reset(new (std::nothrow) _PrivilegeInfo());
301                 SysTryReturn(NID_SEC, pPrivilegeInfo != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
302
303                 r = pPrivilegeInfo->Construct(appId, encryptedPrivileges, checksum, pPrivilegeList);
304                 SysTryReturn(NID_SEC, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
305
306                 r = __pPrivilegeCache->AddPrivilegeInfo(*(pPrivilegeInfo.get()));
307                 SysTryReturn(NID_SEC, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
308
309                 if (pPrivilegeList != null)
310                 {
311                         pPrivilegeList->RemoveAll(true);
312                         delete pPrivilegeList;
313                 }
314         }
315         else
316         {
317                 r = E_SYSTEM;
318                 SysLogException(NID_SEC, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
319                 return null;
320         }
321
322         return pPrivilegeInfo.release();
323 }
324
325
326 IList*
327 _PrivilegeManager::UnpackPrivilegeN(const byte* pBitwisePrivilege)
328 {
329         result r = E_SUCCESS;
330         byte maskFlag = 0;
331         int bitPosition = 0;
332         int bytePosition = 0;
333         int index = 0;
334         int privilegeBit = 0;
335         int privilegeEnum = 0;
336         std::unique_ptr<ArrayList> pPrivilegeList(null);
337
338         ClearLastResult();
339
340         SysTryReturn(NID_SEC, pBitwisePrivilege != null, null, E_INVALID_ARG, "One of the argument is invalid.");
341
342         pPrivilegeList.reset(new (std::nothrow) ArrayList());
343         SysTryReturn(NID_SEC, pPrivilegeList != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
344
345         r = pPrivilegeList->Construct();
346         SysTryReturn(NID_SEC, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
347
348         for (bytePosition = 0; bytePosition < MAX_BITWISE_PRIV_SIZE; bytePosition++)
349         {
350                 maskFlag = 1;
351
352                 if (!(pBitwisePrivilege[bytePosition] & 0xFF))
353                 {
354                         // Pass the checking of empty byte filed.
355                         continue;
356                 }
357
358                 for (bitPosition = 0; bitPosition < _BITS_IN_BYTE; bitPosition++)
359                 {
360                         privilegeBit = (int) (pBitwisePrivilege[bytePosition] & maskFlag);
361                         if (!privilegeBit)
362                         {
363                                 // Shift the maskFlag by 1 bit when face the empty bit.
364                                 maskFlag = maskFlag << 1;
365                                 continue;
366                         }
367
368                         privilegeEnum = (bytePosition * _BITS_IN_BYTE) + bitPosition;
369
370                         for (index = 0; index < _MAX_PRIVILEGE_ENUM; index++)
371                         {
372                                 if (privilegeEnum == privilegeListTable[index].privilege)
373                                 {
374                                         String* privilegeString = new (std::nothrow) String(L"http://tizen.org/privilege/");
375                                         privilegeString->Append(privilegeListTable[index].privilegeString);
376                                         SysTryCatch(NID_SEC, privilegeString != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
377                                                         "[E_OUT_OF_MEMORY]The memory is insufficient.");
378
379                                         pPrivilegeList->Add(*privilegeString);
380                                         break;
381                                 }
382                         }
383
384                         // Shift the maskFlag by 1 bit to check the next byte filed.
385                         maskFlag = maskFlag << 1;
386                 }
387         }
388
389         return pPrivilegeList.release();
390
391 CATCH:
392
393         pPrivilegeList->RemoveAll(true);
394         return null;
395 }
396
397 void
398 _PrivilegeManager::OnPackageInstallationCompleted(const PackageId& packageId, PackageInstallationResult installationResult)
399 {
400         __pPrivilegeCache->RemovePrivilegeInfo(packageId);
401         SysLog(NID_SEC, "%ls is removed.", packageId.GetPointer());
402
403         return;
404 }
405
406 }} //Tizen::Security