authenticationservices/authenticationserver/source/server/trainingmgr.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 24 Nov 2009 09:06:03 +0200
changeset 29 ece3df019add
permissions -rw-r--r--
Revision: 200948 Kit: 200948

/*
* 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: 
* CTrainingMgr - Auth Server helper class
*
*/


/**
 @file 
*/
#include <e32debug.h>
#include <s32mem.h>
#include "authserver_impl.h"
#include "log.h"
#include "authrepository.h"

using namespace AuthServer;


CTrainingMgr::CTrainingMgr(CPluginMgr&      aPluginMgr,
						   CAuthDb2&        aAuthDb,
						   CAuthRepository& aAuthRepository) :
	CActive(EPriorityStandard),
	iPluginMgr(&aPluginMgr),
	iAuthDb(&aAuthDb),
	iAuthRepository(aAuthRepository)
	{
	CActiveScheduler::Add(this);
	}

CTrainingMgr::~CTrainingMgr()
    {
    Cancel();
    Cleanup();
    }

/**
 * @param aMessage
 * @param aId The id number to use for the identity
 * @param aProtKey the protection key will be returned here
 */
void CTrainingMgr::RegisterIdentityL(const RMessage2& aMessage,
									TIdentityId aId,
									CProtectionKey&  aProtKey)
	{
	__ASSERT_ALWAYS(!IsActive(),
					User::Panic(KAuthServerShortName,
								EPanicTrainingMgrBusy));	

	iProtKey = &aProtKey;
	iMessage = new (ELeave) RMessage2(aMessage);
	iCurrentPluginIdx = 0;
	iIdentity = aId;
	iDescription = HBufC::NewL(aMessage.GetDesLength(1));
	TPtr ptr = iDescription->Des();
	aMessage.Read(1,ptr); 

	iState = ERegistrationFirstStep;
	DoRegistrationStepL();
	}

TBool CTrainingMgr::RegisterFirstIdentityL(TIdentityId aId,
										  CProtectionKey& aProtKey)
	{
	__ASSERT_ALWAYS(!IsActive(),
					User::Panic(KAuthServerShortName,
								EPanicTrainingMgrBusy));	

	iIdentity = aId;
	iProtKey  = &aProtKey;
    iDescription = HBufC::NewL(KDefaultUserDescription().Length());
    *iDescription = KDefaultUserDescription;
    
    TBool result = EFalse;
    
    //Get the default plugin id from the configuration file.
    TPluginId defaultPluginId = iAuthRepository.DefaultPluginL();
	
    CAuthPluginInterface* plugin = 0;
	TRAPD(err, plugin = iPluginMgr->PluginL(defaultPluginId));
	
	if ((err == KErrNone) &&
		(plugin->IsActive()) &&
		(plugin->Type() == EAuthKnowledge) && 
	    (plugin->DefaultData(aId, iResult) == KErrNone))
		{
		iCurrentPlugin = plugin->Id(); 
		AddIdentityL(); 
		AddTrainingResultL();
		result = ETrue;
		}	
	
	Cleanup();		    	
	return result;
	}

void CTrainingMgr::TrainPluginL(const RMessage2& aMessage,
							   CProtectionKey&  aProtKey)
	{
	__ASSERT_ALWAYS(!IsActive(),
					User::Panic(KAuthServerShortName,
								EPanicTrainingMgrBusy));	

	iProtKey = &aProtKey;
 	iIdentity = aMessage.Int0();
	iCurrentPlugin = aMessage.Int1();
	iMessage = new (ELeave) RMessage2(aMessage);
	CAuthPluginInterface* plugin = 0;

	TRAPD(err, plugin = iPluginMgr->PluginL(iCurrentPlugin));
	
	if (err != KErrNone)
		{
		iMessage->Complete(err);
		Cleanup();
		return;
		}
	else
		{
		SetActive();
		iState=ETrainingDone;
		if (plugin->IsActive())
			{
			plugin->Train(iIdentity, iResult, iStatus);
			}
		else
			{
			TRequestStatus* status = &iStatus;
			User::RequestComplete(status, KErrAuthServPluginNotActive);
			}
		}
	}

TInt CTrainingMgr::RunError(TInt aError)
    {
    iMessage->Complete(aError);
	return KErrNone;
	
  }

void CTrainingMgr::RunL()
	{
	if (iStatus != KErrNone && 
		(iStatus != KErrAuthServPluginCancelled && 
		iStatus != KErrAuthServPluginNotActive))
		{	
		// error results other than plugin cancelled or inactive handled  here
		Complete();
		return;
		}
	switch (iState)
		{
    	case ERegistrationFirstStep:
			if (AddIdentityL())
				{
				iState = ERegistering;
				}
			DoRegistrationStepL();
			break;
       case ERegistering:
			AddTrainingResultL();
    		DoRegistrationStepL();
    		break;
       case ETrainingDone:
            if (iStatus == KErrAuthServPluginCancelled)
			  {
    		  DEBUG_PRINTF(_L8("Plugin cancelled in training"));
			  }
    	    AddTrainingResultL();
    		Complete();
    		break;
    	case ERegistrationDone:
			WriteResultToMsgL();
    		Complete();
    		break;
    	}
	}

