From afe5450b95fcfca57633fcb27c25772d42f7159c Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Sat, 6 Aug 2016 07:57:39 +0200 Subject: [PATCH] Peer (Main.cpp) no longer manipulates session directly. Session management moved to eap::peer. --- EAPMethods/src/Main.cpp | 259 ++++++++++++++++------------------- lib/EAPBase/include/Module.h | 152 ++++++++++++++++++++ lib/TTLS/include/Module.h | 149 ++++++++++++++++++++ lib/TTLS/src/Module.cpp | 117 ++++++++++++++++ 4 files changed, 537 insertions(+), 140 deletions(-) diff --git a/EAPMethods/src/Main.cpp b/EAPMethods/src/Main.cpp index 644a9d4..a6e85a9 100644 --- a/EAPMethods/src/Main.cpp +++ b/EAPMethods/src/Main.cpp @@ -27,7 +27,6 @@ using namespace winstd; #if EAPMETHOD_TYPE==21 #define _EAPMETHOD_PEER eap::peer_ttls -#define _EAPMETHOD_SESSION eap::session_ttls #else #error Unknown EAP Method type. #endif @@ -283,29 +282,12 @@ DWORD APIENTRY EapPeerBeginSession( g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_INVALID_PARAMETER, _T(__FUNCTION__) _T(" pUserData is NULL."))); else if (!phSession) g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_INVALID_PARAMETER, _T(__FUNCTION__) _T(" phSession is NULL."))); - else { - *phSession = NULL; - - // Allocate new session. - unique_ptr<_EAPMETHOD_SESSION> session(new _EAPMETHOD_SESSION(g_peer)); - if (!session) { - g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_OUTOFMEMORY, _T(__FUNCTION__) _T(" Error allocating memory for EAP session."))); - return dwResult; - } - - // Begin the session. - if (!g_peer.unpack(session->m_cfg, pConnectionData, dwConnectionDataSize, ppEapError) || - !g_peer.unpack(session->m_cred, pUserData, dwUserDataSize, ppEapError) || - !session->begin(dwFlags, pAttributeArray, hTokenImpersonateUser, dwMaxSendPacketSize, ppEapError)) - { - if (*ppEapError) { - g_peer.log_error(*ppEapError); - return dwResult = (*ppEapError)->dwWinError; - } else - return dwResult = ERROR_INVALID_DATA; - } - - *phSession = session.release(); + else if (!g_peer.begin_session(dwFlags, pAttributeArray, hTokenImpersonateUser, pConnectionData, dwConnectionDataSize, pUserData, dwUserDataSize, dwMaxSendPacketSize, phSession, ppEapError)) { + if (*ppEapError) { + g_peer.log_error(*ppEapError); + return dwResult = (*ppEapError)->dwWinError; + } else + return dwResult = ERROR_INVALID_DATA; } return dwResult; @@ -317,7 +299,9 @@ DWORD APIENTRY EapPeerBeginSession( /// /// \sa [EapPeerEndSession function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363604.aspx) /// -DWORD APIENTRY EapPeerEndSession(_In_ EAP_SESSION_HANDLE hSession, _Out_ EAP_ERROR **ppEapError) +DWORD APIENTRY EapPeerEndSession( + _In_ EAP_SESSION_HANDLE hSession, + _Out_ EAP_ERROR **ppEapError) { DWORD dwResult = ERROR_SUCCESS; event_fn_auto_ret event_auto(g_peer.get_event_fn_auto(__FUNCTION__, dwResult)); @@ -333,9 +317,12 @@ DWORD APIENTRY EapPeerEndSession(_In_ EAP_SESSION_HANDLE hSession, _Out_ EAP_ERR if (!hSession) g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_INVALID_PARAMETER, _T(__FUNCTION__) _T(" hSession is NULL."))); - else { - static_cast<_EAPMETHOD_SESSION*>(hSession)->end(ppEapError); - delete static_cast<_EAPMETHOD_SESSION*>(hSession); + else if (!g_peer.end_session(hSession, ppEapError)) { + if (*ppEapError) { + g_peer.log_error(*ppEapError); + return dwResult = (*ppEapError)->dwWinError; + } else + return dwResult = ERROR_INVALID_DATA; } return dwResult; @@ -372,15 +359,12 @@ DWORD APIENTRY EapPeerProcessRequestPacket( g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_INVALID_PARAMETER, _T(__FUNCTION__) _T(" pReceivedPacket is NULL or too short."))); else if (!pEapOutput) g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_INVALID_PARAMETER, _T(__FUNCTION__) _T(" pEapOutput is NULL."))); - else { - assert(dwReceivedPacketSize == ntohs(*(WORD*)pReceivedPacket->Length)); - if (!static_cast<_EAPMETHOD_SESSION*>(hSession)->process_request_packet(dwReceivedPacketSize, pReceivedPacket, pEapOutput, ppEapError)) { - if (*ppEapError) { - g_peer.log_error(*ppEapError); - dwResult = (*ppEapError)->dwWinError; - } else - dwResult = ERROR_INVALID_DATA; - } + else if (!g_peer.process_request_packet(hSession, pReceivedPacket, dwReceivedPacketSize, pEapOutput, ppEapError)) { + if (*ppEapError) { + g_peer.log_error(*ppEapError); + dwResult = (*ppEapError)->dwWinError; + } else + dwResult = ERROR_INVALID_DATA; } return dwResult; @@ -416,14 +400,12 @@ DWORD APIENTRY EapPeerGetResponsePacket( g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_INVALID_PARAMETER, _T(__FUNCTION__) _T(" pdwSendPacketSize is NULL."))); else if (!pSendPacket && *pdwSendPacketSize) g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_INVALID_PARAMETER, _T(__FUNCTION__) _T(" pSendPacket is NULL."))); - else { - if (!static_cast<_EAPMETHOD_SESSION*>(hSession)->get_response_packet(pdwSendPacketSize, pSendPacket, ppEapError)) { - if (*ppEapError) { - g_peer.log_error(*ppEapError); - dwResult = (*ppEapError)->dwWinError; - } else - dwResult = ERROR_INVALID_DATA; - } + else if (!g_peer.get_response_packet(hSession, pSendPacket, pdwSendPacketSize, ppEapError)) { + if (*ppEapError) { + g_peer.log_error(*ppEapError); + dwResult = (*ppEapError)->dwWinError; + } else + dwResult = ERROR_INVALID_DATA; } return dwResult; @@ -435,7 +417,11 @@ DWORD APIENTRY EapPeerGetResponsePacket( /// /// \sa [EapPeerGetResult function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363611.aspx) /// -DWORD APIENTRY EapPeerGetResult(_In_ EAP_SESSION_HANDLE hSession, _In_ EapPeerMethodResultReason reason, _Out_ EapPeerMethodResult *ppResult, _Out_ EAP_ERROR **ppEapError) +DWORD APIENTRY EapPeerGetResult( + _In_ EAP_SESSION_HANDLE hSession, + _In_ EapPeerMethodResultReason reason, + _Out_ EapPeerMethodResult *ppResult, + _Out_ EAP_ERROR **ppEapError) { DWORD dwResult = ERROR_SUCCESS; event_fn_auto_ret event_auto(g_peer.get_event_fn_auto(__FUNCTION__, dwResult)); @@ -453,14 +439,12 @@ DWORD APIENTRY EapPeerGetResult(_In_ EAP_SESSION_HANDLE hSession, _In_ EapPeerMe g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_INVALID_PARAMETER, _T(__FUNCTION__) _T(" hSession is NULL."))); else if (!ppResult) g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_INVALID_PARAMETER, _T(__FUNCTION__) _T(" ppResult is NULL."))); - else { - if (!static_cast<_EAPMETHOD_SESSION*>(hSession)->get_result(reason, ppResult, ppEapError)) { - if (*ppEapError) { - g_peer.log_error(*ppEapError); - dwResult = (*ppEapError)->dwWinError; - } else - dwResult = ERROR_INVALID_DATA; - } + else if (!g_peer.get_result(hSession, reason, ppResult, ppEapError)) { + if (*ppEapError) { + g_peer.log_error(*ppEapError); + dwResult = (*ppEapError)->dwWinError; + } else + dwResult = ERROR_INVALID_DATA; } return dwResult; @@ -498,7 +482,7 @@ DWORD APIENTRY EapPeerGetUIContext( g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_INVALID_PARAMETER, _T(__FUNCTION__) _T(" pdwUIContextDataSize is NULL."))); else if (!ppUIContextData) g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_INVALID_PARAMETER, _T(__FUNCTION__) _T(" ppUIContextData is NULL."))); - else if (!static_cast<_EAPMETHOD_SESSION*>(hSession)->get_ui_context(ppUIContextData, pdwUIContextDataSize, ppEapError)) { + else if (!g_peer.get_ui_context(hSession, ppUIContextData, pdwUIContextDataSize, ppEapError)) { if (*ppEapError) { g_peer.log_error(*ppEapError); dwResult = (*ppEapError)->dwWinError; @@ -542,7 +526,7 @@ DWORD APIENTRY EapPeerSetUIContext( g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_INVALID_PARAMETER, _T(__FUNCTION__) _T(" pUIContextData is NULL."))); else if (!pEapOutput) g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_INVALID_PARAMETER, _T(__FUNCTION__) _T(" pEapOutput is NULL."))); - else if (!static_cast<_EAPMETHOD_SESSION*>(hSession)->set_ui_context(pUIContextData, dwUIContextDataSize, pEapOutput, ppEapError)) { + else if (!g_peer.set_ui_context(hSession, pUIContextData, dwUIContextDataSize, pEapOutput, ppEapError)) { if (*ppEapError) { g_peer.log_error(*ppEapError); dwResult = (*ppEapError)->dwWinError; @@ -559,7 +543,10 @@ DWORD APIENTRY EapPeerSetUIContext( /// /// \sa [EapPeerGetResponseAttributes function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363609.aspx) /// -DWORD APIENTRY EapPeerGetResponseAttributes(_In_ EAP_SESSION_HANDLE hSession, _Out_ EapAttributes *pAttribs, _Out_ EAP_ERROR **ppEapError) +DWORD APIENTRY EapPeerGetResponseAttributes( + _In_ EAP_SESSION_HANDLE hSession, + _Out_ EapAttributes *pAttribs, + _Out_ EAP_ERROR **ppEapError) { DWORD dwResult = ERROR_SUCCESS; event_fn_auto_ret event_auto(g_peer.get_event_fn_auto(__FUNCTION__, dwResult)); @@ -577,14 +564,12 @@ DWORD APIENTRY EapPeerGetResponseAttributes(_In_ EAP_SESSION_HANDLE hSession, _O g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_INVALID_PARAMETER, _T(__FUNCTION__) _T(" hSession is NULL."))); else if (!pAttribs) g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_INVALID_PARAMETER, _T(__FUNCTION__) _T(" pAttribs is NULL."))); - else { - if (!static_cast<_EAPMETHOD_SESSION*>(hSession)->get_response_attributes(pAttribs, ppEapError)) { - if (*ppEapError) { - g_peer.log_error(*ppEapError); - dwResult = (*ppEapError)->dwWinError; - } else - dwResult = ERROR_INVALID_DATA; - } + else if (!g_peer.get_response_attributes(hSession, pAttribs, ppEapError)) { + if (*ppEapError) { + g_peer.log_error(*ppEapError); + dwResult = (*ppEapError)->dwWinError; + } else + dwResult = ERROR_INVALID_DATA; } return dwResult; @@ -596,7 +581,11 @@ DWORD APIENTRY EapPeerGetResponseAttributes(_In_ EAP_SESSION_HANDLE hSession, _O /// /// \sa [EapPeerSetResponseAttributes function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363625.aspx) /// -DWORD APIENTRY EapPeerSetResponseAttributes(_In_ EAP_SESSION_HANDLE hSession, _In_ /*const*/ EapAttributes *pAttribs, _Out_ EapPeerMethodOutput *pEapOutput, _Out_ EAP_ERROR **ppEapError) +DWORD APIENTRY EapPeerSetResponseAttributes( + _In_ EAP_SESSION_HANDLE hSession, + _In_ /*const*/ EapAttributes *pAttribs, + _Out_ EapPeerMethodOutput *pEapOutput, + _Out_ EAP_ERROR **ppEapError) { DWORD dwResult = ERROR_SUCCESS; event_fn_auto_ret event_auto(g_peer.get_event_fn_auto(__FUNCTION__, dwResult)); @@ -614,14 +603,12 @@ DWORD APIENTRY EapPeerSetResponseAttributes(_In_ EAP_SESSION_HANDLE hSession, _I g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_INVALID_PARAMETER, _T(__FUNCTION__) _T(" hSession is NULL."))); else if (!pEapOutput) g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_INVALID_PARAMETER, _T(__FUNCTION__) _T(" pEapOutput is NULL."))); - else { - if (!static_cast<_EAPMETHOD_SESSION*>(hSession)->set_response_attributes(pAttribs, pEapOutput, ppEapError)) { - if (*ppEapError) { - g_peer.log_error(*ppEapError); - dwResult = (*ppEapError)->dwWinError; - } else - dwResult = ERROR_INVALID_DATA; - } + else if (!g_peer.set_response_attributes(hSession, pAttribs, pEapOutput, ppEapError)) { + if (*ppEapError) { + g_peer.log_error(*ppEapError); + dwResult = (*ppEapError)->dwWinError; + } else + dwResult = ERROR_INVALID_DATA; } return dwResult; @@ -775,21 +762,19 @@ DWORD WINAPI EapPeerQueryCredentialInputFields( g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_INVALID_PARAMETER, _T(__FUNCTION__) _T(" pConnectionData is NULL."))); else if (!pEapConfigInputFieldsArray) g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_INVALID_PARAMETER, _T(__FUNCTION__) _T(" pEapConfigInputFieldsArray is NULL."))); - else { - if (!g_peer.query_credential_input_fields( - hUserImpersonationToken, - dwFlags, - dwConnectionDataSize, - pConnectionData, - pEapConfigInputFieldsArray, - ppEapError)) - { - if (*ppEapError) { - g_peer.log_error(*ppEapError); - dwResult = (*ppEapError)->dwWinError; - } else - dwResult = ERROR_INVALID_DATA; - } + else if (!g_peer.query_credential_input_fields( + hUserImpersonationToken, + dwFlags, + dwConnectionDataSize, + pConnectionData, + pEapConfigInputFieldsArray, + ppEapError)) + { + if (*ppEapError) { + g_peer.log_error(*ppEapError); + dwResult = (*ppEapError)->dwWinError; + } else + dwResult = ERROR_INVALID_DATA; } return dwResult; @@ -836,23 +821,21 @@ DWORD WINAPI EapPeerQueryUserBlobFromCredentialInputFields( g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_INVALID_PARAMETER, _T(__FUNCTION__) _T(" pdwUsersBlobSize is NULL."))); else if (!ppUserBlob) g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_INVALID_PARAMETER, _T(__FUNCTION__) _T(" ppUserBlob is NULL."))); - else { - if (!g_peer.query_user_blob_from_credential_input_fields( - hUserImpersonationToken, - dwFlags, - dwConnectionDataSize, - pConnectionData, - pEapConfigInputFieldArray, - pdwUsersBlobSize, - ppUserBlob, - ppEapError)) - { - if (*ppEapError) { - g_peer.log_error(*ppEapError); - dwResult = (*ppEapError)->dwWinError; - } else - dwResult = ERROR_INVALID_DATA; - } + else if (!g_peer.query_user_blob_from_credential_input_fields( + hUserImpersonationToken, + dwFlags, + dwConnectionDataSize, + pConnectionData, + pEapConfigInputFieldArray, + pdwUsersBlobSize, + ppUserBlob, + ppEapError)) + { + if (*ppEapError) { + g_peer.log_error(*ppEapError); + dwResult = (*ppEapError)->dwWinError; + } else + dwResult = ERROR_INVALID_DATA; } return dwResult; @@ -891,22 +874,20 @@ DWORD WINAPI EapPeerQueryInteractiveUIInputFields( g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_INVALID_PARAMETER, _T(__FUNCTION__) _T(" pUIContextData is NULL."))); else if (!pEapInteractiveUIData) g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_INVALID_PARAMETER, _T(__FUNCTION__) _T(" pEapInteractiveUIData is NULL."))); - else { - if (!g_peer.query_interactive_ui_input_fields( - dwVersion, - dwFlags, - dwUIContextDataSize, - pUIContextData, - pEapInteractiveUIData, - ppEapError, - pvReserved)) - { - if (*ppEapError) { - g_peer.log_error(*ppEapError); - dwResult = (*ppEapError)->dwWinError; - } else - dwResult = ERROR_INVALID_DATA; - } + else if (!g_peer.query_interactive_ui_input_fields( + dwVersion, + dwFlags, + dwUIContextDataSize, + pUIContextData, + pEapInteractiveUIData, + ppEapError, + pvReserved)) + { + if (*ppEapError) { + g_peer.log_error(*ppEapError); + dwResult = (*ppEapError)->dwWinError; + } else + dwResult = ERROR_INVALID_DATA; } return dwResult; @@ -949,24 +930,22 @@ DWORD WINAPI EapPeerQueryUIBlobFromInteractiveUIInputFields( g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_INVALID_PARAMETER, _T(__FUNCTION__) _T(" pdwDataFromInteractiveUISize is NULL."))); else if (!ppDataFromInteractiveUI) g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_INVALID_PARAMETER, _T(__FUNCTION__) _T(" ppDataFromInteractiveUI is NULL."))); - else { - if (!g_peer.query_ui_blob_from_interactive_ui_input_fields( - dwVersion, - dwFlags, - dwUIContextDataSize, - pUIContextData, - pEapInteractiveUIData, - pdwDataFromInteractiveUISize, - ppDataFromInteractiveUI, - ppEapError, - ppvReserved)) - { - if (*ppEapError) { - g_peer.log_error(*ppEapError); - dwResult = (*ppEapError)->dwWinError; - } else - dwResult = ERROR_INVALID_DATA; - } + else if (!g_peer.query_ui_blob_from_interactive_ui_input_fields( + dwVersion, + dwFlags, + dwUIContextDataSize, + pUIContextData, + pEapInteractiveUIData, + pdwDataFromInteractiveUISize, + ppDataFromInteractiveUI, + ppEapError, + ppvReserved)) + { + if (*ppEapError) { + g_peer.log_error(*ppEapError); + dwResult = (*ppEapError)->dwWinError; + } else + dwResult = ERROR_INVALID_DATA; } return dwResult; diff --git a/lib/EAPBase/include/Module.h b/lib/EAPBase/include/Module.h index b749730..243a570 100644 --- a/lib/EAPBase/include/Module.h +++ b/lib/EAPBase/include/Module.h @@ -45,6 +45,9 @@ namespace eap #include #include // Must include after +extern "C" { +#include +} #include #include @@ -817,5 +820,154 @@ namespace eap _Out_ BYTE **ppDataFromInteractiveUI, _Out_ EAP_ERROR **ppEapError, _Inout_ LPVOID *ppvReserved) const; + + /// \name Session management + /// @{ + + /// + /// 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_session( + _In_ DWORD dwFlags, + _In_ const EapAttributes *pAttributeArray, + _In_ HANDLE hTokenImpersonateUser, + _In_count_(dwConnectionDataSize) const BYTE *pConnectionData, + _In_ DWORD dwConnectionDataSize, + _In_count_(dwUserDataSize) const BYTE *pUserData, + _In_ DWORD dwUserDataSize, + _In_ DWORD dwMaxSendPacketSize, + _Out_ EAP_SESSION_HANDLE *phSession, + _Out_ EAP_ERROR **ppEapError) = 0; + + /// + /// Ends an EAP authentication session for the EAP method. + /// + /// \sa [EapPeerEndSession function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363604.aspx) + /// + /// \returns + /// - \c true if succeeded + /// - \c false otherwise. See \p ppEapError for details. + /// + virtual bool end_session( + _In_ EAP_SESSION_HANDLE hSession, + _Out_ EAP_ERROR **ppEapError) = 0; + + /// + /// 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_ EAP_SESSION_HANDLE hSession, + _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( + _In_ EAP_SESSION_HANDLE hSession, + _Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket, + _Inout_ DWORD *pdwSendPacketSize, + _Out_ EAP_ERROR **ppEapError) = 0; + + /// + /// 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_ EAP_SESSION_HANDLE hSession, + _In_ EapPeerMethodResultReason reason, + _Out_ EapPeerMethodResult *ppResult, + _Out_ EAP_ERROR **ppEapError) = 0; + + /// + /// Obtains the user interface context from the EAP method. + /// + /// \note This function is always followed by the `EapPeerInvokeInteractiveUI()` function, which is followed by the `EapPeerSetUIContext()` function. + /// + /// \sa [EapPeerGetUIContext function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363612.aspx) + /// + /// \returns + /// - \c true if succeeded + /// - \c false otherwise. See \p ppEapError for details. + /// + virtual bool get_ui_context( + _In_ EAP_SESSION_HANDLE hSession, + _Out_ BYTE **ppUIContextData, + _Out_ DWORD *pdwUIContextDataSize, + _Out_ EAP_ERROR **ppEapError) = 0; + + /// + /// Provides a user interface context to the EAP method. + /// + /// \note This function is called after the UI has been raised through the `EapPeerGetUIContext()` function. + /// + /// \sa [EapPeerSetUIContext function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363626.aspx) + /// + /// \returns + /// - \c true if succeeded + /// - \c false otherwise. See \p ppEapError for details. + /// + virtual bool set_ui_context( + _In_ EAP_SESSION_HANDLE hSession, + _In_count_(dwUIContextDataSize) const BYTE *pUIContextData, + _In_ DWORD dwUIContextDataSize, + _In_ const EapPeerMethodOutput *pEapOutput, + _Out_ EAP_ERROR **ppEapError) = 0; + + /// + /// Obtains an array of EAP response attributes from the EAP method. + /// + /// \sa [EapPeerGetResponseAttributes function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363609.aspx) + /// + /// \returns + /// - \c true if succeeded + /// - \c false otherwise. See \p ppEapError for details. + /// + virtual bool get_response_attributes( + _In_ EAP_SESSION_HANDLE hSession, + _Out_ EapAttributes *pAttribs, + _Out_ EAP_ERROR **ppEapError) = 0; + + /// + /// Provides an updated array of EAP response attributes to the EAP method. + /// + /// \sa [EapPeerSetResponseAttributes function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363625.aspx) + /// + /// \returns + /// - \c true if succeeded + /// - \c false otherwise. See \p ppEapError for details. + /// + virtual bool set_response_attributes( + _In_ EAP_SESSION_HANDLE hSession, + _In_ const EapAttributes *pAttribs, + _Out_ EapPeerMethodOutput *pEapOutput, + _Out_ EAP_ERROR **ppEapError) = 0; + + /// @} }; } diff --git a/lib/TTLS/include/Module.h b/lib/TTLS/include/Module.h index ab241ad..0dbde9e 100644 --- a/lib/TTLS/include/Module.h +++ b/lib/TTLS/include/Module.h @@ -129,5 +129,154 @@ namespace eap _Out_ BYTE **ppCredentialsOut, _Out_ DWORD *pdwCredentialsOutSize, _Out_ EAP_ERROR **ppEapError); + + /// \name Session management + /// @{ + + /// + /// 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_session( + _In_ DWORD dwFlags, + _In_ const EapAttributes *pAttributeArray, + _In_ HANDLE hTokenImpersonateUser, + _In_count_(dwConnectionDataSize) const BYTE *pConnectionData, + _In_ DWORD dwConnectionDataSize, + _In_count_(dwUserDataSize) const BYTE *pUserData, + _In_ DWORD dwUserDataSize, + _In_ DWORD dwMaxSendPacketSize, + _Out_ EAP_SESSION_HANDLE *phSession, + _Out_ EAP_ERROR **ppEapError); + + /// + /// Ends an EAP authentication session for the EAP method. + /// + /// \sa [EapPeerEndSession function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363604.aspx) + /// + /// \returns + /// - \c true if succeeded + /// - \c false otherwise. See \p ppEapError for details. + /// + virtual bool end_session( + _In_ EAP_SESSION_HANDLE hSession, + _Out_ EAP_ERROR **ppEapError); + + /// + /// 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_ EAP_SESSION_HANDLE hSession, + _In_bytecount_(dwReceivedPacketSize) const EapPacket *pReceivedPacket, + _In_ DWORD dwReceivedPacketSize, + _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( + _In_ EAP_SESSION_HANDLE hSession, + _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_ EAP_SESSION_HANDLE hSession, + _In_ EapPeerMethodResultReason reason, + _Out_ EapPeerMethodResult *ppResult, + _Out_ EAP_ERROR **ppEapError); + + /// + /// Obtains the user interface context from the EAP method. + /// + /// \note This function is always followed by the `EapPeerInvokeInteractiveUI()` function, which is followed by the `EapPeerSetUIContext()` function. + /// + /// \sa [EapPeerGetUIContext function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363612.aspx) + /// + /// \returns + /// - \c true if succeeded + /// - \c false otherwise. See \p ppEapError for details. + /// + virtual bool get_ui_context( + _In_ EAP_SESSION_HANDLE hSession, + _Out_ BYTE **ppUIContextData, + _Out_ DWORD *pdwUIContextDataSize, + _Out_ EAP_ERROR **ppEapError); + + /// + /// Provides a user interface context to the EAP method. + /// + /// \note This function is called after the UI has been raised through the `EapPeerGetUIContext()` function. + /// + /// \sa [EapPeerSetUIContext function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363626.aspx) + /// + /// \returns + /// - \c true if succeeded + /// - \c false otherwise. See \p ppEapError for details. + /// + virtual bool set_ui_context( + _In_ EAP_SESSION_HANDLE hSession, + _In_count_(dwUIContextDataSize) const BYTE *pUIContextData, + _In_ DWORD dwUIContextDataSize, + _In_ const EapPeerMethodOutput *pEapOutput, + _Out_ EAP_ERROR **ppEapError); + + /// + /// Obtains an array of EAP response attributes from the EAP method. + /// + /// \sa [EapPeerGetResponseAttributes function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363609.aspx) + /// + /// \returns + /// - \c true if succeeded + /// - \c false otherwise. See \p ppEapError for details. + /// + virtual bool get_response_attributes( + _In_ EAP_SESSION_HANDLE hSession, + _Out_ EapAttributes *pAttribs, + _Out_ EAP_ERROR **ppEapError); + + /// + /// Provides an updated array of EAP response attributes to the EAP method. + /// + /// \sa [EapPeerSetResponseAttributes function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363625.aspx) + /// + /// \returns + /// - \c true if succeeded + /// - \c false otherwise. See \p ppEapError for details. + /// + virtual bool set_response_attributes( + _In_ EAP_SESSION_HANDLE hSession, + _In_ const EapAttributes *pAttribs, + _Out_ EapPeerMethodOutput *pEapOutput, + _Out_ EAP_ERROR **ppEapError); + + /// @} }; } diff --git a/lib/TTLS/src/Module.cpp b/lib/TTLS/src/Module.cpp index bafad72..1b5d78c 100644 --- a/lib/TTLS/src/Module.cpp +++ b/lib/TTLS/src/Module.cpp @@ -309,3 +309,120 @@ bool eap::peer_ttls::credentials_xml2blob( // Pack credentials. return pack(cred, ppCredentialsOut, pdwCredentialsOutSize, ppEapError); } + + +bool eap::peer_ttls::begin_session( + _In_ DWORD dwFlags, + _In_ const EapAttributes *pAttributeArray, + _In_ HANDLE hTokenImpersonateUser, + _In_count_(dwConnectionDataSize) const BYTE *pConnectionData, + _In_ DWORD dwConnectionDataSize, + _In_count_(dwUserDataSize) const BYTE *pUserData, + _In_ DWORD dwUserDataSize, + _In_ DWORD dwMaxSendPacketSize, + _Out_ EAP_SESSION_HANDLE *phSession, + _Out_ EAP_ERROR **ppEapError) +{ + *phSession = NULL; + + // Allocate new session. + unique_ptr session(new session_ttls(*this)); + if (!session) { + log_error(*ppEapError = make_error(ERROR_OUTOFMEMORY, _T(__FUNCTION__) _T(" Error allocating memory for EAP-TTLS session."))); + return false; + } + + // Begin the session. + if (!unpack(session->m_cfg, pConnectionData, dwConnectionDataSize, ppEapError) || + !unpack(session->m_cred, pUserData, dwUserDataSize, ppEapError) || + !session->begin(dwFlags, pAttributeArray, hTokenImpersonateUser, dwMaxSendPacketSize, ppEapError)) + return false; + + *phSession = session.release(); + return true; +} + + +bool eap::peer_ttls::end_session(_In_ EAP_SESSION_HANDLE hSession, _Out_ EAP_ERROR **ppEapError) +{ + assert(hSession); + + // End the session. + session_ttls *session = static_cast(hSession); + session->end(ppEapError); + delete session; + + return true; +} + + +bool eap::peer_ttls::process_request_packet( + _In_ EAP_SESSION_HANDLE hSession, + _In_bytecount_(dwReceivedPacketSize) const EapPacket *pReceivedPacket, + _In_ DWORD dwReceivedPacketSize, + _Out_ EapPeerMethodOutput *pEapOutput, + _Out_ EAP_ERROR **ppEapError) +{ + assert(dwReceivedPacketSize == ntohs(*(WORD*)pReceivedPacket->Length)); + return static_cast(hSession)->process_request_packet(dwReceivedPacketSize, pReceivedPacket, pEapOutput, ppEapError); +} + + +bool eap::peer_ttls::get_response_packet( + _In_ EAP_SESSION_HANDLE hSession, + _Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket, + _Inout_ DWORD *pdwSendPacketSize, + _Out_ EAP_ERROR **ppEapError) +{ + return static_cast(hSession)->get_response_packet(pdwSendPacketSize, pSendPacket, ppEapError); +} + + +bool eap::peer_ttls::get_result( + _In_ EAP_SESSION_HANDLE hSession, + _In_ EapPeerMethodResultReason reason, + _Out_ EapPeerMethodResult *ppResult, + _Out_ EAP_ERROR **ppEapError) +{ + return static_cast(hSession)->get_result(reason, ppResult, ppEapError); +} + + +bool eap::peer_ttls::get_ui_context( + _In_ EAP_SESSION_HANDLE hSession, + _Out_ BYTE **ppUIContextData, + _Out_ DWORD *pdwUIContextDataSize, + _Out_ EAP_ERROR **ppEapError) +{ + return static_cast(hSession)->get_ui_context(ppUIContextData, pdwUIContextDataSize, ppEapError); +} + + +bool eap::peer_ttls::set_ui_context( + _In_ EAP_SESSION_HANDLE hSession, + _In_count_(dwUIContextDataSize) const BYTE *pUIContextData, + _In_ DWORD dwUIContextDataSize, + _In_ const EapPeerMethodOutput *pEapOutput, + _Out_ EAP_ERROR **ppEapError) +{ + return static_cast(hSession)->set_ui_context(pUIContextData, dwUIContextDataSize, pEapOutput, ppEapError); +} + + +bool eap::peer_ttls::get_response_attributes( + _In_ EAP_SESSION_HANDLE hSession, + _Out_ EapAttributes *pAttribs, + _Out_ EAP_ERROR **ppEapError) +{ + return static_cast(hSession)->get_response_attributes(pAttribs, ppEapError); +} + + +bool eap::peer_ttls::set_response_attributes( + _In_ EAP_SESSION_HANDLE hSession, + _In_ const EapAttributes *pAttribs, + _Out_ EapPeerMethodOutput *pEapOutput, + _Out_ EAP_ERROR **ppEapError) +{ + return static_cast(hSession)->set_response_attributes(pAttribs, pEapOutput, ppEapError); +}