sl@0: // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include sl@0: #include "Thelpers.h" sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: #include "TestUtils.h" sl@0: #include "platsectaskcommon.h" sl@0: sl@0: _LIT(KTestName, "Task Scheduler platform security Test"); sl@0: sl@0: _LIT(KProcess1, "tschsvrclient1"); sl@0: _LIT(KProcess2, "tschsvrclient2"); sl@0: _LIT(KProcess3, "tschsvrclient3"); sl@0: sl@0: RTest TheTest(KTestName); sl@0: sl@0: typedef CArrayFixFlat CSchEntryInfoArray; sl@0: typedef CArrayFixFlat CTaskInfoArray; sl@0: typedef CArrayFixFlat CSchItemRefArray; sl@0: sl@0: static RScheduler TheScheduler; sl@0: static CTrapCleanup* TheCleanup; sl@0: static RFs TheFsSession; sl@0: sl@0: //creates a daily schedule with StartTime of aStartTime sl@0: static TInt CreateScheduleL(TSchedulerItemRef& aRef, sl@0: RScheduler& aScheduler, sl@0: const TTime& aStartTime) sl@0: { sl@0: CSchEntryInfoArray* entryList sl@0: = new (ELeave) CSchEntryInfoArray(1); sl@0: CleanupStack::PushL(entryList); sl@0: sl@0: TScheduleEntryInfo entry1; sl@0: entry1.iStartTime = aStartTime; sl@0: entry1.iInterval = 1; // TTimeIntervalDays sl@0: entry1.iIntervalType = EDaily; sl@0: entry1.iValidityPeriod = 30; // minutes sl@0: entryList->AppendL(entry1); sl@0: TInt res = aScheduler.CreatePersistentSchedule(aRef, *entryList); sl@0: CleanupStack::PopAndDestroy(); // entryList sl@0: return res; sl@0: } sl@0: sl@0: static void LaunchClient(TInt aScheduleHandle, sl@0: TInt aTaskHandle, sl@0: const TDesC& aClient, sl@0: TInt aErrorCondition, sl@0: TInt aScheduleCount, sl@0: TInt aTaskCount) sl@0: { sl@0: // now launch process to try and access schedule sl@0: TRequestStatus stat; sl@0: RProcess client; sl@0: sl@0: TBuf<30> id; sl@0: id.Append(':'); sl@0: id.AppendNum(aScheduleHandle); sl@0: id.Append(':'); sl@0: id.AppendNum(aTaskHandle); sl@0: id.Append(':'); sl@0: id.AppendNum(aErrorCondition); sl@0: id.Append(':'); sl@0: id.AppendNum(aScheduleCount); sl@0: id.Append(':'); sl@0: id.AppendNum(aTaskCount); sl@0: id.Append(':'); sl@0: sl@0: TInt res = client.Create(aClient, id); sl@0: TEST2(res, KErrNone); sl@0: // Asynchronous logon: completes when process terminates with process exit code sl@0: client.Logon(stat); sl@0: client.Resume(); sl@0: sl@0: User::WaitForRequest(stat); sl@0: sl@0: TInt exitReason = client.ExitReason(); sl@0: TEST2(exitReason, KErrNone); sl@0: client.Close(); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-SCHSVR-CT-0025 sl@0: @SYMTestCaseDesc Check that schedules/tasks cannot be manipulated by unauthorised clients sl@0: @SYMTestPriority High sl@0: @SYMTestActions Ensure permission denied for client with the wrong SID and without WriteDeviceData sl@0: Ensure permission granted for client with the wrong SID but with WriteDeviceData sl@0: @SYMTestExpectedResults Only the schedule creator or clients with WriteDeviceData can manipulate schedules/tasks. sl@0: @SYMPREQ 277 Ensure integrity of Symbian OS handsets sl@0: */ sl@0: static void DoTest1L() sl@0: { sl@0: sl@0: TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SCHSVR-CT-0025 platformsec - API policing ")); sl@0: sl@0: TheTest.Next(_L("Connect to Scheduler")); sl@0: TInt res = TheScheduler.Connect(); sl@0: TEST2(res, KErrNone); sl@0: sl@0: TheTest.Next(_L("Registering Client")); sl@0: TEST2(SchSvrHelpers::RegisterClientL(TheScheduler), KErrNone); sl@0: sl@0: // Create a schedule sl@0: TheTest.Next(_L("Creating schedule")); sl@0: TSchedulerItemRef scheduleHandle; sl@0: TTime time; sl@0: time.HomeTime(); sl@0: time += TTimeIntervalHours(1); //Task to go off one hour from now (ie we dont sl@0: //want it going off for the purposes of this test) sl@0: User::LeaveIfError(CreateScheduleL(scheduleHandle, TheScheduler, time)); sl@0: sl@0: // Add a task to the schedule sl@0: TheTest.Next(_L("Creating task for schedule")); sl@0: TTaskInfo taskInfo; sl@0: taskInfo.iName = _L("MyTaskName"); sl@0: taskInfo.iPriority = 2; sl@0: taskInfo.iTaskId = 0; sl@0: taskInfo.iRepeat = 1; sl@0: HBufC* data = _L("Tasks Data").AllocLC(); sl@0: res = TheScheduler.ScheduleTask(taskInfo, *data, scheduleHandle.iHandle); sl@0: CleanupStack::PopAndDestroy(); // data sl@0: TEST2(res, KErrNone); sl@0: sl@0: // Now launch client process with a different SID to ours sl@0: // and all capabilities excluding WriteDeviceData (and TCB) sl@0: // Client operations should fail with KErrPermissionDenied sl@0: TheTest.Next(_L("Launch Client1")); sl@0: LaunchClient(scheduleHandle.iHandle, sl@0: taskInfo.iTaskId, sl@0: KProcess1, sl@0: KErrPermissionDenied, sl@0: 0, sl@0: 0); sl@0: sl@0: TheScheduler.Close(); sl@0: // Now shut down the server and restart. sl@0: TheTest.Next(_L("shuting down and restarting server")); sl@0: CleanupHelpers::TestCleanupL(); sl@0: res = TheScheduler.Connect(); sl@0: TEST2(res, KErrNone); sl@0: TEST2(SchSvrHelpers::RegisterClientL(TheScheduler), KErrNone); sl@0: sl@0: //Check we still have 1 schedule and 1 task. sl@0: TheTest.Next(_L("Checking schedule info and launching client")); sl@0: CSchItemRefArray* refs = new (ELeave) CSchItemRefArray(3); sl@0: CleanupStack::PushL(refs); sl@0: res = TheScheduler.GetScheduleRefsL(*refs, EAllSchedules); sl@0: TEST2(res, KErrNone); sl@0: TInt count = refs->Count(); sl@0: TEST2(count, 1); sl@0: scheduleHandle.iHandle = refs->At(0).iHandle; sl@0: sl@0: res = TheScheduler.GetTaskRefsL(*refs, EAllSchedules, EAllTasks); sl@0: TEST2(res, KErrNone); sl@0: count = refs->Count(); sl@0: TEST2(count, 1); sl@0: taskInfo.iTaskId = refs->At(0).iHandle; sl@0: sl@0: CleanupStack::PopAndDestroy(refs); sl@0: sl@0: // Client operations should fail with KErrPermissionDenied sl@0: TheTest.Next(_L("Launch client1 again")); sl@0: LaunchClient(scheduleHandle.iHandle, sl@0: taskInfo.iTaskId, sl@0: KProcess1, sl@0: KErrPermissionDenied, sl@0: 0, sl@0: 0); sl@0: sl@0: // Try with client with no 3rd UID. sl@0: // Client operations should fail with KErrPermissionDenied sl@0: TheTest.Next(_L("Launch client3")); sl@0: LaunchClient(scheduleHandle.iHandle, sl@0: taskInfo.iTaskId, sl@0: KProcess3, sl@0: KErrPermissionDenied, sl@0: 0, sl@0: 0); sl@0: sl@0: // Now try with a client with WriteDeviceData. sl@0: // All operations should succeed sl@0: TheTest.Next(_L("Launch client2")); sl@0: LaunchClient(scheduleHandle.iHandle, sl@0: taskInfo.iTaskId, sl@0: KProcess2, sl@0: KErrNone, sl@0: 1, sl@0: 1); sl@0: sl@0: TheScheduler.Close(); sl@0: sl@0: SchSvrHelpers::Pause(TheTest); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-SCHSVR-CT-0026 sl@0: @SYMTestCaseDesc Check that the scheduled exe receives the security info of the schedule creator. sl@0: @SYMTestPriority High sl@0: @SYMTestActions Check that the scheduled exe receives the security info of the schedule creator. sl@0: @SYMTestExpectedResults The scheduled exe receives the security info of the schedule creator. sl@0: @SYMPREQ 277 Ensure integrity of Symbian OS handsets sl@0: */ sl@0: static void DoTest2L() sl@0: { sl@0: TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SCHSVR-CT-0026 platformsec - TSecurityInfo validity ")); sl@0: TheTest.Next(_L("Connect to Scheduler")); sl@0: TInt res = TheScheduler.Connect(); sl@0: TEST2(res, KErrNone); sl@0: sl@0: TheTest.Next(_L("Registering Client")); sl@0: TFileName filename; sl@0: filename = _L("PlatSecTaskHandler"); sl@0: TEST2(TheScheduler.Register(filename, 27), KErrNone); sl@0: sl@0: // Create a schedule sl@0: TheTest.Next(_L("Creating schedule")); sl@0: TSchedulerItemRef scheduleHandle; sl@0: TTime time; sl@0: time.HomeTime(); sl@0: time += TTimeIntervalSeconds(2); sl@0: User::LeaveIfError(CreateScheduleL(scheduleHandle, TheScheduler, time)); sl@0: sl@0: // Add a task to the schedule sl@0: TheTest.Next(_L("Creating task for schedule")); sl@0: TTaskInfo taskInfo; sl@0: taskInfo.iName = KPlatSecTaskName(); sl@0: taskInfo.iPriority = 2; sl@0: taskInfo.iTaskId = 0; sl@0: taskInfo.iRepeat = 1; sl@0: HBufC* data = KPlatSecTaskData().AllocLC(); sl@0: res = TheScheduler.ScheduleTask(taskInfo, *data, scheduleHandle.iHandle); sl@0: CleanupStack::PopAndDestroy(); // data sl@0: TEST2(res, KErrNone); sl@0: sl@0: TheTest.Next(_L("Wait for task to fire")); sl@0: TEST2(STaskSemaphore::WaitL(KDefaultTimeout), KErrNone); sl@0: sl@0: SchSvrHelpers::Pause(TheTest); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-SCHSVR-CT-1885 sl@0: @SYMTestCaseDesc Check that TTaskInfo states correctly persisted sl@0: @SYMTestPriority High sl@0: @SYMTestActions Setup a schedule and task and then close the server, reconnect and check that the schedule and task sl@0: info has been persisted correctly. sl@0: @SYMTestExpectedResults The test must not panic or fail. sl@0: @SYMDEF INC093573 sl@0: */ sl@0: static void DoTest3L() sl@0: { sl@0: TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SCHSVR-CT-1885 INC093573: Symbian provided task scheduler (RScheduler) loses parts of pending schedule inf ")); sl@0: TheTest.Next(_L("Connect to Scheduler")); sl@0: TInt res = TheScheduler.Connect(); sl@0: TEST2(res, KErrNone); sl@0: sl@0: TheTest.Next(_L("Registering Client")); sl@0: TEST2(SchSvrHelpers::RegisterClientL(TheScheduler), KErrNone); sl@0: sl@0: // Create a schedule sl@0: TheTest.Next(_L("Creating schedule")); sl@0: TSchedulerItemRef scheduleHandle; sl@0: TTime time; sl@0: time.HomeTime(); sl@0: time += TTimeIntervalHours(1); //Task to go off one hour from now (ie we dont sl@0: //want it going off for the purposes of this test) sl@0: User::LeaveIfError(CreateScheduleL(scheduleHandle, TheScheduler, time)); sl@0: sl@0: // Add a task to the schedule sl@0: TheTest.Next(_L("Creating task for schedule")); sl@0: TTaskInfo taskInfo; sl@0: taskInfo.iName = _L("INC093573"); sl@0: taskInfo.iPriority = 2; sl@0: taskInfo.iTaskId = 0; sl@0: taskInfo.iRepeat = -1; sl@0: HBufC* data = _L("Tasks Data").AllocLC(); sl@0: res = TheScheduler.ScheduleTask(taskInfo, *data, scheduleHandle.iHandle); sl@0: CleanupStack::PopAndDestroy(); // data sl@0: TEST2(res, KErrNone); sl@0: sl@0: TheScheduler.Close(); sl@0: sl@0: // Now shut down the server and restart. sl@0: TheTest.Next(_L("shuting down and restarting server")); sl@0: CleanupHelpers::TestCleanupL(); sl@0: res = TheScheduler.Connect(); sl@0: TEST2(res, KErrNone); sl@0: TEST2(SchSvrHelpers::RegisterClientL(TheScheduler), KErrNone); sl@0: sl@0: //Check that the task is still there with all the correct settings sl@0: TheTest.Next(_L("Checking schedule info and launching client")); sl@0: TTaskInfo returnedInfo; sl@0: TSchedulerItemRef returnedItemRef; sl@0: TTsTime returnedTsTime; sl@0: TInt size=0; sl@0: res=TheScheduler.GetTaskDataSize(0,size); sl@0: TEST2(res,KErrNone); sl@0: HBufC* buffer=HBufC::NewL(size); sl@0: TPtr modifiableBuffer=buffer->Des(); sl@0: sl@0: //now get the task info and compare to the original submitted to ensure that it is properly sl@0: //externalized when server shut down. sl@0: res=TheScheduler.GetTaskInfoL(0,returnedInfo,modifiableBuffer,returnedItemRef,returnedTsTime); sl@0: TEST2(res,KErrNone); sl@0: TEST2(returnedInfo.iPriority,taskInfo.iPriority); sl@0: TEST2(returnedInfo.iRepeat,taskInfo.iRepeat); sl@0: TEST2(returnedInfo.iTaskId,taskInfo.iTaskId); sl@0: TEST2(returnedInfo.iName.Compare(taskInfo.iName),0); sl@0: sl@0: //now clear the buffer sl@0: delete buffer; sl@0: } sl@0: sl@0: static TInt RunTestsL() sl@0: { sl@0: TheTest.Next(_L("Delete old files")); sl@0: SchSvrHelpers::DeleteScheduleFilesL(); sl@0: sl@0: TheTest.Next(_L("Create Task notification semaphore")); sl@0: //initialise task notification semaphore sl@0: STaskSemaphore sem; sl@0: sem.CreateL(); sl@0: sl@0: // Connect to the server sl@0: TheTest.Next(_L("===== Connect to Scheduler =====")); sl@0: TInt res = TheScheduler.Connect(); sl@0: TEST2(res, KErrNone); sl@0: sl@0: // Register a client with the server sl@0: TheTest.Next(_L("===== Registering Client =====")); sl@0: res = SchSvrHelpers::RegisterClientL(TheScheduler); sl@0: TEST2(res, KErrNone); sl@0: sl@0: CActiveScheduler* scheduler = new (ELeave) CActiveScheduler(); sl@0: CleanupStack::PushL(scheduler); sl@0: CActiveScheduler::Install(scheduler); sl@0: sl@0: TheTest.Next(_L("Start tests")); sl@0: sl@0: if(PlatSec::IsCapabilityEnforced(ECapabilityWriteDeviceData)) sl@0: DoTest1L(); sl@0: DoTest2L(); sl@0: DoTest3L(); sl@0: TheTest.Next(_L("Tidying up")); sl@0: CleanupStack::PopAndDestroy(scheduler); sl@0: //close handle to semaphore sl@0: sem.Close(); sl@0: sl@0: //Tidying up so next test will be clear. sl@0: TheTest.Next(_L("Delete all schedules")); sl@0: SchSvrHelpers::DeleteAllSchedulesL(TheScheduler); sl@0: SchSvrHelpers::Pause(TheTest, 2); sl@0: TheTest.Next(_L("Delete old files\n")); sl@0: SchSvrHelpers::DeleteScheduleFilesL(); sl@0: sl@0: TheScheduler.Close(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: GLDEF_C TInt E32Main() sl@0: { sl@0: __UHEAP_MARK; sl@0: TheTest.Start(_L("TC_TSCH_PLATSEC")); sl@0: TheTest.Title(); sl@0: sl@0: TheCleanup = CTrapCleanup::New(); sl@0: //If the previous test fails, SCHSVR.exe may stay in memory. sl@0: TRAPD(error, CleanupHelpers::TestCleanupL()); sl@0: TEST2(error, KErrNone); sl@0: sl@0: TheTest(TheFsSession.Connect() == KErrNone); sl@0: sl@0: TRAP(error, RunTestsL()); sl@0: TEST2(error,KErrNone); sl@0: sl@0: TRAP(error,CleanupHelpers::TestCleanupL()); sl@0: TEST2(error, KErrNone); sl@0: delete TheCleanup; sl@0: sl@0: TheFsSession.Close(); sl@0: TheTest.End(); sl@0: TheTest.Close(); sl@0: __UHEAP_MARKEND; sl@0: sl@0: return KErrNone; sl@0: }