diff --git a/lib/EAPBase/build/EAPBase.vcxproj b/lib/EAPBase/build/EAPBase.vcxproj index 06c807e..f58506a 100644 --- a/lib/EAPBase/build/EAPBase.vcxproj +++ b/lib/EAPBase/build/EAPBase.vcxproj @@ -91,6 +91,7 @@ + Create Create diff --git a/lib/EAPBase/build/EAPBase.vcxproj.filters b/lib/EAPBase/build/EAPBase.vcxproj.filters index 7940a33..94c314a 100644 --- a/lib/EAPBase/build/EAPBase.vcxproj.filters +++ b/lib/EAPBase/build/EAPBase.vcxproj.filters @@ -46,5 +46,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/lib/EAPBase/include/Session.h b/lib/EAPBase/include/Session.h index 1a936c4..72a36f8 100644 --- a/lib/EAPBase/include/Session.h +++ b/lib/EAPBase/include/Session.h @@ -20,6 +20,11 @@ namespace eap { + /// + /// EAP method base class + /// + class method; + /// /// EAP session /// @@ -28,6 +33,8 @@ namespace eap #pragma once +#include "Config.h" +#include "Credentials.h" #include "Module.h" #include @@ -42,6 +49,90 @@ extern "C" { namespace eap { + class method + { + public: + /// + /// Constructs an EAP method + /// + /// \param[in] mod EAP module to use for global services + /// \param[in] cfg Method configuration + /// + method(_In_ module &module, _In_ config_method &cfg, _In_ credentials &cred); + + /// + /// Copies an EAP method + /// + /// \param[in] other EAP method to copy from + /// + method(_In_ const method &other); + + /// + /// Moves an EAP method + /// + /// \param[in] other EAP method to move from + /// + method(_Inout_ method &&other); + + /// + /// Copies an EAP method + /// + /// \param[in] other EAP method to copy from + /// + /// \returns Reference to this object + /// + method& operator=(_In_ const method &other); + + /// + /// Moves an EAP method + /// + /// \param[in] other EAP method to move from + /// + /// \returns Reference to this object + /// + method& operator=(_Inout_ method &&other); + + /// \name Packet processing + /// @{ + + /// + /// Processes a packet received by EAPHost from a supplicant. + /// + /// \returns + /// - \c true if succeeded + /// - \c false otherwise. See \p ppEapError for details. + /// + /// \sa [EapPeerProcessRequestPacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363621.aspx) + /// + virtual bool process_request_packet( + _In_bytecount_(dwReceivedPacketSize) const EapPacket *pReceivedPacket, + _In_ DWORD dwReceivedPacketSize, + _Out_ EapPeerMethodOutput *pEapOutput, + _Out_ EAP_ERROR **ppEapError) = 0; + + /// + /// 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_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket, + _Inout_ DWORD *pdwSendPacketSize, + _Out_ EAP_ERROR **ppEapError) = 0; + + /// @} + + public: + module &m_module; ///< EAP module + config_method &m_cfg; ///< Method configuration + credentials &m_cred; ///< User credentials + }; + + template class session { @@ -340,7 +431,7 @@ namespace eap public: module &m_module; ///< EAP module - config_provider_list m_cfg; ///< Providers configuration + config_provider_list 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 diff --git a/lib/EAPBase/src/Session.cpp b/lib/EAPBase/src/Session.cpp new file mode 100644 index 0000000..45f93ae --- /dev/null +++ b/lib/EAPBase/src/Session.cpp @@ -0,0 +1,76 @@ +/* + Copyright 2015-2016 Amebis + Copyright 2016 GÉANT + + This file is part of GÉANTLink. + + GÉANTLink is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + GÉANTLink is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GÉANTLink. If not, see . +*/ + +#include "StdAfx.h" + +using namespace std; +using namespace winstd; + + +////////////////////////////////////////////////////////////////////// +// eap::method +////////////////////////////////////////////////////////////////////// + +eap::method::method(_In_ module &module, _In_ config_method &cfg, _In_ credentials &cred) : + m_module(module), + m_cfg(cfg), + m_cred(cred) +{ +} + + +eap::method::method(_In_ const method &other) : + m_module(other.m_module), + m_cfg(other.m_cfg), + m_cred(other.m_cred) +{ +} + + +eap::method::method(_Inout_ method &&other) : + m_module(other.m_module), + m_cfg(other.m_cfg), + m_cred(other.m_cred) +{ +} + + +eap::method& eap::method::operator=(_In_ const method &other) +{ + if (this != std::addressof(other)) { + assert(std::addressof(m_module) == std::addressof(other.m_module)); // Copy method within same module only! + assert(std::addressof(m_cfg ) == std::addressof(other.m_cfg )); // Copy method with same configuration only! + assert(std::addressof(m_cred ) == std::addressof(other.m_cred )); // Copy method with same credentials only! + } + + return *this; +} + + +eap::method& eap::method::operator=(_Inout_ method &&other) +{ + if (this != std::addressof(other)) { + assert(std::addressof(m_module) == std::addressof(other.m_module)); // Copy method within same module only! + assert(std::addressof(m_cfg ) == std::addressof(other.m_cfg )); // Copy method with same configuration only! + assert(std::addressof(m_cred ) == std::addressof(other.m_cred )); // Copy method with same credentials only! + } + + return *this; +} diff --git a/lib/TLS/include/Session.h b/lib/TLS/include/Session.h index 0ef2343..8fb7a70 100644 --- a/lib/TLS/include/Session.h +++ b/lib/TLS/include/Session.h @@ -32,6 +32,11 @@ namespace eap /// enum tls_flags_t; + /// + /// TLS method + /// + class method_tls; + /// /// TLS session /// @@ -60,73 +65,53 @@ namespace eap }; - class session_tls : public session + class method_tls : public method { public: /// - /// Constructor + /// Constructs an EAP method /// /// \param[in] mod EAP module to use for global services + /// \param[in] cfg Method configuration /// - session_tls(_In_ module &mod); + method_tls(_In_ module &module, _In_ config_method &cfg, _In_ credentials &cred); /// - /// Copies TLS session + /// Copies an EAP method /// - /// \param[in] other Session to copy from + /// \param[in] other EAP method to copy from /// - session_tls(_In_ const session_tls &other); + method_tls(_In_ const method_tls &other); /// - /// Moves TLS session + /// Moves an EAP method /// - /// \param[in] other Session to move from + /// \param[in] other EAP method to move from /// - session_tls(_Inout_ session_tls &&other); + method_tls(_Inout_ method_tls &&other); /// /// Destructor /// - virtual ~session_tls(); + virtual ~method_tls(); /// - /// Copies TLS session + /// Copies an EAP method /// - /// \param[in] other Session to copy from + /// \param[in] other EAP method to copy from /// /// \returns Reference to this object /// - session_tls& operator=(_In_ const session_tls &other); + method_tls& operator=(_In_ const method_tls &other); /// - /// Moves TLS session + /// Moves an EAP method /// - /// \param[in] other Session to move from + /// \param[in] other EAP method to move from /// /// \returns Reference to this object /// - session_tls& operator=(_Inout_ session_tls &&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); - - /// @} + method_tls& operator=(_Inout_ method_tls &&other); /// \name Packet processing /// @{ @@ -134,15 +119,15 @@ namespace eap /// /// Processes a packet received by EAPHost from a supplicant. /// - /// \sa [EapPeerProcessRequestPacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363621.aspx) - /// /// \returns /// - \c true if succeeded /// - \c false otherwise. See \p ppEapError for details. /// + /// \sa [EapPeerProcessRequestPacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363621.aspx) + /// virtual bool process_request_packet( - _In_ DWORD dwReceivedPacketSize, _In_bytecount_(dwReceivedPacketSize) const EapPacket *pReceivedPacket, + _In_ DWORD dwReceivedPacketSize, _Out_ EapPeerMethodOutput *pEapOutput, _Out_ EAP_ERROR **ppEapError); @@ -156,24 +141,10 @@ namespace eap /// - \c false otherwise. See \p ppEapError for details. /// virtual bool get_response_packet( - _Inout_ DWORD *pdwSendPacketSize, _Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket, + _Inout_ DWORD *pdwSendPacketSize, _Out_ EAP_ERROR **ppEapError); - /// - /// Obtains the result of an authentication session from the EAP method. - /// - /// \sa [EapPeerGetResult function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363611.aspx) - /// - /// \returns - /// - \c true if succeeded - /// - \c false otherwise. See \p ppEapError for details. - /// - virtual bool get_result( - _In_ EapPeerMethodResultReason reason, - _Out_ EapPeerMethodResult *ppResult, - _Out_ EAP_ERROR **ppEapError); - /// @} public: diff --git a/lib/TLS/src/Session.cpp b/lib/TLS/src/Session.cpp index 31cd76d..179e2ec 100644 --- a/lib/TLS/src/Session.cpp +++ b/lib/TLS/src/Session.cpp @@ -25,12 +25,12 @@ using namespace winstd; ////////////////////////////////////////////////////////////////////// -// eap::session_tls +// eap::method_tls ////////////////////////////////////////////////////////////////////// -eap::session_tls::session_tls(_In_ module &mod) : +eap::method_tls::method_tls(_In_ module &module, _In_ config_method &cfg, _In_ credentials &cred) : m_phase(phase_handshake_start), - session(mod) + method(module, cfg, cred) { m_packet_req.m_code = (EapCode)0; m_packet_req.m_id = 0; @@ -45,10 +45,10 @@ eap::session_tls::session_tls(_In_ module &mod) : } -eap::session_tls::session_tls(_In_ const session_tls &other) : +eap::method_tls::method_tls(_In_ const method_tls &other) : m_phase(other.m_phase), m_session_id(other.m_session_id), - session(other) + method(other) { m_packet_req.m_code = other.m_packet_req.m_code ; m_packet_req.m_id = other.m_packet_req.m_id ; @@ -65,10 +65,10 @@ eap::session_tls::session_tls(_In_ const session_tls &other) : } -eap::session_tls::session_tls(_Inout_ session_tls &&other) : +eap::method_tls::method_tls(_Inout_ method_tls &&other) : m_phase(std::move(other.m_phase)), m_session_id(std::move(other.m_session_id)), - session(std::move(other)) + method(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 ); @@ -85,17 +85,18 @@ eap::session_tls::session_tls(_Inout_ session_tls &&other) : } -eap::session_tls::~session_tls() +eap::method_tls::~method_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) +eap::method_tls& eap::method_tls::operator=(_In_ const method_tls &other) { - if (this != &other) { - (session&)*this = other; + if (this != std::addressof(other)) { + (method&)*this = other; + m_phase = other.m_phase; m_packet_req.m_code = other.m_packet_req.m_code ; @@ -118,10 +119,11 @@ eap::session_tls& eap::session_tls::operator=(_In_ const session_tls &other) } -eap::session_tls& eap::session_tls::operator=(_Inout_ session_tls &&other) +eap::method_tls& eap::method_tls::operator=(_Inout_ method_tls &&other) { - if (this != &other) { - (session&)*this = std::move(other); + if (this != std::addressof(other)) { + (method&)*this = std::move(other); + m_phase = std::move(other.m_phase); m_packet_req.m_code = std::move(other.m_packet_req.m_code ); @@ -144,25 +146,9 @@ eap::session_tls& eap::session_tls::operator=(_Inout_ session_tls &&other) } -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( - _In_ DWORD dwReceivedPacketSize, +bool eap::method_tls::process_request_packet( _In_bytecount_(dwReceivedPacketSize) const EapPacket *pReceivedPacket, + _In_ DWORD dwReceivedPacketSize, _Out_ EapPeerMethodOutput *pEapOutput, _Out_ EAP_ERROR **ppEapError) { @@ -178,7 +164,7 @@ bool eap::session_tls::process_request_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) { + }/* else if (pReceivedPacket->Data[0] != eap_type_tls) { // Skip method check, to allow TTLS extension. *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; }*/ @@ -266,9 +252,9 @@ bool eap::session_tls::process_request_packet( } -bool eap::session_tls::get_response_packet( - _Inout_ DWORD *pdwSendPacketSize, +bool eap::method_tls::get_response_packet( _Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket, + _Inout_ DWORD *pdwSendPacketSize, _Out_ EAP_ERROR **ppEapError) { assert(pdwSendPacketSize); @@ -278,7 +264,7 @@ bool eap::session_tls::get_response_packet( 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); + WORD size_packet_limit = (WORD)std::min(*pdwSendPacketSize, (WORD)-1); BYTE *data_dst; if (!(m_packet_res.m_flags & tls_flags_more_frag)) { @@ -319,17 +305,3 @@ bool eap::session_tls::get_response_packet( *pdwSendPacketSize = size_packet; return true; } - - -bool eap::session_tls::get_result( - _In_ EapPeerMethodResultReason reason, - _Out_ EapPeerMethodResult *ppResult, - _Out_ EAP_ERROR **ppEapError) -{ - UNREFERENCED_PARAMETER(reason); - UNREFERENCED_PARAMETER(ppResult); - assert(ppEapError); - - *ppEapError = m_module.make_error(ERROR_NOT_SUPPORTED, _T(__FUNCTION__) _T(" Not supported.")); - return false; -}