2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @file FSec_AccessController.cpp
19 * @brief This is the implementation for the _AccessController class.
22 #include <unique_ptr.h>
23 #include <FAppTypes.h>
24 #include <FAppApplication.h>
25 #include <FApp_AppInfo.h>
26 #include <FApp_AppManagerImpl.h>
27 #include <FAppPkg_PackageInfoImpl.h>
28 #include <FBaseSysLog.h>
29 #include <FBaseString.h>
30 #include <FBaseColArrayList.h>
31 #include <FBase_StringConverter.h>
33 #include <FIo_IpcClient.h>
34 #include <privacy_checker_client.h>
35 #include "FSec_AccessController.h"
36 #include "FSec_PrivilegeManager.h"
37 #include "FSec_PrivilegeManagerMessage.h"
38 #include "FSec_PrivilegeInfo.h"
40 using namespace Tizen::App;
41 using namespace Tizen::App::Package;
42 using namespace Tizen::Base;
43 using namespace Tizen::Base::Collection;
44 using namespace Tizen::Io;
46 static _IpcClient ipcClient;
47 static bool isConstructed = false;
48 static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
50 namespace Tizen { namespace Security
53 _PrivilegeManager* _AccessController::__pPrivilegeManager = null;
55 static std::unique_ptr<String> pEncryptedPrivileges(null);
56 static std::unique_ptr<String> pChecksum(null);
57 static std::unique_ptr<String> pEncryptedVisibility(null);
58 static std::unique_ptr<String> pVisibilityChecksum(null);
59 static std::unique_ptr<ArrayList> pPrivilegeList(null);
61 _AccessController::_AccessController(void)
66 _AccessController::~_AccessController(void)
68 if (pPrivilegeList != null)
70 pPrivilegeList->RemoveAll(true);
75 _AccessController::CheckSystemPrivilege(const PackageId& packageId, _Privilege privilege)
80 std::unique_ptr<_PrivilegeInfo> pPrivilegeInfo(null);
82 _PackageInfoImpl infoImpl;
84 String webAppType(L"wgt");
86 SysTryReturnResult(NID_SEC, privilege < _MAX_PRIVILEGE_ENUM, E_INVALID_ARG, "The privilege enumerator is invalid");
88 packageId.SubString(0, MAX_APP_ID_SIZE, subAppId);
90 r = infoImpl.Construct(subAppId);
91 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
93 appType = infoImpl.GetAppType();
94 if (appType.Equals(webAppType, true))
99 if (__pPrivilegeManager == null)
101 __pPrivilegeManager = _PrivilegeManager::GetInstance();
103 SysTryReturnResult(NID_SEC, __pPrivilegeManager != null, E_SYSTEM, "An unexpected system error occurred.");
105 pPrivilegeInfo.reset(__pPrivilegeManager->RetrievePrivilegeInfoN(subAppId));
112 else if (r == E_DATA_NOT_FOUND)
114 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
119 SysLogException(NID_SEC, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
123 ret = pPrivilegeInfo->HasPrivilege(privilege);
126 r = E_PRIVILEGE_DENIED;
130 r = CheckPrivacy(packageId, privilege);
131 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_USER_NOT_CONSENTED, "The user blocks an application from calling the method.");
137 SysLogException(NID_SEC, r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
139 _AppManagerImpl* pAppManagerImpl = _AppManagerImpl::GetInstance();
140 pAppManagerImpl->TerminateApplications(packageId);
146 _AccessController::CheckSystemPrivilege(const PackageId& packageId, _Privilege privilege1, _Privilege privilege2)
148 result r = E_SUCCESS;
151 std::unique_ptr<_PrivilegeInfo> pPrivilegeInfo(null);
153 _PackageInfoImpl infoImpl;
155 String webAppType(L"wgt");
157 SysTryReturnResult(NID_SEC, privilege1 < _MAX_PRIVILEGE_ENUM, E_INVALID_ARG, "The privilege enumerator is invalid");
158 SysTryReturnResult(NID_SEC, privilege2 < _MAX_PRIVILEGE_ENUM, E_INVALID_ARG, "The privilege enumerator is invalid");
160 packageId.SubString(0, MAX_APP_ID_SIZE, subAppId);
162 r = infoImpl.Construct(subAppId);
163 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
165 appType = infoImpl.GetAppType();
166 if (appType.Equals(webAppType, true))
171 if (__pPrivilegeManager == null)
173 __pPrivilegeManager = _PrivilegeManager::GetInstance();
175 SysTryReturnResult(NID_SEC, __pPrivilegeManager != null, E_SYSTEM, "An unexpected system error occurred.");
177 pPrivilegeInfo.reset(__pPrivilegeManager->RetrievePrivilegeInfoN(subAppId));
184 else if (r == E_DATA_NOT_FOUND)
186 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
191 SysLogException(NID_SEC, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
195 ret = pPrivilegeInfo->HasPrivilegeEx(privilege1);
198 ret = pPrivilegeInfo->HasPrivilege(privilege2);
201 r = E_PRIVILEGE_DENIED;
206 r = CheckPrivacy(packageId, privilege2);
207 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_USER_NOT_CONSENTED, "The user blocks an application from calling the method.");
213 SysLogException(NID_SEC, r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
215 _AppManagerImpl* pAppManagerImpl = _AppManagerImpl::GetInstance();
216 pAppManagerImpl->TerminateApplications(packageId);
222 _AccessController::CheckPrivilege(const PackageId& packageId, const String& privilege)
224 result r = E_SUCCESS;
227 std::unique_ptr<_PrivilegeInfo> pPrivilegeInfo(null);
229 _PackageInfoImpl infoImpl;
231 String webAppType(L"wgt");
233 packageId.SubString(0, MAX_APP_ID_SIZE, subAppId);
235 r = infoImpl.Construct(subAppId);
236 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
238 appType = infoImpl.GetAppType();
239 if (appType.Equals(webAppType, true))
244 if (__pPrivilegeManager == null)
246 __pPrivilegeManager = _PrivilegeManager::GetInstance();
248 SysTryReturnResult(NID_SEC, __pPrivilegeManager != null, E_SYSTEM, "An unexpected system error occurred.");
250 pPrivilegeInfo.reset(__pPrivilegeManager->RetrievePrivilegeInfoN(subAppId));
257 else if (r == E_DATA_NOT_FOUND)
259 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
264 SysLogException(NID_SEC, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
268 ret = pPrivilegeInfo->HasPrivilege(privilege);
271 r = E_PRIVILEGE_DENIED;
275 r = CheckPrivacy(packageId, privilege);
276 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_USER_NOT_CONSENTED, "The user blocks an application from calling the method.");
282 SysLogException(NID_SEC, r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
284 _AppManagerImpl* pAppManagerImpl = _AppManagerImpl::GetInstance();
285 pAppManagerImpl->TerminateApplications(packageId);
291 _AccessController::Initialize(void)
293 result r = E_SUCCESS;
294 result ipcResult = E_SUCCESS;
296 std::unique_ptr<IPC::Message> pCipherPrivilegeMessage(null);
297 std::unique_ptr<IPC::Message> pCipherVisibilityMessage(null);
299 r = ipcClient.Construct(L"osp.security.ipcserver.privilegemanager", null);
300 SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "Failed to construct the instance of IPC.");
302 pEncryptedPrivileges.reset(new (std::nothrow) String());
303 SysTryReturnVoidResult(NID_SEC, pEncryptedPrivileges != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
305 pChecksum.reset(new (std::nothrow) String());
306 SysTryReturnVoidResult(NID_SEC, pChecksum != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
308 pPrivilegeList.reset(new ArrayList());
309 SysTryReturnVoidResult(NID_SEC, pPrivilegeList != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
311 pPrivilegeList->Construct();
313 pCipherPrivilegeMessage.reset(new (std::nothrow) PrivilegeManagerMsg_retrieve(pEncryptedPrivileges.get(), pChecksum.get(), pPrivilegeList.get(), &r));
314 SysTryReturnVoidResult(NID_SEC, pCipherPrivilegeMessage != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
316 ipcResult = ipcClient.SendRequest(pCipherPrivilegeMessage.get());
317 SysTryReturnVoidResult(NID_SEC, ipcResult == E_SUCCESS, E_SYSTEM, "Failed to send IPC message.");
318 SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, r, "Failed to retrieve privilege information");
320 pEncryptedVisibility.reset(new (std::nothrow) String());
321 SysTryReturnVoidResult(NID_SEC, pEncryptedVisibility != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
323 pVisibilityChecksum.reset(new (std::nothrow) String());
324 SysTryReturnVoidResult(NID_SEC, pVisibilityChecksum != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
326 pCipherVisibilityMessage.reset(new (std::nothrow) PrivilegeManagerMsg_retrieveEx(pEncryptedVisibility.get(), pVisibilityChecksum.get(), &r));
327 SysTryReturnVoidResult(NID_SEC, pCipherVisibilityMessage != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
329 ipcResult = ipcClient.SendRequest(pCipherVisibilityMessage.get());
330 SysTryReturnVoidResult(NID_SEC, ipcResult == E_SUCCESS, E_SYSTEM, "Failed to send IPC message.");
331 SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, r, "Failed to retrieve privilege information");
333 isConstructed = true;
339 _AccessController::CheckUserPrivilege(_Privilege privilege)
341 result r = E_SUCCESS;
344 _PrivilegeInfo privilegeInfo;
348 SysTryReturnResult(NID_SEC, privilege < _MAX_PRIVILEGE_ENUM, E_INVALID_ARG, "The privilege enumerator is invalid");
349 //SysAssertf(privilegeLevelListTable[privilege][_PRV_API_VER_2_0] == _PRV_LEVEL_USER, "System-level privilege is passed to CheckUserPrivilege.");
351 int appType = _AppInfo::GetAppType();
352 PackageId packageId = _AppInfo::GetPackageId();
353 packageId[0] = packageId[0];
355 if ((appType & _APP_TYPE_WEB_APP) != _APP_TYPE_WEB_APP)
357 if (isConstructed != true)
359 pthread_once(&onceBlock, Initialize);
363 if (r == E_DATA_NOT_FOUND)
365 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
370 onceBlock = PTHREAD_ONCE_INIT;
371 SysLogException(NID_SEC, r, "[%s] Propagated.", GetErrorMessage(r));
377 if ((pEncryptedPrivileges != null) && (pChecksum != null) && (pEncryptedVisibility != null) && (pVisibilityChecksum != null))
379 r = privilegeInfo.Construct(packageId, *(pEncryptedPrivileges.get()), *(pChecksum.get()), *(pEncryptedVisibility.get()), *(pVisibilityChecksum.get()), pPrivilegeList.get());
380 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred. %ls", packageId.GetPointer());
382 SysLog(NID_SEC, "%ls is in the cache [client]", privilegeInfo.GetAppId().GetPointer());
386 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
387 r = E_DATA_NOT_FOUND;
391 ret = privilegeInfo.HasPrivilege(privilege);
394 r = E_PRIVILEGE_DENIED;
399 r = CheckPrivacy(packageId, privilege);
400 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_USER_NOT_CONSENTED, "The user blocks an application from calling the method.");
406 SysLogException(NID_SEC, r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
408 _AppManagerImpl* pAppManagerImpl = _AppManagerImpl::GetInstance();
409 pAppManagerImpl->TerminateApplications(packageId);
416 _AccessController::CheckUserPrivilege(_Privilege privilege1, _Privilege privilege2)
418 result r = E_SUCCESS;
421 _PrivilegeInfo privilegeInfo;
425 SysTryReturnResult(NID_SEC, privilege1 < _MAX_PRIVILEGE_ENUM, E_INVALID_ARG, "The privilege enumerator is invalid");
426 SysTryReturnResult(NID_SEC, privilege2 < _MAX_PRIVILEGE_ENUM, E_INVALID_ARG, "The privilege enumerator is invalid");
427 //SysAssertf(privilegeLevelListTable[privilege][_PRV_API_VER_2_0] == _PRV_LEVEL_USER, "System-level privilege is passed to CheckUserPrivilege.");
429 int appType = _AppInfo::GetAppType();
430 PackageId packageId = _AppInfo::GetPackageId();
431 packageId[0] = packageId[0];
433 if ((appType & _APP_TYPE_WEB_APP) != _APP_TYPE_WEB_APP)
435 if (isConstructed != true)
437 pthread_once(&onceBlock, Initialize);
441 if (r == E_DATA_NOT_FOUND)
443 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
448 onceBlock = PTHREAD_ONCE_INIT;
449 SysLogException(NID_SEC, r, "[%s] Propagated.", GetErrorMessage(r));
455 if ((pEncryptedPrivileges != null) && (pChecksum != null) && (pEncryptedVisibility != null) && (pVisibilityChecksum != null))
457 r = privilegeInfo.Construct(packageId, *(pEncryptedPrivileges.get()), *(pChecksum.get()), *(pEncryptedVisibility.get()), *(pVisibilityChecksum.get()), pPrivilegeList.get());
458 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred. %ls", packageId.GetPointer());
460 SysLog(NID_SEC, "%ls is in the cache [client]", privilegeInfo.GetAppId().GetPointer());
464 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
465 r = E_DATA_NOT_FOUND;
469 ret = privilegeInfo.HasPrivilegeEx(privilege1);
472 ret = privilegeInfo.HasPrivilege(privilege2);
475 r = E_PRIVILEGE_DENIED;
481 r = CheckPrivacy(packageId, privilege2);
482 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_USER_NOT_CONSENTED, "The user blocks an application from calling the method.");
488 SysLogException(NID_SEC, r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
490 _AppManagerImpl* pAppManagerImpl = _AppManagerImpl::GetInstance();
491 pAppManagerImpl->TerminateApplications(packageId);
499 _AccessController::CheckPrivilege(const String& privilege)
501 result r = E_SUCCESS;
504 _PrivilegeInfo privilegeInfo;
508 int appType = _AppInfo::GetAppType();
509 PackageId packageId = _AppInfo::GetPackageId();
510 packageId[0] = packageId[0];
512 if ((appType & _APP_TYPE_WEB_APP) != _APP_TYPE_WEB_APP)
514 if (isConstructed != true)
516 pthread_once(&onceBlock, Initialize);
520 if (r == E_DATA_NOT_FOUND)
522 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
527 onceBlock = PTHREAD_ONCE_INIT;
528 SysLogException(NID_SEC, r, "[%s] Propagated.", GetErrorMessage(r));
534 std::unique_ptr<IEnumerator> pEnum(null);
535 pEnum.reset(pPrivilegeList->GetEnumeratorN());
537 if ((pEncryptedPrivileges != null) && (pChecksum != null) && (pEncryptedVisibility != null) && (pVisibilityChecksum != null))
539 r = privilegeInfo.Construct(packageId, *(pEncryptedPrivileges.get()), *(pChecksum.get()), *(pEncryptedVisibility.get()), *(pVisibilityChecksum.get()), pPrivilegeList.get());
540 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred. %ls", packageId.GetPointer());
542 SysLog(NID_SEC, "%ls is in the cache [client]", privilegeInfo.GetAppId().GetPointer());
546 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
547 r = E_DATA_NOT_FOUND;
551 ret = privilegeInfo.HasPrivilege(privilege);
554 r = E_PRIVILEGE_DENIED;
560 r = CheckPrivacy(packageId, privilege);
561 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_USER_NOT_CONSENTED, "The user blocks an application from calling the method.");
567 SysLogException(NID_SEC, r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
569 _AppManagerImpl* pAppManagerImpl = _AppManagerImpl::GetInstance();
570 pAppManagerImpl->TerminateApplications(packageId);
576 _AccessController::CheckPrivacy(const PackageId & packageId, _Privilege privilege)
578 result r = E_SUCCESS;
579 int ret = PRIV_MGR_ERROR_SUCCESS;
581 if (privacyListTable[privilege][_PRV_API_VER_2_0] != true)
586 std::unique_ptr<char[]> pPackageId(null);
587 pPackageId.reset(_StringConverter::CopyToCharArrayN(packageId));
588 SysTryReturnResult(NID_SEC, pPackageId != null, E_SYSTEM, "An unexpected system error occurred.");
590 std::unique_ptr<char[]> pPrivilegeId(null);
591 String privilegeId(L"http://tizen.org/privilege/");
592 privilegeId.Append(privilegeListTable[privilege].privilegeString);
594 pPrivilegeId.reset(_StringConverter::CopyToCharArrayN(privilegeId));
595 SysTryReturnResult(NID_SEC, pPrivilegeId != null, E_SYSTEM, "An unexpected system error occurred.");
597 ret = privacy_checker_check_package_by_privilege(pPackageId.get(), pPrivilegeId.get());
598 if (ret != PRIV_MGR_ERROR_SUCCESS)
600 r = E_USER_NOT_CONSENTED;
601 SysLog(NID_SEC, "Result : FALSE [Privacy]");
608 _AccessController::CheckPrivacy(const PackageId & packageId, const String& privilege)
610 result r = E_SUCCESS;
611 int ret = PRIV_MGR_ERROR_SUCCESS;
613 std::unique_ptr<char[]> pPackageId(null);
614 pPackageId.reset(_StringConverter::CopyToCharArrayN(packageId));
615 SysTryReturnResult(NID_SEC, pPackageId != null, E_SYSTEM, "An unexpected system error occurred.");
617 std::unique_ptr<char[]> pPrivilegeId(null);
618 pPrivilegeId.reset(_StringConverter::CopyToCharArrayN(privilege));
619 SysTryReturnResult(NID_SEC, pPrivilegeId != null, E_SYSTEM, "An unexpected system error occurred.");
621 ret = privacy_checker_check_package_by_privilege(pPackageId.get(), pPrivilegeId.get());
622 if (ret != PRIV_MGR_ERROR_SUCCESS)
624 r = E_USER_NOT_CONSENTED;
625 SysLog(NID_SEC, "Result : FALSE [Privacy]");