os/kernelhwsrv/kerneltest/e32test/secure/t_platsecconfig.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32test\secure\t_platsecconfig.cpp
    15 // This test checks the correct functioning of the Platform Security configuration.
    16 // To use this test for verification of the features, perform the following steps
    17 // On the WINS Emulator
    18 // 1.  Run "T_PLATSECCONFIG.EXE"
    19 // Check that the results reported are:
    20 // PlatSecEnforcement is OFF
    21 // Disabled Capabilites: NONE
    22 // Check EPOCWIND.OUT and verify that it contains no diagnostic messages. (These will start with the text "*PlatSec* ")
    23 // 2.  Run "T_PLATSECCONFIG.EXE -mt_platsecconfig --"
    24 // Check that the results reported are:
    25 // PlatSecEnforcement is ON
    26 // Disabled Capabilites: CommDD MultimediaDD WriteDeviceData TrustedUI DiskAdmin AllFiles NetworkServices ReadUserData Location (These are all ODD numbered capabilities)
    27 // Check EPOCWIND.OUT and verify that it contains two lines starting with "*PlatSec* ERROR - Capability check failed"
    28 // On reference hardware
    29 // 3.  Build a Text Shell ROM contining the E32 tests. E.g.
    30 // cd \cedar\generic\base\e32\rombuild
    31 // rom -v=lubbock -t=e32test
    32 // Boot this ROM and run "T_PLATSECCONFIG.EXE"
    33 // Check that the results reported are:
    34 // PlatSecEnforcement is OFF
    35 // Disabled Capabilites: NONE
    36 // Check the output of the debug port and verify that it contains no diagnostic messages.
    37 // (These will start with the text "*PlatSec* ")
    38 // 4.  Build a Text Shell ROM using the T_PLATSECCONFIG.OBY file. E.g.
    39 // cd \cedar\generic\base\e32\rombuild
    40 // rom -v=lubbock -t=t_platsecconfig
    41 // Boot this ROM and run "T_PLATSECCONFIG.EXE"
    42 // Check that the results reported are:
    43 // PlatSecEnforcement is ON
    44 // Disabled Capabilites: CommDD MultimediaDD WriteDeviceData TrustedUI DiskAdmin AllFiles NetworkServices ReadUserData Location (These are all ODD numbered capabilities)
    45 // Check the output of the debug port and verify that it contains two lines with "*PlatSec* ERROR - Capability check failed"
    46 // To check ROMBUILD configuration
    47 // 5.  Build a Text Shell ROM using the T_PLATSECCONFIG_WARNIG.OBY file. E.g.
    48 // cd \cedar\generic\base\e32\rombuild
    49 // rom -v=lubbock -t=t_platsecconfig_warning
    50 // This should produce the following warning:
    51 // 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
    52 // 6.  Build a Text Shell ROM using the T_PLATSECCONFIG_ERROR.OBY file. E.g.
    53 // cd \cedar\generic\base\e32\rombuild
    54 // rom -v=lubbock -t=t_platsecconfig_error
    55 // This should produce the following error:
    56 // 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
    57 // 
    58 //
    59 
    60 /**
    61  @file
    62 */
    63 
    64 #define __INCLUDE_CAPABILITY_NAMES__
    65 
    66 #include <e32test.h>
    67 
    68 LOCAL_D RTest test(_L("T_PLATSECCONFIG"));
    69 
    70 enum TTestProcessFunctions
    71 	{
    72 	ETestProcessServer,
    73 	ETestProcessLoadLib,
    74 	};
    75 
    76 #include "testprocess.h"
    77 
    78 TInt StartServer();
    79 
    80 TInt DoTestProcess(TInt aTestNum,TInt aArg1,TInt aArg2)
    81 	{
    82 	(void)aArg1;
    83 	(void)aArg2;
    84 
    85 	switch(aTestNum)
    86 		{
    87 
    88 	case ETestProcessServer:
    89 		return StartServer();
    90 
    91 	case ETestProcessLoadLib:
    92 		{
    93 		RLibrary lib;
    94 		TInt r = lib.Load(_L("T_PSC_DLL"));
    95 		lib.Close();
    96 		return r;
    97 		}
    98 
    99 	default:
   100 		User::Panic(_L("T_PLATSECCONFIG"),1);
   101 		}
   102 
   103 	return KErrNone;
   104 	}
   105 
   106 
   107 
   108 //
   109 // RTestThread
   110 //
   111 
   112 class RTestThread : public RThread
   113 	{
   114 public:
   115 	void Create(TThreadFunction aFunction,TAny* aArg=0);
   116 	};
   117 
   118 void RTestThread::Create(TThreadFunction aFunction,TAny* aArg)
   119 	{
   120 	TInt r=RThread::Create(_L(""),aFunction,KDefaultStackSize,KDefaultStackSize,KDefaultStackSize,aArg);
   121 	test(r==KErrNone);
   122 	}
   123 
   124 
   125 //
   126 // CTestSession
   127 //
   128 
   129 class CTestSession : public CSession2
   130 	{
   131 public:
   132 	enum {EShutdown,EGetSecurityInfo};
   133 public:
   134 	CTestSession();
   135 	virtual void ServiceL(const RMessage2& aMessage);
   136 public:
   137 	};
   138 
   139 CTestSession::CTestSession()
   140 	: CSession2()
   141 	{}
   142 
   143 void CTestSession::ServiceL(const RMessage2& aMessage)
   144 	{
   145 	RMessagePtr2 m(aMessage);
   146 	switch (aMessage.Function())
   147 		{
   148 		case CTestSession::EGetSecurityInfo:
   149 			{
   150 			TSecurityInfo info;
   151 			info.Set(RProcess());
   152 			TInt r = aMessage.Write(0,TPtrC8((TUint8*)&info,sizeof(info)));
   153 			m.Complete(r);
   154 			}
   155 			break;
   156 
   157 		case CTestSession::EShutdown:
   158 			CActiveScheduler::Stop();
   159 			break;
   160 
   161 		default:
   162 			m.Complete(KErrNotSupported);
   163 			break;
   164 		}
   165 	}
   166 
   167 
   168 
   169 //
   170 // CTestServer
   171 //
   172 
   173 class CTestServer : public CServer2
   174 	{
   175 public:
   176 	CTestServer(TInt aPriority);
   177 	virtual CSession2* NewSessionL(const TVersion& aVersion,const RMessage2& aMessage) const;
   178 	};
   179 
   180 CTestServer::CTestServer(TInt aPriority)
   181 	: CServer2(aPriority)
   182 	{
   183 	}
   184 
   185 CSession2* CTestServer::NewSessionL(const TVersion& /*aVersion*/,const RMessage2& /*aMessage*/) const
   186 	{
   187 	return new (ELeave) CTestSession();
   188 	}
   189 
   190 
   191 
   192 //
   193 // CTestActiveScheduler
   194 //
   195 
   196 class CTestActiveScheduler : public CActiveScheduler
   197 	{
   198 public:
   199 	virtual void Error(TInt anError) const;
   200 	};
   201 
   202 void CTestActiveScheduler::Error(TInt anError) const
   203 	{
   204 	User::Panic(_L("TestServer Error"),anError);
   205 	}
   206 
   207 
   208 
   209 //
   210 // Server thread
   211 //
   212 
   213 _LIT(KServerName,"T_PLATSECCONFIG-server");
   214 const TInt KServerRendezvous = KRequestPending+1;
   215 
   216 void DoStartServer()
   217 	{
   218 	CTestActiveScheduler* activeScheduler = new (ELeave) CTestActiveScheduler;
   219 	CActiveScheduler::Install(activeScheduler);
   220 	CleanupStack::PushL(activeScheduler);
   221 
   222 	CTestServer* server = new (ELeave) CTestServer(0);
   223 	CleanupStack::PushL(server);
   224 
   225 	User::LeaveIfError(server->Start(KServerName));
   226 
   227 	RProcess::Rendezvous(KServerRendezvous);
   228 
   229 	CActiveScheduler::Start();
   230 
   231 	CleanupStack::PopAndDestroy(2);
   232 	}
   233 
   234 TInt StartServer()
   235 	{
   236 	CTrapCleanup* cleanupStack = CTrapCleanup::New();
   237 	if(!cleanupStack)
   238 		return KErrNoMemory;
   239 	TRAPD(leaveError,DoStartServer())
   240 	delete cleanupStack;
   241 	return leaveError;
   242 	}
   243 
   244 
   245 
   246 //
   247 // RTestSession
   248 //
   249 
   250 class RTestSession : public RSessionBase
   251 	{
   252 public:
   253 	inline TInt Connect()
   254 		{ return CreateSession(KServerName,TVersion());}
   255 	inline TInt Send(TInt aFunction)
   256 		{ return RSessionBase::SendReceive(aFunction); }
   257 	inline TInt Send(TInt aFunction,const TIpcArgs& aArgs)
   258 		{ return RSessionBase::SendReceive(aFunction,aArgs); }
   259 	inline void Send(TInt aFunction,TRequestStatus& aStatus)
   260 		{ RSessionBase::SendReceive(aFunction,aStatus); }
   261 	inline void Send(TInt aFunction,const TIpcArgs& aArgs,TRequestStatus& aStatus)
   262 		{ RSessionBase::SendReceive(aFunction,aArgs,aStatus); }
   263 	};
   264 
   265 
   266 
   267 RTestSession Session;
   268 
   269 
   270 
   271 void CheckCapabilitySetEqual(const TCapabilitySet& a1,const TCapabilitySet& a2)
   272 	{
   273 	TInt i;
   274 	for(i=0; i<ECapability_Limit; i++)
   275 		test((!a1.HasCapability((TCapability)i))==(!a2.HasCapability((TCapability)i)));
   276 	}
   277 
   278 TBuf8<1024> CapabilityNameBuffer;
   279 TBool PlatSecEnforcement=0;
   280 
   281 TPtrC16 CapabilityList(const TCapabilitySet& aCaps)
   282 	{
   283 	TCapabilitySet allCaps;
   284 	allCaps.SetAllSupported();
   285 	CapabilityNameBuffer.Zero();
   286 	TBool odd=ETrue;
   287 	TBool even=ETrue;
   288 	TInt i;
   289 	for(i=0; i<ECapability_Limit; i++)
   290 		{
   291 		if(!aCaps.HasCapability((TCapability)i))
   292 			{
   293 			if(allCaps.HasCapability((TCapability)i))
   294 				{
   295 				if(i&1)
   296 					odd = EFalse;
   297 				else
   298 					even = EFalse;
   299 				}
   300 			continue;
   301 			}
   302 		TUint8* ptr=(TUint8*)CapabilityNames[i];
   303 		TPtrC8 name(ptr,User::StringLength(ptr));
   304 		CapabilityNameBuffer.Append(name);
   305 		CapabilityNameBuffer.Append((TChar)' ');
   306 		}
   307 	if(!CapabilityNameBuffer.Length())
   308 		CapabilityNameBuffer.Append(_L8("NONE"));
   309 	if(even)
   310 		CapabilityNameBuffer.Append(_L8("(These are all EVEN numbered capabilities)"));
   311 	if(odd)
   312 		CapabilityNameBuffer.Append(_L8("(These are all ODD numbered capabilities)"));
   313 	return CapabilityNameBuffer.Expand();
   314 }
   315 
   316 void TestPlatSecDisabledCaps()
   317 	{
   318 	TSecurityInfo info;
   319 	TPckg<TSecurityInfo> infoPtr(info);
   320 
   321 	test.Start(_L("Get disabled capabilities set"));
   322 	TCapabilitySet disabled;
   323 	disabled.SetDisabled();
   324 	TPtrC16 list(CapabilityList(disabled));
   325 	test.Printf(_L("  %S\n"),&list);
   326 
   327 	test.Next(_L("Get capabilites from this EXE"));
   328 	Mem::FillZ(&info,sizeof(info));
   329 	info.SetToCurrentInfo();
   330 
   331 	test.Next(_L("Check capabilities are same as disabled set"));
   332 	CheckCapabilitySetEqual(info.iCaps,disabled);
   333 
   334 	test.Next(_L("Get capabilites from other EXE"));
   335 	Mem::FillZ(&info,sizeof(info));
   336 	TInt r = Session.Send(CTestSession::EGetSecurityInfo,TIpcArgs(&infoPtr));
   337 	test(r==KErrNone);
   338 
   339 	test.Next(_L("Check capabilities are same as disabled set"));
   340 	CheckCapabilitySetEqual(info.iCaps,disabled);
   341 
   342 	test.Next(_L("Test PlatSec::IsCapabilityEnforced is consistant with our findings"));
   343 	TCapabilitySet notEnforced;
   344 	notEnforced.SetEmpty();
   345 	for(TInt i=0; i<ECapability_HardLimit; i++)
   346 		if(!PlatSec::IsCapabilityEnforced((TCapability)i))
   347 			notEnforced.AddCapability((TCapability)i);
   348 	if(!PlatSec::ConfigSetting(PlatSec::EPlatSecEnforcement))
   349 		disabled.SetAllSupported();
   350 	CheckCapabilitySetEqual(notEnforced,disabled);
   351 
   352 	test.End();
   353 	}
   354 
   355 _LIT(KRomExe,"T_PLATSECCONFIG2.EXE");
   356 _LIT(KOn,"ON");
   357 _LIT(KOff,"OFF");
   358 
   359 void TestPlatSecEnforcement()
   360 	{
   361 	RProcess process;
   362 	TInt r;
   363 
   364 	test.Start(_L("Getting PlatSecEnforcement setting"));
   365 	PlatSecEnforcement = PlatSec::ConfigSetting(PlatSec::EPlatSecEnforcement);
   366 	test.Printf(_L("  PlatSecEnforcement setting returns %S\n"),PlatSecEnforcement?&KOn:&KOff);
   367 
   368 	test.Next(_L("Check dynamic linkage without required capabilities"));
   369 	TBuf<10> arg;
   370 	arg.Num((TInt)ETestProcessLoadLib);
   371 	r=process.Create(_L("T_PSC_DYNAMIC"),arg);
   372 	test(r==KErrNone);
   373 	TRequestStatus logon;
   374 	process.Logon(logon);
   375 	process.Resume();
   376 	User::WaitForRequest(logon);
   377 	test(process.ExitType()==EExitKill);
   378 	r=logon.Int();
   379 	CLOSE_AND_WAIT(process);
   380 	if(PlatSecEnforcement)
   381 		test(r==KErrPermissionDenied);
   382 	else
   383 		test(r==KErrNone);
   384 
   385 	test.Next(_L("Check static linkage without required capabilities"));
   386 	r=process.Create(_L("T_PSC_STATIC"),_L(""));
   387 	if(PlatSecEnforcement)
   388 		test(r==KErrPermissionDenied);
   389 	else
   390 		{
   391 		test(r==KErrNone);
   392 		process.Kill(0);
   393 		CLOSE_AND_WAIT(process);
   394 		}
   395 
   396 	test.End();
   397 	}
   398 
   399 #include <e32svr.h>
   400 IMPORT_C void dummyExport();
   401 
   402 GLDEF_C TInt E32Main()
   403     {
   404 #ifdef STATIC_TEST_LINK
   405 	dummyExport(); // Use dummy export from staticly linked DLL
   406 #endif
   407 	TBuf16<512> cmd;
   408 	User::CommandLine(cmd);
   409 	if(cmd.Length() && TChar(cmd[0]).IsDigit())
   410 		{
   411 		TInt function = -1;
   412 		TInt arg1 = -1;
   413 		TInt arg2 = -1;
   414 		TLex lex(cmd);
   415 
   416 		lex.Val(function);
   417 		lex.SkipSpace();
   418 		lex.Val(arg1);
   419 		lex.SkipSpace();
   420 		lex.Val(arg2);
   421 		return DoTestProcess(function,arg1,arg2);
   422 		}
   423 
   424 	test.Title();
   425 
   426 	test.Start(_L("Starting test server"));
   427 	RTestProcess server;
   428 	TRequestStatus rendezvous;
   429 	TBuf<10> arg;
   430 	arg.Num((TInt)ETestProcessServer);
   431 	TInt r=server.RProcess::Create(KRomExe,arg);
   432 	test(r==KErrNone);
   433 	server.Rendezvous(rendezvous);
   434 	server.Resume();
   435 	User::WaitForRequest(rendezvous);
   436 	test(rendezvous==KServerRendezvous);
   437 
   438 	test.Next(_L("Openning server session"));
   439 	r = Session.Connect();
   440 	RDebug::Print(_L("%d"),r);
   441 	test(r==KErrNone);
   442 
   443 	test.Next(_L("Test PlatSecDisabledCaps"));
   444 	TestPlatSecDisabledCaps();
   445 
   446 	test.Next(_L("Test PlatSecEnforcement"));
   447 	TestPlatSecEnforcement();
   448 
   449 	test.Next(_L("Closing server session"));
   450 	Session.Send(CTestSession::EShutdown);
   451 	Session.Close();
   452 	CLOSE_AND_WAIT(server);
   453 
   454 	// Show results requiring manual inspection
   455 	_LIT(KSeperatorText,"----------------------------------------------------------------------------\n"); 
   456 	test.Printf(_L("\n"));
   457 	test.Printf(_L("RESULTS (To be checked against expected values)\n")); 
   458 	test.Printf(KSeperatorText);
   459 	test.Printf(_L("*  PlatSecEnforcement is %S\n"),PlatSecEnforcement?&KOn:&KOff);
   460 	test.Printf(KSeperatorText);
   461 	TCapabilitySet disabled;
   462 	disabled.SetDisabled();
   463 	TPtrC16 list(CapabilityList(disabled));
   464 	test.Printf(_L("*  Disabled Capabilites: %S\n"),&list);
   465 	test.Printf(KSeperatorText);
   466 
   467 	// Wait for a while, or for a key press
   468 	test.Printf(_L("Waiting a short while for key press...\n"));
   469 	TRequestStatus keyStat;
   470 	test.Console()->Read(keyStat);
   471 	RTimer timer;
   472 	test(timer.CreateLocal()==KErrNone);
   473 	TRequestStatus timerStat;
   474 	timer.After(timerStat,20*1000000);
   475 	User::WaitForRequest(timerStat,keyStat);
   476 	TInt key = 0;
   477 	if(keyStat!=KRequestPending)
   478 		key = test.Console()->KeyCode();
   479 	timer.Cancel();
   480 	test.Console()->ReadCancel();
   481 	User::WaitForAnyRequest();
   482 
   483 	test.End();
   484 	return(0);
   485     }
   486