WinStd
Additional templates and function helpers for Microsoft Windows using Standard C++ classes
EAP.h
Go to the documentation of this file.
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 1991-2022 Amebis
4 Copyright © 2016 GÉANT
5*/
6
12
13#pragma once
14
15#include "Common.h"
16#include <eaphostpeerconfigapis.h>
17#include <eaptypes.h>
18#include <EapHostPeerTypes.h>
19#include <eapmethodtypes.h>
20#include <eappapis.h>
21#include <WinSock2.h>
22#include <memory>
23
24#pragma warning(push)
25#pragma warning(disable: 26812) // Windows EAP API is using unscoped enums
26
27#pragma warning(push)
28#pragma warning(disable: 4505) // Don't warn on unused code
29
32
43static bool operator==(_In_ const EAP_METHOD_TYPE &a, _In_ const EAP_METHOD_TYPE &b) noexcept
44{
45 return
46 a.eapType.type == b.eapType.type &&
47 a.eapType.dwVendorId == b.eapType.dwVendorId &&
48 a.eapType.dwVendorType == b.eapType.dwVendorType &&
49 a.dwAuthorId == a.dwAuthorId;
50}
51
62static bool operator!=(_In_ const EAP_METHOD_TYPE &a, _In_ const EAP_METHOD_TYPE &b) noexcept
63{
64 return !operator==(a, b);
65}
66
68
69#pragma warning(pop)
70
71namespace winstd
72{
75
81 #pragma warning(suppress: 4480)
82 enum class eap_type_t : unsigned char {
83 undefined = 0,
84 identity = 1,
85 notification = 2,
86 nak = 3,
87 md5_challenge = 4,
88 otp = 5,
89 gtc = 6,
90 tls = 13,
91 ttls = 21,
92 peap = 25,
93 mschapv2 = 26,
94 ms_auth_tlv = 33,
95
96 gtcp = 128 + gtc,
97
98 legacy_pap = 192,
99 legacy_mschapv2 = 193,
100
101 start = 1,
102 end = 192,
103 noneap_start = 192,
104 noneap_end = 254,
105 };
106
111 {
116
122 template <class _T>
123 void operator()(_T *_Ptr) const
124 {
125 EapHostPeerFreeMemory((BYTE*)_Ptr);
126 }
127 };
128
132 typedef std::unique_ptr<BYTE[], EapHostPeerFreeMemory_delete> eap_blob;
133
138 {
143
147 template <class _T>
148 void operator()(_T *_Ptr) const
149 {
150 EapHostPeerFreeRuntimeMemory((BYTE*)_Ptr);
151 }
152 };
153
157 typedef std::unique_ptr<BYTE[], EapHostPeerFreeRuntimeMemory_delete> eap_blob_runtime;
158
163 {
168
174 void operator()(EAP_ERROR *_Ptr) const noexcept
175 {
176 EapHostPeerFreeErrorMemory(_Ptr);
177 }
178 };
179
183 typedef std::unique_ptr<EAP_ERROR, EapHostPeerFreeErrorMemory_delete> eap_error;
184
189 {
194
200 void operator()(EAP_ERROR *_Ptr) const noexcept
201 {
202 EapHostPeerFreeEapError(_Ptr);
203 }
204 };
205
209 typedef std::unique_ptr<EAP_ERROR, EapHostPeerFreeEapError_delete> eap_error_runtime;
210
214 #pragma warning(push)
215 #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.
216 class eap_attr : public EAP_ATTRIBUTE
217 {
218 public:
222 eap_attr() noexcept
223 {
224 eaType = eatReserved;
225 dwLength = 0;
226 pValue = NULL;
227 }
228
232 eap_attr(_In_ const EAP_ATTRIBUTE &a)
233 {
234 eaType = a.eaType;
235 dwLength = a.dwLength;
236 if (a.dwLength) {
237 pValue = new BYTE[a.dwLength];
238 assert(pValue);
239 memcpy(pValue, a.pValue, a.dwLength);
240 } else
241 pValue = NULL;
242 }
243
247 eap_attr(_Inout_ eap_attr &&a) noexcept
248 {
249 eaType = a.eaType;
250 dwLength = a.dwLength;
251 if (a.dwLength) {
252 pValue = a.pValue;
253 a.dwLength = 0;
254 a.pValue = NULL;
255 } else
256 pValue = NULL;
257 }
258
263 {
264 if (pValue)
265 delete [] pValue;
266 }
267
271 eap_attr& operator=(_In_ const EAP_ATTRIBUTE &a)
272 {
273 if (this != &a) {
274 eaType = a.eaType;
275 dwLength = a.dwLength;
276 if (a.dwLength) {
277 BYTE *pValueNew = new BYTE[a.dwLength];
278 if (pValueNew) {
279 if (pValue)
280 delete [] pValue;
281 memcpy(pValueNew, a.pValue, a.dwLength);
282 pValue = pValueNew;
283 } else
284 assert(0); // Could not allocate memory
285 } else
286 pValue = NULL;
287 }
288 return *this;
289 }
290
294 eap_attr& operator=(_Inout_ eap_attr &&a) noexcept
295 {
296 if (this != &a) {
297 eaType = a.eaType;
298 dwLength = a.dwLength;
299 if (pValue)
300 delete [] pValue;
301 if (a.dwLength) {
302 pValue = a.pValue;
303 a.dwLength = 0;
304 a.pValue = NULL;
305 } else
306 pValue = NULL;
307 }
308 return *this;
309 }
310
318 void create_ms_mppe_key(_In_ BYTE bVendorType, _In_count_(nKeySize) LPCBYTE pbKey, _In_ BYTE nKeySize)
319 {
320 const BYTE nPaddingLength = static_cast<BYTE>((16 - (1 + static_cast<DWORD>(nKeySize))) % 16);
321 const DWORD dwLengthNew =
322 4 + // Vendor-Id
323 1 + // Vendor type
324 1 + // Vendor length
325 2 + // Salt
326 1 + // Key-Length
327 nKeySize + // Key
328 nPaddingLength; // Padding
329
330 #pragma warning(push)
331 #pragma warning(disable: 6386)
332 LPBYTE p = new BYTE[dwLengthNew];
333 p[0] = 0x00; // Vendor-Id (0x137 = 311 = Microsoft)
334 p[1] = 0x00; // --|
335 p[2] = 0x01; // --|
336 p[3] = 0x37; // --^
337 p[4] = bVendorType; // Vendor type
338 p[5] = static_cast<BYTE>(dwLengthNew - 4); // Vendor length
339 p[6] = 0x00; // Salt
340 p[7] = 0x00; // --^
341 p[8] = nKeySize; // Key-Length
342 #pragma warning(pop)
343 memcpy(p + 9, pbKey, nKeySize); // Key
344 memset(p + 9 + nKeySize, 0, nPaddingLength); // Padding
345
346 if (pValue)
347 delete [] pValue;
348
349 #pragma warning(suppress: 26812) // EAP_ATTRIBUTE_TYPE is unscoped.
350 eaType = eatVendorSpecific;
351 dwLength = dwLengthNew;
352 pValue = p;
353 }
354 };
355 #pragma warning(pop)
356
360 static const EAP_ATTRIBUTE blank_eap_attr = {};
361
365 class eap_method_prop : public EAP_METHOD_PROPERTY
366 {
367 public:
374 eap_method_prop(_In_ EAP_METHOD_PROPERTY_TYPE type, _In_ BOOL value) noexcept
375 {
376 eapMethodPropertyType = type;
377 eapMethodPropertyValueType = empvtBool;
378 eapMethodPropertyValue.empvBool.length = sizeof(BOOL);
379 eapMethodPropertyValue.empvBool.value = value;
380 }
381
388 eap_method_prop(_In_ EAP_METHOD_PROPERTY_TYPE type, _In_ DWORD value) noexcept
389 {
390 eapMethodPropertyType = type;
391 eapMethodPropertyValueType = empvtDword;
392 eapMethodPropertyValue.empvDword.length = sizeof(DWORD);
393 eapMethodPropertyValue.empvDword.value = value;
394 }
395
402 eap_method_prop(_In_ EAP_METHOD_PROPERTY_TYPE type, _In_z_ LPCWSTR value) noexcept
403 {
404 eapMethodPropertyType = type;
405 eapMethodPropertyValueType = empvtString;
406 eapMethodPropertyValue.empvString.length = static_cast<DWORD>(sizeof(WCHAR)*(wcslen(value) + 1));
407 eapMethodPropertyValue.empvString.value = const_cast<BYTE*>(reinterpret_cast<const BYTE*>(value));
408 }
409 };
410
414 class eap_packet : public dplhandle<EapPacket*, NULL>
415 {
417
418 public:
422 virtual ~eap_packet()
423 {
424 if (m_h != invalid)
426 }
427
441 bool create(_In_ EapCode code, _In_ BYTE id, _In_ WORD size) noexcept
442 {
443 assert(size >= 4); // EAP packets must contain at least Code, Id, and Length fields: 4B.
444
445 handle_type h = static_cast<handle_type>(HeapAlloc(GetProcessHeap(), 0, size));
446 if (h != NULL) {
447 h->Code = static_cast<BYTE>(code);
448 h->Id = id;
449 *reinterpret_cast<WORD*>(h->Length) = htons(size);
450
451 attach(h);
452 return true;
453 } else {
454 SetLastError(ERROR_OUTOFMEMORY);
455 return false;
456 }
457 }
458
462 WORD size() const noexcept
463 {
464 return m_h != NULL ? ntohs(*(WORD*)m_h->Length) : 0;
465 }
466
467 protected:
471 void free_internal() noexcept override
472 {
473 HeapFree(GetProcessHeap(), 0, m_h);
474 }
475
479 handle_type duplicate_internal(_In_ handle_type h) const noexcept override
480 {
481 const WORD n = ntohs(*reinterpret_cast<WORD*>(h->Length));
482 handle_type h2 = static_cast<handle_type>(HeapAlloc(GetProcessHeap(), 0, n));
483 if (h2 == NULL) {
484 SetLastError(ERROR_OUTOFMEMORY);
485 return NULL;
486 }
487 memcpy(h2, h, n);
488 return h2;
489 }
490 };
491
495 class eap_method_info_array : public EAP_METHOD_INFO_ARRAY
496 {
498
499 public:
504 {
505 dwNumberOfMethods = 0;
506 pEapMethods = NULL;
507 }
508
515 {
516 dwNumberOfMethods = other.dwNumberOfMethods;
517 pEapMethods = other.pEapMethods;
518 other.dwNumberOfMethods = 0;
519 other.pEapMethods = NULL;
520 }
521
526 {
527 if (pEapMethods)
528 free_internal();
529 }
530
537 {
538 if (this != std::addressof(other)) {
539 if (pEapMethods)
540 free_internal();
541 dwNumberOfMethods = other.dwNumberOfMethods;
542 pEapMethods = other.pEapMethods;
543 other.dwNumberOfMethods = 0;
544 other.pEapMethods = NULL;
545 }
546 return *this;
547 }
548
549 protected:
551
552 void free_internal() noexcept
553 {
554 for (DWORD i = 0; i < dwNumberOfMethods; i++)
555 free_internal(pEapMethods + i);
556
557 EapHostPeerFreeMemory(reinterpret_cast<BYTE*>(pEapMethods));
558 }
559
560 static void free_internal(_In_ EAP_METHOD_INFO *pMethodInfo) noexcept
561 {
562 if (pMethodInfo->pInnerMethodInfo)
563 free_internal(pMethodInfo->pInnerMethodInfo);
564
565 EapHostPeerFreeMemory(reinterpret_cast<BYTE*>(pMethodInfo->pwszAuthorName));
566 EapHostPeerFreeMemory(reinterpret_cast<BYTE*>(pMethodInfo->pwszFriendlyName));
567 }
568
570 };
571
573
576
583 {
584 public:
591 eap_runtime_error(_In_ const EAP_ERROR &err, _In_ const std::string& msg) :
592 m_type (err.type ),
593 m_reason (err.dwReasonCode ),
594 m_root_cause_id (err.rootCauseGuid ),
595 m_root_cause_desc(err.pRootCauseString ),
596 m_repair_id (err.repairGuid ),
597 m_repair_desc (err.pRepairString ),
598 m_help_link_id (err.helpLinkGuid ),
599 win_runtime_error(err.dwWinError, msg.c_str())
600 {
601 }
602
609 eap_runtime_error(_In_ const EAP_ERROR &err, _In_opt_z_ const char *msg = nullptr) :
610 m_type (err.type ),
611 m_reason (err.dwReasonCode ),
612 m_root_cause_id (err.rootCauseGuid ),
613 m_root_cause_desc(err.pRootCauseString),
614 m_repair_id (err.repairGuid ),
615 m_repair_desc (err.pRepairString ),
616 m_help_link_id (err.helpLinkGuid ),
617 win_runtime_error(err.dwWinError, msg )
618 {
619 }
620
624 const EAP_METHOD_TYPE& type() const noexcept
625 {
626 return m_type;
627 }
628
632 DWORD reason() const noexcept
633 {
634 return m_reason;
635 }
636
640 const GUID& root_cause_id() const noexcept
641 {
642 return m_root_cause_id;
643 }
644
648 const wchar_t* root_cause() const noexcept
649 {
650 return m_root_cause_desc.c_str();
651 }
652
656 const GUID& repair_id() const noexcept
657 {
658 return m_repair_id;
659 }
660
664 const wchar_t* repair() const noexcept
665 {
666 return m_repair_desc.c_str();
667 }
668
672 const GUID& help_link_id() const noexcept
673 {
674 return m_help_link_id;
675 }
676
677 protected:
678 EAP_METHOD_TYPE m_type;
679
680 DWORD m_reason;
681
683 std::wstring m_root_cause_desc;
684
686 std::wstring m_repair_desc;
687
689 };
690
692}
693
694#pragma warning(pop)
General API.
Integrates WinStd classes with Microsoft WinSock2 API.
Base abstract template class to support object handle keeping for objects that support trivial handle...
Definition: Common.h:877
EAP_ATTRIBUTE wrapper class.
Definition: EAP.h:217
eap_attr() noexcept
Initializes a new EAP attribute set to eatReserved.
Definition: EAP.h:222
eap_attr(eap_attr &&a) noexcept
Moves an existing EAP attribute.
Definition: EAP.h:247
~eap_attr()
Destroys the EAP attribute.
Definition: EAP.h:262
eap_attr & operator=(eap_attr &&a) noexcept
Moves an existing EAP attribute.
Definition: EAP.h:294
eap_attr(const EAP_ATTRIBUTE &a)
Copies an existing EAP attribute.
Definition: EAP.h:232
void create_ms_mppe_key(BYTE bVendorType, LPCBYTE pbKey, BYTE nKeySize)
Creates MS-MPPE-Send-Key or MS-MPPE-Recv-Key.
Definition: EAP.h:318
eap_attr & operator=(const EAP_ATTRIBUTE &a)
Copies an existing EAP attribute.
Definition: EAP.h:271
EAP_METHOD_INFO_ARRAY wrapper class.
Definition: EAP.h:496
eap_method_info_array(eap_method_info_array &&other) noexcept
Move constructor.
Definition: EAP.h:514
eap_method_info_array() noexcept
Constructs an empty array.
Definition: EAP.h:503
~eap_method_info_array()
Destructor.
Definition: EAP.h:525
eap_method_info_array & operator=(eap_method_info_array &&other) noexcept
Move assignment.
Definition: EAP.h:536
EAP_METHOD_PROPERTY wrapper class.
Definition: EAP.h:366
eap_method_prop(EAP_METHOD_PROPERTY_TYPE type, BOOL value) noexcept
Constructs a BOOL method property.
Definition: EAP.h:374
eap_method_prop(EAP_METHOD_PROPERTY_TYPE type, DWORD value) noexcept
Constructs a DWORD method property.
Definition: EAP.h:388
eap_method_prop(EAP_METHOD_PROPERTY_TYPE type, LPCWSTR value) noexcept
Constructs a Unicode string method property.
Definition: EAP.h:402
EapPacket wrapper class.
Definition: EAP.h:415
WORD size() const noexcept
Returns total EAP packet size in bytes.
Definition: EAP.h:462
handle_type duplicate_internal(handle_type h) const noexcept override
Duplicates the EAP packet.
Definition: EAP.h:479
virtual ~eap_packet()
Destroys the EAP packet.
Definition: EAP.h:422
void free_internal() noexcept override
Destroys the EAP packet.
Definition: EAP.h:471
bool create(EapCode code, BYTE id, WORD size) noexcept
Create new EAP packet.
Definition: EAP.h:441
EapHost runtime error.
Definition: EAP.h:583
const EAP_METHOD_TYPE & type() const noexcept
Returns EAP method type.
Definition: EAP.h:624
GUID m_root_cause_id
A unique ID that identifies cause of error in EAPHost.
Definition: EAP.h:682
const wchar_t * root_cause() const noexcept
Returns root cause ID.
Definition: EAP.h:648
const GUID & repair_id() const noexcept
Returns repair ID.
Definition: EAP.h:656
std::wstring m_repair_desc
A localized and readable string that describes the possible repair action.
Definition: EAP.h:686
DWORD reason() const noexcept
Returns the reason code for error.
Definition: EAP.h:632
EAP_METHOD_TYPE m_type
Structure that identifies the EAP method that raised the error.
Definition: EAP.h:678
eap_runtime_error(const EAP_ERROR &err, const char *msg=nullptr)
Constructs an exception.
Definition: EAP.h:609
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:685
eap_runtime_error(const EAP_ERROR &err, const std::string &msg)
Constructs an exception.
Definition: EAP.h:591
const wchar_t * repair() const noexcept
Returns root cause ID.
Definition: EAP.h:664
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:688
const GUID & root_cause_id() const noexcept
Returns root cause ID.
Definition: EAP.h:640
std::wstring m_root_cause_desc
A localized and readable string that describes the root cause of the error.
Definition: EAP.h:683
const GUID & help_link_id() const noexcept
Returns help_link ID.
Definition: EAP.h:672
DWORD m_reason
The reason code for the error.
Definition: EAP.h:680
EapPacket * handle_type
Datatype of the object handle this template class handles.
Definition: Common.h:620
handle_type m_h
Object handle.
Definition: Common.h:866
void attach(handle_type h) noexcept
Sets a new object handle for the class.
Definition: Common.h:829
Windows runtime error.
Definition: Common.h:1056
tstring msg(DWORD dwLanguageId=0) const
Returns a user-readable Windows error message.
Definition: Common.h:1101
std::unique_ptr< EAP_ERROR, EapHostPeerFreeEapError_delete > eap_error_runtime
EAP_ERROR wrapper class.
Definition: EAP.h:209
std::unique_ptr< BYTE[], EapHostPeerFreeMemory_delete > eap_blob
EapHost BLOB wrapper class.
Definition: EAP.h:132
static bool operator==(const EAP_METHOD_TYPE &a, const EAP_METHOD_TYPE &b) noexcept
Are EAP method types equal?
Definition: EAP.h:43
eap_type_t
EAP method numbers.
Definition: EAP.h:82
std::unique_ptr< EAP_ERROR, EapHostPeerFreeErrorMemory_delete > eap_error
EAP_ERROR wrapper class.
Definition: EAP.h:183
std::unique_ptr< BYTE[], EapHostPeerFreeRuntimeMemory_delete > eap_blob_runtime
EapHost BLOB wrapper class.
Definition: EAP.h:157
static bool operator!=(const EAP_METHOD_TYPE &a, const EAP_METHOD_TYPE &b) noexcept
Are EAP method types non-equal?
Definition: EAP.h:62
static const EAP_ATTRIBUTE blank_eap_attr
Blank EAP attribute.
Definition: EAP.h:360
@ 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:74
#define WINSTD_DPLHANDLE_IMPL(C, INVAL)
Implements default constructors and operators to prevent their auto-generation by compiler.
Definition: Common.h:183
static const EapPacket * invalid
Invalid handle value.
Definition: Common.h:625
Deleter for unique_ptr to EAP_ERROR using EapHostPeerFreeEapError.
Definition: EAP.h:189
EapHostPeerFreeEapError_delete() noexcept
Default constructor.
Definition: EAP.h:193
void operator()(EAP_ERROR *_Ptr) const noexcept
Delete a pointer.
Definition: EAP.h:200
Deleter for unique_ptr to EAP_ERROR using EapHostPeerFreeErrorMemory.
Definition: EAP.h:163
EapHostPeerFreeErrorMemory_delete() noexcept
Default constructor.
Definition: EAP.h:167
void operator()(EAP_ERROR *_Ptr) const noexcept
Delete a pointer.
Definition: EAP.h:174
Deleter for unique_ptr using EapHostPeerFreeMemory.
Definition: EAP.h:111
void operator()(_T *_Ptr) const
Delete a pointer.
Definition: EAP.h:123
EapHostPeerFreeMemory_delete() noexcept
Default constructor.
Definition: EAP.h:115
Deleter for unique_ptr using EapHostPeerFreeRuntimeMemory.
Definition: EAP.h:138
void operator()(_T *_Ptr) const
Delete a pointer.
Definition: EAP.h:148
EapHostPeerFreeRuntimeMemory_delete() noexcept
Default constructor.
Definition: EAP.h:142