Merge "Move the privilege checking code from Imple." into tizen_2.2
[platform/framework/native/appfw.git] / src / security / FSec_PrivilegeInfoImpl.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        FSec_PrivilegeInfoImpl.cpp
19  * @brief       This is the implementation for the _PrivilegeInfoImpl class.
20  */
21
22 #include <new>
23 #include <cstdio>
24 #include <cstdlib>
25 #include <unistd.h>
26 #include <unique_ptr.h>
27
28 #include <FSysSystemTime.h>
29 #include <FSecPrivilegeInfo.h>
30 #include <FBaseSysLog.h>
31 #include <FIo.h>
32 #include <FBase_StringConverter.h>
33 #include <FSec_AccessControlTypes.h>
34 #include <FBaseUtilStringTokenizer.h>
35 #include <FBase_StringConverter.h>
36 #include <privilege_info.h>
37
38 #include "FSec_PrivilegeInfoImpl.h"
39
40 using namespace Tizen::Base::Runtime;
41 using namespace Tizen::Base;
42 using namespace Tizen::Base::Utility;
43 using namespace Tizen::Base::Collection;
44 using namespace Tizen::Io;
45
46 namespace Tizen { namespace Security
47 {
48
49 _PrivilegeInfoImpl::_PrivilegeInfoImpl(void)
50 : __pDb(null)
51 {
52 }
53
54 _PrivilegeInfoImpl::~_PrivilegeInfoImpl(void)
55 {
56         delete __pDb;
57         return;
58 }
59
60 String
61 _PrivilegeInfoImpl::GetName(const String& privilege) const
62 {
63         int ret = 0;
64         char* pPrivilegeDisplayName = null;
65         std::unique_ptr<char[]> pPrivilegeId(null);
66         String displayName;
67
68         pPrivilegeId.reset(_StringConverter::CopyToCharArrayN(privilege));
69         SysTryReturn(NID_SEC, pPrivilegeId != null, displayName, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
70
71         ret = privilege_info_get_privilege_display_name(pPrivilegeId.get(), &pPrivilegeDisplayName);
72         displayName.Append(pPrivilegeDisplayName);
73
74         if (pPrivilegeDisplayName != null)
75         {
76                 free(pPrivilegeDisplayName);
77         }
78         return displayName;
79 }
80
81 String
82 _PrivilegeInfoImpl::GetDescription(const String& privilege) const
83 {
84         int ret = 0;
85         char* pPrivilegeDescription = null;
86         std::unique_ptr<char[]> pPrivilegeId(null);
87         String description;
88
89         pPrivilegeId.reset(_StringConverter::CopyToCharArrayN(privilege));
90         SysTryReturn(NID_SEC, pPrivilegeId != null, description, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
91
92         ret = privilege_info_get_privilege_description(pPrivilegeId.get(), &pPrivilegeDescription);
93         description.Append(pPrivilegeDescription);
94
95         if (pPrivilegeDescription != null)
96         {
97                 free(pPrivilegeDescription);
98         }
99         return description;
100 }
101
102 bool
103 _PrivilegeInfoImpl::CheckExternalPrivilege(const Tizen::Base::String& privilegeId)
104 {
105         result r = E_SUCCESS;
106         bool flag = false;
107
108         String query;
109         DbStatement* pStmt = null;
110         DbEnumerator* pEnum = null;
111
112         Database* pDb = new Database;
113         SysTryReturn(NID_SEC, pDb != null, false, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
114
115         r = pDb->Construct(EXTERNAL_PRIVILEGE_DATABASE_FILE_NAME, false);
116         SysTryCatch(NID_SEC, r == E_SUCCESS, flag = false, E_DATABASE, "External PrivilegeDb is not exist.");
117
118         query.Format(1024, L"SELECT PRIVILEGE_ID FROM PrivilegeInfo WHERE PRIVILEGE_ID = '%ls'", privilegeId.GetPointer());
119
120         pStmt = CreateStatementN(*pDb, query);
121         SysTryCatch(NID_SEC, pStmt != null, flag = false, E_DATABASE, "[E_DATABASE] An error occurs while creating a database statement.");
122
123         pEnum = ExecuteStatementN(*pDb, pStmt);
124         if (pEnum != null)
125         {
126                 if (pEnum->MoveNext() == E_SUCCESS)
127                 {
128                         flag = true;
129                 }
130
131                 delete pEnum;
132                 pEnum = null;
133         }
134         else
135         {
136                 flag = false;
137                 SysLog(NID_SEC, "[%ls] is not exist in PrivilegeDb.", privilegeId.GetPointer());
138         }
139
140 CATCH:
141
142         delete pStmt;
143         delete pDb;
144
145         return flag;
146 }
147
148 result
149 _PrivilegeInfoImpl::Construct(const Tizen::Base::String& privilegeId)
150 {
151         result r = E_SUCCESS;
152
153         String privilegeURI = L"http://tizen.org/privilege/";
154         String privilegeSubStringURI;
155         String privilegeSubString;
156         int index = 0;
157
158         privilegeId.SubString(0, privilegeURI.GetLength(), privilegeSubStringURI);
159         bool validStringFlag = false;
160
161         if (privilegeSubStringURI.Equals(privilegeURI, true))
162         {
163                 privilegeId.SubString(privilegeURI.GetLength(), privilegeId.GetLength() - privilegeURI.GetLength(), privilegeSubString);
164                 for (index = 0; index < _MAX_PRIVILEGE_ENUM; index++)
165                 {
166                         if (wcscmp(privilegeListTable[index].privilegeString, privilegeSubString.GetPointer()) == 0)
167                         {
168                                 validStringFlag = true;
169                                 break;
170                         }
171                 }
172         }
173
174         if (validStringFlag != true)
175         {
176                 if (CheckExternalPrivilege(privilegeId))
177                 {
178                         validStringFlag = true;
179                 }
180         }
181
182         SysTryReturnResult(NID_SEC, validStringFlag == true, E_INVALID_ARG, "Invalid privilege ID [%ls]", privilegeId.GetPointer());
183         __privilegeId = privilegeId;
184
185         return r;
186 }
187
188 String
189 _PrivilegeInfoImpl::GetId(void) const
190 {
191         return __privilegeId; 
192 }
193
194 String
195 _PrivilegeInfoImpl::GetDisplayName(void) const
196 {
197         return GetName(__privilegeId);
198 }
199
200 String
201 _PrivilegeInfoImpl::GetDescription(void) const
202 {
203         return GetDescription(__privilegeId);
204 }
205
206 DbStatement*
207 _PrivilegeInfoImpl::CreateStatementN(Database& db, const String& query)
208 {
209         result r = E_SUCCESS;
210         DbStatement* pStmt = null;
211
212         for (int i = 0; i < MAX_DATABASE_RETRY_COUNT; i++)
213         {
214                 pStmt = db.CreateStatementN(query);
215                 r = GetLastResult();
216
217                 if (r != E_OBJECT_LOCKED)
218                 {
219                         break;
220                 }
221                 else
222                 {
223                         SysLog(NID_SEC, "RetryCount[%d] CreateStatementN - E_OBJECT_LOCKED", i);
224                         delete pStmt;
225                         pStmt = null;
226                         usleep(50000);
227                 }
228         }
229
230         return pStmt;
231 }
232
233 DbEnumerator*
234 _PrivilegeInfoImpl::ExecuteStatementN(Database& db, const DbStatement* pStmt)
235 {
236         result r = E_SUCCESS;
237         DbEnumerator* pEnum = null;
238
239         for (int i = 0; i < MAX_DATABASE_RETRY_COUNT; i++)
240         {
241                 pEnum = db.ExecuteStatementN(*pStmt);
242                 r = GetLastResult();
243
244                 if (r != E_OBJECT_LOCKED)
245                 {
246                         break;
247                 }
248                 else
249                 {
250                         SysLog(NID_SEC, "RetryCount[%d] ExecuteStatementN - E_OBJECT_LOCKED", i);
251                         delete pEnum;
252                         pEnum = null;
253                         usleep(50000);
254                 }
255         }
256
257         return pEnum;
258 }
259
260 } } // Tizen::Security