authenticationservices/authenticationserver/source/server/authserver.cpp
changeset 29 ece3df019add
equal deleted inserted replaced
19:cd501b96611d 29:ece3df019add
       
     1 /*
       
     2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 * CAuthServer implementation
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 /**
       
    21  @file 
       
    22 */
       
    23 
       
    24 #include <s32mem.h>
       
    25 #include <s32file.h>
       
    26 #include <ecom/ecom.h>
       
    27 #include <pbedata.h>
       
    28 #include <scs/cleanuputils.h>
       
    29 #include "authserver_impl.h"
       
    30 #include "authtransaction.h"
       
    31 #include "authserver/aspubsubdefs.h"
       
    32 #include "authserverutil.h"
       
    33 
       
    34 using namespace AuthServer;
       
    35 
       
    36 const TUint CAuthServer::iRangeCount = KPolicyRanges;
       
    37 
       
    38 const TInt CAuthServer::iRanges[KPolicyRanges] = 
       
    39 	{
       
    40 	0,
       
    41 	CScsServer::EBaseSession,
       
    42 	CScsServer::EBaseSession |ERequireNoCapabilities, 		   // accessible by all clients.
       
    43 	CScsServer::EBaseSession |ERequireReadUserData,		   	   // accessible by ReadUserData clients only.
       
    44 	CScsServer::EBaseSession |ERequireWriteUserData,	   	   // accessible by WriteUserData clients only.
       
    45 	CScsServer::EBaseSession |ERequireReadDeviceData, 	       // accessible by ReadDeviceData clients only.
       
    46 	CScsServer::EBaseSession |ERequireWriteDeviceData,         // accessible by WriteDeviceData clients only.
       
    47 	CScsServer::EBaseSession |ERequireTrustedUi,               // accessible by TrustedUi clients only.
       
    48 	CScsServer::EBaseSession |ERequireReadDeviceAndUserData,   // accessible by clients with both
       
    49 																// ReadUserData and ReadDeviceData.
       
    50 	CScsServer::EBaseSession |ERequireCustomCheck,		       // Require custom check.
       
    51 	CScsServer::EBaseSession |ELastService,
       
    52 	CScsServer::EBaseMustAllow     			                   // SCS Internal.
       
    53 	};
       
    54 
       
    55 const TUint8 CAuthServer::iElementsIndex[iRangeCount] = 
       
    56 	{
       
    57 	CPolicyServer::ENotSupported,
       
    58 	CPolicyServer::EAlwaysPass,
       
    59 	0,  // all clients can have access 
       
    60 	1,  // ReadUserData clients only
       
    61 	2,  // WriteUserData clients only
       
    62 	3,	// ReadDeviceData
       
    63 	4,  // WriteDeviceData
       
    64 	5,  // trusted ui
       
    65 	6,  // ReadUserData and ReadDeviceData
       
    66 	CPolicyServer::ECustomCheck,	// custom check
       
    67 	CPolicyServer::EAlwaysPass, 
       
    68 	CPolicyServer::EAlwaysPass, 
       
    69 	};
       
    70 
       
    71 const CPolicyServer::TPolicyElement CAuthServer::iPolicyElements[] = 
       
    72 	{
       
    73 	{_INIT_SECURITY_POLICY_C1(ECapability_None), CPolicyServer::EFailClient},
       
    74 	{_INIT_SECURITY_POLICY_C1(ECapabilityReadUserData), CPolicyServer::EFailClient},
       
    75 	{_INIT_SECURITY_POLICY_C1(ECapabilityWriteUserData), CPolicyServer::EFailClient},
       
    76 	{_INIT_SECURITY_POLICY_C1(ECapabilityReadDeviceData), CPolicyServer::EFailClient}, 
       
    77 	{_INIT_SECURITY_POLICY_C1(ECapabilityWriteDeviceData), CPolicyServer::EFailClient},
       
    78 	{_INIT_SECURITY_POLICY_C1(ECapabilityTrustedUI), CPolicyServer::EFailClient},
       
    79 	{_INIT_SECURITY_POLICY_C2(ECapabilityReadDeviceData, ECapabilityReadUserData), CPolicyServer::EFailClient},
       
    80 	};
       
    81 
       
    82 const CPolicyServer::TPolicy CAuthServer::iPolicy =
       
    83 	{
       
    84 		CPolicyServer::EAlwaysPass, // so that any client can connect	
       
    85 		iRangeCount,                                   
       
    86 		iRanges,
       
    87 		iElementsIndex,
       
    88 		iPolicyElements,
       
    89 	};
       
    90 
       
    91 _LIT_SECURITY_POLICY_S0(CAuthServer::iPropertyWritePolicy, KAuthServerSecureId.iUid);
       
    92 _LIT_SECURITY_POLICY_PASS(CAuthServer::iPropertyReadPolicy);
       
    93 
       
    94 
       
    95 inline CAuthServer::CAuthServer(CActive::TPriority aPriority)
       
    96 	:CScsServer(TVersion(1,0,0), iPolicy, aPriority)
       
    97 	{}
       
    98 	
       
    99 CAuthServer* CAuthServer::NewLC(CActive::TPriority aPriority)
       
   100 	{
       
   101 	CAuthServer* self = new(ELeave) CAuthServer(aPriority);
       
   102 	CleanupStack::PushL(self);
       
   103 	self->ConstructL();
       
   104 	return self;
       
   105 	}
       
   106 
       
   107 void CAuthServer::ConstructL()
       
   108     {
       
   109     // Delay starting of shutdown timer till we finish construction since
       
   110     // loading of ECOM plugins takes a while
       
   111     CScsServer::ConstructL(0);
       
   112     TInt r;
       
   113     StartL(KAuthServerName);
       
   114 	r = iFs.Connect();
       
   115     User::LeaveIfError(r);
       
   116     r = iFs.CreatePrivatePath(RFs::GetSystemDrive());
       
   117     User::LeaveIfError(r);
       
   118 
       
   119     // Retrieve the key size to be used for protection keys
       
   120 	CPBEncryptElement* pbee = CPBEncryptElement::NewLC(_L(""));
       
   121     iKeySize = pbee->EncryptionData().AuthData().Key().Size();
       
   122     CleanupStack::PopAndDestroy(pbee);
       
   123     iAuthRepository = CAuthRepository::NewL();
       
   124 	iAuthDb2 = CAuthDb2::NewL(iFs);
       
   125 	iPluginMgr  = CPluginMgr::NewL();
       
   126     iPluginObserver = CPluginObserver::NewL(*iPluginMgr);
       
   127     iEvaluator = CEvaluator::NewL(this,this);
       
   128     iTrainingMgr = new (ELeave) CTrainingMgr(*iPluginMgr, *iAuthDb2, *iAuthRepository);
       
   129 	TUid clientSid = {0};
       
   130 	iParams = CAuthParams::NewL(0,
       
   131 								EFalse,
       
   132 								clientSid,
       
   133 								EFalse,
       
   134 								KNullDesC());
       
   135     CreatePropertiesL();
       
   136 	FirstStartL();
       
   137 
       
   138 	// Construction complete, now start the shutdown timer
       
   139 	CScsServer::EnableShutdownTimerL(AuthServer::KDefaultShutdownDelay);
       
   140     }
       
   141     
       
   142     
       
   143 CPolicyServer::TCustomResult CAuthServer::CustomSecurityCheckL(const RMessage2& aMessage, 
       
   144 	TInt& /*aAction*/, TSecurityInfo& aMissing)
       
   145 	{
       
   146 	TInt KAuthParams = 1; 
       
   147 	TInt paramsLen = aMessage.GetDesLength(KAuthParams);
       
   148 	
       
   149 	if(paramsLen != KErrBadDescriptor)
       
   150 		{
       
   151 		//Create a buffer.
       
   152 		HBufC8* buffer = HBufC8::NewLC(paramsLen);
       
   153 		TPtr8 bufDes(buffer->Des());
       
   154 		aMessage.ReadL(EIpcArgument1, bufDes);
       
   155 			
       
   156 		//Internalize the params object.
       
   157 		RDesReadStream readStream(*buffer);
       
   158 		CleanupClosePushL(readStream);
       
   159 		iParams->InternalizeL(readStream);
       
   160 		CleanupStack::PopAndDestroy(2, buffer);
       
   161 		}
       
   162 
       
   163 	TBool clientKey = iParams->iClientKey;
       
   164 	TBool withString = iParams->iWithString;
       
   165 	TInt clientSid = iParams->iClientSid.iUid;
       
   166 		
       
   167 	if((!clientKey || withString || ((clientSid != aMessage.SecureId()) && clientSid != 0 )) && !(aMessage.HasCapability(ECapabilityReadUserData)))
       
   168 		{
       
   169 		// Missing ReadUserData capability.
       
   170 		aMissing.iCaps.Set(ECapabilityReadUserData);
       
   171 		return CPolicyServer::EFail;
       
   172 		}	
       
   173 		
       
   174 	else
       
   175 		{
       
   176 		return CPolicyServer::EPass;	
       
   177 		}
       
   178 	}
       
   179 	
       
   180 /**
       
   181  * Creates and initialises the two AuthServer properties -
       
   182  * KUidAuthServerLastAuth and KUidAuthServerAuthChangeEvent.
       
   183  *
       
   184  **/
       
   185 void CAuthServer::CreatePropertiesL()
       
   186 	{
       
   187 	// KUidAuthServerLastAuth
       
   188 	TInt err1 = iAuthProperty.Define(KUidAuthServerLastAuth, RProperty::EText,
       
   189 									iPropertyReadPolicy, iPropertyWritePolicy,
       
   190 									sizeof(TLastAuth));
       
   191 
       
   192 	User::LeaveIfError(iAuthProperty.Attach(KAuthServerSecureId,
       
   193 											KUidAuthServerLastAuth));
       
   194 
       
   195 	
       
   196 	// KUidAuthServerAuthChangeEvent
       
   197 	TInt err2 = iAuthEventProperty.Define(KUidAuthServerAuthChangeEvent,
       
   198 									RProperty::EInt,
       
   199 									iPropertyReadPolicy,
       
   200 									iPropertyWritePolicy);
       
   201 	
       
   202 	User::LeaveIfError(iAuthEventProperty.Attach(KAuthServerSecureId,
       
   203 												 KUidAuthServerAuthChangeEvent));
       
   204 
       
   205 	if (err1 == KErrNone || err2 == KErrNone )
       
   206 		{
       
   207 		ClearPropertiesL();
       
   208 		}
       
   209 	}
       
   210 
       
   211 void CAuthServer::ClearPropertiesL()
       
   212 	{
       
   213 	TLastAuth lastAuth;
       
   214 	TPckg<TLastAuth> authPckg(lastAuth);
       
   215 	User::LeaveIfError(iAuthProperty.Set(authPckg));
       
   216 	User::LeaveIfError(iAuthEventProperty.Set(KUnknownIdentity));
       
   217 	}
       
   218 
       
   219 
       
   220 /**
       
   221  * Checks the number of identities in the database and iff zero asks the
       
   222  * training mgr to register the first identity.
       
   223  *
       
   224  * @leave KErrAuthServerCanNotCreateFirstId if the first identity cannot
       
   225  * be created
       
   226  **/
       
   227 void CAuthServer::FirstStartL()
       
   228 	{
       
   229 	TInt numIds = iAuthDb2->NumIdentitiesL();
       
   230 	if (numIds == 0)
       
   231 		{
       
   232 		TIdentityId id = 0;
       
   233 		TPckg<TIdentityId> idPkg(id);
       
   234 		TRandom::RandomL(idPkg);
       
   235 		
       
   236 		CProtectionKey* key = CProtectionKey::NewL(iKeySize);
       
   237 		if (!iTrainingMgr->RegisterFirstIdentityL(id, *key))
       
   238 			{
       
   239 			User::Panic(KAuthServerShortName, EPanicNoFirstStartPlugin);
       
   240 			}
       
   241 		}
       
   242 	}
       
   243 
       
   244 CAuthServer::~CAuthServer()
       
   245 	{
       
   246 	delete iAuthRepository;
       
   247 	delete iAuthTransaction;
       
   248 	
       
   249 	delete iTrainingMgr;
       
   250 	delete iLastIdentity;
       
   251 	delete iEvaluator;
       
   252 	delete iPluginMgr;
       
   253 	delete iPluginObserver;	
       
   254 	delete iParams;
       
   255 	if (iAuthDb2 != 0)
       
   256 		{
       
   257 		iAuthDb2->CompactIfRequired();
       
   258 		delete iAuthDb2;
       
   259 		}
       
   260 	
       
   261 	iFs.Close();
       
   262 	REComSession::FinalClose();
       
   263 	}
       
   264 
       
   265 		
       
   266 /**
       
   267  *  Creates a new session
       
   268  * @param aClientVersion the version of the connecting client
       
   269  * @param aMessage the connect message
       
   270  */
       
   271 CScsSession* CAuthServer::DoNewSessionL(const RMessage2& /*aMessage*/)
       
   272 	{
       
   273 	return CAuthServerSession::NewL(*this);
       
   274 	}
       
   275 
       
   276 
       
   277 /**
       
   278  * Returns the last identity to be authenticated within the period 
       
   279  * currTime to currTime-timeout.  
       
   280  * 
       
   281  * @param currTime the current universal time
       
   282  * 
       
   283  * @param timeout the number of seconds within which the last
       
   284  * authentication should have been made
       
   285  *
       
   286  * @return 0 if there has been no previous authentications either in the
       
   287  * server lifetime or within the timeout period. 
       
   288  *
       
   289  * @return a pointer to the cached identity object
       
   290  **/
       
   291 CIdentity* CAuthServer::CachedIdentity( const TTimeIntervalSeconds& aTimeOut)
       
   292     {
       
   293     // process request
       
   294     TTime currentTime;
       
   295 	if(currentTime.UniversalTimeSecure() == KErrNoSecureTime)
       
   296 		{
       
   297 		// Fall back to nonsecure time. 
       
   298 		currentTime.UniversalTime();
       
   299 		}
       
   300     
       
   301     CIdentity* id = 0;
       
   302   
       
   303     TTimeIntervalSeconds timeSinceLast;
       
   304     currentTime.SecondsFrom(iLastAuthTime, timeSinceLast);    
       
   305    
       
   306     if (timeSinceLast.Int() >= 0 && timeSinceLast < aTimeOut)
       
   307 		{
       
   308 		id = iLastIdentity;
       
   309 		}
       
   310     
       
   311     return id;
       
   312     }
       
   313     
       
   314 
       
   315 
       
   316 /**
       
   317  *
       
   318  * @param aMessage the message to process
       
   319  **/
       
   320 void CAuthServer::DeauthenticateL(const RMessage2& aMessage)
       
   321 	{
       
   322 	if (ServerBusy())
       
   323 		{
       
   324 		aMessage.Complete(KErrServerBusy);
       
   325 		return;
       
   326 		}
       
   327 
       
   328 	delete iLastIdentity;
       
   329 	iLastIdentity = 0;
       
   330 	iLastAuthTime = 0L;
       
   331 
       
   332 	ClearPropertiesL();	
       
   333 	aMessage.Complete(KErrNone);
       
   334 	}
       
   335 
       
   336 HBufC* CAuthServer::StringOrNullLC(TBool aReturnString, TIdentityId aId)
       
   337     {
       
   338 	HBufC* str = 0;
       
   339 	if (aReturnString)
       
   340 		{
       
   341 		TRAPD(err, str = iAuthDb2->DescriptionL(aId));  
       
   342 		if (!err)
       
   343 			{
       
   344 			CleanupStack::PushL(str);
       
   345 			}
       
   346 		
       
   347 		}
       
   348 	if (str == 0)
       
   349 		{
       
   350 		str = HBufC::NewLC(0);  
       
   351 		}
       
   352 	return str;
       
   353     }
       
   354 
       
   355 void CAuthServer::AuthenticateL(const RMessage2& aMessage)
       
   356     {
       
   357 	if (ServerBusy())
       
   358 		{
       
   359 		aMessage.Complete(KErrServerBusy);
       
   360 		return;
       
   361 		}
       
   362 		
       
   363 	TInt KAuthParams = 1; 
       
   364 	TInt paramsLen = aMessage.GetDesLength(KAuthParams);
       
   365 	
       
   366 	if(paramsLen != KErrBadDescriptor)
       
   367 		{
       
   368 		//Create a buffer.
       
   369 		HBufC8* buffer = HBufC8::NewLC(paramsLen);
       
   370 		TPtr8 bufDes(buffer->Des());
       
   371 			
       
   372 		aMessage.ReadL(EIpcArgument1, bufDes);
       
   373 		
       
   374 		//Internalize the params object.
       
   375 		RDesReadStream readStream(*buffer);
       
   376 		CleanupClosePushL(readStream);
       
   377 		iParams->InternalizeL(readStream);
       
   378 		CleanupStack::PopAndDestroy(2, buffer);	
       
   379 		}
       
   380     
       
   381 	CIdentity* id = CachedIdentity(iParams->iTimeout);
       
   382   
       
   383 	if (id == 0) // no valid cache available
       
   384 		{
       
   385 		const TInt KAuthExprParam = 0;
       
   386 	
       
   387 		// reconstruct the authentication expression
       
   388 		TInt extLen = aMessage.GetDesLengthL(KAuthExprParam);
       
   389 		HBufC8* extSrv = HBufC8::NewLC(extLen);
       
   390 		TPtr8 desSrv8 = extSrv->Des();
       
   391 		aMessage.ReadL(KAuthExprParam, desSrv8);
       
   392 		
       
   393 		RDesReadStream drs(desSrv8);
       
   394 		CAuthExpression* authExpr = CAuthExpressionImpl::NewL(drs);
       
   395 		// don't need the stream any more, so free it
       
   396 		CleanupStack::PopAndDestroy(extSrv);
       
   397 		CleanupStack::PushL(authExpr);
       
   398 
       
   399 		const CAuthExpressionImpl* expr = static_cast<const CAuthExpressionImpl*>(authExpr);
       
   400 		
       
   401 		iAuthTransaction = CAuthTransaction::NewL(aMessage,
       
   402 												  iParams->iClientKey,
       
   403 												  iParams->iClientSid.iUid,
       
   404 												  iParams->iWithString,
       
   405 												  *iParams->iClientMessage,
       
   406 												  expr);
       
   407 		CleanupStack::Pop(authExpr);
       
   408 		
       
   409 		iEvaluator->Evaluate(expr);
       
   410 		
       
   411 		return;
       
   412         }
       
   413         
       
   414 	else if (iParams->iClientKey && (id->Id() != KUnknownIdentity))
       
   415 		{
       
   416 		
       
   417 		HBufC* str = StringOrNullLC(iParams->iWithString, id->Id());
       
   418 		CIdentity* id2 = 0;
       
   419 		
       
   420 		TInt clientId = aMessage.SecureId();
       
   421 		
       
   422 		if(iParams->iClientSid.iUid != 0)
       
   423 			{
       
   424 			clientId = iParams->iClientSid.iUid;
       
   425 			}
       
   426 		
       
   427 		id2 = CIdentity::NewL(id->Id(), id->Key().ClientKeyL(clientId), str);
       
   428 			
       
   429 		CleanupStack::Pop(str);
       
   430 		CleanupStack::PushL(id2);
       
   431 		// id pointer already stored as iLastIdentity
       
   432 		id = id2; 
       
   433 		}
       
   434   
       
   435 	CompleteAuthenticationL(aMessage, id);
       
   436   
       
   437 	if (id != iLastIdentity) 
       
   438 		{
       
   439 		// only clean up the allocated id if it has not been transferred to us.
       
   440 		CleanupStack::PopAndDestroy(id);  
       
   441 		}
       
   442    
       
   443 	}
       
   444 
       
   445 // -------- plugin lists --------
       
   446 
       
   447 
       
   448 /**
       
   449 	Build an array containing descriptions for the
       
   450 	plugins available on the system and send it to
       
   451 	the client.
       
   452 	
       
   453 	@param	aMessage		Message describing client
       
   454 							request.
       
   455 	@param	aFilter			Function which decides whether
       
   456 							or not to include a plugin in the
       
   457 							list.
       
   458  */
       
   459 void CAuthServer::FilterPluginsL(
       
   460 	const RMessage2& aMessage, CAuthServer::TInterfaceFilter aFilter)
       
   461 
       
   462 	{
       
   463 	RCPointerArray<const CPluginDesc> descs;
       
   464 	GetDescriptionsFromEComLC(aFilter, descs);
       
   465 	AuthServerUtil::SendDataPointerArrayL(aMessage, descs, 0);
       
   466 	CleanupStack::PopAndDestroy(&descs);
       
   467 	}
       
   468 
       
   469 
       
   470 /**
       
   471 	Populate the supplied array with plugin descriptions generated
       
   472 	from the available ECOM plugins.
       
   473 	
       
   474 	@param	aFilter			Predicate function decides whether or not
       
   475 							to include each plugin in the list.
       
   476 	@param	aDescs			Array to populate.  When this function is
       
   477 							called, any existing entries are removed.
       
   478 							If this function leaves then any entries are
       
   479 							removed from the array.  On success, the
       
   480 							array is on the cleanup stack.
       
   481  */
       
   482 void CAuthServer::GetDescriptionsFromEComLC(
       
   483 	CAuthServer::TInterfaceFilter aFilter,
       
   484 	RCPointerArray<const CPluginDesc>& aDescs)
       
   485 	{
       
   486 	aDescs.Reset();
       
   487 	CleanupClosePushL(aDescs);
       
   488 	
       
   489 	// ownership of the data pointed by this array is with 
       
   490 	// the plugin manager. 
       
   491 	const RPointerArray<CImplementationInformation>& implInfo = iPluginMgr->ImplementationsL();
       
   492 	TInt implCount = implInfo.Count();
       
   493 	
       
   494 	for (TInt i = 0; i < implCount; ++i)
       
   495 		{
       
   496 		// avoid RVCT warning C2874W: pi may be used before being set
       
   497 		CAuthPluginInterface* pi = 0;
       
   498 		
       
   499 		TRAPD(r, pi = iPluginMgr->ImplementationL(i));
       
   500 		
       
   501 		// skip plugins which are not available
       
   502 		if (KErrNone != r)
       
   503 			continue;
       
   504 		
       
   505 		if (! (this->*aFilter)(*pi))
       
   506 			{
       
   507 			continue;
       
   508 			}
       
   509 		
       
   510 		// get training status from db
       
   511 		TAuthTrainingStatus ts = iAuthDb2->PluginStatusL(pi->Id());
       
   512 		
       
   513 		CPluginDesc* pd = CPluginDesc::NewL(
       
   514 			pi->Id(), pi->Name(), pi->Type(),
       
   515 			ts, pi->MinEntropy(),
       
   516 			pi->FalsePositiveRate(), pi->FalseNegativeRate() );
       
   517 				
       
   518 		CleanupStack::PushL(pd);
       
   519 		aDescs.AppendL(pd);
       
   520 		CleanupStack::Pop(pd);
       
   521 		}
       
   522 	
       
   523 	}
       
   524 
       
   525 
       
   526 
       
   527 /**
       
   528 	Build an array containing plugin descriptions for
       
   529 	each plugin which is available on the system, and
       
   530 	copy this into the client's space.
       
   531 	
       
   532 	@param	aMessage		Client message.  This contains
       
   533 							the client-side buffer.
       
   534  */
       
   535 void CAuthServer::PluginsL(const RMessage2& aMessage)
       
   536 	{
       
   537 	FilterPluginsL(aMessage, &CAuthServer::FilterAllPlugins);
       
   538 	}
       
   539 
       
   540 
       
   541 /**
       
   542 	Predicate function used by PluginsL.. This accepts all plugins.
       
   543 	
       
   544 	@return					Always ETrue.
       
   545 	@see PluginsL
       
   546  */
       
   547 TBool CAuthServer::FilterAllPlugins(const CAuthPluginInterface&)
       
   548 	{
       
   549 	return ETrue;
       
   550 	}
       
   551 
       
   552 
       
   553 /**
       
   554  *
       
   555  * @param aMessage the message to process
       
   556  **/
       
   557 void CAuthServer::ActivePluginsL(const RMessage2& aMessage)
       
   558 	{
       
   559 	FilterPluginsL(aMessage, &CAuthServer::FilterActivePlugins);
       
   560 	}
       
   561 
       
   562 
       
   563 /**
       
   564  * Indicates a plugin is active. 
       
   565  *
       
   566  * @param aInterface the auth plugin interface to check
       
   567  * @return true if aInterface.IsActive()
       
   568  **/
       
   569 TBool CAuthServer::FilterActivePlugins(const CAuthPluginInterface& aInterface)
       
   570 	{
       
   571 	return aInterface.IsActive();
       
   572 	}
       
   573 
       
   574 
       
   575 /**
       
   576 	Build an array which containing plugin descriptions
       
   577 	for each plugin which is available and has the type
       
   578 	supplied by the client.
       
   579 	
       
   580 	@param	aMessage		Client message.  This contains
       
   581 							the plugin type and points to the
       
   582 							client-side buffer.
       
   583  */
       
   584 void CAuthServer::PluginsByTypeL(const RMessage2& aMessage)
       
   585 	{
       
   586 	iFilterType = static_cast<TAuthPluginType>(aMessage.Int1());
       
   587 	FilterPluginsL(aMessage, &CAuthServer::FilterPluginsByType);
       
   588 	}
       
   589 
       
   590 
       
   591 /**
       
   592 	Predicate which checks whether the supplied description should
       
   593 	be included in the result list.
       
   594 	
       
   595 	The type to filter on is stored as a member variable.
       
   596 	
       
   597 	@param	aInterface		Interface to check.
       
   598 	@return					Zero if interface's type does not match
       
   599 							filter type, non-zero otherwise.
       
   600 	@see PluginsByTypeL
       
   601  */
       
   602 TBool CAuthServer::FilterPluginsByType(const CAuthPluginInterface& aInterface)
       
   603 	{
       
   604 	return (aInterface.Type() == iFilterType);
       
   605 	}
       
   606 
       
   607 
       
   608 /**
       
   609 	Build an array which contains plugin descriptions
       
   610 	for each plugin which has the supplied training status,
       
   611 	and write that array into the caller's space.
       
   612 	
       
   613 	@param	aMessage		Client message contains the status
       
   614 							to filter on.
       
   615  */
       
   616 void CAuthServer::PluginsByTrainingL(const RMessage2& aMessage)
       
   617 	{
       
   618 	iFilterTraining = static_cast<TAuthTrainingStatus>(aMessage.Int1());
       
   619 	FilterPluginsL(aMessage, &CAuthServer::FilterPluginsByTraining);
       
   620 	}
       
   621 
       
   622 
       
   623 /**
       
   624 	Predicate checks if the supplied interface describes
       
   625 	a plugin with the required training status.
       
   626 	
       
   627 	@param	aInterface		Interface to check.
       
   628 	@return					Zero if interface's training status
       
   629 							does not match the filter status;
       
   630 							non-zero otherwise.
       
   631 	@see PluginsByTrainingL
       
   632  */
       
   633 TBool
       
   634 CAuthServer::FilterPluginsByTraining(const CAuthPluginInterface& aInterface)
       
   635 	{
       
   636 	// training status is stored in the db, not in the ECOM interface.
       
   637 	// If this function returns non-zero, the same request will be made
       
   638 	// on the DB to get the status again to construct the description.
       
   639 	// This is suboptimal, and could be improved by special-casing the
       
   640 	// training filter if required.
       
   641 
       
   642 	TAuthTrainingStatus ts = EAuthUntrained;
       
   643 	TRAPD(err, ( ts = iAuthDb2->PluginStatusL(aInterface.Id())));
       
   644 	return err == KErrNone ? ts == iFilterTraining : EFalse;
       
   645 	}
       
   646 
       
   647 
       
   648 /**
       
   649 	Populate a client-side array with the set of identities.
       
   650 	
       
   651 	@param	aMessage		Client message which points to the
       
   652 							user-side array.
       
   653  */
       
   654 void CAuthServer::IdentitiesL(const RMessage2& aMessage)
       
   655 	{
       
   656     RArray<TIdentityId> ids;
       
   657     iAuthDb2->IdentitiesL(ids);
       
   658     CleanupClosePushL(ids);
       
   659     AuthServerUtil::SendDataArrayL(aMessage, ids, 0);
       
   660     CleanupStack::PopAndDestroy(&ids);
       
   661 	}
       
   662 /**
       
   663 	Retrieve the preferred plugin for the specified type
       
   664 	
       
   665 	@param	aMessage		Client message
       
   666  */
       
   667 void CAuthServer::PreferredTypePluginL(const RMessage2& aMessage)
       
   668 	{
       
   669     TPluginId id =
       
   670 	  iAuthDb2->PreferredPluginL(static_cast<TAuthPluginType>(aMessage.Int0()));
       
   671 	
       
   672 	TPckg<TPluginId> idPckg(id);
       
   673 	aMessage.WriteL(1, idPckg);
       
   674 	aMessage.Complete(KErrNone);
       
   675 	}
       
   676 
       
   677 /**
       
   678 	Set the preferred plugin for the specified type
       
   679 	
       
   680 	@param	aMessage		Client message
       
   681  */
       
   682 void CAuthServer::SetPreferredTypePluginL(const RMessage2& aMessage)
       
   683 	{
       
   684 	TInt            err        = KErrArgument;
       
   685 	TAuthPluginType pluginType = static_cast<TAuthPluginType>(aMessage.Int0());
       
   686 	TPluginId       pluginId   = aMessage.Int1();
       
   687 	
       
   688 	if (iPluginMgr->PluginL(pluginId)->Type() == pluginType)
       
   689 		{
       
   690 		iAuthDb2->SetPreferredPluginL(pluginType,pluginId);
       
   691 		err = KErrNone;
       
   692 		}
       
   693 	aMessage.Complete(err);
       
   694 	}
       
   695 
       
   696 /**
       
   697 	Retrieve description for a supplied identity.
       
   698 	
       
   699 	@param	aMessage		Client message which contains the
       
   700 							identity and points to a client-side
       
   701 							buffer, to which the description will
       
   702 							be copied.
       
   703  */
       
   704 void CAuthServer::IdentityStringL(const RMessage2& aMessage)
       
   705 	{
       
   706 	HBufC* desc = iAuthDb2->DescriptionL(aMessage.Int1());
       
   707 	CleanupStack::PushL(desc);
       
   708 	aMessage.WriteL(EIpcArgument0, *desc);	
       
   709 	CleanupStack::PopAndDestroy(desc);
       
   710 	aMessage.Complete(KErrNone);	
       
   711 	}
       
   712 
       
   713 /**
       
   714 	Retrieve description & id for all identities.
       
   715 	
       
   716 	@param	aMessage		Client message which contains the
       
   717 							identity and points to a client-side
       
   718 							buffer, to which the description will
       
   719 							be copied.
       
   720  */
       
   721 void CAuthServer::IdentitiesWithStringL(const RMessage2& aMessage)
       
   722 	{
       
   723 	RIdAndStringArray result;
       
   724 
       
   725 	iAuthDb2->IdentitiesWithDescriptionL(result);
       
   726 	CleanupClosePushL(result);
       
   727 
       
   728 	AuthServerUtil::SendDataPointerArrayL(aMessage,result,0);
       
   729 	CleanupStack::PopAndDestroy(&result);
       
   730 	}
       
   731 
       
   732 /**
       
   733  *
       
   734  * @param aMessage the message to process
       
   735  **/
       
   736 void CAuthServer::SetIdentityStringL(const RMessage2& aMessage)
       
   737 	{
       
   738 	HBufC* str = HBufC::NewLC(aMessage.GetDesLengthL(1));
       
   739 	TPtr strDes = str->Des();
       
   740 	TInt err = aMessage.Read(1, strDes);
       
   741 
       
   742 	if (err == KErrNone)
       
   743 	  {
       
   744 	  iAuthDb2->SetDescriptionL(aMessage.Int0(), *str);
       
   745 	  }	
       
   746 	CleanupStack::PopAndDestroy(str);
       
   747 	aMessage.Complete(err);
       
   748 	}
       
   749 
       
   750 
       
   751  
       
   752 /**
       
   753 	Copies the authentication alias list obtained using 
       
   754 	ListAliasL() method to a client-side buffer .
       
   755 	
       
   756 	@param	aMessage		Client message which points to a client-side
       
   757 							buffer, to which the authentication strength 
       
   758 							list will be copied.
       
   759  */
       
   760  
       
   761 void CAuthServer::ListAuthAliasesL(const RMessage2& aMessage)
       
   762 	{
       
   763 	RPointerArray<HBufC> aliasList;
       
   764 	CleanupResetAndDestroyPushL(aliasList);
       
   765 	
       
   766 	//get the list of available authentication strengths from the cenrep file.
       
   767 	iAuthRepository->ListAliasL(aliasList);
       
   768 
       
   769 	AuthServerUtil::SendDataPointerArrayL(aMessage, aliasList, EIpcArgument0);
       
   770 	CleanupStack::PopAndDestroy(&aliasList);
       
   771 	}
       
   772 	
       
   773 /**
       
   774 	Resolves any alias occurrence in the expression to its corresponding
       
   775 	value. 
       
   776 	
       
   777 	@param	aMessage	Client message which contains the free form
       
   778 						authentication expression and points to a 
       
   779 						client-side buffer, to which the string will 
       
   780 						be copied.
       
   781 	
       
   782  */
       
   783 void CAuthServer::ResolveExpressionL(const RMessage2& aMessage)
       
   784 	{
       
   785 	
       
   786 	// the auth strength passed by the client. 
       
   787 	TInt length = aMessage.GetDesLength(EIpcArgument1);
       
   788 	HBufC* clientExpression = HBufC::NewLC(length);
       
   789 	TPtr clientExprPtr(clientExpression->Des());
       
   790 
       
   791 	aMessage.ReadL(EIpcArgument1, clientExprPtr);
       
   792 	
       
   793 	RBuf resultantString;
       
   794 	CleanupClosePushL(resultantString);
       
   795 	
       
   796 	resultantString.CreateL(KDefaultBufferSize/2);
       
   797 		
       
   798 	// get the alias list
       
   799 	RPointerArray<HBufC> aliasList;
       
   800 	CleanupResetAndDestroyPushL(aliasList);
       
   801 	
       
   802 	//get the list of available authentication strength from the cenrep file.
       
   803 	iAuthRepository->ListAliasL(aliasList);
       
   804 		
       
   805 		
       
   806 	// parse the client side expression to see whether there
       
   807 	// are any alias, if present process them accordingly.
       
   808 	TLex input(clientExprPtr);
       
   809 	
       
   810 	// append the open bracket first so that the entire expression is within brackets.
       
   811 	resultantString.Append(KOpenBracket);
       
   812 	
       
   813 	for(TPtrC token = input.NextToken(); token.Size() > 0; token.Set(input.NextToken()))
       
   814 		{
       
   815 		
       
   816 		if(	token.CompareF(KOpenBracket) == 0 ||
       
   817 			token.CompareF(KCloseBracket) == 0 ||
       
   818 			token.CompareF(KAuthOpAnd) == 0 ||
       
   819 			token.CompareF(KAuthOpOr) == 0
       
   820 			)
       
   821 			{
       
   822 			int reqdBufferLength = resultantString.Length() + token.Length();			
       
   823 			
       
   824 			if(resultantString.MaxLength() < reqdBufferLength)
       
   825 				{
       
   826 				if(resultantString.MaxLength() == 0)
       
   827 					{
       
   828 					resultantString.Close();
       
   829 					}
       
   830 				resultantString.ReAllocL(reqdBufferLength);
       
   831 				}
       
   832 						
       
   833 			resultantString.Append(token);
       
   834 			}
       
   835 		else if(token.CompareF(KAuthBiometric) == 0 ||
       
   836 				token.CompareF(KAuthDefault) == 0 ||
       
   837 				token.CompareF(KAuthKnowledge) == 0 ||
       
   838 				token.CompareF(KAuthToken) == 0 ||
       
   839 				token.CompareF(KAuthPerformance) == 0	)
       
   840 			{
       
   841 			RBuf tokenType;
       
   842 			CleanupClosePushL(tokenType);
       
   843 			TokenizeStringL(token, tokenType);
       
   844 			int reqdBufferLength = resultantString.Length() + tokenType.Length();
       
   845 			if(resultantString.MaxLength() < reqdBufferLength)
       
   846 				{
       
   847 				if(resultantString.MaxLength() == 0)
       
   848 					{
       
   849 					resultantString.Close();
       
   850 					}
       
   851 				resultantString.ReAllocL(reqdBufferLength);
       
   852 				}
       
   853 			
       
   854 			resultantString.Append(tokenType);
       
   855 			CleanupStack::PopAndDestroy(&tokenType);
       
   856 			}
       
   857 		else
       
   858 			{
       
   859 			// should not be a number
       
   860 			TInt32 val = 0;
       
   861 			TLex value(token);
       
   862 			if(value.Val(val) == KErrNone)
       
   863 				{
       
   864 				RBuf tokenPluginId;
       
   865 				CleanupClosePushL(tokenPluginId);
       
   866 				TokenizeStringL(token, tokenPluginId);
       
   867 				int reqdBufferLength = resultantString.Length() + tokenPluginId.Length();
       
   868 				if(resultantString.MaxLength() < reqdBufferLength)
       
   869 					{
       
   870 					if(resultantString.MaxLength() == 0)
       
   871 						{
       
   872 						resultantString.Close();
       
   873 						}
       
   874 					resultantString.ReAllocL(reqdBufferLength);
       
   875 					}
       
   876 				resultantString.Append(tokenPluginId);
       
   877 				CleanupStack::PopAndDestroy(&tokenPluginId);
       
   878 				continue;
       
   879 				}
       
   880 			
       
   881 			RBuf aliasString;
       
   882 			CleanupClosePushL(aliasString);
       
   883 				
       
   884 			// this is a alias value which should be processed
       
   885 			ResolveAliasL(token, aliasList, aliasString);
       
   886 			int reqdBufferLength = resultantString.Length() + aliasString.Length();
       
   887 			if(resultantString.MaxLength() < reqdBufferLength)
       
   888 				{
       
   889 				if(resultantString.MaxLength() == 0)
       
   890 					{
       
   891 					resultantString.Close();
       
   892 					}
       
   893 				resultantString.ReAllocL(reqdBufferLength);
       
   894 				}
       
   895 			resultantString.Append(aliasString);
       
   896 			CleanupStack::PopAndDestroy(&aliasString);
       
   897 			}
       
   898 		}
       
   899 	
       
   900 	int reqdBufferLength = resultantString.Length() + KCloseBracket().Length();
       
   901 	
       
   902 	if(resultantString.MaxLength() < reqdBufferLength)
       
   903 		{
       
   904 		if(resultantString.MaxLength() == 0)
       
   905 			{
       
   906 			resultantString.Close();
       
   907 			}
       
   908 		resultantString.ReAllocL(reqdBufferLength);
       
   909 		}
       
   910 										
       
   911 	// append the close bracket in the end so that the entire expression is within brackets.
       
   912 	resultantString.Append(KCloseBracket);
       
   913 					
       
   914 	//see if we have enough space on the client.
       
   915 	length = resultantString.Length();
       
   916 	if(aMessage.GetDesMaxLengthL(EIpcArgument0) < length)
       
   917 		{
       
   918 		TPckg<TInt> lenPckg(length);
       
   919 		aMessage.WriteL(EIpcArgument0, lenPckg);
       
   920 		aMessage.Complete(KErrOverflow);
       
   921 		}
       
   922 	
       
   923 	aMessage.WriteL(EIpcArgument0, resultantString);	
       
   924 	CleanupStack::PopAndDestroy(3, clientExpression);	//aliasList, resultantString.
       
   925 	aMessage.Complete(KErrNone);
       
   926 	}
       
   927 
       
   928 /**
       
   929 	Inserts space in between operators and inserts brackets for as 
       
   930 	expression
       
   931 	
       
   932 	@param	aStringToBeProcessed	string to be tokenized.
       
   933 	@param  aResultantString		would contain the final tokenized
       
   934 									string
       
   935  */
       
   936 
       
   937 void CAuthServer::TokenizeStringL( const TDesC& aStringToBeProcessed, RBuf& aResultantString )
       
   938 	{
       
   939 	TInt newLength = aStringToBeProcessed.Length() + 2;
       
   940 	HBufC* resultantBuffer = HBufC::NewLC(newLength);
       
   941 	TPtr resultantBufPtr(resultantBuffer->Des());
       
   942 	resultantBufPtr.Append(KOpenBracket);
       
   943 	resultantBufPtr.Append(aStringToBeProcessed);
       
   944 	TInt index = resultantBufPtr.Length();
       
   945 	resultantBufPtr.Append(KCloseBracket);
       
   946 	
       
   947 	CAuthExpressionImpl::InsertSpaceBetweenOperatorsL(*resultantBuffer, aResultantString);
       
   948 	CleanupStack::PopAndDestroy(resultantBuffer);
       
   949 	
       
   950 	}
       
   951 
       
   952 /**
       
   953 	Retrieves the alias string corresponding to the 
       
   954 	supplied authentication strength.
       
   955 	
       
   956 	@param	aMessage	Client message which contains the
       
   957 						authentication strength and points to a 
       
   958 						client-side buffer, to which the alais
       
   959 						string will be copied.
       
   960 	
       
   961  */
       
   962  	
       
   963 void CAuthServer::ResolveAliasL(const TDesC& aAliasName, 
       
   964 								RPointerArray<HBufC>& aAliasList, 
       
   965 								RBuf& aResultantString)
       
   966 	{
       
   967 	HBufC* aliasString = HBufC::NewLC(KDefaultBufferSize/2);
       
   968 	TPtr aliasStringPtr(aliasString->Des());
       
   969 	
       
   970 	TBool aliasFound = EFalse;
       
   971 		
       
   972 	// find a match for the client supplied alias from the aliasList.
       
   973 	for(TInt i = 0; i < aAliasList.Count(); ++i)
       
   974 		{
       
   975 		if(aAliasName.CompareF(*aAliasList[i]) != 0)
       
   976 			{
       
   977 			continue;
       
   978 			}
       
   979 		
       
   980 		aliasFound = ETrue;
       
   981 		// retrieve the alias string corresponding to a given authentication strength.
       
   982 		iAuthRepository->GetAliasDefinitionL(i, aliasStringPtr);
       
   983 		if(aliasStringPtr.Length() == 0)
       
   984 			{
       
   985 			User::Leave(KErrAuthStrengthAliasNotDefined);
       
   986 			}
       
   987 			
       
   988 		// enclose the alias string within brackets.This would facilitate easy evaluation 
       
   989 		// of the alias string expression.
       
   990 		TInt newLength = aliasStringPtr.Length() + 2;
       
   991 		if(newLength > aliasStringPtr.MaxLength())
       
   992 			{
       
   993 			aliasString->ReAllocL(newLength);
       
   994 			}
       
   995 			
       
   996 		aliasStringPtr.Insert(0, KOpenBracket);
       
   997 		TInt index = aliasStringPtr.Length();
       
   998 		aliasStringPtr.Insert(index, KCloseBracket);
       
   999 		
       
  1000 		// tokenize aliasString, to facilitate parsing using TLex.
       
  1001 		CAuthExpressionImpl::InsertSpaceBetweenOperatorsL(*aliasString, aResultantString);
       
  1002 				
       
  1003 		if(aResultantString.Length() > aliasStringPtr.MaxLength())
       
  1004 			{
       
  1005 			aliasString = aliasString->ReAllocL(aResultantString.Length());
       
  1006 			}
       
  1007 		
       
  1008 		aliasStringPtr.Copy(aResultantString);
       
  1009 		aResultantString.Close();
       
  1010 		
       
  1011 		// aliasString contains an alias, so process it until we end up 
       
  1012 		// with an expression containing plugin Id or plugin Type or a combination of both.		
       
  1013 		ProcessAliasStringL(aAliasList, *aliasString, aResultantString);
       
  1014 				
       
  1015 		// ensure that the aliasString processing doesn't end in an infinite loop.
       
  1016 		// In case it does , leave with KErrAuthServInvalidAliasStringExpression.
       
  1017 		// For instance : fast = (medium & weak), medium = fast i.e 
       
  1018 		// medium = (medium & weak).
       
  1019 				
       
  1020 		if(aResultantString.FindC(aAliasName) != KErrNotFound)
       
  1021 			{
       
  1022 			User::Leave(KErrAuthServInvalidAliasStringExpression);
       
  1023 			}
       
  1024 							
       
  1025 		TBool found = CheckForAliasInAliasString(aAliasList, aResultantString);
       
  1026 		// 'resultantAliasString' may inturn contain an alias.So loop through the ProcessAliasStringL,
       
  1027 		// until  we end up with an alias string containing only plugin Id,plugin Type or a combination of both.
       
  1028 		while(found)
       
  1029 			{
       
  1030 			for(TInt j = 0; j < aAliasList.Count(); ++j)
       
  1031 				{
       
  1032 				if(aResultantString.FindC(*aAliasList[j]) != KErrNotFound)
       
  1033 					{
       
  1034 					if(aResultantString.Length() > aliasStringPtr.MaxLength())
       
  1035 						{
       
  1036 						aliasString->ReAllocL(aResultantString.Length());
       
  1037 						}
       
  1038 							
       
  1039 					aliasStringPtr.Copy(aResultantString);
       
  1040 					aResultantString.Close();
       
  1041 										
       
  1042 					CAuthExpressionImpl::InsertSpaceBetweenOperatorsL(*aliasString, aResultantString);
       
  1043 					if(aResultantString.Length() > aliasStringPtr.MaxLength())
       
  1044 						{
       
  1045 						aliasString->ReAllocL(aResultantString.Length());
       
  1046 						}
       
  1047 						
       
  1048 					aliasStringPtr.Copy(aResultantString);
       
  1049 					aResultantString.Close();
       
  1050 								
       
  1051 				 	ProcessAliasStringL(aAliasList, *aliasString, aResultantString);
       
  1052 					// ensure that the aliasString processing doesn't end in an infinite loop.
       
  1053 					// In case it does , leave with KErrArgument.
       
  1054 					// For instance : fast = (medium & weak), medium = fast i.e 
       
  1055 					// medium = (medium & weak).
       
  1056 					if(aResultantString.FindC(aAliasName) != KErrNotFound)
       
  1057 						{
       
  1058 						User::Leave(KErrAuthServInvalidAliasStringExpression);
       
  1059 						}
       
  1060 					break;
       
  1061 					}
       
  1062 				}
       
  1063 					
       
  1064 				// check if 'resultantExpr' still contains an alias.
       
  1065 			found = CheckForAliasInAliasString(aAliasList, aResultantString);				
       
  1066 			
       
  1067 			}
       
  1068 				
       
  1069 		break;
       
  1070 		}
       
  1071 	
       
  1072 	CleanupStack::PopAndDestroy(aliasString);
       
  1073 	
       
  1074 	//if the client supplied alias is not in the alias list, leave.
       
  1075 	if(!aliasFound)
       
  1076 		{
       
  1077 		User::Leave(KErrUnknownAuthStrengthAlias);
       
  1078 		}
       
  1079 
       
  1080 	}
       
  1081 
       
  1082 // Resets the training data for the supplied identity.
       
  1083 //	
       
  1084 // @param aMessage Client message which contains the details of 
       
  1085 //					identity and plugins for doing the reset
       
  1086 void CAuthServer::ResetIdentityL(TInt aFunction, const RMessage2& aMessage)
       
  1087 	{
       
  1088 	// Check if either an authentication or a training is going on
       
  1089 	if (ServerBusy())
       
  1090 		{
       
  1091 		aMessage.Complete(KErrServerBusy);
       
  1092 		return;
       
  1093 		}
       
  1094 
       
  1095 	// For reset by type only EAuthKnowledge type is supported
       
  1096 	if (aFunction == EResetIdentityByType)
       
  1097 		{
       
  1098 		TAuthPluginType pluginType = static_cast<TAuthPluginType>(aMessage.Int1());
       
  1099 		if (pluginType != EAuthKnowledge)
       
  1100 			{
       
  1101 			aMessage.Complete(KErrAuthServResetMayLoseIdentity);
       
  1102 			return;
       
  1103 			}
       
  1104 		}
       
  1105 
       
  1106 	// Get the list of trained plugins for this identity
       
  1107 	TIdentityId identityId = static_cast<TIdentityId>(aMessage.Int0());
       
  1108 	RArray<TPluginId> trainedPluginIdList;
       
  1109 	CleanupClosePushL(trainedPluginIdList);
       
  1110 	iAuthDb2->TrainedPluginsListL(identityId, trainedPluginIdList);
       
  1111 
       
  1112 	// Ensure at least one plugin knows identity
       
  1113 	TInt numTrained = trainedPluginIdList.Count();
       
  1114 	if (numTrained < 1)
       
  1115 		{
       
  1116 		CleanupStack::PopAndDestroy(&trainedPluginIdList);
       
  1117 		aMessage.Complete(KErrAuthServIdentityNotFound);
       
  1118 		return;
       
  1119 		}
       
  1120 
       
  1121 	// Try and ensure that after reset at least one plugin has an identity trained
       
  1122 	// Since all the trained plugins for the identity are being reset make sure
       
  1123 	// at least one of them is of the knowledge type to be reasonably sure it registers 
       
  1124 	// the new identity data
       
  1125 	TBool knowledgePluginFound = EFalse;
       
  1126 	for (TInt index = 0; index < numTrained; ++index)
       
  1127 		{
       
  1128 		TPluginId pluginId = trainedPluginIdList[index];
       
  1129 		CAuthPluginInterface* plugin = iPluginMgr->PluginL(pluginId);
       
  1130 		if (plugin->Type() == EAuthKnowledge)
       
  1131 			{
       
  1132 			knowledgePluginFound = ETrue;
       
  1133 			break;
       
  1134 			}
       
  1135 		}
       
  1136 	if (!knowledgePluginFound)
       
  1137 		{
       
  1138 		CleanupStack::PopAndDestroy(&trainedPluginIdList);
       
  1139 		aMessage.Complete(KErrAuthServResetMayLoseIdentity);
       
  1140 		return;
       
  1141 		}
       
  1142 
       
  1143 	// Get the registration data
       
  1144 	HBufC* regData = NULL;
       
  1145 	TInt ipcArg = (aFunction == EResetIdentity) ?  EIpcArgument1:EIpcArgument2;
       
  1146 	regData = HBufC::NewLC(aMessage.GetDesLengthL(ipcArg));
       
  1147 	TPtr regPtr = regData->Des();
       
  1148 	aMessage.ReadL(ipcArg, regPtr);
       
  1149 
       
  1150 	// Finally start the reset process
       
  1151 	// Generate a new protection key
       
  1152 	CProtectionKey* protKey = CProtectionKey::NewLC(iKeySize);
       
  1153 	TInt lastErr = KErrNone;
       
  1154 	TBool oneSuccess = EFalse; // To keep track if at least one reset succeeded
       
  1155 	for (TInt index = 0; index < numTrained; ++index)
       
  1156 		{
       
  1157 		TPluginId pluginId = trainedPluginIdList[index];
       
  1158 		CAuthPluginInterface* plugin = iPluginMgr->PluginL(pluginId);
       
  1159 		HBufC8* result = NULL;
       
  1160 		TInt err = KErrNone;
       
  1161 		// For reset by type the registration data needs to be specified only for the plugins of specified type
       
  1162 		// and this restricted to knowledge type only
       
  1163 		if ((aFunction == EResetIdentity) ||
       
  1164 			((aFunction == EResetIdentityByType) && (plugin->Type() == EAuthKnowledge)))
       
  1165 			{
       
  1166 			err = plugin->Reset(identityId, *regData, result);
       
  1167 			}
       
  1168 		else
       
  1169 			{
       
  1170 			err = plugin->Reset(identityId, KNullDesC, result);
       
  1171 			}
       
  1172 		if (err == KErrNone && result)
       
  1173 			{
       
  1174 			oneSuccess = ETrue;
       
  1175 			// Use the plugin data to generate transient key and then encrypt the protection key
       
  1176 			// using the transient key. A plugin may not return data if it does not use the supplied
       
  1177 			// registration information 
       
  1178 			CleanupStack::PushL(result);
       
  1179 			CTransientKeyInfo* keyInfo = CreateKeyInfoLC(pluginId, *result, *protKey);
       
  1180 			// Replace the trained information in the db
       
  1181 			iAuthDb2->SetTrainedPluginL(identityId, pluginId, *keyInfo);
       
  1182 			CleanupStack::PopAndDestroy(2, result); // keyInfo
       
  1183 			}
       
  1184 		else if (err == KErrNone)
       
  1185 			{
       
  1186 			oneSuccess = ETrue;
       
  1187 			// Remove the entry in the auth db for the plugin
       
  1188 			// Ignore errors
       
  1189 			TRAP_IGNORE(iAuthDb2->RemoveTrainedPluginL(identityId, pluginId));
       
  1190 			}
       
  1191 		else
       
  1192 			{
       
  1193 			// Remember the last error
       
  1194 			lastErr = err;
       
  1195 			}
       
  1196 		}
       
  1197 
       
  1198 	CleanupStack::PopAndDestroy(3, &trainedPluginIdList); // regData, protKey
       
  1199 	
       
  1200 	// If none of the plugins reset correctly then return the last error
       
  1201 	if (oneSuccess)
       
  1202 		{
       
  1203 		lastErr = KErrNone;
       
  1204 		}
       
  1205 	
       
  1206 	aMessage.Complete(lastErr);
       
  1207 	}
       
  1208 
       
  1209 // Resets the training data for the supplied identity.
       
  1210 //	
       
  1211 // @param aMessage Client message which contains the details of 
       
  1212 //					identity and plugins for doing the reset
       
  1213 void CAuthServer::ResetIdentityByListL(const RMessage2& aMessage)
       
  1214 	{
       
  1215 	// Check if either an authentication or a training is going on
       
  1216 	if (ServerBusy())
       
  1217 		{
       
  1218 		aMessage.Complete(KErrServerBusy);
       
  1219 		return;
       
  1220 		}
       
  1221 
       
  1222 	// Get the list of trained plugins for this identity
       
  1223 	TIdentityId identityId = static_cast<TIdentityId>(aMessage.Int0());
       
  1224 	RArray<TPluginId> trainedPluginIdList;
       
  1225 	CleanupClosePushL(trainedPluginIdList);
       
  1226 	iAuthDb2->TrainedPluginsListL(identityId, trainedPluginIdList);
       
  1227 
       
  1228 	// Ensure at least one plugin knows identity
       
  1229 	TInt numTrained = trainedPluginIdList.Count();
       
  1230 	if (numTrained < 1)
       
  1231 		{
       
  1232 		CleanupStack::PopAndDestroy(&trainedPluginIdList);
       
  1233 		aMessage.Complete(KErrAuthServIdentityNotFound);
       
  1234 		return;
       
  1235 		}
       
  1236 
       
  1237 	// Extract the array of plugin ids and their registration information
       
  1238 	RArray<TPluginId> pluginIdList;
       
  1239 	CleanupClosePushL(pluginIdList);
       
  1240 	HBufC8* buf = HBufC8::NewLC(aMessage.GetDesLengthL(EIpcArgument1));
       
  1241 	TPtr8 ptr = buf->Des();
       
  1242 	aMessage.ReadL(EIpcArgument1, ptr);
       
  1243 	RDesReadStream stream(*buf);
       
  1244 	CleanupClosePushL(stream);
       
  1245 	InternalizeArrayL(pluginIdList, stream);
       
  1246 	CleanupStack::PopAndDestroy(2, buf); // stream
       
  1247 
       
  1248 	RPointerArray<HBufC> regInfoList;
       
  1249 	CleanupResetAndDestroyPushL(regInfoList);
       
  1250 	buf = HBufC8::NewLC(aMessage.GetDesLengthL(EIpcArgument2));
       
  1251 	ptr.Set(buf->Des());
       
  1252 	aMessage.ReadL(EIpcArgument2, ptr);
       
  1253 	stream.Open(*buf);
       
  1254 	CleanupClosePushL(stream);
       
  1255 	InternalizePointerArrayL(regInfoList, stream);
       
  1256 	CleanupStack::PopAndDestroy(2, buf); // stream
       
  1257 
       
  1258 	// Sanity check
       
  1259 	if (pluginIdList.Count() != regInfoList.Count())
       
  1260 		{
       
  1261 		CleanupStack::PopAndDestroy(3, &trainedPluginIdList); // pluginIdList, regInfoList
       
  1262 		aMessage.Complete(KErrArgument);
       
  1263 		return;
       
  1264 		}
       
  1265 
       
  1266 	// Prepare an array of TPluginResetDetails to aid during resetting
       
  1267 	RPointerArray<TPluginResetDetails> resetDetails;
       
  1268 	CleanupResetAndDestroyPushL(resetDetails);
       
  1269 	
       
  1270 	for (TInt index = 0; index < numTrained; ++index)
       
  1271 		{
       
  1272 		TPluginId pluginId = trainedPluginIdList[index];
       
  1273 		// Check if the trained plugin needs to be sent registration data
       
  1274 		TInt indexA = pluginIdList.Find(pluginId);
       
  1275 		
       
  1276 		TPluginResetDetails *resetDetailsEntry;
       
  1277 		if (indexA != KErrNotFound)
       
  1278 			{
       
  1279 			// Note: Ownership of the descriptor pointers remains with regInfoList
       
  1280 			resetDetailsEntry = new (ELeave) TPluginResetDetails(pluginId, *regInfoList[indexA]);
       
  1281 			}
       
  1282 		else
       
  1283 			{
       
  1284 			resetDetailsEntry = new (ELeave) TPluginResetDetails(pluginId, KNullDesC());
       
  1285 			}
       
  1286 		CleanupStack::PushL(resetDetailsEntry);
       
  1287 		resetDetails.AppendL(resetDetailsEntry);
       
  1288 		CleanupStack::Pop(resetDetailsEntry);
       
  1289 		}
       
  1290 
       
  1291 	// Try and ensure that after reset at least one plugin has an identity trained
       
  1292 	// Since all the trained plugins for the identity are being reset make sure
       
  1293 	// at least one of them is of the knowledge type and is being passed the registration data 
       
  1294 	// to be reasonably sure it registers the new identity data
       
  1295 	TBool knowledgePluginFound = EFalse;
       
  1296 	for (TInt index = 0; index < numTrained; ++index)
       
  1297 		{
       
  1298 		TPluginId pluginId = resetDetails[index]->PluginId();
       
  1299 		CAuthPluginInterface* plugin = iPluginMgr->PluginL(pluginId);
       
  1300 		if ((plugin->Type() == EAuthKnowledge) && (resetDetails[index]->RegistrationData() != KNullDesC))
       
  1301 			{
       
  1302 			knowledgePluginFound = ETrue;
       
  1303 			break;
       
  1304 			}
       
  1305 		}
       
  1306 	if (!knowledgePluginFound)
       
  1307 		{
       
  1308 		CleanupStack::PopAndDestroy(4, &trainedPluginIdList); // pluginIdList, regInfoList, resetDetails
       
  1309 		aMessage.Complete(KErrAuthServResetMayLoseIdentity);
       
  1310 		return;
       
  1311 		}
       
  1312 
       
  1313 	// Finally start the reset process
       
  1314 	// Generate a new protection key
       
  1315 	CProtectionKey* protKey = CProtectionKey::NewLC(iKeySize);
       
  1316 	TInt lastErr = KErrNone;
       
  1317 	TBool oneSuccess = EFalse; // To keep track if at least one reset succeeded
       
  1318 	for (TInt index = 0; index < numTrained; ++index)
       
  1319 		{
       
  1320 		TPluginResetDetails* reset = resetDetails[index];
       
  1321 		TPluginId pluginId = reset->PluginId();
       
  1322 		CAuthPluginInterface* plugin = iPluginMgr->PluginL(pluginId);
       
  1323 		HBufC8* result = NULL;
       
  1324 		TInt err = plugin->Reset(identityId, reset->RegistrationData(), result);
       
  1325 		if (err == KErrNone && result)
       
  1326 			{
       
  1327 			oneSuccess = ETrue;
       
  1328 			// Use the plugin data to generate transient key and then encrypt the protection key
       
  1329 			// using the transient key. A plugin may not return data if it does not use the supplied
       
  1330 			// registration information 
       
  1331 			CleanupStack::PushL(result);
       
  1332 			CTransientKeyInfo* keyInfo = CreateKeyInfoLC(pluginId, *result, *protKey);
       
  1333 			// Replace the trained information in the db
       
  1334 			iAuthDb2->SetTrainedPluginL(identityId, pluginId, *keyInfo);
       
  1335 			CleanupStack::PopAndDestroy(2, result); // keyInfo
       
  1336 			}
       
  1337 		else if (err == KErrNone)
       
  1338 			{
       
  1339 			oneSuccess = ETrue;
       
  1340 			// Remove the entry in the auth db for the plugin
       
  1341 			// Ignore errors
       
  1342 			TRAP_IGNORE(iAuthDb2->RemoveTrainedPluginL(identityId, pluginId));
       
  1343 			}
       
  1344 		else
       
  1345 			{
       
  1346 			// Remember the last error
       
  1347 			lastErr = err;
       
  1348 			}
       
  1349 		}
       
  1350 	
       
  1351 	CleanupStack::PopAndDestroy(5, &trainedPluginIdList); // pluginIdList, regInfoList, resetDetails, protKey
       
  1352 
       
  1353 	// If none of the plugins reset correctly then return the last error
       
  1354 	if (oneSuccess)
       
  1355 		{
       
  1356 		lastErr = KErrNone;
       
  1357 		}
       
  1358 	
       
  1359 	aMessage.Complete(lastErr);
       
  1360 	}
       
  1361 
       
  1362 // Generates and returns transient key info using the supplied plugin data and the protection key
       
  1363 CTransientKeyInfo* CAuthServer::CreateKeyInfoLC(TPluginId aPluginId, const TDesC8& aPluginData, const CProtectionKey& aProtKey)
       
  1364 	{
       
  1365 	CTransientKeyInfo* keyInfo = CTransientKeyInfo::NewLC(aPluginId);
       
  1366 
       
  1367 	CTransientKey* transKey = keyInfo->CreateTransientKeyL(aPluginData);
       
  1368 	CleanupStack::PushL(transKey);
       
  1369     
       
  1370 	CEncryptedProtectionKey* encProtKey = transKey->EncryptL(aProtKey);
       
  1371 	CleanupStack::PushL(encProtKey);
       
  1372 	
       
  1373 	keyInfo->SetEncryptedProtectionKeyL(encProtKey);
       
  1374 	CleanupStack::Pop(encProtKey);
       
  1375 	CleanupStack::PopAndDestroy(transKey);
       
  1376 	return keyInfo;
       
  1377 	}
       
  1378 
       
  1379 /**
       
  1380 	Checks if the value of strength alias inturn contains an alias.
       
  1381 	
       
  1382 	@param	aAuthAliasList		an array of authentication strengths as obtained from
       
  1383 								authserver cenrep file.
       
  1384 	@param	aAliasString		an alias string containing the alias to be searched for.
       
  1385 	
       
  1386  */	
       
  1387 	
       
  1388 TBool CAuthServer::CheckForAliasInAliasString(RPointerArray<HBufC>& aAuthAliasList, const TDes& aAliasString)
       
  1389 	{
       
  1390 	// find a match for the client supplied alias from the aliasList.
       
  1391 	for(TInt i = 0; i < aAuthAliasList.Count(); ++i)
       
  1392 		{
       
  1393 		TInt found = aAliasString.FindC(*aAuthAliasList[i]);
       
  1394 		if(found > 0)
       
  1395 			{
       
  1396 			return ETrue;
       
  1397 			}
       
  1398 		}
       
  1399 		
       
  1400 	return EFalse;
       
  1401 	}
       
  1402 	
       
  1403 /**
       
  1404 	Processes an alias string, This method is called recursively until we end
       
  1405 	up with an alias string containing only pluginIds and pluginTypes or a 
       
  1406 	combination of both.
       
  1407 	
       
  1408 	
       
  1409 	@param	aAliasList					an array of authentication strengths as obtained from
       
  1410 										authserver cenrep file.
       
  1411 	@param	aAliasStringToBeProcessed	an alias string to be processed.	
       
  1412 	@param	aResultantAliasString		Buffer to be populated with an alias string resulting from processing aAliasStringToBeProcessed.				
       
  1413 	 
       
  1414  */
       
  1415  	
       
  1416 void CAuthServer::ProcessAliasStringL(RPointerArray<HBufC>& aAliasList, const TDesC& aAliasStringToBeProcessed, RBuf& aResultantAliasString)
       
  1417 	{
       
  1418 	TBuf<KDefaultBufferSize> exprString;
       
  1419 	HBufC* aliasString = HBufC::NewLC(KMaxBufferSize);
       
  1420 	TPtr aliasStringPtr(aliasString->Des());
       
  1421 		
       
  1422 	TLex input(aAliasStringToBeProcessed);
       
  1423 	_LIT(KDelimiter, " ");
       
  1424 	TBool aliasFoundInString = EFalse;
       
  1425 	
       
  1426 	//iterate through the obtained expression to verify if it contains any strength subsets.
       
  1427 	for(TPtrC token = input.NextToken(); token.Size() > 0; token.Set(input.NextToken()))
       
  1428 		{
       
  1429 		TInt resultingLen = 0;
       
  1430 		aliasFoundInString = EFalse;
       
  1431 		for(TInt i = 0; i < aAliasList.Count(); ++i)
       
  1432 			{
       
  1433 			if(token.FindC(*aAliasList[i]) != KErrNotFound)
       
  1434 				{
       
  1435 				aliasFoundInString = ETrue;
       
  1436 				iAuthRepository->GetAliasDefinitionL(i, exprString);
       
  1437 				if(exprString.Length() == 0)
       
  1438 					{
       
  1439 					User::Leave(KErrAuthStrengthAliasNotDefined);
       
  1440 					}
       
  1441 					
       
  1442 				// resulting length obtained by appending exprString ,KCloseBracket and KOpenBracket to aliasString.
       
  1443 				resultingLen = (exprString.Length() + 2);
       
  1444 				if(resultingLen > KMaxBufferSize)
       
  1445 					{
       
  1446 					aliasString->ReAllocL(resultingLen);
       
  1447 					}
       
  1448 				
       
  1449 				aliasStringPtr.Append(KOpenBracket);	
       
  1450 				aliasStringPtr.Append(exprString);
       
  1451 				aliasStringPtr.Append(KCloseBracket);
       
  1452 				break;
       
  1453 				}
       
  1454 			}
       
  1455 		
       
  1456 		//if the token is an operator or a plugin type or pluginId, append it to aResultantExpr.
       
  1457 		if(!aliasFoundInString)
       
  1458 			{
       
  1459 			// resulting length obtained by appending token and delimiter to be aliasString.
       
  1460 			resultingLen = (exprString.Length() + token.Length() + 1);
       
  1461 			if(resultingLen > KMaxBufferSize)
       
  1462 					{
       
  1463 					aliasString->ReAllocL(resultingLen);
       
  1464 					}
       
  1465 					
       
  1466 			aliasStringPtr.Append(token);
       
  1467 			aliasStringPtr.Append(KDelimiter);	
       
  1468 			}
       
  1469 		}
       
  1470 	
       
  1471 	CleanupStack::Pop(aliasString);
       
  1472 	aResultantAliasString.Assign(aliasString);	
       
  1473 	
       
  1474 	}
       
  1475 	
       
  1476 
       
  1477 /**
       
  1478  *
       
  1479  * @param aMessage the message to process
       
  1480  **/
       
  1481 void CAuthServer::RegisterIdentityL(const RMessage2& aMessage)
       
  1482 	{
       
  1483 	if (ServerBusy())
       
  1484 		{
       
  1485 		aMessage.Complete(KErrServerBusy);
       
  1486 		return;
       
  1487 		}
       
  1488 
       
  1489 	TIdentityId id = 0;
       
  1490 	TPckg<TIdentityId> idPkg(id);
       
  1491 	TRandom::RandomL(idPkg);
       
  1492 
       
  1493 	CProtectionKey* key = CProtectionKey::NewL(iKeySize);
       
  1494 	
       
  1495 	iTrainingMgr->RegisterIdentityL(aMessage, id, *key);
       
  1496 	}
       
  1497 
       
  1498 /**
       
  1499  *
       
  1500  * @param aMessage the message to process
       
  1501  **/
       
  1502 void CAuthServer::CancelL(const RMessage2& aMessage)
       
  1503     {
       
  1504 	TInt err = KErrNone;
       
  1505 
       
  1506 	if (iTrainingMgr->IsBusy())
       
  1507 		{
       
  1508 		iTrainingMgr->Cancel();
       
  1509 		}
       
  1510 	else if (iAuthTransaction != 0)
       
  1511 		{
       
  1512 		if (aMessage.SecureId() == iAuthTransaction->Message().SecureId())
       
  1513 			{
       
  1514 			iEvaluator->Cancel();
       
  1515 			}
       
  1516 		else
       
  1517 			{
       
  1518 			// Shouldn't come here since we don't support share-able sessions
       
  1519 			err = KErrInUse;
       
  1520 			}
       
  1521 		}
       
  1522 	aMessage.Complete(err);
       
  1523 	}
       
  1524 
       
  1525 
       
  1526 /**
       
  1527 	Remove the supplied identity from the database.
       
  1528 	
       
  1529 	@param	aMessage		Client which contains identity
       
  1530 							to remove.
       
  1531  */
       
  1532 void CAuthServer::RemoveIdentityL(const RMessage2& aMessage)
       
  1533 	{
       
  1534 	TInt result = KErrNone;
       
  1535 	
       
  1536 	//The identity to be removed
       
  1537 	TIdentityId id = static_cast<TIdentityId>(aMessage.Int0());
       
  1538 	
       
  1539 	//Check if the identity to be removed is not the default identity.
       
  1540 	TIdentityId defaultIdentity = iAuthDb2->DefaultIdentityL();
       
  1541 
       
  1542 	if(defaultIdentity != id)
       
  1543 		{
       
  1544 		iAuthDb2->RemoveIdentityL(id);
       
  1545 
       
  1546 		if (iLastIdentity && iLastIdentity->Id() == id)
       
  1547 			{
       
  1548 			delete iLastIdentity;
       
  1549 			iLastIdentity = 0;
       
  1550 			iLastAuthTime = 0L;
       
  1551 			}
       
  1552 		iPluginMgr->ForgetIdentityL(id);
       
  1553 		}
       
  1554 	else
       
  1555 		{
       
  1556 		result = KErrAuthServCanNotRemoveDefaultIdentity;
       
  1557 		}
       
  1558 	aMessage.Complete(result);
       
  1559 	}
       
  1560 
       
  1561 /**
       
  1562  * @return true if either the training mgr or authentication transaction
       
  1563  * is busy
       
  1564  **/
       
  1565 TBool CAuthServer::ServerBusy()
       
  1566 	{
       
  1567 	return iTrainingMgr->IsBusy() || iAuthTransaction != 0;
       
  1568 	}
       
  1569 
       
  1570 
       
  1571 /**
       
  1572  *
       
  1573  * @param aMessage the message to process
       
  1574  **/
       
  1575 void CAuthServer::TrainPluginL(const RMessage2& aMessage)
       
  1576 	{
       
  1577 	if (ServerBusy())
       
  1578 		{
       
  1579 		aMessage.Complete(KErrServerBusy);
       
  1580 		return;
       
  1581 		}
       
  1582 
       
  1583 	if (iLastIdentity == 0 || iLastIdentity->Id() != aMessage.Int0())
       
  1584 		{
       
  1585 		// we need a cached identity to get the protection key
       
  1586 		aMessage.Complete(KErrAuthServAuthenticationRequired);
       
  1587 		return;
       
  1588 		}
       
  1589 	
       
  1590 	TIdentityId retrainId = aMessage.Int0();
       
  1591 	
       
  1592 	//The default identity cannot be retrained.
       
  1593 	TIdentityId defaultIdentity = iAuthDb2->DefaultIdentityL();
       
  1594 		
       
  1595 	if(defaultIdentity == retrainId)
       
  1596 		{
       
  1597 		aMessage.Complete(KErrNotSupported);
       
  1598 		return;
       
  1599 		}
       
  1600 	
       
  1601 	HBufC8* data = HBufC8::NewLC(iLastIdentity->Key().KeyData().Size());
       
  1602 	*data = iLastIdentity->Key().KeyData(); 
       
  1603 
       
  1604 	CProtectionKey* key = CProtectionKey::NewL(data);
       
  1605 	CleanupStack::Pop(data);
       
  1606 	
       
  1607 	iTrainingMgr->TrainPluginL(aMessage, *key);
       
  1608 	
       
  1609     }
       
  1610 
       
  1611 
       
  1612   
       
  1613 /**
       
  1614  * Remove the supplied identity, plugin pair from the
       
  1615  * authentication database.
       
  1616  *
       
  1617  * @param aMessage  Client message which contains the
       
  1618  * 					identity and the plugin.
       
  1619  **/
       
  1620 void CAuthServer::ForgetPluginL(const RMessage2& aMessage)
       
  1621 	{
       
  1622 	if (ServerBusy())
       
  1623 		{
       
  1624 		aMessage.Complete(KErrServerBusy);
       
  1625 		return;
       
  1626 		}
       
  1627 	
       
  1628 	TIdentityId id   = static_cast<TIdentityId>(aMessage.Int0());
       
  1629 	TPluginId plugin = static_cast<TPluginId>(aMessage.Int1());
       
  1630 	TInt err         = KErrNone;
       
  1631 
       
  1632 	TInt numTrained = iAuthDb2->NumTrainedPluginsL(id);
       
  1633 
       
  1634 	switch (numTrained)
       
  1635 	  {
       
  1636 	case 0:
       
  1637 	  err = KErrAuthServNoSuchIdentity;
       
  1638 	  break;
       
  1639 	case 1:	
       
  1640 	  err = KErrAuthServCanNotRemoveLastPlugin;	  
       
  1641 	  break;
       
  1642 	default:
       
  1643 	  iAuthDb2->RemoveTrainedPluginL(id, plugin);
       
  1644 	  iPluginMgr->PluginL(plugin)->Forget(id);
       
  1645 	  break;
       
  1646 	  }
       
  1647 
       
  1648 	aMessage.Complete(err);
       
  1649 	}
       
  1650 
       
  1651 
       
  1652 void CAuthServer::EvaluateL(TPluginId aPluginId,
       
  1653 						   TIdentityId& aIdentityId,
       
  1654 						   CAuthExpressionImpl::TType aType,
       
  1655 						   TRequestStatus& aStatus)
       
  1656 	{
       
  1657 	
       
  1658 	if(aPluginId == 0 && aType == CAuthExpressionImpl::ENull)
       
  1659 		{
       
  1660 		aPluginId = iAuthRepository->DefaultPluginL();
       
  1661 		}
       
  1662 		
       
  1663   	CAuthPluginInterface* plugin = iPluginMgr->PluginL(aPluginId);
       
  1664 
       
  1665 	if (plugin != 0)
       
  1666 	  {
       
  1667 	  const HBufC* clientMessage = iAuthTransaction->ClientMessage();
       
  1668 	  
       
  1669 	  HBufC8*& data = iAuthTransaction->AddPluginL(aPluginId, aIdentityId);
       
  1670 	  	
       
  1671 	  if (plugin->IsActive())
       
  1672 		  {
       
  1673 		  plugin->Identify(aIdentityId, *clientMessage, data, aStatus);
       
  1674 		  }
       
  1675 		  
       
  1676 	  else
       
  1677 		  {
       
  1678 		  User::Leave(KErrAuthServPluginNotActive);
       
  1679 		  }
       
  1680 	  }
       
  1681 	}
       
  1682 /**
       
  1683  * @see MEvaluatorPluginInterface::Evaluate
       
  1684  **/
       
  1685 void CAuthServer::Evaluate(TPluginId aPluginId,
       
  1686 						   TIdentityId& aIdentityId,
       
  1687 						   CAuthExpressionImpl::TType aType,
       
  1688 						   TRequestStatus& aStatus)
       
  1689 	{
       
  1690 	TRAPD(err, EvaluateL(aPluginId, aIdentityId, aType, aStatus));
       
  1691 
       
  1692 	if (err != KErrNone) 
       
  1693 	  {
       
  1694 	  TRequestStatus* status = &aStatus;
       
  1695       User::RequestComplete(status, err);
       
  1696 	  }
       
  1697 	}
       
  1698 
       
  1699 /**
       
  1700  * Retrieve the preferred plugin for the supplied type and
       
  1701  * get an identity from it.
       
  1702  * @see MEvaluatorPluginInterface::Evaluate
       
  1703  *
       
  1704  **/
       
  1705 void CAuthServer::Evaluate(TAuthPluginType aPluginType,
       
  1706 						   TIdentityId& aIdentityId,
       
  1707 						   CAuthExpressionImpl::TType aType,	
       
  1708 						   TRequestStatus& aStatus)
       
  1709 	{
       
  1710 	TPluginId id = 0;
       
  1711 	TRAPD(r, id = iAuthDb2->PreferredPluginL(aPluginType));
       
  1712 	if (r == KErrNone)
       
  1713 	    {
       
  1714 	    Evaluate(id, aIdentityId, aType, aStatus);
       
  1715 	    }
       
  1716 	else
       
  1717 		{
       
  1718 		// Pass back error (can happen if a user preference hasn't been defined)
       
  1719 		aStatus = KRequestPending;
       
  1720 		TRequestStatus* rs = &aStatus;
       
  1721 		User::RequestComplete(rs, r);
       
  1722 		}
       
  1723 	}
       
  1724 
       
  1725 /**
       
  1726  * Completes the message and sends the id on it's way back to the client
       
  1727  **/
       
  1728 void CAuthServer::CompleteAuthenticationL(const RMessagePtr2& aMessage,
       
  1729 										 CIdentity* aId)
       
  1730 	{
       
  1731 	// write to client
       
  1732 	HBufC8* idBuff = HBufC8::NewLC(KDefaultBufferSize);
       
  1733 	TPtr8  idPtr =  idBuff->Des();
       
  1734 	RDesWriteStream writeStream(idPtr);
       
  1735 	writeStream << *aId;
       
  1736 	writeStream.CommitL();
       
  1737 
       
  1738 	TInt clientBuffSize = aMessage.GetDesMaxLength(2);
       
  1739   
       
  1740 	if (clientBuffSize >= idBuff->Size())
       
  1741 		{
       
  1742 		aMessage.Write(2, *idBuff);
       
  1743 		}
       
  1744 	else
       
  1745 		{
       
  1746 		User::Leave(KErrUnderflow);
       
  1747 		}
       
  1748 	
       
  1749 	CleanupStack::PopAndDestroy(idBuff);  
       
  1750   
       
  1751 	aMessage.Complete(KErrNone);
       
  1752 	}
       
  1753 
       
  1754 /**
       
  1755  * @see MEvaluatorClientInterface::EvaluationSucceeded
       
  1756  **/
       
  1757 void CAuthServer::EvaluationSucceeded(TIdentityId aIdentityId)
       
  1758 	{
       
  1759 
       
  1760 	TRAPD(err, EvaluationSucceededL(aIdentityId));
       
  1761 	
       
  1762 	switch(err)
       
  1763 	    {
       
  1764 	    case KErrNone:
       
  1765 	        break;
       
  1766 	    default:
       
  1767 	        EvaluationFailed(err);
       
  1768 	    }
       
  1769 	}
       
  1770 
       
  1771 
       
  1772 /**
       
  1773  * The full, leaving, implementation of EvaluationSucceeded (which is a trap
       
  1774  * harness).
       
  1775  *
       
  1776  * @param aIdentityId the identity discovered
       
  1777  **/
       
  1778 void CAuthServer::EvaluationSucceededL(TIdentityId aIdentityId)
       
  1779 	{
       
  1780 
       
  1781 	CAuthTransaction::RResultArray& results = iAuthTransaction->Results();
       
  1782 
       
  1783 	HBufC8* data = 0;
       
  1784 	TPluginId plugin = KUnknownPluginId;
       
  1785 
       
  1786 	TLastAuth lastAuth;
       
  1787 	lastAuth.iId = aIdentityId;
       
  1788 	
       
  1789 	for (TInt i = 0 ; i < results.Count() ; ++i)
       
  1790 		{
       
  1791 		if (aIdentityId == *results[i]->iId)
       
  1792 			{
       
  1793 			plugin = results[i]->iPlugin;
       
  1794 			data = results[i]->iData;
       
  1795 			UpdateAuthL(lastAuth, plugin); 
       
  1796 			}
       
  1797 		}
       
  1798   
       
  1799     CProtectionKey* key = 0;
       
  1800 
       
  1801     // Ensure that the ID and DATA are valid.
       
  1802     if (( aIdentityId != KUnknownIdentity ) && ( data != 0 ))
       
  1803         {
       
  1804         // get the protection key 
       
  1805         CTransientKeyInfo* keyInfo = iAuthDb2->KeyInfoL(aIdentityId, plugin);
       
  1806 		CleanupStack::PushL(keyInfo);
       
  1807         		  
       
  1808 		CTransientKey* transKey = keyInfo->CreateTransientKeyL(*data);
       
  1809         CleanupStack::PushL(transKey);
       
  1810   
       
  1811         key = transKey->DecryptL(keyInfo->EncryptedKey());
       
  1812         CleanupStack::PopAndDestroy(2,keyInfo);
       
  1813         CleanupStack::PushL(key);
       
  1814         
       
  1815         // convert to a client key if we need to
       
  1816         if (iAuthTransaction->ClientKey())
       
  1817            {
       
  1818            CProtectionKey* key2 = key->ClientKeyL(iAuthTransaction->ClientSid());
       
  1819             
       
  1820            CleanupStack::PopAndDestroy(key);
       
  1821            key = key2;
       
  1822            CleanupStack::PushL(key);
       
  1823            }   
       
  1824         }
       
  1825 	else
       
  1826 	    {
       
  1827 	    // create a blank key
       
  1828 	    key = CProtectionKey::NewLC(0);
       
  1829 	    
       
  1830 	    // clear the cached identity
       
  1831 	    delete iLastIdentity;
       
  1832         iLastIdentity = 0;
       
  1833         iLastAuthTime = 0L;
       
  1834         }
       
  1835 
       
  1836 	HBufC* str =
       
  1837 		StringOrNullLC(iAuthTransaction->WithString(), aIdentityId);
       
  1838 	
       
  1839 	// create the client identity object
       
  1840 	CIdentity* identity = CIdentity::NewL(aIdentityId, key, str);
       
  1841     CleanupStack::Pop(2, key);
       
  1842 	CleanupStack::PushL(identity);
       
  1843     
       
  1844     CompleteAuthenticationL(iAuthTransaction->Message(),
       
  1845     					    identity);
       
  1846 	
       
  1847     if (aIdentityId != KUnknownIdentity)
       
  1848         {
       
  1849 		TIdentityId oldId = iLastIdentity ? iLastIdentity->Id() : 0;
       
  1850 
       
  1851         // cache the latest id
       
  1852         delete iLastIdentity;
       
  1853         iLastIdentity = identity;
       
  1854         if(iLastAuthTime.UniversalTimeSecure() == KErrNoSecureTime)
       
  1855         	{
       
  1856             // Fall back to nonsecure time. 
       
  1857             iLastAuthTime.UniversalTime();
       
  1858             }
       
  1859 		// and publish it
       
  1860 		lastAuth.iAuthTime = iLastAuthTime;
       
  1861 		TPckg<TLastAuth> authPckg(lastAuth);
       
  1862 		User::LeaveIfError(iAuthProperty.Set(authPckg));
       
  1863 
       
  1864 		// if the identity has changed publish that fact	
       
  1865 		if (oldId != aIdentityId)
       
  1866 			{
       
  1867 			User::LeaveIfError(iAuthEventProperty.Set(aIdentityId));
       
  1868 			}
       
  1869 
       
  1870 		CleanupStack::Pop(identity);
       
  1871         }
       
  1872 	else
       
  1873 	   {
       
  1874 		CleanupStack::PopAndDestroy(identity);
       
  1875 	   }
       
  1876 	delete iAuthTransaction;
       
  1877 	iAuthTransaction = 0;
       
  1878     }
       
  1879 
       
  1880 /**
       
  1881  * Tells the authserver to cancel the current evaluation (i.e. call to
       
  1882  * the plugin)
       
  1883  *
       
  1884  * @see MEvaluatorPluginInterface::Evaluate
       
  1885  *
       
  1886  **/
       
  1887 void CAuthServer::CancelEvaluate()
       
  1888 	{
       
  1889 	if (iAuthTransaction)
       
  1890 		{
       
  1891 		TPluginId pluginId = iAuthTransaction->LastPluginId();
       
  1892 		CAuthPluginInterface* plugin = 0;
       
  1893 		TRAPD(err, (plugin = iPluginMgr->PluginL(pluginId)));
       
  1894 		if (err == KErrNone)
       
  1895 		  {
       
  1896 			plugin->Cancel();
       
  1897 		  }
       
  1898 		}
       
  1899 	}
       
  1900 
       
  1901 
       
  1902 /**
       
  1903  * @see MEvaluatorClientInterface::EvaluationFailed
       
  1904  **/
       
  1905 void CAuthServer::EvaluationFailed(TInt aReason)
       
  1906 	{
       
  1907 	iAuthTransaction->Message().Complete(aReason);
       
  1908 	delete iAuthTransaction;
       
  1909 	iAuthTransaction = 0;
       
  1910 	// there's nothing we can do here. Panic? 
       
  1911 	TRAP_IGNORE(ClearPropertiesL());
       
  1912 	}
       
  1913 	  
       
  1914 
       
  1915 void CAuthServer::UpdateAuthL(TLastAuth& aAuth, TPluginId aPlugin)
       
  1916 	{
       
  1917 	CAuthPluginInterface* plugin = iPluginMgr->PluginL(aPlugin);
       
  1918 
       
  1919 	aAuth.iMaxCombinations =
       
  1920 		Max(aAuth.iMaxCombinations, plugin->MinEntropy());
       
  1921 	aAuth.iFalsePositiveRate =
       
  1922 		Max(aAuth.iFalsePositiveRate, plugin->FalsePositiveRate());
       
  1923 	aAuth.iFalseNegativeRate =
       
  1924 		Max(aAuth.iFalseNegativeRate, plugin->FalseNegativeRate());
       
  1925 	++aAuth.iNumFactors;
       
  1926 	}
       
  1927 
       
  1928 
       
  1929 /**
       
  1930  * Free all the uncompressable memory before the 
       
  1931  * heap mark is set/reset to get the OOM tests to pass.
       
  1932  **/
       
  1933 void CAuthServer::FreeMemoryBeforeHeapMark()
       
  1934 	{
       
  1935 #ifdef _DEBUG
       
  1936 	
       
  1937 	if(iTrainingMgr)
       
  1938 		{
       
  1939 		delete iTrainingMgr;
       
  1940 		iTrainingMgr = 0;
       
  1941 		}
       
  1942 
       
  1943 	if(iPluginMgr)
       
  1944 		{
       
  1945 		delete iPluginMgr;
       
  1946 		iPluginMgr = 0;
       
  1947 		}
       
  1948 	
       
  1949 	if(iLastIdentity)
       
  1950 		{
       
  1951 		delete iLastIdentity;
       
  1952 		iLastIdentity = 0;
       
  1953 		}
       
  1954 	
       
  1955 	iAuthDb2->CloseDbFile();
       
  1956 	
       
  1957 	REComSession::FinalClose();
       
  1958 	
       
  1959 #endif
       
  1960 	}
       
  1961 
       
  1962 
       
  1963 /**
       
  1964  * Recreate all the variables deleted after the heap mark has 
       
  1965  * been set/reset.
       
  1966  **/
       
  1967 void CAuthServer::SetupVariablesAfterHeapMarkEndL()
       
  1968 	{
       
  1969 #ifdef _DEBUG
       
  1970 	
       
  1971 	//Opening Db file.
       
  1972 	TFileName dbName(KDbName);
       
  1973 	dbName[0] = RFs::GetSystemDriveChar();
       
  1974 	iAuthDb2->OpenDbFileL(iFs, dbName);
       
  1975 	
       
  1976 	//Creating plugin manager.
       
  1977 	if(!iPluginMgr)
       
  1978 		{
       
  1979 		iPluginMgr  = CPluginMgr::NewL();
       
  1980 		}
       
  1981 	
       
  1982 	//Creating training manager.
       
  1983 	if(!iTrainingMgr)
       
  1984 		{
       
  1985 		 iTrainingMgr = new (ELeave) CTrainingMgr(*iPluginMgr, *iAuthDb2, *iAuthRepository);
       
  1986 		}
       
  1987 #endif	
       
  1988 	}
       
  1989 
       
  1990 /**
       
  1991  * Things to be done before the heap mark is set/reset 
       
  1992  * during OOM testing
       
  1993  **/
       
  1994 void CAuthServer::DoPreHeapMarkOrCheckL()
       
  1995 	{
       
  1996 #ifdef _DEBUG
       
  1997 	FreeMemoryBeforeHeapMark();
       
  1998 #endif
       
  1999 	}
       
  2000 
       
  2001 /**
       
  2002  * Things to be done after the heap mark is set/reset 
       
  2003  * during OOM testing
       
  2004  **/
       
  2005 void CAuthServer::DoPostHeapMarkOrCheckL()
       
  2006 	{
       
  2007 #ifdef _DEBUG
       
  2008 	SetupVariablesAfterHeapMarkEndL();
       
  2009 #endif
       
  2010 	}
       
  2011