From a9ecde86d9baa27fef36a28a774c54c3da441e8e Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Fri, 5 Aug 2016 11:01:30 +0200 Subject: [PATCH] TLS specific package communication moved from TTLS to TLS session --- lib/EAPBase/include/Session.h | 14 +- lib/TLS/include/Session.h | 73 ++++++++- lib/TLS/src/Session.cpp | 270 +++++++++++++++++++++++++++++++--- lib/TLS/src/StdAfx.h | 3 + lib/TTLS/include/Session.h | 54 ++----- lib/TTLS/src/Session.cpp | 214 ++------------------------- 6 files changed, 346 insertions(+), 282 deletions(-) diff --git a/lib/EAPBase/include/Session.h b/lib/EAPBase/include/Session.h index 4d5ea29..ee54cf4 100644 --- a/lib/EAPBase/include/Session.h +++ b/lib/EAPBase/include/Session.h @@ -349,12 +349,12 @@ namespace eap /// @} public: - module &m_module; ///< Reference of the EAP module - config_providers m_cfg; ///< Session configuration - credentials_type m_cred; ///< User credentials - interactive_request_type m_intreq; ///< Interactive UI request data - DWORD m_eap_flags; ///< A combination of EAP flags that describe the new EAP authentication session behavior - HANDLE m_token; ///< Specifies a handle to the user impersonation token to use in this session - DWORD m_send_packet_size_max; ///< Specifies the maximum size in bytes of an EAP packet sent during the session. If the method needs to send a packet larger than the maximum size, the method must accommodate fragmentation and reassembly. + module &m_module; ///< Reference of the EAP module + config_providers m_cfg; ///< Providers configuration + credentials_type m_cred; ///< User credentials + interactive_request_type m_intreq; ///< Interactive UI request data + DWORD m_eap_flags; ///< A combination of EAP flags that describe the new EAP authentication session behavior + HANDLE m_token; ///< Specifies a handle to the user impersonation token to use in this session + DWORD m_send_packet_size_max; ///< Specifies the maximum size in bytes of an EAP packet sent during the session. If the method needs to send a packet larger than the maximum size, the method must accommodate fragmentation and reassembly. }; } diff --git a/lib/TLS/include/Session.h b/lib/TLS/include/Session.h index 056f17f..f46d8aa 100644 --- a/lib/TLS/include/Session.h +++ b/lib/TLS/include/Session.h @@ -20,6 +20,18 @@ namespace eap { + /// + /// TLS random + /// + typedef unsigned char tls_random_t[32]; + + /// + /// EAP-TLS packet flags + /// + /// \sa [The EAP-TLS Authentication Protocol (Chapter: 3.1 EAP-TLS Request Packet)](https://tools.ietf.org/html/rfc5216#section-3.1) + /// + enum tls_flags_t; + /// /// TLS session /// @@ -33,11 +45,21 @@ namespace eap #include "../../EAPBase/include/Session.h" +#include #include +#include + namespace eap { + enum tls_flags_t { + tls_flags_length_incl = 0x80, ///< Length included + tls_flags_more_frag = 0x40, ///< More fragments + tls_flags_start = 0x20, ///< Start + }; + + class session_tls : public session { public: @@ -62,6 +84,11 @@ namespace eap /// session_tls(_Inout_ session_tls &&other); + /// + /// Destructor + /// + virtual ~session_tls(); + /// /// Copies TLS session /// @@ -92,12 +119,12 @@ namespace eap /// - \c true if succeeded /// - \c false otherwise. See \p ppEapError for details. /// - //virtual bool begin( - // _In_ DWORD dwFlags, - // _In_ const EapAttributes *pAttributeArray, - // _In_ HANDLE hTokenImpersonateUser, - // _In_ DWORD dwMaxSendPacketSize, - // _Out_ EAP_ERROR **ppEapError); + virtual bool begin( + _In_ DWORD dwFlags, + _In_ const EapAttributes *pAttributeArray, + _In_ HANDLE hTokenImpersonateUser, + _In_ DWORD dwMaxSendPacketSize, + _Out_ EAP_ERROR **ppEapError); /// @} @@ -119,6 +146,20 @@ namespace eap _Out_ EapPeerMethodOutput *pEapOutput, _Out_ EAP_ERROR **ppEapError); + /// + /// Obtains a response packet from the EAP method. + /// + /// \sa [EapPeerGetResponsePacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363610.aspx) + /// + /// \returns + /// - \c true if succeeded + /// - \c false otherwise. See \p ppEapError for details. + /// + virtual bool get_response_packet( + _Inout_ DWORD *pdwSendPacketSize, + _Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket, + _Out_ EAP_ERROR **ppEapError); + /// /// Obtains the result of an authentication session from the EAP method. /// @@ -136,6 +177,24 @@ namespace eap /// @} public: - winstd::crypt_prov m_cp; ///< Cryptography provider + enum phase_t { + phase_handshake_start = 0, + } m_phase; ///< Session phase + + struct { + EapCode m_code; ///< Packet code + BYTE m_id; ///< Packet ID + BYTE m_flags; ///< Packet flags + std::vector m_data; ///< Packet data + } + m_packet_req, ///< Request packet + m_packet_res; ///< Response packet + + winstd::crypt_prov m_cp; ///< Cryptography provider + + tls_random_t m_random_client; ///< Client random + tls_random_t m_random_server; ///< Server random + + std::vector > m_session_id; ///< TLS session ID }; } diff --git a/lib/TLS/src/Session.cpp b/lib/TLS/src/Session.cpp index 6328c13..24dbcd9 100644 --- a/lib/TLS/src/Session.cpp +++ b/lib/TLS/src/Session.cpp @@ -28,27 +28,91 @@ using namespace winstd; // eap::session_tls ////////////////////////////////////////////////////////////////////// -eap::session_tls::session_tls(_In_ module &mod) : session(mod) +eap::session_tls::session_tls(_In_ module &mod) : + m_phase(phase_handshake_start), + session(mod) { + m_packet_req.m_code = (EapCode)0; + m_packet_req.m_id = 0; + m_packet_req.m_flags = 0; + + m_packet_res.m_code = (EapCode)0; + m_packet_res.m_id = 0; + m_packet_res.m_flags = 0; + + memset(m_random_client, 0, sizeof(tls_random_t)); + memset(m_random_server, 0, sizeof(tls_random_t)); } eap::session_tls::session_tls(_In_ const session_tls &other) : + m_phase(other.m_phase), + m_session_id(other.m_session_id), session(other) { + m_packet_req.m_code = other.m_packet_req.m_code ; + m_packet_req.m_id = other.m_packet_req.m_id ; + m_packet_req.m_flags = other.m_packet_req.m_flags; + m_packet_req.m_data = other.m_packet_req.m_data ; + + m_packet_res.m_code = other.m_packet_res.m_code ; + m_packet_res.m_id = other.m_packet_res.m_id ; + m_packet_res.m_flags = other.m_packet_res.m_flags; + m_packet_res.m_data = other.m_packet_res.m_data ; + + memcpy(m_random_client, other.m_random_client, sizeof(tls_random_t)); + memcpy(m_random_server, other.m_random_server, sizeof(tls_random_t)); } eap::session_tls::session_tls(_Inout_ session_tls &&other) : + m_phase(std::move(other.m_phase)), + m_session_id(std::move(other.m_session_id)), session(std::move(other)) { + m_packet_req.m_code = std::move(other.m_packet_req.m_code ); + m_packet_req.m_id = std::move(other.m_packet_req.m_id ); + m_packet_req.m_flags = std::move(other.m_packet_req.m_flags); + m_packet_req.m_data = std::move(other.m_packet_req.m_data ); + + m_packet_res.m_code = std::move(other.m_packet_res.m_code ); + m_packet_res.m_id = std::move(other.m_packet_res.m_id ); + m_packet_res.m_flags = std::move(other.m_packet_res.m_flags); + m_packet_res.m_data = std::move(other.m_packet_res.m_data ); + + memcpy(m_random_client, other.m_random_client, sizeof(tls_random_t)); + memcpy(m_random_server, other.m_random_server, sizeof(tls_random_t)); +} + + +eap::session_tls::~session_tls() +{ + SecureZeroMemory(m_random_client, sizeof(tls_random_t)); + SecureZeroMemory(m_random_server, sizeof(tls_random_t)); } eap::session_tls& eap::session_tls::operator=(_In_ const session_tls &other) { - if (this != &other) + if (this != &other) { (session&)*this = other; + m_phase = other.m_phase; + + m_packet_req.m_code = other.m_packet_req.m_code ; + m_packet_req.m_id = other.m_packet_req.m_id ; + m_packet_req.m_flags = other.m_packet_req.m_flags; + m_packet_req.m_data = other.m_packet_req.m_data ; + + m_packet_res.m_code = other.m_packet_res.m_code ; + m_packet_res.m_id = other.m_packet_res.m_id ; + m_packet_res.m_flags = other.m_packet_res.m_flags; + m_packet_res.m_data = other.m_packet_res.m_data ; + + m_session_id = other.m_session_id; + + memcpy(m_random_client, other.m_random_client, sizeof(tls_random_t)); + memcpy(m_random_server, other.m_random_server, sizeof(tls_random_t)); + } return *this; } @@ -56,27 +120,44 @@ eap::session_tls& eap::session_tls::operator=(_In_ const session_tls &other) eap::session_tls& eap::session_tls::operator=(_Inout_ session_tls &&other) { - if (this != &other) + if (this != &other) { (session&)*this = std::move(other); + m_phase = std::move(other.m_phase); + + m_packet_req.m_code = std::move(other.m_packet_req.m_code ); + m_packet_req.m_id = std::move(other.m_packet_req.m_id ); + m_packet_req.m_flags = std::move(other.m_packet_req.m_flags); + m_packet_req.m_data = std::move(other.m_packet_req.m_data ); + + m_packet_res.m_code = std::move(other.m_packet_res.m_code ); + m_packet_res.m_id = std::move(other.m_packet_res.m_id ); + m_packet_res.m_flags = std::move(other.m_packet_res.m_flags); + m_packet_res.m_data = std::move(other.m_packet_res.m_data ); + + m_session_id = std::move(other.m_session_id); + + memcpy(m_random_client, other.m_random_client, sizeof(tls_random_t)); + memcpy(m_random_server, other.m_random_server, sizeof(tls_random_t)); + } return *this; } -//bool eap::session_tls::begin( -// _In_ DWORD dwFlags, -// _In_ const EapAttributes *pAttributeArray, -// _In_ HANDLE hTokenImpersonateUser, -// _In_ DWORD dwMaxSendPacketSize, -// _Out_ EAP_ERROR **ppEapError) -//{ -// if (!session::begin(dwFlags, pAttributeArray, hTokenImpersonateUser, dwMaxSendPacketSize, ppEapError)) -// return false; -// -// -// -// return true; -//} +bool eap::session_tls::begin( + _In_ DWORD dwFlags, + _In_ const EapAttributes *pAttributeArray, + _In_ HANDLE hTokenImpersonateUser, + _In_ DWORD dwMaxSendPacketSize, + _Out_ EAP_ERROR **ppEapError) +{ + if (dwMaxSendPacketSize <= 10) { + *ppEapError = m_module.make_error(ERROR_NOT_SUPPORTED, wstring_printf(_T(__FUNCTION__) _T(" Maximum send packet size too small (expected: >%u, received: %u)."), 10, dwMaxSendPacketSize).c_str()); + return false; + } + + return session::begin(dwFlags, pAttributeArray, hTokenImpersonateUser, dwMaxSendPacketSize, ppEapError); +} bool eap::session_tls::process_request_packet( @@ -85,13 +166,158 @@ bool eap::session_tls::process_request_packet( _Out_ EapPeerMethodOutput *pEapOutput, _Out_ EAP_ERROR **ppEapError) { - UNREFERENCED_PARAMETER(dwReceivedPacketSize); - UNREFERENCED_PARAMETER(pReceivedPacket); - UNREFERENCED_PARAMETER(pEapOutput); + assert(pReceivedPacket && dwReceivedPacketSize >= 4); + assert(pEapOutput); assert(ppEapError); - *ppEapError = m_module.make_error(ERROR_NOT_SUPPORTED, _T(__FUNCTION__) _T(" Not supported.")); - return false; + // Initialize output. + pEapOutput->fAllowNotifications = TRUE; + pEapOutput->action = EapPeerMethodResponseActionDiscard; + + // Is this a valid EAP-TLS packet? + if (dwReceivedPacketSize < 6) { + *ppEapError = m_module.make_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, _T(__FUNCTION__) _T(" Packet is too small. EAP-%s packets should be at least 6B.")); + return false; + }/* else if (pReceivedPacket->Data[0] != eap_type_tls) { + *ppEapError = m_module.make_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, wstring_printf(_T(__FUNCTION__) _T(" Packet is not EAP-TLS (expected: %u, received: %u)."), eap_type_tls, pReceivedPacket->Data[0]).c_str()); + return false; + }*/ + + if (pReceivedPacket->Data[1] & tls_flags_more_frag) { + if (pReceivedPacket->Data[1] & tls_flags_length_incl) { + // First fragment received. + if (dwReceivedPacketSize < 10) { + *ppEapError = m_module.make_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, _T(__FUNCTION__) _T(" Packet is too small. EAP-TLS first fragmented packet should be at least 10B.")); + return false; + } + + // Start a new packet. + m_packet_req.m_code = (EapCode)pReceivedPacket->Code; + m_packet_req.m_id = pReceivedPacket->Id; + m_packet_req.m_flags = pReceivedPacket->Data[1]; + m_packet_req.m_data.reserve(*(DWORD*)(pReceivedPacket->Data + 2)); + m_packet_req.m_data.assign(pReceivedPacket->Data + 6, pReceivedPacket->Data + dwReceivedPacketSize - 4); + } else { + // Mid fragment received. Append data. + m_packet_req.m_data.insert(m_packet_req.m_data.end(), pReceivedPacket->Data + 2, pReceivedPacket->Data + dwReceivedPacketSize - 4); + } + + // Reply with ACK packet. + m_packet_res.m_code = EapCodeResponse; + m_packet_res.m_id = m_packet_req.m_id; + m_packet_res.m_flags = 0; + m_packet_res.m_data.clear(); + pEapOutput->action = EapPeerMethodResponseActionSend; + return true; + } else if (!m_packet_req.m_data.empty()) { + // Last fragment received. Append data. + m_packet_req.m_data.insert(m_packet_req.m_data.end(), + pReceivedPacket->Data + (!(pReceivedPacket->Data[1] & tls_flags_length_incl) ? 2 : 6), // Should not include "Length" field (by RFC 5281: https://tools.ietf.org/html/rfc5281#section-9.2.2). Tolerate. + pReceivedPacket->Data + dwReceivedPacketSize - 4); + } + + if ( m_packet_req.m_code == EapCodeRequest && + m_packet_req.m_id == m_packet_res.m_id && + m_packet_req.m_data.empty() && + !(m_packet_req.m_flags & (tls_flags_length_incl | tls_flags_more_frag | tls_flags_start)) && + (m_packet_res.m_flags & tls_flags_more_frag )) + { + // This is an ACK of our fragmented packet response. Send the next fragment. + m_packet_res.m_id++; + pEapOutput->action = EapPeerMethodResponseActionSend; + return true; + } + + switch (m_phase) { + case phase_handshake_start: { + // Is this an EAP-TLS Start packet? + if (m_packet_req.m_code != EapCodeRequest) { + *ppEapError = m_module.make_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, wstring_printf(_T(__FUNCTION__) _T(" Packet is not a request (expected: %x, received: %x)."), EapCodeRequest, m_packet_req.m_code).c_str()); + return false; + } else if (!(m_packet_req.m_flags & tls_flags_start)) { + *ppEapError = m_module.make_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, wstring_printf(_T(__FUNCTION__) _T(" Packet is not EAP-TLS Start (expected: %x, received: %x)."), tls_flags_start, m_packet_req.m_flags).c_str()); + return false; + } + + //// Determine minimum EAP-TLS version supported by server and us. + //version_t ver_remote = (version_t)(m_packet_req.m_flags & tls_flags_ver_mask); + //m_version = std::min(ver_remote, version_0); + //m_module.log_event(&EAPMETHOD_HANDSHAKE_START, event_data(m_cred.target_suffix()), event_data((unsigned char)m_version), event_data((unsigned char)ver_remote), event_data::blank); + + // Build response packet. + m_packet_res.m_code = EapCodeResponse; + m_packet_res.m_id = m_packet_req.m_id; + m_packet_res.m_flags = 0; + + + //if (!m_packet_res.create(EapCodeResponse, pReceivedPacket->Id, eap_type_tls, (BYTE)m_version)) { + // *ppEapError = m_module.make_error(GetLastError(), _T(__FUNCTION__) _T(" Error creating packet.")); + // return false; + //} + break; + } + + default: + *ppEapError = m_module.make_error(ERROR_NOT_SUPPORTED, _T(__FUNCTION__) _T(" Not supported.")); + return false; + } + + return true; +} + + +bool eap::session_tls::get_response_packet( + _Inout_ DWORD *pdwSendPacketSize, + _Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket, + _Out_ EAP_ERROR **ppEapError) +{ + assert(pdwSendPacketSize); + assert(pSendPacket); + UNREFERENCED_PARAMETER(ppEapError); + + DWORD + size_data = (DWORD)m_packet_res.m_data.size(), + size_packet = size_data + 6; + WORD size_packet_limit = (WORD)std::min(m_send_packet_size_max, (WORD)-1); + BYTE *data_dst; + + if (!(m_packet_res.m_flags & tls_flags_more_frag)) { + // Not fragmented. + if (size_packet <= size_packet_limit) { + // No need to fragment the packet. + m_packet_res.m_flags &= ~tls_flags_length_incl; // No need to explicitly include the Length field either. + data_dst = pSendPacket->Data + 2; + } else { + // But it should be fragmented. + m_packet_res.m_flags |= tls_flags_length_incl | tls_flags_more_frag; + *(DWORD*)(pSendPacket->Data + 2) = (DWORD)size_packet; + data_dst = pSendPacket->Data + 6; + size_data = size_packet_limit - 10; + size_packet = size_packet_limit; + } + } else { + // Continuing the fragmented packet... + if (size_packet <= size_packet_limit) { + // This is the last fragment. + m_packet_res.m_flags &= ~(tls_flags_length_incl | tls_flags_more_frag); + } else { + // This is a mid fragment. + m_packet_res.m_flags &= ~tls_flags_length_incl; + size_data = size_packet_limit - 6; + size_packet = size_packet_limit; + } + data_dst = pSendPacket->Data + 2; + } + + pSendPacket->Code = (BYTE)m_packet_res.m_code; + pSendPacket->Id = m_packet_res.m_id; + *(WORD*)pSendPacket->Length = htons((WORD)size_packet); + pSendPacket->Data[0] = (BYTE)eap_type_tls; + pSendPacket->Data[1] = m_packet_res.m_flags; + memcpy(data_dst, m_packet_res.m_data.data(), size_data); + m_packet_res.m_data.erase(m_packet_res.m_data.begin(), m_packet_res.m_data.begin() + size_data); + *pdwSendPacketSize = size_packet; + return true; } diff --git a/lib/TLS/src/StdAfx.h b/lib/TLS/src/StdAfx.h index 92f3151..59e752a 100644 --- a/lib/TLS/src/StdAfx.h +++ b/lib/TLS/src/StdAfx.h @@ -27,3 +27,6 @@ #include "../../EAPBase/include/EAPXML.h" #include +#include + +#include diff --git a/lib/TTLS/include/Session.h b/lib/TTLS/include/Session.h index 50863b7..efec1f6 100644 --- a/lib/TTLS/include/Session.h +++ b/lib/TTLS/include/Session.h @@ -20,32 +20,32 @@ namespace eap { - /// - /// TTLS session - /// - class session_ttls; - - /// /// EAP-TTLS packet flags /// /// \sa [Extensible Authentication Protocol Tunneled Transport Layer Security Authenticated Protocol Version 0 (EAP-TTLSv0) (Chapter: 9.1 Packet Format)](https://tools.ietf.org/html/rfc5281#section-9.1) /// enum ttls_flags_t; + + /// + /// TTLS session + /// + class session_ttls; } #pragma once +#include "../../TLS/include/Session.h" #include "../../EAPBase/include/Session.h" namespace eap { enum ttls_flags_t { - ttls_flags_length_incl = 0x80, ///< Length included - ttls_flags_more_frag = 0x40, ///< More fragments - ttls_flags_start = 0x20, ///< Start - ttls_flags_ver_mask = 0x07, ///< Version mask + ttls_flags_length_incl = tls_flags_length_incl, ///< Length included + ttls_flags_more_frag = tls_flags_more_frag, ///< More fragments + ttls_flags_start = tls_flags_start, ///< Start + ttls_flags_ver_mask = 0x07, ///< Version mask }; @@ -91,27 +91,6 @@ namespace eap /// session_ttls& operator=(_Inout_ session_ttls &&other); - /// \name Session start/end - /// @{ - - /// - /// Starts an EAP authentication session on the peer EAPHost using the EAP method. - /// - /// \sa [EapPeerBeginSession function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363600.aspx) - /// - /// \returns - /// - \c true if succeeded - /// - \c false otherwise. See \p ppEapError for details. - /// - virtual bool begin( - _In_ DWORD dwFlags, - _In_ const EapAttributes *pAttributeArray, - _In_ HANDLE hTokenImpersonateUser, - _In_ DWORD dwMaxSendPacketSize, - _Out_ EAP_ERROR **ppEapError); - - /// @} - /// \name Packet processing /// @{ @@ -161,21 +140,8 @@ namespace eap /// @} public: - enum phase_t { - phase_handshake_start = 0, - } m_phase; ///< Session phase - enum version_t { version_0 = 0, ///< EAP-TTLS v0 } m_version; ///< EAP-TTLS version - - struct { - EapCode m_code; ///< Packet code - BYTE m_id; ///< Packet ID - BYTE m_flags; ///< Packet flags - std::vector m_data; ///< Packet data - } - m_packet_req, ///< Request packet - m_packet_res; ///< Response packet }; } diff --git a/lib/TTLS/src/Session.cpp b/lib/TTLS/src/Session.cpp index 83f7754..9855008 100644 --- a/lib/TTLS/src/Session.cpp +++ b/lib/TTLS/src/Session.cpp @@ -29,51 +29,23 @@ using namespace winstd; ////////////////////////////////////////////////////////////////////// eap::session_ttls::session_ttls(_In_ module &mod) : - m_phase(phase_handshake_start), m_version(version_0), session(mod) { - m_packet_req.m_code = (EapCode)0; - m_packet_req.m_id = 0; - m_packet_req.m_flags = version_0; - - m_packet_res.m_code = (EapCode)0; - m_packet_res.m_id = 0; - m_packet_res.m_flags = version_0; } eap::session_ttls::session_ttls(_In_ const session_ttls &other) : - m_phase(other.m_phase), m_version(other.m_version), session(other) { - m_packet_req.m_code = other.m_packet_req.m_code ; - m_packet_req.m_id = other.m_packet_req.m_id ; - m_packet_req.m_flags = other.m_packet_req.m_flags; - m_packet_req.m_data = other.m_packet_req.m_data ; - - m_packet_res.m_code = other.m_packet_res.m_code ; - m_packet_res.m_id = other.m_packet_res.m_id ; - m_packet_res.m_flags = other.m_packet_res.m_flags; - m_packet_res.m_data = other.m_packet_res.m_data ; } eap::session_ttls::session_ttls(_Inout_ session_ttls &&other) : - m_phase(std::move(other.m_phase)), m_version(std::move(other.m_version)), session(std::move(other)) { - m_packet_req.m_code = std::move(other.m_packet_req.m_code ); - m_packet_req.m_id = std::move(other.m_packet_req.m_id ); - m_packet_req.m_flags = std::move(other.m_packet_req.m_flags); - m_packet_req.m_data = std::move(other.m_packet_req.m_data ); - - m_packet_res.m_code = std::move(other.m_packet_res.m_code ); - m_packet_res.m_id = std::move(other.m_packet_res.m_id ); - m_packet_res.m_flags = std::move(other.m_packet_res.m_flags); - m_packet_res.m_data = std::move(other.m_packet_res.m_data ); } @@ -81,18 +53,7 @@ eap::session_ttls& eap::session_ttls::operator=(_In_ const session_ttls &other) { if (this != &other) { (session&)*this = other; - m_phase = other.m_phase; - m_version = other.m_version; - - m_packet_req.m_code = other.m_packet_req.m_code ; - m_packet_req.m_id = other.m_packet_req.m_id ; - m_packet_req.m_flags = other.m_packet_req.m_flags; - m_packet_req.m_data = other.m_packet_req.m_data ; - - m_packet_res.m_code = other.m_packet_res.m_code ; - m_packet_res.m_id = other.m_packet_res.m_id ; - m_packet_res.m_flags = other.m_packet_res.m_flags; - m_packet_res.m_data = other.m_packet_res.m_data ; + m_version = other.m_version; } return *this; @@ -103,136 +64,26 @@ eap::session_ttls& eap::session_ttls::operator=(_Inout_ session_ttls &&other) { if (this != &other) { (session&)*this = std::move(other); - m_phase = std::move(other.m_phase); - m_version = std::move(other.m_version); - - m_packet_req.m_code = std::move(other.m_packet_req.m_code ); - m_packet_req.m_id = std::move(other.m_packet_req.m_id ); - m_packet_req.m_flags = std::move(other.m_packet_req.m_flags); - m_packet_req.m_data = std::move(other.m_packet_req.m_data ); - - m_packet_res.m_code = std::move(other.m_packet_res.m_code ); - m_packet_res.m_id = std::move(other.m_packet_res.m_id ); - m_packet_res.m_flags = std::move(other.m_packet_res.m_flags); - m_packet_res.m_data = std::move(other.m_packet_res.m_data ); + m_version = std::move(other.m_version); } return *this; } -bool eap::session_ttls::begin( - _In_ DWORD dwFlags, - _In_ const EapAttributes *pAttributeArray, - _In_ HANDLE hTokenImpersonateUser, - _In_ DWORD dwMaxSendPacketSize, - _Out_ EAP_ERROR **ppEapError) -{ - if (dwMaxSendPacketSize <= 10) { - *ppEapError = m_module.make_error(ERROR_NOT_SUPPORTED, wstring_printf(_T(__FUNCTION__) _T(" Maximum send packet size too small (expected: >%u, received: %u)."), 10, dwMaxSendPacketSize).c_str()); - return false; - } - - return session::begin(dwFlags, pAttributeArray, hTokenImpersonateUser, dwMaxSendPacketSize, ppEapError); -} - - bool eap::session_ttls::process_request_packet( _In_ DWORD dwReceivedPacketSize, _In_bytecount_(dwReceivedPacketSize) const EapPacket *pReceivedPacket, _Out_ EapPeerMethodOutput *pEapOutput, _Out_ EAP_ERROR **ppEapError) { - assert(pReceivedPacket && dwReceivedPacketSize >= 4); - assert(pEapOutput); + UNREFERENCED_PARAMETER(dwReceivedPacketSize); + UNREFERENCED_PARAMETER(pReceivedPacket); + UNREFERENCED_PARAMETER(pEapOutput); assert(ppEapError); - // Initialize output. - pEapOutput->fAllowNotifications = TRUE; - pEapOutput->action = EapPeerMethodResponseActionDiscard; - - // Is this a valid EAP-TTLS packet? - if (dwReceivedPacketSize < 6) { - *ppEapError = m_module.make_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, _T(__FUNCTION__) _T(" Packet is too small. EAP-TTLS packets should be at least 6B.")); - return false; - } else if (pReceivedPacket->Data[0] != eap_type_ttls) { - *ppEapError = m_module.make_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, wstring_printf(_T(__FUNCTION__) _T(" Packet is not EAP-TTLS (expected: %u, received: %u)."), eap_type_ttls, pReceivedPacket->Data[0]).c_str()); - return false; - } - - if (pReceivedPacket->Data[1] & ttls_flags_more_frag) { - if (pReceivedPacket->Data[1] & ttls_flags_length_incl) { - // First fragment received. - if (dwReceivedPacketSize < 10) { - *ppEapError = m_module.make_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, _T(__FUNCTION__) _T(" Packet is too small. EAP-TTLS first fragmented packet should be at least 10B.")); - return false; - } - - // Start a new packet. - m_packet_req.m_code = (EapCode)pReceivedPacket->Code; - m_packet_req.m_id = pReceivedPacket->Id; - m_packet_req.m_flags = pReceivedPacket->Data[1]; - m_packet_req.m_data.reserve(*(DWORD*)(pReceivedPacket->Data + 2)); - m_packet_req.m_data.assign(pReceivedPacket->Data + 6, pReceivedPacket->Data + dwReceivedPacketSize - 4); - } else { - // Mid fragment received. Append data. - m_packet_req.m_data.insert(m_packet_req.m_data.end(), pReceivedPacket->Data + 2, pReceivedPacket->Data + dwReceivedPacketSize - 4); - } - - // Reply with Acknowledgement packet. - m_packet_res.m_code = EapCodeResponse; - m_packet_res.m_id = m_packet_req.m_id; - m_packet_res.m_flags = 0; - m_packet_res.m_data.clear(); - pEapOutput->action = EapPeerMethodResponseActionSend; - return true; - } else if (!m_packet_req.m_data.empty()) { - // Last fragment received. Append data. - m_packet_req.m_data.insert(m_packet_req.m_data.end(), - pReceivedPacket->Data + (!(pReceivedPacket->Data[1] & ttls_flags_length_incl) ? 2 : 6), // Should not include "Length" field (by RFC 5281: https://tools.ietf.org/html/rfc5281#section-9.2.2). Tolerate. - pReceivedPacket->Data + dwReceivedPacketSize - 4); - } - - if ( m_packet_req.m_code == EapCodeResponse && - m_packet_req.m_id == m_packet_res.m_id && - !(m_packet_req.m_flags & (ttls_flags_length_incl | ttls_flags_more_frag | ttls_flags_start)) && - (m_packet_res.m_flags & ttls_flags_more_frag )) - { - // This is an Acknowledgement of our fragmented packet response. Send the next fragment. - pEapOutput->action = EapPeerMethodResponseActionSend; - return true; - } - - switch (m_phase) { - case phase_handshake_start: { - // Is this an EAP-TTLS Start packet? - if (m_packet_req.m_code != EapCodeRequest) { - *ppEapError = m_module.make_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, wstring_printf(_T(__FUNCTION__) _T(" Packet is not a request (expected: %x, received: %x)."), EapCodeRequest, m_packet_req.m_code).c_str()); - return false; - } else if (!(m_packet_req.m_flags & ttls_flags_start)) { - *ppEapError = m_module.make_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, wstring_printf(_T(__FUNCTION__) _T(" Packet is not EAP-TTLS Start (expected: %x, received: %x)."), ttls_flags_start, m_packet_req.m_flags).c_str()); - return false; - } - - // Determine minimum EAP-TTLS version supported by server and us. - version_t ver_remote = (version_t)(m_packet_req.m_flags & ttls_flags_ver_mask); - m_version = std::min(ver_remote, version_0); - m_module.log_event(&EAPMETHOD_HANDSHAKE_START, event_data(m_cred.target_suffix()), event_data((unsigned char)m_version), event_data((unsigned char)ver_remote), event_data::blank); - - // Build response packet. - //if (!m_packet_res.create(EapCodeResponse, pReceivedPacket->Id, eap_type_ttls, (BYTE)m_version)) { - // *ppEapError = m_module.make_error(GetLastError(), _T(__FUNCTION__) _T(" Error creating packet.")); - // return false; - //} - break; - } - - default: - *ppEapError = m_module.make_error(ERROR_NOT_SUPPORTED, _T(__FUNCTION__) _T(" Not supported.")); - return false; - } - - return true; + *ppEapError = m_module.make_error(ERROR_NOT_SUPPORTED, _T(__FUNCTION__) _T(" Not supported.")); + return false; } @@ -241,53 +92,12 @@ bool eap::session_ttls::get_response_packet( _Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket, _Out_ EAP_ERROR **ppEapError) { - assert(pdwSendPacketSize); - assert(pSendPacket); - UNREFERENCED_PARAMETER(ppEapError); + UNREFERENCED_PARAMETER(pdwSendPacketSize); + UNREFERENCED_PARAMETER(pSendPacket); + assert(ppEapError); - DWORD - size_data = (DWORD)m_packet_res.m_data.size(), - size_packet = size_data + 6; - WORD size_packet_limit = (WORD)std::min(m_send_packet_size_max, (WORD)-1); - BYTE *data_dst; - - if (!(m_packet_res.m_flags & ttls_flags_more_frag)) { - // Not fragmented. - if (size_packet <= size_packet_limit) { - // No need to fragment the packet. - m_packet_res.m_flags &= ~ttls_flags_length_incl; // No need to explicitly include the Length field either. - data_dst = pSendPacket->Data + 2; - } else { - // But it should be fragmented. - m_packet_res.m_flags |= ttls_flags_length_incl | ttls_flags_more_frag; - *(DWORD*)(pSendPacket->Data + 2) = (DWORD)size_packet; - data_dst = pSendPacket->Data + 6; - size_data = size_packet_limit - 10; - size_packet = size_packet_limit; - } - } else { - // Continuing the fragmented packet... - if (size_packet <= size_packet_limit) { - // This is the last fragment. - m_packet_res.m_flags &= ~(ttls_flags_length_incl | ttls_flags_more_frag); - } else { - // This is a mid fragment. - m_packet_res.m_flags &= ~ttls_flags_length_incl; - size_data = size_packet_limit - 6; - size_packet = size_packet_limit; - } - data_dst = pSendPacket->Data + 2; - } - - pSendPacket->Code = (BYTE)m_packet_res.m_code; - pSendPacket->Id = m_packet_res.m_id; - *(WORD*)pSendPacket->Length = htons((WORD)size_packet); - pSendPacket->Data[0] = (BYTE)eap_type_ttls; - pSendPacket->Data[1] = m_packet_res.m_flags | (BYTE)m_version; - memcpy(data_dst, m_packet_res.m_data.data(), size_data); - m_packet_res.m_data.erase(m_packet_res.m_data.begin(), m_packet_res.m_data.begin() + size_data); - *pdwSendPacketSize = size_packet; - return true; + *ppEapError = m_module.make_error(ERROR_NOT_SUPPORTED, _T(__FUNCTION__) _T(" Not supported.")); + return false; }