Merge "GetErrorMessage() to print the error log" into tizen_2.1
[platform/framework/native/appfw.git] / src / security / FSecAccessController.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        FSecAccessController.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 <FSecAccessController.h>
35 #include <FSec_AccessController.h>
36 #include "FSec_AccessControlTypes.h"
37 #include "FSec_PrivilegeManager.h"
38 #include "FSec_PrivilegeManagerMessage.h"
39 #include "FSec_PrivilegeInfo.h"
40
41
42 using namespace Tizen::App;
43 using namespace Tizen::App::Package;
44 using namespace Tizen::Base;
45 using namespace Tizen::Base::Collection;
46 using namespace Tizen::Io;
47
48 static _IpcClient ipcClient;
49 static bool isConstructed = false;
50 static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
51
52 namespace Tizen { namespace Security
53 {
54
55 AccessController::AccessController(void)
56 {
57
58 }
59
60 AccessController::~AccessController(void)
61 {
62
63 }
64
65 static _PrivilegeInfo privilegeInfo;
66
67
68 void
69 AccessController::Initialize(void)
70 {
71         result r = E_SUCCESS;
72         result ipcResult = E_SUCCESS;
73
74         std::unique_ptr<String> pEncryptedPrivileges(null);
75         std::unique_ptr<String> pChecksum(null);
76         std::unique_ptr<String> pEncryptedVisibility(null);
77         std::unique_ptr<String> pVisibilityChecksum(null);
78
79         std::unique_ptr<IPC::Message> pCipherPrivilegeMessage(null);
80         std::unique_ptr<IPC::Message> pCipherVisibilityMessage(null);
81         std::unique_ptr<ArrayList> pPrivilegeList(null);
82
83         r = ipcClient.Construct(L"osp.security.ipcserver.privilegemanager", null);
84         SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "Failed to construct the instance of IPC.");
85
86         pEncryptedPrivileges.reset(new (std::nothrow) String());
87         SysTryReturnVoidResult(NID_SEC, pEncryptedPrivileges != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
88
89         pChecksum.reset(new (std::nothrow) String());
90         SysTryReturnVoidResult(NID_SEC, pChecksum != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
91
92         pPrivilegeList.reset(new ArrayList());
93         SysTryReturnVoidResult(NID_SEC, pPrivilegeList != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
94
95         pPrivilegeList->Construct();
96
97         pCipherPrivilegeMessage.reset(new (std::nothrow) PrivilegeManagerMsg_retrieve(pEncryptedPrivileges.get(), pChecksum.get(), pPrivilegeList.get(), &r));
98         SysTryReturnVoidResult(NID_SEC, pCipherPrivilegeMessage != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
99
100         ipcResult = ipcClient.SendRequest(pCipherPrivilegeMessage.get());
101         SysTryReturnVoidResult(NID_SEC, ipcResult == E_SUCCESS, E_SYSTEM, "Failed to send IPC message.");
102         SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, r, "Failed to retrieve privilege information");
103
104         pEncryptedVisibility.reset(new (std::nothrow) String());
105         SysTryReturnVoidResult(NID_SEC, pEncryptedVisibility != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
106
107         pVisibilityChecksum.reset(new (std::nothrow) String());
108         SysTryReturnVoidResult(NID_SEC, pVisibilityChecksum != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
109
110         pCipherVisibilityMessage.reset(new (std::nothrow) PrivilegeManagerMsg_retrieveEx(pEncryptedVisibility.get(), pVisibilityChecksum.get(), &r));
111         SysTryReturnVoidResult(NID_SEC, pCipherVisibilityMessage != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
112
113         ipcResult = ipcClient.SendRequest(pCipherVisibilityMessage.get());
114         SysTryReturnVoidResult(NID_SEC, ipcResult == E_SUCCESS, E_SYSTEM, "Failed to send IPC message.");
115         SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, r, "Failed to retrieve privilege information");
116
117         PackageId packageId = _AppInfo::GetPackageId();
118         packageId[0] = packageId[0];
119
120         r = privilegeInfo.Construct(packageId, *(pEncryptedPrivileges.get()), *(pChecksum.get()), *(pEncryptedVisibility.get()), *(pVisibilityChecksum.get()), pPrivilegeList.get());
121         SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
122
123         pPrivilegeList->RemoveAll(true);
124         isConstructed = true;
125         return;
126 }
127
128 result
129 AccessController::CheckPrivilege(int privilege)
130 {
131         result r = E_SUCCESS;
132         bool ret = false;
133
134         ClearLastResult();
135
136         SysTryReturnResult(NID_SEC, privilege < _MAX_PRIVILEGE_ENUM, E_INVALID_ARG, "The privilege enumerator is invalid");
137
138         if (!isConstructed)
139         {
140                 pthread_once(&onceBlock, Initialize);
141                 r = GetLastResult();
142                 if (IsFailed(r))
143                 {
144                         if (r == E_DATA_NOT_FOUND)
145                         {
146                                 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
147                                 goto CATCH;
148                         }
149                         else
150                         {
151                                 onceBlock = PTHREAD_ONCE_INIT;
152                                 SysLogException(NID_SEC, r, "[%s] Propagated.", GetErrorMessage(r));
153                         }
154                         return r;
155                 }
156         }
157
158         if (privilegeInfo.GetAppId().IsEmpty())
159         {
160                 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
161                 r = E_DATA_NOT_FOUND;
162                 goto CATCH;
163         }
164         else
165         {
166                 SysLog(NID_SEC, "%ls is in the cache [client]", privilegeInfo.GetAppId().GetPointer());
167         }
168
169         ret = privilegeInfo.HasPrivilege(static_cast< _Privilege >(privilege));
170         if (!ret)
171         {
172                 r = E_PRIVILEGE_DENIED;
173                 goto CATCH;
174         }
175
176         return r;
177
178 CATCH:
179
180         SysLogException(NID_SEC,  r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
181         return r;
182 }
183
184 result
185 AccessController::CheckPrivilege(const String& privilege)
186 {
187         result r = E_SUCCESS;
188         bool ret = false;
189
190         ClearLastResult();
191
192         if (!isConstructed)
193         {
194                 pthread_once(&onceBlock, Initialize);
195                 r = GetLastResult();
196                 if (IsFailed(r))
197                 {
198                         if (r == E_DATA_NOT_FOUND)
199                         {
200                                 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
201                                 goto CATCH;
202                         }
203                         else
204                         {
205                                 onceBlock = PTHREAD_ONCE_INIT;
206                                 SysLogException(NID_SEC, r, "[%s] Propagated.", GetErrorMessage(r));
207                         }
208                         return r;
209                 }
210         }
211
212         if (privilegeInfo.GetAppId().IsEmpty())
213         {
214                 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
215                 r = E_DATA_NOT_FOUND;
216                 goto CATCH;
217         }
218         else
219         {
220                 SysLog(NID_SEC, "%ls is in the cache [client]", privilegeInfo.GetAppId().GetPointer());
221         }
222
223         ret = privilegeInfo.HasPrivilege(privilege);
224         if (!ret)
225         {
226                 r = E_PRIVILEGE_DENIED;
227                 goto CATCH;
228         }
229
230         return r;
231
232 CATCH:
233
234         SysLogException(NID_SEC,  r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
235         return r;
236 }
237
238 _PrivilegeManager* AccessController::__pPrivilegeManager = null;
239
240 result
241 AccessController::CheckPrivilege(const PackageId& packageId, const String& privilege)
242 {
243         result r = E_SUCCESS;
244
245         bool ret = false;
246         std::unique_ptr<_PrivilegeInfo> pPrivilegeInfo(null);
247         String subAppId;
248         _PackageInfoImpl infoImpl;
249         String appType;
250         String webAppType(L"wgt");
251
252         r = _AccessController::CheckUserPrivilege(_PRV_PRIVILEGEMANAGER_READ);
253         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_PRIVILEGE_DENIED, "The application does not have the privilege to call this method.");
254
255         packageId.SubString(0, MAX_APP_ID_SIZE, subAppId);
256
257         r = infoImpl.Construct(subAppId);
258         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
259
260         appType = infoImpl.GetAppType();
261         if (appType.Equals(webAppType, true))
262         {
263                 return E_SUCCESS;
264         }
265
266         if (__pPrivilegeManager == null)
267         {
268                 __pPrivilegeManager = _PrivilegeManager::GetInstance();
269         }
270         SysTryReturnResult(NID_SEC, __pPrivilegeManager != null, E_SYSTEM, "An unexpected system error occurred.");
271
272         pPrivilegeInfo.reset(__pPrivilegeManager->RetrievePrivilegeInfoN(subAppId));
273         r = GetLastResult();
274
275         if (r == E_SUCCESS)
276         {
277                 // nothing to do.
278         }
279         else if (r == E_DATA_NOT_FOUND)
280         {
281                 SysLogException(NID_SEC, E_DATA_NOT_FOUND, "[E_DATA_NOT_FOUND] The privilege information does not exist.");
282                 goto CATCH;
283         }
284         else
285         {
286                 SysLogException(NID_SEC, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
287                 return E_SYSTEM;
288         }
289
290         ret = pPrivilegeInfo->HasPrivilege(privilege);
291         if (!ret)
292         {
293                 r = E_PRIVILEGE_DENIED;
294                 goto CATCH;
295         }
296
297         return r;
298
299 CATCH:
300
301         SysLogException(NID_SEC,  r, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
302         return r;
303 }
304
305 }} //Tizen::Security