sync with master
[platform/framework/native/appfw.git] / src / security / FSec_AccessController.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_AccessController.cpp
20  * @brief       This is the implementation for the _AccessController class.
21  */
22
23 #include <unique_ptr.h>
24 #include <FAppTypes.h>
25 #include <FAppApplication.h>
26 #include <FApp_AppInfo.h>
27 #include <FApp_AppManagerImpl.h>
28 #include <FAppPkg_PackageInfoImpl.h>
29 #include <FBaseSysLog.h>
30 #include <FBaseString.h>
31 #include <FBaseColArrayList.h>
32 #include <FIoFile.h>
33 #include <FIo_IpcClient.h>
34 #include "FSec_AccessController.h"
35 #include "FSec_PrivilegeManager.h"
36 #include "FSec_PrivilegeManagerMessage.h"
37 #include "FSec_PrivilegeInfo.h"
38
39 using namespace Tizen::App;
40 using namespace Tizen::App::Package;
41 using namespace Tizen::Base;
42 using namespace Tizen::Base::Collection;
43 using namespace Tizen::Io;
44
45 static _IpcClient ipcClient;
46 static bool isConstructed = false;
47
48 namespace Tizen { namespace Security
49 {
50
51 _PrivilegeManager* _AccessController::__pPrivilegeManager = null;
52
53 static std::unique_ptr<String> pEncryptedPrivileges(null);
54 static std::unique_ptr<String> pChecksum(null);
55 static std::unique_ptr<String> pEncryptedVisibility(null);
56 static std::unique_ptr<String> pVisibilityChecksum(null);
57 static std::unique_ptr<ArrayList> pPrivilegeList(null);
58
59 _AccessController::_AccessController(void)
60 {
61
62 }
63
64 _AccessController::~_AccessController(void)
65 {
66         if (pPrivilegeList != null)
67         {
68                 pPrivilegeList->RemoveAll(true);
69         }
70 }
71
72 result
73 _AccessController::CheckSystemPrivilege(const PackageId& packageId, _Privilege privilege)
74 {
75         result r = E_SUCCESS;
76
77         bool ret = false;
78         std::unique_ptr<_PrivilegeInfo> pPrivilegeInfo(null);
79         String subAppId;
80         _PackageInfoImpl infoImpl;
81         String appType;
82         String webAppType(L"wgt");
83
84         SysTryReturnResult(NID_SEC, privilege < _MAX_PRIVILEGE_ENUM, E_INVALID_ARG, "The privilege enumerator is invalid");
85
86         packageId.SubString(0, MAX_APP_ID_SIZE, subAppId);
87
88         r = infoImpl.Construct(subAppId);
89         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
90
91         appType = infoImpl.GetAppType();
92         if (appType.Equals(webAppType, true))
93         {
94                 return E_SUCCESS;
95         }
96
97         if (__pPrivilegeManager == null)
98         {
99                 __pPrivilegeManager = _PrivilegeManager::GetInstance();
100         }
101         SysTryReturnResult(NID_SEC, __pPrivilegeManager != null, E_SYSTEM, "An unexpected system error occurred.");
102
103         pPrivilegeInfo.reset(__pPrivilegeManager->RetrievePrivilegeInfoN(subAppId));
104         r = GetLastResult();
105
106         if (r == E_SUCCESS)
107         {
108                 // nothing to do.
109         }
110         else if (r == E_DATA_NOT_FOUND)
111         {
112                 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
113                 goto CATCH;
114         }
115         else
116         {
117                 SysLogException(NID_SEC, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
118                 return E_SYSTEM;
119         }
120
121         ret = pPrivilegeInfo->HasPrivilege(privilege);
122         if (!ret)
123         {
124                 r = E_PRIVILEGE_DENIED;
125                 goto CATCH;
126         }
127
128         return r;
129
130 CATCH:
131
132         SysLogException(NID_SEC,  r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
133
134         _AppManagerImpl* pAppManagerImpl = _AppManagerImpl::GetInstance();
135         pAppManagerImpl->TerminateApplications(packageId);
136
137         return r;
138 }
139
140 result
141 _AccessController::CheckSystemPrivilege(const PackageId& packageId, _Privilege privilege1, _Privilege privilege2)
142 {
143         result r = E_SUCCESS;
144
145         bool ret = false;
146         std::unique_ptr<_PrivilegeInfo> pPrivilegeInfo(null);
147         String subAppId;
148         _PackageInfoImpl infoImpl;
149         String appType;
150         String webAppType(L"wgt");
151
152         SysTryReturnResult(NID_SEC, privilege1 < _MAX_PRIVILEGE_ENUM, E_INVALID_ARG, "The privilege enumerator is invalid");
153         SysTryReturnResult(NID_SEC, privilege2 < _MAX_PRIVILEGE_ENUM, E_INVALID_ARG, "The privilege enumerator is invalid");
154
155         packageId.SubString(0, MAX_APP_ID_SIZE, subAppId);
156
157         r = infoImpl.Construct(subAppId);
158         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
159
160         appType = infoImpl.GetAppType();
161         if (appType.Equals(webAppType, true))
162         {
163                 return E_SUCCESS;
164         }
165
166         if (__pPrivilegeManager == null)
167         {
168                 __pPrivilegeManager = _PrivilegeManager::GetInstance();
169         }
170         SysTryReturnResult(NID_SEC, __pPrivilegeManager != null, E_SYSTEM, "An unexpected system error occurred.");
171
172         pPrivilegeInfo.reset(__pPrivilegeManager->RetrievePrivilegeInfoN(subAppId));
173         r = GetLastResult();
174
175         if (r == E_SUCCESS)
176         {
177                 // nothing to do.
178         }
179         else if (r == E_DATA_NOT_FOUND)
180         {
181                 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
182                 goto CATCH;
183         }
184         else
185         {
186                 SysLogException(NID_SEC, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
187                 return E_SYSTEM;
188         }
189
190         ret = pPrivilegeInfo->HasPrivilegeEx(privilege1);
191         if (!ret)
192         {
193                 ret = pPrivilegeInfo->HasPrivilege(privilege2);
194                 if (!ret)
195                 {
196                         r = E_PRIVILEGE_DENIED;
197                         goto CATCH;
198                 }
199         }
200
201         return r;
202
203 CATCH:
204
205         SysLogException(NID_SEC,  r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
206
207         _AppManagerImpl* pAppManagerImpl = _AppManagerImpl::GetInstance();
208         pAppManagerImpl->TerminateApplications(packageId);
209
210         return r;
211 }
212
213 result
214 _AccessController::CheckPrivilege(const PackageId& packageId, const String& privilege)
215 {
216         result r = E_SUCCESS;
217
218         bool ret = false;
219         std::unique_ptr<_PrivilegeInfo> pPrivilegeInfo(null);
220         String subAppId;
221         _PackageInfoImpl infoImpl;
222         String appType;
223         String webAppType(L"wgt");
224
225         packageId.SubString(0, MAX_APP_ID_SIZE, subAppId);
226
227         r = infoImpl.Construct(subAppId);
228         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
229
230         appType = infoImpl.GetAppType();
231         if (appType.Equals(webAppType, true))
232         {
233                 return E_SUCCESS;
234         }
235
236         if (__pPrivilegeManager == null)
237         {
238                 __pPrivilegeManager = _PrivilegeManager::GetInstance();
239         }
240         SysTryReturnResult(NID_SEC, __pPrivilegeManager != null, E_SYSTEM, "An unexpected system error occurred.");
241
242         pPrivilegeInfo.reset(__pPrivilegeManager->RetrievePrivilegeInfoN(subAppId));
243         r = GetLastResult();
244
245         if (r == E_SUCCESS)
246         {
247                 // nothing to do.
248         }
249         else if (r == E_DATA_NOT_FOUND)
250         {
251                 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
252                 goto CATCH;
253         }
254         else
255         {
256                 SysLogException(NID_SEC, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
257                 return E_SYSTEM;
258         }
259
260         ret = pPrivilegeInfo->HasPrivilege(privilege);
261         if (!ret)
262         {
263                 r = E_PRIVILEGE_DENIED;
264                 goto CATCH;
265         }
266
267         return r;
268
269 CATCH:
270
271         SysLogException(NID_SEC,  r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
272
273         _AppManagerImpl* pAppManagerImpl = _AppManagerImpl::GetInstance();
274         pAppManagerImpl->TerminateApplications(packageId);
275
276         return r;
277 }
278
279 void
280 _AccessController::Initialize(void)
281 {
282         result r = E_SUCCESS;
283         result ipcResult = E_SUCCESS;
284
285         std::unique_ptr<IPC::Message> pCipherPrivilegeMessage(null);
286         std::unique_ptr<IPC::Message> pCipherVisibilityMessage(null);
287
288         r = ipcClient.Construct(L"osp.security.ipcserver.privilegemanager", null);
289         SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "Failed to construct the instance of IPC.");
290
291         pEncryptedPrivileges.reset(new (std::nothrow) String());
292         SysTryReturnVoidResult(NID_SEC, pEncryptedPrivileges != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
293
294         pChecksum.reset(new (std::nothrow) String());
295         SysTryReturnVoidResult(NID_SEC, pChecksum != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
296
297         pPrivilegeList.reset(new ArrayList());
298         SysTryReturnVoidResult(NID_SEC, pPrivilegeList != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
299
300         pPrivilegeList->Construct();
301
302         pCipherPrivilegeMessage.reset(new (std::nothrow) PrivilegeManagerMsg_retrieve(pEncryptedPrivileges.get(), pChecksum.get(), pPrivilegeList.get(), &r));
303         SysTryReturnVoidResult(NID_SEC, pCipherPrivilegeMessage != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
304
305         ipcResult = ipcClient.SendRequest(pCipherPrivilegeMessage.get());
306         SysTryReturnVoidResult(NID_SEC, ipcResult == E_SUCCESS, E_SYSTEM, "Failed to send IPC message.");
307         SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, r, "Failed to retrieve privilege information");
308
309         pEncryptedVisibility.reset(new (std::nothrow) String());
310         SysTryReturnVoidResult(NID_SEC, pEncryptedVisibility != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
311
312         pVisibilityChecksum.reset(new (std::nothrow) String());
313         SysTryReturnVoidResult(NID_SEC, pVisibilityChecksum != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
314
315         pCipherVisibilityMessage.reset(new (std::nothrow) PrivilegeManagerMsg_retrieveEx(pEncryptedVisibility.get(), pVisibilityChecksum.get(), &r));
316         SysTryReturnVoidResult(NID_SEC, pCipherVisibilityMessage != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
317
318         ipcResult = ipcClient.SendRequest(pCipherVisibilityMessage.get());
319         SysTryReturnVoidResult(NID_SEC, ipcResult == E_SUCCESS, E_SYSTEM, "Failed to send IPC message.");
320         SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, r, "Failed to retrieve privilege information");
321
322         isConstructed = true;
323
324         return;
325 }
326
327 result
328 _AccessController::CheckUserPrivilege(_Privilege privilege)
329 {
330         result r = E_SUCCESS;
331         static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
332
333         bool ret = false;
334
335         _PrivilegeInfo privilegeInfo;
336
337         ClearLastResult();
338
339         SysTryReturnResult(NID_SEC, privilege < _MAX_PRIVILEGE_ENUM, E_INVALID_ARG, "The privilege enumerator is invalid");
340         //SysAssertf(privilegeLevelListTable[privilege][_PRV_API_VER_2_0] == _PRV_LEVEL_USER, "System-level privilege is passed to CheckUserPrivilege.");
341
342         int appType = _AppInfo::GetAppType();
343         PackageId packageId = _AppInfo::GetPackageId();
344         packageId[0] = packageId[0];
345
346         if ((appType & _APP_TYPE_WEB_APP) != _APP_TYPE_WEB_APP)
347         {
348             if (isConstructed != true)
349             {
350                 pthread_once(&onceBlock, Initialize);
351                 r = GetLastResult();
352                 if (IsFailed(r))
353                 {
354                         if (r == E_DATA_NOT_FOUND)
355                         {
356                                 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
357                                 goto CATCH;
358                         }
359                         else
360                         {
361                                 onceBlock = PTHREAD_ONCE_INIT;
362                                         SysLogException(NID_SEC, r, "[%s] Propagated.", GetErrorMessage(r));
363                         }
364                                 return r;
365                 }
366             }
367
368                 if ((pEncryptedPrivileges != null) && (pChecksum != null) && (pEncryptedVisibility != null) && (pVisibilityChecksum != null))
369                 {
370                         r = privilegeInfo.Construct(packageId, *(pEncryptedPrivileges.get()), *(pChecksum.get()), *(pEncryptedVisibility.get()), *(pVisibilityChecksum.get()), pPrivilegeList.get());
371                         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred. %ls", packageId.GetPointer());
372
373                         SysLog(NID_SEC, "%ls is in the cache [client]", privilegeInfo.GetAppId().GetPointer());
374                 }
375                 else
376                 {
377                         SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
378                         r =  E_DATA_NOT_FOUND;
379                         goto CATCH;
380                 }
381
382                 ret = privilegeInfo.HasPrivilege(privilege);
383                 if (!ret)
384                 {
385                         r = E_PRIVILEGE_DENIED;
386                         goto CATCH;
387                 }
388         }
389
390         return r;
391
392 CATCH:
393
394         SysLogException(NID_SEC,  r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
395
396         _AppManagerImpl* pAppManagerImpl = _AppManagerImpl::GetInstance();
397         pAppManagerImpl->TerminateApplications(packageId);
398
399         return r;
400
401 }
402
403 result
404 _AccessController::CheckUserPrivilege(_Privilege privilege1, _Privilege privilege2)
405 {
406         result r = E_SUCCESS;
407         static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
408
409         bool ret = false;
410
411         _PrivilegeInfo privilegeInfo;
412
413         ClearLastResult();
414
415         SysTryReturnResult(NID_SEC, privilege1 < _MAX_PRIVILEGE_ENUM, E_INVALID_ARG, "The privilege enumerator is invalid");
416         SysTryReturnResult(NID_SEC, privilege2 < _MAX_PRIVILEGE_ENUM, E_INVALID_ARG, "The privilege enumerator is invalid");
417         //SysAssertf(privilegeLevelListTable[privilege][_PRV_API_VER_2_0] == _PRV_LEVEL_USER, "System-level privilege is passed to CheckUserPrivilege.");
418
419         int appType = _AppInfo::GetAppType();
420         PackageId packageId = _AppInfo::GetPackageId();
421         packageId[0] = packageId[0];
422
423         if ((appType & _APP_TYPE_WEB_APP) != _APP_TYPE_WEB_APP)
424         {
425             if (isConstructed != true)
426             {
427                 pthread_once(&onceBlock, Initialize);
428                 r = GetLastResult();
429                 if (IsFailed(r))
430                 {
431                         if (r == E_DATA_NOT_FOUND)
432                         {
433                                 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
434                                 goto CATCH;
435                         }
436                         else
437                         {
438                                 onceBlock = PTHREAD_ONCE_INIT;
439                                         SysLogException(NID_SEC, r, "[%s] Propagated.", GetErrorMessage(r));
440                         }
441                                 return r;
442                 }
443             }
444
445                 if ((pEncryptedPrivileges != null) && (pChecksum != null) && (pEncryptedVisibility != null) && (pVisibilityChecksum != null))
446                 {
447                         r = privilegeInfo.Construct(packageId, *(pEncryptedPrivileges.get()), *(pChecksum.get()), *(pEncryptedVisibility.get()), *(pVisibilityChecksum.get()), pPrivilegeList.get());
448                         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred. %ls", packageId.GetPointer());
449
450                         SysLog(NID_SEC, "%ls is in the cache [client]", privilegeInfo.GetAppId().GetPointer());
451                 }
452                 else
453                 {
454                         SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
455                         r =  E_DATA_NOT_FOUND;
456                         goto CATCH;
457                 }
458
459                 ret = privilegeInfo.HasPrivilegeEx(privilege1);
460                 if (!ret)
461                 {
462                         ret = privilegeInfo.HasPrivilege(privilege2);
463                         if (!ret)
464                         {
465                                 r = E_PRIVILEGE_DENIED;
466                                 goto CATCH;
467                         }
468                 }
469         }
470
471         return r;
472
473 CATCH:
474
475         SysLogException(NID_SEC,  r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
476
477         _AppManagerImpl* pAppManagerImpl = _AppManagerImpl::GetInstance();
478         pAppManagerImpl->TerminateApplications(packageId);
479
480         return r;
481
482 }
483
484
485 result
486 _AccessController::CheckPrivilege(const String& privilege)
487 {
488         result r = E_SUCCESS;
489         static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
490
491         bool ret = false;
492
493         _PrivilegeInfo privilegeInfo;
494
495         ClearLastResult();
496
497         int appType = _AppInfo::GetAppType();
498         PackageId packageId = _AppInfo::GetPackageId();
499         packageId[0] = packageId[0];
500
501         if ((appType & _APP_TYPE_WEB_APP) != _APP_TYPE_WEB_APP)
502         {
503                 if (isConstructed != true)
504                 {
505                         pthread_once(&onceBlock, Initialize);
506                         r = GetLastResult();
507                         if (IsFailed(r))
508                         {
509                                 if (r == E_DATA_NOT_FOUND)
510                                 {
511                                         SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
512                                         goto CATCH;
513                                 }
514                                 else
515                                 {
516                                         onceBlock = PTHREAD_ONCE_INIT;
517                                         SysLogException(NID_SEC, r, "[%s] Propagated.", GetErrorMessage(r));
518                                 }
519                                 return r;
520                         }
521                 }
522
523                 std::unique_ptr<IEnumerator> pEnum(null);
524                 pEnum.reset(pPrivilegeList->GetEnumeratorN());
525
526                 if ((pEncryptedPrivileges != null) && (pChecksum != null) && (pEncryptedVisibility != null) && (pVisibilityChecksum != null))
527                 {
528                         r = privilegeInfo.Construct(packageId, *(pEncryptedPrivileges.get()), *(pChecksum.get()), *(pEncryptedVisibility.get()), *(pVisibilityChecksum.get()), pPrivilegeList.get());
529                         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred. %ls", packageId.GetPointer());
530
531                         SysLog(NID_SEC, "%ls is in the cache [client]", privilegeInfo.GetAppId().GetPointer());
532                 }
533                 else
534                 {
535                         SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
536                         r =  E_DATA_NOT_FOUND;
537                         goto CATCH;
538                 }
539
540                 ret = privilegeInfo.HasPrivilege(privilege);
541                 if (!ret)
542                 {
543                         r = E_PRIVILEGE_DENIED;
544                         goto CATCH;
545                 }
546         }
547
548         return r;
549
550 CATCH:
551
552         SysLogException(NID_SEC,  r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
553
554         _AppManagerImpl* pAppManagerImpl = _AppManagerImpl::GetInstance();
555         pAppManagerImpl->TerminateApplications(packageId);
556
557         return r;
558 }
559
560 }} //Tizen::Security