From 1290d83b9d63c581e93fe72f4f2033d479aeee66 Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Mon, 20 Jan 2020 13:12:31 +0100 Subject: [PATCH] method_eapmsg: Let inner method handle EAP-Identity packets With EapHost inner method, this is a must. Signed-off-by: Simon Rozman --- lib/TTLS/include/Method.h | 5 +---- lib/TTLS/src/Method.cpp | 42 +++++++++++++++------------------------ lib/TTLS/src/Module.cpp | 10 +++++----- 3 files changed, 22 insertions(+), 35 deletions(-) diff --git a/lib/TTLS/include/Method.h b/lib/TTLS/include/Method.h index bc4c785..7fb37cc 100644 --- a/lib/TTLS/include/Method.h +++ b/lib/TTLS/include/Method.h @@ -131,10 +131,9 @@ namespace eap /// Constructs a method /// /// \param[in] mod Module to use for global services - /// \param[in] identity User identity /// \param[in] inner Inner method /// - method_eapmsg(_In_ module &mod, _In_ const wchar_t *identity, _In_ method *inner); + method_eapmsg(_In_ module &mod, _In_ method *inner); /// \name Session management /// @{ @@ -161,8 +160,6 @@ namespace eap /// @} protected: - std::wstring m_identity; ///< User identity - /// /// Communication phase /// diff --git a/lib/TTLS/src/Method.cpp b/lib/TTLS/src/Method.cpp index f65bc9d..93b6e6c 100644 --- a/lib/TTLS/src/Method.cpp +++ b/lib/TTLS/src/Method.cpp @@ -163,8 +163,7 @@ void eap::method_defrag::get_response_packet( // eap::method_eapmsg ////////////////////////////////////////////////////////////////////// -eap::method_eapmsg::method_eapmsg(_In_ module &mod, _In_ const wchar_t *identity, _In_ method *inner) : - m_identity(identity), +eap::method_eapmsg::method_eapmsg(_In_ module &mod, _In_ method *inner) : m_phase(phase_t::unknown), method_tunnel(mod, inner) { @@ -196,27 +195,17 @@ EapPeerMethodResponseAction eap::method_eapmsg::process_request_packet( _In_ DWORD dwReceivedPacketSize) { switch (m_phase) { - case phase_t::identity: { - // Convert identity to UTF-8. - sanitizing_string identity_utf8; - WideCharToMultiByte(CP_UTF8, 0, m_identity, identity_utf8, NULL, NULL); - + case phase_t::identity: // Build EAP-Response/Identity packet. - auto size_identity = identity_utf8.length(), size_packet = size_identity + sizeof(EapPacket); - assert(size_packet <= MAXWORD); // Packets spanning over 64kB are not supported. - eap_packet pck; - if (!pck.create(EapCodeResponse, 0, (WORD)size_packet)) - throw win_runtime_error(__FUNCTION__ " EapPacket creation failed."); - pck->Data[0] = (BYTE)eap_type_t::identity; - memcpy(pck->Data + 1, identity_utf8.data(), size_identity); - - // Diameter AVP (EAP-Message=79) - m_packet_res.clear(); - diameter_avp_append(79, diameter_avp_flag_mandatory, (const EapPacket*)pck, (unsigned int)size_packet, m_packet_res); + EapPacket hdr_req; + hdr_req.Code = EapCodeRequest; + hdr_req.Id = 0; + *reinterpret_cast(hdr_req.Length) = htons(sizeof(EapPacket)); + hdr_req.Data[0] = (BYTE)eap_type_t::identity; m_phase = phase_t::finished; - return EapPeerMethodResponseActionSend; - } + m_packet_res.clear(); + return method_tunnel::process_request_packet(&hdr_req, sizeof(EapPacket)); case phase_t::finished: { EapPeerMethodResponseAction action = EapPeerMethodResponseActionNone; @@ -271,16 +260,15 @@ void eap::method_eapmsg::get_response_packet( _In_opt_ DWORD size_max) { if (m_packet_res.empty()) { - assert(size_max >= sizeof(diameter_avp_header)); // We should be able to respond with at least Diameter AVP header. - if (size_max > 0xffffff) size_max = 0xffffff; // Diameter AVP maximum size is 16MB. // Get data from underlying method. + assert(size_max >= sizeof(diameter_avp_header)); // We should be able to respond with at least Diameter AVP header. method_tunnel::get_response_packet(packet, size_max - sizeof(diameter_avp_header)); // Prepare EAP-Message Diameter AVP header. diameter_avp_header hdr; - *reinterpret_cast(hdr.code) = htonl(79); + *reinterpret_cast(hdr.code) = htonl(79); // EAP-Message=79 hdr.flags = diameter_avp_flag_mandatory; size_t size_packet = packet.size() + sizeof(diameter_avp_header); assert(size_packet <= 0xffffff); // Packets spanning over 16MB are not supported. @@ -292,10 +280,12 @@ void eap::method_eapmsg::get_response_packet( // Add padding. packet.insert(packet.end(), (unsigned int)((4 - size_packet) % 4), 0); } else { - if (m_packet_res.size() > size_max) - throw invalid_argument(string_printf(__FUNCTION__ " This method does not support packet fragmentation, but the data size is too big to fit in one packet (packet: %zu, maximum: %u).", m_packet_res.size(), size_max)); + // We have a response packet ready. + size_t size_packet = m_packet_res.size(); + if (size_packet > size_max) + throw invalid_argument(string_printf(__FUNCTION__ " This method does not support packet fragmentation, but the data size is too big to fit in one packet (packet: %zu, maximum: %u).", size_packet, size_max)); - packet.assign(m_packet_res.begin(), m_packet_res.end()); + packet.assign(m_packet_res.cbegin(), m_packet_res.cend()); } } diff --git a/lib/TTLS/src/Module.cpp b/lib/TTLS/src/Module.cpp index 0908bea..245f76e 100644 --- a/lib/TTLS/src/Module.cpp +++ b/lib/TTLS/src/Module.cpp @@ -673,8 +673,8 @@ eap::config_method* eap::peer_ttls::make_config_method() eap::method* eap::peer_ttls::make_method(_In_ config_method_tls_tunnel &cfg, _In_ credentials_tls_tunnel &cred) { unique_ptr meth_inner; - auto cfg_inner = cfg.m_inner.get(); - auto cred_inner = cred.m_inner.get(); + auto cfg_inner = cfg.m_inner.get(); + auto cred_inner = cred.m_inner.get(); assert(cfg_inner); switch (cfg_inner->get_method_id()) { @@ -690,14 +690,14 @@ eap::method* eap::peer_ttls::make_method(_In_ config_method_tls_tunnel &cfg, _In case eap_type_t::mschapv2: meth_inner.reset( - new method_eapmsg (*this, cred_inner->get_identity().c_str(), + new method_eapmsg (*this, new method_eap (*this, eap_type_t::mschapv2, *cred_inner, new method_mschapv2(*this, dynamic_cast(*cfg_inner), dynamic_cast(*cred_inner))))); break; case eap_type_t::gtc: meth_inner.reset( - new method_eapmsg(*this, cred_inner->get_identity().c_str(), + new method_eapmsg(*this, new method_eap (*this, eap_type_t::gtc, *cred_inner, new method_gtc (*this, dynamic_cast(*cfg_inner), dynamic_cast(*cred_inner))))); break; @@ -705,7 +705,7 @@ eap::method* eap::peer_ttls::make_method(_In_ config_method_tls_tunnel &cfg, _In #if EAP_INNER_EAPHOST case eap_type_t::undefined: meth_inner.reset( - new method_eapmsg (*this, cred_inner->get_identity().c_str(), + new method_eapmsg (*this, new method_eaphost(*this, dynamic_cast(*cfg_inner), dynamic_cast(*cred_inner)))); break; #endif