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