--- a/authenticationservices/authenticationserver/source/server/authserver.cpp Thu Aug 19 11:18:56 2010 +0530
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2011 +0,0 @@
-/*
-* 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:
-* CAuthServer implementation
-*
-*/
-
-
-/**
- @file
-*/
-
-#include <s32mem.h>
-#include <s32file.h>
-#include <ecom/ecom.h>
-#include <pbedata.h>
-#include <scs/cleanuputils.h>
-#include "authserver_impl.h"
-#include "authtransaction.h"
-#include "authserver/aspubsubdefs.h"
-#include "authserverutil.h"
-
-using namespace AuthServer;
-
-const TUint CAuthServer::iRangeCount = KPolicyRanges;
-
-const TInt CAuthServer::iRanges[KPolicyRanges] =
- {
- 0,
- CScsServer::EBaseSession,
- CScsServer::EBaseSession |ERequireNoCapabilities, // accessible by all clients.
- CScsServer::EBaseSession |ERequireReadUserData, // accessible by ReadUserData clients only.
- CScsServer::EBaseSession |ERequireWriteUserData, // accessible by WriteUserData clients only.
- CScsServer::EBaseSession |ERequireReadDeviceData, // accessible by ReadDeviceData clients only.
- CScsServer::EBaseSession |ERequireWriteDeviceData, // accessible by WriteDeviceData clients only.
- CScsServer::EBaseSession |ERequireTrustedUi, // accessible by TrustedUi clients only.
- CScsServer::EBaseSession |ERequireReadDeviceAndUserData, // accessible by clients with both
- // ReadUserData and ReadDeviceData.
- CScsServer::EBaseSession |ERequireCustomCheck, // Require custom check.
- CScsServer::EBaseSession |ELastService,
- CScsServer::EBaseMustAllow // SCS Internal.
- };
-
-const TUint8 CAuthServer::iElementsIndex[iRangeCount] =
- {
- CPolicyServer::ENotSupported,
- CPolicyServer::EAlwaysPass,
- 0, // all clients can have access
- 1, // ReadUserData clients only
- 2, // WriteUserData clients only
- 3, // ReadDeviceData
- 4, // WriteDeviceData
- 5, // trusted ui
- 6, // ReadUserData and ReadDeviceData
- CPolicyServer::ECustomCheck, // custom check
- CPolicyServer::EAlwaysPass,
- CPolicyServer::EAlwaysPass,
- };
-
-const CPolicyServer::TPolicyElement CAuthServer::iPolicyElements[] =
- {
- {_INIT_SECURITY_POLICY_C1(ECapability_None), CPolicyServer::EFailClient},
- {_INIT_SECURITY_POLICY_C1(ECapabilityReadUserData), CPolicyServer::EFailClient},
- {_INIT_SECURITY_POLICY_C1(ECapabilityWriteUserData), CPolicyServer::EFailClient},
- {_INIT_SECURITY_POLICY_C1(ECapabilityReadDeviceData), CPolicyServer::EFailClient},
- {_INIT_SECURITY_POLICY_C1(ECapabilityWriteDeviceData), CPolicyServer::EFailClient},
- {_INIT_SECURITY_POLICY_C1(ECapabilityTrustedUI), CPolicyServer::EFailClient},
- {_INIT_SECURITY_POLICY_C2(ECapabilityReadDeviceData, ECapabilityReadUserData), CPolicyServer::EFailClient},
- };
-
-const CPolicyServer::TPolicy CAuthServer::iPolicy =
- {
- CPolicyServer::EAlwaysPass, // so that any client can connect
- iRangeCount,
- iRanges,
- iElementsIndex,
- iPolicyElements,
- };
-
-_LIT_SECURITY_POLICY_S0(CAuthServer::iPropertyWritePolicy, KAuthServerSecureId.iUid);
-_LIT_SECURITY_POLICY_PASS(CAuthServer::iPropertyReadPolicy);
-
-
-inline CAuthServer::CAuthServer(CActive::TPriority aPriority)
- :CScsServer(TVersion(1,0,0), iPolicy, aPriority)
- {}
-
-CAuthServer* CAuthServer::NewLC(CActive::TPriority aPriority)
- {
- CAuthServer* self = new(ELeave) CAuthServer(aPriority);
- CleanupStack::PushL(self);
- self->ConstructL();
- return self;
- }
-
-void CAuthServer::ConstructL()
- {
- // Delay starting of shutdown timer till we finish construction since
- // loading of ECOM plugins takes a while
- CScsServer::ConstructL(0);
- TInt r;
- StartL(KAuthServerName);
- r = iFs.Connect();
- User::LeaveIfError(r);
- r = iFs.CreatePrivatePath(RFs::GetSystemDrive());
- User::LeaveIfError(r);
-
- // Retrieve the key size to be used for protection keys
- CPBEncryptElement* pbee = CPBEncryptElement::NewLC(_L(""));
- iKeySize = pbee->EncryptionData().AuthData().Key().Size();
- CleanupStack::PopAndDestroy(pbee);
- iAuthRepository = CAuthRepository::NewL();
- iAuthDb2 = CAuthDb2::NewL(iFs);
- iPluginMgr = CPluginMgr::NewL();
- iPluginObserver = CPluginObserver::NewL(*iPluginMgr);
- iEvaluator = CEvaluator::NewL(this,this);
- iTrainingMgr = new (ELeave) CTrainingMgr(*iPluginMgr, *iAuthDb2, *iAuthRepository);
- TUid clientSid = {0};
- iParams = CAuthParams::NewL(0,
- EFalse,
- clientSid,
- EFalse,
- KNullDesC());
- CreatePropertiesL();
- FirstStartL();
-
- // Construction complete, now start the shutdown timer
- CScsServer::EnableShutdownTimerL(AuthServer::KDefaultShutdownDelay);
- }
-
-
-CPolicyServer::TCustomResult CAuthServer::CustomSecurityCheckL(const RMessage2& aMessage,
- TInt& /*aAction*/, TSecurityInfo& aMissing)
- {
- TInt KAuthParams = 1;
- TInt paramsLen = aMessage.GetDesLength(KAuthParams);
-
- if(paramsLen != KErrBadDescriptor)
- {
- //Create a buffer.
- HBufC8* buffer = HBufC8::NewLC(paramsLen);
- TPtr8 bufDes(buffer->Des());
- aMessage.ReadL(EIpcArgument1, bufDes);
-
- //Internalize the params object.
- RDesReadStream readStream(*buffer);
- CleanupClosePushL(readStream);
- iParams->InternalizeL(readStream);
- CleanupStack::PopAndDestroy(2, buffer);
- }
-
- TBool clientKey = iParams->iClientKey;
- TBool withString = iParams->iWithString;
- TInt clientSid = iParams->iClientSid.iUid;
-
- if((!clientKey || withString || ((clientSid != aMessage.SecureId()) && clientSid != 0 )) && !(aMessage.HasCapability(ECapabilityReadUserData)))
- {
- // Missing ReadUserData capability.
- aMissing.iCaps.Set(ECapabilityReadUserData);
- return CPolicyServer::EFail;
- }
-
- else
- {
- return CPolicyServer::EPass;
- }
- }
-
-/**
- * Creates and initialises the two AuthServer properties -
- * KUidAuthServerLastAuth and KUidAuthServerAuthChangeEvent.
- *
- **/
-void CAuthServer::CreatePropertiesL()
- {
- // KUidAuthServerLastAuth
- TInt err1 = iAuthProperty.Define(KUidAuthServerLastAuth, RProperty::EText,
- iPropertyReadPolicy, iPropertyWritePolicy,
- sizeof(TLastAuth));
-
- User::LeaveIfError(iAuthProperty.Attach(KAuthServerSecureId,
- KUidAuthServerLastAuth));
-
-
- // KUidAuthServerAuthChangeEvent
- TInt err2 = iAuthEventProperty.Define(KUidAuthServerAuthChangeEvent,
- RProperty::EInt,
- iPropertyReadPolicy,
- iPropertyWritePolicy);
-
- User::LeaveIfError(iAuthEventProperty.Attach(KAuthServerSecureId,
- KUidAuthServerAuthChangeEvent));
-
- if (err1 == KErrNone || err2 == KErrNone )
- {
- ClearPropertiesL();
- }
- }
-
-void CAuthServer::ClearPropertiesL()
- {
- TLastAuth lastAuth;
- TPckg<TLastAuth> authPckg(lastAuth);
- User::LeaveIfError(iAuthProperty.Set(authPckg));
- User::LeaveIfError(iAuthEventProperty.Set(KUnknownIdentity));
- }
-
-
-/**
- * Checks the number of identities in the database and iff zero asks the
- * training mgr to register the first identity.
- *
- * @leave KErrAuthServerCanNotCreateFirstId if the first identity cannot
- * be created
- **/
-void CAuthServer::FirstStartL()
- {
- TInt numIds = iAuthDb2->NumIdentitiesL();
- if (numIds == 0)
- {
- TIdentityId id = 0;
- TPckg<TIdentityId> idPkg(id);
- TRandom::RandomL(idPkg);
-
- CProtectionKey* key = CProtectionKey::NewL(iKeySize);
- if (!iTrainingMgr->RegisterFirstIdentityL(id, *key))
- {
- User::Panic(KAuthServerShortName, EPanicNoFirstStartPlugin);
- }
- }
- }
-
-CAuthServer::~CAuthServer()
- {
- delete iAuthRepository;
- delete iAuthTransaction;
-
- delete iTrainingMgr;
- delete iLastIdentity;
- delete iEvaluator;
- delete iPluginMgr;
- delete iPluginObserver;
- delete iParams;
- if (iAuthDb2 != 0)
- {
- iAuthDb2->CompactIfRequired();
- delete iAuthDb2;
- }
-
- iFs.Close();
- REComSession::FinalClose();
- }
-
-
-/**
- * Creates a new session
- * @param aClientVersion the version of the connecting client
- * @param aMessage the connect message
- */
-CScsSession* CAuthServer::DoNewSessionL(const RMessage2& /*aMessage*/)
- {
- return CAuthServerSession::NewL(*this);
- }
-
-
-/**
- * Returns the last identity to be authenticated within the period
- * currTime to currTime-timeout.
- *
- * @param currTime the current universal time
- *
- * @param timeout the number of seconds within which the last
- * authentication should have been made
- *
- * @return 0 if there has been no previous authentications either in the
- * server lifetime or within the timeout period.
- *
- * @return a pointer to the cached identity object
- **/
-CIdentity* CAuthServer::CachedIdentity( const TTimeIntervalSeconds& aTimeOut)
- {
- // process request
- TTime currentTime;
- if(currentTime.UniversalTimeSecure() == KErrNoSecureTime)
- {
- // Fall back to nonsecure time.
- currentTime.UniversalTime();
- }
-
- CIdentity* id = 0;
-
- TTimeIntervalSeconds timeSinceLast;
- currentTime.SecondsFrom(iLastAuthTime, timeSinceLast);
-
- if (timeSinceLast.Int() >= 0 && timeSinceLast < aTimeOut)
- {
- id = iLastIdentity;
- }
-
- return id;
- }
-
-
-
-/**
- *
- * @param aMessage the message to process
- **/
-void CAuthServer::DeauthenticateL(const RMessage2& aMessage)
- {
- if (ServerBusy())
- {
- aMessage.Complete(KErrServerBusy);
- return;
- }
-
- delete iLastIdentity;
- iLastIdentity = 0;
- iLastAuthTime = 0L;
-
- ClearPropertiesL();
- aMessage.Complete(KErrNone);
- }
-
-HBufC* CAuthServer::StringOrNullLC(TBool aReturnString, TIdentityId aId)
- {
- HBufC* str = 0;
- if (aReturnString)
- {
- TRAPD(err, str = iAuthDb2->DescriptionL(aId));
- if (!err)
- {
- CleanupStack::PushL(str);
- }
-
- }
- if (str == 0)
- {
- str = HBufC::NewLC(0);
- }
- return str;
- }
-
-void CAuthServer::AuthenticateL(const RMessage2& aMessage)
- {
- if (ServerBusy())
- {
- aMessage.Complete(KErrServerBusy);
- return;
- }
-
- TInt KAuthParams = 1;
- TInt paramsLen = aMessage.GetDesLength(KAuthParams);
-
- if(paramsLen != KErrBadDescriptor)
- {
- //Create a buffer.
- HBufC8* buffer = HBufC8::NewLC(paramsLen);
- TPtr8 bufDes(buffer->Des());
-
- aMessage.ReadL(EIpcArgument1, bufDes);
-
- //Internalize the params object.
- RDesReadStream readStream(*buffer);
- CleanupClosePushL(readStream);
- iParams->InternalizeL(readStream);
- CleanupStack::PopAndDestroy(2, buffer);
- }
-
- CIdentity* id = CachedIdentity(iParams->iTimeout);
-
- if (id == 0) // no valid cache available
- {
- const TInt KAuthExprParam = 0;
-
- // reconstruct the authentication expression
- TInt extLen = aMessage.GetDesLengthL(KAuthExprParam);
- HBufC8* extSrv = HBufC8::NewLC(extLen);
- TPtr8 desSrv8 = extSrv->Des();
- aMessage.ReadL(KAuthExprParam, desSrv8);
-
- RDesReadStream drs(desSrv8);
- CAuthExpression* authExpr = CAuthExpressionImpl::NewL(drs);
- // don't need the stream any more, so free it
- CleanupStack::PopAndDestroy(extSrv);
- CleanupStack::PushL(authExpr);
-
- const CAuthExpressionImpl* expr = static_cast<const CAuthExpressionImpl*>(authExpr);
-
- iAuthTransaction = CAuthTransaction::NewL(aMessage,
- iParams->iClientKey,
- iParams->iClientSid.iUid,
- iParams->iWithString,
- *iParams->iClientMessage,
- expr);
- CleanupStack::Pop(authExpr);
-
- iEvaluator->Evaluate(expr);
-
- return;
- }
-
- else if (iParams->iClientKey && (id->Id() != KUnknownIdentity))
- {
-
- HBufC* str = StringOrNullLC(iParams->iWithString, id->Id());
- CIdentity* id2 = 0;
-
- TInt clientId = aMessage.SecureId();
-
- if(iParams->iClientSid.iUid != 0)
- {
- clientId = iParams->iClientSid.iUid;
- }
-
- id2 = CIdentity::NewL(id->Id(), id->Key().ClientKeyL(clientId), str);
-
- CleanupStack::Pop(str);
- CleanupStack::PushL(id2);
- // id pointer already stored as iLastIdentity
- id = id2;
- }
-
- CompleteAuthenticationL(aMessage, id);
-
- if (id != iLastIdentity)
- {
- // only clean up the allocated id if it has not been transferred to us.
- CleanupStack::PopAndDestroy(id);
- }
-
- }
-
-// -------- plugin lists --------
-
-
-/**
- Build an array containing descriptions for the
- plugins available on the system and send it to
- the client.
-
- @param aMessage Message describing client
- request.
- @param aFilter Function which decides whether
- or not to include a plugin in the
- list.
- */
-void CAuthServer::FilterPluginsL(
- const RMessage2& aMessage, CAuthServer::TInterfaceFilter aFilter)
-
- {
- RCPointerArray<const CPluginDesc> descs;
- GetDescriptionsFromEComLC(aFilter, descs);
- AuthServerUtil::SendDataPointerArrayL(aMessage, descs, 0);
- CleanupStack::PopAndDestroy(&descs);
- }
-
-
-/**
- Populate the supplied array with plugin descriptions generated
- from the available ECOM plugins.
-
- @param aFilter Predicate function decides whether or not
- to include each plugin in the list.
- @param aDescs Array to populate. When this function is
- called, any existing entries are removed.
- If this function leaves then any entries are
- removed from the array. On success, the
- array is on the cleanup stack.
- */
-void CAuthServer::GetDescriptionsFromEComLC(
- CAuthServer::TInterfaceFilter aFilter,
- RCPointerArray<const CPluginDesc>& aDescs)
- {
- aDescs.Reset();
- CleanupClosePushL(aDescs);
-
- // ownership of the data pointed by this array is with
- // the plugin manager.
- const RPointerArray<CImplementationInformation>& implInfo = iPluginMgr->ImplementationsL();
- TInt implCount = implInfo.Count();
-
- for (TInt i = 0; i < implCount; ++i)
- {
- // avoid RVCT warning C2874W: pi may be used before being set
- CAuthPluginInterface* pi = 0;
-
- TRAPD(r, pi = iPluginMgr->ImplementationL(i));
-
- // skip plugins which are not available
- if (KErrNone != r)
- continue;
-
- if (! (this->*aFilter)(*pi))
- {
- continue;
- }
-
- // get training status from db
- TAuthTrainingStatus ts = iAuthDb2->PluginStatusL(pi->Id());
-
- CPluginDesc* pd = CPluginDesc::NewL(
- pi->Id(), pi->Name(), pi->Type(),
- ts, pi->MinEntropy(),
- pi->FalsePositiveRate(), pi->FalseNegativeRate() );
-
- CleanupStack::PushL(pd);
- aDescs.AppendL(pd);
- CleanupStack::Pop(pd);
- }
-
- }
-
-
-
-/**
- Build an array containing plugin descriptions for
- each plugin which is available on the system, and
- copy this into the client's space.
-
- @param aMessage Client message. This contains
- the client-side buffer.
- */
-void CAuthServer::PluginsL(const RMessage2& aMessage)
- {
- FilterPluginsL(aMessage, &CAuthServer::FilterAllPlugins);
- }
-
-
-/**
- Predicate function used by PluginsL.. This accepts all plugins.
-
- @return Always ETrue.
- @see PluginsL
- */
-TBool CAuthServer::FilterAllPlugins(const CAuthPluginInterface&)
- {
- return ETrue;
- }
-
-
-/**
- *
- * @param aMessage the message to process
- **/
-void CAuthServer::ActivePluginsL(const RMessage2& aMessage)
- {
- FilterPluginsL(aMessage, &CAuthServer::FilterActivePlugins);
- }
-
-
-/**
- * Indicates a plugin is active.
- *
- * @param aInterface the auth plugin interface to check
- * @return true if aInterface.IsActive()
- **/
-TBool CAuthServer::FilterActivePlugins(const CAuthPluginInterface& aInterface)
- {
- return aInterface.IsActive();
- }
-
-
-/**
- Build an array which containing plugin descriptions
- for each plugin which is available and has the type
- supplied by the client.
-
- @param aMessage Client message. This contains
- the plugin type and points to the
- client-side buffer.
- */
-void CAuthServer::PluginsByTypeL(const RMessage2& aMessage)
- {
- iFilterType = static_cast<TAuthPluginType>(aMessage.Int1());
- FilterPluginsL(aMessage, &CAuthServer::FilterPluginsByType);
- }
-
-
-/**
- Predicate which checks whether the supplied description should
- be included in the result list.
-
- The type to filter on is stored as a member variable.
-
- @param aInterface Interface to check.
- @return Zero if interface's type does not match
- filter type, non-zero otherwise.
- @see PluginsByTypeL
- */
-TBool CAuthServer::FilterPluginsByType(const CAuthPluginInterface& aInterface)
- {
- return (aInterface.Type() == iFilterType);
- }
-
-
-/**
- Build an array which contains plugin descriptions
- for each plugin which has the supplied training status,
- and write that array into the caller's space.
-
- @param aMessage Client message contains the status
- to filter on.
- */
-void CAuthServer::PluginsByTrainingL(const RMessage2& aMessage)
- {
- iFilterTraining = static_cast<TAuthTrainingStatus>(aMessage.Int1());
- FilterPluginsL(aMessage, &CAuthServer::FilterPluginsByTraining);
- }
-
-
-/**
- Predicate checks if the supplied interface describes
- a plugin with the required training status.
-
- @param aInterface Interface to check.
- @return Zero if interface's training status
- does not match the filter status;
- non-zero otherwise.
- @see PluginsByTrainingL
- */
-TBool
-CAuthServer::FilterPluginsByTraining(const CAuthPluginInterface& aInterface)
- {
- // training status is stored in the db, not in the ECOM interface.
- // If this function returns non-zero, the same request will be made
- // on the DB to get the status again to construct the description.
- // This is suboptimal, and could be improved by special-casing the
- // training filter if required.
-
- TAuthTrainingStatus ts = EAuthUntrained;
- TRAPD(err, ( ts = iAuthDb2->PluginStatusL(aInterface.Id())));
- return err == KErrNone ? ts == iFilterTraining : EFalse;
- }
-
-
-/**
- Populate a client-side array with the set of identities.
-
- @param aMessage Client message which points to the
- user-side array.
- */
-void CAuthServer::IdentitiesL(const RMessage2& aMessage)
- {
- RArray<TIdentityId> ids;
- iAuthDb2->IdentitiesL(ids);
- CleanupClosePushL(ids);
- AuthServerUtil::SendDataArrayL(aMessage, ids, 0);
- CleanupStack::PopAndDestroy(&ids);
- }
-/**
- Retrieve the preferred plugin for the specified type
-
- @param aMessage Client message
- */
-void CAuthServer::PreferredTypePluginL(const RMessage2& aMessage)
- {
- TPluginId id =
- iAuthDb2->PreferredPluginL(static_cast<TAuthPluginType>(aMessage.Int0()));
-
- TPckg<TPluginId> idPckg(id);
- aMessage.WriteL(1, idPckg);
- aMessage.Complete(KErrNone);
- }
-
-/**
- Set the preferred plugin for the specified type
-
- @param aMessage Client message
- */
-void CAuthServer::SetPreferredTypePluginL(const RMessage2& aMessage)
- {
- TInt err = KErrArgument;
- TAuthPluginType pluginType = static_cast<TAuthPluginType>(aMessage.Int0());
- TPluginId pluginId = aMessage.Int1();
-
- if (iPluginMgr->PluginL(pluginId)->Type() == pluginType)
- {
- iAuthDb2->SetPreferredPluginL(pluginType,pluginId);
- err = KErrNone;
- }
- aMessage.Complete(err);
- }
-
-/**
- Retrieve description for a supplied identity.
-
- @param aMessage Client message which contains the
- identity and points to a client-side
- buffer, to which the description will
- be copied.
- */
-void CAuthServer::IdentityStringL(const RMessage2& aMessage)
- {
- HBufC* desc = iAuthDb2->DescriptionL(aMessage.Int1());
- CleanupStack::PushL(desc);
- aMessage.WriteL(EIpcArgument0, *desc);
- CleanupStack::PopAndDestroy(desc);
- aMessage.Complete(KErrNone);
- }
-
-/**
- Retrieve description & id for all identities.
-
- @param aMessage Client message which contains the
- identity and points to a client-side
- buffer, to which the description will
- be copied.
- */
-void CAuthServer::IdentitiesWithStringL(const RMessage2& aMessage)
- {
- RIdAndStringArray result;
-
- iAuthDb2->IdentitiesWithDescriptionL(result);
- CleanupClosePushL(result);
-
- AuthServerUtil::SendDataPointerArrayL(aMessage,result,0);
- CleanupStack::PopAndDestroy(&result);
- }
-
-/**
- *
- * @param aMessage the message to process
- **/
-void CAuthServer::SetIdentityStringL(const RMessage2& aMessage)
- {
- HBufC* str = HBufC::NewLC(aMessage.GetDesLengthL(1));
- TPtr strDes = str->Des();
- TInt err = aMessage.Read(1, strDes);
-
- if (err == KErrNone)
- {
- iAuthDb2->SetDescriptionL(aMessage.Int0(), *str);
- }
- CleanupStack::PopAndDestroy(str);
- aMessage.Complete(err);
- }
-
-
-
-/**
- Copies the authentication alias list obtained using
- ListAliasL() method to a client-side buffer .
-
- @param aMessage Client message which points to a client-side
- buffer, to which the authentication strength
- list will be copied.
- */
-
-void CAuthServer::ListAuthAliasesL(const RMessage2& aMessage)
- {
- RPointerArray<HBufC> aliasList;
- CleanupResetAndDestroyPushL(aliasList);
-
- //get the list of available authentication strengths from the cenrep file.
- iAuthRepository->ListAliasL(aliasList);
-
- AuthServerUtil::SendDataPointerArrayL(aMessage, aliasList, EIpcArgument0);
- CleanupStack::PopAndDestroy(&aliasList);
- }
-
-/**
- Resolves any alias occurrence in the expression to its corresponding
- value.
-
- @param aMessage Client message which contains the free form
- authentication expression and points to a
- client-side buffer, to which the string will
- be copied.
-
- */
-void CAuthServer::ResolveExpressionL(const RMessage2& aMessage)
- {
-
- // the auth strength passed by the client.
- TInt length = aMessage.GetDesLength(EIpcArgument1);
- HBufC* clientExpression = HBufC::NewLC(length);
- TPtr clientExprPtr(clientExpression->Des());
-
- aMessage.ReadL(EIpcArgument1, clientExprPtr);
-
- RBuf resultantString;
- CleanupClosePushL(resultantString);
-
- resultantString.CreateL(KDefaultBufferSize/2);
-
- // get the alias list
- RPointerArray<HBufC> aliasList;
- CleanupResetAndDestroyPushL(aliasList);
-
- //get the list of available authentication strength from the cenrep file.
- iAuthRepository->ListAliasL(aliasList);
-
-
- // parse the client side expression to see whether there
- // are any alias, if present process them accordingly.
- TLex input(clientExprPtr);
-
- // append the open bracket first so that the entire expression is within brackets.
- resultantString.Append(KOpenBracket);
-
- for(TPtrC token = input.NextToken(); token.Size() > 0; token.Set(input.NextToken()))
- {
-
- if( token.CompareF(KOpenBracket) == 0 ||
- token.CompareF(KCloseBracket) == 0 ||
- token.CompareF(KAuthOpAnd) == 0 ||
- token.CompareF(KAuthOpOr) == 0
- )
- {
- int reqdBufferLength = resultantString.Length() + token.Length();
-
- if(resultantString.MaxLength() < reqdBufferLength)
- {
- if(resultantString.MaxLength() == 0)
- {
- resultantString.Close();
- }
- resultantString.ReAllocL(reqdBufferLength);
- }
-
- resultantString.Append(token);
- }
- else if(token.CompareF(KAuthBiometric) == 0 ||
- token.CompareF(KAuthDefault) == 0 ||
- token.CompareF(KAuthKnowledge) == 0 ||
- token.CompareF(KAuthToken) == 0 ||
- token.CompareF(KAuthPerformance) == 0 )
- {
- RBuf tokenType;
- CleanupClosePushL(tokenType);
- TokenizeStringL(token, tokenType);
- int reqdBufferLength = resultantString.Length() + tokenType.Length();
- if(resultantString.MaxLength() < reqdBufferLength)
- {
- if(resultantString.MaxLength() == 0)
- {
- resultantString.Close();
- }
- resultantString.ReAllocL(reqdBufferLength);
- }
-
- resultantString.Append(tokenType);
- CleanupStack::PopAndDestroy(&tokenType);
- }
- else
- {
- // should not be a number
- TInt32 val = 0;
- TLex value(token);
- if(value.Val(val) == KErrNone)
- {
- RBuf tokenPluginId;
- CleanupClosePushL(tokenPluginId);
- TokenizeStringL(token, tokenPluginId);
- int reqdBufferLength = resultantString.Length() + tokenPluginId.Length();
- if(resultantString.MaxLength() < reqdBufferLength)
- {
- if(resultantString.MaxLength() == 0)
- {
- resultantString.Close();
- }
- resultantString.ReAllocL(reqdBufferLength);
- }
- resultantString.Append(tokenPluginId);
- CleanupStack::PopAndDestroy(&tokenPluginId);
- continue;
- }
-
- RBuf aliasString;
- CleanupClosePushL(aliasString);
-
- // this is a alias value which should be processed
- ResolveAliasL(token, aliasList, aliasString);
- int reqdBufferLength = resultantString.Length() + aliasString.Length();
- if(resultantString.MaxLength() < reqdBufferLength)
- {
- if(resultantString.MaxLength() == 0)
- {
- resultantString.Close();
- }
- resultantString.ReAllocL(reqdBufferLength);
- }
- resultantString.Append(aliasString);
- CleanupStack::PopAndDestroy(&aliasString);
- }
- }
-
- int reqdBufferLength = resultantString.Length() + KCloseBracket().Length();
-
- if(resultantString.MaxLength() < reqdBufferLength)
- {
- if(resultantString.MaxLength() == 0)
- {
- resultantString.Close();
- }
- resultantString.ReAllocL(reqdBufferLength);
- }
-
- // append the close bracket in the end so that the entire expression is within brackets.
- resultantString.Append(KCloseBracket);
-
- //see if we have enough space on the client.
- length = resultantString.Length();
- if(aMessage.GetDesMaxLengthL(EIpcArgument0) < length)
- {
- TPckg<TInt> lenPckg(length);
- aMessage.WriteL(EIpcArgument0, lenPckg);
- aMessage.Complete(KErrOverflow);
- }
-
- aMessage.WriteL(EIpcArgument0, resultantString);
- CleanupStack::PopAndDestroy(3, clientExpression); //aliasList, resultantString.
- aMessage.Complete(KErrNone);
- }
-
-/**
- Inserts space in between operators and inserts brackets for as
- expression
-
- @param aStringToBeProcessed string to be tokenized.
- @param aResultantString would contain the final tokenized
- string
- */
-
-void CAuthServer::TokenizeStringL( const TDesC& aStringToBeProcessed, RBuf& aResultantString )
- {
- TInt newLength = aStringToBeProcessed.Length() + 2;
- HBufC* resultantBuffer = HBufC::NewLC(newLength);
- TPtr resultantBufPtr(resultantBuffer->Des());
- resultantBufPtr.Append(KOpenBracket);
- resultantBufPtr.Append(aStringToBeProcessed);
- TInt index = resultantBufPtr.Length();
- resultantBufPtr.Append(KCloseBracket);
-
- CAuthExpressionImpl::InsertSpaceBetweenOperatorsL(*resultantBuffer, aResultantString);
- CleanupStack::PopAndDestroy(resultantBuffer);
-
- }
-
-/**
- Retrieves the alias string corresponding to the
- supplied authentication strength.
-
- @param aMessage Client message which contains the
- authentication strength and points to a
- client-side buffer, to which the alais
- string will be copied.
-
- */
-
-void CAuthServer::ResolveAliasL(const TDesC& aAliasName,
- RPointerArray<HBufC>& aAliasList,
- RBuf& aResultantString)
- {
- HBufC* aliasString = HBufC::NewLC(KDefaultBufferSize/2);
- TPtr aliasStringPtr(aliasString->Des());
-
- TBool aliasFound = EFalse;
-
- // find a match for the client supplied alias from the aliasList.
- for(TInt i = 0; i < aAliasList.Count(); ++i)
- {
- if(aAliasName.CompareF(*aAliasList[i]) != 0)
- {
- continue;
- }
-
- aliasFound = ETrue;
- // retrieve the alias string corresponding to a given authentication strength.
- iAuthRepository->GetAliasDefinitionL(i, aliasStringPtr);
- if(aliasStringPtr.Length() == 0)
- {
- User::Leave(KErrAuthStrengthAliasNotDefined);
- }
-
- // enclose the alias string within brackets.This would facilitate easy evaluation
- // of the alias string expression.
- TInt newLength = aliasStringPtr.Length() + 2;
- if(newLength > aliasStringPtr.MaxLength())
- {
- aliasString->ReAllocL(newLength);
- }
-
- aliasStringPtr.Insert(0, KOpenBracket);
- TInt index = aliasStringPtr.Length();
- aliasStringPtr.Insert(index, KCloseBracket);
-
- // tokenize aliasString, to facilitate parsing using TLex.
- CAuthExpressionImpl::InsertSpaceBetweenOperatorsL(*aliasString, aResultantString);
-
- if(aResultantString.Length() > aliasStringPtr.MaxLength())
- {
- aliasString = aliasString->ReAllocL(aResultantString.Length());
- }
-
- aliasStringPtr.Copy(aResultantString);
- aResultantString.Close();
-
- // aliasString contains an alias, so process it until we end up
- // with an expression containing plugin Id or plugin Type or a combination of both.
- ProcessAliasStringL(aAliasList, *aliasString, aResultantString);
-
- // ensure that the aliasString processing doesn't end in an infinite loop.
- // In case it does , leave with KErrAuthServInvalidAliasStringExpression.
- // For instance : fast = (medium & weak), medium = fast i.e
- // medium = (medium & weak).
-
- if(aResultantString.FindC(aAliasName) != KErrNotFound)
- {
- User::Leave(KErrAuthServInvalidAliasStringExpression);
- }
-
- TBool found = CheckForAliasInAliasString(aAliasList, aResultantString);
- // 'resultantAliasString' may inturn contain an alias.So loop through the ProcessAliasStringL,
- // until we end up with an alias string containing only plugin Id,plugin Type or a combination of both.
- while(found)
- {
- for(TInt j = 0; j < aAliasList.Count(); ++j)
- {
- if(aResultantString.FindC(*aAliasList[j]) != KErrNotFound)
- {
- if(aResultantString.Length() > aliasStringPtr.MaxLength())
- {
- aliasString->ReAllocL(aResultantString.Length());
- }
-
- aliasStringPtr.Copy(aResultantString);
- aResultantString.Close();
-
- CAuthExpressionImpl::InsertSpaceBetweenOperatorsL(*aliasString, aResultantString);
- if(aResultantString.Length() > aliasStringPtr.MaxLength())
- {
- aliasString->ReAllocL(aResultantString.Length());
- }
-
- aliasStringPtr.Copy(aResultantString);
- aResultantString.Close();
-
- ProcessAliasStringL(aAliasList, *aliasString, aResultantString);
- // ensure that the aliasString processing doesn't end in an infinite loop.
- // In case it does , leave with KErrArgument.
- // For instance : fast = (medium & weak), medium = fast i.e
- // medium = (medium & weak).
- if(aResultantString.FindC(aAliasName) != KErrNotFound)
- {
- User::Leave(KErrAuthServInvalidAliasStringExpression);
- }
- break;
- }
- }
-
- // check if 'resultantExpr' still contains an alias.
- found = CheckForAliasInAliasString(aAliasList, aResultantString);
-
- }
-
- break;
- }
-
- CleanupStack::PopAndDestroy(aliasString);
-
- //if the client supplied alias is not in the alias list, leave.
- if(!aliasFound)
- {
- User::Leave(KErrUnknownAuthStrengthAlias);
- }
-
- }
-
-// Resets the training data for the supplied identity.
-//
-// @param aMessage Client message which contains the details of
-// identity and plugins for doing the reset
-void CAuthServer::ResetIdentityL(TInt aFunction, const RMessage2& aMessage)
- {
- // Check if either an authentication or a training is going on
- if (ServerBusy())
- {
- aMessage.Complete(KErrServerBusy);
- return;
- }
-
- // For reset by type only EAuthKnowledge type is supported
- if (aFunction == EResetIdentityByType)
- {
- TAuthPluginType pluginType = static_cast<TAuthPluginType>(aMessage.Int1());
- if (pluginType != EAuthKnowledge)
- {
- aMessage.Complete(KErrAuthServResetMayLoseIdentity);
- return;
- }
- }
-
- // Get the list of trained plugins for this identity
- TIdentityId identityId = static_cast<TIdentityId>(aMessage.Int0());
- RArray<TPluginId> trainedPluginIdList;
- CleanupClosePushL(trainedPluginIdList);
- iAuthDb2->TrainedPluginsListL(identityId, trainedPluginIdList);
-
- // Ensure at least one plugin knows identity
- TInt numTrained = trainedPluginIdList.Count();
- if (numTrained < 1)
- {
- CleanupStack::PopAndDestroy(&trainedPluginIdList);
- aMessage.Complete(KErrAuthServIdentityNotFound);
- return;
- }
-
- // Try and ensure that after reset at least one plugin has an identity trained
- // Since all the trained plugins for the identity are being reset make sure
- // at least one of them is of the knowledge type to be reasonably sure it registers
- // the new identity data
- TBool knowledgePluginFound = EFalse;
- for (TInt index = 0; index < numTrained; ++index)
- {
- TPluginId pluginId = trainedPluginIdList[index];
- CAuthPluginInterface* plugin = iPluginMgr->PluginL(pluginId);
- if (plugin->Type() == EAuthKnowledge)
- {
- knowledgePluginFound = ETrue;
- break;
- }
- }
- if (!knowledgePluginFound)
- {
- CleanupStack::PopAndDestroy(&trainedPluginIdList);
- aMessage.Complete(KErrAuthServResetMayLoseIdentity);
- return;
- }
-
- // Get the registration data
- HBufC* regData = NULL;
- TInt ipcArg = (aFunction == EResetIdentity) ? EIpcArgument1:EIpcArgument2;
- regData = HBufC::NewLC(aMessage.GetDesLengthL(ipcArg));
- TPtr regPtr = regData->Des();
- aMessage.ReadL(ipcArg, regPtr);
-
- // Finally start the reset process
- // Generate a new protection key
- CProtectionKey* protKey = CProtectionKey::NewLC(iKeySize);
- TInt lastErr = KErrNone;
- TBool oneSuccess = EFalse; // To keep track if at least one reset succeeded
- for (TInt index = 0; index < numTrained; ++index)
- {
- TPluginId pluginId = trainedPluginIdList[index];
- CAuthPluginInterface* plugin = iPluginMgr->PluginL(pluginId);
- HBufC8* result = NULL;
- TInt err = KErrNone;
- // For reset by type the registration data needs to be specified only for the plugins of specified type
- // and this restricted to knowledge type only
- if ((aFunction == EResetIdentity) ||
- ((aFunction == EResetIdentityByType) && (plugin->Type() == EAuthKnowledge)))
- {
- err = plugin->Reset(identityId, *regData, result);
- }
- else
- {
- err = plugin->Reset(identityId, KNullDesC, result);
- }
- if (err == KErrNone && result)
- {
- oneSuccess = ETrue;
- // Use the plugin data to generate transient key and then encrypt the protection key
- // using the transient key. A plugin may not return data if it does not use the supplied
- // registration information
- CleanupStack::PushL(result);
- CTransientKeyInfo* keyInfo = CreateKeyInfoLC(pluginId, *result, *protKey);
- // Replace the trained information in the db
- iAuthDb2->SetTrainedPluginL(identityId, pluginId, *keyInfo);
- CleanupStack::PopAndDestroy(2, result); // keyInfo
- }
- else if (err == KErrNone)
- {
- oneSuccess = ETrue;
- // Remove the entry in the auth db for the plugin
- // Ignore errors
- TRAP_IGNORE(iAuthDb2->RemoveTrainedPluginL(identityId, pluginId));
- }
- else
- {
- // Remember the last error
- lastErr = err;
- }
- }
-
- CleanupStack::PopAndDestroy(3, &trainedPluginIdList); // regData, protKey
-
- // If none of the plugins reset correctly then return the last error
- if (oneSuccess)
- {
- lastErr = KErrNone;
- }
-
- aMessage.Complete(lastErr);
- }
-
-// Resets the training data for the supplied identity.
-//
-// @param aMessage Client message which contains the details of
-// identity and plugins for doing the reset
-void CAuthServer::ResetIdentityByListL(const RMessage2& aMessage)
- {
- // Check if either an authentication or a training is going on
- if (ServerBusy())
- {
- aMessage.Complete(KErrServerBusy);
- return;
- }
-
- // Get the list of trained plugins for this identity
- TIdentityId identityId = static_cast<TIdentityId>(aMessage.Int0());
- RArray<TPluginId> trainedPluginIdList;
- CleanupClosePushL(trainedPluginIdList);
- iAuthDb2->TrainedPluginsListL(identityId, trainedPluginIdList);
-
- // Ensure at least one plugin knows identity
- TInt numTrained = trainedPluginIdList.Count();
- if (numTrained < 1)
- {
- CleanupStack::PopAndDestroy(&trainedPluginIdList);
- aMessage.Complete(KErrAuthServIdentityNotFound);
- return;
- }
-
- // Extract the array of plugin ids and their registration information
- RArray<TPluginId> pluginIdList;
- CleanupClosePushL(pluginIdList);
- HBufC8* buf = HBufC8::NewLC(aMessage.GetDesLengthL(EIpcArgument1));
- TPtr8 ptr = buf->Des();
- aMessage.ReadL(EIpcArgument1, ptr);
- RDesReadStream stream(*buf);
- CleanupClosePushL(stream);
- InternalizeArrayL(pluginIdList, stream);
- CleanupStack::PopAndDestroy(2, buf); // stream
-
- RPointerArray<HBufC> regInfoList;
- CleanupResetAndDestroyPushL(regInfoList);
- buf = HBufC8::NewLC(aMessage.GetDesLengthL(EIpcArgument2));
- ptr.Set(buf->Des());
- aMessage.ReadL(EIpcArgument2, ptr);
- stream.Open(*buf);
- CleanupClosePushL(stream);
- InternalizePointerArrayL(regInfoList, stream);
- CleanupStack::PopAndDestroy(2, buf); // stream
-
- // Sanity check
- if (pluginIdList.Count() != regInfoList.Count())
- {
- CleanupStack::PopAndDestroy(3, &trainedPluginIdList); // pluginIdList, regInfoList
- aMessage.Complete(KErrArgument);
- return;
- }
-
- // Prepare an array of TPluginResetDetails to aid during resetting
- RPointerArray<TPluginResetDetails> resetDetails;
- CleanupResetAndDestroyPushL(resetDetails);
-
- for (TInt index = 0; index < numTrained; ++index)
- {
- TPluginId pluginId = trainedPluginIdList[index];
- // Check if the trained plugin needs to be sent registration data
- TInt indexA = pluginIdList.Find(pluginId);
-
- TPluginResetDetails *resetDetailsEntry;
- if (indexA != KErrNotFound)
- {
- // Note: Ownership of the descriptor pointers remains with regInfoList
- resetDetailsEntry = new (ELeave) TPluginResetDetails(pluginId, *regInfoList[indexA]);
- }
- else
- {
- resetDetailsEntry = new (ELeave) TPluginResetDetails(pluginId, KNullDesC());
- }
- CleanupStack::PushL(resetDetailsEntry);
- resetDetails.AppendL(resetDetailsEntry);
- CleanupStack::Pop(resetDetailsEntry);
- }
-
- // Try and ensure that after reset at least one plugin has an identity trained
- // Since all the trained plugins for the identity are being reset make sure
- // at least one of them is of the knowledge type and is being passed the registration data
- // to be reasonably sure it registers the new identity data
- TBool knowledgePluginFound = EFalse;
- for (TInt index = 0; index < numTrained; ++index)
- {
- TPluginId pluginId = resetDetails[index]->PluginId();
- CAuthPluginInterface* plugin = iPluginMgr->PluginL(pluginId);
- if ((plugin->Type() == EAuthKnowledge) && (resetDetails[index]->RegistrationData() != KNullDesC))
- {
- knowledgePluginFound = ETrue;
- break;
- }
- }
- if (!knowledgePluginFound)
- {
- CleanupStack::PopAndDestroy(4, &trainedPluginIdList); // pluginIdList, regInfoList, resetDetails
- aMessage.Complete(KErrAuthServResetMayLoseIdentity);
- return;
- }
-
- // Finally start the reset process
- // Generate a new protection key
- CProtectionKey* protKey = CProtectionKey::NewLC(iKeySize);
- TInt lastErr = KErrNone;
- TBool oneSuccess = EFalse; // To keep track if at least one reset succeeded
- for (TInt index = 0; index < numTrained; ++index)
- {
- TPluginResetDetails* reset = resetDetails[index];
- TPluginId pluginId = reset->PluginId();
- CAuthPluginInterface* plugin = iPluginMgr->PluginL(pluginId);
- HBufC8* result = NULL;
- TInt err = plugin->Reset(identityId, reset->RegistrationData(), result);
- if (err == KErrNone && result)
- {
- oneSuccess = ETrue;
- // Use the plugin data to generate transient key and then encrypt the protection key
- // using the transient key. A plugin may not return data if it does not use the supplied
- // registration information
- CleanupStack::PushL(result);
- CTransientKeyInfo* keyInfo = CreateKeyInfoLC(pluginId, *result, *protKey);
- // Replace the trained information in the db
- iAuthDb2->SetTrainedPluginL(identityId, pluginId, *keyInfo);
- CleanupStack::PopAndDestroy(2, result); // keyInfo
- }
- else if (err == KErrNone)
- {
- oneSuccess = ETrue;
- // Remove the entry in the auth db for the plugin
- // Ignore errors
- TRAP_IGNORE(iAuthDb2->RemoveTrainedPluginL(identityId, pluginId));
- }
- else
- {
- // Remember the last error
- lastErr = err;
- }
- }
-
- CleanupStack::PopAndDestroy(5, &trainedPluginIdList); // pluginIdList, regInfoList, resetDetails, protKey
-
- // If none of the plugins reset correctly then return the last error
- if (oneSuccess)
- {
- lastErr = KErrNone;
- }
-
- aMessage.Complete(lastErr);
- }
-
-// Generates and returns transient key info using the supplied plugin data and the protection key
-CTransientKeyInfo* CAuthServer::CreateKeyInfoLC(TPluginId aPluginId, const TDesC8& aPluginData, const CProtectionKey& aProtKey)
- {
- CTransientKeyInfo* keyInfo = CTransientKeyInfo::NewLC(aPluginId);
-
- CTransientKey* transKey = keyInfo->CreateTransientKeyL(aPluginData);
- CleanupStack::PushL(transKey);
-
- CEncryptedProtectionKey* encProtKey = transKey->EncryptL(aProtKey);
- CleanupStack::PushL(encProtKey);
-
- keyInfo->SetEncryptedProtectionKeyL(encProtKey);
- CleanupStack::Pop(encProtKey);
- CleanupStack::PopAndDestroy(transKey);
- return keyInfo;
- }
-
-/**
- Checks if the value of strength alias inturn contains an alias.
-
- @param aAuthAliasList an array of authentication strengths as obtained from
- authserver cenrep file.
- @param aAliasString an alias string containing the alias to be searched for.
-
- */
-
-TBool CAuthServer::CheckForAliasInAliasString(RPointerArray<HBufC>& aAuthAliasList, const TDes& aAliasString)
- {
- // find a match for the client supplied alias from the aliasList.
- for(TInt i = 0; i < aAuthAliasList.Count(); ++i)
- {
- TInt found = aAliasString.FindC(*aAuthAliasList[i]);
- if(found > 0)
- {
- return ETrue;
- }
- }
-
- return EFalse;
- }
-
-/**
- Processes an alias string, This method is called recursively until we end
- up with an alias string containing only pluginIds and pluginTypes or a
- combination of both.
-
-
- @param aAliasList an array of authentication strengths as obtained from
- authserver cenrep file.
- @param aAliasStringToBeProcessed an alias string to be processed.
- @param aResultantAliasString Buffer to be populated with an alias string resulting from processing aAliasStringToBeProcessed.
-
- */
-
-void CAuthServer::ProcessAliasStringL(RPointerArray<HBufC>& aAliasList, const TDesC& aAliasStringToBeProcessed, RBuf& aResultantAliasString)
- {
- TBuf<KDefaultBufferSize> exprString;
- HBufC* aliasString = HBufC::NewLC(KMaxBufferSize);
- TPtr aliasStringPtr(aliasString->Des());
-
- TLex input(aAliasStringToBeProcessed);
- _LIT(KDelimiter, " ");
- TBool aliasFoundInString = EFalse;
-
- //iterate through the obtained expression to verify if it contains any strength subsets.
- for(TPtrC token = input.NextToken(); token.Size() > 0; token.Set(input.NextToken()))
- {
- TInt resultingLen = 0;
- aliasFoundInString = EFalse;
- for(TInt i = 0; i < aAliasList.Count(); ++i)
- {
- if(token.FindC(*aAliasList[i]) != KErrNotFound)
- {
- aliasFoundInString = ETrue;
- iAuthRepository->GetAliasDefinitionL(i, exprString);
- if(exprString.Length() == 0)
- {
- User::Leave(KErrAuthStrengthAliasNotDefined);
- }
-
- // resulting length obtained by appending exprString ,KCloseBracket and KOpenBracket to aliasString.
- resultingLen = (exprString.Length() + 2);
- if(resultingLen > KMaxBufferSize)
- {
- aliasString->ReAllocL(resultingLen);
- }
-
- aliasStringPtr.Append(KOpenBracket);
- aliasStringPtr.Append(exprString);
- aliasStringPtr.Append(KCloseBracket);
- break;
- }
- }
-
- //if the token is an operator or a plugin type or pluginId, append it to aResultantExpr.
- if(!aliasFoundInString)
- {
- // resulting length obtained by appending token and delimiter to be aliasString.
- resultingLen = (exprString.Length() + token.Length() + 1);
- if(resultingLen > KMaxBufferSize)
- {
- aliasString->ReAllocL(resultingLen);
- }
-
- aliasStringPtr.Append(token);
- aliasStringPtr.Append(KDelimiter);
- }
- }
-
- CleanupStack::Pop(aliasString);
- aResultantAliasString.Assign(aliasString);
-
- }
-
-
-/**
- *
- * @param aMessage the message to process
- **/
-void CAuthServer::RegisterIdentityL(const RMessage2& aMessage)
- {
- if (ServerBusy())
- {
- aMessage.Complete(KErrServerBusy);
- return;
- }
-
- TIdentityId id = 0;
- TPckg<TIdentityId> idPkg(id);
- TRandom::RandomL(idPkg);
-
- CProtectionKey* key = CProtectionKey::NewL(iKeySize);
-
- iTrainingMgr->RegisterIdentityL(aMessage, id, *key);
- }
-
-/**
- *
- * @param aMessage the message to process
- **/
-void CAuthServer::CancelL(const RMessage2& aMessage)
- {
- TInt err = KErrNone;
-
- if (iTrainingMgr->IsBusy())
- {
- iTrainingMgr->Cancel();
- }
- else if (iAuthTransaction != 0)
- {
- if (aMessage.SecureId() == iAuthTransaction->Message().SecureId())
- {
- iEvaluator->Cancel();
- }
- else
- {
- // Shouldn't come here since we don't support share-able sessions
- err = KErrInUse;
- }
- }
- aMessage.Complete(err);
- }
-
-
-/**
- Remove the supplied identity from the database.
-
- @param aMessage Client which contains identity
- to remove.
- */
-void CAuthServer::RemoveIdentityL(const RMessage2& aMessage)
- {
- TInt result = KErrNone;
-
- //The identity to be removed
- TIdentityId id = static_cast<TIdentityId>(aMessage.Int0());
-
- //Check if the identity to be removed is not the default identity.
- TIdentityId defaultIdentity = iAuthDb2->DefaultIdentityL();
-
- if(defaultIdentity != id)
- {
- iAuthDb2->RemoveIdentityL(id);
-
- if (iLastIdentity && iLastIdentity->Id() == id)
- {
- delete iLastIdentity;
- iLastIdentity = 0;
- iLastAuthTime = 0L;
- }
- iPluginMgr->ForgetIdentityL(id);
- }
- else
- {
- result = KErrAuthServCanNotRemoveDefaultIdentity;
- }
- aMessage.Complete(result);
- }
-
-/**
- * @return true if either the training mgr or authentication transaction
- * is busy
- **/
-TBool CAuthServer::ServerBusy()
- {
- return iTrainingMgr->IsBusy() || iAuthTransaction != 0;
- }
-
-
-/**
- *
- * @param aMessage the message to process
- **/
-void CAuthServer::TrainPluginL(const RMessage2& aMessage)
- {
- if (ServerBusy())
- {
- aMessage.Complete(KErrServerBusy);
- return;
- }
-
- if (iLastIdentity == 0 || iLastIdentity->Id() != aMessage.Int0())
- {
- // we need a cached identity to get the protection key
- aMessage.Complete(KErrAuthServAuthenticationRequired);
- return;
- }
-
- TIdentityId retrainId = aMessage.Int0();
-
- //The default identity cannot be retrained.
- TIdentityId defaultIdentity = iAuthDb2->DefaultIdentityL();
-
- if(defaultIdentity == retrainId)
- {
- aMessage.Complete(KErrNotSupported);
- return;
- }
-
- HBufC8* data = HBufC8::NewLC(iLastIdentity->Key().KeyData().Size());
- *data = iLastIdentity->Key().KeyData();
-
- CProtectionKey* key = CProtectionKey::NewL(data);
- CleanupStack::Pop(data);
-
- iTrainingMgr->TrainPluginL(aMessage, *key);
-
- }
-
-
-
-/**
- * Remove the supplied identity, plugin pair from the
- * authentication database.
- *
- * @param aMessage Client message which contains the
- * identity and the plugin.
- **/
-void CAuthServer::ForgetPluginL(const RMessage2& aMessage)
- {
- if (ServerBusy())
- {
- aMessage.Complete(KErrServerBusy);
- return;
- }
-
- TIdentityId id = static_cast<TIdentityId>(aMessage.Int0());
- TPluginId plugin = static_cast<TPluginId>(aMessage.Int1());
- TInt err = KErrNone;
-
- TInt numTrained = iAuthDb2->NumTrainedPluginsL(id);
-
- switch (numTrained)
- {
- case 0:
- err = KErrAuthServNoSuchIdentity;
- break;
- case 1:
- err = KErrAuthServCanNotRemoveLastPlugin;
- break;
- default:
- iAuthDb2->RemoveTrainedPluginL(id, plugin);
- iPluginMgr->PluginL(plugin)->Forget(id);
- break;
- }
-
- aMessage.Complete(err);
- }
-
-
-void CAuthServer::EvaluateL(TPluginId aPluginId,
- TIdentityId& aIdentityId,
- CAuthExpressionImpl::TType aType,
- TRequestStatus& aStatus)
- {
-
- if(aPluginId == 0 && aType == CAuthExpressionImpl::ENull)
- {
- aPluginId = iAuthRepository->DefaultPluginL();
- }
-
- CAuthPluginInterface* plugin = iPluginMgr->PluginL(aPluginId);
-
- if (plugin != 0)
- {
- const HBufC* clientMessage = iAuthTransaction->ClientMessage();
-
- HBufC8*& data = iAuthTransaction->AddPluginL(aPluginId, aIdentityId);
-
- if (plugin->IsActive())
- {
- plugin->Identify(aIdentityId, *clientMessage, data, aStatus);
- }
-
- else
- {
- User::Leave(KErrAuthServPluginNotActive);
- }
- }
- }
-/**
- * @see MEvaluatorPluginInterface::Evaluate
- **/
-void CAuthServer::Evaluate(TPluginId aPluginId,
- TIdentityId& aIdentityId,
- CAuthExpressionImpl::TType aType,
- TRequestStatus& aStatus)
- {
- TRAPD(err, EvaluateL(aPluginId, aIdentityId, aType, aStatus));
-
- if (err != KErrNone)
- {
- TRequestStatus* status = &aStatus;
- User::RequestComplete(status, err);
- }
- }
-
-/**
- * Retrieve the preferred plugin for the supplied type and
- * get an identity from it.
- * @see MEvaluatorPluginInterface::Evaluate
- *
- **/
-void CAuthServer::Evaluate(TAuthPluginType aPluginType,
- TIdentityId& aIdentityId,
- CAuthExpressionImpl::TType aType,
- TRequestStatus& aStatus)
- {
- TPluginId id = 0;
- TRAPD(r, id = iAuthDb2->PreferredPluginL(aPluginType));
- if (r == KErrNone)
- {
- Evaluate(id, aIdentityId, aType, aStatus);
- }
- else
- {
- // Pass back error (can happen if a user preference hasn't been defined)
- aStatus = KRequestPending;
- TRequestStatus* rs = &aStatus;
- User::RequestComplete(rs, r);
- }
- }
-
-/**
- * Completes the message and sends the id on it's way back to the client
- **/
-void CAuthServer::CompleteAuthenticationL(const RMessagePtr2& aMessage,
- CIdentity* aId)
- {
- // write to client
- HBufC8* idBuff = HBufC8::NewLC(KDefaultBufferSize);
- TPtr8 idPtr = idBuff->Des();
- RDesWriteStream writeStream(idPtr);
- writeStream << *aId;
- writeStream.CommitL();
-
- TInt clientBuffSize = aMessage.GetDesMaxLength(2);
-
- if (clientBuffSize >= idBuff->Size())
- {
- aMessage.Write(2, *idBuff);
- }
- else
- {
- User::Leave(KErrUnderflow);
- }
-
- CleanupStack::PopAndDestroy(idBuff);
-
- aMessage.Complete(KErrNone);
- }
-
-/**
- * @see MEvaluatorClientInterface::EvaluationSucceeded
- **/
-void CAuthServer::EvaluationSucceeded(TIdentityId aIdentityId)
- {
-
- TRAPD(err, EvaluationSucceededL(aIdentityId));
-
- switch(err)
- {
- case KErrNone:
- break;
- default:
- EvaluationFailed(err);
- }
- }
-
-
-/**
- * The full, leaving, implementation of EvaluationSucceeded (which is a trap
- * harness).
- *
- * @param aIdentityId the identity discovered
- **/
-void CAuthServer::EvaluationSucceededL(TIdentityId aIdentityId)
- {
-
- CAuthTransaction::RResultArray& results = iAuthTransaction->Results();
-
- HBufC8* data = 0;
- TPluginId plugin = KUnknownPluginId;
-
- TLastAuth lastAuth;
- lastAuth.iId = aIdentityId;
-
- for (TInt i = 0 ; i < results.Count() ; ++i)
- {
- if (aIdentityId == *results[i]->iId)
- {
- plugin = results[i]->iPlugin;
- data = results[i]->iData;
- UpdateAuthL(lastAuth, plugin);
- }
- }
-
- CProtectionKey* key = 0;
-
- // Ensure that the ID and DATA are valid.
- if (( aIdentityId != KUnknownIdentity ) && ( data != 0 ))
- {
- // get the protection key
- CTransientKeyInfo* keyInfo = iAuthDb2->KeyInfoL(aIdentityId, plugin);
- CleanupStack::PushL(keyInfo);
-
- CTransientKey* transKey = keyInfo->CreateTransientKeyL(*data);
- CleanupStack::PushL(transKey);
-
- key = transKey->DecryptL(keyInfo->EncryptedKey());
- CleanupStack::PopAndDestroy(2,keyInfo);
- CleanupStack::PushL(key);
-
- // convert to a client key if we need to
- if (iAuthTransaction->ClientKey())
- {
- CProtectionKey* key2 = key->ClientKeyL(iAuthTransaction->ClientSid());
-
- CleanupStack::PopAndDestroy(key);
- key = key2;
- CleanupStack::PushL(key);
- }
- }
- else
- {
- // create a blank key
- key = CProtectionKey::NewLC(0);
-
- // clear the cached identity
- delete iLastIdentity;
- iLastIdentity = 0;
- iLastAuthTime = 0L;
- }
-
- HBufC* str =
- StringOrNullLC(iAuthTransaction->WithString(), aIdentityId);
-
- // create the client identity object
- CIdentity* identity = CIdentity::NewL(aIdentityId, key, str);
- CleanupStack::Pop(2, key);
- CleanupStack::PushL(identity);
-
- CompleteAuthenticationL(iAuthTransaction->Message(),
- identity);
-
- if (aIdentityId != KUnknownIdentity)
- {
- TIdentityId oldId = iLastIdentity ? iLastIdentity->Id() : 0;
-
- // cache the latest id
- delete iLastIdentity;
- iLastIdentity = identity;
- if(iLastAuthTime.UniversalTimeSecure() == KErrNoSecureTime)
- {
- // Fall back to nonsecure time.
- iLastAuthTime.UniversalTime();
- }
- // and publish it
- lastAuth.iAuthTime = iLastAuthTime;
- TPckg<TLastAuth> authPckg(lastAuth);
- User::LeaveIfError(iAuthProperty.Set(authPckg));
-
- // if the identity has changed publish that fact
- if (oldId != aIdentityId)
- {
- User::LeaveIfError(iAuthEventProperty.Set(aIdentityId));
- }
-
- CleanupStack::Pop(identity);
- }
- else
- {
- CleanupStack::PopAndDestroy(identity);
- }
- delete iAuthTransaction;
- iAuthTransaction = 0;
- }
-
-/**
- * Tells the authserver to cancel the current evaluation (i.e. call to
- * the plugin)
- *
- * @see MEvaluatorPluginInterface::Evaluate
- *
- **/
-void CAuthServer::CancelEvaluate()
- {
- if (iAuthTransaction)
- {
- TPluginId pluginId = iAuthTransaction->LastPluginId();
- CAuthPluginInterface* plugin = 0;
- TRAPD(err, (plugin = iPluginMgr->PluginL(pluginId)));
- if (err == KErrNone)
- {
- plugin->Cancel();
- }
- }
- }
-
-
-/**
- * @see MEvaluatorClientInterface::EvaluationFailed
- **/
-void CAuthServer::EvaluationFailed(TInt aReason)
- {
- iAuthTransaction->Message().Complete(aReason);
- delete iAuthTransaction;
- iAuthTransaction = 0;
- // there's nothing we can do here. Panic?
- TRAP_IGNORE(ClearPropertiesL());
- }
-
-
-void CAuthServer::UpdateAuthL(TLastAuth& aAuth, TPluginId aPlugin)
- {
- CAuthPluginInterface* plugin = iPluginMgr->PluginL(aPlugin);
-
- aAuth.iMaxCombinations =
- Max(aAuth.iMaxCombinations, plugin->MinEntropy());
- aAuth.iFalsePositiveRate =
- Max(aAuth.iFalsePositiveRate, plugin->FalsePositiveRate());
- aAuth.iFalseNegativeRate =
- Max(aAuth.iFalseNegativeRate, plugin->FalseNegativeRate());
- ++aAuth.iNumFactors;
- }
-
-
-/**
- * Free all the uncompressable memory before the
- * heap mark is set/reset to get the OOM tests to pass.
- **/
-void CAuthServer::FreeMemoryBeforeHeapMark()
- {
-#ifdef _DEBUG
-
- if(iTrainingMgr)
- {
- delete iTrainingMgr;
- iTrainingMgr = 0;
- }
-
- if(iPluginMgr)
- {
- delete iPluginMgr;
- iPluginMgr = 0;
- }
-
- if(iLastIdentity)
- {
- delete iLastIdentity;
- iLastIdentity = 0;
- }
-
- iAuthDb2->CloseDbFile();
-
- REComSession::FinalClose();
-
-#endif
- }
-
-
-/**
- * Recreate all the variables deleted after the heap mark has
- * been set/reset.
- **/
-void CAuthServer::SetupVariablesAfterHeapMarkEndL()
- {
-#ifdef _DEBUG
-
- //Opening Db file.
- TFileName dbName(KDbName);
- dbName[0] = RFs::GetSystemDriveChar();
- iAuthDb2->OpenDbFileL(iFs, dbName);
-
- //Creating plugin manager.
- if(!iPluginMgr)
- {
- iPluginMgr = CPluginMgr::NewL();
- }
-
- //Creating training manager.
- if(!iTrainingMgr)
- {
- iTrainingMgr = new (ELeave) CTrainingMgr(*iPluginMgr, *iAuthDb2, *iAuthRepository);
- }
-#endif
- }
-
-/**
- * Things to be done before the heap mark is set/reset
- * during OOM testing
- **/
-void CAuthServer::DoPreHeapMarkOrCheckL()
- {
-#ifdef _DEBUG
- FreeMemoryBeforeHeapMark();
-#endif
- }
-
-/**
- * Things to be done after the heap mark is set/reset
- * during OOM testing
- **/
-void CAuthServer::DoPostHeapMarkOrCheckL()
- {
-#ifdef _DEBUG
- SetupVariablesAfterHeapMarkEndL();
-#endif
- }
-