GEANTLink/lib/EapHost/src/Method.cpp
Simon Rozman b55ddd7d86 Update Copyright and build year
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-11-22 15:31:23 +01:00

256 lines
8.9 KiB
C++

/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
Copyright © 2016 GÉANT
*/
#include "PCH.h"
using namespace std;
using namespace winstd;
//////////////////////////////////////////////////////////////////////
// eap::method_eaphost
//////////////////////////////////////////////////////////////////////
eap::method_eaphost::method_eaphost(_In_ module &mod, _In_ config_method_eaphost &cfg, _In_ credentials_eaphost &cred) :
m_cfg(cfg),
m_cred(cred),
m_session_id(0),
method(mod)
{
}
void eap::method_eaphost::begin_session(
_In_ DWORD dwFlags,
_In_ const EapAttributes *pAttributeArray,
_In_ HANDLE hTokenImpersonateUser,
_In_opt_ DWORD dwMaxSendPacketSize)
{
method::begin_session(dwFlags, pAttributeArray, hTokenImpersonateUser, dwMaxSendPacketSize);
// Presume authentication will fail with generic protocol failure. (Pesimist!!!)
// We will reset once we get get_result(Success) call.
m_cfg.m_last_status = config_method::status_t::auth_failed;
m_cfg.m_last_msg.clear();
// Create EapHost peer session using available connection data (m_cfg) and user data (m_cred).
eap_error_runtime error;
DWORD dwResult = EapHostPeerBeginSession(
dwFlags,
m_cfg.get_type(),
pAttributeArray,
hTokenImpersonateUser,
(DWORD)m_cfg.m_cfg_blob.size(),
m_cfg.m_cfg_blob.data(),
(DWORD)m_cred.m_cred_blob.size(),
m_cred.m_cred_blob.data(),
dwMaxSendPacketSize,
NULL, NULL, NULL,
&m_session_id,
get_ptr(error));
if (dwResult == ERROR_SUCCESS) {
// Session succesfully created.
} else if (error)
throw eap_runtime_error(*error , __FUNCTION__ " EapHostPeerBeginSession failed.");
else
throw win_runtime_error(dwResult, __FUNCTION__ " EapHostPeerBeginSession failed.");
}
void eap::method_eaphost::end_session()
{
// End EapHost peer session.
eap_error_runtime error;
DWORD dwResult = EapHostPeerEndSession(m_session_id, get_ptr(error));
if (dwResult == ERROR_SUCCESS) {
// Session successfuly ended.
} else if (error)
throw eap_runtime_error(*error , __FUNCTION__ " EapHostPeerEndSession failed.");
else
throw win_runtime_error(dwResult, __FUNCTION__ " EapHostPeerEndSession failed.");
method::end_session();
}
EapPeerMethodResponseAction eap::method_eaphost::process_request_packet(
_In_bytecount_(dwReceivedPacketSize) const void *pReceivedPacket,
_In_ DWORD dwReceivedPacketSize)
{
assert(pReceivedPacket || dwReceivedPacketSize == 0);
// Let EapHost peer process the packet.
EapHostPeerResponseAction action;
eap_error_runtime error;
DWORD dwResult = EapHostPeerProcessReceivedPacket(
m_session_id,
dwReceivedPacketSize,
reinterpret_cast<const BYTE*>(pReceivedPacket),
&action,
get_ptr(error));
if (dwResult == ERROR_SUCCESS) {
// Packet successfuly processed.
return action_h2p(action);
} else if (error)
throw eap_runtime_error(*error , __FUNCTION__ " EapHostPeerProcessReceivedPacket failed.");
else
throw win_runtime_error(dwResult, __FUNCTION__ " EapHostPeerProcessReceivedPacket failed.");
}
void eap::method_eaphost::get_response_packet(
_Out_ sanitizing_blob &packet,
_In_opt_ DWORD size_max)
{
// Let EapHost peer prepare response packet.
LPBYTE _packet;
eap_error_runtime error;
DWORD dwResult = EapHostPeerGetSendPacket(
m_session_id,
&size_max,
&_packet,
get_ptr(error));
if (dwResult == ERROR_SUCCESS) {
// Packet successfuly prepared.
packet.assign(_packet, _packet + size_max);
} else if (error)
throw eap_runtime_error(*error , __FUNCTION__ " EapHostPeerGetSendPacket failed.");
else
throw win_runtime_error(dwResult, __FUNCTION__ " EapHostPeerGetSendPacket failed.");
}
void eap::method_eaphost::get_result(
_In_ EapPeerMethodResultReason reason,
_Inout_ EapPeerMethodResult *pResult)
{
// Let EapHost peer return result.
eap_error_runtime error;
EapHostPeerMethodResult result = {};
DWORD dwResult = EapHostPeerGetResult(
m_session_id,
EapHostPeerMethodResultFromMethod,
&result,
get_ptr(error));
if (dwResult == ERROR_SUCCESS) {
// Result successfuly returned.
method::get_result(reason, pResult);
pResult->dwFailureReasonCode = result.dwFailureReasonCode;
pResult->pAttribArray = result.pAttribArray;
if (result.pEapError) {
// Transfer error to our module memory space.
pResult->pEapError = m_module.make_error(result.pEapError);
EapHostPeerFreeEapError(result.pEapError);
result.pEapError = NULL;
}
if (result.fSaveConnectionData) {
// Update configuration BLOB.
m_cfg.m_cfg_blob.assign(result.pConnectionData, result.pConnectionData + result.dwSizeofConnectionData);
}
if (result.fSaveUserData) {
// Update credentials BLOB.
m_cred.m_cred_blob.assign(result.pUserData, result.pUserData + result.dwSizeofUserData);
}
if (reason == EapPeerMethodResultSuccess)
m_cfg.m_last_status = config_method::status_t::success;
// Ask EAP host to save the configuration (connection data).
pResult->fSaveConnectionData = TRUE;
} else if (error)
throw eap_runtime_error(*error , __FUNCTION__ " EapHostPeerGetResult failed.");
else
throw win_runtime_error(dwResult, __FUNCTION__ " EapHostPeerGetResult failed.");
}
void eap::method_eaphost::get_ui_context(_Out_ sanitizing_blob &context_data)
{
// Get EapHost peer UI context data.
DWORD dwUIContextDataSize;
LPBYTE pUIContextData;
eap_error_runtime error;
DWORD dwResult = EapHostPeerGetUIContext(
m_session_id,
&dwUIContextDataSize,
&pUIContextData,
get_ptr(error));
if (dwResult == ERROR_SUCCESS) {
// UI context data successfuly returned.
context_data.assign(pUIContextData, pUIContextData + dwUIContextDataSize);
// TODO: Test if EapHostPeerGetUIContext() requires us to free the buffer.
//EapHostPeerFreeMemory(pUIContextData);
} else if (error)
throw eap_runtime_error(*error , __FUNCTION__ " EapHostPeerGetUIContext failed.");
else
throw win_runtime_error(dwResult, __FUNCTION__ " EapHostPeerGetUIContext failed.");
}
EapPeerMethodResponseAction eap::method_eaphost::set_ui_context(
_In_count_(dwUIContextDataSize) const BYTE *pUIContextData,
_In_ DWORD dwUIContextDataSize)
{
// Set EapHost peer UI context data.
EapHostPeerResponseAction action;
eap_error_runtime error;
DWORD dwResult = EapHostPeerSetUIContext(
m_session_id,
dwUIContextDataSize,
pUIContextData,
&action,
get_ptr(error));
if (dwResult == ERROR_SUCCESS) {
// UI context data successfuly returned.
return action_h2p(action);
} else if (error)
throw eap_runtime_error(*error , __FUNCTION__ " EapHostPeerSetUIContext failed.");
else
throw win_runtime_error(dwResult, __FUNCTION__ " EapHostPeerSetUIContext failed.");
}
void eap::method_eaphost::get_response_attributes(_Out_ EapAttributes *pAttribs)
{
// Get response attributes from EapHost peer.
eap_error_runtime error;
DWORD dwResult = EapHostPeerGetResponseAttributes(
m_session_id,
pAttribs,
get_ptr(error));
if (dwResult == ERROR_SUCCESS) {
// Response attributes successfuly returned.
} else if (error)
throw eap_runtime_error(*error , __FUNCTION__ " EapHostPeerGetResponseAttributes failed.");
else
throw win_runtime_error(dwResult, __FUNCTION__ " EapHostPeerGetResponseAttributes failed.");
}
EapPeerMethodResponseAction eap::method_eaphost::set_response_attributes(_In_ const EapAttributes *pAttribs)
{
// Set response attributes for EapHost peer.
EapHostPeerResponseAction action;
eap_error_runtime error;
DWORD dwResult = EapHostPeerSetResponseAttributes(
m_session_id,
pAttribs,
&action,
get_ptr(error));
if (dwResult == ERROR_SUCCESS) {
// Response attributes successfuly set.
return action_h2p(action);
} else if (error)
throw eap_runtime_error(*error , __FUNCTION__ " EapHostPeerGetResponseAttributes failed.");
else
throw win_runtime_error(dwResult, __FUNCTION__ " EapHostPeerGetResponseAttributes failed.");
}