void CTrainingMgr::DoCancel()
	{
	CAuthPluginInterface* plugin = 0;
	TRAPD(err, plugin = iPluginMgr->PluginL(iCurrentPlugin));
	
	if (err == KErrNone)
		{
		iMessage->Complete(KErrCancel);
		plugin->Cancel();
		}
	else
		{
		User::Panic(KAuthServerShortName, EPanicNoSuchAuthPlugin);
		}
	Cleanup();
	}

TBool CTrainingMgr::IsBusy() const
  {
  return iState != EIdle;
  }

CTransientKeyInfo* CTrainingMgr::CreateKeyInfoLC()
	{
    __ASSERT_ALWAYS(iResult != 0 && iResult->Size() > 0,
					User::Panic(KAuthServerShortName,
								EPanicInvalidDefaultData));	

	CTransientKeyInfo* keyInfo = CTransientKeyInfo::NewLC(iCurrentPlugin);

	CTransientKey* key = keyInfo->CreateTransientKeyL(*iResult);
	CleanupStack::PushL(key);
    
	CEncryptedProtectionKey* encKey = key->EncryptL(*iProtKey);
	CleanupStack::PushL(encKey);
		
	keyInfo->SetEncryptedProtectionKeyL(encKey);
	CleanupStack::Pop(encKey);
	CleanupStack::PopAndDestroy(key);
	return keyInfo;
	}

TBool CTrainingMgr::AddTrainingResultL()
	{
	TBool result = EFalse;
	if (iStatus == KErrNone)
		{	
		CTransientKeyInfo* keyInfo = CreateKeyInfoLC();
		iAuthDb->SetTrainedPluginL(iIdentity, keyInfo->PluginId(),
								   *keyInfo);
		CleanupStack::PopAndDestroy(keyInfo);
		result = ETrue;
		}
	return result;
	}

TBool CTrainingMgr::AddIdentityL()
	{
	TBool result = EFalse;
	if (iStatus == KErrNone)
		{
		CTransientKeyInfo* keyInfo = CreateKeyInfoLC();
		iAuthDb->AddIdentityWithTrainedPluginL(iIdentity, *iDescription, *keyInfo);
		CleanupStack::PopAndDestroy(keyInfo);
		result = ETrue;
		}
	return result;
	}

void CTrainingMgr::DoRegistrationStepL()
	{
	

	if (iCurrentPluginIdx == iPluginMgr->ImplementationsL().Count())
		{	
		SetActive();
		iState = ERegistrationDone;
		TRequestStatus* status = &iStatus;
		User::RequestComplete(status, KErrNone);
		return;
		}

	iCurrentPlugin  =
		iPluginMgr->ImplementationsL()[iCurrentPluginIdx++]
	      ->ImplementationUid().iUid;
	
	CAuthPluginInterface* plugin = 0;
	TRAPD(err, plugin = iPluginMgr->PluginL(iCurrentPlugin));
	
	SetActive();
	switch (err)
		{
    	case KErrAuthServNoSuchPlugin:
			{
			// skip this plugin
			TRequestStatus* status = &iStatus;
			User::RequestComplete(status, KErrNone);
			return;
			}
    	case KErrNone:
			break;
    	default:
			User::Leave(err);
			break;
		}
	delete iResult;
	iResult = 0;
	if (plugin->IsActive())
		{
		plugin->Train(iIdentity, iResult, iStatus);
		}
	else
		{
		TRequestStatus* status = &iStatus;
		User::RequestComplete(status, KErrAuthServPluginNotActive);
		}
	}

void CTrainingMgr::WriteResultToMsgL()
    {

	if (iAuthDb->NumTrainedPluginsL(iIdentity) > 0)
		{
		CIdentity* identity = CIdentity::NewLC(iIdentity, iProtKey,
											   iDescription);
		iProtKey = 0;
		iDescription = 0;
	
		HBufC8* idBuff = HBufC8::NewLC(KDefaultBufferSize);
		TPtr8  idPtr =  idBuff->Des();
    
		RDesWriteStream writeStream(idPtr);
		CleanupClosePushL(writeStream);
    
		writeStream << *identity;
		writeStream.CommitL();

		TInt clientBuffSize = iMessage->GetDesMaxLength(0);
  
		if (clientBuffSize >= idBuff->Size())
			{
				iMessage->Write(0, *idBuff);
			}
		else
			{
				User::Leave(KErrUnderflow);
			}
		CleanupStack::PopAndDestroy(3,identity);
		}
	else
		{

		iStatus = KErrAuthServRegistrationFailed;
		}

    }
    
void CTrainingMgr::Complete()
	{
	iMessage->Complete(iStatus.Int());
	Cleanup();
	}

void CTrainingMgr::Cleanup()
	{
	if(iDescription)
		{
		delete iDescription;
		iDescription = 0;
		}
	
	if(iResult)
		{
		delete iResult;
		iResult = 0;
		}
	
	if(iMessage)
		{
		delete iMessage;
		iMessage = 0;
		}
	
	if(iProtKey)
		{
		delete iProtKey;
		iProtKey = 0;
		}
	
	iState = EIdle;
	}