WinStd
Additional templates and function helpers for Microsoft Windows using Standard C++ classes
EAP.h
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 1991-2022 Amebis
4 Copyright © 2016 GÉANT
5*/
6
7#pragma once
8
9#include "Common.h"
10#include <eaphostpeerconfigapis.h>
11#include <eaptypes.h>
12#include <EapHostPeerTypes.h>
13#include <eapmethodtypes.h>
14#include <eappapis.h>
15#include <WinSock2.h>
16#include <memory>
17
18#pragma warning(push)
19#pragma warning(disable: 26812) // Windows EAP API is using unscoped enums
20
21#pragma warning(push)
22#pragma warning(disable: 4505) // Don't warn on unused code
23
29
40static bool operator==(_In_ const EAP_METHOD_TYPE &a, _In_ const EAP_METHOD_TYPE &b) noexcept
41{
42 return
43 a.eapType.type == b.eapType.type &&
44 a.eapType.dwVendorId == b.eapType.dwVendorId &&
45 a.eapType.dwVendorType == b.eapType.dwVendorType &&
46 a.dwAuthorId == a.dwAuthorId;
47}
48
59static bool operator!=(_In_ const EAP_METHOD_TYPE &a, _In_ const EAP_METHOD_TYPE &b) noexcept
60{
61 return !operator==(a, b);
62}
63
65
66#pragma warning(pop)
67
68namespace winstd
69{
72
78 #pragma warning(suppress: 4480)
79 enum class eap_type_t : unsigned char {
80 undefined = 0,
81 identity = 1,
82 notification = 2,
83 nak = 3,
84 md5_challenge = 4,
85 otp = 5,
86 gtc = 6,
87 tls = 13,
88 ttls = 21,
89 peap = 25,
90 mschapv2 = 26,
91 ms_auth_tlv = 33,
92
93 gtcp = 128 + gtc,
94
95 legacy_pap = 192,
96 legacy_mschapv2 = 193,
97
98 start = 1,
99 end = 192,
100 noneap_start = 192,
101 noneap_end = 254,
102 };
103
108 {
113
119 template <class _T>
120 void operator()(_T *_Ptr) const
121 {
122 EapHostPeerFreeMemory((BYTE*)_Ptr);
123 }
124 };
125
129 typedef std::unique_ptr<BYTE[], EapHostPeerFreeMemory_delete> eap_blob;
130
135 {
140
144 template <class _T>
145 void operator()(_T *_Ptr) const
146 {
147 EapHostPeerFreeRuntimeMemory((BYTE*)_Ptr);
148 }
149 };
150
154 typedef std::unique_ptr<BYTE[], EapHostPeerFreeRuntimeMemory_delete> eap_blob_runtime;
155
160 {
165
171 void operator()(EAP_ERROR *_Ptr) const noexcept
172 {
173 EapHostPeerFreeErrorMemory(_Ptr);
174 }
175 };
176
180 typedef std::unique_ptr<EAP_ERROR, EapHostPeerFreeErrorMemory_delete> eap_error;
181
186 {
191
197 void operator()(EAP_ERROR *_Ptr) const noexcept
198 {
199 EapHostPeerFreeEapError(_Ptr);
200 }
201 };
202
206 typedef std::unique_ptr<EAP_ERROR, EapHostPeerFreeEapError_delete> eap_error_runtime;
207
211 #pragma warning(push)
212 #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.
213 class eap_attr : public EAP_ATTRIBUTE
214 {
215 public:
219 eap_attr() noexcept
220 {
221 eaType = eatReserved;
222 dwLength = 0;
223 pValue = NULL;
224 }
225
229 eap_attr(_In_ const EAP_ATTRIBUTE &a)
230 {
231 eaType = a.eaType;
232 dwLength = a.dwLength;
233 if (a.dwLength) {
234 pValue = new BYTE[a.dwLength];
235 assert(pValue);
236 memcpy(pValue, a.pValue, a.dwLength);
237 } else
238 pValue = NULL;
239 }
240
244 eap_attr(_Inout_ eap_attr &&a) noexcept
245 {
246 eaType = a.eaType;
247 dwLength = a.dwLength;
248 if (a.dwLength) {
249 pValue = a.pValue;
250 a.dwLength = 0;
251 a.pValue = NULL;
252 } else
253 pValue = NULL;
254 }
255
260 {
261 if (pValue)
262 delete [] pValue;
263 }
264
268 eap_attr& operator=(_In_ const EAP_ATTRIBUTE &a)
269 {
270 if (this != &a) {
271 eaType = a.eaType;
272 dwLength = a.dwLength;
273 if (a.dwLength) {
274 BYTE *pValueNew = new BYTE[a.dwLength];
275 if (pValueNew) {
276 if (pValue)
277 delete [] pValue;
278 memcpy(pValueNew, a.pValue, a.dwLength);
279 pValue = pValueNew;
280 } else
281 assert(0); // Could not allocate memory
282 } else
283 pValue = NULL;
284 }
285 return *this;
286 }
287
291 eap_attr& operator=(_Inout_ eap_attr &&a) noexcept
292 {
293 if (this != &a) {
294 eaType = a.eaType;
295 dwLength = a.dwLength;
296 if (pValue)
297 delete [] pValue;
298 if (a.dwLength) {
299 pValue = a.pValue;
300 a.dwLength = 0;
301 a.pValue = NULL;
302 } else
303 pValue = NULL;
304 }
305 return *this;
306 }
307
315 void create_ms_mppe_key(_In_ BYTE bVendorType, _In_count_(nKeySize) LPCBYTE pbKey, _In_ BYTE nKeySize)
316 {
317 const BYTE nPaddingLength = static_cast<BYTE>((16 - (1 + static_cast<DWORD>(nKeySize))) % 16);
318 const DWORD dwLengthNew =
319 4 + // Vendor-Id
320 1 + // Vendor type
321 1 + // Vendor length
322 2 + // Salt
323 1 + // Key-Length
324 nKeySize + // Key
325 nPaddingLength; // Padding
326
327 #pragma warning(push)
328 #pragma warning(disable: 6386)
329 LPBYTE p = new BYTE[dwLengthNew];
330 p[0] = 0x00; // Vendor-Id (0x137 = 311 = Microsoft)
331 p[1] = 0x00; // --|
332 p[2] = 0x01; // --|
333 p[3] = 0x37; // --^
334 p[4] = bVendorType; // Vendor type
335 p[5] = static_cast<BYTE>(dwLengthNew - 4); // Vendor length
336 p[6] = 0x00; // Salt
337 p[7] = 0x00; // --^
338 p[8] = nKeySize; // Key-Length
339 #pragma warning(pop)
340 memcpy(p + 9, pbKey, nKeySize); // Key
341 memset(p + 9 + nKeySize, 0, nPaddingLength); // Padding
342
343 if (pValue)
344 delete [] pValue;
345
346 #pragma warning(suppress: 26812) // EAP_ATTRIBUTE_TYPE is unscoped.
347 eaType = eatVendorSpecific;
348 dwLength = dwLengthNew;
349 pValue = p;
350 }
351 };
352 #pragma warning(pop)
353
357 static const EAP_ATTRIBUTE blank_eap_attr = {};
358
362 class eap_method_prop : public EAP_METHOD_PROPERTY
363 {
364 public:
371 eap_method_prop(_In_ EAP_METHOD_PROPERTY_TYPE type, _In_ BOOL value) noexcept
372 {
373 eapMethodPropertyType = type;
374 eapMethodPropertyValueType = empvtBool;
375 eapMethodPropertyValue.empvBool.length = sizeof(BOOL);
376 eapMethodPropertyValue.empvBool.value = value;
377 }
378
385 eap_method_prop(_In_ EAP_METHOD_PROPERTY_TYPE type, _In_ DWORD value) noexcept
386 {
387 eapMethodPropertyType = type;
388 eapMethodPropertyValueType = empvtDword;
389 eapMethodPropertyValue.empvDword.length = sizeof(DWORD);
390 eapMethodPropertyValue.empvDword.value = value;
391 }
392
399 eap_method_prop(_In_ EAP_METHOD_PROPERTY_TYPE type, _In_z_ LPCWSTR value) noexcept
400 {
401 eapMethodPropertyType = type;
402 eapMethodPropertyValueType = empvtString;
403 eapMethodPropertyValue.empvString.length = static_cast<DWORD>(sizeof(WCHAR)*(wcslen(value) + 1));
404 eapMethodPropertyValue.empvString.value = const_cast<BYTE*>(reinterpret_cast<const BYTE*>(value));
405 }
406 };
407
411 class eap_packet : public dplhandle<EapPacket*, NULL>
412 {
414
415 public:
419 virtual ~eap_packet()
420 {
421 if (m_h != invalid)
423 }
424
438 bool create(_In_ EapCode code, _In_ BYTE id, _In_ WORD size) noexcept
439 {
440 assert(size >= 4); // EAP packets must contain at least Code, Id, and Length fields: 4B.
441
442 handle_type h = static_cast<handle_type>(HeapAlloc(GetProcessHeap(), 0, size));
443 if (h != NULL) {
444 h->Code = static_cast<BYTE>(code);
445 h->Id = id;
446 *reinterpret_cast<WORD*>(h->Length) = htons(size);
447
448 attach(h);
449 return true;
450 } else {
451 SetLastError(ERROR_OUTOFMEMORY);
452 return false;
453 }
454 }
455
459 WORD size() const noexcept
460 {
461 return m_h != NULL ? ntohs(*(WORD*)m_h->Length) : 0;
462 }
463
464 protected:
468 void free_internal() noexcept override
469 {
470 HeapFree(GetProcessHeap(), 0, m_h);
471 }
472
476 handle_type duplicate_internal(_In_ handle_type h) const noexcept override
477 {
478 const WORD n = ntohs(*reinterpret_cast<WORD*>(h->Length));
479 handle_type h2 = static_cast<handle_type>(HeapAlloc(GetProcessHeap(), 0, n));
480 if (h2 == NULL) {
481 SetLastError(ERROR_OUTOFMEMORY);
482 return NULL;
483 }
484 memcpy(h2, h, n);
485 return h2;
486 }
487 };
488
492 class eap_method_info_array : public EAP_METHOD_INFO_ARRAY
493 {
495
496 public:
501 {
502 dwNumberOfMethods = 0;
503 pEapMethods = NULL;
504 }
505
512 {
513 dwNumberOfMethods = other.dwNumberOfMethods;
514 pEapMethods = other.pEapMethods;
515 other.dwNumberOfMethods = 0;
516 other.pEapMethods = NULL;
517 }
518
523 {
524 if (pEapMethods)
525 free_internal();
526 }
527
534 {
535 if (this != std::addressof(other)) {
536 if (pEapMethods)
537 free_internal();
538 dwNumberOfMethods = other.dwNumberOfMethods;
539 pEapMethods = other.pEapMethods;
540 other.dwNumberOfMethods = 0;
541 other.pEapMethods = NULL;
542 }
543 return *this;
544 }
545
546 protected:
548
549 void free_internal() noexcept
550 {
551 for (DWORD i = 0; i < dwNumberOfMethods; i++)
552 free_internal(pEapMethods + i);
553
554 EapHostPeerFreeMemory(reinterpret_cast<BYTE*>(pEapMethods));
555 }
556
557 static void free_internal(_In_ EAP_METHOD_INFO *pMethodInfo) noexcept
558 {
559 if (pMethodInfo->pInnerMethodInfo)
560 free_internal(pMethodInfo->pInnerMethodInfo);
561
562 EapHostPeerFreeMemory(reinterpret_cast<BYTE*>(pMethodInfo->pwszAuthorName));
563 EapHostPeerFreeMemory(reinterpret_cast<BYTE*>(pMethodInfo->pwszFriendlyName));
564 }
565
567 };
568
570
573
580 {
581 public:
588 eap_runtime_error(_In_ const EAP_ERROR &err, _In_ const std::string& msg) :
589 m_type (err.type ),
590 m_reason (err.dwReasonCode ),
591 m_root_cause_id (err.rootCauseGuid ),
592 m_root_cause_desc(err.pRootCauseString ),
593 m_repair_id (err.repairGuid ),
594 m_repair_desc (err.pRepairString ),
595 m_help_link_id (err.helpLinkGuid ),
596 win_runtime_error(err.dwWinError, msg.c_str())
597 {
598 }
599
606 eap_runtime_error(_In_ const EAP_ERROR &err, _In_opt_z_ const char *msg = nullptr) :
607 m_type (err.type ),
608 m_reason (err.dwReasonCode ),
609 m_root_cause_id (err.rootCauseGuid ),
610 m_root_cause_desc(err.pRootCauseString),
611 m_repair_id (err.repairGuid ),
612 m_repair_desc (err.pRepairString ),
613 m_help_link_id (err.helpLinkGuid ),
614 win_runtime_error(err.dwWinError, msg )
615 {
616 }
617
621 const EAP_METHOD_TYPE& type() const noexcept
622 {
623 return m_type;
624 }
625
629 DWORD reason() const noexcept
630 {
631 return m_reason;
632 }
633
637 const GUID& root_cause_id() const noexcept
638 {
639 return m_root_cause_id;
640 }
641
645 const wchar_t* root_cause() const noexcept
646 {
647 return m_root_cause_desc.c_str();
648 }
649
653 const GUID& repair_id() const noexcept
654 {
655 return m_repair_id;
656 }
657
661 const wchar_t* repair() const noexcept
662 {
663 return m_repair_desc.c_str();
664 }
665
669 const GUID& help_link_id() const noexcept
670 {
671 return m_help_link_id;
672 }
673
674 protected:
675 EAP_METHOD_TYPE m_type;
676
677 DWORD m_reason;
678
680 std::wstring m_root_cause_desc;
681
683 std::wstring m_repair_desc;
684
686 };
687
689}
690
691#pragma warning(pop)
Base abstract template class to support object handle keeping for objects that support handle duplica...
Definition: Common.h:866
EAP_ATTRIBUTE wrapper class.
Definition: EAP.h:214
eap_attr() noexcept
Initializes a new EAP attribute set to eatReserved.
Definition: EAP.h:219
eap_attr(eap_attr &&a) noexcept
Moves an existing EAP attribute.
Definition: EAP.h:244
~eap_attr()
Destroys the EAP attribute.
Definition: EAP.h:259
eap_attr & operator=(eap_attr &&a) noexcept
Moves an existing EAP attribute.
Definition: EAP.h:291
eap_attr(const EAP_ATTRIBUTE &a)
Copies an existing EAP attribute.
Definition: EAP.h:229
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
eap_attr & operator=(const EAP_ATTRIBUTE &a)
Copies an existing EAP attribute.
Definition: EAP.h:268
EAP_METHOD_INFO_ARRAY wrapper class.
Definition: EAP.h:493
eap_method_info_array(eap_method_info_array &&other) noexcept
Move constructor.
Definition: EAP.h:511
eap_method_info_array() noexcept
Constructs an empty array.
Definition: EAP.h:500
~eap_method_info_array()
Destructor.
Definition: EAP.h:522
eap_method_info_array & operator=(eap_method_info_array &&other) noexcept
Move assignment.
Definition: EAP.h:533
EAP_METHOD_PROPERTY wrapper class.
Definition: EAP.h:363
eap_method_prop(EAP_METHOD_PROPERTY_TYPE type, BOOL value) noexcept
Constructs a BOOL method property.
Definition: EAP.h:371
eap_method_prop(EAP_METHOD_PROPERTY_TYPE type, DWORD value) noexcept
Constructs a DWORD method property.
Definition: EAP.h:385
eap_method_prop(EAP_METHOD_PROPERTY_TYPE type, LPCWSTR value) noexcept
Constructs a Unicode string method property.
Definition: EAP.h:399
EapPacket wrapper class.
Definition: EAP.h:412
WORD size() const noexcept
Returns total EAP packet size in bytes.
Definition: EAP.h:459
handle_type duplicate_internal(handle_type h) const noexcept override
Duplicates the EAP packet.
Definition: EAP.h:476
virtual ~eap_packet()
Destroys the EAP packet.
Definition: EAP.h:419
void free_internal() noexcept override
Destroys the EAP packet.
Definition: EAP.h:468
bool create(EapCode code, BYTE id, WORD size) noexcept
Create new EAP packet.
Definition: EAP.h:438
EapHost runtime error.
Definition: EAP.h:580
const EAP_METHOD_TYPE & type() const noexcept
Returns EAP method type.
Definition: EAP.h:621
GUID m_root_cause_id
A unique ID that identifies cause of error in EAPHost.
Definition: EAP.h:679
const wchar_t * root_cause() const noexcept
Returns root cause ID.
Definition: EAP.h:645
const GUID & repair_id() const noexcept
Returns repair ID.
Definition: EAP.h:653
std::wstring m_repair_desc
A localized and readable string that describes the possible repair action.
Definition: EAP.h:683
DWORD reason() const noexcept
Returns the reason code for error.
Definition: EAP.h:629
EAP_METHOD_TYPE m_type
Structure that identifies the EAP method that raised the error.
Definition: EAP.h:675
eap_runtime_error(const EAP_ERROR &err, const char *msg=nullptr)
Constructs an exception.
Definition: EAP.h:606
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
eap_runtime_error(const EAP_ERROR &err, const std::string &msg)
Constructs an exception.
Definition: EAP.h:588
const wchar_t * repair() const noexcept
Returns root cause ID.
Definition: EAP.h:661
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
const GUID & root_cause_id() const noexcept
Returns root cause ID.
Definition: EAP.h:637
std::wstring m_root_cause_desc
A localized and readable string that describes the root cause of the error.
Definition: EAP.h:680
const GUID & help_link_id() const noexcept
Returns help_link ID.
Definition: EAP.h:669
DWORD m_reason
The reason code for the error.
Definition: EAP.h:677
EapPacket * handle_type
Datatype of the object handle this template class handles.
Definition: Common.h:609
handle_type m_h
Object handle.
Definition: Common.h:855
void attach(handle_type h) noexcept
Sets a new object handle for the class.
Definition: Common.h:818
Windows runtime error.
Definition: Common.h:1048
tstring msg(DWORD dwLanguageId=0) const
Returns a user-readable Windows error message.
Definition: Common.h:1093
std::unique_ptr< EAP_ERROR, EapHostPeerFreeEapError_delete > eap_error_runtime
EAP_ERROR wrapper class.
Definition: EAP.h:206
std::unique_ptr< BYTE[], EapHostPeerFreeMemory_delete > eap_blob
EapHost BLOB wrapper class.
Definition: EAP.h:129
eap_type_t
EAP method numbers.
Definition: EAP.h:79
std::unique_ptr< EAP_ERROR, EapHostPeerFreeErrorMemory_delete > eap_error
EAP_ERROR wrapper class.
Definition: EAP.h:180
std::unique_ptr< BYTE[], EapHostPeerFreeRuntimeMemory_delete > eap_blob_runtime
EapHost BLOB wrapper class.
Definition: EAP.h:154
@ notification
Notification.
@ md5_challenge
MD5-Challenge.
@ legacy_pap
PAP (Not actually an EAP method; Moved to the Unassigned area)
@ gtc
Generic Token Card (GTC)
@ undefined
Undefined EAP type.
@ end
End of EAP methods (non-inclusive)
@ gtcp
EAP-GTC using a password.
@ noneap_start
Start of non-EAP methods.
@ nak
Legacy Nak.
@ noneap_end
End of non-EAP methods (non-inclusive)
@ otp
One-Time Password (OTP)
@ legacy_mschapv2
MSCHAPv2 (Not actually an EAP method; Moved to the Unassigned area)
@ ms_auth_tlv
MS-Authentication-TLV.
@ start
Start of EAP methods.
@ mschapv2
EAP-MSCHAPv2.
@ identity
Identity.
#define WINSTD_NONCOPYABLE(C)
Declares a class as non-copyable.
Definition: Common.h:53
#define WINSTD_DPLHANDLE_IMPL(C, INVAL)
Implements default constructors and operators to prevent their auto-generation by compiler.
Definition: Common.h:174
static const EapPacket * invalid
Invalid handle value.
Definition: Common.h:614
Deleter for unique_ptr to EAP_ERROR using EapHostPeerFreeEapError.
Definition: EAP.h:186
EapHostPeerFreeEapError_delete() noexcept
Default constructor.
Definition: EAP.h:190
void operator()(EAP_ERROR *_Ptr) const noexcept
Delete a pointer.
Definition: EAP.h:197
Deleter for unique_ptr to EAP_ERROR using EapHostPeerFreeErrorMemory.
Definition: EAP.h:160
EapHostPeerFreeErrorMemory_delete() noexcept
Default constructor.
Definition: EAP.h:164
void operator()(EAP_ERROR *_Ptr) const noexcept
Delete a pointer.
Definition: EAP.h:171
Deleter for unique_ptr using EapHostPeerFreeMemory.
Definition: EAP.h:108
void operator()(_T *_Ptr) const
Delete a pointer.
Definition: EAP.h:120
EapHostPeerFreeMemory_delete() noexcept
Default constructor.
Definition: EAP.h:112
Deleter for unique_ptr using EapHostPeerFreeRuntimeMemory.
Definition: EAP.h:135
void operator()(_T *_Ptr) const
Delete a pointer.
Definition: EAP.h:145
EapHostPeerFreeRuntimeMemory_delete() noexcept
Default constructor.
Definition: EAP.h:139