persistentstorage/sql/TEST/t_sqlsecurity2.cpp
changeset 0 08ec8eefde2f
child 8 fa9941cf3867
--- /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 <e32test.h>
+#include <bautils.h>
+#include <sqldb.h>
+
+///////////////////////////////////////////////////////////////////////////////////////
+//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;
+	}