Fix the boiler plate codes
[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
137         ClearLastResult();
138
139         r = RetrieveCipherPrivilegeN(appId, encryptedPrivileges, checksum, pPrivilegeList);
140         if (r == E_DATA_NOT_FOUND)
141         {
142                 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
143                 return null;
144         }
145         SysTryReturn(NID_SEC, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
146
147         r = privilegeInfo.Construct(appId, encryptedPrivileges, checksum, pPrivilegeList);
148         SysTryCatch(NID_SEC, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
149
150         r = privilegeInfo.GetBitwisePrivilegeN(pTargetBitwisePrivilege);
151         SysTryCatch(NID_SEC, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
152
153         pReturnPrivilegeList = UnpackPrivilegeN(pTargetBitwisePrivilege);
154         SysTryCatch(NID_SEC,  pReturnPrivilegeList != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
155
156         // fall through
157
158 CATCH:
159
160         if (pPrivilegeList != null)
161         {
162                 pPrivilegeList->RemoveAll(true);
163                 delete pPrivilegeList;
164         }
165
166         if (pTargetBitwisePrivilege)
167         {
168                 free(pTargetBitwisePrivilege);
169                 pTargetBitwisePrivilege = null;
170         }
171
172         return pReturnPrivilegeList;
173 }
174
175 result
176 _PrivilegeManager::RetrieveCipherPrivilegeN(const AppId& appId, Tizen::Base::String& encryptedPrivileges, Tizen::Base::String& checksum, ArrayList*& pPrivilegeList)
177 {
178         result r = E_SUCCESS;
179         ArrayList tempPrivilegeList;
180
181         encryptedPrivileges.Clear();
182         checksum.Clear();
183
184         r = tempPrivilegeList.Construct();
185         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
186
187         _PackageInfoImpl infoImpl;
188         r = infoImpl.Construct(appId);
189         if (r == E_APP_NOT_INSTALLED)
190         {
191                 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
192                 return E_DATA_NOT_FOUND;
193         }
194         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
195
196         r = infoImpl.GetPrivileges(encryptedPrivileges, checksum, tempPrivilegeList);
197         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
198         SysTryReturnResult(NID_SEC, encryptedPrivileges.IsEmpty() != true, E_DATA_NOT_FOUND, "The privilege information does not exist.");
199         SysTryReturnResult(NID_SEC, checksum.IsEmpty() != true, E_SYSTEM, "An unexpected system error occurred.");
200
201         pPrivilegeList = new ArrayList;
202         r = pPrivilegeList->Construct();
203
204         IEnumerator* pEnum = tempPrivilegeList.GetEnumeratorN();
205         while (pEnum->MoveNext() == E_SUCCESS)
206         {
207                 String* tempString = static_cast< String* >(pEnum->GetCurrent());
208                 pPrivilegeList->Add(new String(*tempString));
209         }
210
211         tempPrivilegeList.RemoveAll(true);
212         return r;
213 }
214
215 result
216 _PrivilegeManager::RetrieveCipherPrivilegeExN(const AppId& appId, Tizen::Base::String& encryptedPrivileges, Tizen::Base::String& checksum, ArrayList*& pPrivilegeList)
217 {
218         result r = E_SUCCESS;
219
220         encryptedPrivileges.Clear();
221         checksum.Clear();
222
223         String tempEncryptedPrivileges;
224         String tempChecksum;
225         ArrayList tempPrivilegeList;
226
227         r = tempPrivilegeList.Construct();
228         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
229
230         _PackageInfoImpl infoImpl;
231         r = infoImpl.Construct(appId);
232         if (r == E_APP_NOT_INSTALLED)
233         {
234                 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
235                 return E_DATA_NOT_FOUND;
236         }
237         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
238
239         r = infoImpl.GetPrivileges(tempEncryptedPrivileges, tempChecksum, tempPrivilegeList);
240         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
241         SysTryReturnResult(NID_SEC, tempEncryptedPrivileges.IsEmpty() != true, E_DATA_NOT_FOUND, "The privilege information does not exist.");
242         SysTryReturnResult(NID_SEC, tempChecksum.IsEmpty() != true, E_SYSTEM, "An unexpected system error occurred.");
243
244         _PrivilegeInfo privilegeInfo;
245
246         r = privilegeInfo.Construct(appId, tempEncryptedPrivileges, tempChecksum, &tempPrivilegeList);
247         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
248
249         r = privilegeInfo.GetEncryptedBitwise(encryptedPrivileges);
250         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
251
252         r = privilegeInfo.GetChecksum(checksum);
253         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
254
255         pPrivilegeList = new ArrayList;
256         r = pPrivilegeList->Construct();
257
258         IEnumerator* pEnum = tempPrivilegeList.GetEnumeratorN();
259         while (pEnum->MoveNext() == E_SUCCESS)
260         {
261                 String* tempString = static_cast< String* >(pEnum->GetCurrent());
262                 pPrivilegeList->Add(new String(*tempString));
263         }
264
265         tempPrivilegeList.RemoveAll(true);
266         return r;
267 }
268
269 _PrivilegeInfo*
270 _PrivilegeManager::RetrievePrivilegeInfoN(const AppId& appId) const
271 {
272         result r = E_SUCCESS;
273
274         String encryptedPrivileges;
275         String checksum;
276         std::unique_ptr<_PrivilegeInfo> pPrivilegeInfo(null);
277         _PackageInfoImpl infoImpl;
278         ArrayList* pPrivilegeList = null;
279
280         ClearLastResult();
281
282         pPrivilegeInfo.reset(__pPrivilegeCache->GetPrivilegeInfoN(appId));
283         r = GetLastResult();
284
285         if (r == E_SUCCESS)
286         {
287                 // nothing to do.
288         }
289         else if (r == E_DATA_NOT_FOUND)
290         {
291                 r = RetrieveCipherPrivilegeN(appId, encryptedPrivileges, checksum, pPrivilegeList);
292                 if (r == E_DATA_NOT_FOUND)
293                 {
294                         SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
295                         return null;
296                 }
297                 SysTryReturn(NID_SEC, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
298
299                 pPrivilegeInfo.reset(new (std::nothrow) _PrivilegeInfo());
300                 SysTryReturn(NID_SEC, pPrivilegeInfo != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
301
302                 r = pPrivilegeInfo->Construct(appId, encryptedPrivileges, checksum, pPrivilegeList);
303                 SysTryReturn(NID_SEC, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
304
305                 r = __pPrivilegeCache->AddPrivilegeInfo(*(pPrivilegeInfo.get()));
306                 SysTryReturn(NID_SEC, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
307
308                 if (pPrivilegeList != null)
309                 {
310                         pPrivilegeList->RemoveAll(true);
311                         delete pPrivilegeList;
312                 }
313         }
314         else
315         {
316                 r = E_SYSTEM;
317                 SysLogException(NID_SEC, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
318                 return null;
319         }
320
321         return pPrivilegeInfo.release();
322 }
323
324
325 IList*
326 _PrivilegeManager::UnpackPrivilegeN(const byte* pBitwisePrivilege)
327 {
328         result r = E_SUCCESS;
329         byte maskFlag = 0;
330         int bitPosition = 0;
331         int bytePosition = 0;
332         int index = 0;
333         int privilegeBit = 0;
334         int privilegeEnum = 0;
335         std::unique_ptr<ArrayList> pPrivilegeList(null);
336
337         ClearLastResult();
338
339         SysTryReturn(NID_SEC, pBitwisePrivilege != null, null, E_INVALID_ARG, "One of the argument is invalid.");
340
341         pPrivilegeList.reset(new (std::nothrow) ArrayList());
342         SysTryReturn(NID_SEC, pPrivilegeList != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
343
344         r = pPrivilegeList->Construct();
345         SysTryReturn(NID_SEC, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
346
347         for (bytePosition = 0; bytePosition < MAX_BITWISE_PRIV_SIZE; bytePosition++)
348         {
349                 maskFlag = 1;
350
351                 if (!(pBitwisePrivilege[bytePosition] & 0xFF))
352                 {
353                         // Pass the checking of empty byte filed.
354                         continue;
355                 }
356
357                 for (bitPosition = 0; bitPosition < _BITS_IN_BYTE; bitPosition++)
358                 {
359                         privilegeBit = (int) (pBitwisePrivilege[bytePosition] & maskFlag);
360                         if (!privilegeBit)
361                         {
362                                 // Shift the maskFlag by 1 bit when face the empty bit.
363                                 maskFlag = maskFlag << 1;
364                                 continue;
365                         }
366
367                         privilegeEnum = (bytePosition * _BITS_IN_BYTE) + bitPosition;
368
369                         for (index = 0; index < _MAX_PRIVILEGE_ENUM; index++)
370                         {
371                                 if (privilegeEnum == privilegeListTable[index].privilege)
372                                 {
373                                         String* privilegeString = new (std::nothrow) String(L"http://tizen.org/privilege/");
374                                         privilegeString->Append(privilegeListTable[index].privilegeString);
375                                         SysTryCatch(NID_SEC, privilegeString != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
376                                                         "[E_OUT_OF_MEMORY]The memory is insufficient.");
377
378                                         pPrivilegeList->Add(*privilegeString);
379                                         break;
380                                 }
381                         }
382
383                         // Shift the maskFlag by 1 bit to check the next byte filed.
384                         maskFlag = maskFlag << 1;
385                 }
386         }
387
388         return pPrivilegeList.release();
389
390 CATCH:
391
392         pPrivilegeList->RemoveAll(true);
393         return null;
394 }
395
396 void
397 _PrivilegeManager::OnPackageInstallationCompleted(const PackageId& packageId, PackageInstallationResult installationResult)
398 {
399         __pPrivilegeCache->RemovePrivilegeInfo(packageId);
400         SysLog(NID_SEC, "%ls is removed.", packageId.GetPointer());
401
402         return;
403 }
404
405 }} //Tizen::Security