sl@0: // Copyright (c) 2001-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 the License "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: // e32test\secure\t_platsecconfig.cpp sl@0: // This test checks the correct functioning of the Platform Security configuration. sl@0: // To use this test for verification of the features, perform the following steps sl@0: // On the WINS Emulator sl@0: // 1. Run "T_PLATSECCONFIG.EXE" sl@0: // Check that the results reported are: sl@0: // PlatSecEnforcement is OFF sl@0: // Disabled Capabilites: NONE sl@0: // Check EPOCWIND.OUT and verify that it contains no diagnostic messages. (These will start with the text "*PlatSec* ") sl@0: // 2. Run "T_PLATSECCONFIG.EXE -mt_platsecconfig --" sl@0: // Check that the results reported are: sl@0: // PlatSecEnforcement is ON sl@0: // Disabled Capabilites: CommDD MultimediaDD WriteDeviceData TrustedUI DiskAdmin AllFiles NetworkServices ReadUserData Location (These are all ODD numbered capabilities) sl@0: // Check EPOCWIND.OUT and verify that it contains two lines starting with "*PlatSec* ERROR - Capability check failed" sl@0: // On reference hardware sl@0: // 3. Build a Text Shell ROM contining the E32 tests. E.g. sl@0: // cd \cedar\generic\base\e32\rombuild sl@0: // rom -v=lubbock -t=e32test sl@0: // Boot this ROM and run "T_PLATSECCONFIG.EXE" sl@0: // Check that the results reported are: sl@0: // PlatSecEnforcement is OFF sl@0: // Disabled Capabilites: NONE sl@0: // Check the output of the debug port and verify that it contains no diagnostic messages. sl@0: // (These will start with the text "*PlatSec* ") sl@0: // 4. Build a Text Shell ROM using the T_PLATSECCONFIG.OBY file. E.g. sl@0: // cd \cedar\generic\base\e32\rombuild sl@0: // rom -v=lubbock -t=t_platsecconfig sl@0: // Boot this ROM and run "T_PLATSECCONFIG.EXE" sl@0: // Check that the results reported are: sl@0: // PlatSecEnforcement is ON sl@0: // Disabled Capabilites: CommDD MultimediaDD WriteDeviceData TrustedUI DiskAdmin AllFiles NetworkServices ReadUserData Location (These are all ODD numbered capabilities) sl@0: // Check the output of the debug port and verify that it contains two lines with "*PlatSec* ERROR - Capability check failed" sl@0: // To check ROMBUILD configuration sl@0: // 5. Build a Text Shell ROM using the T_PLATSECCONFIG_WARNIG.OBY file. E.g. sl@0: // cd \cedar\generic\base\e32\rombuild sl@0: // rom -v=lubbock -t=t_platsecconfig_warning sl@0: // This should produce the following warning: sl@0: // WARNING: *PlatSec* WARNING - Capability check failed. Can't load \Epoc32\RELEASE\ARM4\UDEB\t_psc_static.exebecause it links to t_psc_dll{00010000}.dll which has the following capabilities missing: TCB PowerMgmt ReadDeviceData DRM ProtServ NetworkControl SwEvent LocalServices WriteUserData sl@0: // 6. Build a Text Shell ROM using the T_PLATSECCONFIG_ERROR.OBY file. E.g. sl@0: // cd \cedar\generic\base\e32\rombuild sl@0: // rom -v=lubbock -t=t_platsecconfig_error sl@0: // This should produce the following error: sl@0: // ERROR: *PlatSec* ERROR - Capability check failed. Can't load \Epoc32\RELEASE\ARM4\UDEB\t_psc_static.exe because it links to t_psc_dll{00010000}.dll which has the following capabilities missing: TCB PowerMgmt ReadDeviceData DRM ProtServ NetworkControl SwEvent LocalServices WriteUserData sl@0: // sl@0: // sl@0: sl@0: /** sl@0: @file sl@0: */ sl@0: sl@0: #define __INCLUDE_CAPABILITY_NAMES__ sl@0: sl@0: #include sl@0: sl@0: LOCAL_D RTest test(_L("T_PLATSECCONFIG")); sl@0: sl@0: enum TTestProcessFunctions sl@0: { sl@0: ETestProcessServer, sl@0: ETestProcessLoadLib, sl@0: }; sl@0: sl@0: #include "testprocess.h" sl@0: sl@0: TInt StartServer(); sl@0: sl@0: TInt DoTestProcess(TInt aTestNum,TInt aArg1,TInt aArg2) sl@0: { sl@0: (void)aArg1; sl@0: (void)aArg2; sl@0: sl@0: switch(aTestNum) sl@0: { sl@0: sl@0: case ETestProcessServer: sl@0: return StartServer(); sl@0: sl@0: case ETestProcessLoadLib: sl@0: { sl@0: RLibrary lib; sl@0: TInt r = lib.Load(_L("T_PSC_DLL")); sl@0: lib.Close(); sl@0: return r; sl@0: } sl@0: sl@0: default: sl@0: User::Panic(_L("T_PLATSECCONFIG"),1); sl@0: } sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: sl@0: // sl@0: // RTestThread sl@0: // sl@0: sl@0: class RTestThread : public RThread sl@0: { sl@0: public: sl@0: void Create(TThreadFunction aFunction,TAny* aArg=0); sl@0: }; sl@0: sl@0: void RTestThread::Create(TThreadFunction aFunction,TAny* aArg) sl@0: { sl@0: TInt r=RThread::Create(_L(""),aFunction,KDefaultStackSize,KDefaultStackSize,KDefaultStackSize,aArg); sl@0: test(r==KErrNone); sl@0: } sl@0: sl@0: sl@0: // sl@0: // CTestSession sl@0: // sl@0: sl@0: class CTestSession : public CSession2 sl@0: { sl@0: public: sl@0: enum {EShutdown,EGetSecurityInfo}; sl@0: public: sl@0: CTestSession(); sl@0: virtual void ServiceL(const RMessage2& aMessage); sl@0: public: sl@0: }; sl@0: sl@0: CTestSession::CTestSession() sl@0: : CSession2() sl@0: {} sl@0: sl@0: void CTestSession::ServiceL(const RMessage2& aMessage) sl@0: { sl@0: RMessagePtr2 m(aMessage); sl@0: switch (aMessage.Function()) sl@0: { sl@0: case CTestSession::EGetSecurityInfo: sl@0: { sl@0: TSecurityInfo info; sl@0: info.Set(RProcess()); sl@0: TInt r = aMessage.Write(0,TPtrC8((TUint8*)&info,sizeof(info))); sl@0: m.Complete(r); sl@0: } sl@0: break; sl@0: sl@0: case CTestSession::EShutdown: sl@0: CActiveScheduler::Stop(); sl@0: break; sl@0: sl@0: default: sl@0: m.Complete(KErrNotSupported); sl@0: break; sl@0: } sl@0: } sl@0: sl@0: sl@0: sl@0: // sl@0: // CTestServer sl@0: // sl@0: sl@0: class CTestServer : public CServer2 sl@0: { sl@0: public: sl@0: CTestServer(TInt aPriority); sl@0: virtual CSession2* NewSessionL(const TVersion& aVersion,const RMessage2& aMessage) const; sl@0: }; sl@0: sl@0: CTestServer::CTestServer(TInt aPriority) sl@0: : CServer2(aPriority) sl@0: { sl@0: } sl@0: sl@0: CSession2* CTestServer::NewSessionL(const TVersion& /*aVersion*/,const RMessage2& /*aMessage*/) const sl@0: { sl@0: return new (ELeave) CTestSession(); sl@0: } sl@0: sl@0: sl@0: sl@0: // sl@0: // CTestActiveScheduler sl@0: // sl@0: sl@0: class CTestActiveScheduler : public CActiveScheduler sl@0: { sl@0: public: sl@0: virtual void Error(TInt anError) const; sl@0: }; sl@0: sl@0: void CTestActiveScheduler::Error(TInt anError) const sl@0: { sl@0: User::Panic(_L("TestServer Error"),anError); sl@0: } sl@0: sl@0: sl@0: sl@0: // sl@0: // Server thread sl@0: // sl@0: sl@0: _LIT(KServerName,"T_PLATSECCONFIG-server"); sl@0: const TInt KServerRendezvous = KRequestPending+1; sl@0: sl@0: void DoStartServer() sl@0: { sl@0: CTestActiveScheduler* activeScheduler = new (ELeave) CTestActiveScheduler; sl@0: CActiveScheduler::Install(activeScheduler); sl@0: CleanupStack::PushL(activeScheduler); sl@0: sl@0: CTestServer* server = new (ELeave) CTestServer(0); sl@0: CleanupStack::PushL(server); sl@0: sl@0: User::LeaveIfError(server->Start(KServerName)); sl@0: sl@0: RProcess::Rendezvous(KServerRendezvous); sl@0: sl@0: CActiveScheduler::Start(); sl@0: sl@0: CleanupStack::PopAndDestroy(2); sl@0: } sl@0: sl@0: TInt StartServer() sl@0: { sl@0: CTrapCleanup* cleanupStack = CTrapCleanup::New(); sl@0: if(!cleanupStack) sl@0: return KErrNoMemory; sl@0: TRAPD(leaveError,DoStartServer()) sl@0: delete cleanupStack; sl@0: return leaveError; sl@0: } sl@0: sl@0: sl@0: sl@0: // sl@0: // RTestSession sl@0: // sl@0: sl@0: class RTestSession : public RSessionBase sl@0: { sl@0: public: sl@0: inline TInt Connect() sl@0: { return CreateSession(KServerName,TVersion());} sl@0: inline TInt Send(TInt aFunction) sl@0: { return RSessionBase::SendReceive(aFunction); } sl@0: inline TInt Send(TInt aFunction,const TIpcArgs& aArgs) sl@0: { return RSessionBase::SendReceive(aFunction,aArgs); } sl@0: inline void Send(TInt aFunction,TRequestStatus& aStatus) sl@0: { RSessionBase::SendReceive(aFunction,aStatus); } sl@0: inline void Send(TInt aFunction,const TIpcArgs& aArgs,TRequestStatus& aStatus) sl@0: { RSessionBase::SendReceive(aFunction,aArgs,aStatus); } sl@0: }; sl@0: sl@0: sl@0: sl@0: RTestSession Session; sl@0: sl@0: sl@0: sl@0: void CheckCapabilitySetEqual(const TCapabilitySet& a1,const TCapabilitySet& a2) sl@0: { sl@0: TInt i; sl@0: for(i=0; i CapabilityNameBuffer; sl@0: TBool PlatSecEnforcement=0; sl@0: sl@0: TPtrC16 CapabilityList(const TCapabilitySet& aCaps) sl@0: { sl@0: TCapabilitySet allCaps; sl@0: allCaps.SetAllSupported(); sl@0: CapabilityNameBuffer.Zero(); sl@0: TBool odd=ETrue; sl@0: TBool even=ETrue; sl@0: TInt i; sl@0: for(i=0; i infoPtr(info); sl@0: sl@0: test.Start(_L("Get disabled capabilities set")); sl@0: TCapabilitySet disabled; sl@0: disabled.SetDisabled(); sl@0: TPtrC16 list(CapabilityList(disabled)); sl@0: test.Printf(_L(" %S\n"),&list); sl@0: sl@0: test.Next(_L("Get capabilites from this EXE")); sl@0: Mem::FillZ(&info,sizeof(info)); sl@0: info.SetToCurrentInfo(); sl@0: sl@0: test.Next(_L("Check capabilities are same as disabled set")); sl@0: CheckCapabilitySetEqual(info.iCaps,disabled); sl@0: sl@0: test.Next(_L("Get capabilites from other EXE")); sl@0: Mem::FillZ(&info,sizeof(info)); sl@0: TInt r = Session.Send(CTestSession::EGetSecurityInfo,TIpcArgs(&infoPtr)); sl@0: test(r==KErrNone); sl@0: sl@0: test.Next(_L("Check capabilities are same as disabled set")); sl@0: CheckCapabilitySetEqual(info.iCaps,disabled); sl@0: sl@0: test.Next(_L("Test PlatSec::IsCapabilityEnforced is consistant with our findings")); sl@0: TCapabilitySet notEnforced; sl@0: notEnforced.SetEmpty(); sl@0: for(TInt i=0; i arg; sl@0: arg.Num((TInt)ETestProcessLoadLib); sl@0: r=process.Create(_L("T_PSC_DYNAMIC"),arg); sl@0: test(r==KErrNone); sl@0: TRequestStatus logon; sl@0: process.Logon(logon); sl@0: process.Resume(); sl@0: User::WaitForRequest(logon); sl@0: test(process.ExitType()==EExitKill); sl@0: r=logon.Int(); sl@0: CLOSE_AND_WAIT(process); sl@0: if(PlatSecEnforcement) sl@0: test(r==KErrPermissionDenied); sl@0: else sl@0: test(r==KErrNone); sl@0: sl@0: test.Next(_L("Check static linkage without required capabilities")); sl@0: r=process.Create(_L("T_PSC_STATIC"),_L("")); sl@0: if(PlatSecEnforcement) sl@0: test(r==KErrPermissionDenied); sl@0: else sl@0: { sl@0: test(r==KErrNone); sl@0: process.Kill(0); sl@0: CLOSE_AND_WAIT(process); sl@0: } sl@0: sl@0: test.End(); sl@0: } sl@0: sl@0: #include sl@0: IMPORT_C void dummyExport(); sl@0: sl@0: GLDEF_C TInt E32Main() sl@0: { sl@0: #ifdef STATIC_TEST_LINK sl@0: dummyExport(); // Use dummy export from staticly linked DLL sl@0: #endif sl@0: TBuf16<512> cmd; sl@0: User::CommandLine(cmd); sl@0: if(cmd.Length() && TChar(cmd[0]).IsDigit()) sl@0: { sl@0: TInt function = -1; sl@0: TInt arg1 = -1; sl@0: TInt arg2 = -1; sl@0: TLex lex(cmd); sl@0: sl@0: lex.Val(function); sl@0: lex.SkipSpace(); sl@0: lex.Val(arg1); sl@0: lex.SkipSpace(); sl@0: lex.Val(arg2); sl@0: return DoTestProcess(function,arg1,arg2); sl@0: } sl@0: sl@0: test.Title(); sl@0: sl@0: test.Start(_L("Starting test server")); sl@0: RTestProcess server; sl@0: TRequestStatus rendezvous; sl@0: TBuf<10> arg; sl@0: arg.Num((TInt)ETestProcessServer); sl@0: TInt r=server.RProcess::Create(KRomExe,arg); sl@0: test(r==KErrNone); sl@0: server.Rendezvous(rendezvous); sl@0: server.Resume(); sl@0: User::WaitForRequest(rendezvous); sl@0: test(rendezvous==KServerRendezvous); sl@0: sl@0: test.Next(_L("Openning server session")); sl@0: r = Session.Connect(); sl@0: RDebug::Print(_L("%d"),r); sl@0: test(r==KErrNone); sl@0: sl@0: test.Next(_L("Test PlatSecDisabledCaps")); sl@0: TestPlatSecDisabledCaps(); sl@0: sl@0: test.Next(_L("Test PlatSecEnforcement")); sl@0: TestPlatSecEnforcement(); sl@0: sl@0: test.Next(_L("Closing server session")); sl@0: Session.Send(CTestSession::EShutdown); sl@0: Session.Close(); sl@0: CLOSE_AND_WAIT(server); sl@0: sl@0: // Show results requiring manual inspection sl@0: _LIT(KSeperatorText,"----------------------------------------------------------------------------\n"); sl@0: test.Printf(_L("\n")); sl@0: test.Printf(_L("RESULTS (To be checked against expected values)\n")); sl@0: test.Printf(KSeperatorText); sl@0: test.Printf(_L("* PlatSecEnforcement is %S\n"),PlatSecEnforcement?&KOn:&KOff); sl@0: test.Printf(KSeperatorText); sl@0: TCapabilitySet disabled; sl@0: disabled.SetDisabled(); sl@0: TPtrC16 list(CapabilityList(disabled)); sl@0: test.Printf(_L("* Disabled Capabilites: %S\n"),&list); sl@0: test.Printf(KSeperatorText); sl@0: sl@0: // Wait for a while, or for a key press sl@0: test.Printf(_L("Waiting a short while for key press...\n")); sl@0: TRequestStatus keyStat; sl@0: test.Console()->Read(keyStat); sl@0: RTimer timer; sl@0: test(timer.CreateLocal()==KErrNone); sl@0: TRequestStatus timerStat; sl@0: timer.After(timerStat,20*1000000); sl@0: User::WaitForRequest(timerStat,keyStat); sl@0: TInt key = 0; sl@0: if(keyStat!=KRequestPending) sl@0: key = test.Console()->KeyCode(); sl@0: timer.Cancel(); sl@0: test.Console()->ReadCancel(); sl@0: User::WaitForAnyRequest(); sl@0: sl@0: test.End(); sl@0: return(0); sl@0: } sl@0: