eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/EapAkaInterface.cpp
changeset 0 c8830336c852
child 2 1c7bc153c08e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/eapol_symbian/am/type/aka/symbian/EapAkaInterface.cpp	Thu Dec 17 08:47:43 2009 +0200
@@ -0,0 +1,485 @@
+/*
+* Copyright (c) 2001-2006 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:  EAP and WLAN authentication protocols.
+*
+*/
+
+
+// This is enumeration of EAPOL source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 603 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+// INCLUDE FILES
+#include "EapAkaInterface.h"
+#include "eap_type_aka_types.h"
+
+#include <mmtsy_names.h>
+#include <etelmmerr.h>
+
+// ================= MEMBER FUNCTIONS =======================
+
+CEapAkaInterface::CEapAkaInterface(abs_eap_am_tools_c* const aTools, eap_am_type_aka_symbian_c* const aParent)
+: CActive(CActive::EPriorityStandard)
+, iParent(aParent)
+, m_am_tools(aTools)
+, iAuthenticationData(NULL)
+, iQueryId(EQueryNone)
+, iMMETELConnectionStatus(EFalse)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+CEapAkaInterface* CEapAkaInterface::NewL(abs_eap_am_tools_c* const aTools, 
+											   eap_am_type_aka_symbian_c* const aParent)
+{
+	CEapAkaInterface* self = new(ELeave) CEapAkaInterface(aTools, aParent);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+}
+
+//--------------------------------------------------
+
+void CEapAkaInterface::ConstructL()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	
+	CActiveScheduler::Add(this);	
+	
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+CEapAkaInterface::~CEapAkaInterface()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	if(IsActive())
+	{
+		Cancel();		
+	}
+	
+	/*
+	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Closing RMobilePhone and MMETEL.\n")));
+	
+	iPhone.Close();
+	iServer.Close(); // Phone module is unloaded automatically when RTelServer session is closed
+	*/
+	DisconnectMMETel();
+	
+	delete iAuthenticationData;
+	iAuthenticationData = NULL;		
+	
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+void CEapAkaInterface::QueryIMSIL()
+{	
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Querying IMSI.\n")));
+	
+	iQueryId = EQueryIMSI;
+		
+	// Create MMETEl connection.
+	User::LeaveIfError( CreateMMETelConnectionL() );
+	
+   	iPhone.GetSubscriberId( iStatus, iSubscriberId ); 
+ 	
+	if( !IsActive() )
+	{
+		SetActive();
+	}  
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+void CEapAkaInterface::QueryRESL( eap_variable_data_c * const aRand, eap_variable_data_c * const aAUTN )
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Querying RES, CK, IK and AUTS.\n")));
+
+	iQueryId = EQueryRES;
+
+	EAP_TRACE_DATA_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT,(EAPL("RAND"),
+			aRand->get_data(aRand->get_data_length()),
+			aRand->get_data_length()));
+			
+	EAP_TRACE_DATA_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT,(EAPL("AUTN"),
+			aAUTN->get_data(aAUTN->get_data_length()),
+			aAUTN->get_data_length()));
+			
+	// Rand must be 16 bytes
+	if (static_cast<u16_t>( aRand->get_data_length() ) != EAP_TYPE_AKA_MINIMUM_RAND_LENGTH)
+	{
+		EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Illegal RAND - Incorrect length.\n")));
+		User::Leave(KErrArgument);
+	}
+
+	// AUTN must be 16 bytes
+	if (static_cast<u16_t>( aAUTN->get_data_length() ) != EAP_TYPE_AKA_MINIMUM_AUTN_LENGTH)
+	{
+		EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Illegal AUTN - Incorrect length.\n")));
+		User::Leave(KErrArgument);
+	}
+	
+	// Create MMETEL connection.
+	User::LeaveIfError( CreateMMETelConnectionL() );
+	
+	// Open CustomAPI.
+	User::LeaveIfError( iCustomAPI.Open(iPhone) );
+	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: OPENED CUSTOM API \n")));
+	
+	u8_t *rand = aRand->get_data(aRand->get_data_length());
+	u8_t *autn = aAUTN->get_data(aAUTN->get_data_length());
+	
+	iEAPAka.iRandomParameters.Copy( rand, EAP_TYPE_AKA_MINIMUM_RAND_LENGTH); //Copy the rand to iEAPAka
+	
+	iEAPAka.iAUTN.Copy( autn, EAP_TYPE_AKA_MINIMUM_AUTN_LENGTH); //Copy the AUTN to iEAPAka
+
+	//Pack iEAPAka to iAuthenticationData for passing it to the custom API.
+	iAuthenticationData = new (ELeave) RMmCustomAPI::TAkaDataPckg( iEAPAka );
+	
+	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Before querying CustomAPI GetWlanSimAuthenticationData \n")));
+		
+    iCustomAPI.GetWlanSimAuthenticationData( iStatus, *iAuthenticationData );	
+    
+	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: After querying CustomAPI. iStatus.Int() =%d \n"), iStatus.Int() ));
+    
+	if( !IsActive() )
+	{
+		SetActive();
+	}  
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+ 
+void CEapAkaInterface::DoCancel()
+{
+	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("CEapAkaInterface::DoCancel() - Cancelling MMETEL query.\n") ) );
+
+	// Cancel the request.
+	iCustomAPI.CancelAsyncRequest( ECustomGetSimAuthenticationDataIPC );
+	
+	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("CEapAkaInterface::DoCancel(): CANCELLED CUSTOM API REQUEST \n")));
+}
+
+//--------------------------------------------------
+
+void CEapAkaInterface::RunL()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	
+	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("CEapAkaInterface::RunL(). iStatus.Int() =%d \n"), iStatus.Int() ));
+
+	
+	TInt error = KErrNone;
+	eap_status_e completion_status = eap_status_ok;
+	eap_status_e AuthenticationStatus = eap_status_ok;
+	
+	eap_variable_data_c imsi(m_am_tools); // Keeping it here to avoid "error" in ARMV5 build.
+	
+	// This is to store the IMSI, which is in Unicode form.
+	eap_variable_data_c imsiInUnicode(m_am_tools); // Keeping it here to avoid "error" in ARMV5 build.
+	
+	eap_variable_data_c res(m_am_tools);
+	eap_variable_data_c ck(m_am_tools);
+	eap_variable_data_c ik(m_am_tools);
+	eap_variable_data_c auts(m_am_tools);	
+	
+	if (iStatus.Int() == KErrNone)
+	{	
+		switch( iQueryId )
+		{
+			case EQueryIMSI:
+				EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Got IMSI reply.\n")));
+						
+				EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("IMSI"),
+						iSubscriberId.Ptr(),
+						iSubscriberId.Size()));
+				
+				// Convert the IMSI from unicode to UTF8 characters.
+
+				completion_status = imsiInUnicode.set_buffer(iSubscriberId.Ptr(), iSubscriberId.Size(), false, false);
+
+				if (completion_status != eap_status_ok)
+				{
+					imsiInUnicode.reset();
+					EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Could not set buffer for IMSI.\n")));
+					
+					// No need to continue. The request will be completed towards the end, in this kind of error situation.
+					break;
+				}
+				
+				completion_status = m_am_tools->convert_unicode_to_utf8(imsi, imsiInUnicode);
+				
+				if (completion_status != eap_status_ok)
+				{
+					imsi.reset();
+					EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Could not convert IMSI from UNICODE to UTF8.\n")));
+					break;					
+				}
+				
+				// Complete. This happens only if completion_status is eap_status_ok so far.
+				TRAP(error, iParent->complete_AKA_imsi_L(&imsi, completion_status));
+			
+			break;
+			
+			case EQueryRES:
+				EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("####AKA interface: Got RES, CK, IK and AUTS reply. ####\n")));			
+				
+				EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("RES"),
+						iEAPAka.iRES.Ptr(),
+						iEAPAka.iRES.Size()));
+						
+				EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("CK"),
+						iEAPAka.iCK.Ptr(),
+						iEAPAka.iCK.Size()));
+
+				EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("IK"),
+						iEAPAka.iIK.Ptr(),
+						iEAPAka.iIK.Size()));
+						
+				EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AUTS"),
+						iEAPAka.iAUTS.Ptr(),
+						iEAPAka.iAUTS.Size()));
+										
+				delete iAuthenticationData;
+				iAuthenticationData = NULL;	
+						
+				// Close the custom API since we don't need it any more.
+				iCustomAPI.Close();				
+				EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("CEapAkaInterface::RunL() - KErrNone case: CLOSED CUSTOM API \n")));
+				
+				completion_status = res.set_buffer(iEAPAka.iRES.Ptr(), iEAPAka.iRES.Size(), false, false);
+				if (completion_status != eap_status_ok)
+				{
+					res.reset();
+					EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Could not set buffer for RES.\n")));
+					break;
+				}
+
+				completion_status = ck.set_buffer(iEAPAka.iCK.Ptr(), iEAPAka.iCK.Size(), false, false);
+				if (completion_status != eap_status_ok)
+				{
+					ck.reset();
+					EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Could not set buffer for CK.\n")));
+					break;
+				}
+
+				completion_status = ik.set_buffer(iEAPAka.iIK.Ptr(), iEAPAka.iIK.Size(), false, false);
+				if (completion_status != eap_status_ok)
+				{
+					ik.reset();
+					EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Could not set buffer for IK.\n")));
+					break;
+				}
+
+				completion_status = auts.set_buffer(iEAPAka.iAUTS.Ptr(), iEAPAka.iAUTS.Size(), false, false);
+				if (completion_status != eap_status_ok)
+				{
+					auts.reset();
+					EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Could not set buffer for AUTS.\n")));
+					break;
+				}
+			
+				// Complete. This happens only if completion_status is eap_status_ok so far.		
+				TRAP(error, iParent->complete_AKA_RES_L( &res, &ck, &ik, &auts ) );			
+			
+			break;
+		}
+	} 
+	else 
+	{
+		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Got error reply.\n")));	
+	
+		switch( iQueryId )
+		{
+			case EQueryIMSI:
+			
+				// Error with IMSI. Reset it and complete the request.			
+				imsi.reset();
+				EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Error in IMSI.\n")));
+							
+				TRAP(error, iParent->complete_AKA_imsi_L(&imsi));
+			break;
+			
+			case EQueryRES:
+			
+				// Re-synchronization needed or error with RES or CK or IK.
+				
+				// We have to close the custom API anyway. 
+				iCustomAPI.Close();				
+				EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("CEapAkaInterface::RunL() - error case: CLOSED CUSTOM API \n")));
+				
+				// Just to verify if there is any values set.
+				
+				EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("RES"),
+						iEAPAka.iRES.Ptr(),
+						iEAPAka.iRES.Size()));
+						
+				EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("CK"),
+						iEAPAka.iCK.Ptr(),
+						iEAPAka.iCK.Size()));
+
+				EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("IK"),
+						iEAPAka.iIK.Ptr(),
+						iEAPAka.iIK.Size()));
+						
+				EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AUTS"),
+						iEAPAka.iAUTS.Ptr(),
+						iEAPAka.iAUTS.Size()));				
+				
+				// Complete the request after resetting res, ck and ik.
+				// auts might have some value if the error is related to re-synchronization. So don't reset it.
+				res.reset();
+				ck.reset();
+				ik.reset();
+				
+				completion_status = auts.set_buffer(iEAPAka.iAUTS.Ptr(), iEAPAka.iAUTS.Size(), false, false);
+				if (completion_status != eap_status_ok)
+				{
+					auts.reset();
+					EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("AKA interface: Could not set buffer for AUTS.\n")));
+					break;
+				}
+				
+				// Check if the failure is due to re-synchronization fail.
+				if(	iStatus.Int() == KErrMMEtelSqnVerificationFailed ) 
+				{
+					// Re-synchronization failure.
+					AuthenticationStatus = eap_status_syncronization_failure;
+				}
+				else
+				{
+					// Authentication failed. Errors could be KErrMMEtelMacVerificationFailed or KErrMMEtelAuthenticateFailed also.
+					AuthenticationStatus = eap_status_authentication_failure;
+				}
+			
+				// Complete. This happens only if completion_status is eap_status_ok so far.
+				TRAP(error, iParent->complete_AKA_RES_L( &res, &ck, &ik, &auts, AuthenticationStatus, completion_status ) );
+			break;
+		}
+	}
+	
+	if( completion_status != eap_status_ok  && iQueryId == EQueryIMSI )
+	{
+		TRAP(error, iParent->complete_AKA_imsi_L(&imsi, completion_status));		
+	}
+
+	if( completion_status != eap_status_ok  && iQueryId == EQueryRES )
+	{
+		TRAP(error, iParent->complete_AKA_RES_L( &res, &ck, &ik, &auts, AuthenticationStatus, completion_status ) );
+	}	
+
+	DisconnectMMETel();
+	
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+TInt CEapAkaInterface::CreateMMETelConnectionL()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Creating MMETel connection.\n")));
+
+	TInt errorCode = KErrNone;
+	
+	// MMETel need to be connected only once.    
+    if( !iMMETELConnectionStatus )
+    {
+		RTelServer::TPhoneInfo phoneInfo;
+		TInt phoneCount = 0;
+
+		// Connect to ETel server
+		User::LeaveIfError( iServer.Connect() ); 	
+		
+	    EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Connected to ETel server.\n")));	
+
+		// This function loads an ETel TSY module, mmtsy.
+		errorCode = iServer.LoadPhoneModule( KMmTsyModuleName );	
+		
+	    EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Loaded phone module.\n")));	    
+		
+		if ( errorCode != KErrNone && errorCode != KErrAlreadyExists )
+		{
+			User::Leave( errorCode );
+		}
+
+		iServer.SetExtendedErrorGranularity( RTelServer::EErrorExtended );
+
+		// This function retrieves the total number of phones supported by all 
+		// the currently loaded ETel (TSY) modules.
+		User::LeaveIfError( iServer.EnumeratePhones( phoneCount ) );	
+		
+		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Number of phones supported by the loaded ETel = %d.\n"), phoneCount));
+		
+		// This function retrieves information associated with the specified phone
+		while ( ( phoneCount-- ) && ( phoneInfo.iName != KMmTsyPhoneName ) ) 
+		{ 
+			User::LeaveIfError( iServer.GetPhoneInfo( phoneCount, phoneInfo ) );		
+			
+		    EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Got phone info.\n")));
+		} 
+
+		// This function opens a phone subsession by name. ("DefaultPhone").
+		User::LeaveIfError( iPhone.Open( iServer, phoneInfo.iName ) );	
+		
+	    EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Opened phone subsession.\n")));
+		
+		// MMETel connected and the phone module loaded fine.	
+		iMMETELConnectionStatus = ETrue; 	
+    }
+    else
+    {
+    	// MMETel already connected.
+	    EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("MMETel connected once already.\n")));
+    }
+	    
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+    
+    return errorCode;	
+}
+
+void CEapAkaInterface::DisconnectMMETel()
+{
+    if( iMMETELConnectionStatus )
+    {
+		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Closing RMobilePhone and MMETEL.\n")));
+		
+		iPhone.Close();
+		iServer.Close(); // Phone module is unloaded automatically when RTelServer session is closed
+		
+		iMMETELConnectionStatus = EFalse;
+    }
+    else
+    {
+		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("RMobilePhone and MMETEL already closed.\n")));    	
+    }	
+}
+
+// End of file