Remove the memory leak on osp-security-service
[platform/framework/native/appfw.git] / src / security / FSecAccessController.cpp
index 7d5b0a7..fbc43b9 100644 (file)
@@ -28,6 +28,8 @@
 #include <FBaseSysLog.h>
 #include <FBaseString.h>
 #include <FBaseColArrayList.h>
+#include <FBaseColArrayListT.h>
+#include <FBaseColIEnumeratorT.h>
 #include <FIoFile.h>
 #include <FIo_IpcClient.h>
 #include <FSecAccessController.h>
@@ -44,9 +46,10 @@ using namespace Tizen::Base;
 using namespace Tizen::Base::Collection;
 using namespace Tizen::Io;
 
-static _IpcClient ipcClient;
 static bool isConstructed = false;
+static std::unique_ptr<_IpcClient> pIpcClient(null);
 static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
+static pthread_once_t ipcOnceBlock = PTHREAD_ONCE_INIT;
 
 namespace Tizen { namespace Security
 {
@@ -65,51 +68,77 @@ static _PrivilegeInfo privilegeInfo;
 
 
 void
-AccessController::Initialize(void)
+AccessController::InitIpcClient(void)
 {
-       result r = E_SUCCESS;
-       result ipcResult = E_SUCCESS;
+       std::unique_ptr<_IpcClient> pLocalIpcClient(new (std::nothrow) _IpcClient);
+       SysTryReturnVoidResult(NID_SEC, pLocalIpcClient != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
 
-       std::unique_ptr<String> pEncryptedPrivileges(null);
-       std::unique_ptr<String> pChecksum(null);
-       std::unique_ptr<String> pEncryptedVisibility(null);
-       std::unique_ptr<String> pVisibilityChecksum(null);
+       result r = pLocalIpcClient->Construct(L"osp.security.ipcserver.privilegemanager", null);
+       SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "Failed to construct the instance of IPC.");
 
-       std::unique_ptr<IPC::Message> pCipherPrivilegeMessage(null);
-       std::unique_ptr<IPC::Message> pCipherVisibilityMessage(null);
-       std::unique_ptr<ArrayList> pPrivilegeList(null);
+       pIpcClient = std::move(pLocalIpcClient);
+       return;
+}
 
-       r = ipcClient.Construct(L"osp.security.ipcserver.privilegemanager", null);
-       SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "Failed to construct the instance of IPC.");
+void
+AccessController::Initialize(void)
+{
+       result r = E_SUCCESS;
 
-       pEncryptedPrivileges.reset(new (std::nothrow) String());
+       if (pIpcClient == null)
+    {
+       pthread_once(&ipcOnceBlock, InitIpcClient);
+        r = GetLastResult();
+        if (IsFailed(r))
+        {
+                       ipcOnceBlock = PTHREAD_ONCE_INIT;
+                       SysLogException(NID_SEC, r, "[%s] Propagated.", GetErrorMessage(r));
+                       return;
+        }
+    }
+
+    std::unique_ptr<String> pEncryptedPrivileges(new (std::nothrow) String());
        SysTryReturnVoidResult(NID_SEC, pEncryptedPrivileges != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
 
-       pChecksum.reset(new (std::nothrow) String());
+       std::unique_ptr<String> pChecksum(new (std::nothrow) String());
        SysTryReturnVoidResult(NID_SEC, pChecksum != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
 
-       pPrivilegeList.reset(new ArrayList());
-       SysTryReturnVoidResult(NID_SEC, pPrivilegeList != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
+       std::unique_ptr< ArrayListT< String > > pPrivilegeListT(new ArrayListT< String >());
+       SysTryReturnVoidResult(NID_SEC, pPrivilegeListT != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
 
-       pPrivilegeList->Construct();
+       pPrivilegeListT->Construct();
 
-       pCipherPrivilegeMessage.reset(new (std::nothrow) PrivilegeManagerMsg_retrieve(pEncryptedPrivileges.get(), pChecksum.get(), pPrivilegeList.get(), &r));
+       std::unique_ptr<IPC::Message> pCipherPrivilegeMessage(new (std::nothrow) PrivilegeManagerMsg_retrieve(pEncryptedPrivileges.get(), pChecksum.get(), pPrivilegeListT.get(), &r));
        SysTryReturnVoidResult(NID_SEC, pCipherPrivilegeMessage != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
 
-       ipcResult = ipcClient.SendRequest(pCipherPrivilegeMessage.get());
+       result ipcResult = pIpcClient->SendRequest(pCipherPrivilegeMessage.get());
        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");
 
-       pEncryptedVisibility.reset(new (std::nothrow) String());
+       std::unique_ptr<ArrayList> pPrivilegeList(new ArrayList());
+       SysTryReturnVoidResult(NID_SEC, pPrivilegeList != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
+
+       pPrivilegeList->Construct();
+
+       std::unique_ptr<IEnumeratorT< String > > pEnum(pPrivilegeListT->GetEnumeratorN());
+       while (pEnum->MoveNext() == E_SUCCESS)
+       {
+               String tempString;
+               pEnum->GetCurrent(tempString);
+               pPrivilegeList->Add(new String(tempString));
+       }
+       pPrivilegeListT->RemoveAll();
+
+       std::unique_ptr<String> pEncryptedVisibility(new (std::nothrow) String());
        SysTryReturnVoidResult(NID_SEC, pEncryptedVisibility != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
 
-       pVisibilityChecksum.reset(new (std::nothrow) String());
+       std::unique_ptr<String> pVisibilityChecksum(new (std::nothrow) String());
        SysTryReturnVoidResult(NID_SEC, pVisibilityChecksum != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
 
-       pCipherVisibilityMessage.reset(new (std::nothrow) PrivilegeManagerMsg_retrieveEx(pEncryptedVisibility.get(), pVisibilityChecksum.get(), &r));
+       std::unique_ptr<IPC::Message> pCipherVisibilityMessage(new (std::nothrow) PrivilegeManagerMsg_retrieveEx(pEncryptedVisibility.get(), pVisibilityChecksum.get(), &r));
        SysTryReturnVoidResult(NID_SEC, pCipherVisibilityMessage != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
 
-       ipcResult = ipcClient.SendRequest(pCipherVisibilityMessage.get());
+       ipcResult = pIpcClient->SendRequest(pCipherVisibilityMessage.get());
        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");
 
@@ -121,6 +150,7 @@ AccessController::Initialize(void)
 
        pPrivilegeList->RemoveAll(true);
        isConstructed = true;
+
        return;
 }
 
@@ -129,10 +159,9 @@ AccessController::CheckPrivilege(int privilege)
 {
        result r = E_SUCCESS;
        bool ret = false;
-
        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)
        {
@@ -188,7 +217,6 @@ AccessController::CheckPrivilege(const String& privilege)
 {
        result r = E_SUCCESS;
        bool ret = false;
-
        ClearLastResult();
 
        if (!isConstructed)
@@ -245,24 +273,20 @@ _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);
+       result 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.");
 
+       String subAppId;
        packageId.SubString(0, MAX_APP_ID_SIZE, subAppId);
 
+       _PackageInfoImpl infoImpl;
        r = infoImpl.Construct(packageId);
        SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
 
+       String appType;
+       String webAppType(L"wgt");
+       String cAppType(L"rpm");
        appType = infoImpl.GetAppType();
        if (appType.Equals(webAppType, true))
        {
@@ -282,7 +306,7 @@ AccessController::CheckPrivilege(const PackageId& packageId, const String& privi
        }
        SysTryReturnResult(NID_SEC, __pPrivilegeManager != null, E_SYSTEM, "An unexpected system error occurred.");
 
-       pPrivilegeInfo.reset(__pPrivilegeManager->RetrievePrivilegeInfoN(subAppId));
+       std::unique_ptr<_PrivilegeInfo> pPrivilegeInfo(__pPrivilegeManager->RetrievePrivilegeInfoN(subAppId));
        r = GetLastResult();
 
        if (r == E_SUCCESS)