eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_application_ttls_plain_mschapv2.cpp
/*
* 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.
*
*/
/*
* %version: 8 %
*/
// This is enumeration of EAPOL source code.
#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
#undef EAP_FILE_NUMBER_ENUM
#define EAP_FILE_NUMBER_ENUM 124
#undef EAP_FILE_NUMBER_DATE
#define EAP_FILE_NUMBER_DATE 1127594498
#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
#include "eap_am_memory.h"
#include "eap_tools.h"
#include "eap_am_tools.h"
#include "eap_core.h"
#include "eap_type_tls_peap_types.h"
#include "tls_record_header.h"
#include "abs_tls_base_application.h"
#include "tls_application_eap_core.h"
#include "tls_peap_types.h"
#include "tls_peap_tlv_header.h"
#include "eap_diameter_avp_header.h"
#include "eap_state_notification.h"
#include "eap_crypto_api.h"
#include "eap_header_string.h"
#include "abs_eap_am_mutex.h"
#include "eap_config.h"
#include "eapol_header.h"
#include "eap_network_id_selector.h"
#include "eap_tlv_message_data.h"
#include "eap_array_algorithms.h"
#include "eap_automatic_variable.h"
#include "eap_base_type.h"
#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
#include "eap_type_mschapv2_types.h"
#include "eap_type_mschapv2_header.h"
#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
//--------------------------------------------------
#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::check_ttls_plain_mschapv2_payloads(
eap_diameter_payloads_c * const payloads,
eap_ttls_tunneled_message_type_e * const message_type)
{
EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
EAP_TRACE_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("TTLS: %s: tls_application_eap_core_c::check_ttls_plain_mschapv2_payloads()\n"),
(m_is_client == true ? "client": "server")));
EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::check_ttls_plain_mschapv2_payloads()");
*message_type = eap_ttls_tunneled_message_type_none;
eap_status_e status(eap_status_not_found);
eap_array_c<eap_diameter_avp_code_c> needed_payloads(m_am_tools);
if (m_is_client == false)
{
{
// First check are there User-Name, MS-CHAP-Challenge and MS-CHAP2-Response AVPs.
needed_payloads.reset();
// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
eap_diameter_avp_code_c code_user_name(
eap_diameter_avp_code_user_name);
status = needed_payloads.add_object(&code_user_name, false);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
eap_diameter_avp_code_c code_ms_chap_challenge(
eap_diameter_vendor_code_of_microsoft_ms_chap_challenge.get_code());
status = needed_payloads.add_object(&code_ms_chap_challenge, false);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
eap_diameter_avp_code_c code_ms_chap2_response(
eap_diameter_vendor_code_of_microsoft_ms_chap2_response.get_code());
status = needed_payloads.add_object(&code_ms_chap2_response, false);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Test the required attribute.
status = payloads->check_payloads_existense(
&needed_payloads);
if (status == eap_status_ok)
{
// This packet includes required AVPs.
status = payloads->check_mandatory_payloads(
&needed_payloads);
if (status == eap_status_ok)
{
// All mandatory AVPs are included.
*message_type = eap_ttls_tunneled_message_type_ms_chapv2_response;
EAP_TRACE_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("Match User-Name, MS-CHAP-Challenge and MS-CHAP2-Response AVPs.\n")));
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
}
}
{
// Second check are there MS-CHAP-NT-Enc-PW, MS-CHAP2-CPW, and MS-CHAP-Challenge AVPs.
needed_payloads.reset();
// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
eap_diameter_avp_code_c code_ms_chap_nt_enc_pw(
eap_diameter_vendor_code_of_microsoft_ms_chap_nt_enc_pw.get_code());
status = needed_payloads.add_object(&code_ms_chap_nt_enc_pw, false);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
eap_diameter_avp_code_c code_ms_chap2_cpw(
eap_diameter_vendor_code_of_microsoft_ms_chap2_cpw.get_code());
status = needed_payloads.add_object(&code_ms_chap2_cpw, false);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
eap_diameter_avp_code_c code_ms_chap_challenge(
eap_diameter_vendor_code_of_microsoft_ms_chap_challenge.get_code());
status = needed_payloads.add_object(&code_ms_chap_challenge, false);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Test the required attribute.
status = payloads->check_payloads_existense(
&needed_payloads);
if (status == eap_status_ok)
{
// This packet includes required AVPs.
status = payloads->check_mandatory_payloads(
&needed_payloads);
if (status == eap_status_ok)
{
// All mandatory AVPs are included.
*message_type = eap_ttls_tunneled_message_type_ms_chapv2_change_password;
EAP_TRACE_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("Match MS-CHAP-NT-Enc-PW, MS-CHAP2-CPW, and MS-CHAP-Challenge AVPs.\n")));
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
}
}
}
else //if (m_is_client == true)
{
{
// First check are there MS-CHAP2-Success AVP.
needed_payloads.reset();
// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
eap_diameter_avp_code_c code_ms_chap2_success(
eap_diameter_vendor_code_of_microsoft_ms_chap2_success.get_code());
status = needed_payloads.add_object(&code_ms_chap2_success, false);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Test the required attribute.
status = payloads->check_payloads_existense(
&needed_payloads);
if (status == eap_status_ok)
{
// This packet includes required AVPs.
status = payloads->check_mandatory_payloads(
&needed_payloads);
if (status == eap_status_ok)
{
// All mandatory AVPs are included.
*message_type = eap_ttls_tunneled_message_type_ms_chapv2_success;
EAP_TRACE_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("Match MS-CHAP2-Success AVP.\n")));
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
}
}
{
// Second check are there MS-CHAP2-Error AVP.
needed_payloads.reset();
// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
eap_diameter_avp_code_c code_ms_chap_error(
eap_diameter_vendor_code_of_microsoft_ms_chap_error.get_code());
status = needed_payloads.add_object(&code_ms_chap_error, false);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Test the required attribute.
status = payloads->check_payloads_existense(
&needed_payloads);
if (status == eap_status_ok)
{
// This packet includes required AVPs.
status = payloads->check_mandatory_payloads(
&needed_payloads);
if (status == eap_status_ok)
{
// All mandatory AVPs are included.
*message_type = eap_ttls_tunneled_message_type_ms_chapv2_error;
EAP_TRACE_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("Match MS-CHAP2-Error AVP.\n")));
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
}
}
}
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
//--------------------------------------------------
#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_server_handles_ms_chapv2_response(
eap_diameter_payloads_c * const /* payloads */,
const u8_t received_eap_identifier)
{
EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
EAP_TRACE_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("PEAP: %s: function: tls_application_eap_core_c::ttls_server_handles_ms_chapv2_response(): ")
EAPL("this = 0x%08x\n"),
(m_is_client == true ? "client": "server"),
this));
EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_server_handles_ms_chapv2_response()");
eap_status_e status(eap_status_not_found);
eap_diameter_variable_data_c * const user_name_payload
= m_ttls_received_payloads.get_payload(eap_diameter_avp_code_user_name);
if (user_name_payload == 0)
{
return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
}
eap_variable_data_c * const user_name
= user_name_payload->get_payload_buffer();
if (user_name->get_is_valid_data() == false)
{
return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
}
status = get_application_partner()->get_ttls_implicit_challenge(
&m_ttls_implicit_challenge,
EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_FULL_LENGTH);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
const u8_t * const mschapv2_challenge = m_ttls_implicit_challenge.get_data_offset(
EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_OFFSET,
EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_LENGTH);
if (mschapv2_challenge == 0)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
EAP_TRACE_DATA_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("ttls_server_handles_ms_chapv2_response(): mschapv2_challenge"),
mschapv2_challenge,
EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_LENGTH));
{
eap_variable_data_c memory_store_key(m_am_tools);
eap_status_e status = memory_store_key.set_copy_of_buffer(
EAP_MSCHAPV2_IMPLICIT_CHALLENGE_HANDLE_KEY,
sizeof(EAP_MSCHAPV2_IMPLICIT_CHALLENGE_HANDLE_KEY));
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
status = memory_store_key.add_data(
&m_is_client,
sizeof(m_is_client));
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
eap_network_id_selector_c state_selector(
m_am_tools,
&m_receive_network_id);
status = memory_store_key.add_data(
&state_selector);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
eap_tlv_message_data_c tlv_data(m_am_tools);
status = tlv_data.add_message_data(
eap_type_mschapv2_implicit_challenge,
EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_LENGTH,
mschapv2_challenge);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
status = m_am_tools->memory_store_remove_data(&memory_store_key);
if (status != eap_status_ok
&& status != eap_status_not_found)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
status = m_am_tools->memory_store_add_data(
&memory_store_key,
&tlv_data,
eap_type_default_credential_timeout);
if (status != eap_status_ok)
{
EAP_TRACE_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("ttls_server_handles_ms_chapv2_response(): cannot store credentials\n")));
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
}
// We must create EAP-Response/Identity message and forward that message
// to tunneled EAP-MsChapv2.
u32_t eap_length = eap_header_wr_c::get_header_length() + 1ul + user_name->get_data_length();
eap_buf_chain_wr_c eap_packet_buffer(
eap_write_buffer,
m_am_tools,
eap_length);
if (eap_packet_buffer.get_is_valid() == false)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
eap_header_wr_c forwarded_eap_packet(
m_am_tools,
eap_packet_buffer.get_data(eap_length),
eap_length);
if (forwarded_eap_packet.get_is_valid() == false)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
forwarded_eap_packet.reset_header(
static_cast<u16_t>(eap_length),
m_use_eap_expanded_type);
forwarded_eap_packet.set_identifier(received_eap_identifier);
forwarded_eap_packet.set_code(eap_code_response);
forwarded_eap_packet.set_length(
static_cast<u16_t>(eap_length),
m_use_eap_expanded_type);
forwarded_eap_packet.set_type(
eap_type_identity,
m_use_eap_expanded_type);
u8_t * const eap_type_data = forwarded_eap_packet.get_type_data(user_name->get_data_length());
if (eap_type_data == 0)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
m_am_tools->memmove(eap_type_data, user_name->get_data(), user_name->get_data_length());
set_ttls_tunneled_message_state(eap_ttls_tunneled_message_state_process_identity_response);
status = packet_forward_to_tunnel(
&m_receive_network_id,
&forwarded_eap_packet,
eap_length);
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
//--------------------------------------------------
#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_server_handles_ms_chapv2_change_password(
eap_diameter_payloads_c * const /* payloads */,
const u8_t received_eap_identifier)
{
EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
EAP_TRACE_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("TTLS: %s: tls_application_eap_core_c::ttls_server_handles_ms_chapv2_change_password()\n"),
(m_is_client == true ? "client": "server")));
EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_server_handles_ms_chapv2_change_password()");
eap_status_e status(eap_status_not_found);
const u32_t type_data_length = EAP_MSCHAPV2_HEADER_SIZE // OpCode, MS-CHAPv2-ID and MS-Length
+ mschapv2_change_password_c::get_header_minimum_size();
const u32_t eap_length = eap_header_base_c::get_type_data_start_offset(m_use_eap_expanded_type)
+ type_data_length;
eap_buf_chain_wr_c eap_packet_buffer(
eap_write_buffer,
m_am_tools,
eap_length);
if (eap_packet_buffer.get_is_valid() == false)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
eap_header_wr_c forwarded_eap_packet(
m_am_tools,
eap_packet_buffer.get_data(eap_length),
eap_length);
if (forwarded_eap_packet.get_is_valid() == false)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
forwarded_eap_packet.set_code(eap_code_response);
forwarded_eap_packet.set_identifier(received_eap_identifier);
forwarded_eap_packet.set_length(
static_cast<u16_t>(eap_length),
m_use_eap_expanded_type);
forwarded_eap_packet.set_type(
eap_type_mschapv2,
m_use_eap_expanded_type);
mschapv2_header_c mschapv2_header(
m_am_tools,
forwarded_eap_packet.get_type_data_offset(0, forwarded_eap_packet.get_type_data_length()),
forwarded_eap_packet.get_type_data_length());
mschapv2_header.set_opcode(mschapv2_opcode_change_password);
const u8_t * const mschapv2ident = m_ttls_implicit_challenge.get_data_offset(
EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_IDENT_OFFSET,
sizeof(u8_t));
if (mschapv2ident == 0)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
EAP_TRACE_DATA_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("ttls_server_handles_ms_chapv2_change_password(): mschapv2ident"),
mschapv2ident,
sizeof(*mschapv2ident)));
mschapv2_header.set_mschapv2_id(*mschapv2ident);
mschapv2_header.set_ms_length(static_cast<u16_t>(type_data_length));
mschapv2_change_password_c response(
m_am_tools,
mschapv2_header.get_data(),
mschapv2_header.get_data_length());
if (response.get_is_valid() == false)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
status = response.set_constants();
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{
eap_diameter_variable_data_c * const nt_enc_pw_payload
= m_ttls_received_payloads.get_payload(
eap_diameter_vendor_code_of_microsoft_ms_chap_nt_enc_pw.get_code());
if (nt_enc_pw_payload == 0)
{
return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
}
eap_variable_data_c * const nt_enc_pw
= nt_enc_pw_payload->get_payload_buffer();
if (nt_enc_pw == 0
|| nt_enc_pw->get_is_valid_data() == false)
{
return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
}
if (nt_enc_pw->get_data_length() != EAP_MSCHAPV2_CHANGE_PASSWORD_ENCRYPTED_PASSWORD_SIZE)
{
return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
}
response.set_encrypted_pw_block(nt_enc_pw->get_data());
}
{
eap_diameter_variable_data_c * const cpw_payload
= m_ttls_received_payloads.get_payload(
eap_diameter_vendor_code_of_microsoft_ms_chap2_cpw.get_code());
if (cpw_payload == 0)
{
return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
}
eap_variable_data_c * const cpw
= cpw_payload->get_payload_buffer();
if (cpw == 0
|| cpw->get_is_valid_data() == false)
{
return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
}
if (cpw->get_data_length()
!= (EAP_MSCHAPV2_CHANGE_PASSWORD_ENCRYPTED_HASH_SIZE
+ EAP_MSCHAPV2_PEER_CHALLENGE_SIZE
+ EAP_MSCHAPV2_NT_RESPONSE_SIZE))
{
return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
}
u32_t offset = 0ul;
response.set_encrypted_hash(
cpw->get_data_offset(offset, EAP_MSCHAPV2_CHANGE_PASSWORD_ENCRYPTED_HASH_SIZE));
offset += EAP_MSCHAPV2_CHANGE_PASSWORD_ENCRYPTED_HASH_SIZE;
response.set_peer_challenge(
cpw->get_data_offset(offset, EAP_MSCHAPV2_PEER_CHALLENGE_SIZE));
offset += EAP_MSCHAPV2_PEER_CHALLENGE_SIZE;
response.set_nt_response(
cpw->get_data_offset(offset, EAP_MSCHAPV2_NT_RESPONSE_SIZE));
}
status = packet_forward_to_tunnel(
&m_receive_network_id,
&forwarded_eap_packet,
eap_length);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
set_ttls_tunneled_message_state(eap_ttls_tunneled_message_state_process_change_password_response);
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
//--------------------------------------------------
#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_client_handles_ms_chapv2_success(
eap_diameter_payloads_c * const /* payloads */,
const u8_t received_eap_identifier)
{
EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
EAP_TRACE_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("TTLS: %s: tls_application_eap_core_c::ttls_client_handles_ms_chapv2_success()\n"),
(m_is_client == true ? "client": "server")));
EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_client_handles_ms_chapv2_success()");
eap_status_e status(eap_status_not_found);
eap_diameter_variable_data_c * const success_data_payload
= m_ttls_received_payloads.get_payload(
eap_diameter_vendor_code_of_microsoft_ms_chap2_success.get_code());
if (success_data_payload == 0)
{
return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
}
eap_variable_data_c * const success_data
= success_data_payload->get_payload_buffer();
if (success_data == 0
|| success_data->get_is_valid_data() == false)
{
return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
}
const u32_t type_data_length
= EAP_MSCHAPV2_HEADER_SIZE // OpCode, MS-CHAPv2-ID and MS-Length
+ (success_data->get_data_length() - 1ul);
const u32_t eap_length
= eap_header_base_c::get_type_data_start_offset(m_use_eap_expanded_type)
+ type_data_length;
eap_buf_chain_wr_c eap_packet_buffer(
eap_write_buffer,
m_am_tools,
eap_length);
if (eap_packet_buffer.get_is_valid() == false)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
eap_header_wr_c forwarded_eap_packet(
m_am_tools,
eap_packet_buffer.get_data(eap_length),
eap_length);
if (forwarded_eap_packet.get_is_valid() == false)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
forwarded_eap_packet.reset_header(
static_cast<u16_t>(eap_length),
m_use_eap_expanded_type);
forwarded_eap_packet.set_identifier(static_cast<u8_t>(received_eap_identifier+1ul));
forwarded_eap_packet.set_code(eap_code_request);
forwarded_eap_packet.set_length(
static_cast<u16_t>(eap_length),
m_use_eap_expanded_type);
u8_t * const eap_data = forwarded_eap_packet.get_data(success_data->get_data_length());
if (eap_data == 0)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
forwarded_eap_packet.set_type(
eap_type_mschapv2,
m_use_eap_expanded_type);
mschapv2_header_c mschapv2_header(
m_am_tools,
forwarded_eap_packet.get_type_data_offset(
0,
forwarded_eap_packet.get_type_data_length()),
forwarded_eap_packet.get_type_data_length());
mschapv2_header.set_opcode(mschapv2_opcode_success);
const u8_t * const mschapv2ident = m_ttls_implicit_challenge.get_data_offset(
EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_IDENT_OFFSET,
sizeof(u8_t));
if (mschapv2ident == 0)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
EAP_TRACE_DATA_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("ttls_client_handles_ms_chapv2_success(): mschapv2ident"),
mschapv2ident,
sizeof(*mschapv2ident)));
mschapv2_header.set_mschapv2_id(*mschapv2ident);
mschapv2_header.set_ms_length(static_cast<u16_t>(type_data_length));
mschapv2_response_c response(
m_am_tools,
mschapv2_header.get_data(),
mschapv2_header.get_data_length());
if (response.get_is_valid() == false)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
status = response.set_constants();
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
u8_t * ms_success_data = mschapv2_header.get_data();
if (ms_success_data == 0)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
if (success_data->get_data_length() < 1ul)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
// Copy auth string after headers
m_am_tools->memmove(
ms_success_data,
success_data->get_data_offset(1ul, success_data->get_data_length() - 1ul),
success_data->get_data_length() - 1ul);
set_ttls_tunneled_message_state(eap_ttls_tunneled_message_state_process_success_request);
status = packet_forward_to_tunnel(
&m_receive_network_id,
&forwarded_eap_packet,
eap_length);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
if (get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_complete_success_request)
{
eap_header_wr_c sent_eap_packet(
m_am_tools,
m_ttls_sent_eap_packet.get_data(),
m_ttls_sent_eap_packet.get_data_length());
status = ttls_tunneled_message_state_complete_success_request(&sent_eap_packet);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
}
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
//--------------------------------------------------
#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_client_handles_ms_chapv2_error(
eap_diameter_payloads_c * const /* payloads */,
const u8_t received_eap_identifier)
{
EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
EAP_TRACE_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("TTLS: %s: tls_application_eap_core_c::ttls_client_handles_ms_chapv2_error()\n"),
(m_is_client == true ? "client": "server")));
EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_client_handles_ms_chapv2_error()");
eap_status_e status(eap_status_not_found);
eap_diameter_variable_data_c * const error_data_payload
= m_ttls_received_payloads.get_payload(
eap_diameter_vendor_code_of_microsoft_ms_chap_error.get_code());
if (error_data_payload == 0)
{
return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
}
eap_variable_data_c * const error_data
= error_data_payload->get_payload_buffer();
if (error_data == 0
|| error_data->get_is_valid_data() == false)
{
return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
}
const u32_t type_data_length = EAP_MSCHAPV2_HEADER_SIZE // OpCode, MS-CHAPv2-ID and MS-Length
+ mschapv2_challenge_c::get_header_minimum_size()
+ error_data->get_data_length();
const u32_t eap_length
= eap_header_base_c::get_type_data_start_offset(m_use_eap_expanded_type)
+ type_data_length;
eap_buf_chain_wr_c eap_packet_buffer(
eap_write_buffer,
m_am_tools,
eap_length);
if (eap_packet_buffer.get_is_valid() == false)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
eap_header_wr_c forwarded_eap_packet(
m_am_tools,
eap_packet_buffer.get_data(eap_length),
eap_length);
if (forwarded_eap_packet.get_is_valid() == false)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
forwarded_eap_packet.reset_header(
static_cast<u16_t>(eap_length),
m_use_eap_expanded_type);
forwarded_eap_packet.set_identifier(static_cast<u8_t>(received_eap_identifier+1ul));
forwarded_eap_packet.set_code(eap_code_request);
forwarded_eap_packet.set_length(
static_cast<u16_t>(eap_length),
m_use_eap_expanded_type);
u8_t * const eap_data = forwarded_eap_packet.get_data(error_data->get_data_length());
if (eap_data == 0)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
forwarded_eap_packet.set_type(
eap_type_mschapv2,
m_use_eap_expanded_type);
mschapv2_header_c mschapv2_header(
m_am_tools,
forwarded_eap_packet.get_type_data_offset(
0,
forwarded_eap_packet.get_type_data_length()),
forwarded_eap_packet.get_type_data_length());
mschapv2_header.set_opcode(mschapv2_opcode_failure);
const u8_t * const mschapv2ident = m_ttls_implicit_challenge.get_data_offset(
EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_IDENT_OFFSET,
sizeof(u8_t));
if (mschapv2ident == 0)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
EAP_TRACE_DATA_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("ttls_client_handles_ms_chapv2_error(): mschapv2ident"),
mschapv2ident,
sizeof(*mschapv2ident)));
mschapv2_header.set_mschapv2_id(*mschapv2ident);
mschapv2_header.set_ms_length(static_cast<u16_t>(type_data_length));
mschapv2_response_c response(
m_am_tools,
mschapv2_header.get_data(),
mschapv2_header.get_data_length());
if (response.get_is_valid() == false)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
status = response.set_constants();
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
u8_t * ms_error_data = mschapv2_header.get_data();
if (ms_error_data == 0)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
// Copy auth string after headers
m_am_tools->memmove(
ms_error_data,
error_data->get_data(),
error_data->get_data_length());
set_ttls_tunneled_message_state(eap_ttls_tunneled_message_state_process_error_request);
status = packet_forward_to_tunnel(
&m_receive_network_id,
&forwarded_eap_packet,
eap_length);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
if (get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_complete_error_request)
{
eap_header_wr_c sent_eap_packet(
m_am_tools,
m_ttls_sent_eap_packet.get_data(),
m_ttls_sent_eap_packet.get_data_length());
status = ttls_tunneled_message_state_complete_error_request(&sent_eap_packet);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
}
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
//--------------------------------------------------
#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::handle_ttls_plain_mschapv2_payloads(
eap_diameter_payloads_c * const payloads,
const eap_ttls_tunneled_message_type_e message_type,
const u8_t received_eap_identifier)
{
EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
EAP_TRACE_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("TTLS: %s: tls_application_eap_core_c::handle_ttls_plain_mschapv2_payloads()\n"),
(m_is_client == true ? "client": "server")));
EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::handle_ttls_plain_mschapv2_payloads()");
eap_status_e status(eap_status_not_found);
switch(message_type)
{
case eap_ttls_tunneled_message_type_ms_chapv2_response:
// Here are included User-Name, MS-CHAP-Challenge and MS-CHAP2-Response AVPs.
status = ttls_server_handles_ms_chapv2_response(payloads, received_eap_identifier);
break;
case eap_ttls_tunneled_message_type_ms_chapv2_change_password:
// Here are included MS-CHAP-NT-Enc-PW, MS-CHAP2-CPW, and MS-CHAP-Challenge AVPs.
status = ttls_server_handles_ms_chapv2_change_password(payloads, received_eap_identifier);
break;
case eap_ttls_tunneled_message_type_ms_chapv2_success:
// Here is included MS-CHAP2-Success AVP.
status = ttls_client_handles_ms_chapv2_success(payloads, received_eap_identifier);
break;
case eap_ttls_tunneled_message_type_ms_chapv2_error:
// Here is included MS-CHAP2-Error AVP.
status = ttls_client_handles_ms_chapv2_error(payloads, received_eap_identifier);
break;
default:
status = eap_status_unexpected_message;
break;
}
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
//--------------------------------------------------
#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::create_ttls_diameter_avp(
eap_variable_data_c * const avp,
const eap_variable_data_c * const data,
eap_diameter_avp_code_c code,
const bool include_vendor_id)
{
EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
EAP_TRACE_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("TLS: %s: message_function: tls_application_eap_core_c::create_ttls_diameter_avp()\n"),
(m_is_client == true ? "client": "server")));
EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::create_ttls_diameter_avp()");
if (avp == 0)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
}
if (data == 0
|| data->get_is_valid_data() == false)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
}
if (code.get_vendor_code() == eap_diameter_avp_code_none)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
}
eap_status_e status = avp->reset();
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
bool needs_vendor_id = include_vendor_id;
if (code.get_vendor_id() != eap_diameter_vendor_id_of_ietf)
{
needs_vendor_id = true;
}
const u32_t padding_byte_data = 3ul;
const u32_t avp_payload_length
= eap_diameter_avp_header_c::get_header_length(needs_vendor_id) + data->get_data_length();
status = avp->set_buffer_length(avp_payload_length + padding_byte_data);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
if (avp->get_is_valid_data() == false)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
status = avp->set_data_length(avp_payload_length);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
eap_diameter_avp_header_c avp_header(
m_am_tools,
avp->get_data(),
avp->get_data_length());
if (avp_header.get_is_valid() == false)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
// These packets are encapsulated to AVP.
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | AVP Code |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |V|M|r r r r r r| AVP Length |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Vendor-ID (optional) |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Data ...
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
status = avp_header.reset_header(static_cast<u16_t>(avp_payload_length));
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
status = avp_header.set_avp_code(code);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
status = avp_header.set_avp_flag_mandatory_avp(false);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
{
// Adds data as a payload to AVP.
u16_t * const avp_payload = reinterpret_cast<u16_t *>(
avp_header.get_data_offset(0ul, data->get_data_length()));
if (avp_payload == 0)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
m_am_tools->memmove(
avp_payload,
data->get_data(),
data->get_data_length());
}
u32_t padding_length = avp_header.get_padding_length();
if (padding_length != 0ul)
{
// Add padding.
u8_t padding_byte = 0ul;
for (u32_t ind = 0ul; ind < padding_length; ind++)
{
status = avp->add_data(
&padding_byte,
sizeof(padding_byte));
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
} // for()
}
EAP_TLS_PEAP_TRACE_TTLS_PAYLOAD("Created TTLS AVP payload", &avp_header, m_is_client);
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
}
#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
//--------------------------------------------------
#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_tunneled_message_state_process_identity_response(
eap_header_wr_c * const sent_eap_packet)
{
EAP_TRACE_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("TTLS: %s: function: tls_application_eap_core_c::ttls_tunneled_message_state_process_identity_response(): ")
EAPL("this = 0x%08x, m_ttls_tunneled_message_state=%d=%s, EAP-type=%d\n"),
(m_is_client == true ? "client": "server"),
this,
get_ttls_tunneled_message_state(),
eap_tls_trace_string_c::get_ttls_state_string(get_ttls_tunneled_message_state()),
convert_eap_type_to_u32_t(sent_eap_packet->get_type())));
EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_tunneled_message_state_process_identity_response()");
eap_status_e status(eap_status_process_general_error);
// This message shoud include MS-CHAP-V2 Challenge.
// We ignore this Challenge and instead we send Implicit Challenge from client.
/**
* @{ This will require changes in EAP-MsChapv2 server.
* Implicit Challenge need to be used in authentication check. }
*/
const u8_t * const mschapv2ident = m_ttls_implicit_challenge.get_data_offset(
EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_IDENT_OFFSET,
sizeof(u8_t));
if (mschapv2ident == 0)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
EAP_TRACE_DATA_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("ttls_tunneled_message_state_process_identity_response(): mschapv2ident"),
mschapv2ident,
sizeof(*mschapv2ident)));
eap_diameter_variable_data_c * const user_name_payload
= m_ttls_received_payloads.get_payload(eap_diameter_avp_code_user_name);
if (user_name_payload == 0)
{
return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
}
eap_variable_data_c * const user_name
= user_name_payload->get_payload_buffer();
if (user_name != 0
&& user_name->get_is_valid_data() == false)
{
return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
}
const u32_t type_data_length = EAP_MSCHAPV2_HEADER_SIZE // OpCode, MS-CHAPv2-ID and MS-Length
+ mschapv2_response_c::get_header_minimum_size()
+ user_name->get_data_length();
const u32_t eap_length = eap_header_base_c::get_type_data_start_offset(m_use_eap_expanded_type)
+ type_data_length;
eap_buf_chain_wr_c eap_packet_buffer(
eap_write_buffer,
m_am_tools,
eap_length);
if (eap_packet_buffer.get_is_valid() == false)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
eap_header_wr_c forwarded_eap_packet(
m_am_tools,
eap_packet_buffer.get_data(eap_length),
eap_length);
if (forwarded_eap_packet.get_is_valid() == false)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
forwarded_eap_packet.reset_header(
static_cast<u16_t>(eap_length),
m_use_eap_expanded_type);
forwarded_eap_packet.set_identifier(sent_eap_packet->get_identifier());
forwarded_eap_packet.set_code(eap_code_response);
forwarded_eap_packet.set_length(
static_cast<u16_t>(eap_length),
m_use_eap_expanded_type);
forwarded_eap_packet.set_type(
eap_type_mschapv2,
m_use_eap_expanded_type);
mschapv2_header_c mschapv2_header(
m_am_tools,
forwarded_eap_packet.get_type_data_offset(
0,
forwarded_eap_packet.get_type_data_length()),
forwarded_eap_packet.get_type_data_length());
mschapv2_header.set_opcode(mschapv2_opcode_response);
mschapv2_header.set_mschapv2_id(*mschapv2ident);
mschapv2_header.set_ms_length(static_cast<u16_t>(type_data_length));
mschapv2_response_c response(
m_am_tools,
mschapv2_header.get_data(),
mschapv2_header.get_data_length());
if (response.get_is_valid() == false)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
status = response.set_constants();
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
eap_diameter_variable_data_c * const peer_challenge_payload
= m_ttls_received_payloads.get_payload(
eap_diameter_vendor_code_of_microsoft_ms_chap_challenge.get_code());
if (peer_challenge_payload == 0)
{
return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
}
eap_variable_data_c * const peer_challenge
= peer_challenge_payload->get_payload_buffer();
if (peer_challenge != 0
&& peer_challenge->get_is_valid_data() == false
&& peer_challenge->get_data_length() == EAP_MSCHAPV2_PEER_CHALLENGE_SIZE)
{
return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
}
const u8_t * const mschapv2_challenge = m_ttls_implicit_challenge.get_data_offset(
EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_OFFSET,
EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_LENGTH);
if (mschapv2_challenge == 0)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
if (m_am_tools->memcmp(
peer_challenge->get_data(),
mschapv2_challenge,
EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_LENGTH) != 0)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
eap_diameter_variable_data_c * const response_data_payload
= m_ttls_received_payloads.get_payload(
eap_diameter_vendor_code_of_microsoft_ms_chap2_response.get_code());
if (response_data_payload == 0)
{
return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
}
eap_variable_data_c * const response_data
= response_data_payload->get_payload_buffer();
if (response_data != 0
&& response_data->get_is_valid_data() == false
&& response_data->get_data_length() != EAP_MSCHAPV2_RESPONSE_MESSAGE_SIZE)
{
return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
}
response.set_peer_challenge(
response_data->get_data_offset(
EAP_MSCHAPV2_PEER_CHALLENGE_OFFSET,
EAP_MSCHAPV2_PEER_CHALLENGE_SIZE));
response.set_nt_response(
response_data->get_data_offset(
EAP_MSCHAPV2_NT_RESPONSE_OFFSET,
EAP_MSCHAPV2_NT_RESPONSE_SIZE));
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Copy username to end of response packet
response.set_name(user_name->get_data());
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
set_ttls_tunneled_message_state(eap_ttls_tunneled_message_state_process_response);
status = packet_forward_to_tunnel(
&m_receive_network_id,
&forwarded_eap_packet,
eap_length);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
//--------------------------------------------------
#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_tunneled_message_state_process_response(
eap_header_wr_c * const sent_eap_packet)
{
EAP_TRACE_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("TTLS: %s: function: tls_application_eap_core_c::ttls_tunneled_message_state_process_response(): ")
EAPL("this = 0x%08x, m_ttls_tunneled_message_state=%d=%s, EAP-type=%d\n"),
(m_is_client == true ? "client": "server"),
this,
get_ttls_tunneled_message_state(),
eap_tls_trace_string_c::get_ttls_state_string(get_ttls_tunneled_message_state()),
convert_eap_type_to_u32_t(sent_eap_packet->get_type())));
EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_tunneled_message_state_process_response()");
eap_status_e status(eap_status_process_general_error);
// This message should include MS-CHAP-V2 Success or MS-CHAP-V2 Error.
mschapv2_header_c mschapv2_header(
m_am_tools,
sent_eap_packet->get_type_data_offset(0, sent_eap_packet->get_type_data_length()),
sent_eap_packet->get_type_data_length());
status = mschapv2_header.check_header();
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
if (mschapv2_header.get_opcode() == mschapv2_opcode_success)
{
eap_variable_data_c avp_success(m_am_tools);
{
eap_variable_data_c success_data(m_am_tools);
success_data.reset();
u8_t ident = mschapv2_header.get_mschapv2_id();
status = success_data.add_data(
&ident,
EAP_MSCHAPV2_IDENT_SIZE);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
if (mschapv2_header.get_ms_length() < EAP_MSCHAPV2_HEADER_SIZE)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
EAP_TRACE_DATA_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("ttls_tunneled_message_state_process_response(): mschapv2 data"),
mschapv2_header.get_data(),
mschapv2_header.get_ms_length()- EAP_MSCHAPV2_HEADER_SIZE));
status = success_data.add_data(
mschapv2_header.get_data(),
mschapv2_header.get_ms_length() - EAP_MSCHAPV2_HEADER_SIZE);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
status = create_ttls_diameter_avp(
&avp_success,
&success_data,
eap_diameter_vendor_code_of_microsoft_ms_chap2_success.get_code(),
true);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
}
eap_buf_chain_wr_c forwarded_packet(
eap_write_buffer,
m_am_tools,
avp_success.get_data(),
avp_success.get_data_length(),
false,
false,
0ul);
if (forwarded_packet.get_is_valid() == false)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
status = get_application_partner()->packet_send(
&forwarded_packet,
0ul,
forwarded_packet.get_data_length(),
forwarded_packet.get_buffer_length());
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
// Here we swap the addresses.
eap_am_network_id_c send_network_id(
m_am_tools,
m_receive_network_id.get_destination_id(),
m_receive_network_id.get_source_id(),
m_receive_network_id.get_type());
eap_state_notification_c notification(
m_am_tools,
&send_network_id,
m_is_client,
eap_state_notification_eap,
eap_protocol_layer_internal_type,
eap_type_ttls,
eap_state_none,
tls_peap_state_server_waits_ttls_plain_ms_chap_v2_empty_ack,
sent_eap_packet->get_identifier(),
false);
get_application_partner()->state_notification(¬ification);
m_ttls_plain_ms_chap_v2_eap_identifier = sent_eap_packet->get_identifier();
}
else if (mschapv2_header.get_opcode() == mschapv2_opcode_failure)
{
eap_variable_data_c avp_error(m_am_tools);
{
eap_variable_data_c error_data(m_am_tools);
status = error_data.set_buffer(
mschapv2_header.get_data(),
mschapv2_header.get_ms_length() - EAP_MSCHAPV2_HEADER_SIZE,
false,
false);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
status = create_ttls_diameter_avp(
&avp_error,
&error_data,
eap_diameter_vendor_code_of_microsoft_ms_chap_error.get_code(),
true);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
}
eap_buf_chain_wr_c forwarded_packet(
eap_write_buffer,
m_am_tools,
avp_error.get_data(),
avp_error.get_data_length(),
false,
false,
0ul);
if (forwarded_packet.get_is_valid() == false)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
status = get_application_partner()->packet_send(
&forwarded_packet,
0ul,
forwarded_packet.get_data_length(),
forwarded_packet.get_buffer_length());
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
m_ttls_plain_ms_chap_v2_eap_identifier = sent_eap_packet->get_identifier();
}
else
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
}
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
//--------------------------------------------------
#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_tunneled_message_state_process_change_password_response(
eap_header_wr_c * const sent_eap_packet)
{
EAP_TRACE_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("TTLS: %s: function: tls_application_eap_core_c::ttls_tunneled_message_state_process_change_password_response(): ")
EAPL("this = 0x%08x, m_ttls_tunneled_message_state=%d=%s, EAP-type=%d\n"),
(m_is_client == true ? "client": "server"),
this,
get_ttls_tunneled_message_state(),
eap_tls_trace_string_c::get_ttls_state_string(get_ttls_tunneled_message_state()),
convert_eap_type_to_u32_t(sent_eap_packet->get_type())));
EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_tunneled_message_state_process_change_password_response()");
eap_status_e status(eap_status_process_general_error);
// This message should include MS-CHAP-V2 Success.
status = ttls_tunneled_message_state_process_response(sent_eap_packet);
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
//--------------------------------------------------
#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_tunneled_message_state_process_identity_request(
eap_header_wr_c * const sent_eap_packet)
{
EAP_TRACE_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("TTLS: %s: function: tls_application_eap_core_c::ttls_tunneled_message_state_process_identity_request(): ")
EAPL("this = 0x%08x, m_ttls_tunneled_message_state=%d=%s, EAP-type=%d\n"),
(m_is_client == true ? "client": "server"),
this,
get_ttls_tunneled_message_state(),
eap_tls_trace_string_c::get_ttls_state_string(get_ttls_tunneled_message_state()),
convert_eap_type_to_u32_t(sent_eap_packet->get_type())));
EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_tunneled_message_state_process_identity_request()");
eap_status_e status(eap_status_process_general_error);
// This message includes username.
u32_t user_name_length = sent_eap_packet->get_type_data_length();
status = m_ttls_user_name.set_copy_of_buffer(
sent_eap_packet->get_type_data(user_name_length),
user_name_length);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
status = get_application_partner()->get_ttls_implicit_challenge(
&m_ttls_implicit_challenge,
EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_FULL_LENGTH);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
{
const u32_t type_data_length = EAP_MSCHAPV2_HEADER_SIZE // OpCode, MS-CHAPv2-ID and MS-Length
+ mschapv2_challenge_c::get_header_minimum_size()
+ m_ttls_user_name.get_data_length();
const u32_t eap_length = eap_header_base_c::get_type_data_start_offset(m_use_eap_expanded_type)
+ type_data_length;
eap_buf_chain_wr_c eap_packet_buffer(
eap_write_buffer,
m_am_tools,
eap_length);
if (eap_packet_buffer.get_is_valid() == false)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
eap_header_wr_c forwarded_eap_packet(
m_am_tools,
eap_packet_buffer.get_data(eap_length),
eap_length);
if (forwarded_eap_packet.get_is_valid() == false)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
}
forwarded_eap_packet.set_code(eap_code_request);
forwarded_eap_packet.set_identifier(static_cast<u8_t>(sent_eap_packet->get_identifier()+1ul));
forwarded_eap_packet.set_length(
static_cast<u16_t>(eap_length),
m_use_eap_expanded_type);
forwarded_eap_packet.set_type(
eap_type_mschapv2,
m_use_eap_expanded_type);
mschapv2_header_c mschapv2_header(
m_am_tools,
forwarded_eap_packet.get_type_data_offset(0, forwarded_eap_packet.get_type_data_length()),
forwarded_eap_packet.get_type_data_length());
mschapv2_header.set_opcode(mschapv2_opcode_challenge);
const u8_t * const mschapv2ident = m_ttls_implicit_challenge.get_data_offset(
EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_IDENT_OFFSET,
sizeof(u8_t));
if (mschapv2ident == 0)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
EAP_TRACE_DATA_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("ttls_tunneled_message_state_process_identity_request(): mschapv2ident"),
mschapv2ident,
sizeof(*mschapv2ident)));
mschapv2_header.set_mschapv2_id(*mschapv2ident);
mschapv2_header.set_ms_length(static_cast<u16_t>(type_data_length));
mschapv2_challenge_c challenge_packet(
m_am_tools,
mschapv2_header.get_data(),
mschapv2_header.get_data_length());
if (challenge_packet.get_is_valid() == false)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
const u8_t * const mschapv2_challenge = m_ttls_implicit_challenge.get_data_offset(
EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_OFFSET,
EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_LENGTH);
if (mschapv2_challenge == 0)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
EAP_TRACE_DATA_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("ttls_tunneled_message_state_process_identity_request(): mschapv2_challenge"),
mschapv2_challenge,
EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_LENGTH));
challenge_packet.set_challenge(mschapv2_challenge);
challenge_packet.set_value_size();
challenge_packet.set_name(m_ttls_user_name.get_data(m_ttls_user_name.get_data_length()));
set_ttls_tunneled_message_state(eap_ttls_tunneled_message_state_process_challenge_request);
status = packet_forward_to_tunnel(
&m_receive_network_id,
&forwarded_eap_packet,
eap_length);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
}
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
//--------------------------------------------------
#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_tunneled_message_state_process_challenge_request(
eap_header_wr_c * const sent_eap_packet)
{
EAP_TRACE_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("TTLS: %s: function: tls_application_eap_core_c::ttls_tunneled_message_state_process_challenge_request(): ")
EAPL("this = 0x%08x, m_ttls_tunneled_message_state=%d=%s, EAP-type=%d\n"),
(m_is_client == true ? "client": "server"),
this,
get_ttls_tunneled_message_state(),
eap_tls_trace_string_c::get_ttls_state_string(get_ttls_tunneled_message_state()),
convert_eap_type_to_u32_t(sent_eap_packet->get_type())));
EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_tunneled_message_state_process_challenge_request()");
eap_status_e status(eap_status_process_general_error);
// This message shoud include MS-CHAP-V2 Response.
mschapv2_header_c mschapv2_header(
m_am_tools,
sent_eap_packet->get_type_data_offset(0, sent_eap_packet->get_type_data_length()),
sent_eap_packet->get_type_data_length());
mschapv2_response_c response(
m_am_tools,
mschapv2_header.get_data(),
mschapv2_header.get_data_length());
if (response.get_is_valid() == false)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
eap_variable_data_c tunneled_data(m_am_tools);
eap_variable_data_c avp(m_am_tools);
{
status = create_ttls_diameter_avp(
&avp,
&m_ttls_user_name,
eap_diameter_avp_code_user_name,
false);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
status = tunneled_data.add_data(&avp);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
}
{
const u8_t * const mschapv2_challenge = m_ttls_implicit_challenge.get_data_offset(
EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_OFFSET,
EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_LENGTH);
if (mschapv2_challenge == 0)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
EAP_TRACE_DATA_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("ttls_tunneled_message_state_process_challenge_request(): mschapv2_challenge"),
mschapv2_challenge,
EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_LENGTH));
eap_variable_data_c peer_challenge(m_am_tools);
status = peer_challenge.set_buffer(
mschapv2_challenge,
EAP_MSCHAPV2_PEER_CHALLENGE_SIZE,
false,
false);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
status = create_ttls_diameter_avp(
&avp,
&peer_challenge,
eap_diameter_vendor_code_of_microsoft_ms_chap_challenge.get_code(),
true);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
status = tunneled_data.add_data(&avp);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
}
{
eap_variable_data_c response_data(m_am_tools);
response_data.reset();
const u8_t * const mschapv2ident = m_ttls_implicit_challenge.get_data_offset(
EAP_TTLS_MS_CHAPV2_IMPLICIT_CHALLENGE_IDENT_OFFSET,
EAP_MSCHAPV2_IDENT_SIZE);
if (mschapv2ident == 0)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
status = response_data.add_data(
mschapv2ident,
EAP_MSCHAPV2_IDENT_SIZE);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
u8_t flags = 0ul;
status = response_data.add_data(
&flags,
EAP_MSCHAPV2_FLAGS_SIZE);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
status = response_data.add_data(
response.get_peer_challenge(),
EAP_MSCHAPV2_PEER_CHALLENGE_SIZE);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
u8_t reserved_data[EAP_MSCHAPV2_RESERVED_RESPONSE_SIZE] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
status = response_data.add_data(
reserved_data,
EAP_MSCHAPV2_RESERVED_RESPONSE_SIZE);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
status = response_data.add_data(
response.get_nt_response(),
EAP_MSCHAPV2_NT_RESPONSE_SIZE);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
status = create_ttls_diameter_avp(
&avp,
&response_data,
eap_diameter_vendor_code_of_microsoft_ms_chap2_response.get_code(),
true);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
status = tunneled_data.add_data(&avp);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
}
eap_buf_chain_wr_c forwarded_packet(
eap_write_buffer,
m_am_tools,
tunneled_data.get_data(),
tunneled_data.get_data_length(),
false,
false,
0ul);
if (forwarded_packet.get_is_valid() == false)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
status = get_application_partner()->packet_send(
&forwarded_packet,
0ul,
forwarded_packet.get_data_length(),
forwarded_packet.get_buffer_length());
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
//--------------------------------------------------
#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_tunneled_message_state_process_success_request(
eap_header_wr_c * const sent_eap_packet)
{
EAP_TRACE_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("TTLS: %s: function: tls_application_eap_core_c::ttls_tunneled_message_state_process_success_request(): ")
EAPL("this = 0x%08x, m_ttls_tunneled_message_state=%d=%s, EAP-type=%d\n"),
(m_is_client == true ? "client": "server"),
this,
get_ttls_tunneled_message_state(),
eap_tls_trace_string_c::get_ttls_state_string(get_ttls_tunneled_message_state()),
convert_eap_type_to_u32_t(sent_eap_packet->get_type())));
EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_tunneled_message_state_process_success_request()");
// Here should be no data.
mschapv2_header_c mschapv2_header(
m_am_tools,
sent_eap_packet->get_type_data(sent_eap_packet->get_type_data_length()),
sent_eap_packet->get_type_data_length());
if (mschapv2_header.get_opcode() != mschapv2_opcode_success)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
}
eap_status_e status = m_ttls_sent_eap_packet.set_copy_of_buffer(
sent_eap_packet->get_header_buffer(sent_eap_packet->get_header_buffer_length()),
sent_eap_packet->get_header_buffer_length());
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
// This will be completed after EAP-MSChapv2 returns. This is to reduce stack usage.
set_ttls_tunneled_message_state(eap_ttls_tunneled_message_state_complete_success_request);
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
//--------------------------------------------------
#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_tunneled_message_state_complete_success_request(
eap_header_wr_c * const sent_eap_packet)
{
EAP_TRACE_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("TTLS: %s: function: tls_application_eap_core_c::ttls_tunneled_message_state_complete_success_request(): ")
EAPL("this = 0x%08x, m_ttls_tunneled_message_state=%d=%s\n"),
(m_is_client == true ? "client": "server"),
this,
get_ttls_tunneled_message_state(),
eap_tls_trace_string_c::get_ttls_state_string(get_ttls_tunneled_message_state())
));
EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_tunneled_message_state_complete_success_request()");
// Here we swap the addresses.
eap_am_network_id_c send_network_id(
m_am_tools,
m_receive_network_id.get_destination_id(),
m_receive_network_id.get_source_id(),
m_receive_network_id.get_type());
eap_state_notification_c notification(
m_am_tools,
&send_network_id,
m_is_client,
eap_state_notification_eap,
eap_protocol_layer_internal_type,
eap_type_ttls,
eap_state_none,
tls_peap_state_client_send_ttls_plain_ms_chap_v2_empty_ack,
sent_eap_packet->get_identifier(),
false);
get_application_partner()->state_notification(¬ification);
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
}
#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
//--------------------------------------------------
#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_tunneled_message_state_process_error_request(
eap_header_wr_c * const sent_eap_packet)
{
EAP_TRACE_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("TTLS: %s: function: tls_application_eap_core_c::ttls_tunneled_message_state_process_error_request(): ")
EAPL("this = 0x%08x, m_ttls_tunneled_message_state=%d=%s, EAP-type=%d\n"),
(m_is_client == true ? "client": "server"),
this,
get_ttls_tunneled_message_state(),
eap_tls_trace_string_c::get_ttls_state_string(get_ttls_tunneled_message_state()),
convert_eap_type_to_u32_t(sent_eap_packet->get_type())));
EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_tunneled_message_state_process_error_request()");
eap_status_e status(eap_status_process_general_error);
// This message shoud include MS-CHAP-V2 Change-Password.
mschapv2_header_c mschapv2_header(
m_am_tools,
sent_eap_packet->get_type_data(sent_eap_packet->get_type_data_length()),
sent_eap_packet->get_type_data_length());
if (mschapv2_header.get_opcode() != mschapv2_opcode_change_password)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
}
status = m_ttls_sent_eap_packet.set_copy_of_buffer(
sent_eap_packet->get_header_buffer(sent_eap_packet->get_header_buffer_length()),
sent_eap_packet->get_header_buffer_length());
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
// This will be completed after EAP-MSChapv2 returns. This is to reduce stack usage.
set_ttls_tunneled_message_state(eap_ttls_tunneled_message_state_complete_error_request);
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
//--------------------------------------------------
#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_tunneled_message_state_complete_error_request(
eap_header_wr_c * const sent_eap_packet)
{
EAP_TRACE_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("TTLS: %s: function: tls_application_eap_core_c::ttls_tunneled_message_state_process_error_request(): ")
EAPL("this = 0x%08x, m_ttls_tunneled_message_state=%d=%s, EAP-type=%d\n"),
(m_is_client == true ? "client": "server"),
this,
get_ttls_tunneled_message_state(),
eap_tls_trace_string_c::get_ttls_state_string(get_ttls_tunneled_message_state()),
convert_eap_type_to_u32_t(sent_eap_packet->get_type())));
EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_tunneled_message_state_complete_error_request()");
eap_status_e status(eap_status_process_general_error);
// This message shoud include MS-CHAP-V2 Change-Password.
mschapv2_header_c mschapv2_header(
m_am_tools,
sent_eap_packet->get_type_data(sent_eap_packet->get_type_data_length()),
sent_eap_packet->get_type_data_length());
if (mschapv2_header.get_opcode() != mschapv2_opcode_change_password)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
}
mschapv2_change_password_c response(
m_am_tools,
mschapv2_header.get_data(),
mschapv2_header.get_data_length());
if (response.get_is_valid() == false)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
// We need to create MS-CHAP-NT-Enc-PW, MS-CHAP2-CPW, and MS-CHAP-Challenge AVPs.
eap_variable_data_c tunneled_data(m_am_tools);
eap_variable_data_c avp(m_am_tools);
{
eap_variable_data_c nt_enc_pw(m_am_tools);
status = nt_enc_pw.set_buffer(
response.get_encrypted_pw_block(),
EAP_MSCHAPV2_CHANGE_PASSWORD_ENCRYPTED_PASSWORD_SIZE,
false,
false);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
status = create_ttls_diameter_avp(
&avp,
&nt_enc_pw,
eap_diameter_vendor_code_of_microsoft_ms_chap_nt_enc_pw.get_code(),
true);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
status = tunneled_data.add_data(&avp);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
}
{
eap_variable_data_c cpw(m_am_tools);
status = cpw.set_copy_of_buffer(
response.get_encrypted_hash(),
EAP_MSCHAPV2_CHANGE_PASSWORD_ENCRYPTED_HASH_SIZE);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
status = cpw.add_data(
response.get_peer_challenge(),
EAP_MSCHAPV2_PEER_CHALLENGE_SIZE);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
status = cpw.add_data(
response.get_nt_response(),
EAP_MSCHAPV2_NT_RESPONSE_SIZE);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
status = create_ttls_diameter_avp(
&avp,
&cpw,
eap_diameter_vendor_code_of_microsoft_ms_chap2_cpw.get_code(),
true);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
status = tunneled_data.add_data(&avp);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
}
{
eap_variable_data_c challenge_data(m_am_tools);
status = challenge_data.set_buffer(
response.get_peer_challenge(),
EAP_MSCHAPV2_PEER_CHALLENGE_SIZE,
false,
false);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
status = create_ttls_diameter_avp(
&avp,
&challenge_data,
eap_diameter_vendor_code_of_microsoft_ms_chap_challenge.get_code(),
true);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
status = tunneled_data.add_data(&avp);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
}
eap_buf_chain_wr_c forwarded_packet(
eap_write_buffer,
m_am_tools,
tunneled_data.get_data(),
tunneled_data.get_data_length(),
false,
false,
0ul);
if (forwarded_packet.get_is_valid() == false)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
}
status = get_application_partner()->packet_send(
&forwarded_packet,
0ul,
forwarded_packet.get_data_length(),
forwarded_packet.get_buffer_length());
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
//--------------------------------------------------
#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::send_ttls_ms_chapv2_packet(
eap_header_wr_c * const sent_eap_packet)
{
EAP_TRACE_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("TTLS: %s: function: tls_application_eap_core_c::send_ttls_ms_chapv2_packet(): ")
EAPL("this = 0x%08x, m_ttls_tunneled_message_state=%d=%s, EAP-type=%d\n"),
(m_is_client == true ? "client": "server"),
this,
get_ttls_tunneled_message_state(),
eap_tls_trace_string_c::get_ttls_state_string(get_ttls_tunneled_message_state()),
convert_eap_type_to_u32_t(sent_eap_packet->get_type())));
EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::send_ttls_ms_chapv2_packet()");
eap_status_e status(eap_status_process_general_error);
if (m_is_client == false)
{
// Server
if (sent_eap_packet->get_code() == eap_code_request
&& sent_eap_packet->get_type() == eap_type_mschapv2)
{
if (get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_process_identity_response)
{
status = ttls_tunneled_message_state_process_identity_response(sent_eap_packet);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
}
else if (get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_process_response)
{
status = ttls_tunneled_message_state_process_response(sent_eap_packet);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
}
else if (get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_process_change_password_response)
{
status = ttls_tunneled_message_state_process_change_password_response(sent_eap_packet);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
}
else
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
}
}
else if (sent_eap_packet->get_code() == eap_code_success)
{
// EAP-Success is not needed in TTLS/MsChapv2.
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly);
}
else
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
}
}
else
{
// Client
if (sent_eap_packet->get_type() == eap_type_identity)
{
// Client sends EAP-Response/Identity.
if (get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_process_identity_request
|| get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_process_identity_request_pending)
{
status = m_ttls_sent_eap_packet.set_copy_of_buffer(
sent_eap_packet->get_header_buffer(sent_eap_packet->get_header_buffer_length()),
sent_eap_packet->get_header_buffer_length());
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
if (get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_process_identity_request_pending)
{
// NOTE, here we process client send packets separately to
// reduce stack consumption.
{
eap_header_wr_c tmp_sent_eap_packet(
m_am_tools,
m_ttls_sent_eap_packet.get_data(),
m_ttls_sent_eap_packet.get_data_length());
if (tmp_sent_eap_packet.get_type() == eap_type_identity)
{
// Client sent EAP-Response/Identity.
// This message should include username.
status = ttls_tunneled_message_state_process_identity_request(&tmp_sent_eap_packet);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
}
else
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{
eap_header_wr_c tmp_sent_eap_packet(
m_am_tools,
m_ttls_sent_eap_packet.get_data(),
m_ttls_sent_eap_packet.get_data_length());
if (tmp_sent_eap_packet.get_type() == eap_type_mschapv2
&& get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_process_challenge_request)
{
// This message should include MS-CHAP-V2 Response.
status = ttls_tunneled_message_state_process_challenge_request(&tmp_sent_eap_packet);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
}
else
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
}
}
else
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
}
}
else if (sent_eap_packet->get_type() == eap_type_mschapv2)
{
if (get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_process_challenge_request)
{
status = m_ttls_sent_eap_packet.set_copy_of_buffer(
sent_eap_packet->get_header_buffer(sent_eap_packet->get_header_buffer_length()),
sent_eap_packet->get_header_buffer_length());
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
}
else if (get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_process_success_request)
{
// NOTE, here we process client send packets separately to
// reduce stack consumption.
status = ttls_tunneled_message_state_process_success_request(sent_eap_packet);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
}
else if (get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_process_error_request)
{
mschapv2_header_c mschapv2_header(
m_am_tools,
sent_eap_packet->get_type_data(sent_eap_packet->get_type_data_length()),
sent_eap_packet->get_type_data_length());
if (mschapv2_header.get_opcode() == mschapv2_opcode_change_password)
{
// This message shoud include MS-CHAP-V2 Change-Password.
status = ttls_tunneled_message_state_process_error_request(sent_eap_packet);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
}
else if (mschapv2_header.get_opcode() == mschapv2_opcode_response)
{
// This message shoud include MS-CHAP-V2 Response.
status = ttls_tunneled_message_state_process_challenge_request(sent_eap_packet);
if (status != eap_status_ok)
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
}
else
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
}
}
else
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
}
}
else
{
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
}
}
EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
return EAP_STATUS_RETURN(m_am_tools, status);
}
#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
//--------------------------------------------------
#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
eap_ttls_tunneled_message_state_e tls_application_eap_core_c::get_ttls_tunneled_message_state()
{
return m_ttls_tunneled_message_state;
}
#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
//--------------------------------------------------
#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
void tls_application_eap_core_c::set_ttls_tunneled_message_state(eap_ttls_tunneled_message_state_e ttls_state)
{
EAP_TRACE_DEBUG(
m_am_tools,
TRACE_FLAGS_DEFAULT,
(EAPL("TTLS: %s: function: tls_application_eap_core_c::set_ttls_tunneled_message_state(): ")
EAPL("old m_ttls_tunneled_message_state=%d=%s, new m_ttls_tunneled_message_state=%d=%s\n"),
(m_is_client == true ? "client": "server"),
m_ttls_tunneled_message_state,
eap_tls_trace_string_c::get_ttls_state_string(m_ttls_tunneled_message_state),
ttls_state,
eap_tls_trace_string_c::get_ttls_state_string(ttls_state)));
EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::set_ttls_tunneled_message_state()");
m_ttls_tunneled_message_state = ttls_state;
}
#endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
//--------------------------------------------------
// End.