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 FSecAccessController.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 <FBaseColIEnumeratorT.h>
34 #include <FIo_IpcClient.h>
35 #include <FSecAccessController.h>
36 #include <FSec_AccessController.h>
37 #include "FSec_AccessControlTypes.h"
38 #include "FSec_PrivilegeManager.h"
39 #include "FSec_PrivilegeManagerMessage.h"
40 #include "FSec_PrivilegeInfo.h"
43 using namespace Tizen::App;
44 using namespace Tizen::App::Package;
45 using namespace Tizen::Base;
46 using namespace Tizen::Base::Collection;
47 using namespace Tizen::Io;
49 static bool isConstructed = false;
50 static std::unique_ptr<_IpcClient> pIpcClient(null);
51 static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
52 static pthread_once_t ipcOnceBlock = PTHREAD_ONCE_INIT;
54 namespace Tizen { namespace Security
57 AccessController::AccessController(void)
62 AccessController::~AccessController(void)
67 static _PrivilegeInfo privilegeInfo;
71 AccessController::InitIpcClient(void)
73 std::unique_ptr<_IpcClient> pLocalIpcClient(new (std::nothrow) _IpcClient);
74 SysTryReturnVoidResult(NID_SEC, pLocalIpcClient != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
76 result r = pLocalIpcClient->Construct(L"osp.security.ipcserver.privilegemanager", null);
77 SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "Failed to construct the instance of IPC.");
79 pIpcClient = std::move(pLocalIpcClient);
84 AccessController::Initialize(void)
88 if (pIpcClient == null)
90 pthread_once(&ipcOnceBlock, InitIpcClient);
94 ipcOnceBlock = PTHREAD_ONCE_INIT;
95 SysLogException(NID_SEC, r, "[%s] Propagated.", GetErrorMessage(r));
100 std::unique_ptr<String> pEncryptedPrivileges(new (std::nothrow) String());
101 SysTryReturnVoidResult(NID_SEC, pEncryptedPrivileges != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
103 std::unique_ptr<String> pChecksum(new (std::nothrow) String());
104 SysTryReturnVoidResult(NID_SEC, pChecksum != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
106 std::unique_ptr< ArrayListT< String > > pPrivilegeListT(new ArrayListT< String >());
107 SysTryReturnVoidResult(NID_SEC, pPrivilegeListT != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
109 pPrivilegeListT->Construct();
111 std::unique_ptr<IPC::Message> pCipherPrivilegeMessage(new (std::nothrow) PrivilegeManagerMsg_retrieve(pEncryptedPrivileges.get(), pChecksum.get(), pPrivilegeListT.get(), &r));
112 SysTryReturnVoidResult(NID_SEC, pCipherPrivilegeMessage != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
114 result ipcResult = pIpcClient->SendRequest(pCipherPrivilegeMessage.get());
115 SysTryReturnVoidResult(NID_SEC, ipcResult == E_SUCCESS, E_SYSTEM, "Failed to send IPC message.");
116 SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, r, "Failed to retrieve privilege information");
118 std::unique_ptr<ArrayList> pPrivilegeList(new ArrayList());
119 SysTryReturnVoidResult(NID_SEC, pPrivilegeList != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
121 pPrivilegeList->Construct();
123 std::unique_ptr<IEnumeratorT< String > > pEnum(pPrivilegeListT->GetEnumeratorN());
124 while (pEnum->MoveNext() == E_SUCCESS)
127 pEnum->GetCurrent(tempString);
128 pPrivilegeList->Add(new String(tempString));
130 pPrivilegeListT->RemoveAll();
132 std::unique_ptr<String> pEncryptedVisibility(new (std::nothrow) String());
133 SysTryReturnVoidResult(NID_SEC, pEncryptedVisibility != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
135 std::unique_ptr<String> pVisibilityChecksum(new (std::nothrow) String());
136 SysTryReturnVoidResult(NID_SEC, pVisibilityChecksum != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
138 std::unique_ptr<IPC::Message> pCipherVisibilityMessage(new (std::nothrow) PrivilegeManagerMsg_retrieveEx(pEncryptedVisibility.get(), pVisibilityChecksum.get(), &r));
139 SysTryReturnVoidResult(NID_SEC, pCipherVisibilityMessage != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
141 ipcResult = pIpcClient->SendRequest(pCipherVisibilityMessage.get());
142 SysTryReturnVoidResult(NID_SEC, ipcResult == E_SUCCESS, E_SYSTEM, "Failed to send IPC message.");
143 SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, r, "Failed to retrieve privilege information");
145 PackageId packageId = _AppInfo::GetPackageId();
146 packageId[0] = packageId[0];
148 r = privilegeInfo.Construct(packageId, *(pEncryptedPrivileges.get()), *(pChecksum.get()), *(pEncryptedVisibility.get()), *(pVisibilityChecksum.get()), pPrivilegeList.get());
149 SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
151 pPrivilegeList->RemoveAll(true);
152 isConstructed = true;
158 AccessController::CheckPrivilege(int privilege)
160 result r = E_SUCCESS;
164 SysTryReturnResult(NID_SEC, (privilege >= 0) && (privilege < _MAX_PRIVILEGE_ENUM), E_INVALID_ARG, "The privilege enumerator is invalid");
168 pthread_once(&onceBlock, Initialize);
172 if (r == E_DATA_NOT_FOUND)
174 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
179 onceBlock = PTHREAD_ONCE_INIT;
180 SysLogException(NID_SEC, r, "[%s] Propagated.", GetErrorMessage(r));
186 if (privilegeInfo.GetAppId().IsEmpty())
188 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
189 r = E_DATA_NOT_FOUND;
194 SysLog(NID_SEC, "%ls is in the cache [client]", privilegeInfo.GetAppId().GetPointer());
197 ret = privilegeInfo.HasPrivilege(static_cast< _Privilege >(privilege));
200 r = E_PRIVILEGE_DENIED;
204 r = _AccessController::CheckPrivacy(privilegeInfo.GetAppId(), static_cast< _Privilege >(privilege));
205 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_USER_NOT_CONSENTED, "The user blocks an application from calling the method.");
211 SysLogException(NID_SEC, r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
216 AccessController::CheckPrivilege(const String& privilege)
218 result r = E_SUCCESS;
224 pthread_once(&onceBlock, Initialize);
228 if (r == E_DATA_NOT_FOUND)
230 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
235 onceBlock = PTHREAD_ONCE_INIT;
236 SysLogException(NID_SEC, r, "[%s] Propagated.", GetErrorMessage(r));
242 if (privilegeInfo.GetAppId().IsEmpty())
244 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
245 r = E_DATA_NOT_FOUND;
250 SysLog(NID_SEC, "%ls is in the cache [client]", privilegeInfo.GetAppId().GetPointer());
253 ret = privilegeInfo.HasPrivilege(privilege);
256 r = E_PRIVILEGE_DENIED;
260 r = _AccessController::CheckPrivacy(privilegeInfo.GetAppId(), privilege);
261 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_USER_NOT_CONSENTED, "The user blocks an application from calling the method.");
267 SysLogException(NID_SEC, r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
271 _PrivilegeManager* AccessController::__pPrivilegeManager = null;
274 AccessController::CheckPrivilege(const PackageId& packageId, const String& privilege)
277 result r = _AccessController::CheckUserPrivilege(_PRV_PRIVILEGEMANAGER_READ);
278 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_PRIVILEGE_DENIED, "The application does not have the privilege to call this method.");
281 packageId.SubString(0, MAX_APP_ID_SIZE, subAppId);
283 _PackageInfoImpl infoImpl;
284 r = infoImpl.Construct(packageId);
285 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
288 String webAppType(L"wgt");
289 String cAppType(L"rpm");
290 appType = infoImpl.GetAppType();
291 if (appType.Equals(webAppType, true))
295 else if (appType.Equals(cAppType, true))
297 r = _AccessController::CheckPrivacy(packageId, privilege);
298 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_USER_NOT_CONSENTED, "The user blocks an application from calling the method.");
303 if (__pPrivilegeManager == null)
305 __pPrivilegeManager = _PrivilegeManager::GetInstance();
307 SysTryReturnResult(NID_SEC, __pPrivilegeManager != null, E_SYSTEM, "An unexpected system error occurred.");
309 std::unique_ptr<_PrivilegeInfo> pPrivilegeInfo(__pPrivilegeManager->RetrievePrivilegeInfoN(subAppId));
316 else if (r == E_DATA_NOT_FOUND)
318 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
323 SysLogException(NID_SEC, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
327 ret = pPrivilegeInfo->HasPrivilege(privilege);
330 r = E_PRIVILEGE_DENIED;
334 r = _AccessController::CheckPrivacy(packageId, privilege);
335 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_USER_NOT_CONSENTED, "The user blocks an application from calling the method.");
341 SysLogException(NID_SEC, r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");