eapol/eapol_framework/eapol_common/type/securid/core/eap_type_securid_client.cpp
changeset 0 c8830336c852
child 2 1c7bc153c08e
equal deleted inserted replaced
-1:000000000000 0:c8830336c852
       
     1 /*
       
     2 * Copyright (c) 2001-2006 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:  EAP and WLAN authentication protocols.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // This is enumeration of EAPOL source code.
       
    20 #if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
       
    21 	#undef EAP_FILE_NUMBER_ENUM
       
    22 	#define EAP_FILE_NUMBER_ENUM 114 
       
    23 	#undef EAP_FILE_NUMBER_DATE 
       
    24 	#define EAP_FILE_NUMBER_DATE 1127594498 
       
    25 #endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
       
    26 
       
    27 
       
    28 // INCLUDE FILES
       
    29 
       
    30 #include "eap_am_memory.h"
       
    31 #include "eap_state_notification.h"
       
    32 #include "eap_type_securid.h"
       
    33 #include "eap_type_securid_types.h"
       
    34 #include "eap_buffer.h"
       
    35 
       
    36 const u8_t EAP_SECURID_PIN_STRING[] = "pin";
       
    37 const u8_t EAP_SECURID_PASSCODE_STRING[] = "passcode";
       
    38 
       
    39 
       
    40 EAP_FUNC_EXPORT eap_status_e eap_type_securid_c::query_eap_identity(
       
    41 	const bool /*must_be_synchronous*/,
       
    42 	eap_variable_data_c * const identity,
       
    43 	const eap_am_network_id_c * const receive_network_id,
       
    44 	const u8_t eap_identifier)
       
    45 {
       
    46 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    47 
       
    48 	// Here we swap the addresses.
       
    49 	eap_am_network_id_c send_network_id(m_am_tools,
       
    50 		receive_network_id->get_destination_id(),
       
    51 		receive_network_id->get_source_id(),
       
    52 		receive_network_id->get_type());
       
    53 
       
    54 	m_identifier = eap_identifier;
       
    55 
       
    56 	eap_status_e status;
       
    57 
       
    58 	if (m_identity.get_is_valid_data() == false
       
    59         || m_identity.get_data_length() == 0)
       
    60 	{
       
    61 		EAP_TRACE_DEBUG(m_am_tools, 
       
    62 			TRACE_FLAGS_DEFAULT, (
       
    63 			EAPL("eap_type_securid_c::query_eap_identity(): Identity (username) is empty or invalid\n")));
       
    64 	
       
    65 		// Ask identity
       
    66 		if (m_is_pending == false)
       
    67 		{
       
    68 			m_is_pending = true;
       
    69 			status = m_am_type_securid->show_identity_query_dialog(m_eap_type, &m_identity);
       
    70 
       
    71 			EAP_TRACE_DEBUG(m_am_tools, 
       
    72 				TRACE_FLAGS_DEFAULT, (
       
    73 				EAPL("eap_type_securid_c::query_eap_identity(): show_identity_query_dialog returns %d\n"),
       
    74 				status));
       
    75 
       
    76 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    77 			return EAP_STATUS_RETURN(m_am_tools, status);
       
    78 		}
       
    79 		else
       
    80 		{
       
    81 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    82 			return EAP_STATUS_RETURN(m_am_tools, eap_status_pending_request);
       
    83 		}
       
    84 	}
       
    85 	else
       
    86 	{
       
    87 		EAP_TRACE_DEBUG(m_am_tools, 
       
    88 			TRACE_FLAGS_DEFAULT, (
       
    89 			EAPL("eap_type_securid_c::query_eap_identity(): m_identity (identity or username) is valid.\n")));
       
    90 
       
    91 		status = identity->set_copy_of_buffer(&m_identity);
       
    92 
       
    93 		m_state.set_state(eap_type_securid_state_identity_query);
       
    94 	}
       
    95 
       
    96 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    97 	return EAP_STATUS_RETURN(m_am_tools, status);
       
    98 }
       
    99 
       
   100 //--------------------------------------------------
       
   101 
       
   102 EAP_FUNC_EXPORT eap_status_e eap_type_securid_c::complete_eap_identity_query(
       
   103 	const eap_variable_data_c * const identity_utf8)
       
   104 {
       
   105 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   106 
       
   107 	EAP_TRACE_DATA_DEBUG(
       
   108 		m_am_tools,
       
   109 		TRACE_FLAGS_DEFAULT,
       
   110 		(EAPL("EAP_type_GTC: function: complete_eap_identity_query, identity:"),
       
   111 		 m_identity.get_data(m_identity.get_data_length()),
       
   112 		 m_identity.get_data_length()));
       
   113 
       
   114 	eap_status_e status = get_type_partner()->complete_eap_identity_query(
       
   115 		&m_send_network_id,
       
   116 		identity_utf8,
       
   117 		m_identifier);
       
   118 
       
   119 	if (status == eap_status_ok)
       
   120 	{
       
   121 		m_state.set_state(eap_type_securid_state_identity_query);
       
   122 	}
       
   123 
       
   124 	m_identity_asked = true;
       
   125 	m_is_pending = false;
       
   126 
       
   127 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   128 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   129 }
       
   130 
       
   131 //--------------------------------------------------
       
   132 
       
   133 eap_status_e eap_type_securid_c::client_packet_process(
       
   134 	eap_header_wr_c * const received_eap,
       
   135 	const u32_t eap_packet_length)
       
   136 {	
       
   137 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   138 	eap_status_e status = eap_status_drop_packet_quietly;
       
   139 
       
   140 	m_identifier = received_eap->get_identifier();
       
   141 
       
   142 	if (received_eap->get_type() == eap_type_identity)
       
   143 	{
       
   144 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   145 		return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly);
       
   146 	}
       
   147 
       
   148 	if (received_eap->get_code() == eap_code_failure)
       
   149 	{
       
   150 		if (m_state.is_valid_state(eap_type_securid_state_failure) == false)
       
   151 		{
       
   152 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   153 			return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly);
       
   154 		}
       
   155 
       
   156 		status = finish_unsuccessful_authentication(false);
       
   157 
       
   158 		m_state.set_state(eap_type_securid_state_failure);
       
   159 	}
       
   160 	else if (received_eap->get_code() == eap_code_success)
       
   161 	{
       
   162 		if (m_state.is_valid_state(eap_type_securid_state_success) == false)
       
   163 		{
       
   164 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   165 			return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly);
       
   166 		}
       
   167 
       
   168 		status = finish_successful_authentication();
       
   169 
       
   170 		m_state.set_state(eap_type_securid_state_success);
       
   171 	}
       
   172 	else if (received_eap->get_type() != m_eap_type)
       
   173 	{
       
   174 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   175 		return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly);
       
   176 	}
       
   177 	else if (received_eap->get_code() == eap_code_request) // Request
       
   178 	{
       
   179 		// Securid
       
   180 		if (m_eap_type == eap_type_securid)
       
   181 		{
       
   182 			status = client_securid_packet_process(
       
   183 				received_eap,
       
   184 				eap_packet_length);			    
       
   185 		}
       
   186 		// GTC
       
   187 		else if (m_eap_type == eap_type_generic_token_card)
       
   188 		{ 
       
   189 			status = client_gtc_packet_process(
       
   190 				received_eap,
       
   191 				eap_packet_length);			    
       
   192 		}
       
   193 	}
       
   194 
       
   195 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   196 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   197 }
       
   198 
       
   199 //--------------------------------------------------
       
   200 
       
   201 eap_status_e eap_type_securid_c::client_securid_packet_process(
       
   202 	eap_header_wr_c * const eap,
       
   203 	const u32_t eap_packet_length)
       
   204 {
       
   205 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   206 
       
   207 	eap_status_e status = eap_status_drop_packet_quietly;
       
   208 
       
   209 	if (eap_packet_length < eap->get_length())
       
   210 	{
       
   211 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   212 		return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly);
       
   213 	}
       
   214 
       
   215 	u32_t type_data_length = eap->get_data_length();
       
   216 
       
   217 	if (type_data_length == 0)
       
   218 	{
       
   219 		// Passcode query
       
   220 		if (m_is_pending == false)
       
   221 		{
       
   222 			m_is_pending = true;
       
   223 			m_am_type_securid->show_passcode_query_dialog(&m_passcode, true);
       
   224 			if (status != eap_status_pending_request)
       
   225 			{
       
   226 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   227 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   228 			}
       
   229 		}
       
   230 	}
       
   231 	else
       
   232 	{
       
   233 		u8_t * data = eap->get_type_data(type_data_length);
       
   234 		if (data == 0)
       
   235 		{
       
   236 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   237 		}
       
   238 		
       
   239 		if (type_data_length < 4)
       
   240 		{
       
   241 			return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly);
       
   242 		}
       
   243 		else if (type_data_length >= 4)
       
   244 		{
       
   245 			if (m_am_tools->memcmp(data, EAP_SECURID_PIN_STRING, 3) == 0
       
   246 				&& data[3] == 0x00)
       
   247 			{
       
   248 				// Pincode query
       
   249 				if (m_is_pending == false)
       
   250 				{
       
   251 					m_is_pending = true;
       
   252 					m_am_type_securid->show_pincode_query_dialog(&m_passcode, &m_pincode, true);
       
   253 					if (status != eap_status_pending_request)
       
   254 					{
       
   255 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   256 						return EAP_STATUS_RETURN(m_am_tools, status);
       
   257 					}
       
   258 				}
       
   259 			}
       
   260 			else if (type_data_length == 9
       
   261 				&& m_am_tools->memcmp(data, EAP_SECURID_PASSCODE_STRING, 8) == 0
       
   262 				&& data[8] == 0x00)
       
   263 			{
       
   264 				// Additional passcode query
       
   265 				if (m_is_pending == false)
       
   266 				{
       
   267 					m_is_pending = true;
       
   268 					m_am_type_securid->show_passcode_query_dialog(&m_passcode, false);
       
   269 					if (status != eap_status_pending_request)
       
   270 					{
       
   271 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   272 						return EAP_STATUS_RETURN(m_am_tools, status);
       
   273 					}
       
   274 				}
       
   275 			}
       
   276 			else
       
   277 			{
       
   278 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   279 				return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly);
       
   280 			}
       
   281 		}
       
   282 	}
       
   283 
       
   284 			
       
   285 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   286 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   287 }
       
   288 
       
   289 //--------------------------------------------------
       
   290 
       
   291 eap_status_e eap_type_securid_c::client_gtc_packet_process(
       
   292 	eap_header_wr_c * const eap,
       
   293 	const u32_t eap_packet_length)
       
   294 {
       
   295 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   296 
       
   297 	eap_status_e status = eap_status_drop_packet_quietly;
       
   298 
       
   299 	if (eap_packet_length < eap->get_length())
       
   300 	{
       
   301 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   302 		return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly);
       
   303 	}
       
   304 
       
   305 	u32_t type_data_length = eap->get_type_data_length();
       
   306 	if (type_data_length > 1020)
       
   307 	{
       
   308 		type_data_length = 1020; // Magic
       
   309 	}
       
   310 
       
   311 	// Passcode query
       
   312 	if (m_is_pending == false)
       
   313 	{
       
   314 		m_is_pending = true;
       
   315 
       
   316 #if defined(USE_EAP_CONFIGURATION_TO_SKIP_USER_INTERACTIONS)
       
   317 		if (m_skip_user_interactions == true)
       
   318 		{
       
   319 			EAP_TRACE_DEBUG(
       
   320 				m_am_tools,
       
   321 				TRACE_FLAGS_DEFAULT,
       
   322 				(EAPL("WARNING: EAP-GTC: eap_type_securid_c::client_gtc_packet_process(): skips user interactions\n")));
       
   323 
       
   324 			status = client_gtc_complete_user_input_query(&m_passcode);
       
   325 		}
       
   326 		else
       
   327 #endif //#if defined(USE_EAP_CONFIGURATION_TO_SKIP_USER_INTERACTIONS)
       
   328 		{
       
   329 			eap_variable_data_c message(m_am_tools);
       
   330 			status = message.set_copy_of_buffer(eap->get_type_data(type_data_length), type_data_length);
       
   331 			if (status != eap_status_ok)
       
   332 			{
       
   333 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   334 			}
       
   335 
       
   336 			status = m_am_type_securid->show_gtc_query_dialog(
       
   337 				&m_passcode,
       
   338 				message.get_data(),
       
   339 				message.get_data_length(),
       
   340 				true);
       
   341 		}
       
   342 	}
       
   343 			
       
   344 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   345 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   346 }
       
   347 
       
   348 //--------------------------------------------------
       
   349 
       
   350 EAP_FUNC_EXPORT eap_status_e eap_type_securid_c::client_securid_complete_passcode_query(
       
   351 	const eap_variable_data_c * const passcode_utf8)
       
   352 {
       
   353 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   354 
       
   355 	// Send passcode
       
   356 	u32_t packet_length = eap_header_base_c::get_type_data_start_offset(m_use_eap_expanded_type)
       
   357 		+ passcode_utf8->get_data_length() + 2 + 1;
       
   358 
       
   359 	eap_buf_chain_wr_c * packet = create_send_packet(packet_length);
       
   360 	if (!packet)
       
   361 	{
       
   362 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   363 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   364 	}
       
   365 
       
   366 	eap_header_base_c eap_header(
       
   367 		m_am_tools,
       
   368 		packet->get_data_offset(m_offset, packet_length),
       
   369 		packet_length);
       
   370 	if (eap_header.get_is_valid() == false)
       
   371 	{
       
   372 		delete packet;
       
   373 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   374 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   375 	}
       
   376 	eap_header.set_code(eap_code_response);
       
   377 	eap_header.set_identifier(m_identifier);
       
   378 	eap_header.set_length(
       
   379 		static_cast<u16_t>(packet_length),
       
   380 		m_use_eap_expanded_type);
       
   381 	eap_header.set_type(
       
   382 		m_eap_type,
       
   383 		m_use_eap_expanded_type);
       
   384 
       
   385 	u8_t * type_data = const_cast<u8_t *> (eap_header.get_type_data_offset(0, eap_header.get_type_data_length()));
       
   386 	if (type_data == 0)
       
   387 	{
       
   388 		delete packet;
       
   389 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   390 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   391 	}
       
   392 
       
   393 	{
       
   394 		m_am_tools->memset(type_data, 0x00, 2);
       
   395 		type_data += 2;
       
   396 		m_am_tools->memmove(
       
   397 			type_data,
       
   398 			passcode_utf8->get_data(passcode_utf8->get_data_length()),
       
   399 			passcode_utf8->get_data_length());
       
   400 		type_data += passcode_utf8->get_data_length();
       
   401 		type_data[0] = 0x00;
       
   402 	}
       
   403 
       
   404 	eap_status_e status = packet_send(packet, packet_length);
       
   405 	delete packet;
       
   406 
       
   407 	m_is_pending = false;
       
   408 
       
   409 	m_state.set_state(eap_type_securid_state_passcode_query);
       
   410 
       
   411 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   412 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   413 }
       
   414 
       
   415 //--------------------------------------------------
       
   416 
       
   417 EAP_FUNC_EXPORT eap_status_e eap_type_securid_c::client_securid_complete_pincode_query(
       
   418 	const eap_variable_data_c * const pincode,
       
   419 	const eap_variable_data_c * const passcode)
       
   420 {
       
   421 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   422 
       
   423 	m_is_first_pincode_query = false;
       
   424 
       
   425 	// Send pincode
       
   426 	u32_t packet_length = eap_header_base_c::get_type_data_start_offset(m_use_eap_expanded_type)
       
   427 		+ passcode->get_data_length() + 2 + 1 + pincode->get_data_length() + 1;
       
   428 	eap_buf_chain_wr_c * packet = create_send_packet(packet_length);
       
   429 	if (!packet)
       
   430 	{
       
   431 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   432 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   433 	}
       
   434 
       
   435 	eap_header_base_c eap_header(
       
   436 		m_am_tools,
       
   437 		packet->get_data_offset(m_offset, packet_length),
       
   438 		packet_length);
       
   439 	if (eap_header.get_is_valid() == false)
       
   440 	{
       
   441 		delete packet;
       
   442 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   443 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   444 	}
       
   445 	eap_header.set_code(eap_code_response);
       
   446 	eap_header.set_identifier(m_identifier);
       
   447 	eap_header.set_length(
       
   448 		static_cast<u16_t>(packet_length),
       
   449 		m_use_eap_expanded_type);
       
   450 	eap_header.set_type(
       
   451 		m_eap_type,
       
   452 		m_use_eap_expanded_type);
       
   453 
       
   454 	u8_t * type_data = const_cast<u8_t *> (eap_header.get_type_data_offset(0, eap_header.get_type_data_length()));
       
   455 	if (type_data == 0)
       
   456 	{
       
   457 		delete packet;
       
   458 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   459 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   460 	}
       
   461 
       
   462 	m_am_tools->memset(type_data, 0x00, 2);
       
   463 	type_data += 2;
       
   464 	// identity
       
   465 	m_am_tools->memmove(
       
   466 		type_data,
       
   467 		passcode->get_data(passcode->get_data_length()),
       
   468 		passcode->get_data_length());
       
   469 	type_data += passcode->get_data_length();
       
   470 	type_data[0] = 0x00;
       
   471 	type_data++;
       
   472 	m_am_tools->memmove(
       
   473 		type_data,
       
   474 		pincode->get_data(pincode->get_data_length()),
       
   475 		pincode->get_data_length());
       
   476 	type_data += pincode->get_data_length();
       
   477 	type_data[0] = 0x00;
       
   478 
       
   479 	eap_status_e status = packet_send(packet, packet_length);
       
   480 	delete packet;
       
   481 
       
   482 	m_is_pending = false;
       
   483 
       
   484 	m_state.set_state(eap_type_securid_state_pincode_query);
       
   485 
       
   486 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   487 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   488 }
       
   489 
       
   490 //--------------------------------------------------
       
   491 
       
   492 EAP_FUNC_EXPORT eap_status_e eap_type_securid_c::client_gtc_complete_user_input_query(
       
   493 	const eap_variable_data_c * const response_utf8)
       
   494 {
       
   495 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   496 
       
   497 	// Send response
       
   498 	u32_t packet_length = eap_header_base_c::get_type_data_start_offset(m_use_eap_expanded_type)
       
   499 		+ response_utf8->get_data_length();
       
   500 
       
   501 #if defined(USE_FAST_EAP_TYPE)
       
   502 	if (m_use_EAP_FAST_response == true)
       
   503 	{
       
   504 		packet_length += EAP_FAST_EAP_GTC_RESPONSE_PREFIX_LENGTH + m_identity.get_data_length() + EAP_FAST_EAP_GTC_RESPONSE_SEPARATOR_LENGTH;
       
   505 	}
       
   506 #endif //#if defined(USE_FAST_EAP_TYPE)
       
   507 
       
   508 	eap_buf_chain_wr_c * packet = create_send_packet(packet_length);
       
   509 	if (!packet)
       
   510 	{
       
   511 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   512 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   513 	}
       
   514 
       
   515 	eap_header_base_c eap_header(
       
   516 		m_am_tools,
       
   517 		packet->get_data_offset(m_offset, packet_length),
       
   518 		packet_length);
       
   519 	if (eap_header.get_is_valid() == false)
       
   520 	{
       
   521 		delete packet;
       
   522 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   523 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   524 	}
       
   525 	eap_header.set_code(eap_code_response);
       
   526 	eap_header.set_identifier(m_identifier);
       
   527 	eap_header.set_length(
       
   528 		static_cast<u16_t>(packet_length),
       
   529 		m_use_eap_expanded_type);
       
   530 	eap_header.set_type(
       
   531 		m_eap_type,
       
   532 		m_use_eap_expanded_type);
       
   533 
       
   534 	if (response_utf8->get_data_length() > 0UL)
       
   535 	{
       
   536 		u8_t * type_data = const_cast<u8_t *> (eap_header.get_type_data_offset(0, eap_header.get_type_data_length()));
       
   537 		if (type_data == 0)
       
   538 		{
       
   539 			delete packet;
       
   540 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   541 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   542 		}
       
   543 
       
   544 #if defined(USE_FAST_EAP_TYPE)
       
   545 		if (m_use_EAP_FAST_response == true)
       
   546 		{
       
   547 			eap_variable_data_c eap_fast_response(m_am_tools);
       
   548 			if (eap_fast_response.get_is_valid() == false)
       
   549 			{
       
   550 				delete packet;
       
   551 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   552 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   553 			}
       
   554 
       
   555 			eap_status_e status = eap_fast_response.set_copy_of_buffer(EAP_FAST_EAP_GTC_RESPONSE_PREFIX, EAP_FAST_EAP_GTC_RESPONSE_PREFIX_LENGTH);
       
   556 			if (status != eap_status_ok)
       
   557 			{
       
   558 				delete packet;
       
   559 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   560 			}
       
   561 
       
   562 			status = eap_fast_response.add_data(&m_identity);
       
   563 			if (status != eap_status_ok)
       
   564 			{
       
   565 				delete packet;
       
   566 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   567 			}
       
   568 
       
   569 			status = eap_fast_response.add_data(EAP_FAST_EAP_GTC_RESPONSE_SEPARATOR, EAP_FAST_EAP_GTC_RESPONSE_SEPARATOR_LENGTH);
       
   570 			if (status != eap_status_ok)
       
   571 			{
       
   572 				delete packet;
       
   573 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   574 			}
       
   575 
       
   576 			status = eap_fast_response.add_data(response_utf8);
       
   577 			if (status != eap_status_ok)
       
   578 			{
       
   579 				delete packet;
       
   580 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   581 			}
       
   582 
       
   583 			m_am_tools->memmove(
       
   584 				type_data,
       
   585 				eap_fast_response.get_data(),
       
   586 				eap_fast_response.get_data_length());
       
   587 		}
       
   588 		else
       
   589 #endif //#if defined(USE_FAST_EAP_TYPE)
       
   590 		{
       
   591 			m_am_tools->memmove(
       
   592 				type_data,
       
   593 				response_utf8->get_data(response_utf8->get_data_length()),
       
   594 				response_utf8->get_data_length());
       
   595 		}
       
   596 	}
       
   597 
       
   598 	eap_status_e status = packet_send(packet, packet_length);
       
   599 	delete packet;
       
   600 
       
   601 	m_is_pending = false;
       
   602 
       
   603 	m_state.set_state(eap_type_securid_state_gtc_user_input_query);
       
   604 
       
   605 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   606 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   607 }
       
   608 
       
   609 //--------------------------------------------------
       
   610 
       
   611 
       
   612 // End.