diff -r 000000000000 -r 08ec8eefde2f persistentstorage/sql/TEST/t_sqlsecurity2.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/persistentstorage/sql/TEST/t_sqlsecurity2.cpp Fri Jan 22 11:06:30 2010 +0200 @@ -0,0 +1,361 @@ +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// t_sqlsecurity2 application has capabilities allowing read-only access to the test database +// +// + +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////////////////// +//The test database has: +// SCHEMA database policy: ECapabilityReadDeviceData, ECapabilityWriteUserData, ECapabilityReadUserData +// WRITE database policy: ECapabilityWriteUserData +// READ database policy: ECapabilityReadUserData +// +//Database tables: +// TABLE A(F1 INTEGER, B1 BLOB) +// TABLE B(F2 INTEGER, F3 TEXT, B2 BLOB) +// +//Database data: +// TABLE A: {1, x'41414141414141414141'}, {2, x'42424242424242424242'}, {3, x'43434343434343434343'}, {4, x'44444444444444444444'} +// TABLE B: {2, "ABC", x'45454545454545454545'}, {4, "DEF", x'46464646464646464646'} + +/////////////////////////////////////////////////////////////////////////////////////// + +#define UNUSED_VAR(a) (a) = (a) + +RTest TheTest(_L("t_sqlsecurity2 test")); +RSqlDatabase TheDb; + +_LIT(KTestDbName, "c:[21212125]t_ab.db"); +_LIT(KTestDbName2, "c:\\test\\t_sqlsecurity2_2.db"); + +/////////////////////////////////////////////////////////////////////////////////////// + +void DeleteTestDb() + { + TheDb.Close(); + (void)RSqlDatabase::Delete(KTestDbName2); + } + +/////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +//Test macros and functions +void Check1(TInt aValue, TInt aLine) + { + if(!aValue) + { + DeleteTestDb(); + RDebug::Print(_L("*** Line %d\r\n"), aLine); + TheTest(EFalse, aLine); + } + } +void Check2(TInt aValue, TInt aExpected, TInt aLine) + { + if(aValue != aExpected) + { + DeleteTestDb(); + RDebug::Print(_L("*** Line %d, Expected error: %d, got: %d\r\n"), aLine, aExpected, aValue); + TheTest(EFalse, aLine); + } + } +#define TEST(arg) ::Check1((arg), __LINE__) +#define TEST2(aValue, aExpected) ::Check2(aValue, aExpected, __LINE__) + +/////////////////////////////////////////////////////////////////////////////////////// + +/** +@SYMTestCaseID SYSLIB-SQL-CT-1644 +@SYMTestCaseDesc Testing database operations on a secure database. + The test application's capabilities allow read-only access to the test secure database. + Verify that any other kind of a database operation will fail with KErrPermissionDenied error. +@SYMTestPriority High +@SYMTestActions Testing database operations on a secure database. +@SYMTestExpectedResults Test must not fail +@SYMREQ REQ5792 + REQ5793 +*/ +void ReadOnlyDatabaseTest() + { + TInt err = TheDb.Open(KTestDbName); + TEST2(err, KErrNone); + + //Attempt to modify the database schema + err = TheDb.Exec(_L("CREATE TABLE C(FFF TEXT)")); + TEST2(err, KErrPermissionDenied); + //Attempt to update the user data + err = TheDb.Exec(_L("UPDATE A SET F1 = 11 WHERE F1 = 1")); + TEST2(err, KErrPermissionDenied); + //Attempt to delete the user data + err = TheDb.Exec(_L("DELETE FROM B WHERE F2 = 2")); + TEST2(err, KErrPermissionDenied); + //Attempt to insert new user data + err = TheDb.Exec(_L("INSERT INTO B(F2, F3) VALUES(22, 'AAA')")); + TEST2(err, KErrPermissionDenied); + //Attempt to read the user data + RSqlStatement stmt; + err = stmt.Prepare(TheDb, _L("SELECT A.F1 FROM B,A WHERE A.F1 = B.F2")); + TEST2(err, KErrNone); + //ColumnCount() has no capabilities assigned + TInt colCnt = stmt.ColumnCount(); + TEST2(colCnt, 1); + //DeclaredColumnType() has no capabilities assigned + TSqlColumnType colType; + err = stmt.DeclaredColumnType(0, colType); + TEST2(err, KErrNone); + TEST2(colType, ESqlInt); + err = stmt.Next(); + TEST2(err, KSqlAtRow); + RDebug::Print(_L("Value=%d\r\n"), stmt.ColumnInt(0)); + err = stmt.Next(); + TEST2(err, KSqlAtRow); + RDebug::Print(_L("Value=%d\r\n"), stmt.ColumnInt(0)); + stmt.Close(); + //Attempt to read the system data + err = stmt.Prepare(TheDb, _L("SELECT * FROM SQLITE_MASTER")); + TEST2(err, KErrNone); + err = stmt.Next(); + TEST2(err, KSqlAtRow); + TPtrC p; + err = stmt.ColumnText(0, p); + TEST2(err, KErrNone); + RDebug::Print(_L("Value=%S\r\n"), &p); + stmt.Close(); + + //Attempt to execute PRAGMA statement directly + err = TheDb.Exec(_L("PRAGMA encoding = \"UTF-8\"")); + TEST2(err, KErrPermissionDenied); + + TheDb.Close(); + } + +/** +@SYMTestCaseID SYSLIB-SQL-UT-4009 +@SYMTestCaseDesc PlatSec warnings can occur even if an SQL database is successfully opened. + This test application has a "ReadUserData" capability, and that should allow the + test database ("c:[21212125]t_ab.db") to be opened successfully, because the "read" + database policy consists of a "ReadUserData" capability only. + No platsec warnings should be seen in the log file ("epocwind.out" file). +@SYMTestPriority High +@SYMTestActions PlatSec warnings can occur even if an SQL database is successfully opened. +@SYMTestExpectedResults Test must not fail +@SYMDEF DEF115811 +*/ +void DEF115811() + { + TInt err = TheDb.Open(KTestDbName); + TEST2(err, KErrNone); + TheDb.Close(); + } + +/** +@SYMTestCaseID SYSLIB-SQL-UT-4095 +@SYMTestCaseDesc Testing incremental blob reads on a secure database. + The test application's capabilities allow read-only access to the blobs. + Verify that any attempt to write to a blob will fail with KErrPermissionDenied. +@SYMTestPriority High +@SYMTestActions Testing incremental blob reads on a secure database. +@SYMTestExpectedResults Test must not fail +@SYMREQ REQ5794 +*/ +void ReadOnlyBlobTestL() + { + TInt err = TheDb.Open(KTestDbName); + TEST2(err, KErrNone); + + // Attempt to read the blobs in tables A and B + RSqlBlobReadStream rdStrm; + CleanupClosePushL(rdStrm); + TBuf8<20> data; + TRAP(err, rdStrm.OpenL(TheDb, _L("A"), _L("B1"), 1)); + TEST2(err, KErrNone); + TRAP(err, rdStrm.ReadL(data, 3)); + TEST2(err, KErrNone); + TEST(data.Compare(_L8("AAA")) == 0); + rdStrm.Close(); + TRAP(err, rdStrm.OpenL(TheDb, _L("B"), _L("B2"), 2)); + TEST2(err, KErrNone); + TRAP(err, rdStrm.ReadL(data, 10)); + TEST2(err, KErrNone); + TEST(data.Compare(_L8("FFFFFFFFFF")) == 0); + CleanupStack::PopAndDestroy(&rdStrm); + + HBufC8* wholeBuf = TSqlBlob::GetLC(TheDb, _L("A"), _L("B1"), 4); + TEST(wholeBuf->Des().Compare(_L8("DDDDDDDDDD")) == 0); + CleanupStack::PopAndDestroy(wholeBuf); + wholeBuf = TSqlBlob::GetLC(TheDb, _L("B"), _L("B2"), 1); + TEST(wholeBuf->Des().Compare(_L8("EEEEEEEEEE")) == 0); + CleanupStack::PopAndDestroy(wholeBuf); + + HBufC8* buf = HBufC8::NewLC(10); + TPtr8 bufPtr(buf->Des()); + err = TSqlBlob::Get(TheDb, _L("A"), _L("B1"), bufPtr, 2); + TEST2(err, KErrNone); + TEST(bufPtr.Compare(_L8("BBBBBBBBBB")) == 0); + err = TSqlBlob::Get(TheDb, _L("B"), _L("B2"), bufPtr, 2); + TEST2(err, KErrNone); + TEST(bufPtr.Compare(_L8("FFFFFFFFFF")) == 0); + CleanupStack::PopAndDestroy(buf); + + // Attempt to write to the blobs in tables A and B + RSqlBlobWriteStream wrStrm; + CleanupClosePushL(wrStrm); + TRAP(err, wrStrm.OpenL(TheDb, _L("A"), _L("B1"), 1)); + TEST2(err, KErrPermissionDenied); + wrStrm.Close(); + TRAP(err, wrStrm.OpenL(TheDb, _L("B"), _L("B2"), 1)); + TEST2(err, KErrPermissionDenied); + CleanupStack::PopAndDestroy(&wrStrm); + + TRAP(err, TSqlBlob::SetL(TheDb, _L("A"), _L("B1"), _L8("VVVV"), 1)); + TEST2(err, KErrPermissionDenied); + TRAP(err, TSqlBlob::SetL(TheDb, _L("B"), _L("B2"), _L8("VVVV"), 1)); + TEST2(err, KErrPermissionDenied); + + // SQLite and system tables + + // Attempt to read from and write to the SQLite master table - only reads should be permitted + CleanupClosePushL(rdStrm); + TRAP(err, rdStrm.OpenL(TheDb, _L("sqlite_master"), _L("tbl_name"), 1)); // TEXT column + TEST2(err, KErrNone); + TRAP(err, rdStrm.ReadL(data, 1)); + TEST2(err, KErrNone); + CleanupStack::PopAndDestroy(&rdStrm); + + wholeBuf = TSqlBlob::GetLC(TheDb, _L("sqlite_master"), _L("tbl_name"), 1); + TEST(wholeBuf->Length() > 0); + CleanupStack::PopAndDestroy(wholeBuf); + + buf = HBufC8::NewLC(100); + bufPtr.Set(buf->Des()); + err = TSqlBlob::Get(TheDb, _L("sqlite_master"), _L("tbl_name"), bufPtr, 1); + TEST2(err, KErrNone); + TEST(bufPtr.Length() > 0); + CleanupStack::PopAndDestroy(buf); + + CleanupClosePushL(wrStrm); + TRAP(err, wrStrm.OpenL(TheDb, _L("sqlite_master"), _L("tbl_name"), 1)); + TEST2(err, KErrPermissionDenied); + CleanupStack::PopAndDestroy(&wrStrm); + + TRAP(err, TSqlBlob::SetL(TheDb, _L("sqlite_master"), _L("tbl_name"), _L8("VVVV"), 1)); + TEST2(err, KErrPermissionDenied); + + // Attempt to read from and write to the system tables - neither reads nor writes should be permitted + CleanupClosePushL(rdStrm); + TRAP(err, rdStrm.OpenL(TheDb, _L("symbian_security"), _L("PolicyData"), 1)); // BLOB column + TEST2(err, KErrPermissionDenied); + CleanupStack::PopAndDestroy(&rdStrm); + + TRAP(err, wholeBuf = TSqlBlob::GetLC(TheDb, _L("symbian_security"), _L("PolicyData"), 1)); + TEST2(err, KErrPermissionDenied); + + buf = HBufC8::NewLC(100); + bufPtr.Set(buf->Des()); + err = TSqlBlob::Get(TheDb, _L("symbian_security"), _L("PolicyData"), bufPtr, 1); + TEST2(err, KErrPermissionDenied); + CleanupStack::PopAndDestroy(buf); + + CleanupClosePushL(wrStrm); + TRAP(err, wrStrm.OpenL(TheDb, _L("symbian_security"), _L("PolicyData"), 1)); + TEST2(err, KErrPermissionDenied); + CleanupStack::PopAndDestroy(&wrStrm); + + TRAP(err, TSqlBlob::SetL(TheDb, _L("symbian_security"), _L("PolicyData"), _L8("VVVV"), 1)); + TEST2(err, KErrPermissionDenied); + + TheDb.Close(); + } + +/** +@SYMTestCaseID SYSLIB-SQL-UT-4078 +@SYMTestCaseDesc RSqlDatabase::Compact(), platsec test. + The test verifies that RSqlDatabase::Compact() can be called + on the main or on an attached database no matter what the client capabilities are. +@SYMTestPriority Medium +@SYMTestActions RSqlDatabase::Compact(), platsec test. +@SYMTestExpectedResults Test must not fail +@SYMREQ REQ10405 +*/ +void CompactTest() + { + TInt err = TheDb.Open(KTestDbName); + TEST2(err, KErrNone); + + err = TheDb.Compact(RSqlDatabase::EMaxCompaction); + TEST(err >= 0); + + TRequestStatus stat; + TheDb.Compact(RSqlDatabase::EMaxCompaction, stat); + User::WaitForRequest(stat); + TEST(stat.Int() >= 0); + + TheDb.Close(); + + err = TheDb.Create(KTestDbName2); + TEST2(err, KErrNone); + _LIT(KDbName, "Db"); + err = TheDb.Attach(KTestDbName, KDbName); + TEST2(err, KErrNone); + + err = TheDb.Compact(RSqlDatabase::EMaxCompaction, KDbName); + TEST(err >= 0); + + TheDb.Compact(RSqlDatabase::EMaxCompaction, stat, KDbName); + User::WaitForRequest(stat); + TEST(stat.Int() >= 0); + + err = TheDb.Detach(KDbName); + TheDb.Close(); + (void)RSqlDatabase::Delete(KTestDbName2); + } + +void DoTestsL() + { + TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-SQL-CT-1644 Read-only database access test ")); + ReadOnlyDatabaseTest(); + + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4009 DEF115811 - PlatSec warnings can occur even if an SQL database is successfully opened ")); + DEF115811(); + + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4095 - Read-only blob access test")); + ReadOnlyBlobTestL(); + + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4078 - RSqlDatabase::Compact() test")); + CompactTest(); + } + +TInt E32Main() + { + TheTest.Title(); + + CTrapCleanup* tc = CTrapCleanup::New(); + + __UHEAP_MARK; + + TRAPD(err, DoTestsL()); + TEST2(err, KErrNone); + + __UHEAP_MARKEND; + + TheTest.End(); + TheTest.Close(); + + delete tc; + + User::Heap().Check(); + return KErrNone; + }