EAP.h
/*
SPDX-License-Identifier: MIT
Copyright © 1991-2022 Amebis
Copyright © 2016 GÉANT
*/
#pragma once
#include "Common.h"
#include <eaphostpeerconfigapis.h>
#include <eaptypes.h>
#include <EapHostPeerTypes.h>
#include <eapmethodtypes.h>
#include <eappapis.h>
#include <WinSock2.h>
#include <memory>
#pragma warning(push)
#pragma warning(disable: 26812) // Windows EAP API is using unscoped enums
#pragma warning(push)
#pragma warning(disable: 4505) // Don't warn on unused code
static bool operator==(_In_ const EAP_METHOD_TYPE &a, _In_ const EAP_METHOD_TYPE &b) noexcept
{
return
a.eapType.type == b.eapType.type &&
a.eapType.dwVendorId == b.eapType.dwVendorId &&
a.eapType.dwVendorType == b.eapType.dwVendorType &&
a.dwAuthorId == a.dwAuthorId;
}
static bool operator!=(_In_ const EAP_METHOD_TYPE &a, _In_ const EAP_METHOD_TYPE &b) noexcept
{
return !operator==(a, b);
}
#pragma warning(pop)
namespace winstd
{
#pragma warning(suppress: 4480)
enum class eap_type_t : unsigned char {
undefined = 0,
identity = 1,
notification = 2,
nak = 3,
md5_challenge = 4,
otp = 5,
gtc = 6,
tls = 13,
ttls = 21,
peap = 25,
mschapv2 = 26,
ms_auth_tlv = 33,
gtcp = 128 + gtc,
legacy_pap = 192,
legacy_mschapv2 = 193,
start = 1,
end = 192,
noneap_start = 192,
noneap_end = 254,
};
struct EapHostPeerFreeMemory_delete
{
EapHostPeerFreeMemory_delete() noexcept {}
template <class _T>
void operator()(_T *_Ptr) const
{
EapHostPeerFreeMemory((BYTE*)_Ptr);
}
};
typedef std::unique_ptr<BYTE[], EapHostPeerFreeMemory_delete> eap_blob;
struct EapHostPeerFreeRuntimeMemory_delete
{
EapHostPeerFreeRuntimeMemory_delete() noexcept {}
template <class _T>
void operator()(_T *_Ptr) const
{
EapHostPeerFreeRuntimeMemory((BYTE*)_Ptr);
}
};
typedef std::unique_ptr<BYTE[], EapHostPeerFreeRuntimeMemory_delete> eap_blob_runtime;
struct EapHostPeerFreeErrorMemory_delete
{
EapHostPeerFreeErrorMemory_delete() noexcept {}
void operator()(EAP_ERROR *_Ptr) const noexcept
{
EapHostPeerFreeErrorMemory(_Ptr);
}
};
typedef std::unique_ptr<EAP_ERROR, EapHostPeerFreeErrorMemory_delete> eap_error;
struct EapHostPeerFreeEapError_delete
{
EapHostPeerFreeEapError_delete() noexcept {}
void operator()(EAP_ERROR *_Ptr) const noexcept
{
EapHostPeerFreeEapError(_Ptr);
}
};
typedef std::unique_ptr<EAP_ERROR, EapHostPeerFreeEapError_delete> eap_error_runtime;
#pragma warning(push)
#pragma warning(disable: 26432) // Copy constructor and assignment operator are also present, but not detected by code analysis as they are using base type source object reference.
class eap_attr : public EAP_ATTRIBUTE
{
public:
eap_attr() noexcept
{
eaType = eatReserved;
dwLength = 0;
pValue = NULL;
}
eap_attr(_In_ const EAP_ATTRIBUTE &a)
{
eaType = a.eaType;
dwLength = a.dwLength;
if (a.dwLength) {
pValue = new BYTE[a.dwLength];
assert(pValue);
memcpy(pValue, a.pValue, a.dwLength);
} else
pValue = NULL;
}
eap_attr(_Inout_ eap_attr &&a) noexcept
{
eaType = a.eaType;
dwLength = a.dwLength;
if (a.dwLength) {
pValue = a.pValue;
a.dwLength = 0;
a.pValue = NULL;
} else
pValue = NULL;
}
~eap_attr()
{
if (pValue)
delete [] pValue;
}
eap_attr& operator=(_In_ const EAP_ATTRIBUTE &a)
{
if (this != &a) {
eaType = a.eaType;
dwLength = a.dwLength;
if (a.dwLength) {
BYTE *pValueNew = new BYTE[a.dwLength];
if (pValueNew) {
if (pValue)
delete [] pValue;
memcpy(pValueNew, a.pValue, a.dwLength);
pValue = pValueNew;
} else
assert(0); // Could not allocate memory
} else
pValue = NULL;
}
return *this;
}
eap_attr& operator=(_Inout_ eap_attr &&a) noexcept
{
if (this != &a) {
eaType = a.eaType;
dwLength = a.dwLength;
if (pValue)
delete [] pValue;
if (a.dwLength) {
pValue = a.pValue;
a.dwLength = 0;
a.pValue = NULL;
} else
pValue = NULL;
}
return *this;
}
void create_ms_mppe_key(_In_ BYTE bVendorType, _In_count_(nKeySize) LPCBYTE pbKey, _In_ BYTE nKeySize)
{
const BYTE nPaddingLength = static_cast<BYTE>((16 - (1 + static_cast<DWORD>(nKeySize))) % 16);
const DWORD dwLengthNew =
4 + // Vendor-Id
1 + // Vendor type
1 + // Vendor length
2 + // Salt
1 + // Key-Length
nKeySize + // Key
nPaddingLength; // Padding
#pragma warning(push)
#pragma warning(disable: 6386)
LPBYTE p = new BYTE[dwLengthNew];
p[0] = 0x00; // Vendor-Id (0x137 = 311 = Microsoft)
p[1] = 0x00; // --|
p[2] = 0x01; // --|
p[3] = 0x37; // --^
p[4] = bVendorType; // Vendor type
p[5] = static_cast<BYTE>(dwLengthNew - 4); // Vendor length
p[6] = 0x00; // Salt
p[7] = 0x00; // --^
p[8] = nKeySize; // Key-Length
#pragma warning(pop)
memcpy(p + 9, pbKey, nKeySize); // Key
memset(p + 9 + nKeySize, 0, nPaddingLength); // Padding
if (pValue)
delete [] pValue;
#pragma warning(suppress: 26812) // EAP_ATTRIBUTE_TYPE is unscoped.
eaType = eatVendorSpecific;
dwLength = dwLengthNew;
pValue = p;
}
};
#pragma warning(pop)
static const EAP_ATTRIBUTE blank_eap_attr = {};
class eap_method_prop : public EAP_METHOD_PROPERTY
{
public:
eap_method_prop(_In_ EAP_METHOD_PROPERTY_TYPE type, _In_ BOOL value) noexcept
{
eapMethodPropertyType = type;
eapMethodPropertyValueType = empvtBool;
eapMethodPropertyValue.empvBool.length = sizeof(BOOL);
eapMethodPropertyValue.empvBool.value = value;
}
eap_method_prop(_In_ EAP_METHOD_PROPERTY_TYPE type, _In_ DWORD value) noexcept
{
eapMethodPropertyType = type;
eapMethodPropertyValueType = empvtDword;
eapMethodPropertyValue.empvDword.length = sizeof(DWORD);
eapMethodPropertyValue.empvDword.value = value;
}
eap_method_prop(_In_ EAP_METHOD_PROPERTY_TYPE type, _In_z_ LPCWSTR value) noexcept
{
eapMethodPropertyType = type;
eapMethodPropertyValueType = empvtString;
eapMethodPropertyValue.empvString.length = static_cast<DWORD>(sizeof(WCHAR)*(wcslen(value) + 1));
eapMethodPropertyValue.empvString.value = const_cast<BYTE*>(reinterpret_cast<const BYTE*>(value));
}
};
class eap_packet : public dplhandle<EapPacket*, NULL>
{
WINSTD_DPLHANDLE_IMPL(eap_packet, NULL)
public:
virtual ~eap_packet()
{
if (m_h != invalid)
free_internal();
}
bool create(_In_ EapCode code, _In_ BYTE id, _In_ WORD size) noexcept
{
assert(size >= 4); // EAP packets must contain at least Code, Id, and Length fields: 4B.
handle_type h = static_cast< handle_type >(HeapAlloc(GetProcessHeap(), 0, size));
if (h != NULL) {
h->Code = static_cast<BYTE>(code);
h->Id = id;
*reinterpret_cast<WORD*>(h->Length) = htons(size);
attach(h);
return true;
} else {
SetLastError(ERROR_OUTOFMEMORY);
return false;
}
}
WORD size() const noexcept
{
return m_h != NULL ? ntohs(*(WORD*)m_h->Length) : 0;
}
protected:
void free_internal() noexcept override
{
HeapFree(GetProcessHeap(), 0, m_h);
}
handle_type duplicate_internal(_In_ handle_type h) const noexcept override
{
const WORD n = ntohs(*reinterpret_cast<WORD*>(h->Length));
handle_type h2 = static_cast< handle_type >(HeapAlloc(GetProcessHeap(), 0, n));
if (h2 == NULL) {
SetLastError(ERROR_OUTOFMEMORY);
return NULL;
}
memcpy(h2, h, n);
return h2;
}
};
class eap_method_info_array : public EAP_METHOD_INFO_ARRAY
{
WINSTD_NONCOPYABLE(eap_method_info_array)
public:
eap_method_info_array() noexcept
{
dwNumberOfMethods = 0;
pEapMethods = NULL;
}
eap_method_info_array(_Inout_ eap_method_info_array &&other) noexcept
{
dwNumberOfMethods = other.dwNumberOfMethods;
pEapMethods = other.pEapMethods;
other.dwNumberOfMethods = 0;
other.pEapMethods = NULL;
}
~eap_method_info_array()
{
if (pEapMethods)
free_internal();
}
eap_method_info_array& operator=(_Inout_ eap_method_info_array &&other) noexcept
{
if (this != std::addressof(other)) {
if (pEapMethods)
free_internal();
dwNumberOfMethods = other.dwNumberOfMethods;
pEapMethods = other.pEapMethods;
other.dwNumberOfMethods = 0;
other.pEapMethods = NULL;
}
return *this;
}
protected:
void free_internal() noexcept
{
for (DWORD i = 0; i < dwNumberOfMethods; i++)
free_internal(pEapMethods + i);
EapHostPeerFreeMemory(reinterpret_cast<BYTE*>(pEapMethods));
}
static void free_internal(_In_ EAP_METHOD_INFO *pMethodInfo) noexcept
{
if (pMethodInfo->pInnerMethodInfo)
free_internal(pMethodInfo->pInnerMethodInfo);
EapHostPeerFreeMemory(reinterpret_cast<BYTE*>(pMethodInfo->pwszAuthorName));
EapHostPeerFreeMemory(reinterpret_cast<BYTE*>(pMethodInfo->pwszFriendlyName));
}
};
class eap_runtime_error : public win_runtime_error
{
public:
eap_runtime_error(_In_ const EAP_ERROR &err, _In_ const std::string& msg) :
m_type (err.type ),
m_reason (err.dwReasonCode ),
m_root_cause_id (err.rootCauseGuid ),
m_root_cause_desc(err.pRootCauseString ),
m_repair_id (err.repairGuid ),
m_repair_desc (err.pRepairString ),
m_help_link_id (err.helpLinkGuid ),
win_runtime_error(err.dwWinError, msg.c_str())
{
}
eap_runtime_error(_In_ const EAP_ERROR &err, _In_opt_z_ const char *msg = nullptr) :
m_type (err.type ),
m_reason (err.dwReasonCode ),
m_root_cause_id (err.rootCauseGuid ),
m_root_cause_desc(err.pRootCauseString),
m_repair_id (err.repairGuid ),
m_repair_desc (err.pRepairString ),
m_help_link_id (err.helpLinkGuid ),
win_runtime_error(err.dwWinError, msg )
{
}
const EAP_METHOD_TYPE& type() const noexcept
{
return m_type;
}
DWORD reason() const noexcept
{
return m_reason;
}
const GUID& root_cause_id() const noexcept
{
return m_root_cause_id;
}
const wchar_t* root_cause() const noexcept
{
return m_root_cause_desc.c_str();
}
const GUID& repair_id() const noexcept
{
return m_repair_id;
}
const wchar_t* repair() const noexcept
{
return m_repair_desc.c_str();
}
const GUID& help_link_id() const noexcept
{
return m_help_link_id;
}
protected:
EAP_METHOD_TYPE m_type;
DWORD m_reason;
GUID m_root_cause_id;
std::wstring m_root_cause_desc;
GUID m_repair_id;
std::wstring m_repair_desc;
GUID m_help_link_id;
};
}
#pragma warning(pop)
winstd::dplhandle
Base abstract template class to support object handle keeping for objects that support handle duplica...
Definition: Common.h:866
winstd::eap_attr
EAP_ATTRIBUTE wrapper class.
Definition: EAP.h:214
winstd::eap_attr::eap_attr
eap_attr() noexcept
Initializes a new EAP attribute set to eatReserved.
Definition: EAP.h:219
winstd::eap_attr::eap_attr
eap_attr(eap_attr &&a) noexcept
Moves an existing EAP attribute.
Definition: EAP.h:244
winstd::eap_attr::~eap_attr
~eap_attr()
Destroys the EAP attribute.
Definition: EAP.h:259
winstd::eap_attr::operator=
eap_attr & operator=(eap_attr &&a) noexcept
Moves an existing EAP attribute.
Definition: EAP.h:291
winstd::eap_attr::eap_attr
eap_attr(const EAP_ATTRIBUTE &a)
Copies an existing EAP attribute.
Definition: EAP.h:229
winstd::eap_attr::create_ms_mppe_key
void create_ms_mppe_key(BYTE bVendorType, LPCBYTE pbKey, BYTE nKeySize)
Creates MS-MPPE-Send-Key or MS-MPPE-Recv-Key.
Definition: EAP.h:315
winstd::eap_attr::operator=
eap_attr & operator=(const EAP_ATTRIBUTE &a)
Copies an existing EAP attribute.
Definition: EAP.h:268
winstd::eap_method_info_array
EAP_METHOD_INFO_ARRAY wrapper class.
Definition: EAP.h:493
winstd::eap_method_info_array::eap_method_info_array
eap_method_info_array(eap_method_info_array &&other) noexcept
Move constructor.
Definition: EAP.h:511
winstd::eap_method_info_array::eap_method_info_array
eap_method_info_array() noexcept
Constructs an empty array.
Definition: EAP.h:500
winstd::eap_method_info_array::~eap_method_info_array
~eap_method_info_array()
Destructor.
Definition: EAP.h:522
winstd::eap_method_info_array::operator=
eap_method_info_array & operator=(eap_method_info_array &&other) noexcept
Move assignment.
Definition: EAP.h:533
winstd::eap_method_prop
EAP_METHOD_PROPERTY wrapper class.
Definition: EAP.h:363
winstd::eap_method_prop::eap_method_prop
eap_method_prop(EAP_METHOD_PROPERTY_TYPE type, BOOL value) noexcept
Constructs a BOOL method property.
Definition: EAP.h:371
winstd::eap_method_prop::eap_method_prop
eap_method_prop(EAP_METHOD_PROPERTY_TYPE type, DWORD value) noexcept
Constructs a DWORD method property.
Definition: EAP.h:385
winstd::eap_method_prop::eap_method_prop
eap_method_prop(EAP_METHOD_PROPERTY_TYPE type, LPCWSTR value) noexcept
Constructs a Unicode string method property.
Definition: EAP.h:399
winstd::eap_packet
EapPacket wrapper class.
Definition: EAP.h:412
winstd::eap_packet::size
WORD size() const noexcept
Returns total EAP packet size in bytes.
Definition: EAP.h:459
winstd::eap_packet::duplicate_internal
handle_type duplicate_internal(handle_type h) const noexcept override
Duplicates the EAP packet.
Definition: EAP.h:476
winstd::eap_packet::~eap_packet
virtual ~eap_packet()
Destroys the EAP packet.
Definition: EAP.h:419
winstd::eap_packet::free_internal
void free_internal() noexcept override
Destroys the EAP packet.
Definition: EAP.h:468
winstd::eap_packet::create
bool create(EapCode code, BYTE id, WORD size) noexcept
Create new EAP packet.
Definition: EAP.h:438
winstd::eap_runtime_error
EapHost runtime error.
Definition: EAP.h:580
winstd::eap_runtime_error::type
const EAP_METHOD_TYPE & type() const noexcept
Returns EAP method type.
Definition: EAP.h:621
winstd::eap_runtime_error::m_root_cause_id
GUID m_root_cause_id
A unique ID that identifies cause of error in EAPHost.
Definition: EAP.h:679
winstd::eap_runtime_error::root_cause
const wchar_t * root_cause() const noexcept
Returns root cause ID.
Definition: EAP.h:645
winstd::eap_runtime_error::repair_id
const GUID & repair_id() const noexcept
Returns repair ID.
Definition: EAP.h:653
winstd::eap_runtime_error::m_repair_desc
std::wstring m_repair_desc
A localized and readable string that describes the possible repair action.
Definition: EAP.h:683
winstd::eap_runtime_error::reason
DWORD reason() const noexcept
Returns the reason code for error.
Definition: EAP.h:629
winstd::eap_runtime_error::m_type
EAP_METHOD_TYPE m_type
Structure that identifies the EAP method that raised the error.
Definition: EAP.h:675
winstd::eap_runtime_error::eap_runtime_error
eap_runtime_error(const EAP_ERROR &err, const char *msg=nullptr)
Constructs an exception.
Definition: EAP.h:606
winstd::eap_runtime_error::m_repair_id
GUID m_repair_id
A unique ID that maps to a localizable string that identifies the repair action that can be taken to ...
Definition: EAP.h:682
winstd::eap_runtime_error::eap_runtime_error
eap_runtime_error(const EAP_ERROR &err, const std::string &msg)
Constructs an exception.
Definition: EAP.h:588
winstd::eap_runtime_error::repair
const wchar_t * repair() const noexcept
Returns root cause ID.
Definition: EAP.h:661
winstd::eap_runtime_error::m_help_link_id
GUID m_help_link_id
A unique ID that maps to a localizable string that specifies an URL for a page that contains addition...
Definition: EAP.h:685
winstd::eap_runtime_error::root_cause_id
const GUID & root_cause_id() const noexcept
Returns root cause ID.
Definition: EAP.h:637
winstd::eap_runtime_error::m_root_cause_desc
std::wstring m_root_cause_desc
A localized and readable string that describes the root cause of the error.
Definition: EAP.h:680
winstd::eap_runtime_error::help_link_id
const GUID & help_link_id() const noexcept
Returns help_link ID.
Definition: EAP.h:669
winstd::eap_runtime_error::m_reason
DWORD m_reason
The reason code for the error.
Definition: EAP.h:677
winstd::handle< EapPacket *, INVAL >::handle_type
EapPacket * handle_type
Datatype of the object handle this template class handles.
Definition: Common.h:609
winstd::handle< EapPacket *, INVAL >::m_h
handle_type m_h
Object handle.
Definition: Common.h:855
winstd::handle< EapPacket *, INVAL >::attach
void attach(handle_type h) noexcept
Sets a new object handle for the class.
Definition: Common.h:818
winstd::win_runtime_error
Windows runtime error.
Definition: Common.h:1048
winstd::win_runtime_error::msg
tstring msg(DWORD dwLanguageId=0) const
Returns a user-readable Windows error message.
Definition: Common.h:1093
winstd::eap_error_runtime
std::unique_ptr< EAP_ERROR, EapHostPeerFreeEapError_delete > eap_error_runtime
EAP_ERROR wrapper class.
Definition: EAP.h:206
winstd::eap_blob
std::unique_ptr< BYTE[], EapHostPeerFreeMemory_delete > eap_blob
EapHost BLOB wrapper class.
Definition: EAP.h:129
winstd::eap_type_t
eap_type_t
EAP method numbers.
Definition: EAP.h:79
winstd::eap_error
std::unique_ptr< EAP_ERROR, EapHostPeerFreeErrorMemory_delete > eap_error
EAP_ERROR wrapper class.
Definition: EAP.h:180
winstd::eap_blob_runtime
std::unique_ptr< BYTE[], EapHostPeerFreeRuntimeMemory_delete > eap_blob_runtime
EapHost BLOB wrapper class.
Definition: EAP.h:154
winstd::eap_type_t::notification
@ notification
Notification.
winstd::eap_type_t::md5_challenge
@ md5_challenge
MD5-Challenge.
winstd::eap_type_t::legacy_pap
@ legacy_pap
PAP (Not actually an EAP method; Moved to the Unassigned area)
winstd::eap_type_t::gtc
@ gtc
Generic Token Card (GTC)
winstd::eap_type_t::undefined
@ undefined
Undefined EAP type.
winstd::eap_type_t::end
@ end
End of EAP methods (non-inclusive)
winstd::eap_type_t::gtcp
@ gtcp
EAP-GTC using a password.
winstd::eap_type_t::noneap_start
@ noneap_start
Start of non-EAP methods.
winstd::eap_type_t::tls
@ tls
EAP-TLS.
winstd::eap_type_t::nak
@ nak
Legacy Nak.
winstd::eap_type_t::noneap_end
@ noneap_end
End of non-EAP methods (non-inclusive)
winstd::eap_type_t::peap
@ peap
PEAP.
winstd::eap_type_t::ttls
@ ttls
EAP-TTLS.
winstd::eap_type_t::otp
@ otp
One-Time Password (OTP)
winstd::eap_type_t::legacy_mschapv2
@ legacy_mschapv2
MSCHAPv2 (Not actually an EAP method; Moved to the Unassigned area)
winstd::eap_type_t::ms_auth_tlv
@ ms_auth_tlv
MS-Authentication-TLV.
winstd::eap_type_t::start
@ start
Start of EAP methods.
winstd::eap_type_t::mschapv2
@ mschapv2
EAP-MSCHAPv2.
winstd::eap_type_t::identity
@ identity
Identity.
WINSTD_NONCOPYABLE
#define WINSTD_NONCOPYABLE(C)
Declares a class as non-copyable.
Definition: Common.h:53
WINSTD_DPLHANDLE_IMPL
#define WINSTD_DPLHANDLE_IMPL(C, INVAL)
Implements default constructors and operators to prevent their auto-generation by compiler.
Definition: Common.h:174
winstd::handle< EapPacket *, INVAL >::invalid
static const EapPacket * invalid
Invalid handle value.
Definition: Common.h:614
winstd::EapHostPeerFreeEapError_delete
Deleter for unique_ptr to EAP_ERROR using EapHostPeerFreeEapError.
Definition: EAP.h:186
winstd::EapHostPeerFreeEapError_delete::EapHostPeerFreeEapError_delete
EapHostPeerFreeEapError_delete() noexcept
Default constructor.
Definition: EAP.h:190
winstd::EapHostPeerFreeEapError_delete::operator()
void operator()(EAP_ERROR *_Ptr) const noexcept
Delete a pointer.
Definition: EAP.h:197
winstd::EapHostPeerFreeErrorMemory_delete
Deleter for unique_ptr to EAP_ERROR using EapHostPeerFreeErrorMemory.
Definition: EAP.h:160
winstd::EapHostPeerFreeErrorMemory_delete::EapHostPeerFreeErrorMemory_delete
EapHostPeerFreeErrorMemory_delete() noexcept
Default constructor.
Definition: EAP.h:164
winstd::EapHostPeerFreeErrorMemory_delete::operator()
void operator()(EAP_ERROR *_Ptr) const noexcept
Delete a pointer.
Definition: EAP.h:171
winstd::EapHostPeerFreeMemory_delete
Deleter for unique_ptr using EapHostPeerFreeMemory.
Definition: EAP.h:108
winstd::EapHostPeerFreeMemory_delete::operator()
void operator()(_T *_Ptr) const
Delete a pointer.
Definition: EAP.h:120
winstd::EapHostPeerFreeMemory_delete::EapHostPeerFreeMemory_delete
EapHostPeerFreeMemory_delete() noexcept
Default constructor.
Definition: EAP.h:112
winstd::EapHostPeerFreeRuntimeMemory_delete
Deleter for unique_ptr using EapHostPeerFreeRuntimeMemory.
Definition: EAP.h:135
winstd::EapHostPeerFreeRuntimeMemory_delete::operator()
void operator()(_T *_Ptr) const
Delete a pointer.
Definition: EAP.h:145
winstd::EapHostPeerFreeRuntimeMemory_delete::EapHostPeerFreeRuntimeMemory_delete
EapHostPeerFreeRuntimeMemory_delete() noexcept
Default constructor.
Definition: EAP.h:139