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