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