authenticationservices/authenticationserver/source/server/trainingmgr.cpp
changeset 29 ece3df019add
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/authenticationservices/authenticationserver/source/server/trainingmgr.cpp	Tue Nov 24 09:06:03 2009 +0200
@@ -0,0 +1,381 @@
+/*
+* 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;
+	}