eap::metod thorough redesign:

- Support for method stacking introduced
- EAP-TLS method has been discontinued
- ownTLS has been discontinued
This commit is contained in:
2016-10-31 16:58:53 +01:00
parent b054dcdc7a
commit c31e019cef
24 changed files with 1740 additions and 3046 deletions

View File

@@ -28,16 +28,20 @@ using namespace winstd;
// eap::method_eaphost
//////////////////////////////////////////////////////////////////////
eap::method_eaphost::method_eaphost(_In_ module &module, _In_ config_method_eaphost &cfg, _In_ credentials_eaphost &cred) :
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(module, cfg, cred)
method(mod)
{
}
eap::method_eaphost::method_eaphost(_Inout_ method_eaphost &&other) :
m_session_id (std::move(other.m_session_id)),
method(std::move(other ))
m_cfg ( other.m_cfg ),
m_cred ( other.m_cred ),
m_session_id(std::move(other.m_session_id)),
method (std::move(other ))
{
}
@@ -45,8 +49,10 @@ eap::method_eaphost::method_eaphost(_Inout_ method_eaphost &&other) :
eap::method_eaphost& eap::method_eaphost::operator=(_Inout_ method_eaphost &&other)
{
if (this != std::addressof(other)) {
assert(std::addressof(m_cfg ) == std::addressof(other.m_cfg )); // Move method within same configuration only!
assert(std::addressof(m_cred) == std::addressof(other.m_cred)); // Move method within same credentials only!
(method&)*this = std::move(other );
m_session_id = std::move(other.m_session_id);
m_session_id = std::move(other.m_session_id);
}
return *this;
@@ -59,28 +65,30 @@ void eap::method_eaphost::begin_session(
_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_auth_failed;
m_cfg.m_last_msg.clear();
// Create EapHost peer session using available connection data (m_cfg) and user data (m_cred).
auto &cfg = dynamic_cast<config_method_eaphost&>(m_cfg);
auto &cred = dynamic_cast<credentials_eaphost &>(m_cred);
eap_error_runtime error;
DWORD dwResult = EapHostPeerBeginSession(
dwFlags,
cfg.get_type(),
m_cfg.get_type(),
pAttributeArray,
hTokenImpersonateUser,
(DWORD)cfg.m_cfg_blob.size(),
cfg.m_cfg_blob.data(),
(DWORD)cred.m_cred_blob.size(),
cred.m_cred_blob.data(),
(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,
&error._Myptr);
if (dwResult == ERROR_SUCCESS) {
// Session succesfully created.
method::begin_session(dwFlags, pAttributeArray, hTokenImpersonateUser, dwMaxSendPacketSize);
m_module.log_event(&EAPMETHOD_METHOD_HANDSHAKE_START2, event_data((unsigned int)m_cfg.get_method_id()), event_data::blank);
} else if (error)
throw eap_runtime_error(*error , __FUNCTION__ " EapHostPeerBeginSession failed.");
else
@@ -90,8 +98,6 @@ void eap::method_eaphost::begin_session(
void eap::method_eaphost::end_session()
{
method::end_session();
// End EapHost peer session.
eap_error_runtime error;
DWORD dwResult = EapHostPeerEndSession(m_session_id, &error._Myptr);
@@ -101,6 +107,8 @@ void eap::method_eaphost::end_session()
throw eap_runtime_error(*error , __FUNCTION__ " EapHostPeerEndSession failed.");
else
throw win_runtime_error(dwResult, __FUNCTION__ " EapHostPeerEndSession failed.");
method::end_session();
}
@@ -110,8 +118,6 @@ EapPeerMethodResponseAction eap::method_eaphost::process_request_packet(
{
assert(pReceivedPacket || dwReceivedPacketSize == 0);
m_module.log_event(&EAPMETHOD_PACKET_RECV, event_data((unsigned int)m_cfg.get_method_id()), event_data((unsigned int)dwReceivedPacketSize), event_data::blank);
// Let EapHost peer process the packet.
EapHostPeerResponseAction action;
eap_error_runtime error;
@@ -132,24 +138,20 @@ EapPeerMethodResponseAction eap::method_eaphost::process_request_packet(
void eap::method_eaphost::get_response_packet(
_Inout_bytecap_(*dwSendPacketSize) void *pSendPacket,
_Inout_ DWORD *pdwSendPacketSize)
_Out_ sanitizing_blob &packet,
_In_opt_ DWORD size_max)
{
assert(pdwSendPacketSize);
assert(pSendPacket || !*pdwSendPacketSize);
// Let EapHost peer prepare response packet.
DWORD size_max = *pdwSendPacketSize;
eap_blob_runtime packet;
eap_blob_runtime _packet;
eap_error_runtime error;
DWORD dwResult = EapHostPeerGetSendPacket(
m_session_id,
pdwSendPacketSize,
&packet._Myptr,
&size_max,
&_packet._Myptr,
&error._Myptr);
if (dwResult == ERROR_SUCCESS) {
// Packet successfuly prepared.
memcpy_s(pSendPacket, size_max, packet.get(), *pdwSendPacketSize);
packet.assign(_packet.get(), _packet.get() + size_max);
} else if (error)
throw eap_runtime_error(*error , __FUNCTION__ " EapHostPeerGetSendPacket failed.");
else
@@ -161,34 +163,49 @@ void eap::method_eaphost::get_result(
_In_ EapPeerMethodResultReason reason,
_Inout_ EapPeerMethodResult *pResult)
{
assert(pResult);
// Let EapHost peer return result.
eap_error_runtime error;
EapHostPeerMethodResult result = {};
DWORD dwResult = EapHostPeerGetResult(
m_session_id,
EapHostPeerMethodResultFromMethod,
&result,
&error._Myptr);
if (dwResult == ERROR_SUCCESS) {
// Result successfuly returned.
method::get_result(reason, pResult);
if (reason == EapPeerMethodResultSuccess) {
// Let EapHost peer return result.
eap_error_runtime error;
EapHostPeerMethodResult result = {};
DWORD dwResult = EapHostPeerGetResult(
m_session_id,
EapHostPeerMethodResultFromMethod,
&result,
&error._Myptr);
if (dwResult == ERROR_SUCCESS) {
// Result successfuly returned.
pResult->fIsSuccess = result.fIsSuccess;
pResult->dwFailureReasonCode = result.dwFailureReasonCode;
pResult->pAttribArray = result.pAttribArray;
pResult->pEapError = result.pEapError;
pResult->dwFailureReasonCode = result.dwFailureReasonCode;
pResult->pAttribArray = result.pAttribArray;
if (result.fSaveConnectionData)
dynamic_cast<config_method_eaphost&>(m_cfg).m_cfg_blob.assign(result.pConnectionData, result.pConnectionData + result.dwSizeofConnectionData);
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.fSaveUserData)
dynamic_cast<credentials_eaphost &>(m_cred).m_cred_blob.assign(result.pUserData, result.pUserData + result.dwSizeofUserData);
} else if (error)
throw eap_runtime_error(*error , __FUNCTION__ " EapHostPeerGetResult failed.");
else
throw win_runtime_error(dwResult, __FUNCTION__ " EapHostPeerGetResult failed.");
}
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_success;
// Always ask EAP host to save the connection data. And it will save it *only* when we report "success".
// Don't worry. EapHost is well aware of failed authentication condition.
pResult->fSaveConnectionData = TRUE;
pResult->fIsSuccess = TRUE;
} else if (error)
throw eap_runtime_error(*error , __FUNCTION__ " EapHostPeerGetResult failed.");
else
throw win_runtime_error(dwResult, __FUNCTION__ " EapHostPeerGetResult failed.");
}