WinStd
Windows Win32 API using Standard C++
Loading...
Searching...
No Matches
EAP.h
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 1991-2024 Amebis
4 Copyright © 2016 GÉANT
5*/
6
8
9#pragma once
10
11#include "Common.h"
12#include <eaphostpeerconfigapis.h>
13#include <eaptypes.h>
14#include <EapHostPeerTypes.h>
15#include <eapmethodtypes.h>
16#include <eappapis.h>
17#include <WinSock2.h>
18#include <memory>
19
20#pragma warning(push)
21#pragma warning(disable: 26812) // Windows EAP API is using unscoped enums
22
23#pragma warning(push)
24#pragma warning(disable: 4505) // Don't warn on unused code
25
28
39static bool operator==(_In_ const EAP_METHOD_TYPE &a, _In_ const EAP_METHOD_TYPE &b) noexcept
40{
41 return
42 a.eapType.type == b.eapType.type &&
43 a.eapType.dwVendorId == b.eapType.dwVendorId &&
44 a.eapType.dwVendorType == b.eapType.dwVendorType &&
45 a.dwAuthorId == a.dwAuthorId;
46}
47
58static bool operator!=(_In_ const EAP_METHOD_TYPE &a, _In_ const EAP_METHOD_TYPE &b) noexcept
59{
60 return !operator==(a, b);
61}
62
64
65#pragma warning(pop)
66
67namespace winstd
68{
71
77 #pragma warning(suppress: 4480)
78 enum class eap_type_t : unsigned char {
79 undefined = 0,
80 identity = 1,
81 notification = 2,
82 nak = 3,
83 md5_challenge = 4,
84 otp = 5,
85 gtc = 6,
86 tls = 13,
87 ttls = 21,
88 peap = 25,
89 mschapv2 = 26,
90 ms_auth_tlv = 33,
91
92 gtcp = 128 + gtc,
93
94 legacy_pap = 192,
95 legacy_mschapv2 = 193,
96
97 start = 1,
98 end = 192,
99 noneap_start = 192,
100 noneap_end = 254,
101 };
102
107 {
112
118 template <class _T>
119 void operator()(_T *_Ptr) const
120 {
121 EapHostPeerFreeMemory((BYTE*)_Ptr);
122 }
123 };
124
128 typedef std::unique_ptr<BYTE[], EapHostPeerFreeMemory_delete> eap_blob;
129
134 {
139
143 template <class _T>
144 void operator()(_T *_Ptr) const
145 {
146 EapHostPeerFreeRuntimeMemory((BYTE*)_Ptr);
147 }
148 };
149
153 typedef std::unique_ptr<BYTE[], EapHostPeerFreeRuntimeMemory_delete> eap_blob_runtime;
154
159 {
164
170 void operator()(EAP_ERROR *_Ptr) const noexcept
171 {
172 EapHostPeerFreeErrorMemory(_Ptr);
173 }
174 };
175
179 typedef std::unique_ptr<EAP_ERROR, EapHostPeerFreeErrorMemory_delete> eap_error;
180
185 {
190
196 void operator()(EAP_ERROR *_Ptr) const noexcept
197 {
198 EapHostPeerFreeEapError(_Ptr);
199 }
200 };
201
205 typedef std::unique_ptr<EAP_ERROR, EapHostPeerFreeEapError_delete> eap_error_runtime;
206
210 #pragma warning(push)
211 #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.
212 class eap_attr : public EAP_ATTRIBUTE
213 {
214 public:
218 eap_attr() noexcept
219 {
220 eaType = eatReserved;
221 dwLength = 0;
222 pValue = NULL;
223 }
224
228 eap_attr(_In_ const EAP_ATTRIBUTE &a)
229 {
230 eaType = a.eaType;
231 dwLength = a.dwLength;
232 if (a.dwLength) {
233 pValue = new BYTE[a.dwLength];
234 memcpy(pValue, a.pValue, a.dwLength);
235 } else
236 pValue = NULL;
237 }
238
242 eap_attr(_Inout_ eap_attr &&a) noexcept
243 {
244 eaType = a.eaType;
245 dwLength = a.dwLength;
246 if (a.dwLength) {
247 pValue = a.pValue;
248 a.dwLength = 0;
249 a.pValue = NULL;
250 } else
251 pValue = NULL;
252 }
253
258 {
259 if (pValue)
260 delete [] pValue;
261 }
262
266 eap_attr& operator=(_In_ const EAP_ATTRIBUTE &a)
267 {
268 if (this != &a) {
269 eaType = a.eaType;
270 dwLength = a.dwLength;
271 if (a.dwLength) {
272 BYTE *pValueNew = new BYTE[a.dwLength];
273 if (pValue)
274 delete [] pValue;
275 memcpy(pValueNew, a.pValue, a.dwLength);
276 pValue = pValueNew;
277 } else
278 pValue = NULL;
279 }
280 return *this;
281 }
282
286 eap_attr& operator=(_Inout_ eap_attr &&a) noexcept
287 {
288 if (this != &a) {
289 eaType = a.eaType;
290 dwLength = a.dwLength;
291 if (pValue)
292 delete [] pValue;
293 if (a.dwLength) {
294 pValue = a.pValue;
295 a.dwLength = 0;
296 a.pValue = NULL;
297 } else
298 pValue = NULL;
299 }
300 return *this;
301 }
302
310 void create_ms_mppe_key(_In_ BYTE bVendorType, _In_count_(nKeySize) LPCBYTE pbKey, _In_ BYTE nKeySize)
311 {
312 const BYTE nPaddingLength = static_cast<BYTE>((16 - (1 + static_cast<DWORD>(nKeySize))) % 16);
313 const DWORD dwLengthNew =
314 4 + // Vendor-Id
315 1 + // Vendor type
316 1 + // Vendor length
317 2 + // Salt
318 1 + // Key-Length
319 nKeySize + // Key
320 nPaddingLength; // Padding
321
322 #pragma warning(push)
323 #pragma warning(disable: 6386)
324 LPBYTE p = new BYTE[dwLengthNew];
325 p[0] = 0x00; // Vendor-Id (0x137 = 311 = Microsoft)
326 p[1] = 0x00; // --|
327 p[2] = 0x01; // --|
328 p[3] = 0x37; // --^
329 p[4] = bVendorType; // Vendor type
330 p[5] = static_cast<BYTE>(dwLengthNew - 4); // Vendor length
331 p[6] = 0x00; // Salt
332 p[7] = 0x00; // --^
333 p[8] = nKeySize; // Key-Length
334 #pragma warning(pop)
335 memcpy(p + 9, pbKey, nKeySize); // Key
336 memset(p + 9 + nKeySize, 0, nPaddingLength); // Padding
337
338 if (pValue)
339 delete [] pValue;
340
341 #pragma warning(suppress: 26812) // EAP_ATTRIBUTE_TYPE is unscoped.
342 eaType = eatVendorSpecific;
343 dwLength = dwLengthNew;
344 pValue = p;
345 }
346 };
347 #pragma warning(pop)
348
352 static const EAP_ATTRIBUTE blank_eap_attr = {};
353
357 class eap_method_prop : public EAP_METHOD_PROPERTY
358 {
359 public:
366 eap_method_prop(_In_ EAP_METHOD_PROPERTY_TYPE type, _In_ BOOL value) noexcept
367 {
368 eapMethodPropertyType = type;
369 eapMethodPropertyValueType = empvtBool;
370 eapMethodPropertyValue.empvBool.length = sizeof(BOOL);
371 eapMethodPropertyValue.empvBool.value = value;
372 }
373
380 eap_method_prop(_In_ EAP_METHOD_PROPERTY_TYPE type, _In_ DWORD value) noexcept
381 {
382 eapMethodPropertyType = type;
383 eapMethodPropertyValueType = empvtDword;
384 eapMethodPropertyValue.empvDword.length = sizeof(DWORD);
385 eapMethodPropertyValue.empvDword.value = value;
386 }
387
394 eap_method_prop(_In_ EAP_METHOD_PROPERTY_TYPE type, _In_z_ LPCWSTR value) noexcept
395 {
396 eapMethodPropertyType = type;
397 eapMethodPropertyValueType = empvtString;
398 eapMethodPropertyValue.empvString.length = static_cast<DWORD>(sizeof(WCHAR)*(wcslen(value) + 1));
399 eapMethodPropertyValue.empvString.value = const_cast<BYTE*>(reinterpret_cast<const BYTE*>(value));
400 }
401 };
402
406 class eap_packet : public dplhandle<EapPacket*, NULL>
407 {
408 WINSTD_DPLHANDLE_IMPL(eap_packet, EapPacket*, NULL)
409
410 public:
414 virtual ~eap_packet()
415 {
416 if (m_h != invalid)
418 }
419
433 bool create(_In_ EapCode code, _In_ BYTE id, _In_ WORD size) noexcept
434 {
435 assert(size >= 4); // EAP packets must contain at least Code, Id, and Length fields: 4B.
436
437 handle_type h = static_cast<handle_type>(HeapAlloc(GetProcessHeap(), 0, size));
438 if (h != NULL) {
439 h->Code = static_cast<BYTE>(code);
440 h->Id = id;
441 *reinterpret_cast<WORD*>(h->Length) = htons(size);
442
443 attach(h);
444 return true;
445 } else {
446 SetLastError(ERROR_OUTOFMEMORY);
447 return false;
448 }
449 }
450
454 WORD size() const noexcept
455 {
456 return m_h != NULL ? ntohs(*(WORD*)m_h->Length) : 0;
457 }
458
459 protected:
463 void free_internal() noexcept override
464 {
465 HeapFree(GetProcessHeap(), 0, m_h);
466 }
467
472 {
473 assert(h);
474 const WORD n = ntohs(*reinterpret_cast<WORD*>(h->Length));
475 handle_type h2 = static_cast<handle_type>(HeapAlloc(GetProcessHeap(), 0, n));
476 if (h2 != invalid) {
477 _Analysis_assume_(h2 != NULL); // VS2022 can't figure out `invalid` is `NULL`
478 memcpy(h2, h, n);
479 return h2;
480 }
481 throw std::bad_alloc();
482 }
483 };
484
488 class eap_method_info_array : public EAP_METHOD_INFO_ARRAY
489 {
491
492 public:
497 {
498 dwNumberOfMethods = 0;
499 pEapMethods = NULL;
500 }
501
508 {
509 dwNumberOfMethods = other.dwNumberOfMethods;
510 pEapMethods = other.pEapMethods;
511 other.dwNumberOfMethods = 0;
512 other.pEapMethods = NULL;
513 }
514
519 {
520 if (pEapMethods)
521 free_internal();
522 }
523
530 {
531 if (this != std::addressof(other)) {
532 if (pEapMethods)
533 free_internal();
534 dwNumberOfMethods = other.dwNumberOfMethods;
535 pEapMethods = other.pEapMethods;
536 other.dwNumberOfMethods = 0;
537 other.pEapMethods = NULL;
538 }
539 return *this;
540 }
541
542 protected:
544
545 void free_internal() noexcept
546 {
547 for (DWORD i = 0; i < dwNumberOfMethods; i++)
548 free_internal(pEapMethods + i);
549
550 EapHostPeerFreeMemory(reinterpret_cast<BYTE*>(pEapMethods));
551 }
552
553 static void free_internal(_In_ EAP_METHOD_INFO *pMethodInfo) noexcept
554 {
555 if (pMethodInfo->pInnerMethodInfo)
556 free_internal(pMethodInfo->pInnerMethodInfo);
557
558 EapHostPeerFreeMemory(reinterpret_cast<BYTE*>(pMethodInfo->pwszAuthorName));
559 EapHostPeerFreeMemory(reinterpret_cast<BYTE*>(pMethodInfo->pwszFriendlyName));
560 }
561
563 };
564
566
569
576 {
577 public:
584 eap_runtime_error(_In_ const EAP_ERROR &err, _In_ const std::string& msg) :
585 m_type (err.type ),
586 m_reason (err.dwReasonCode ),
587 m_root_cause_id (err.rootCauseGuid ),
588 m_root_cause_desc(err.pRootCauseString ),
589 m_repair_id (err.repairGuid ),
590 m_repair_desc (err.pRepairString ),
591 m_help_link_id (err.helpLinkGuid ),
592 win_runtime_error(err.dwWinError, msg.c_str())
593 {}
594
600 eap_runtime_error(_In_ const EAP_ERROR &err) :
601 m_type (err.type ),
602 m_reason (err.dwReasonCode ),
603 m_root_cause_id (err.rootCauseGuid ),
604 m_root_cause_desc(err.pRootCauseString),
605 m_repair_id (err.repairGuid ),
606 m_repair_desc (err.pRepairString ),
607 m_help_link_id (err.helpLinkGuid ),
608 win_runtime_error(err.dwWinError )
609 {}
610
617 eap_runtime_error(_In_ const EAP_ERROR &err, _In_z_ const char *msg) :
618 m_type (err.type ),
619 m_reason (err.dwReasonCode ),
620 m_root_cause_id (err.rootCauseGuid ),
621 m_root_cause_desc(err.pRootCauseString),
622 m_repair_id (err.repairGuid ),
623 m_repair_desc (err.pRepairString ),
624 m_help_link_id (err.helpLinkGuid ),
625 win_runtime_error(err.dwWinError, msg )
626 {}
627
631 const EAP_METHOD_TYPE& type() const noexcept
632 {
633 return m_type;
634 }
635
639 DWORD reason() const noexcept
640 {
641 return m_reason;
642 }
643
647 const GUID& root_cause_id() const noexcept
648 {
649 return m_root_cause_id;
650 }
651
655 const wchar_t* root_cause() const noexcept
656 {
657 return m_root_cause_desc.c_str();
658 }
659
663 const GUID& repair_id() const noexcept
664 {
665 return m_repair_id;
666 }
667
671 const wchar_t* repair() const noexcept
672 {
673 return m_repair_desc.c_str();
674 }
675
679 const GUID& help_link_id() const noexcept
680 {
681 return m_help_link_id;
682 }
683
684 protected:
685 EAP_METHOD_TYPE m_type;
686
687 DWORD m_reason;
688
690 std::wstring m_root_cause_desc;
691
693 std::wstring m_repair_desc;
694
696 };
697
699}
700
701#pragma warning(pop)
Base abstract template class to support object handle keeping for objects that support trivial handle...
Definition Common.h:1137
EAP_ATTRIBUTE wrapper class.
Definition EAP.h:213
eap_attr() noexcept
Initializes a new EAP attribute set to eatReserved.
Definition EAP.h:218
eap_attr(eap_attr &&a) noexcept
Moves an existing EAP attribute.
Definition EAP.h:242
~eap_attr()
Destroys the EAP attribute.
Definition EAP.h:257
eap_attr & operator=(eap_attr &&a) noexcept
Moves an existing EAP attribute.
Definition EAP.h:286
eap_attr(const EAP_ATTRIBUTE &a)
Copies an existing EAP attribute.
Definition EAP.h:228
void create_ms_mppe_key(BYTE bVendorType, LPCBYTE pbKey, BYTE nKeySize)
Creates MS-MPPE-Send-Key or MS-MPPE-Recv-Key.
Definition EAP.h:310
eap_attr & operator=(const EAP_ATTRIBUTE &a)
Copies an existing EAP attribute.
Definition EAP.h:266
EAP_METHOD_INFO_ARRAY wrapper class.
Definition EAP.h:489
eap_method_info_array(eap_method_info_array &&other) noexcept
Move constructor.
Definition EAP.h:507
eap_method_info_array() noexcept
Constructs an empty array.
Definition EAP.h:496
~eap_method_info_array()
Destructor.
Definition EAP.h:518
eap_method_info_array & operator=(eap_method_info_array &&other) noexcept
Move assignment.
Definition EAP.h:529
EAP_METHOD_PROPERTY wrapper class.
Definition EAP.h:358
eap_method_prop(EAP_METHOD_PROPERTY_TYPE type, BOOL value) noexcept
Constructs a BOOL method property.
Definition EAP.h:366
eap_method_prop(EAP_METHOD_PROPERTY_TYPE type, DWORD value) noexcept
Constructs a DWORD method property.
Definition EAP.h:380
eap_method_prop(EAP_METHOD_PROPERTY_TYPE type, LPCWSTR value) noexcept
Constructs a Unicode string method property.
Definition EAP.h:394
EapPacket wrapper class.
Definition EAP.h:407
WORD size() const noexcept
Returns total EAP packet size in bytes.
Definition EAP.h:454
virtual ~eap_packet()
Destroys the EAP packet.
Definition EAP.h:414
void free_internal() noexcept override
Destroys the EAP packet.
Definition EAP.h:463
bool create(EapCode code, BYTE id, WORD size) noexcept
Create new EAP packet.
Definition EAP.h:433
handle_type duplicate_internal(handle_type h) const override
Duplicates the EAP packet.
Definition EAP.h:471
EapHost runtime error.
Definition EAP.h:576
const EAP_METHOD_TYPE & type() const noexcept
Returns EAP method type.
Definition EAP.h:631
GUID m_root_cause_id
A unique ID that identifies cause of error in EAPHost.
Definition EAP.h:689
const wchar_t * root_cause() const noexcept
Returns root cause ID.
Definition EAP.h:655
const GUID & repair_id() const noexcept
Returns repair ID.
Definition EAP.h:663
eap_runtime_error(const EAP_ERROR &err)
Constructs an exception.
Definition EAP.h:600
std::wstring m_repair_desc
A localized and readable string that describes the possible repair action.
Definition EAP.h:693
DWORD reason() const noexcept
Returns the reason code for error.
Definition EAP.h:639
EAP_METHOD_TYPE m_type
Structure that identifies the EAP method that raised the error.
Definition EAP.h:685
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:692
eap_runtime_error(const EAP_ERROR &err, const std::string &msg)
Constructs an exception.
Definition EAP.h:584
const wchar_t * repair() const noexcept
Returns root cause ID.
Definition EAP.h:671
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:695
eap_runtime_error(const EAP_ERROR &err, const char *msg)
Constructs an exception.
Definition EAP.h:617
const GUID & root_cause_id() const noexcept
Returns root cause ID.
Definition EAP.h:647
std::wstring m_root_cause_desc
A localized and readable string that describes the root cause of the error.
Definition EAP.h:690
const GUID & help_link_id() const noexcept
Returns help_link ID.
Definition EAP.h:679
DWORD m_reason
The reason code for the error.
Definition EAP.h:687
handle_type m_h
Definition Common.h:1126
void attach(handle_type h) noexcept
Definition Common.h:1089
EapPacket * handle_type
Definition Common.h:879
Windows runtime error.
Definition Common.h:1403
std::unique_ptr< EAP_ERROR, EapHostPeerFreeEapError_delete > eap_error_runtime
EAP_ERROR wrapper class.
Definition EAP.h:205
std::unique_ptr< BYTE[], EapHostPeerFreeMemory_delete > eap_blob
EapHost BLOB wrapper class.
Definition EAP.h:128
static bool operator==(const EAP_METHOD_TYPE &a, const EAP_METHOD_TYPE &b) noexcept
Are EAP method types equal?
Definition EAP.h:39
eap_type_t
EAP method numbers.
Definition EAP.h:78
std::unique_ptr< EAP_ERROR, EapHostPeerFreeErrorMemory_delete > eap_error
EAP_ERROR wrapper class.
Definition EAP.h:179
std::unique_ptr< BYTE[], EapHostPeerFreeRuntimeMemory_delete > eap_blob_runtime
EapHost BLOB wrapper class.
Definition EAP.h:153
static bool operator!=(const EAP_METHOD_TYPE &a, const EAP_METHOD_TYPE &b) noexcept
Are EAP method types non-equal?
Definition EAP.h:58
static const EAP_ATTRIBUTE blank_eap_attr
Blank EAP attribute.
Definition EAP.h:352
@ 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:67
#define WINSTD_DPLHANDLE_IMPL(C, T, INVAL)
Implements default constructors and operators to prevent their auto-generation by compiler.
Definition Common.h:176
static const EapPacket * invalid
Definition Common.h:884
Deleter for unique_ptr to EAP_ERROR using EapHostPeerFreeEapError.
Definition EAP.h:185
EapHostPeerFreeEapError_delete() noexcept
Default constructor.
Definition EAP.h:189
void operator()(EAP_ERROR *_Ptr) const noexcept
Delete a pointer.
Definition EAP.h:196
Deleter for unique_ptr to EAP_ERROR using EapHostPeerFreeErrorMemory.
Definition EAP.h:159
EapHostPeerFreeErrorMemory_delete() noexcept
Default constructor.
Definition EAP.h:163
void operator()(EAP_ERROR *_Ptr) const noexcept
Delete a pointer.
Definition EAP.h:170
Deleter for unique_ptr using EapHostPeerFreeMemory.
Definition EAP.h:107
void operator()(_T *_Ptr) const
Delete a pointer.
Definition EAP.h:119
EapHostPeerFreeMemory_delete() noexcept
Default constructor.
Definition EAP.h:111
Deleter for unique_ptr using EapHostPeerFreeRuntimeMemory.
Definition EAP.h:134
void operator()(_T *_Ptr) const
Delete a pointer.
Definition EAP.h:144
EapHostPeerFreeRuntimeMemory_delete() noexcept
Default constructor.
Definition EAP.h:138