Modifty getting method of undefined privilege description
[platform/framework/native/appfw.git] / src / security / FSec_PrivilegeInfoImpl.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_PrivilegeInfoImpl.cpp
20  * @brief       This is the implementation for the _PrivilegeInfoImpl class.
21  */
22
23 #include <new>
24 #include <cstdio>
25 #include <cstdlib>
26 #include <unistd.h>
27 #include <unique_ptr.h>
28
29 #include <FSysSystemTime.h>
30 #include <FSecPrivilegeInfo.h>
31 #include <FBaseSysLog.h>
32 #include <FIo.h>
33 #include <FBase_StringConverter.h>
34 #include <FSec_AccessControlTypes.h>
35 #include <FBaseUtilStringTokenizer.h>
36
37 #include "FSec_PrivilegeInfoImpl.h"
38
39 using namespace Tizen::Base::Runtime;
40 using namespace Tizen::Base;
41 using namespace Tizen::Base::Utility;
42 using namespace Tizen::Base::Collection;
43 using namespace Tizen::Io;
44
45 namespace Tizen { namespace Security
46 {
47
48 _PrivilegeInfoImpl* _PrivilegeInfoImpl::__pPrivilegeInfoImplInstance  = null;
49
50 _PrivilegeInfoImpl::_PrivilegeInfoImpl(void)
51 : __pDb(null)
52 {
53 }
54
55 _PrivilegeInfoImpl::~_PrivilegeInfoImpl(void)
56 {
57         delete __pDb;
58         return;
59 }
60
61 result
62 _PrivilegeInfoImpl::Construct(void)
63 {
64         ClearLastResult();
65         result r = E_SUCCESS;
66
67         r = CheckDatabase();
68         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
69
70         Database* pDb = new Database;
71         SysTryReturnResult(NID_SEC, pDb != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
72
73         r = pDb->Construct(PRIVILEGE_DESCRIPTION_DATABASE_FILE_NAME, false);
74         SysTryReturnResult(NID_SEC, r == E_SUCCESS, E_SYSTEM, "An unexpected system error occurred.");
75
76         __pDb = pDb;
77
78         return E_SUCCESS;
79 }
80
81 result
82 _PrivilegeInfoImpl::CheckDatabase(void)
83 {
84         if (File::IsFileExist(PRIVILEGE_DESCRIPTION_DATABASE_FILE_NAME) != true)
85         {
86                 SysLogException(NID_SEC, E_SYSTEM, "[E_SYSTEM] Privilege information DB is not exist.");
87                 return E_SYSTEM;
88         }
89
90         return E_SUCCESS;
91 }
92
93
94 void
95 _PrivilegeInfoImpl::InitInstance(void)
96 {
97         result r = E_SUCCESS;
98         static _PrivilegeInfoImpl instance;
99
100         ClearLastResult();
101
102         r = instance.Construct();
103         SysTryReturnVoidResult(NID_SEC, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
104
105         __pPrivilegeInfoImplInstance = &instance;
106 }
107
108 _PrivilegeInfoImpl*
109 _PrivilegeInfoImpl::GetInstance(void)
110 {
111         result r = E_SUCCESS;
112         static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
113
114         ClearLastResult();
115
116     if (__pPrivilegeInfoImplInstance == null)
117     {
118         pthread_once(&onceBlock, InitInstance);
119
120         r = GetLastResult();
121         if (IsFailed(r))
122         {
123             onceBlock = PTHREAD_ONCE_INIT;
124             __pPrivilegeInfoImplInstance = null;
125             SysLogException(NID_SEC, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
126         }
127     }
128
129         return __pPrivilegeInfoImplInstance;
130 }
131
132 String
133 _PrivilegeInfoImpl::GetName(const String& privilege) const
134 {
135         String name;
136         result r = E_SUCCESS;
137         DbStatement* pStmt = null;
138         DbEnumerator* pEnum = null;
139         String query;
140
141         String privilegeURI = L"http://tizen.org/privilege/";
142         String uriString;
143         String privilegeString;
144
145         SysTryCatch(NID_SEC, (privilege.GetLength()) > (privilegeURI.GetLength()), ,E_INVALID_ARG, "[E_INVALID_ARG] Invalid privilege string : %ls", privilege.GetPointer());
146
147
148         privilege.SubString(0, privilegeURI.GetLength(), uriString);
149         SysTryCatch(NID_SEC, uriString.Equals(privilegeURI, true), ,E_INVALID_ARG, "[E_INVALID_ARG] Invalid privilege string : %ls", privilege.GetPointer());
150
151         privilege.SubString(privilegeURI.GetLength(), privilege.GetLength()-privilegeURI.GetLength(), privilegeString);
152         query.Format(1024, L"SELECT NAME FROM Privileges WHERE PRIVILEGE = '%ls'", privilegeString.GetPointer());
153
154         pStmt = CreateStatementN(*__pDb, query);
155         SysTryCatch(NID_SEC, pStmt != null, , E_DATABASE, "[E_DATABASE] An error occurs while creating a database statement.");
156
157         pEnum = ExecuteStatementN(*__pDb, pStmt);
158         if (pEnum != null)
159         {
160                 if (pEnum->MoveNext() == E_SUCCESS)
161                 {
162                         r = pEnum->GetStringAt(0, name);
163                 }
164
165                 delete pEnum;
166                 pEnum = null;
167         }
168         else
169         {
170                 SysLog(NID_SEC, "Privilege information is not found. [%ls]", privilegeString.GetPointer());
171
172                 String displayName;
173             StringTokenizer strTok(__privilegeId, L"/");
174             while(strTok.HasMoreTokens() == true)
175             {
176                 strTok.GetNextToken(displayName);
177             }
178
179                 name = displayName;
180         }
181
182 CATCH:
183         delete pStmt;
184         pStmt = null;
185
186         return name;
187 }
188
189 String
190 _PrivilegeInfoImpl::GetDescription(const String& privilege) const
191 {
192         String description;
193         result r = E_SUCCESS;
194         DbStatement* pStmt = null;
195         DbEnumerator* pEnum = null;
196         String query;
197
198         String privilegeURI = L"http://tizen.org/privilege/";
199         String uriString;
200         String privilegeString;
201
202         SysTryCatch(NID_SEC, (privilege.GetLength()) > (privilegeURI.GetLength()), ,E_INVALID_ARG, "[E_INVALID_ARG] Invalid privilege string : %ls", privilege.GetPointer());
203
204         privilege.SubString(0, privilegeURI.GetLength(), uriString);
205         SysTryCatch(NID_SEC, uriString.Equals(privilegeURI, true), ,E_INVALID_ARG, "[E_INVALID_ARG] Invalid privilege string : %ls", privilege.GetPointer());
206
207         privilege.SubString(privilegeURI.GetLength(), privilege.GetLength()-privilegeURI.GetLength(), privilegeString);
208         query.Format(1024, L"SELECT DESCRIPTION FROM Privileges WHERE PRIVILEGE = '%ls'", privilegeString.GetPointer());
209
210         pStmt = CreateStatementN(*__pDb, query);
211         SysTryCatch(NID_SEC, pStmt != null, , E_DATABASE, "[E_DATABASE] An error occurs while creating a database statement.");
212
213         pEnum = ExecuteStatementN(*__pDb, pStmt);
214         if (pEnum != null)
215         {
216                 if (pEnum->MoveNext() == E_SUCCESS)
217                 {
218                         r = pEnum->GetStringAt(0, description);
219                 }
220
221                 delete pEnum;
222                 pEnum = null;
223         }
224         else
225         {
226                 description.Append("Undefined");
227         }
228
229 CATCH:
230         delete pStmt;
231         pStmt = null;
232
233         return description;
234 }
235
236 DbStatement*
237 _PrivilegeInfoImpl::CreateStatementN(Database& db, const String& query)
238 {
239         result r = E_SUCCESS;
240         DbStatement* pStmt = null;
241
242         for (int i = 0; i < MAX_DATABASE_RETRY_COUNT; i++)
243         {
244                 pStmt = db.CreateStatementN(query);
245                 r = GetLastResult();
246
247                 if (r != E_OBJECT_LOCKED)
248                 {
249                         break;
250                 }
251                 else
252                 {
253                         SysLog(NID_SEC, "RetryCount[%d] CreateStatementN - E_OBJECT_LOCKED", i);
254                         delete pStmt;
255                         pStmt = null;
256                         usleep(50000);
257                 }
258         }
259
260         return pStmt;
261 }
262
263 DbEnumerator*
264 _PrivilegeInfoImpl::ExecuteStatementN(Database& db, const DbStatement* pStmt)
265 {
266         result r = E_SUCCESS;
267         DbEnumerator* pEnum = null;
268
269         for (int i = 0; i < MAX_DATABASE_RETRY_COUNT; i++)
270         {
271                 pEnum = db.ExecuteStatementN(*pStmt);
272                 r = GetLastResult();
273
274                 if (r != E_OBJECT_LOCKED)
275                 {
276                         break;
277                 }
278                 else
279                 {
280                         SysLog(NID_SEC, "RetryCount[%d] ExecuteStatementN - E_OBJECT_LOCKED", i);
281                         delete pEnum;
282                         pEnum = null;
283                         usleep(50000);
284                 }
285         }
286
287         return pEnum;
288 }
289
290 bool
291 _PrivilegeInfoImpl::CheckExternalPrivilege(const Tizen::Base::String& privilegeId)
292 {
293         result r = E_SUCCESS;
294         bool flag = false;
295
296         String query;
297         DbStatement* pStmt = null;
298         DbEnumerator* pEnum = null;
299
300         Database* pDb = new Database;
301         SysTryReturn(NID_SEC, pDb != null, false, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
302
303         r = pDb->Construct(EXTERNAL_PRIVILEGE_DATABASE_FILE_NAME, false);
304         SysTryCatch(NID_SEC, r == E_SUCCESS, flag = false, E_DATABASE, "External PrivilegeDb is not exist.");
305
306         query.Format(1024, L"SELECT PRIVILEGE_ID FROM PrivilegeInfo WHERE PRIVILEGE_ID = '%ls'", privilegeId.GetPointer());
307
308         pStmt = CreateStatementN(*pDb, query);
309         SysTryCatch(NID_SEC, pStmt != null, flag = false, E_DATABASE, "[E_DATABASE] An error occurs while creating a database statement.");
310
311         pEnum = ExecuteStatementN(*pDb, pStmt);
312         if (pEnum != null)
313         {
314                 if (pEnum->MoveNext() == E_SUCCESS)
315                 {
316                         flag = true;
317                 }
318
319                 delete pEnum;
320                 pEnum = null;
321         }
322         else
323         {
324                 flag = false;
325                 SysLog(NID_SEC, "[%ls] is not exist in PrivilegeDb.", privilegeId.GetPointer());
326         }
327
328 CATCH:
329
330         delete pDb;
331         delete pStmt;
332
333         return flag;
334 }
335
336 result
337 _PrivilegeInfoImpl::Construct(const Tizen::Base::String& privilegeId)
338 {
339         result r = E_SUCCESS;
340
341         String privilegeURI = L"http://tizen.org/privilege/";
342         String privilegeSubStringURI;
343         String privilegeSubString;
344         int index = 0;
345
346         privilegeId.SubString(0, privilegeURI.GetLength(), privilegeSubStringURI);
347         bool validStringFlag = false;
348
349         if (privilegeSubStringURI.Equals(privilegeURI, true))
350         {
351                 privilegeId.SubString(privilegeURI.GetLength(), privilegeId.GetLength() - privilegeURI.GetLength(), privilegeSubString);
352                 for (index = 0; index < _MAX_PRIVILEGE_ENUM; index++)
353                 {
354                         if (wcscmp(privilegeListTable[index].privilegeString, privilegeSubString.GetPointer()) == 0)
355                         {
356                                 validStringFlag = true;
357                                 break;
358                         }
359                 }
360         }
361
362         if (validStringFlag != true)
363         {
364                 if (CheckExternalPrivilege(privilegeId))
365                 {
366                         validStringFlag = true;
367                 }
368         }
369
370         SysTryReturnResult(NID_SEC, validStringFlag == true, E_INVALID_ARG, "Invalid privilege ID [%ls]", privilegeId.GetPointer());
371
372         r = Construct();
373         SysTryReturnResult(NID_SEC, validStringFlag == true, E_SYSTEM, "The method cannot proceed due to a severe system error.");
374
375         __privilegeId = privilegeId;
376
377         return r;
378 }
379
380 String
381 _PrivilegeInfoImpl::GetId(void) const
382 {
383         return __privilegeId; 
384 }
385
386 String
387 _PrivilegeInfoImpl::GetDisplayName(void) const
388 {
389         return GetName(__privilegeId);
390 }
391
392 String
393 _PrivilegeInfoImpl::GetDescription(void) const
394 {
395         return GetDescription(__privilegeId);
396 }
397
398 } } // Tizen::Security