sync with tizen_2.0
[platform/framework/native/appfw.git] / src / security / FSec_AccessController.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file        FSec_AccessController.cpp
20  * @brief       This is the implementation for the _AccessController class.
21  */
22
23 #include <unique_ptr.h>
24 #include <FAppTypes.h>
25 #include <FAppApplication.h>
26 #include <FApp_AppInfo.h>
27 #include <FApp_AppManagerImpl.h>
28 #include <FAppPkg_PackageInfoImpl.h>
29 #include <FBaseSysLog.h>
30 #include <FBaseString.h>
31 #include <FBaseColArrayList.h>
32 #include <FIoFile.h>
33 #include <FIo_IpcClient.h>
34 #include "FSec_AccessController.h"
35 #include "FSec_PrivilegeManager.h"
36 #include "FSec_PrivilegeManagerMessage.h"
37 #include "FSec_PrivilegeInfo.h"
38
39 using namespace Tizen::App;
40 using namespace Tizen::App::Package;
41 using namespace Tizen::Base;
42 using namespace Tizen::Base::Collection;
43 using namespace Tizen::Io;
44
45 static _IpcClient ipcClient;
46 static bool isConstructed = false;
47
48 namespace Tizen { namespace Security
49 {
50
51 _PrivilegeManager* _AccessController::__pPrivilegeManager = null;
52
53 _AccessController::_AccessController(void)
54 {
55
56 }
57
58 _AccessController::~_AccessController(void)
59 {
60
61 }
62
63 result
64 _AccessController::CheckSystemPrivilege(const AppId& appId, _Privilege privilege)
65 {
66         result r = E_SUCCESS;
67
68         bool ret = false;
69         std::unique_ptr<_PrivilegeInfo> pPrivilegeInfo(null);
70         String subAppId;
71         _PackageInfoImpl infoImpl;
72         String appType;
73         String webAppType(L"wgt");
74
75         SysLog(NID_SEC, "Enter.");
76         SysTryReturnResult(NID_SEC, privilege < _MAX_PRIVILEGE_ENUM, E_INVALID_ARG, "The privilege enumerator is invalid");
77
78         appId.SubString(0, MAX_APP_ID_SIZE, subAppId);
79
80         r = infoImpl.Construct(subAppId);
81         if (r == E_APP_NOT_INSTALLED)
82         {
83                 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The package information does not exist.");
84                 r = E_DATA_NOT_FOUND;
85                 goto CATCH;
86         }
87
88         appType = infoImpl.GetAppType();
89         r = GetLastResult();
90         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
91
92         if (appType.Equals(webAppType, true))
93         {
94                 return E_SUCCESS;
95         }
96
97         if (__pPrivilegeManager == null)
98         {
99                 __pPrivilegeManager = _PrivilegeManager::GetInstance();
100         }
101         SysTryReturnResult(NID_SEC, __pPrivilegeManager != null, E_SYSTEM, "An unexpected system error occurred.");
102
103         pPrivilegeInfo.reset(__pPrivilegeManager->RetrievePrivilegeInfoN(subAppId));
104         r = GetLastResult();
105
106         if (r == E_SUCCESS)
107         {
108                 // nothing to do.
109         }
110         else if (r == E_DATA_NOT_FOUND)
111         {
112                 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
113                 goto CATCH;
114         }
115         else
116         {
117                 SysLogException(NID_SEC, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
118                 return E_SYSTEM;
119         }
120
121         ret = pPrivilegeInfo->HasPrivilege(privilege);
122         if (!ret)
123         {
124                 r = E_PRIVILEGE_DENIED;
125                 goto CATCH;
126         }
127
128         SysLog(NID_SEC, "Exit.");
129         return r;
130
131 CATCH:
132
133         SysLogException(NID_SEC,  r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
134         SysLog(NID_SEC, "Exit.");
135
136         _AppManagerImpl* pAppManagerImpl = _AppManagerImpl::GetInstance();
137         pAppManagerImpl->TerminateApplications(appId);
138
139         return r;
140 }
141
142 static std::unique_ptr<String> pEncryptedPrivileges(null);
143 static std::unique_ptr<String> pChecksum(null);
144 static std::unique_ptr<String> pEncryptedVisibility(null);
145 static std::unique_ptr<String> pVisibilityChecksum(null);
146
147 void
148 _AccessController::Initialize(void)
149 {
150         result r = E_SUCCESS;
151         result ipcResult = E_SUCCESS;
152
153         std::unique_ptr<IPC::Message> pCipherPrivilegeMessage(null);
154         std::unique_ptr<IPC::Message> pCipherVisibilityMessage(null);
155
156         SysLog(NID_SEC, "Enter");
157
158         r = ipcClient.Construct(L"osp.security.ipcserver.privilegemanager", null);
159         SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "Failed to construct the instance of IPC.");
160
161         pEncryptedPrivileges.reset(new (std::nothrow) String());
162         SysTryReturnVoidResult(NID_SEC, pEncryptedPrivileges != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
163
164         pChecksum.reset(new (std::nothrow) String());
165         SysTryReturnVoidResult(NID_SEC, pChecksum != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
166
167         pCipherPrivilegeMessage.reset(new (std::nothrow) PrivilegeManagerMsg_retrieve(pEncryptedPrivileges.get(), pChecksum.get(), &r));
168         SysTryReturnVoidResult(NID_SEC, pCipherPrivilegeMessage != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
169
170         ipcResult = ipcClient.SendRequest(pCipherPrivilegeMessage.get());
171         SysTryReturnVoidResult(NID_SEC, ipcResult == E_SUCCESS, E_SYSTEM, "Failed to send IPC message.");
172         SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, r, "Failed to retrieve privilege information");
173
174         pEncryptedVisibility.reset(new (std::nothrow) String());
175         SysTryReturnVoidResult(NID_SEC, pEncryptedVisibility != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
176
177         pVisibilityChecksum.reset(new (std::nothrow) String());
178         SysTryReturnVoidResult(NID_SEC, pVisibilityChecksum != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
179
180         pCipherVisibilityMessage.reset(new (std::nothrow) PrivilegeManagerMsg_retrieveEx(pEncryptedVisibility.get(), pVisibilityChecksum.get(), &r));
181         SysTryReturnVoidResult(NID_SEC, pCipherVisibilityMessage != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
182
183         ipcResult = ipcClient.SendRequest(pCipherVisibilityMessage.get());
184         SysTryReturnVoidResult(NID_SEC, ipcResult == E_SUCCESS, E_SYSTEM, "Failed to send IPC message.");
185         SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, r, "Failed to retrieve privilege information");
186
187         isConstructed = true;
188
189     SysLog(NID_SEC, "Exit");
190         return;
191 }
192
193 result
194 _AccessController::CheckUserPrivilege(_Privilege privilege)
195 {
196         result r = E_SUCCESS;
197         static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
198
199         bool ret = false;
200
201         _AppType appType = _APP_TYPE_UI_APP;
202         _PrivilegeInfo privilegeInfo;
203
204         SysLog(NID_SEC, "Enter.");
205         ClearLastResult();
206
207         SysTryReturnResult(NID_SEC, privilege < _MAX_PRIVILEGE_ENUM, E_INVALID_ARG, "The privilege enumerator is invalid");
208         //SysAssertf(privilegeLevelListTable[privilege][_PRV_API_VER_2_0] == _PRV_LEVEL_USER, "System-level privilege is passed to CheckUserPrivilege.");
209
210         appType = _AppInfo::GetAppType();
211         const PackageId& packageId = _AppInfo::GetPackageId();
212
213         if ((appType & _APP_TYPE_WEB_APP) != _APP_TYPE_WEB_APP)
214         {
215             if (isConstructed != true)
216             {
217                 pthread_once(&onceBlock, Initialize);
218                 r = GetLastResult();
219                 if (IsFailed(r))
220                 {
221                         if (r == E_DATA_NOT_FOUND)
222                         {
223                                 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
224                                 goto CATCH;
225                         }
226                         else
227                         {
228                                 onceBlock = PTHREAD_ONCE_INIT;
229                                         SysLogException(NID_SEC, r, "[%s] Propagated.", GetErrorMessage(r));
230                         }
231                                 return r;
232                 }
233             }
234
235                 if ((pEncryptedPrivileges != null) && (pChecksum != null) && (pEncryptedVisibility != null) && (pVisibilityChecksum != null))
236                 {
237                         r = privilegeInfo.Construct(packageId, *(pEncryptedPrivileges.get()), *(pChecksum.get()), *(pEncryptedVisibility.get()), *(pVisibilityChecksum.get()));
238                         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred. %ls", packageId.GetPointer());
239
240                         SysLog(NID_SEC, "%ls is in the cache [client]", privilegeInfo.GetAppId().GetPointer());
241                 }
242                 else
243                 {
244                         SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
245                         r =  E_DATA_NOT_FOUND;
246                         goto CATCH;
247                 }
248
249                 ret = privilegeInfo.HasPrivilege(privilege);
250                 if (!ret)
251                 {
252                         r = E_PRIVILEGE_DENIED;
253                         goto CATCH;
254                 }
255         }
256
257         SysLog(NID_SEC, "Exit.");
258         return r;
259
260 CATCH:
261
262         SysLogException(NID_SEC,  r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
263         SysLog(NID_SEC, "Exit.");
264
265         _AppManagerImpl* pAppManagerImpl = _AppManagerImpl::GetInstance();
266         pAppManagerImpl->TerminateApplications(packageId);
267
268         return r;
269
270 }
271
272 }} //Tizen::Security