os/security/cryptomgmtlibs/securitytestfw/test/captestframework/captestframeworkstep.cpp
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/security/cryptomgmtlibs/securitytestfw/test/captestframework/captestframeworkstep.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,342 @@
1.4 +/*
1.5 +* Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
1.6 +* All rights reserved.
1.7 +* This component and the accompanying materials are made available
1.8 +* under the terms of the License "Eclipse Public License v1.0"
1.9 +* which accompanies this distribution, and is available
1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.11 +*
1.12 +* Initial Contributors:
1.13 +* Nokia Corporation - initial contribution.
1.14 +*
1.15 +* Contributors:
1.16 +*
1.17 +* Description:
1.18 +*
1.19 +*/
1.20 +
1.21 +
1.22 +
1.23 +
1.24 +/**
1.25 + @file
1.26 +*/
1.27 +#define __INCLUDE_CAPABILITY_NAMES__
1.28 +#include <e32capability.h>
1.29 +
1.30 +#include "captestframeworkstep.h"
1.31 +#include "captestframework.h"
1.32 +
1.33 +#include <test/testexecutelog.h>
1.34 +#include <s32file.h>
1.35 +#include <f32file.h>
1.36 +
1.37 +
1.38 +CCapTestFrameworkStep::CCapTestFrameworkStep(TThoroughness aThoroughness)
1.39 + : iThoroughness(aThoroughness)
1.40 + {
1.41 + }
1.42 +
1.43 +CCapTestFrameworkStep::~CCapTestFrameworkStep()
1.44 + {
1.45 + iLibrary.Close();
1.46 + iFs.Close();
1.47 + }
1.48 +
1.49 +TVerdict CCapTestFrameworkStep::doTestStepPreambleL()
1.50 + {
1.51 + User::LeaveIfError(iFs.Connect());
1.52 + User::LeaveIfError(iFs.ShareProtected());
1.53 +
1.54 + if (EFalse==GetStringFromConfig(ConfigSection(), _L("DllName"), iDllName))
1.55 + {
1.56 + return EFail;
1.57 + }
1.58 +
1.59 + GetBoolFromConfig(ConfigSection(), _L("OmitTCBCapInComplementSet"), iOmitTCBCapInComplementSet);
1.60 +
1.61 + SetupFactoryL();
1.62 + return EPass;
1.63 + }
1.64 +
1.65 +TVerdict CCapTestFrameworkStep::doTestStepL()
1.66 + {
1.67 + for (iCurrentTest=0; iCurrentTest < iFactory->NumberOfTests(); ++iCurrentTest)
1.68 + {
1.69 + INFO_PRINTF1(_L(""));
1.70 + INFO_PRINTF2(_L("Running %S"), &iFactory->Test(iCurrentTest)->Name());
1.71 + INFO_PRINTF1(_L("Assumed to require:"));
1.72 + INFO_PRINTF2(_L("\tSid: %x"), iFactory->Test(iCurrentTest)->SidRequired());
1.73 + INFO_PRINTF2(_L("\tVid: %x"), iFactory->Test(iCurrentTest)->VidRequired());
1.74 + PrintCapabilitySet(iFactory->Test(iCurrentTest)->CapabilitiesRequired(), _L("\tCapabilities: "));
1.75 + RunTestStepL(iFactory->Test(iCurrentTest));
1.76 + }
1.77 +
1.78 + return EPass;
1.79 + }
1.80 +
1.81 +void CCapTestFrameworkStep::RunTestStepL(MCapabilityTest* aTest)
1.82 + {
1.83 + // figure out capabilities required
1.84 + TCapabilitySet capsRequired=aTest->CapabilitiesRequired();
1.85 + TUid sidRequired=aTest->SidRequired();
1.86 + TUid vidRequired=aTest->VidRequired();
1.87 +
1.88 + RArray<TTestEnvironment> capTestEnvs;
1.89 + CleanupClosePushL(capTestEnvs);
1.90 +
1.91 + GenerateEnvironmentsL(capsRequired, sidRequired, vidRequired, capTestEnvs);
1.92 +
1.93 + // for all cap sets needed
1.94 + for (TInt i=0; i < capTestEnvs.Count(); ++i)
1.95 + {
1.96 + INFO_PRINTF1(_L("With:"));
1.97 + INFO_PRINTF2(_L("\tSid: %x"), capTestEnvs[i].iSid);
1.98 + INFO_PRINTF2(_L("\tVid: %x"), capTestEnvs[i].iVid);
1.99 + PrintCapabilitySet(capTestEnvs[i].iCaps, _L("\tCapabilities: "));
1.100 +
1.101 + // Set the capabilities of the helper
1.102 + SetupHelperL(capTestEnvs[i]);
1.103 +
1.104 + // run the helper and check results
1.105 + RunHelperL(iCurrentTest, capTestEnvs[i].iExpectPass);
1.106 + }
1.107 +
1.108 + CleanupStack::PopAndDestroy(&capTestEnvs);
1.109 + }
1.110 +
1.111 +void CCapTestFrameworkStep::RunHelperL(TInt aTestNumber, TBool aShouldPass)
1.112 + {
1.113 + RProcess p;
1.114 +
1.115 + //Launching process
1.116 + User::LeaveIfError(p.Create(_L("tempcaptestframeworkhelper.exe"), KNullDesC));
1.117 +
1.118 + p.SetParameter(KDllNameTransferSlot, iDllName);
1.119 + p.SetParameter(KShouldPassTransferSlot, aShouldPass);
1.120 + p.SetParameter(KTestNumberTransferSlot, aTestNumber);
1.121 +
1.122 + _LIT(KLogFileName , "\\captestframework.txt");
1.123 + TDriveUnit sysDrive(RFs::GetSystemDrive());
1.124 +
1.125 + TBuf<128> logFileNameOnSysDrive = sysDrive.Name();
1.126 + logFileNameOnSysDrive.Append(KLogFileName);
1.127 + p.SetParameter(KLogFileNameTransferSlot, logFileNameOnSysDrive);
1.128 +
1.129 + // Wait for the test to finish
1.130 + TRequestStatus s;
1.131 + TRequestStatus& a=s;
1.132 + p.Logon(a);
1.133 + p.Resume();
1.134 + User::WaitForRequest(a);
1.135 + p.Close();
1.136 +
1.137 + // Extract the info from the logfile
1.138 + RFileReadStream logFile;
1.139 + logFile.Open(iFs, logFileNameOnSysDrive, 0);
1.140 + CleanupClosePushL(logFile);
1.141 +
1.142 + while (ETrue)
1.143 + {
1.144 + TInt32 pass=logFile.ReadInt32L();
1.145 + if (pass==ETestsEnded)
1.146 + {
1.147 + break; // end of file
1.148 + }
1.149 + else if (pass==EFileEnd)
1.150 + {
1.151 + // reached end of file marker, with no success
1.152 + SetTestStepResult(EFail);
1.153 + break;
1.154 + }
1.155 + else if (pass==ETestFailed)
1.156 + {
1.157 + HBufC* text=HBufC::NewL(logFile, KMaxTInt);
1.158 + ERR_PRINTF2(_L("%S"), text);
1.159 + delete text;
1.160 + }
1.161 + else if (pass==ETestPassed)
1.162 + {
1.163 + HBufC* text=HBufC::NewL(logFile, KMaxTInt);
1.164 + INFO_PRINTF2(_L("%S"), text);
1.165 + delete text;
1.166 + }
1.167 + }
1.168 +
1.169 + CleanupStack::PopAndDestroy(&logFile);
1.170 + }
1.171 +
1.172 +void CCapTestFrameworkStep::SetupHelperL(const TTestEnvironment& aEnvironment)
1.173 + {
1.174 + RProcess p;
1.175 +// SETCAP source_exe capability [-SID secureId] [-VID vendorId] [destination_path]
1.176 + _LIT(KArgsFormat, "captestframeworkhelper.exe %X -SID %X -VID %X tempcaptestframeworkhelper.exe");
1.177 +
1.178 +// The 'capability' command line argument is the hexadecimal value of the
1.179 +// capabilities when they are represented as a bit-field. E.g. the 3 capabilities
1.180 +// LocalServices, ReadUserData and WriteUserData would together have a value of:
1.181 +//
1.182 +// (1<<ECapabilityLocalServices) | (<<ECapabilityReadUserData) | (1<<ECapabilityWriteUserData)
1.183 +//
1.184 +// Which in hexadecimal is '1c000'
1.185 +
1.186 + const TCapabilitySet& aCapSet=aEnvironment.iCaps;
1.187 + TInt caps=0;
1.188 + for (TInt c = 0; c < ECapability_Limit; ++c)
1.189 + {
1.190 + if (aCapSet.HasCapability(TCapability(c)))
1.191 + {
1.192 + caps+=(1<<c);
1.193 + }
1.194 + }
1.195 +
1.196 + TBuf<512> cmdLine;
1.197 + cmdLine.Format(KArgsFormat, caps, aEnvironment.iSid, aEnvironment.iVid);
1.198 +
1.199 + User::LeaveIfError(p.Create(_L("setcap.exe"), cmdLine));
1.200 +
1.201 + // Wait for setcap to finish
1.202 + TRequestStatus s;
1.203 + TRequestStatus& rs=s;
1.204 + p.Logon(rs);
1.205 +
1.206 + p.Resume();
1.207 + User::WaitForRequest(rs);
1.208 + p.Close();
1.209 + }
1.210 +
1.211 +void CCapTestFrameworkStep::PrintCapabilitySet(const TCapabilitySet& aCapSet, const TDesC& aExtra)
1.212 + {
1.213 + TBuf<512> string;
1.214 + string.AppendFormat(_L("%S"), &aExtra);
1.215 + for (TInt c = 0; c < ECapability_Limit; ++c)
1.216 + {
1.217 + if (aCapSet.HasCapability(TCapability(c)))
1.218 + {
1.219 + string.Append(' ');
1.220 + const char *p=CapabilityNames[c];
1.221 +
1.222 + while(*p)
1.223 + {
1.224 + string.Append(*p++);
1.225 + }
1.226 + }
1.227 + }
1.228 + if (string.Length()==aExtra.Length())
1.229 + {
1.230 + string.AppendFormat(_L("None"));
1.231 + }
1.232 + INFO_PRINTF1(string);
1.233 + }
1.234 +
1.235 +
1.236 +void CCapTestFrameworkStep::GenerateEnvironmentsL(const TCapabilitySet& aCapsNeeded, const TUid& aSidNeeded, const TUid& aVidNeeded, RArray<TTestEnvironment>& aEnvironments)
1.237 + {
1.238 + for (TUid sid={0}; sid.iUid <= aSidNeeded.iUid; sid.iUid+= aSidNeeded.iUid ? aSidNeeded.iUid : 1) // if no sid is needed then only do check once
1.239 + {
1.240 + TBool shouldPass=ETrue;
1.241 +
1.242 + if (sid!=aSidNeeded)
1.243 + {
1.244 + shouldPass=EFalse;
1.245 + }
1.246 +
1.247 + for (TUid vid={0}; vid.iUid <= aVidNeeded.iUid; vid.iUid+= aVidNeeded.iUid ? aVidNeeded.iUid : 1)
1.248 + {
1.249 + if (vid!=aVidNeeded)
1.250 + {
1.251 + shouldPass=EFalse;
1.252 + }
1.253 +
1.254 + //For each IPC, your test should implement the following:
1.255 + //
1.256 + // If an IPC is controlled by one capability only, the test code should run
1.257 + //first with the required capability only and second with the complement set
1.258 + //of the required capability. If the first test is successful and the second
1.259 + //a failure, the IPC value is proven to be controlled by the required capability
1.260 + //only.
1.261 + //
1.262 + // If an IPC is controlled by n capabilities, the test code should run first with
1.263 + //exact n required capabilities and after with any combination of all subsets of
1.264 + //n-1 capabilities with the complement set.
1.265 + //
1.266 + // For example, ABC controls an IPC. The full list of capabilities is
1.267 + //A, B, C, D, E and F. Test code with ABC must be successful, while test code
1.268 + //with ABDEF, ACDEF, BCDEF must all fail.
1.269 + //
1.270 + // So, the number of tests to run to validate a IPC is the combination of n
1.271 + //capabilities, n-1 at a time (i.e. n!/(n-1)! ) plus 1 exact positive test,
1.272 + //therefore a total of n+1 tests.
1.273 +
1.274 + // possibly positive case (depends on Sid and Vid settings)
1.275 + aEnvironments.Append(TTestEnvironment(aCapsNeeded, sid, vid, shouldPass));
1.276 +
1.277 + if (iThoroughness == EBasicChecks) // will fail when cap set is empty, but there is no TCapabilitySet::NotEmpty exported, write a replacement copy
1.278 + {
1.279 + // Just add one with no caps and expect to fail
1.280 + TCapabilitySet noCaps;
1.281 + aEnvironments.Append(TTestEnvironment(noCaps, sid, vid, EFalse));
1.282 + }
1.283 + else
1.284 + {
1.285 + // Thorough, cap sets as per comment above
1.286 + for (TInt c = 0; c < ECapability_Limit; ++c)
1.287 + {
1.288 + if (aCapsNeeded.HasCapability(TCapability(c)))
1.289 + {
1.290 + // Need to add a new one with (aCapsNeeded / c) | ~aCapsNeeded
1.291 + TCapabilitySet caps(aCapsNeeded);
1.292 + caps.RemoveCapability(TCapability(c)); // take cap c away
1.293 + caps.Union(InvertCapSet(aCapsNeeded)); // add in complement
1.294 +
1.295 + aEnvironments.Append(TTestEnvironment(caps, sid, vid, EFalse)); // add to sets, should fail
1.296 + }
1.297 + }
1.298 + } // end thorough cap tests
1.299 +
1.300 + } // end vid loop
1.301 +
1.302 + } // end sid loop
1.303 + }
1.304 +
1.305 +
1.306 +TVerdict CCapTestFrameworkStep::doTestStepPostambleL()
1.307 + {
1.308 + return EPass;
1.309 + }
1.310 +
1.311 +// helper functions
1.312 +TCapabilitySet CCapTestFrameworkStep::InvertCapSet(const TCapabilitySet& aCapSet)
1.313 + {
1.314 + TCapabilitySet ret;
1.315 + ret.SetEmpty();
1.316 +
1.317 + for (TInt c = 0; c < ECapability_Limit; ++c)
1.318 + {
1.319 + if (c == ECapabilityTCB && iOmitTCBCapInComplementSet)
1.320 + {
1.321 + continue;
1.322 + }
1.323 + if (!aCapSet.HasCapability(TCapability(c)))
1.324 + {
1.325 + ret.AddCapability(TCapability(c));
1.326 + }
1.327 + }
1.328 + return ret;
1.329 + }
1.330 +
1.331 +MCapabilityTestFactory* CCapTestFrameworkStep::SetupFactoryL()
1.332 + {
1.333 + User::LeaveIfError(iLibrary.Load(iDllName));
1.334 +
1.335 + TLibraryFunction testFactory=iLibrary.Lookup(1);
1.336 + iFactory=reinterpret_cast<MCapabilityTestFactory*>(testFactory());
1.337 +
1.338 + return iFactory;
1.339 + }
1.340 +
1.341 +// TCapSetTestInfo
1.342 +TTestEnvironment::TTestEnvironment(const TCapabilitySet& aCaps, TUid aSid, TUid aVid, TBool aExpectPass)
1.343 + : iCaps(aCaps), iSid(aSid), iVid(aVid), iExpectPass(aExpectPass)
1.344 + {
1.345 + }