Merge "Revert "Fix prevent defect for locales"" into devel_3.0_main
[platform/framework/native/appfw.git] / src / security / FSecAccessController.cpp
index 383e397..19c15f1 100644 (file)
@@ -1,5 +1,4 @@
 //
-// Open Service Platform
 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
 //
 // Licensed under the Apache License, Version 2.0 (the License);
 #include <FAppApplication.h>
 #include <FApp_AppInfo.h>
 #include <FApp_AppManagerImpl.h>
+#include <FAppPkg_PackageInfoImpl.h>
 #include <FBaseSysLog.h>
 #include <FBaseString.h>
 #include <FBaseColArrayList.h>
 #include <FIoFile.h>
 #include <FIo_IpcClient.h>
 #include <FSecAccessController.h>
+#include <FSec_AccessController.h>
 #include "FSec_AccessControlTypes.h"
 #include "FSec_PrivilegeManager.h"
 #include "FSec_PrivilegeManagerMessage.h"
 
 
 using namespace Tizen::App;
+using namespace Tizen::App::Package;
 using namespace Tizen::Base;
 using namespace Tizen::Base::Collection;
 using namespace Tizen::Io;
 
 static _IpcClient ipcClient;
 static bool isConstructed = false;
+static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
 
 namespace Tizen { namespace Security
 {
@@ -74,9 +77,7 @@ AccessController::Initialize(void)
 
        std::unique_ptr<IPC::Message> pCipherPrivilegeMessage(null);
        std::unique_ptr<IPC::Message> pCipherVisibilityMessage(null);
-
-
-       SysLog(NID_SEC, "Enter");
+       std::unique_ptr<ArrayList> pPrivilegeList(null);
 
        r = ipcClient.Construct(L"osp.security.ipcserver.privilegemanager", null);
        SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "Failed to construct the instance of IPC.");
@@ -87,7 +88,12 @@ AccessController::Initialize(void)
        pChecksum.reset(new (std::nothrow) String());
        SysTryReturnVoidResult(NID_SEC, pChecksum != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
 
-       pCipherPrivilegeMessage.reset(new (std::nothrow) PrivilegeManagerMsg_retrieve(pEncryptedPrivileges.get(), pChecksum.get(), &r));
+       pPrivilegeList.reset(new ArrayList());
+       SysTryReturnVoidResult(NID_SEC, pPrivilegeList != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
+
+       pPrivilegeList->Construct();
+
+       pCipherPrivilegeMessage.reset(new (std::nothrow) PrivilegeManagerMsg_retrieve(pEncryptedPrivileges.get(), pChecksum.get(), pPrivilegeList.get(), &r));
        SysTryReturnVoidResult(NID_SEC, pCipherPrivilegeMessage != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
 
        ipcResult = ipcClient.SendRequest(pCipherPrivilegeMessage.get());
@@ -107,14 +113,14 @@ AccessController::Initialize(void)
        SysTryReturnVoidResult(NID_SEC, ipcResult == E_SUCCESS, E_SYSTEM, "Failed to send IPC message.");
        SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, r, "Failed to retrieve privilege information");
 
-       const PackageId& packageId = _AppInfo::GetPackageId();
+       PackageId packageId = _AppInfo::GetPackageId();
+       packageId[0] = packageId[0];
 
-       r = privilegeInfo.Construct(packageId, *(pEncryptedPrivileges.get()), *(pChecksum.get()), *(pEncryptedVisibility.get()), *(pVisibilityChecksum.get()));
+       r = privilegeInfo.Construct(packageId, *(pEncryptedPrivileges.get()), *(pChecksum.get()), *(pEncryptedVisibility.get()), *(pVisibilityChecksum.get()), pPrivilegeList.get());
        SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
 
+       pPrivilegeList->RemoveAll(true);
        isConstructed = true;
-
-    SysLog(NID_SEC, "Exit");
        return;
 }
 
@@ -122,14 +128,11 @@ result
 AccessController::CheckPrivilege(int privilege)
 {
        result r = E_SUCCESS;
-       static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
-
        bool ret = false;
 
-       SysLog(NID_SEC, "Enter.");
        ClearLastResult();
 
-       SysTryReturnResult(NID_SEC, privilege < _MAX_PRIVILEGE_ENUM, E_INVALID_ARG, "The privilege enumerator is invalid");
+       SysTryReturnResult(NID_SEC, (privilege >= 0) && (privilege < _MAX_PRIVILEGE_ENUM), E_INVALID_ARG, "The privilege enumerator is invalid");
 
        if (!isConstructed)
        {
@@ -169,20 +172,149 @@ AccessController::CheckPrivilege(int privilege)
                goto CATCH;
        }
 
-       SysLog(NID_SEC, "Exit.");
+       r = _AccessController::CheckPrivacy(privilegeInfo.GetAppId(), static_cast< _Privilege >(privilege));
+       SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_USER_NOT_CONSENTED, "The user blocks an application from calling the method.");
+
        return r;
 
+CATCH:
+
+       SysLogException(NID_SEC,  r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
+       return r;
+}
+
+result
+AccessController::CheckPrivilege(const String& privilege)
+{
+       result r = E_SUCCESS;
+       bool ret = false;
+
+       ClearLastResult();
+
+       if (!isConstructed)
+       {
+               pthread_once(&onceBlock, Initialize);
+               r = GetLastResult();
+               if (IsFailed(r))
+               {
+                       if (r == E_DATA_NOT_FOUND)
+                       {
+                               SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
+                               goto CATCH;
+                       }
+                       else
+                       {
+                               onceBlock = PTHREAD_ONCE_INIT;
+                               SysLogException(NID_SEC, r, "[%s] Propagated.", GetErrorMessage(r));
+                       }
+                       return r;
+               }
+       }
+
+       if (privilegeInfo.GetAppId().IsEmpty())
+       {
+               SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
+               r = E_DATA_NOT_FOUND;
+               goto CATCH;
+       }
+       else
+       {
+               SysLog(NID_SEC, "%ls is in the cache [client]", privilegeInfo.GetAppId().GetPointer());
+       }
+
+       ret = privilegeInfo.HasPrivilege(privilege);
+       if (!ret)
+       {
+               r = E_PRIVILEGE_DENIED;
+               goto CATCH;
+       }
+
+       r = _AccessController::CheckPrivacy(privilegeInfo.GetAppId(), privilege);
+       SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_USER_NOT_CONSENTED, "The user blocks an application from calling the method.");
+
+       return r;
 
 CATCH:
 
        SysLogException(NID_SEC,  r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
-       SysLog(NID_SEC, "Exit.");
+       return r;
+}
+
+_PrivilegeManager* AccessController::__pPrivilegeManager = null;
+
+result
+AccessController::CheckPrivilege(const PackageId& packageId, const String& privilege)
+{
+       result r = E_SUCCESS;
+
+       bool ret = false;
+       std::unique_ptr<_PrivilegeInfo> pPrivilegeInfo(null);
+       String subAppId;
+       _PackageInfoImpl infoImpl;
+       String appType;
+       String webAppType(L"wgt");
+       String cAppType(L"rpm");
+
+       r = _AccessController::CheckUserPrivilege(_PRV_PRIVILEGEMANAGER_READ);
+       SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_PRIVILEGE_DENIED, "The application does not have the privilege to call this method.");
+
+       packageId.SubString(0, MAX_APP_ID_SIZE, subAppId);
+
+       r = infoImpl.Construct(packageId);
+       SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
+
+       appType = infoImpl.GetAppType();
+       if (appType.Equals(webAppType, true))
+       {
+               return E_SUCCESS;
+       }
+       else if (appType.Equals(cAppType, true))
+       {
+               r = _AccessController::CheckPrivacy(packageId, privilege);
+               SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_USER_NOT_CONSENTED, "The user blocks an application from calling the method.");
+
+               return r;
+       }
+
+       if (__pPrivilegeManager == null)
+       {
+               __pPrivilegeManager = _PrivilegeManager::GetInstance();
+       }
+       SysTryReturnResult(NID_SEC, __pPrivilegeManager != null, E_SYSTEM, "An unexpected system error occurred.");
 
-       const PackageId& packageId = _AppInfo::GetPackageId();
+       pPrivilegeInfo.reset(__pPrivilegeManager->RetrievePrivilegeInfoN(subAppId));
+       r = GetLastResult();
 
-       _AppManagerImpl* pAppManagerImpl = _AppManagerImpl::GetInstance();
-       pAppManagerImpl->TerminateApplications(packageId);
+       if (r == E_SUCCESS)
+       {
+               // nothing to do.
+       }
+       else if (r == E_DATA_NOT_FOUND)
+       {
+               SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
+               goto CATCH;
+       }
+       else
+       {
+               SysLogException(NID_SEC, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
+               return E_SYSTEM;
+       }
 
+       ret = pPrivilegeInfo->HasPrivilege(privilege);
+       if (!ret)
+       {
+               r = E_PRIVILEGE_DENIED;
+               goto CATCH;
+       }
+
+       r = _AccessController::CheckPrivacy(packageId, privilege);
+       SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_USER_NOT_CONSENTED, "The user blocks an application from calling the method.");
+
+       return r;
+
+CATCH:
+
+       SysLogException(NID_SEC,  r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
        return r;
 }