--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/authenticationservices/authenticationserver/test/tauthcliserv/step_authexpr_build.cpp Tue Nov 24 09:06:03 2009 +0200
@@ -0,0 +1,759 @@
+/*
+* Copyright (c) 2005-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 <s32mem.h>
+#include "tauthcliservstep.h"
+#include <scs/scsclient.h>
+using namespace AuthServer;
+
+inline void CorruptTypeField(const CAuthExpressionImpl* aExpr)
+/**
+ Corrupt the type field of the supplied
+ expression so the invariant-checking code fails.
+
+ @param aExpr Expression to corrupt. This
+ is const, even though it is
+ modified, because Left and
+ Right return pointers to const
+ expressions.
+ */
+ {
+ // 4 == _FOFF(CAuthExpression, iType), but iType is private
+ // sizeof(CAuthExpression::iType) == 8
+ *(((TUint32*)aExpr) + 2) = ~0;
+ }
+
+
+CTStepAuthExprBuild::CTStepAuthExprBuild()
+/**
+ Record this test step's name.
+ */
+ {
+ SetTestStepName(KTStepAuthExprBuild);
+ }
+
+
+TVerdict CTStepAuthExprBuild::doTestStepL()
+/**
+ Implement CTestStep by creating simple and
+ complex expression types. In debug mode this
+ function also ensures the operations fail
+ cleanly in OOM.
+ */
+ {
+ RunTestsL(); // create all expression types
+ TestFailedCombsL();
+ TestCorruptPersistL();
+
+ // create all expression types in OOM
+#ifdef _DEBUG
+ TInt i = 1;
+ TBool failed = EFalse;
+
+ do
+ {
+ __UHEAP_SETFAIL(RAllocator::EDeterministic, i);
+ TRAPD(r, RunTestsL());
+ TESTL(r == KErrNone || r == KErrNoMemory);
+ __UHEAP_RESET;
+
+ failed = (r == KErrNoMemory);
+ ++i;
+ } while (failed);
+
+ // i is now one greater than the last alloc count.
+ // run the tests again, to ensure there really was
+ // enough memory, and this wasn't just an error case
+ // that wasn't handled properly.
+
+ TInt lim = i * 2;
+ while (i++ < lim)
+ {
+ __UHEAP_SETFAIL(RAllocator::EDeterministic, i);
+ RunTestsL();
+ __UHEAP_RESET;
+ }
+#endif
+
+ return EPass;
+ }
+
+
+void CTStepAuthExprBuild::RunTestsL()
+/**
+ Helper function for doTestStepL. This generates
+ authentication expressions.
+
+ 1. creating simple type and plugin id nodes.
+ 2. creating simple AND and OR combinations
+ 3. creating complex (multi-level) AND and OR combinations.
+ */
+ {
+ TestSimpleExprL();
+ TestSimpleExprCombsConsL();
+ TestComplexExprCombsConsL();
+ }
+
+
+void CTStepAuthExprBuild::TestExprLD(
+ void (CTStepAuthExprBuild::*aTestFuncL)(CAuthExpression*),
+ CAuthExpression* aExpr)
+/**
+ Run the supplied test function on the supplied expression.
+ This function only exists to place the expression on the
+ cleanup stand and delete it afterwards.
+
+ This function leaves with KErrNoMemory if the supplied
+ expression is NULL.
+ */
+ {
+ User::LeaveIfNull(aExpr);
+
+ CleanupStack::PushL(aExpr);
+ (this->*aTestFuncL)(aExpr);
+
+ // test externalization and internalization
+ // (this can fail because of OOM.)
+ TSizeStream ss;
+ RWriteStream ws(&ss);
+ aExpr->ExternalizeL(ws);
+
+ HBufC8* buf = HBufC8::NewLC(ss.Size());
+ TPtr8 bufPtr(buf->Des());
+ RDesWriteStream dws(bufPtr);
+ aExpr->ExternalizeL(dws);
+ dws.CommitL();
+
+ RDesReadStream drs(*buf);
+ CAuthExpression* aeRestore = CAuthExpressionImpl::NewL(drs);
+ CleanupStack::PushL(aeRestore);
+
+ (this->*aTestFuncL)(aExpr);
+
+ CleanupStack::PopAndDestroy(3, aExpr);
+ }
+
+
+void CTStepAuthExprBuild::TestSimpleExprL()
+/**
+ Test constructing leaf node expressions from
+ a plugin ID and a plugin type.
+ */
+ {
+ __UHEAP_MARK;
+
+ TestExprLD(&CTStepAuthExprBuild::TestPluginIdL, AuthExpr(KTestPluginId0));
+ TestExprLD(&CTStepAuthExprBuild::TestPluginTypeL, AuthExpr(EAuthKnowledge));
+
+ __UHEAP_MARKEND;
+ }
+
+
+void CTStepAuthExprBuild::TestPluginIdL(CAuthExpression* aExpr)
+/**
+ Tests the supplied expression is a simple expression
+ for plugin ID KTestPluginId0.
+ */
+ {
+ CAuthExpressionImpl* impl = static_cast<CAuthExpressionImpl*>(aExpr);
+ TESTL(impl->Type() == KPluginId);
+ TESTL(impl->PluginId() == KTestPluginId0);
+ }
+
+
+void CTStepAuthExprBuild::TestPluginTypeL(CAuthExpression* aExpr)
+/**
+ Tests the supplied expression is a simple expression
+ for plugin type EAuthKnowledge.
+ */
+ {
+ CAuthExpressionImpl* impl = static_cast<CAuthExpressionImpl*>(aExpr);
+ TESTL(impl->Type() == KPluginType);
+ TESTL(impl->PluginType() == EAuthKnowledge);
+ }
+
+
+void CTStepAuthExprBuild::TestSimpleExprCombsConsL()
+/**
+ Tests combining two simple types (plugin type or plugin id)
+ with the AuthAnd and AuthOr functions, and with the overloaded
+ binary AND (&) and OR (|) operators.
+ */
+ {
+ __UHEAP_MARK;
+
+ // type AND type
+ OpTestExprLD(&CTStepAuthExprBuild::TestTypeAndTypeL, AuthExpr(EAuthKnowledge) & AuthExpr(EAuthBiometric));
+ TestExprLD(&CTStepAuthExprBuild::TestTypeAndTypeL, AuthAnd(AuthExpr(EAuthKnowledge), AuthExpr(EAuthBiometric)));
+
+ // id OR id
+ OpTestExprLD(&CTStepAuthExprBuild::TestTypeOrTypeL, AuthExpr(EAuthKnowledge) | AuthExpr(EAuthBiometric));
+ TestExprLD(&CTStepAuthExprBuild::TestTypeOrTypeL, AuthOr(AuthExpr(EAuthKnowledge), AuthExpr(EAuthBiometric)));
+
+ // ID AND type
+ OpTestExprLD(&CTStepAuthExprBuild::TestIdAndTypeL, AuthExpr(KTestPluginId0) & AuthExpr(EAuthBiometric));
+ TestExprLD(&CTStepAuthExprBuild::TestIdAndTypeL, AuthAnd(AuthExpr(KTestPluginId0), AuthExpr(EAuthBiometric)));
+
+ // type AND ID
+ OpTestExprLD(&CTStepAuthExprBuild::TestTypeAndIdL, AuthExpr(EAuthBiometric) & AuthExpr(KTestPluginId0));
+ TestExprLD(&CTStepAuthExprBuild::TestTypeAndIdL, AuthAnd(AuthExpr(EAuthBiometric), AuthExpr(KTestPluginId0)));
+
+ // id AND id
+ OpTestExprLD(&CTStepAuthExprBuild::TestIdAndIdL, AuthExpr(KTestPluginId0) & AuthExpr(KTestPluginId1));
+ TestExprLD(&CTStepAuthExprBuild::TestIdAndIdL, AuthAnd(AuthExpr(KTestPluginId0), AuthExpr(KTestPluginId1)));
+
+ __UHEAP_MARKEND;
+ }
+
+
+void CTStepAuthExprBuild::TestTypeAndTypeL(CAuthExpression* aExpr)
+/**
+ Test the supplied expression says know & bio.
+ */
+ {
+ CAuthExpressionImpl* impl = static_cast<CAuthExpressionImpl*>(aExpr);
+ TESTL(impl->Type() == KAnd);
+ TESTL(impl->Left()->Type() == KPluginType);
+ TESTL(impl->Left()->PluginType() == EAuthKnowledge);
+ TESTL(impl->Right()->Type() == KPluginType);
+ TESTL(impl->Right()->PluginType() == EAuthBiometric);
+ }
+
+
+void CTStepAuthExprBuild::TestTypeOrTypeL(CAuthExpression* aExpr)
+/**
+ Test the supplied expression says know | bio.
+ */
+ {
+ CAuthExpressionImpl* impl = static_cast<CAuthExpressionImpl*>(aExpr);
+ TESTL(impl->Type() == KOr);
+ TESTL(impl->Left()->Type() == KPluginType);
+ TESTL(impl->Left()->PluginType() == EAuthKnowledge);
+ TESTL(impl->Right()->Type() == KPluginType);
+ TESTL(impl->Right()->PluginType() == EAuthBiometric);
+ }
+
+
+void CTStepAuthExprBuild::TestIdAndTypeL(CAuthExpression* aExpr)
+/**
+ Test the supplied expression says id0 & bio.
+ */
+ {
+ CAuthExpressionImpl* impl = static_cast<CAuthExpressionImpl*>(aExpr);
+ TESTL(impl->Type() == KAnd);
+ TESTL(impl->Left()->Type() == KPluginId);
+ TESTL(impl->Left()->PluginId() == KTestPluginId0);
+ TESTL(impl->Right()->Type() == KPluginType);
+ TESTL(impl->Right()->PluginType() == EAuthBiometric);
+ }
+
+
+void CTStepAuthExprBuild::TestTypeAndIdL(CAuthExpression* aExpr)
+/**
+ Test the supplied expression says bio & id0.
+ */
+ {
+ CAuthExpressionImpl* impl = static_cast<CAuthExpressionImpl*>(aExpr);
+ TESTL(impl->Type() == KAnd);
+ TESTL(impl->Left()->Type() == KPluginType);
+ TESTL(impl->Left()->PluginType() == EAuthBiometric);
+ TESTL(impl->Right()->Type() == KPluginId);
+ TESTL(impl->Right()->PluginId() == KTestPluginId0);
+ }
+
+
+void CTStepAuthExprBuild::TestIdAndIdL(CAuthExpression* aExpr)
+/**
+ Test the supplied expression says id0 & id1.
+ */
+ {
+ CAuthExpressionImpl* impl = static_cast<CAuthExpressionImpl*>(aExpr);
+ TESTL(impl->Type() == KAnd);
+ TESTL(impl->Left()->Type() == KPluginId);
+ TESTL(impl->Left()->PluginId() == KTestPluginId0);
+ TESTL(impl->Right()->Type() == KPluginId);
+ TESTL(impl->Right()->PluginId() == KTestPluginId1);
+ }
+
+
+void CTStepAuthExprBuild::TestComplexExprCombsConsL()
+/**
+ Test complex AND and OR combinations.
+ For the overloaded operators, this additionally checks
+ that precedence works as expected.
+ */
+ {
+ __UHEAP_MARK;
+
+ // complex combinations - ensure precedence works
+
+ // id AND id AND id == (id AND id) AND id
+ OpTestExprLD(&CTStepAuthExprBuild::TestAndAndL, AuthExpr(KTestPluginId0) & AuthExpr(KTestPluginId1) & AuthExpr(KTestPluginId2));
+ TestExprLD(&CTStepAuthExprBuild::TestAndAndL, AuthAnd(AuthAnd(AuthExpr(KTestPluginId0), AuthExpr(KTestPluginId1)), AuthExpr(KTestPluginId2)));
+
+ // id AND id AND id == (id AND id) OR id
+ OpTestExprLD(&CTStepAuthExprBuild::TestAndOrL, AuthExpr(KTestPluginId0) & AuthExpr(KTestPluginId1) | AuthExpr(KTestPluginId2));
+ TestExprLD(&CTStepAuthExprBuild::TestAndOrL, AuthOr(AuthAnd(AuthExpr(KTestPluginId0), AuthExpr(KTestPluginId1)), AuthExpr(KTestPluginId2)));
+
+ // id OR id AND id == id OR (id AND id)
+ OpTestExprLD(&CTStepAuthExprBuild::TestOrAndL, AuthExpr(KTestPluginId0) | AuthExpr(KTestPluginId1) & AuthExpr(KTestPluginId2));
+ TestExprLD(&CTStepAuthExprBuild::TestOrAndL, AuthOr(AuthExpr(KTestPluginId0), AuthAnd(AuthExpr(KTestPluginId1), AuthExpr(KTestPluginId2))));
+
+ // id OR id OR id == (id OR id) OR id
+ OpTestExprLD(&CTStepAuthExprBuild::TestOrOrL, AuthExpr(KTestPluginId0) | AuthExpr(KTestPluginId1) | AuthExpr(KTestPluginId2));
+ OpTestExprLD(&CTStepAuthExprBuild::TestOrOrL, AuthOr(AuthOr(AuthExpr(KTestPluginId0), AuthExpr(KTestPluginId1)), AuthExpr(KTestPluginId2)));
+
+ __UHEAP_MARKEND;
+ }
+
+
+void CTStepAuthExprBuild::TestAndAndL(CAuthExpression* aExpr)
+/**
+ Test the supplied expression says (id0 & id1) & id2.
+ */
+ {
+ CAuthExpressionImpl* impl = static_cast<CAuthExpressionImpl*>(aExpr);
+ TESTL(impl->Type() == KAnd);
+ TESTL(impl->Left()->Type() == KAnd);
+ TESTL(impl->Left()->Left()->Type() == KPluginId);
+ TESTL(impl->Left()->Left()->PluginId() == KTestPluginId0);
+ TESTL(impl->Left()->Right()->Type() == KPluginId);
+ TESTL(impl->Left()->Right()->PluginId() == KTestPluginId1);
+ TESTL(impl->Right()->Type() == KPluginId);
+ TESTL(impl->Right()->PluginId() == KTestPluginId2);
+ }
+
+
+void CTStepAuthExprBuild::TestAndOrL(CAuthExpression* aExpr)
+/**
+ Test the supplied expression says (id0 & id 1) | id2.
+ */
+ {
+ CAuthExpressionImpl* impl = static_cast<CAuthExpressionImpl*>(aExpr);
+ TESTL(impl->Type() == KOr);
+ TESTL(impl->Left()->Type() == KAnd);
+ TESTL(impl->Left()->Left()->Type() == KPluginId);
+ TESTL(impl->Left()->Left()->PluginId() == KTestPluginId0);
+ TESTL(impl->Left()->Right()->Type() == KPluginId);
+ TESTL(impl->Left()->Right()->PluginId() == KTestPluginId1);
+ TESTL(impl->Right()->Type() == KPluginId);
+ TESTL(impl->Right()->PluginId() == KTestPluginId2);
+ }
+
+
+void CTStepAuthExprBuild::TestOrAndL(CAuthExpression* aExpr)
+/**
+ Test the supplied expression says id0 | (id1 & id2).
+ */
+ {
+ CAuthExpressionImpl* impl = static_cast<CAuthExpressionImpl*>(aExpr);
+ TESTL(impl->Type() == KOr);
+ TESTL(impl->Left()->Type() == KPluginId);
+ TESTL(impl->Left()->PluginId() == KTestPluginId0);
+ TESTL(impl->Right()->Type() == KAnd);
+ TESTL(impl->Right()->Left()->Type() == KPluginId);
+ TESTL(impl->Right()->Left()->PluginId() == KTestPluginId1);
+ TESTL(impl->Right()->Right()->Type() == KPluginId);
+ TESTL(impl->Right()->Right()->PluginId() == KTestPluginId2);
+ }
+
+
+void CTStepAuthExprBuild::TestOrOrL(CAuthExpression* aExpr)
+/**
+ Test the supplied expression says (id0 | id1) | id2.
+ */
+ {
+ CAuthExpressionImpl* impl = static_cast<CAuthExpressionImpl*>(aExpr);
+ TESTL(impl->Type() == KOr);
+ TESTL(impl->Left()->Type() == KOr);
+ TESTL(impl->Left()->Left()->Type() == KPluginId);
+ TESTL(impl->Left()->Left()->PluginId() == KTestPluginId0);
+ TESTL(impl->Left()->Right()->Type() == KPluginId);
+ TESTL(impl->Left()->Right()->PluginId() == KTestPluginId1);
+ TESTL(impl->Right()->Type() == KPluginId);
+ TESTL(impl->Right()->PluginId() == KTestPluginId2);
+ }
+
+
+void CTStepAuthExprBuild::TestFailedCombsL()
+/**
+ Test that complex expression builder fails cleanly
+ for all permutations of unallocated input.
+ */
+ {
+ __UHEAP_MARK;
+
+ // left null only
+ CAuthExpression* aeRight = AuthExpr(KTestPluginId0);
+ User::LeaveIfNull(aeRight);
+ CAuthExpression* aeLeftNull = AuthAnd(0, aeRight);
+ TESTL(aeLeftNull == 0);
+
+ // right null only
+ CAuthExpression* aeLeft = AuthExpr(KTestPluginId1);
+ User::LeaveIfNull(aeRight);
+ CAuthExpression* aeRightNull = AuthAnd(aeLeft, 0);
+ TESTL(aeRightNull == 0);
+
+ // both null
+ CAuthExpression* aeBothNull = AuthAnd(0, 0);
+ TESTL(aeBothNull == 0);
+
+ __UHEAP_MARKEND;
+ }
+
+
+void CTStepAuthExprBuild::TestCorruptPersistL()
+/**
+ Test get expected errors when externalize or
+ internalize invalid expressions.
+ */
+ {
+ TInt r;
+
+ __UHEAP_MARK;
+ CAuthExpression* aeTest = AuthExpr(KTestPluginId0);
+ TESTL(aeTest != 0);
+ CleanupStack::PushL(aeTest);
+
+ TSizeStream ss;
+ RWriteStream ws(&ss);
+ aeTest->ExternalizeL(ws);
+
+ TInt len = ss.Size();
+ TAny* buf= User::AllocLC(ss.Size());
+
+ // externalize valid expression
+ RMemWriteStream mwsValid(buf, len);
+ aeTest->ExternalizeL(mwsValid);
+
+ // internalize unsupported expression stream
+ TInt8& verByteP = ((TInt8*)buf)[0];
+ TInt8 origVer = verByteP;
+ verByteP = KMaxTInt8;
+ RMemReadStream mrsHighVer(buf, len);
+ TRAP(r, /* ignore */ CAuthExpressionImpl::NewL(mrsHighVer));
+ TESTL(r == KErrAuthServUnsupportedExprVersion);
+ verByteP = origVer;
+
+ // internalize corrupt expression stream
+ TInt8& typeByteP = ((TInt8*)buf)[1];
+ TInt8 origType = typeByteP;
+ typeByteP = ~0;
+ RMemReadStream mrsCorrupt(buf, len);
+ TRAP(r, /* ignore */ CAuthExpressionImpl::NewL(mrsCorrupt));
+ TESTL(r == KErrAuthServInvalidInternalizeExpr);
+ typeByteP = origType;
+
+ // internalize valid expression stream
+ RMemReadStream mrsValid(buf, len);
+ CAuthExpression* aeRestore = CAuthExpressionImpl::NewL(mrsValid);
+ TESTL(aeRestore != 0);
+ delete aeRestore;
+
+ CleanupStack::PopAndDestroy(2, aeTest);
+ __UHEAP_MARKEND;
+ }
+
+
+// -------- Server fails expressions from client --------
+
+
+namespace {
+
+class RTestAuthClient : public RAuthClient
+/**
+ This subclass of RAuthClient is used to
+ send a corrupt externalized expression
+ to the authentication server.
+
+ The test code can't call SendReceive() on
+ an instance of RAuthClient because it is
+ protected.
+ */
+ {
+public:
+ void SendCorruptAuthExprL();
+ void SendHighVerAuthExprL();
+
+ static HBufC8* GetAuthExprExternalizationLC();
+ };
+
+HBufC8* RTestAuthClient::GetAuthExprExternalizationLC()
+/**
+ Helper function for SendCorruptAuthExprL and
+ SendHighVerAuthExprL. This allocates a buffer
+ containing an externalized auth expr, so the
+ calling function can corrupt it.
+
+ @return Buffer containing externalized
+ authentication expression. This
+ is also placed on the cleanup stack.
+ @see SendCorruptAuthExprL
+ @see SendHighVerAuthExprL
+ */
+ {
+ CAuthExpression* ae = AuthAnd(AuthExpr(KTestPluginId0), AuthExpr(KTestPluginId1));
+ User::LeaveIfNull(ae);
+ CleanupStack::PushL(ae);
+
+ TSizeStream ss;
+ RWriteStream ws(&ss);
+ ae->ExternalizeL(ws);
+
+ HBufC8* buf = HBufC8::NewLC(ss.Size());
+ TPtr8 bufPtr = buf->Des();
+
+ RDesWriteStream dws(bufPtr);
+ ae->ExternalizeL(dws);
+ dws.CommitL();
+
+ CleanupStack::Pop(2, ae);
+ CleanupStack::PushL(buf);
+
+ return buf;
+ }
+
+
+void RTestAuthClient::SendCorruptAuthExprL()
+/**
+ Send an authenticate request to the server,
+ with a corrupt authentication expression.
+ */
+ {
+ HBufC8* buf = GetAuthExprExternalizationLC();
+
+ // corrupt the type field, one byte after the version field
+ buf->Des()[1] = ~0;
+
+ // the server should panick this thread with
+ // category "AuthServer" and reason EPanicBadExternalizedAuthExpr (3)
+ TRequestStatus rs;
+ CallSessionFunction(EAuthenticate, TIpcArgs(buf), rs);
+
+ // this code will not be reached
+ User::WaitForRequest(rs);
+ CleanupStack::PopAndDestroy(buf);
+ }
+
+
+void RTestAuthClient::SendHighVerAuthExprL()
+/**
+ Send an authenticate request to the server,
+ with an unsupported version number.
+
+ The server should fail the request with
+ KErrAuthServUnsupportedExprVersion.
+ */
+ {
+ HBufC8* buf = GetAuthExprExternalizationLC();
+
+ // change the version field, which is the first byte
+ buf->Des()[0] = KMaxTInt8;
+
+ TRequestStatus rs;
+ CallSessionFunction(EAuthenticate, TIpcArgs(buf), rs);
+ User::WaitForRequest(rs);
+
+ // this isn't semantically the right code to
+ // fail the test with, because it is expected.
+ // However, it is easy to find in the test code
+ // if it occurs.
+ if (rs != KErrAuthServUnsupportedExprVersion)
+ User::Leave(KErrAuthServUnsupportedExprVersion);
+
+ CleanupStack::PopAndDestroy(buf);
+ }
+
+
+void RunTestAuthClientFunctionL(void (RTestAuthClient::* aTacFuncL)())
+/**
+ Connect to the authentication server using
+ RTestAuthClient, and call the supplied function.
+
+ This is a helper function for CTStepBadExtAuthExpr
+ and CTStepAuthExprHighVer which both use
+ RTestAuthClient, and only call different functions.
+
+ @param aTacFuncL Function to call on RTestAuthClient
+ once the connection has been made.
+ If this function leaves then the
+ leave code is propagated through this
+ (RunTestAuthClientFunctionL) function.
+ */
+ {
+ RTestAuthClient tac;
+ User::LeaveIfError(tac.Connect());
+ CleanupClosePushL(tac);
+
+ // this function should not return
+ (tac.*aTacFuncL)();
+
+ CleanupStack::PopAndDestroy(&tac);
+ }
+
+
+} // namespace
+
+
+CTStepBadExtAuthExpr::CTStepBadExtAuthExpr()
+/**
+ Record this test step's name.
+ */
+ {
+ SetTestStepName(KTStepBadExtAuthExpr);
+ }
+
+
+TVerdict CTStepBadExtAuthExpr::doTestStepL()
+/**
+ Implement CTestStep by calling RAuthClient::Authenticate
+ with a corrupt externalized authentication expression.
+
+ The current thread should be panicked with
+ category AuthServer and reason EPanicBadExternalizedAuthExpr.
+ */
+ {
+ // this function should not return
+ RunTestAuthClientFunctionL(&RTestAuthClient::SendCorruptAuthExprL);
+ return EPass;
+ }
+
+
+CTStepAuthExprHighVer::CTStepAuthExprHighVer()
+/**
+ Record this test step's name.
+ */
+ {
+ SetTestStepName(KTStepAuthExprHighVer);
+ }
+
+
+TVerdict CTStepAuthExprHighVer::doTestStepL()
+/**
+ Implement CTestStep by calling RAuthClient::SendHighVerAuthExprL()
+ and ensuring the server fails the request if
+ the externalized auth expr uses an unsupported
+ version number.
+ */
+ {
+ RunTestAuthClientFunctionL(&RTestAuthClient::SendHighVerAuthExprL);
+ return EPass;
+ }
+
+
+// -------- Debug-mode client-side panicks --------
+
+
+#ifdef _DEBUG
+
+
+// -------- CTStepAuthExprTypePnc --------
+
+
+CTStepAuthExprTypePnc::CTStepAuthExprTypePnc()
+/**
+ Record this test step's name.
+ */
+ {
+ SetTestStepName(KTStepAuthExprTypePnc);
+ }
+
+
+TVerdict CTStepAuthExprTypePnc::doTestStepL()
+/**
+ Implement CTestStep by creating a plugin id
+ node, corrupting the type field, and testing
+ that it is panicked when the type is
+ retrieved. Debug only.
+ */
+ {
+ CAuthExpression* ae = AuthExpr(KTestPluginId0);
+ User::LeaveIfNull(ae);
+ CAuthExpressionImpl* aeImpl = static_cast<CAuthExpressionImpl*>(ae);
+ CorruptTypeField(aeImpl);
+ /* ignore */ aeImpl->Type();
+
+ // this code should never be reached
+ return EPass;
+ }
+
+
+// -------- CTStepAuthExprTypePncBadLeft --------
+
+
+CTStepAuthExprTypePncBadLeft::CTStepAuthExprTypePncBadLeft()
+/**
+ Record this test step's name.
+ */
+ {
+ SetTestStepName(KTStepAuthExprTypePncBadLeft);
+ }
+
+
+TVerdict CTStepAuthExprTypePncBadLeft::doTestStepL()
+/**
+ Implement CTestStep by creating a complex
+ expression where the left subexpression is
+ corrupt. This tests that the invariant
+ correctly validates the left subtree.
+ */
+ {
+ CAuthExpression* ae = AuthAnd(AuthExpr(KTestPluginId0), AuthExpr(KTestPluginId1));
+ User::LeaveIfNull(ae);
+ CAuthExpressionImpl* aeImpl = static_cast<CAuthExpressionImpl*>(ae);
+ CorruptTypeField(aeImpl->Left());
+ /* ignore */ aeImpl->Type();
+
+ // this code should never be reached
+ return EPass;
+ }
+
+
+// -------- CTStepAuthExprTypePncBadRight --------
+
+
+CTStepAuthExprTypePncBadRight::CTStepAuthExprTypePncBadRight()
+/**
+ Record this test step's name.
+ */
+ {
+ SetTestStepName(KTStepAuthExprTypePncBadRight);
+ }
+
+
+TVerdict CTStepAuthExprTypePncBadRight::doTestStepL()
+/**
+ Implement CTestStep by creating a complex
+ expression where the Right subexpression is
+ corrupt. This tests that the invariant
+ correctly validates the Right subtree.
+ */
+ {
+ CAuthExpression* ae = AuthAnd(AuthExpr(KTestPluginId0), AuthExpr(KTestPluginId1));
+ User::LeaveIfNull(ae);
+ CAuthExpressionImpl* aeImpl = static_cast<CAuthExpressionImpl*>(ae);
+ CorruptTypeField(aeImpl->Right());
+ /* ignore */ aeImpl->Type();
+
+ // this code should never be reached
+ return EPass;
+ }
+
+
+#endif // #ifdef _DEBUG