|
1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // t_sqlsecurity5 application has capabilities allowing schema access to the test database |
|
15 // |
|
16 // |
|
17 |
|
18 #include <e32test.h> |
|
19 #include <bautils.h> |
|
20 #include <sqldb.h> |
|
21 |
|
22 /////////////////////////////////////////////////////////////////////////////////////// |
|
23 //The test database has: |
|
24 // SCHEMA database policy: ECapabilityReadDeviceData, ECapabilityWriteUserData, ECapabilityReadUserData |
|
25 // WRITE database policy: ECapabilityWriteUserData |
|
26 // READ database policy: ECapabilityReadUserData |
|
27 // |
|
28 //Database tables: |
|
29 // TABLE A(F1 INTEGER, B1 BLOB) |
|
30 // TABLE B(F2 INTEGER, F3 TEXT, B2 BLOB) |
|
31 // |
|
32 //Database data: |
|
33 // TABLE A: {1, x'41414141414141414141'}, {2, x'42424242424242424242'}, {3, x'43434343434343434343'}, {4, x'44444444444444444444'} |
|
34 // TABLE B: {2, "ABC", x'45454545454545454545'}, {4, "DEF", x'46464646464646464646'} |
|
35 |
|
36 /////////////////////////////////////////////////////////////////////////////////////// |
|
37 |
|
38 #define UNUSED_VAR(a) (a) = (a) |
|
39 |
|
40 RSqlDatabase TheDb; |
|
41 RTest TheTest(_L("t_sqlsecurity5 test")); |
|
42 |
|
43 _LIT(KTestDbName, "c:[21212125]t_ab.db"); |
|
44 _LIT(KTestDbName2, "c:\\test\\t_sqlsecurity5_2.db"); |
|
45 |
|
46 /////////////////////////////////////////////////////////////////////////////////////// |
|
47 |
|
48 void DeleteTestDb2() |
|
49 { |
|
50 TheDb.Close(); |
|
51 (void)RSqlDatabase::Delete(KTestDbName2); |
|
52 } |
|
53 |
|
54 /////////////////////////////////////////////////////////////////////////////////////// |
|
55 //Restore original test database function |
|
56 void RestoreOriginalDb() |
|
57 { |
|
58 TheDb.Close(); |
|
59 TheDb.Open(KTestDbName); |
|
60 |
|
61 // Delete and restore the content of table A (unconditional DELETE, no READ operations) |
|
62 TheDb.Exec(_L("DELETE FROM A")); |
|
63 TheDb.Exec(_L("INSERT INTO A(F1,B1) VALUES(1,x'41414141414141414141');INSERT INTO A(F1,B1) VALUES(2,x'42424242424242424242');INSERT INTO A(F1,B1) VALUES(3,x'43434343434343434343');INSERT INTO A(F1,B1) VALUES(4,x'44444444444444444444');")); |
|
64 |
|
65 // Delete and restore the content of table B (unconditional DELETE, no READ operations) |
|
66 TheDb.Exec(_L("DELETE FROM B")); |
|
67 TheDb.Exec(_L("INSERT INTO B(F2,F3,B2) VALUES(2, 'ABC',x'45454545454545454545');INSERT INTO B(F2,F3,B2) VALUES(4,'DEF',x'46464646464646464646');")); |
|
68 |
|
69 TheDb.Close(); |
|
70 } |
|
71 |
|
72 /////////////////////////////////////////////////////////////////////////////////////// |
|
73 //Test macros and functions |
|
74 void Check1(TInt aValue, TInt aLine) |
|
75 { |
|
76 if(!aValue) |
|
77 { |
|
78 DeleteTestDb2(); |
|
79 RestoreOriginalDb(); |
|
80 RDebug::Print(_L("*** Line %d\r\n"), aLine); |
|
81 TheTest(EFalse, aLine); |
|
82 } |
|
83 } |
|
84 void Check2(TInt aValue, TInt aExpected, TInt aLine) |
|
85 { |
|
86 if(aValue != aExpected) |
|
87 { |
|
88 DeleteTestDb2(); |
|
89 RestoreOriginalDb(); |
|
90 RDebug::Print(_L("*** Line %d, Expected error: %d, got: %d\r\n"), aLine, aExpected, aValue); |
|
91 TheTest(EFalse, aLine); |
|
92 } |
|
93 } |
|
94 #define TEST(arg) ::Check1((arg), __LINE__) |
|
95 #define TEST2(aValue, aExpected) ::Check2(aValue, aExpected, __LINE__) |
|
96 |
|
97 /////////////////////////////////////////////////////////////////////////////////////// |
|
98 |
|
99 /** |
|
100 @SYMTestCaseID SYSLIB-SQL-CT-1647 |
|
101 @SYMTestCaseDesc Testing database operations on a secure database. |
|
102 The test application's capabilities allow schema access to the test secure database. |
|
103 Verify that any other kind of a database operation will pass. |
|
104 @SYMTestPriority High |
|
105 @SYMTestActions Testing database operations on a secure database. |
|
106 @SYMTestExpectedResults Test must not fail |
|
107 @SYMREQ REQ5792 |
|
108 REQ5793 |
|
109 */ |
|
110 void SchemaSecurityTest() |
|
111 { |
|
112 TInt err = TheDb.Open(KTestDbName); |
|
113 TEST2(err, KErrNone); |
|
114 |
|
115 //Attempt to modify the database schema |
|
116 err = TheDb.Exec(_L("CREATE TABLE IF NOT EXISTS C(FFF TEXT)")); |
|
117 TEST(err >= 0); |
|
118 //Attempt to update the user data (but it includes a READ operation) |
|
119 err = TheDb.Exec(_L("UPDATE A SET F1 = 11 WHERE F1 = 1")); |
|
120 TEST(err >= 0); |
|
121 //Attempt to update the user data (unconditional UPDATE, no READ operations) |
|
122 err = TheDb.Exec(_L("UPDATE A SET F1 = 11")); |
|
123 TEST(err >= 0); |
|
124 //Attempt to delete the user data (but it includes a READ operation) |
|
125 err = TheDb.Exec(_L("DELETE FROM B WHERE F2 = 2")); |
|
126 TEST(err >= 0); |
|
127 //Attempt to delete the user data (unconditional DELETE, no READ operations) |
|
128 err = TheDb.Exec(_L("DELETE FROM A")); |
|
129 TEST(err >= 0); |
|
130 //Restore the deleted table A |
|
131 err = TheDb.Exec(_L("INSERT INTO A(F1,B1) VALUES(1,x'41414141414141414141');INSERT INTO A(F1,B1) VALUES(2,x'42424242424242424242');INSERT INTO A(F1,B1) VALUES(3,x'43434343434343434343');INSERT INTO A(F1,B1) VALUES(4,x'44444444444444444444');")); |
|
132 TEST(err >= 0); |
|
133 //Restore the deleted record in table B |
|
134 err = TheDb.Exec(_L("INSERT INTO B(F2, F3, B2) VALUES(2, 'ABC', x'45454545454545454545');")); |
|
135 TEST2(err, 1); |
|
136 //Attempt to insert new user data |
|
137 err = TheDb.Exec(_L("INSERT INTO B(F2, F3, B2) VALUES(6, 'GHI', x'47474747474747474747');")); |
|
138 TEST2(err, 1); |
|
139 //Attempt to read the user data |
|
140 RSqlStatement stmt; |
|
141 err = stmt.Prepare(TheDb, _L("SELECT A.F1 FROM B,A WHERE A.F1 = B.F2")); |
|
142 TEST2(err, KErrNone); |
|
143 //ColumnCount() has no capabilities assigned |
|
144 TInt colCnt = stmt.ColumnCount(); |
|
145 TEST2(colCnt, 1); |
|
146 // |
|
147 stmt.Close(); |
|
148 TheDb.Close(); |
|
149 } |
|
150 |
|
151 /** |
|
152 @SYMTestCaseID SYSLIB-SQL-UT-4037 |
|
153 @SYMTestCaseDesc RSqlStatement::DeclaredColumnType() - security test. |
|
154 The test calls RSqlStatement::DeclaredColumnType() on a secure database. |
|
155 It should be possible to retrieve the declared column type without problems. |
|
156 @SYMTestPriority High |
|
157 @SYMTestActions RSqlStatement::DeclaredColumnType() - security test. |
|
158 @SYMTestExpectedResults Test must not fail |
|
159 @SYMREQ REQ5794 |
|
160 */ |
|
161 void DeclaredColumnTypeTest() |
|
162 { |
|
163 TInt err = TheDb.Open(KTestDbName); |
|
164 TEST2(err, KErrNone); |
|
165 RSqlStatement stmt; |
|
166 err = stmt.Prepare(TheDb, _L("SELECT A.F1 FROM B,A WHERE A.F1 = B.F2")); |
|
167 TEST2(err, KErrNone); |
|
168 //DeclaredColumnType() has no capabilities assigned |
|
169 TSqlColumnType colType; |
|
170 err = stmt.DeclaredColumnType(0, colType); |
|
171 TEST2(err, KErrNone); |
|
172 TEST2(colType, ESqlInt); |
|
173 err = stmt.Next(); |
|
174 TEST2(err, KSqlAtRow); |
|
175 RDebug::Print(_L("Value=%d\r\n"), stmt.ColumnInt(0)); |
|
176 err = stmt.Next(); |
|
177 TEST2(err, KSqlAtRow); |
|
178 RDebug::Print(_L("Value=%d\r\n"), stmt.ColumnInt(0)); |
|
179 stmt.Close(); |
|
180 //Attempt to read the system data |
|
181 err = stmt.Prepare(TheDb, _L("SELECT * FROM SQLITE_MASTER")); |
|
182 TEST2(err, KErrNone); |
|
183 err = stmt.Next(); |
|
184 TEST2(err, KSqlAtRow); |
|
185 TPtrC p; |
|
186 err = stmt.ColumnText(0, p); |
|
187 TEST2(err, KErrNone); |
|
188 RDebug::Print(_L("Value=%S\r\n"), &p); |
|
189 // |
|
190 stmt.Close(); |
|
191 TheDb.Close(); |
|
192 } |
|
193 |
|
194 /** |
|
195 @SYMTestCaseID SYSLIB-SQL-UT-4046 |
|
196 @SYMTestCaseDesc RSqlDatabase::Size(TSize&), platsec test. |
|
197 The test verifies that RSqlDatabase::Size(TSize&) can be called |
|
198 on the main or on an attached database no matter what the client capabilities are. |
|
199 @SYMTestPriority Medium |
|
200 @SYMTestActions RSqlDatabase::Size(TSize&), platsec test. |
|
201 @SYMTestExpectedResults Test must not fail |
|
202 @SYMREQ REQ10407 |
|
203 */ |
|
204 void Size2Test() |
|
205 { |
|
206 TInt err = TheDb.Open(KTestDbName); |
|
207 TEST2(err, KErrNone); |
|
208 //Size(TSize&) has no capabilities assigned |
|
209 RSqlDatabase::TSize size; |
|
210 err = TheDb.Size(size); |
|
211 TEST2(err, KErrNone); |
|
212 //Attach and repeat the test again |
|
213 _LIT(KAttachDbName, "Db"); |
|
214 err = TheDb.Attach(KTestDbName, KAttachDbName); |
|
215 TEST2(err, KErrNone); |
|
216 TEST(size.iSize > 0); |
|
217 TEST(size.iFree >= 0); |
|
218 err = TheDb.Size(size, KAttachDbName); |
|
219 TEST2(err, KErrNone); |
|
220 TEST(size.iSize > 0); |
|
221 TEST(size.iFree >= 0); |
|
222 err = TheDb.Detach(KAttachDbName); |
|
223 TEST2(err, KErrNone); |
|
224 TheDb.Close(); |
|
225 } |
|
226 |
|
227 /** |
|
228 @SYMTestCaseID SYSLIB-SQL-UT-4047 |
|
229 @SYMTestCaseDesc RSqlDatabase::Compact(), platsec test. |
|
230 The test verifies that RSqlDatabase::Compact() can be called |
|
231 on the main or on an attached database no matter what the client capabilities are. |
|
232 @SYMTestPriority Medium |
|
233 @SYMTestActions RSqlDatabase::Compact(), platsec test. |
|
234 @SYMTestExpectedResults Test must not fail |
|
235 @SYMREQ REQ10405 |
|
236 */ |
|
237 void CompactTest() |
|
238 { |
|
239 TInt err = TheDb.Open(KTestDbName); |
|
240 TEST2(err, KErrNone); |
|
241 |
|
242 err = TheDb.Compact(RSqlDatabase::EMaxCompaction); |
|
243 TEST(err >= 0); |
|
244 |
|
245 TRequestStatus stat; |
|
246 TheDb.Compact(RSqlDatabase::EMaxCompaction, stat); |
|
247 User::WaitForRequest(stat); |
|
248 TEST(stat.Int() >= 0); |
|
249 |
|
250 TheDb.Close(); |
|
251 |
|
252 err = TheDb.Create(KTestDbName2); |
|
253 TEST2(err, KErrNone); |
|
254 _LIT(KDbName, "Db"); |
|
255 err = TheDb.Attach(KTestDbName, KDbName); |
|
256 TEST2(err, KErrNone); |
|
257 |
|
258 err = TheDb.Compact(RSqlDatabase::EMaxCompaction, KDbName); |
|
259 TEST(err >= 0); |
|
260 |
|
261 TheDb.Compact(RSqlDatabase::EMaxCompaction, stat, KDbName); |
|
262 User::WaitForRequest(stat); |
|
263 TEST(stat.Int() >= 0); |
|
264 |
|
265 err = TheDb.Detach(KDbName); |
|
266 TheDb.Close(); |
|
267 (void)RSqlDatabase::Delete(KTestDbName2); |
|
268 } |
|
269 |
|
270 /** |
|
271 @SYMTestCaseID SYSLIB-SQL-UT-4098 |
|
272 @SYMTestCaseDesc Testing incremental blob reads and writes on a secure database. |
|
273 The test application's schema capabilities allow read and write access to the blobs. |
|
274 Verify that both reads and writes are allowed and also that database operations |
|
275 that require schema capability are allowed. |
|
276 @SYMTestPriority Medium |
|
277 @SYMTestActions Testing incremental blob reads and writes and schema operations on a secure database. |
|
278 @SYMTestExpectedResults Test must not fail |
|
279 @SYMREQ REQ5794 |
|
280 */ |
|
281 void SchemaBlobTestL() |
|
282 { |
|
283 // Current database data: |
|
284 // TABLE A: {1, x'41414141414141414141'}, {2, x'42424242424242424242'}, {3, x'43434343434343434343'}, {4, x'44444444444444444444'} |
|
285 // TABLE B: {4, "DEF", x'46464646464646464646'} <- ROWID = 2, {2, "ABC", x'45454545454545454545'} <- ROWID = 3, {6, "GHI", x'47474747474747474747'} <- ROWID = 4 |
|
286 |
|
287 RSqlDatabase db; |
|
288 TInt err = db.Open(KTestDbName); |
|
289 TEST2(err, KErrNone); |
|
290 |
|
291 // Attempt to read the blobs in tables A and B |
|
292 RSqlBlobReadStream rdStrm; |
|
293 CleanupClosePushL(rdStrm); |
|
294 TBuf8<20> data; |
|
295 TRAP(err, rdStrm.OpenL(db, _L("A"), _L("B1"), 2)); |
|
296 TEST2(err, KErrNone); |
|
297 TRAP(err, rdStrm.ReadL(data, 7)); |
|
298 TEST2(err, KErrNone); |
|
299 TEST(data.Compare(_L8("BBBBBBB")) == 0); |
|
300 rdStrm.Close(); |
|
301 TRAP(err, rdStrm.OpenL(db, _L("B"), _L("B2"), 2)); |
|
302 TEST2(err, KErrNone); |
|
303 TRAP(err, rdStrm.ReadL(data, 9)); |
|
304 TEST2(err, KErrNone); |
|
305 TEST(data.Compare(_L8("FFFFFFFFF")) == 0); |
|
306 CleanupStack::PopAndDestroy(&rdStrm); |
|
307 |
|
308 HBufC8* wholeBuf = TSqlBlob::GetLC(db, _L("A"), _L("B1"), 1); |
|
309 TEST(wholeBuf->Des().Compare(_L8("AAAAAAAAAA")) == 0); |
|
310 CleanupStack::PopAndDestroy(wholeBuf); |
|
311 wholeBuf = TSqlBlob::GetLC(db, _L("B"), _L("B2"), 4); |
|
312 TEST(wholeBuf->Des().Compare(_L8("GGGGGGGGGG")) == 0); |
|
313 CleanupStack::PopAndDestroy(wholeBuf); |
|
314 |
|
315 HBufC8* buf = HBufC8::NewLC(10); |
|
316 TPtr8 bufPtr(buf->Des()); |
|
317 err = TSqlBlob::Get(db, _L("A"), _L("B1"), bufPtr, 3); |
|
318 TEST2(err, KErrNone); |
|
319 TEST(bufPtr.Compare(_L8("CCCCCCCCCC")) == 0); |
|
320 err = TSqlBlob::Get(db, _L("B"), _L("B2"), bufPtr, 2); |
|
321 TEST2(err, KErrNone); |
|
322 TEST(bufPtr.Compare(_L8("FFFFFFFFFF")) == 0); |
|
323 CleanupStack::PopAndDestroy(buf); |
|
324 |
|
325 // Attempt to write the blobs in tables A and B |
|
326 RSqlBlobWriteStream wrStrm; |
|
327 CleanupClosePushL(wrStrm); |
|
328 TRAP(err, wrStrm.OpenL(db, _L("A"), _L("B1"), 1)); |
|
329 TEST2(err, KErrNone); |
|
330 TRAP(err, wrStrm.WriteL(_L8("ZZZ"))); |
|
331 TEST2(err, KErrNone); |
|
332 wrStrm.Close(); |
|
333 TRAP(err, wrStrm.OpenL(db, _L("B"), _L("B2"), 3)); |
|
334 TEST2(err, KErrNone); |
|
335 TRAP(err, wrStrm.WriteL(_L8("WWWWWWWWWW"))); |
|
336 TEST2(err, KErrNone); |
|
337 CleanupStack::PopAndDestroy(&wrStrm); |
|
338 |
|
339 TRAP(err, TSqlBlob::SetL(db, _L("A"), _L("B1"), _L8("UUUUUUUU"), 4)); |
|
340 TEST2(err, KErrNone); |
|
341 TRAP(err, TSqlBlob::SetL(db, _L("B"), _L("B2"), _L8("SSS"), 4)); |
|
342 TEST2(err, KErrNone); |
|
343 |
|
344 // SQLite and system tables |
|
345 |
|
346 // Attempt to read from and write to the SQLite master table - |
|
347 // reads should be permitted because schema capability is enough for this, |
|
348 // writes should be permitted because schema capability is enough for this |
|
349 CleanupClosePushL(rdStrm); |
|
350 TRAP(err, rdStrm.OpenL(db, _L("sqlite_master"), _L("tbl_name"), 1)); // TEXT column |
|
351 TEST2(err, KErrNone); |
|
352 TRAP(err, rdStrm.ReadL(data, 1)); |
|
353 TEST2(err, KErrNone); |
|
354 CleanupStack::PopAndDestroy(&rdStrm); |
|
355 |
|
356 wholeBuf = TSqlBlob::GetLC(db, _L("sqlite_master"), _L("tbl_name"), 1); |
|
357 TEST(wholeBuf->Length() > 0); |
|
358 CleanupStack::PopAndDestroy(wholeBuf); |
|
359 |
|
360 buf = HBufC8::NewLC(100); |
|
361 bufPtr.Set(buf->Des()); |
|
362 err = TSqlBlob::Get(db, _L("sqlite_master"), _L("tbl_name"), bufPtr, 1); |
|
363 TEST2(err, KErrNone); |
|
364 TEST(bufPtr.Length() > 0); |
|
365 CleanupStack::PopAndDestroy(buf); |
|
366 |
|
367 CleanupClosePushL(wrStrm); |
|
368 TRAP(err, wrStrm.OpenL(db, _L("sqlite_master"), _L("tbl_name"), 1)); |
|
369 TEST2(err, KErrNone); |
|
370 TRAP(err, wrStrm.WriteL(_L8("myTableName"))); |
|
371 TEST2(err, KErrNone); |
|
372 CleanupStack::PopAndDestroy(&wrStrm); |
|
373 |
|
374 TRAP(err, TSqlBlob::SetL(db, _L("sqlite_master"), _L("tbl_name"), _L8("myTableName"), 1)); |
|
375 TEST2(err, KErrNone); |
|
376 |
|
377 // Attempt to read from and write to the system tables - neither reads nor writes should be permitted |
|
378 CleanupClosePushL(rdStrm); |
|
379 TRAP(err, rdStrm.OpenL(db, _L("symbian_security"), _L("PolicyData"), 1)); // BLOB column |
|
380 TEST2(err, KErrPermissionDenied); |
|
381 CleanupStack::PopAndDestroy(&rdStrm); |
|
382 |
|
383 TRAP(err, wholeBuf = TSqlBlob::GetLC(db, _L("symbian_security"), _L("PolicyData"), 1)); |
|
384 TEST2(err, KErrPermissionDenied); |
|
385 |
|
386 buf = HBufC8::NewLC(100); |
|
387 bufPtr.Set(buf->Des()); |
|
388 err = TSqlBlob::Get(db, _L("symbian_security"), _L("PolicyData"), bufPtr, 1); |
|
389 TEST2(err, KErrPermissionDenied); |
|
390 CleanupStack::PopAndDestroy(buf); |
|
391 |
|
392 CleanupClosePushL(wrStrm); |
|
393 TRAP(err, wrStrm.OpenL(db, _L("symbian_security"), _L("PolicyData"), 1)); |
|
394 TEST2(err, KErrPermissionDenied); |
|
395 CleanupStack::PopAndDestroy(&wrStrm); |
|
396 |
|
397 TRAP(err, TSqlBlob::SetL(db, _L("symbian_security"), _L("PolicyData"), _L8("VVVV"), 1)); |
|
398 TEST2(err, KErrPermissionDenied); |
|
399 |
|
400 db.Close(); |
|
401 } |
|
402 |
|
403 void DoTestsL() |
|
404 { |
|
405 TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-SQL-CT-1647 Schema database access test ")); |
|
406 SchemaSecurityTest(); |
|
407 |
|
408 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4037 Declared column type test")); |
|
409 DeclaredColumnTypeTest(); |
|
410 |
|
411 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4046 Size(TSize&) test")); |
|
412 Size2Test(); |
|
413 |
|
414 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4047 Compact() test")); |
|
415 CompactTest(); |
|
416 |
|
417 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4098 Schema blob access test")); |
|
418 SchemaBlobTestL(); |
|
419 |
|
420 RestoreOriginalDb(); // the same db is used by the other t_security test exe's |
|
421 } |
|
422 |
|
423 TInt E32Main() |
|
424 { |
|
425 TheTest.Title(); |
|
426 |
|
427 CTrapCleanup* tc = CTrapCleanup::New(); |
|
428 |
|
429 __UHEAP_MARK; |
|
430 |
|
431 TRAPD(err, DoTestsL()); |
|
432 TEST2(err, KErrNone); |
|
433 |
|
434 __UHEAP_MARKEND; |
|
435 |
|
436 TheTest.End(); |
|
437 TheTest.Close(); |
|
438 |
|
439 delete tc; |
|
440 |
|
441 User::Heap().Check(); |
|
442 return KErrNone; |
|
443 } |