|
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 |