cryptomgmtlibs/securitytestfw/test/testhandler2/t_policy.cpp
changeset 0 2c201484c85f
child 8 35751d3474b7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cryptomgmtlibs/securitytestfw/test/testhandler2/t_policy.cpp	Wed Jul 08 11:25:26 2009 +0100
@@ -0,0 +1,541 @@
+/*
+* Copyright (c) 2004-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: 
+*
+*/
+
+
+#include "t_policy.h"
+#include "t_input.h"
+#include "t_output.h"
+#include "t_testhandler.h"
+#include "utf.h"
+
+#include <s32file.h>
+
+// run failure tests first
+
+_LIT8(KTestExeStart, "<testexe>");
+_LIT8(KExcludedCapsStart, "<excludedcapabilities>");
+_LIT8(KPolicyStart, "<policy>");
+_LIT8(KPreActionsStart, "<preactions>");
+_LIT8(KPassAcionStart, "<passactions>");
+_LIT8(KFailAcionStart, "<failactions>");
+_LIT8(KPostActionsStart, "<postactions>");
+_LIT8(KSecureIdStart, "<secureid>");
+_LIT8(KSecureIdEnd, "</secureid>");
+_LIT8(KVendorIdStart, "<vendorid>");
+_LIT8(KVendorIdEnd, "</vendorid>");
+
+_LIT(KFormat,"Action Name : %S \n");
+_LIT(KSetCapExe, "setcap");
+_LIT(KSetCapExe2, "setcap : ");
+//NOTE :If the below literal is uncommented , remove the c:\hardcoded reference
+// and replace with RFs::GetSystemDrive().
+//_LIT(KTestExeTmpPath, "c:\\sys\\bin\\policytest_exe.exe");
+_LIT(KPassScriptPath, "\\policytest_script_pass.txt");
+_LIT(KFailScriptPath, "\\policytest_script_fail.txt");
+_LIT(KLogTmpPath, "\\policytest_log.txt");
+_LIT(KTestPath, "policytest_");
+_LIT(KFailTestRunning, "Fail Test Script Running");
+_LIT(KPassTestRunning, "Pass Test Script Running");
+
+
+const TUint KCapabilityAll = 0xffffffff;
+
+CPolicyTest* CPolicyTest::NewL(CConsoleBase& aConsole, 
+							   Output& aOut,
+							   const TTestActionSpec& aTestActionSpec)
+	{
+	CPolicyTest* self = CPolicyTest::NewLC(aConsole, aOut, aTestActionSpec);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CPolicyTest* CPolicyTest::NewLC(CConsoleBase& aConsole, 
+								Output& aOut,
+								const TTestActionSpec& aTestActionSpec)
+	{
+	CPolicyTest* self = new(ELeave) CPolicyTest(aConsole, aOut);
+	CleanupStack::PushL(self);
+	self->ConstructL(aTestActionSpec);
+	return self;
+	}
+
+CPolicyTest::CPolicyTest(CConsoleBase& aConsole, 
+						 Output& aOut)
+    : CTestAction(aConsole, aOut)
+	{
+	}
+
+void CPolicyTest::ConstructL(const TTestActionSpec& aTestActionSpec)
+	{
+	CTestAction::ConstructL(aTestActionSpec);
+	iExpectedResult = KErrNone;
+
+	User::LeaveIfError(iFs.Connect());
+
+	RProcess thisProcess;
+	User::LeaveIfError(thisProcess.Open(thisProcess.Id()));
+	iProcessSecureId = thisProcess.SecureId();
+	iProcessVendorId = thisProcess.VendorId();
+	thisProcess.Close();
+	
+	SetTestExeL(Input::ParseElement(aTestActionSpec.iActionBody, KTestExeStart));
+	Input::ParseCapabilitySetL(Input::ParseElement(aTestActionSpec.iActionBody, KExcludedCapsStart), iExcludedCaps);
+	SetPolicyL(Input::ParseElement(aTestActionSpec.iActionBody, KPolicyStart));
+	iPreActions = Input::ParseElement(aTestActionSpec.iActionBody, KPreActionsStart).AllocL();
+	SetTestActionL(Input::ParseElement(aTestActionSpec.iActionBody, KPassAcionStart),
+				   Input::ParseElement(aTestActionSpec.iActionBody, KFailAcionStart));
+	iPostActions = Input::ParseElement(aTestActionSpec.iActionBody, KPostActionsStart).AllocL();
+	}
+
+CPolicyTest::~CPolicyTest()
+	{
+	iFs.Close();
+	delete iTestExe;
+	iCapabilities.Close();
+	delete iPreActions;
+	delete iPassAction;
+	delete iFailAction;
+	delete iPostActions;
+	iProcess.Close();
+	}
+
+void CPolicyTest::BadUsageL(const TDesC& aMessage)
+	{
+	iOut.writeString(_L("Error in script action testpolicy"));
+	iOut.writeNewLine();
+	iOut.writeString(aMessage);
+	iOut.writeNewLine();
+	User::Leave(KErrArgument);
+	}
+
+void CPolicyTest::SetTestExeL(const TDesC8& aPath)
+	{
+	if (aPath == KNullDesC8)
+		{
+		BadUsageL(_L("testexe not specified"));
+		}
+	
+	iTestExe = HBufC::NewMaxL(aPath.Length());
+	TPtr ptr = iTestExe->Des();
+	ptr.Copy(aPath);
+	}
+
+void CPolicyTest::SetPolicyL(const TDesC8& aSpec)
+	{
+	iSecureId = Input::ParseIntElement(aSpec, KSecureIdStart, KSecureIdEnd);
+	iVendorId = Input::ParseIntElement(aSpec, KVendorIdStart, KVendorIdEnd);
+
+	TCapabilitySet capSet;
+	Input::ParseCapabilitySetL(aSpec, capSet);
+
+	// Extract capabilities into array
+	for (TInt i = 0 ; i < ECapability_Limit ; ++i)
+		{
+		TCapability c = static_cast<TCapability>(i);
+		if (capSet.HasCapability(c))
+			{
+			User::LeaveIfError(iCapabilities.Append(c));
+			}
+		}	
+	}
+
+void CPolicyTest::SetTestActionL(const TDesC8& aPassAction, const TDesC8& aFailAction)
+	{
+	if (aPassAction == KNullDesC8)
+		{
+		BadUsageL(_L("passactions not specified"));
+		}
+
+	iPassAction = aPassAction.AllocL();
+
+	if (aFailAction == KNullDesC8)
+		{
+		BadUsageL(_L("failactions not specified"));
+		}
+
+	iFailAction = aFailAction.AllocL();
+}
+
+void CPolicyTest::PerformAction(TRequestStatus& aStatus)
+	{
+	if (aStatus < 0)
+		{
+		iState = EFinished;
+		}
+
+	switch (iState)
+		{
+		case EInit:
+			{
+			TDriveUnit sysDrive (RFs::GetSystemDrive());
+			TDriveName sysDriveName (sysDrive.Name());
+				
+			TBuf<128> scriptFile (sysDriveName);
+			scriptFile.Append(KPassScriptPath);
+			WriteScriptFileL(scriptFile, *iPassAction);	
+			
+			scriptFile.Copy(sysDriveName);
+			scriptFile.Append(KFailScriptPath);
+			WriteScriptFileL(scriptFile, *iFailAction);
+			}
+			// fall through
+		
+		case ESetupTest:
+			GetNextTest();
+			if (iTestState == ETestFinished)
+				{
+				iState = EFinished;
+				TRequestStatus* status = &aStatus;
+				User::RequestComplete(status, KErrNone);
+				}
+			else
+				{
+				SetupTestL(aStatus);
+				iState = ERunTest;
+				}
+			break;
+
+		case ERunTest:
+			CheckProcessTermintationL();
+			RunTestL(aStatus);
+			iState = EProcessResults;
+			break;
+			
+		case EProcessResults:
+			CheckProcessTermintationL();
+			ProcessResultsL(aStatus);
+			iState = ESetupTest;
+			break;
+
+		case EFinished:
+			iActionState = EPostrequisite;				
+			TRequestStatus* status = &aStatus;
+			User::RequestComplete(status, aStatus.Int());
+			break;
+		}
+	}
+
+void CPolicyTest::StartProcessL(const TDesC& aExe, const TDesC& aCommandLine, TRequestStatus& aStatus)
+	{
+	iOut.writeString(_L("Starting child process: "));
+	iOut.writeString(aExe);
+	iOut.writeString(_L(" "));
+	iOut.writeString(aCommandLine);
+	iOut.writeNewLine();
+	
+	User::LeaveIfError(iProcess.Create(aExe, aCommandLine));
+	iProcess.Logon(aStatus);
+	iProcess.Resume();
+	}
+
+void CPolicyTest::CheckProcessTermintationL()
+	{
+	if (iProcess.ExitType() == EExitPanic)
+		{
+		iOut.writeString(_L("Child process panicked: "));
+		iOut.writeString(iProcess.ExitCategory());
+		iOut.writeString(_L(" "));
+		iOut.writeNum(iProcess.ExitReason());
+		iOut.writeNewLine();
+		User::Leave(KErrGeneral);
+		}
+	ASSERT(iProcess.ExitType() == EExitKill);
+	iProcess.Close();
+	}
+
+void CPolicyTest::GetNextTest()
+	{
+	// Step through capabilities to be tested
+	if (iTestState == ETestFailCap)
+		{
+		++iCapIndex;
+		if (iCapIndex < iCapabilities.Count())
+			return;
+		}
+	
+	// Step through possible tests until we hit a vaild test
+	do
+		{
+		iTestState = static_cast<TTestState>(iTestState + 1);
+		}
+	while (!((iTestState == ETestFailSID && iSecureId) ||
+			 (iTestState == ETestFailVID && iVendorId) ||
+			 (iTestState == ETestFailCap && iCapabilities.Count()) ||
+			 (iTestState == ETestPass) ||
+			 (iTestState == ETestFinished)));
+	}
+
+void CPolicyTest::SetupTestL(TRequestStatus& aStatus)
+	{
+	switch (iTestState)
+		{
+		case ETestFailSID:
+			{
+			TInt wrongSecureId = iSecureId + 1;
+			iOut.write(_L("Failure test: Wrong SID (%08x):\n\n"), wrongSecureId);			
+			SetTestSecurityInfoL(wrongSecureId, iVendorId, KCapabilityAll, aStatus);
+			}
+			break;
+
+		case ETestFailVID:
+			{
+			TInt wrongVendorId = iVendorId + 1;
+			iOut.write(_L("Failure test: Wrong VID (%08x):\n\n"), wrongVendorId);
+			SetTestSecurityInfoL(iSecureId, wrongVendorId, KCapabilityAll, aStatus);
+			}
+			break;
+
+		case ETestFailCap:
+			{
+			TCapability missingCap = iCapabilities[iCapIndex];
+			
+			iOut.writeString(_L("Failure test: Missing capability ("));
+			iOut.writeCapabilityL(missingCap);
+			iOut.writeString(_L("):\n\n"));
+
+			TUint capSet = ~ (1 << missingCap);			
+			SetTestSecurityInfoL(iSecureId, iVendorId, capSet, aStatus);
+			}
+			break;
+
+		case ETestPass:
+			{
+			iOut.write(_L("Pass test:\n\n"));			
+
+			TUint capSet = 0;
+			for (TInt i = 0 ; i < iCapabilities.Count() ; ++i)
+				{
+				capSet |= 1 << iCapabilities[i];
+				}
+			
+			SetTestSecurityInfoL(iSecureId, iVendorId, capSet, aStatus);
+			}
+			break;
+
+		default:
+			User::Invariant();
+		}
+	}
+
+void CPolicyTest::SetTestSecurityInfoL(TInt aSecureId, TInt aVendorId, TUint aCapSet, TRequestStatus& aStatus)
+	{
+	// Remove excluded capabilities
+	for (TInt i = 0 ; i < ECapability_Limit ; ++i)
+		{
+		if (iExcludedCaps.HasCapability(static_cast<TCapability>(i)))
+			{
+			aCapSet &= ~ (1 << i);
+			}
+		}
+	
+	TBuf<128> commandLine;
+	commandLine.AppendFormat(_L("%S %08x "), iTestExe, aCapSet);
+	if (aSecureId)
+		{
+		commandLine.AppendFormat(_L("-SID %08x "), aSecureId);
+		}
+	if (aVendorId)
+		{
+		commandLine.AppendFormat(_L("-VID %08x "), aVendorId);
+		}
+   // commandLine.Append(KTestExeTmpPath);
+    iTestExeTmpNewPath = KTestPath;
+	iTestExeTmpNewPath.Append(*iTestExe);
+	commandLine.Append(iTestExeTmpNewPath);
+    
+    TBuf<128> isetcapTmpNewPath1; //stores the value of commandline
+    TBuf<128> isetcapTmpNewPath;  //stores the value of KsetCapexe2
+	isetcapTmpNewPath = KSetCapExe2;
+	isetcapTmpNewPath1= commandLine;
+	isetcapTmpNewPath.Append(isetcapTmpNewPath1);
+	RDebug::RawPrint(isetcapTmpNewPath);
+	StartProcessL(KSetCapExe, commandLine, aStatus);
+	
+	}
+
+void CPolicyTest::WriteScriptFileL(const TDesC& aPath, const TDesC8& aAction)
+	{	
+	iFs.Delete(aPath); // ignore errors
+	
+	RFile file;
+	User::LeaveIfError(file.Create(iFs, aPath, EFileShareExclusive | EFileWrite));
+	CleanupClosePushL(file);
+	
+	User::LeaveIfError(file.Write(*iPreActions));
+	User::LeaveIfError(file.Write(aAction));	
+	User::LeaveIfError(file.Write(*iPostActions));
+	
+	CleanupStack::PopAndDestroy(&file);
+	}
+
+void CPolicyTest::RunTestL(TRequestStatus& aStatus)
+	{
+	  
+	HBufC* hptr16; 
+	hptr16 = CnvUtfConverter::ConvertToUnicodeFromUtf8L(*iNameInfo);
+	RDebug::Print(KFormat,hptr16);
+	delete hptr16;
+	
+	TDriveUnit sysDrive (RFs::GetSystemDrive());
+	TDriveName sysDriveName (sysDrive.Name());
+	
+	TBuf<128> passScriptFile (sysDriveName);
+	passScriptFile.Append(KPassScriptPath);
+	
+	TBuf<128> failScriptFile (sysDriveName);
+	failScriptFile.Append(KFailScriptPath);
+			
+	TPtrC script = (iTestState == ETestPass) ? passScriptFile : failScriptFile;
+	(iTestState == ETestPass) ? RDebug::RawPrint(KPassTestRunning) : RDebug::RawPrint(KFailTestRunning);
+  	
+	
+	TBuf<128> logTmpFile (sysDriveName);
+	logTmpFile.Append(KLogTmpPath);
+	iFs.Delete(logTmpFile); // ignore errors
+	
+	TBuf<128> commandLine;
+	commandLine.AppendFormat(_L("%S %S"), &script, &logTmpFile);	
+	
+	StartProcessL(iTestExeTmpNewPath, commandLine, aStatus);
+	}
+
+void CPolicyTest::ProcessResultsL(TRequestStatus& aStatus)
+	{
+	_LIT8(KSummaryLine, " tests failed out of ");
+	_LIT8(KNewLine, "\r\n");
+
+	TInt failCount = KErrNotFound, runCount;
+	
+	// Read entire log file into memory to process
+	RFile file;
+	TDriveUnit sysDrive (RFs::GetSystemDrive());
+	TBuf<128> logTmpFile (sysDrive.Name());
+	logTmpFile.Append(KLogTmpPath);
+	User::LeaveIfError(file.Open(iFs, logTmpFile, EFileShareReadersOnly | EFileRead));
+	CleanupClosePushL(file);
+
+	TInt size;
+	User::LeaveIfError(file.Size(size));
+	HBufC8* buffer = HBufC8::NewLC(size);
+	TPtr8 ptr = buffer->Des();
+
+	User::LeaveIfError(file.Read(ptr));
+
+	iOut.writeString(_L("Child test output:\n"));
+
+	TInt pos = 0;
+	while (pos < size)
+		{
+		TInt nextNewline = buffer->Mid(pos).Find(KNewLine);
+
+		// Split buffer into lines
+		TPtrC8 line;
+		if (nextNewline == KErrNotFound)
+			{
+			line.Set(buffer->Mid(pos));
+			}
+		else
+			{
+			line.Set(buffer->Mid(pos, nextNewline + KNewLine().Length()));
+			}
+		pos += line.Length();
+
+		// Search for summary line
+		TInt pos2 = line.Find(KSummaryLine);
+		if (pos2 != KErrNotFound)
+			{
+			// Parse the summary line to work out if the test passed
+			TLex8 lex1(line.Left(pos2));
+			TInt err1 = lex1.Val(failCount);
+			TLex8 lex2(line.Mid(pos2 + KSummaryLine().Length()));
+			TInt err2 = lex2.Val(runCount);
+
+			if (err1 != KErrNone || err2 != KErrNone)
+				{
+				iOut.writeString(_L("Failed to parse summary line\n"));
+				User::LeaveIfError(err1);
+				User::LeaveIfError(err2);
+				}
+			}
+		else
+			{
+			// Don't print the summary line as this will confuse whatever parsed
+			// the main log
+			iOut.writeString(_L("> "));
+			iOut.writeString(line);
+			}		
+		}
+	
+	if (failCount == KErrNotFound)
+		{
+		iOut.writeString(_L("Couldn't find summary line in test output\n"));
+		User::Leave(KErrNotFound);
+		}
+	iFailCount += failCount;
+
+	// Print results in different format
+	iOut.write(_L("Tests run: %d\n"), runCount);
+	iOut.write(_L("Tests failed: %d\n"), failCount);
+	iOut.writeNewLine();
+	
+	CleanupStack::PopAndDestroy(2, &file);
+
+	TRequestStatus* status = &aStatus;
+	User::RequestComplete(status, KErrNone);
+	}
+
+void CPolicyTest::PerformCancel()
+	{
+	// not implemented - need to pass original status object to LogonCancel
+	User::Invariant(); 
+	/*
+	switch (iState)
+		{
+		case ESetCapsPass:
+		case ERunTest:
+			iProcess.LogonCancel();
+			iProcess.Kill(KErrCancel);
+			iProcess.Close();
+			break;
+		}
+	*/
+	}
+
+void CPolicyTest::Reset()
+	{
+	iProcess.Close();
+	iState = ESetupTest;
+	iTestState = ETestNone;
+	iCapIndex = -1;
+	iFailCount = 0;
+	}
+
+void CPolicyTest::DoReportAction()
+	{
+	iOut.writeString(_L("Running policy tests...\n\n"));
+	}
+
+void CPolicyTest::DoCheckResult(TInt aError)
+	{
+	if (aError == KErrNone && iFailCount > 0)
+		{
+		iOut.write(_L("%d tests failed\n"), iFailCount);
+		aError = KErrGeneral;
+		}
+	
+	iResult = (aError == iExpectedResult);
+	}