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_PrivilegeManager.cpp
19 * @brief This is the implementation for the _PrivilegeManager class.
24 #include <unique_ptr.h>
25 #include <pkgmgr-info.h>
26 #include <FAppPkg_PackageInfoImpl.h>
27 #include <FAppPkg_PackageManagerImpl.h>
28 #include <FBaseString.h>
29 #include <FBaseSysLog.h>
30 #include <FBase_StringConverter.h>
31 #include <FIo_IpcClient.h>
32 #include "FSec_AccessControlTypes.h"
33 #include "FSec_PrivilegeManager.h"
34 #include "FSec_PrivilegeManagerMessage.h"
35 #include "FSec_PrivilegeCache.h"
36 #include "FSec_PrivilegeInfo.h"
38 using namespace Tizen::App;
39 using namespace Tizen::App::Package;
40 using namespace Tizen::Base;
41 using namespace Tizen::Base::Collection;
42 using namespace Tizen::Io;
44 namespace Tizen { namespace Security
47 _PrivilegeManager* _PrivilegeManager::__pPrivilegeManagerInstance = null;
49 _PrivilegeManager::_PrivilegeManager(void)
50 : __pPrivilegeCache(null)
55 _PrivilegeManager::~_PrivilegeManager(void)
57 delete __pPrivilegeCache;
62 _PrivilegeManager::Construct(void)
66 _PackageManagerImpl* pPackageManagerImpl = null;
68 pPackageManagerImpl = _PackageManagerImpl::GetInstance();
69 SysTryReturnResult(NID_SEC, pPackageManagerImpl != null, E_SYSTEM, "An unexpected system error occurred.");
71 //pPackageManagerImpl->RemoveEventListener(this);
72 r = pPackageManagerImpl->AddEventListener(this);
73 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
75 __pPrivilegeCache = new (std::nothrow) _PrivilegeCache();
76 SysTryReturnResult(NID_SEC, __pPrivilegeCache != null, E_OUT_OF_MEMORY, "Memory allocation is failed.");
78 r = __pPrivilegeCache->Construct();
79 SysTryCatch(NID_SEC, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
85 delete __pPrivilegeCache;
90 _PrivilegeManager::InitInstance(void)
93 static _PrivilegeManager instance;
97 r = instance.Construct();
98 SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
100 __pPrivilegeManagerInstance = &instance;
106 _PrivilegeManager::GetInstance(void)
108 result r = E_SUCCESS;
109 static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
113 if (__pPrivilegeManagerInstance == null)
115 pthread_once(&onceBlock, InitInstance);
120 onceBlock = PTHREAD_ONCE_INIT;
124 return __pPrivilegeManagerInstance;
127 int GetPrivilegeListCallback (const char *privilege_name, void *user_data)
129 ArrayList* pPrivilegeList = static_cast<ArrayList*>(user_data);
130 pPrivilegeList->Add(new String(privilege_name));
136 _PrivilegeManager::GetPrivilegeListN(const AppId& appId)
140 result r = E_SUCCESS;
141 int res = PMINFO_R_OK;
142 std::unique_ptr<ArrayList> pReturnPrivilegeList(null);
144 pReturnPrivilegeList.reset(new (std::nothrow) ArrayList());
145 SysTryReturn(NID_SEC, pReturnPrivilegeList != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
147 r = pReturnPrivilegeList->Construct();
148 SysTryReturn(NID_SEC, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
150 std::unique_ptr<char[]> pPackageId(null);
151 pPackageId.reset(_StringConverter::CopyToCharArrayN(appId));
152 SysTryReturn(NID_SEC, pPackageId != null, null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
154 pkgmgrinfo_pkginfo_h handle;
155 res = pkgmgrinfo_pkginfo_get_pkginfo(pPackageId.get(), &handle);
156 SysTryReturn(NID_SEC, res == PMINFO_R_OK, null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
158 res = pkgmgrinfo_pkginfo_foreach_privilege(handle, GetPrivilegeListCallback, pReturnPrivilegeList.get());
159 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
160 SysTryReturn(NID_SEC, res == PMINFO_R_OK, null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
162 return pReturnPrivilegeList.release();
166 _PrivilegeManager::RetrieveCipherPrivilegeN(const AppId& appId, Tizen::Base::String& encryptedPrivileges, Tizen::Base::String& checksum, ArrayList*& pPrivilegeList)
168 result r = E_SUCCESS;
169 ArrayList tempPrivilegeList;
171 encryptedPrivileges.Clear();
174 r = tempPrivilegeList.Construct();
175 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
177 _PackageInfoImpl infoImpl;
178 r = infoImpl.Construct(appId);
179 if (r == E_APP_NOT_INSTALLED)
181 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
182 return E_DATA_NOT_FOUND;
184 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
186 r = infoImpl.GetPrivileges(encryptedPrivileges, checksum, tempPrivilegeList);
187 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
188 SysTryReturnResult(NID_SEC, encryptedPrivileges.IsEmpty() != true, E_DATA_NOT_FOUND, "The privilege information does not exist.");
189 SysTryReturnResult(NID_SEC, checksum.IsEmpty() != true, E_SYSTEM, "An unexpected system error occurred.");
191 pPrivilegeList = new ArrayList;
192 r = pPrivilegeList->Construct();
194 std::unique_ptr<IEnumerator> pEnum(null);
195 pEnum.reset(tempPrivilegeList.GetEnumeratorN());
196 SysTryReturnResult(NID_SEC, pEnum != null, E_SYSTEM, "An unexpected system error occurred.");
198 while (pEnum->MoveNext() == E_SUCCESS)
200 String* tempString = static_cast< String* >(pEnum->GetCurrent());
201 pPrivilegeList->Add(new String(*tempString));
204 tempPrivilegeList.RemoveAll(true);
209 _PrivilegeManager::RetrieveCipherPrivilegeExN(const AppId& appId, Tizen::Base::String& encryptedPrivileges, Tizen::Base::String& checksum, ArrayList*& pPrivilegeList)
211 result r = E_SUCCESS;
213 encryptedPrivileges.Clear();
216 String tempEncryptedPrivileges;
218 ArrayList tempPrivilegeList;
220 r = tempPrivilegeList.Construct();
221 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
223 _PackageInfoImpl infoImpl;
224 r = infoImpl.Construct(appId);
225 if (r == E_APP_NOT_INSTALLED)
227 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
228 return E_DATA_NOT_FOUND;
230 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
232 r = infoImpl.GetPrivileges(tempEncryptedPrivileges, tempChecksum, tempPrivilegeList);
233 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
234 SysTryReturnResult(NID_SEC, tempEncryptedPrivileges.IsEmpty() != true, E_DATA_NOT_FOUND, "The privilege information does not exist.");
235 SysTryReturnResult(NID_SEC, tempChecksum.IsEmpty() != true, E_SYSTEM, "An unexpected system error occurred.");
237 _PrivilegeInfo privilegeInfo;
239 r = privilegeInfo.Construct(appId, tempEncryptedPrivileges, tempChecksum, &tempPrivilegeList);
240 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
242 r = privilegeInfo.GetEncryptedBitwise(encryptedPrivileges);
243 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
245 r = privilegeInfo.GetChecksum(checksum);
246 SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
248 pPrivilegeList = new ArrayList;
249 r = pPrivilegeList->Construct();
251 std::unique_ptr<IEnumerator> pEnum(null);
252 pEnum.reset(tempPrivilegeList.GetEnumeratorN());
253 SysTryReturnResult(NID_SEC, pEnum != null, E_SYSTEM, "An unexpected system error occurred.");
255 while (pEnum->MoveNext() == E_SUCCESS)
257 String* tempString = static_cast< String* >(pEnum->GetCurrent());
258 pPrivilegeList->Add(new String(*tempString));
261 tempPrivilegeList.RemoveAll(true);
266 _PrivilegeManager::RetrievePrivilegeInfoN(const AppId& appId) const
268 result r = E_SUCCESS;
270 String encryptedPrivileges;
272 std::unique_ptr<_PrivilegeInfo> pPrivilegeInfo(null);
273 _PackageInfoImpl infoImpl;
274 ArrayList* pPrivilegeList = null;
278 pPrivilegeInfo.reset(__pPrivilegeCache->GetPrivilegeInfoN(appId));
285 else if (r == E_DATA_NOT_FOUND)
287 r = RetrieveCipherPrivilegeN(appId, encryptedPrivileges, checksum, pPrivilegeList);
288 if (r == E_DATA_NOT_FOUND)
290 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
293 SysTryReturn(NID_SEC, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
295 pPrivilegeInfo.reset(new (std::nothrow) _PrivilegeInfo());
296 SysTryReturn(NID_SEC, pPrivilegeInfo != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
298 r = pPrivilegeInfo->Construct(appId, encryptedPrivileges, checksum, pPrivilegeList);
299 SysTryReturn(NID_SEC, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
301 r = __pPrivilegeCache->AddPrivilegeInfo(*(pPrivilegeInfo.get()));
302 SysTryReturn(NID_SEC, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
304 if (pPrivilegeList != null)
306 pPrivilegeList->RemoveAll(true);
307 delete pPrivilegeList;
313 SysLogException(NID_SEC, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
317 return pPrivilegeInfo.release();
322 _PrivilegeManager::UnpackPrivilegeN(const byte* pBitwisePrivilege)
324 result r = E_SUCCESS;
327 int bytePosition = 0;
329 int privilegeBit = 0;
330 int privilegeEnum = 0;
331 std::unique_ptr<ArrayList> pPrivilegeList(null);
335 SysTryReturn(NID_SEC, pBitwisePrivilege != null, null, E_INVALID_ARG, "One of the argument is invalid.");
337 pPrivilegeList.reset(new (std::nothrow) ArrayList());
338 SysTryReturn(NID_SEC, pPrivilegeList != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
340 r = pPrivilegeList->Construct();
341 SysTryReturn(NID_SEC, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
343 for (bytePosition = 0; bytePosition < MAX_BITWISE_PRIV_SIZE; bytePosition++)
347 if (!(pBitwisePrivilege[bytePosition] & 0xFF))
349 // Pass the checking of empty byte filed.
353 for (bitPosition = 0; bitPosition < _BITS_IN_BYTE; bitPosition++)
355 privilegeBit = (int) (pBitwisePrivilege[bytePosition] & maskFlag);
358 // Shift the maskFlag by 1 bit when face the empty bit.
359 maskFlag = maskFlag << 1;
363 privilegeEnum = (bytePosition * _BITS_IN_BYTE) + bitPosition;
365 for (index = 0; index < _MAX_PRIVILEGE_ENUM; index++)
367 if (privilegeEnum == privilegeListTable[index].privilege)
369 String* privilegeString = new (std::nothrow) String(L"http://tizen.org/privilege/");
370 privilegeString->Append(privilegeListTable[index].privilegeString);
371 SysTryCatch(NID_SEC, privilegeString != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
372 "[E_OUT_OF_MEMORY]The memory is insufficient.");
374 pPrivilegeList->Add(*privilegeString);
379 // Shift the maskFlag by 1 bit to check the next byte filed.
380 maskFlag = maskFlag << 1;
384 return pPrivilegeList.release();
388 pPrivilegeList->RemoveAll(true);
393 _PrivilegeManager::OnPackageInstallationCompleted(const PackageId& packageId, PackageInstallationResult installationResult)
395 __pPrivilegeCache->RemovePrivilegeInfo(packageId);
396 SysLog(NID_SEC, "%ls is removed.", packageId.GetPointer());