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