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 bool isConstructed = false;
47 static std::unique_ptr<_IpcClient> pIpcClient(null);
48 static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
49 static pthread_once_t ipcOnceBlock = PTHREAD_ONCE_INIT;
51 namespace Tizen { namespace Security
54 _PrivilegeManager* _AccessController::__pPrivilegeManager = null;
56 static std::unique_ptr<String> pEncryptedPrivileges(null);
57 static std::unique_ptr<String> pChecksum(null);
58 static std::unique_ptr<String> pEncryptedVisibility(null);
59 static std::unique_ptr<String> pVisibilityChecksum(null);
60 static std::unique_ptr<ArrayList> pPrivilegeList(null);
62 _AccessController::_AccessController(void)
67 _AccessController::~_AccessController(void)
69 if (pPrivilegeList != null)
71 pPrivilegeList->RemoveAll(true);
76 _AccessController::CheckSystemPrivilege(const PackageId& packageId, _Privilege privilege)
80 SysTryReturnResult(NID_SEC, (privilege >= 0) && (privilege < _MAX_PRIVILEGE_ENUM), E_INVALID_ARG, "The privilege enumerator is invalid");
83 packageId.SubString(0, MAX_APP_ID_SIZE, subAppId);
85 _PackageInfoImpl infoImpl;
86 result r = infoImpl.Construct(subAppId);
87 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
89 String webAppType(L"wgt");
90 String appType = infoImpl.GetAppType();
91 if (appType.Equals(webAppType, true))
96 if (__pPrivilegeManager == null)
98 __pPrivilegeManager = _PrivilegeManager::GetInstance();
100 SysTryReturnResult(NID_SEC, __pPrivilegeManager != null, E_SYSTEM, "An unexpected system error occurred.");
102 std::unique_ptr<_PrivilegeInfo> pPrivilegeInfo(__pPrivilegeManager->RetrievePrivilegeInfoN(subAppId));
109 else if (r == E_DATA_NOT_FOUND)
111 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
116 SysLogException(NID_SEC, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
120 ret = pPrivilegeInfo->HasPrivilege(privilege);
123 r = E_PRIVILEGE_DENIED;
127 r = CheckPrivacy(packageId, privilege);
128 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_USER_NOT_CONSENTED, "The user blocks an application from calling the method.");
134 SysLogException(NID_SEC, r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
136 _AppManagerImpl* pAppManagerImpl = _AppManagerImpl::GetInstance();
137 pAppManagerImpl->TerminateApplications(packageId);
143 _AccessController::CheckSystemPrivilege(const PackageId& packageId, _Privilege privilege1, _Privilege privilege2)
147 SysTryReturnResult(NID_SEC, (privilege1 >= 0) && (privilege1 < _MAX_PRIVILEGE_ENUM), E_INVALID_ARG, "The privilege enumerator is invalid");
148 SysTryReturnResult(NID_SEC, (privilege2 >= 0) && (privilege2 < _MAX_PRIVILEGE_ENUM), E_INVALID_ARG, "The privilege enumerator is invalid");
151 packageId.SubString(0, MAX_APP_ID_SIZE, subAppId);
153 _PackageInfoImpl infoImpl;
154 result r = infoImpl.Construct(subAppId);
155 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
157 String webAppType(L"wgt");
158 String appType = infoImpl.GetAppType();
159 if (appType.Equals(webAppType, true))
164 if (__pPrivilegeManager == null)
166 __pPrivilegeManager = _PrivilegeManager::GetInstance();
168 SysTryReturnResult(NID_SEC, __pPrivilegeManager != null, E_SYSTEM, "An unexpected system error occurred.");
170 std::unique_ptr<_PrivilegeInfo> pPrivilegeInfo(__pPrivilegeManager->RetrievePrivilegeInfoN(subAppId));
177 else if (r == E_DATA_NOT_FOUND)
179 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
184 SysLogException(NID_SEC, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
188 ret = pPrivilegeInfo->HasPrivilegeEx(privilege1);
191 ret = pPrivilegeInfo->HasPrivilege(privilege2);
194 r = E_PRIVILEGE_DENIED;
199 r = CheckPrivacy(packageId, privilege2);
200 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_USER_NOT_CONSENTED, "The user blocks an application from calling the method.");
206 SysLogException(NID_SEC, r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
208 _AppManagerImpl* pAppManagerImpl = _AppManagerImpl::GetInstance();
209 pAppManagerImpl->TerminateApplications(packageId);
215 _AccessController::CheckPrivilege(const PackageId& packageId, const String& privilege)
220 packageId.SubString(0, MAX_APP_ID_SIZE, subAppId);
222 _PackageInfoImpl infoImpl;
223 result r = infoImpl.Construct(subAppId);
224 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
226 String webAppType(L"wgt");
227 String appType = infoImpl.GetAppType();
228 if (appType.Equals(webAppType, true))
233 if (__pPrivilegeManager == null)
235 __pPrivilegeManager = _PrivilegeManager::GetInstance();
237 SysTryReturnResult(NID_SEC, __pPrivilegeManager != null, E_SYSTEM, "An unexpected system error occurred.");
239 std::unique_ptr<_PrivilegeInfo> pPrivilegeInfo(__pPrivilegeManager->RetrievePrivilegeInfoN(subAppId));
246 else if (r == E_DATA_NOT_FOUND)
248 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
253 SysLogException(NID_SEC, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
257 ret = pPrivilegeInfo->HasPrivilege(privilege);
260 r = E_PRIVILEGE_DENIED;
264 r = CheckPrivacy(packageId, privilege);
265 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_USER_NOT_CONSENTED, "The user blocks an application from calling the method.");
271 SysLogException(NID_SEC, r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
273 _AppManagerImpl* pAppManagerImpl = _AppManagerImpl::GetInstance();
274 pAppManagerImpl->TerminateApplications(packageId);
280 _AccessController::InitIpcClient(void)
282 std::unique_ptr<_IpcClient> pLocalIpcClient(new (std::nothrow) _IpcClient);
283 SysTryReturnVoidResult(NID_SEC, pLocalIpcClient != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
285 result r = pLocalIpcClient->Construct(L"osp.security.ipcserver.privilegemanager", null);
286 SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "Failed to construct the instance of IPC.");
288 pIpcClient = std::move(pLocalIpcClient);
293 _AccessController::Initialize(void)
295 result r = E_SUCCESS;
297 if (pIpcClient == null)
299 pthread_once(&ipcOnceBlock, InitIpcClient);
303 ipcOnceBlock = PTHREAD_ONCE_INIT;
304 SysLogException(NID_SEC, r, "[%s] Propagated.", GetErrorMessage(r));
309 pEncryptedPrivileges.reset(new (std::nothrow) String());
310 SysTryReturnVoidResult(NID_SEC, pEncryptedPrivileges != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
312 pChecksum.reset(new (std::nothrow) String());
313 SysTryReturnVoidResult(NID_SEC, pChecksum != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
315 pPrivilegeList.reset(new ArrayList());
316 SysTryReturnVoidResult(NID_SEC, pPrivilegeList != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
317 pPrivilegeList->Construct();
319 std::unique_ptr<IPC::Message> pCipherPrivilegeMessage(new (std::nothrow) PrivilegeManagerMsg_retrieve(pEncryptedPrivileges.get(), pChecksum.get(), pPrivilegeList.get(), &r));
320 SysTryReturnVoidResult(NID_SEC, pCipherPrivilegeMessage != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
322 result ipcResult = pIpcClient->SendRequest(pCipherPrivilegeMessage.get());
323 SysTryReturnVoidResult(NID_SEC, ipcResult == E_SUCCESS, E_SYSTEM, "Failed to send IPC message.");
324 SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, r, "Failed to retrieve privilege information");
326 pEncryptedVisibility.reset(new (std::nothrow) String());
327 SysTryReturnVoidResult(NID_SEC, pEncryptedVisibility != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
329 pVisibilityChecksum.reset(new (std::nothrow) String());
330 SysTryReturnVoidResult(NID_SEC, pVisibilityChecksum != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
332 std::unique_ptr<IPC::Message> pCipherVisibilityMessage(new (std::nothrow) PrivilegeManagerMsg_retrieveEx(pEncryptedVisibility.get(), pVisibilityChecksum.get(), &r));
333 SysTryReturnVoidResult(NID_SEC, pCipherVisibilityMessage != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
335 ipcResult = pIpcClient->SendRequest(pCipherVisibilityMessage.get());
336 SysTryReturnVoidResult(NID_SEC, ipcResult == E_SUCCESS, E_SYSTEM, "Failed to send IPC message.");
337 SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, r, "Failed to retrieve privilege information");
339 isConstructed = true;
344 _AccessController::CheckUserPrivilege(_Privilege privilege)
346 result r = E_SUCCESS;
348 _PrivilegeInfo privilegeInfo;
351 SysTryReturnResult(NID_SEC, (privilege >= 0) && (privilege < _MAX_PRIVILEGE_ENUM), E_INVALID_ARG, "The privilege enumerator is invalid");
353 int appType = _AppInfo::GetAppType();
354 PackageId packageId = _AppInfo::GetPackageId();
355 packageId[0] = packageId[0];
357 if ((appType & _APP_TYPE_WEB_APP) != _APP_TYPE_WEB_APP)
359 if (isConstructed != true)
361 pthread_once(&onceBlock, Initialize);
365 if (r == E_DATA_NOT_FOUND)
367 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
372 onceBlock = PTHREAD_ONCE_INIT;
373 SysLogException(NID_SEC, r, "[%s] Propagated.", GetErrorMessage(r));
379 if ((pEncryptedPrivileges != null) && (pChecksum != null) && (pEncryptedVisibility != null) && (pVisibilityChecksum != null))
381 r = privilegeInfo.Construct(packageId, *(pEncryptedPrivileges.get()), *(pChecksum.get()), *(pEncryptedVisibility.get()), *(pVisibilityChecksum.get()), pPrivilegeList.get());
382 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred. %ls", packageId.GetPointer());
384 SysLog(NID_SEC, "%ls is in the cache [client]", privilegeInfo.GetAppId().GetPointer());
388 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
389 r = E_DATA_NOT_FOUND;
393 ret = privilegeInfo.HasPrivilege(privilege);
396 r = E_PRIVILEGE_DENIED;
401 r = CheckPrivacy(packageId, privilege);
402 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_USER_NOT_CONSENTED, "The user blocks an application from calling the method.");
408 SysLogException(NID_SEC, r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
410 _AppManagerImpl* pAppManagerImpl = _AppManagerImpl::GetInstance();
411 pAppManagerImpl->TerminateApplications(packageId);
418 _AccessController::CheckUserPrivilege(_Privilege privilege1, _Privilege privilege2)
420 result r = E_SUCCESS;
422 _PrivilegeInfo privilegeInfo;
425 SysTryReturnResult(NID_SEC, (privilege1 >= 0) && (privilege1 < _MAX_PRIVILEGE_ENUM), E_INVALID_ARG, "The privilege enumerator is invalid");
426 SysTryReturnResult(NID_SEC, (privilege2 >= 0) && (privilege2 < _MAX_PRIVILEGE_ENUM), E_INVALID_ARG, "The privilege enumerator is invalid");
428 int appType = _AppInfo::GetAppType();
429 PackageId packageId = _AppInfo::GetPackageId();
430 packageId[0] = packageId[0];
432 if ((appType & _APP_TYPE_WEB_APP) != _APP_TYPE_WEB_APP)
434 if (isConstructed != true)
436 pthread_once(&onceBlock, Initialize);
440 if (r == E_DATA_NOT_FOUND)
442 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
447 onceBlock = PTHREAD_ONCE_INIT;
448 SysLogException(NID_SEC, r, "[%s] Propagated.", GetErrorMessage(r));
454 if ((pEncryptedPrivileges != null) && (pChecksum != null) && (pEncryptedVisibility != null) && (pVisibilityChecksum != null))
456 r = privilegeInfo.Construct(packageId, *(pEncryptedPrivileges.get()), *(pChecksum.get()), *(pEncryptedVisibility.get()), *(pVisibilityChecksum.get()), pPrivilegeList.get());
457 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred. %ls", packageId.GetPointer());
459 SysLog(NID_SEC, "%ls is in the cache [client]", privilegeInfo.GetAppId().GetPointer());
463 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
464 r = E_DATA_NOT_FOUND;
468 ret = privilegeInfo.HasPrivilegeEx(privilege1);
471 ret = privilegeInfo.HasPrivilege(privilege2);
474 r = E_PRIVILEGE_DENIED;
480 r = CheckPrivacy(packageId, privilege2);
481 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_USER_NOT_CONSENTED, "The user blocks an application from calling the method.");
487 SysLogException(NID_SEC, r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
489 _AppManagerImpl* pAppManagerImpl = _AppManagerImpl::GetInstance();
490 pAppManagerImpl->TerminateApplications(packageId);
498 _AccessController::CheckPrivilege(const String& privilege)
500 result r = E_SUCCESS;
502 _PrivilegeInfo privilegeInfo;
505 int appType = _AppInfo::GetAppType();
506 PackageId packageId = _AppInfo::GetPackageId();
507 packageId[0] = packageId[0];
509 if ((appType & _APP_TYPE_WEB_APP) != _APP_TYPE_WEB_APP)
511 if (isConstructed != true)
513 pthread_once(&onceBlock, Initialize);
517 if (r == E_DATA_NOT_FOUND)
519 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
524 onceBlock = PTHREAD_ONCE_INIT;
525 SysLogException(NID_SEC, r, "[%s] Propagated.", GetErrorMessage(r));
531 std::unique_ptr<IEnumerator> pEnum(null);
532 pEnum.reset(pPrivilegeList->GetEnumeratorN());
534 if ((pEncryptedPrivileges != null) && (pChecksum != null) && (pEncryptedVisibility != null) && (pVisibilityChecksum != null))
536 r = privilegeInfo.Construct(packageId, *(pEncryptedPrivileges.get()), *(pChecksum.get()), *(pEncryptedVisibility.get()), *(pVisibilityChecksum.get()), pPrivilegeList.get());
537 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred. %ls", packageId.GetPointer());
539 SysLog(NID_SEC, "%ls is in the cache [client]", privilegeInfo.GetAppId().GetPointer());
543 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
544 r = E_DATA_NOT_FOUND;
548 ret = privilegeInfo.HasPrivilege(privilege);
551 r = E_PRIVILEGE_DENIED;
557 r = CheckPrivacy(packageId, privilege);
558 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_USER_NOT_CONSENTED, "The user blocks an application from calling the method.");
564 SysLogException(NID_SEC, r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
566 _AppManagerImpl* pAppManagerImpl = _AppManagerImpl::GetInstance();
567 pAppManagerImpl->TerminateApplications(packageId);
573 _AccessController::CheckPrivacy(const PackageId & packageId, _Privilege privilege)
575 result r = E_SUCCESS;
577 if (privacyListTable[privilege] != true)
582 std::unique_ptr<char[]> pPackageId(null);
583 pPackageId.reset(_StringConverter::CopyToCharArrayN(packageId));
584 SysTryReturnResult(NID_SEC, pPackageId != null, E_SYSTEM, "An unexpected system error occurred.");
586 std::unique_ptr<char[]> pPrivilegeId(null);
587 String privilegeId(L"http://tizen.org/privilege/");
588 privilegeId.Append(privilegeListTable[privilege].privilegeString);
590 pPrivilegeId.reset(_StringConverter::CopyToCharArrayN(privilegeId));
591 SysTryReturnResult(NID_SEC, pPrivilegeId != null, E_SYSTEM, "An unexpected system error occurred.");
593 int ret = privacy_checker_check_package_by_privilege(pPackageId.get(), pPrivilegeId.get());
594 if (ret != PRIV_MGR_ERROR_SUCCESS)
596 r = E_USER_NOT_CONSENTED;
597 SysLog(NID_SEC, "Result : FALSE [Privacy]");
604 _AccessController::CheckPrivacy(const PackageId & packageId, const String& privilege)
606 result r = E_SUCCESS;
608 std::unique_ptr<char[]> pPackageId(null);
609 pPackageId.reset(_StringConverter::CopyToCharArrayN(packageId));
610 SysTryReturnResult(NID_SEC, pPackageId != null, E_SYSTEM, "An unexpected system error occurred.");
612 std::unique_ptr<char[]> pPrivilegeId(null);
613 pPrivilegeId.reset(_StringConverter::CopyToCharArrayN(privilege));
614 SysTryReturnResult(NID_SEC, pPrivilegeId != null, E_SYSTEM, "An unexpected system error occurred.");
616 int ret = privacy_checker_check_package_by_privilege(pPackageId.get(), pPrivilegeId.get());
617 if (ret != PRIV_MGR_ERROR_SUCCESS)
619 r = E_USER_NOT_CONSENTED;
620 SysLog(NID_SEC, "Result : FALSE [Privacy]");