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