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 <FBaseColArrayListT.h>
32 #include <FBase_StringConverter.h>
34 #include <FIo_IpcClient.h>
35 #include <privacy_checker_client.h>
36 #include "FSec_AccessController.h"
37 #include "FSec_PrivilegeManager.h"
38 #include "FSec_PrivilegeManagerMessage.h"
39 #include "FSec_PrivilegeInfo.h"
41 using namespace Tizen::App;
42 using namespace Tizen::App::Package;
43 using namespace Tizen::Base;
44 using namespace Tizen::Base::Collection;
45 using namespace Tizen::Io;
47 static bool isConstructed = false;
48 static std::unique_ptr<_IpcClient> pIpcClient(null);
49 static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
50 static pthread_once_t ipcOnceBlock = PTHREAD_ONCE_INIT;
52 namespace Tizen { namespace Security
55 _PrivilegeManager* _AccessController::__pPrivilegeManager = null;
57 static std::unique_ptr<String> pEncryptedPrivileges(null);
58 static std::unique_ptr<String> pChecksum(null);
59 static std::unique_ptr<String> pEncryptedVisibility(null);
60 static std::unique_ptr<String> pVisibilityChecksum(null);
61 static std::unique_ptr<ArrayList> pPrivilegeList(null);
63 _AccessController::_AccessController(void)
68 _AccessController::~_AccessController(void)
70 if (pPrivilegeList != null)
72 pPrivilegeList->RemoveAll(true);
77 _AccessController::CheckSystemPrivilege(const PackageId& packageId, _Privilege privilege)
81 SysTryReturnResult(NID_SEC, (privilege >= 0) && (privilege < _MAX_PRIVILEGE_ENUM), E_INVALID_ARG, "The privilege enumerator is invalid");
84 packageId.SubString(0, MAX_APP_ID_SIZE, subAppId);
86 _PackageInfoImpl infoImpl;
87 result r = infoImpl.Construct(subAppId);
88 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
90 String webAppType(L"wgt");
91 String appType = infoImpl.GetAppType();
92 if (appType.Equals(webAppType, true))
97 if (__pPrivilegeManager == null)
99 __pPrivilegeManager = _PrivilegeManager::GetInstance();
101 SysTryReturnResult(NID_SEC, __pPrivilegeManager != null, E_SYSTEM, "An unexpected system error occurred.");
103 std::unique_ptr<_PrivilegeInfo> pPrivilegeInfo(__pPrivilegeManager->RetrievePrivilegeInfoN(subAppId));
110 else if (r == E_DATA_NOT_FOUND)
112 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
117 SysLogException(NID_SEC, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
121 ret = pPrivilegeInfo->HasPrivilege(privilege);
124 r = E_PRIVILEGE_DENIED;
128 r = CheckPrivacy(packageId, privilege);
129 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_USER_NOT_CONSENTED, "The user blocks an application from calling the method.");
135 SysLogException(NID_SEC, r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
137 _AppManagerImpl* pAppManagerImpl = _AppManagerImpl::GetInstance();
138 pAppManagerImpl->TerminateApplications(packageId);
144 _AccessController::CheckSystemPrivilege(const PackageId& packageId, _Privilege privilege1, _Privilege privilege2)
148 SysTryReturnResult(NID_SEC, (privilege1 >= 0) && (privilege1 < _MAX_PRIVILEGE_ENUM), E_INVALID_ARG, "The privilege enumerator is invalid");
149 SysTryReturnResult(NID_SEC, (privilege2 >= 0) && (privilege2 < _MAX_PRIVILEGE_ENUM), E_INVALID_ARG, "The privilege enumerator is invalid");
152 packageId.SubString(0, MAX_APP_ID_SIZE, subAppId);
154 _PackageInfoImpl infoImpl;
155 result r = infoImpl.Construct(subAppId);
156 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
158 String webAppType(L"wgt");
159 String appType = infoImpl.GetAppType();
160 if (appType.Equals(webAppType, true))
165 if (__pPrivilegeManager == null)
167 __pPrivilegeManager = _PrivilegeManager::GetInstance();
169 SysTryReturnResult(NID_SEC, __pPrivilegeManager != null, E_SYSTEM, "An unexpected system error occurred.");
171 std::unique_ptr<_PrivilegeInfo> pPrivilegeInfo(__pPrivilegeManager->RetrievePrivilegeInfoN(subAppId));
178 else if (r == E_DATA_NOT_FOUND)
180 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
185 SysLogException(NID_SEC, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
189 ret = pPrivilegeInfo->HasPrivilegeEx(privilege1);
192 ret = pPrivilegeInfo->HasPrivilege(privilege2);
195 r = E_PRIVILEGE_DENIED;
200 r = CheckPrivacy(packageId, privilege2);
201 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_USER_NOT_CONSENTED, "The user blocks an application from calling the method.");
207 SysLogException(NID_SEC, r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
209 _AppManagerImpl* pAppManagerImpl = _AppManagerImpl::GetInstance();
210 pAppManagerImpl->TerminateApplications(packageId);
216 _AccessController::CheckPrivilege(const PackageId& packageId, const String& privilege)
221 packageId.SubString(0, MAX_APP_ID_SIZE, subAppId);
223 _PackageInfoImpl infoImpl;
224 result r = infoImpl.Construct(subAppId);
225 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
227 String webAppType(L"wgt");
228 String appType = infoImpl.GetAppType();
229 if (appType.Equals(webAppType, true))
234 if (__pPrivilegeManager == null)
236 __pPrivilegeManager = _PrivilegeManager::GetInstance();
238 SysTryReturnResult(NID_SEC, __pPrivilegeManager != null, E_SYSTEM, "An unexpected system error occurred.");
240 std::unique_ptr<_PrivilegeInfo> pPrivilegeInfo(__pPrivilegeManager->RetrievePrivilegeInfoN(subAppId));
247 else if (r == E_DATA_NOT_FOUND)
249 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
254 SysLogException(NID_SEC, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
258 ret = pPrivilegeInfo->HasPrivilege(privilege);
261 r = E_PRIVILEGE_DENIED;
265 r = CheckPrivacy(packageId, privilege);
266 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_USER_NOT_CONSENTED, "The user blocks an application from calling the method.");
272 SysLogException(NID_SEC, r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
274 _AppManagerImpl* pAppManagerImpl = _AppManagerImpl::GetInstance();
275 pAppManagerImpl->TerminateApplications(packageId);
281 _AccessController::InitIpcClient(void)
283 std::unique_ptr<_IpcClient> pLocalIpcClient(new (std::nothrow) _IpcClient);
284 SysTryReturnVoidResult(NID_SEC, pLocalIpcClient != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
286 result r = pLocalIpcClient->Construct(L"osp.security.ipcserver.privilegemanager", null);
287 SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "Failed to construct the instance of IPC.");
289 pIpcClient = std::move(pLocalIpcClient);
294 _AccessController::Initialize(void)
296 result r = E_SUCCESS;
298 if (pIpcClient == null)
300 pthread_once(&ipcOnceBlock, InitIpcClient);
304 ipcOnceBlock = PTHREAD_ONCE_INIT;
305 SysLogException(NID_SEC, r, "[%s] Propagated.", GetErrorMessage(r));
310 pEncryptedPrivileges.reset(new (std::nothrow) String());
311 SysTryReturnVoidResult(NID_SEC, pEncryptedPrivileges != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
313 pChecksum.reset(new (std::nothrow) String());
314 SysTryReturnVoidResult(NID_SEC, pChecksum != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
316 std::unique_ptr< ArrayListT< String > > pPrivilegeListT(new ArrayListT< String >());
317 SysTryReturnVoidResult(NID_SEC, pPrivilegeListT != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
319 pPrivilegeListT->Construct();
321 std::unique_ptr<IPC::Message> pCipherPrivilegeMessage(new (std::nothrow) PrivilegeManagerMsg_retrieve(pEncryptedPrivileges.get(), pChecksum.get(), pPrivilegeListT.get(), &r));
322 SysTryReturnVoidResult(NID_SEC, pCipherPrivilegeMessage != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
324 result ipcResult = pIpcClient->SendRequest(pCipherPrivilegeMessage.get());
325 SysTryReturnVoidResult(NID_SEC, ipcResult == E_SUCCESS, E_SYSTEM, "Failed to send IPC message.");
326 SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, r, "Failed to retrieve privilege information");
328 pPrivilegeList.reset(new ArrayList(SingleObjectDeleter));
329 SysTryReturnVoidResult(NID_SEC, pPrivilegeList != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
330 pPrivilegeList->Construct();
332 std::unique_ptr<IEnumeratorT< String > > pEnum(pPrivilegeListT->GetEnumeratorN());
333 while (pEnum->MoveNext() == E_SUCCESS)
336 pEnum->GetCurrent(tempString);
337 pPrivilegeList->Add(new String(tempString));
339 pPrivilegeListT->RemoveAll();
341 pEncryptedVisibility.reset(new (std::nothrow) String());
342 SysTryReturnVoidResult(NID_SEC, pEncryptedVisibility != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
344 pVisibilityChecksum.reset(new (std::nothrow) String());
345 SysTryReturnVoidResult(NID_SEC, pVisibilityChecksum != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
347 std::unique_ptr<IPC::Message> pCipherVisibilityMessage(new (std::nothrow) PrivilegeManagerMsg_retrieveEx(pEncryptedVisibility.get(), pVisibilityChecksum.get(), &r));
348 SysTryReturnVoidResult(NID_SEC, pCipherVisibilityMessage != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
350 ipcResult = pIpcClient->SendRequest(pCipherVisibilityMessage.get());
351 SysTryReturnVoidResult(NID_SEC, ipcResult == E_SUCCESS, E_SYSTEM, "Failed to send IPC message.");
352 SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, r, "Failed to retrieve privilege information");
354 isConstructed = true;
359 _AccessController::CheckUserPrivilege(_Privilege privilege)
361 result r = E_SUCCESS;
363 _PrivilegeInfo privilegeInfo;
366 SysTryReturnResult(NID_SEC, (privilege >= 0) && (privilege < _MAX_PRIVILEGE_ENUM), E_INVALID_ARG, "The privilege enumerator is invalid");
368 int appType = _AppInfo::GetAppType();
369 PackageId packageId = _AppInfo::GetPackageId();
370 packageId[0] = packageId[0];
372 if ((appType & _APP_TYPE_WEB_APP) != _APP_TYPE_WEB_APP)
374 if (isConstructed != true)
376 pthread_once(&onceBlock, Initialize);
380 if (r == E_DATA_NOT_FOUND)
382 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
387 onceBlock = PTHREAD_ONCE_INIT;
388 SysLogException(NID_SEC, r, "[%s] Propagated.", GetErrorMessage(r));
394 if ((pEncryptedPrivileges != null) && (pChecksum != null) && (pEncryptedVisibility != null) && (pVisibilityChecksum != null))
396 r = privilegeInfo.Construct(packageId, *(pEncryptedPrivileges.get()), *(pChecksum.get()), *(pEncryptedVisibility.get()), *(pVisibilityChecksum.get()), pPrivilegeList.get());
397 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred. %ls", packageId.GetPointer());
399 SysLog(NID_SEC, "%ls is in the cache [client]", privilegeInfo.GetAppId().GetPointer());
403 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
404 r = E_DATA_NOT_FOUND;
408 ret = privilegeInfo.HasPrivilege(privilege);
411 r = E_PRIVILEGE_DENIED;
416 r = CheckPrivacy(packageId, privilege);
417 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_USER_NOT_CONSENTED, "The user blocks an application from calling the method.");
423 SysLogException(NID_SEC, r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
425 _AppManagerImpl* pAppManagerImpl = _AppManagerImpl::GetInstance();
426 pAppManagerImpl->TerminateApplications(packageId);
433 _AccessController::CheckUserPrivilege(_Privilege privilege1, _Privilege privilege2)
435 result r = E_SUCCESS;
437 _PrivilegeInfo privilegeInfo;
440 SysTryReturnResult(NID_SEC, (privilege1 >= 0) && (privilege1 < _MAX_PRIVILEGE_ENUM), E_INVALID_ARG, "The privilege enumerator is invalid");
441 SysTryReturnResult(NID_SEC, (privilege2 >= 0) && (privilege2 < _MAX_PRIVILEGE_ENUM), E_INVALID_ARG, "The privilege enumerator is invalid");
443 int appType = _AppInfo::GetAppType();
444 PackageId packageId = _AppInfo::GetPackageId();
445 packageId[0] = packageId[0];
447 if ((appType & _APP_TYPE_WEB_APP) != _APP_TYPE_WEB_APP)
449 if (isConstructed != true)
451 pthread_once(&onceBlock, Initialize);
455 if (r == E_DATA_NOT_FOUND)
457 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
462 onceBlock = PTHREAD_ONCE_INIT;
463 SysLogException(NID_SEC, r, "[%s] Propagated.", GetErrorMessage(r));
469 if ((pEncryptedPrivileges != null) && (pChecksum != null) && (pEncryptedVisibility != null) && (pVisibilityChecksum != null))
471 r = privilegeInfo.Construct(packageId, *(pEncryptedPrivileges.get()), *(pChecksum.get()), *(pEncryptedVisibility.get()), *(pVisibilityChecksum.get()), pPrivilegeList.get());
472 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred. %ls", packageId.GetPointer());
474 SysLog(NID_SEC, "%ls is in the cache [client]", privilegeInfo.GetAppId().GetPointer());
478 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
479 r = E_DATA_NOT_FOUND;
483 ret = privilegeInfo.HasPrivilegeEx(privilege1);
486 ret = privilegeInfo.HasPrivilege(privilege2);
489 r = E_PRIVILEGE_DENIED;
495 r = CheckPrivacy(packageId, privilege2);
496 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_USER_NOT_CONSENTED, "The user blocks an application from calling the method.");
502 SysLogException(NID_SEC, r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
504 _AppManagerImpl* pAppManagerImpl = _AppManagerImpl::GetInstance();
505 pAppManagerImpl->TerminateApplications(packageId);
513 _AccessController::CheckPrivilege(const String& privilege)
515 result r = E_SUCCESS;
517 _PrivilegeInfo privilegeInfo;
520 int appType = _AppInfo::GetAppType();
521 PackageId packageId = _AppInfo::GetPackageId();
522 packageId[0] = packageId[0];
524 if ((appType & _APP_TYPE_WEB_APP) != _APP_TYPE_WEB_APP)
526 if (isConstructed != true)
528 pthread_once(&onceBlock, Initialize);
532 if (r == E_DATA_NOT_FOUND)
534 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
539 onceBlock = PTHREAD_ONCE_INIT;
540 SysLogException(NID_SEC, r, "[%s] Propagated.", GetErrorMessage(r));
546 std::unique_ptr<IEnumerator> pEnum(null);
547 pEnum.reset(pPrivilegeList->GetEnumeratorN());
549 if ((pEncryptedPrivileges != null) && (pChecksum != null) && (pEncryptedVisibility != null) && (pVisibilityChecksum != null))
551 r = privilegeInfo.Construct(packageId, *(pEncryptedPrivileges.get()), *(pChecksum.get()), *(pEncryptedVisibility.get()), *(pVisibilityChecksum.get()), pPrivilegeList.get());
552 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred. %ls", packageId.GetPointer());
554 SysLog(NID_SEC, "%ls is in the cache [client]", privilegeInfo.GetAppId().GetPointer());
558 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
559 r = E_DATA_NOT_FOUND;
563 ret = privilegeInfo.HasPrivilege(privilege);
566 r = E_PRIVILEGE_DENIED;
572 r = CheckPrivacy(packageId, privilege);
573 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_USER_NOT_CONSENTED, "The user blocks an application from calling the method.");
579 SysLogException(NID_SEC, r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
581 _AppManagerImpl* pAppManagerImpl = _AppManagerImpl::GetInstance();
582 pAppManagerImpl->TerminateApplications(packageId);
588 _AccessController::CheckPrivacy(const PackageId & packageId, _Privilege privilege)
590 result r = E_SUCCESS;
592 if (privacyListTable[privilege] != true)
597 std::unique_ptr<char[]> pPackageId(null);
598 pPackageId.reset(_StringConverter::CopyToCharArrayN(packageId));
599 SysTryReturnResult(NID_SEC, pPackageId != null, E_SYSTEM, "An unexpected system error occurred.");
601 std::unique_ptr<char[]> pPrivilegeId(null);
602 String privilegeId(L"http://tizen.org/privilege/");
603 privilegeId.Append(privilegeListTable[privilege].privilegeString);
605 pPrivilegeId.reset(_StringConverter::CopyToCharArrayN(privilegeId));
606 SysTryReturnResult(NID_SEC, pPrivilegeId != null, E_SYSTEM, "An unexpected system error occurred.");
608 int ret = privacy_checker_check_package_by_privilege(pPackageId.get(), pPrivilegeId.get());
609 if (ret != PRIV_MGR_ERROR_SUCCESS)
611 r = E_USER_NOT_CONSENTED;
612 SysLog(NID_SEC, "Result: FALSE [Privacy]");
619 _AccessController::CheckPrivacy(const PackageId & packageId, const String& privilege)
621 result r = E_SUCCESS;
623 std::unique_ptr<char[]> pPackageId(null);
624 pPackageId.reset(_StringConverter::CopyToCharArrayN(packageId));
625 SysTryReturnResult(NID_SEC, pPackageId != null, E_SYSTEM, "An unexpected system error occurred.");
627 std::unique_ptr<char[]> pPrivilegeId(null);
628 pPrivilegeId.reset(_StringConverter::CopyToCharArrayN(privilege));
629 SysTryReturnResult(NID_SEC, pPrivilegeId != null, E_SYSTEM, "An unexpected system error occurred.");
631 int ret = privacy_checker_check_package_by_privilege(pPackageId.get(), pPrivilegeId.get());
632 if (ret != PRIV_MGR_ERROR_SUCCESS)
634 r = E_USER_NOT_CONSENTED;
635 SysLog(NID_SEC, "Result: FALSE [Privacy]");