WinStd
Windows Win32 API using Standard C++
Loading...
Searching...
No Matches
EAP.h
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 1991-2022 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 assert(pValue);
235 memcpy(pValue, a.pValue, a.dwLength);
236 } else
237 pValue = NULL;
238 }
239
243 eap_attr(_Inout_ eap_attr &&a) noexcept
244 {
245 eaType = a.eaType;
246 dwLength = a.dwLength;
247 if (a.dwLength) {
248 pValue = a.pValue;
249 a.dwLength = 0;
250 a.pValue = NULL;
251 } else
252 pValue = NULL;
253 }
254
259 {
260 if (pValue)
261 delete [] pValue;
262 }
263
267 eap_attr& operator=(_In_ const EAP_ATTRIBUTE &a)
268 {
269 if (this != &a) {
270 eaType = a.eaType;
271 dwLength = a.dwLength;
272 if (a.dwLength) {
273 BYTE *pValueNew = new BYTE[a.dwLength];
274 if (pValueNew) {
275 if (pValue)
276 delete [] pValue;
277 memcpy(pValueNew, a.pValue, a.dwLength);
278 pValue = pValueNew;
279 } else
280 assert(0); // Could not allocate memory
281 } else
282 pValue = NULL;
283 }
284 return *this;
285 }
286
290 eap_attr& operator=(_Inout_ eap_attr &&a) noexcept
291 {
292 if (this != &a) {
293 eaType = a.eaType;
294 dwLength = a.dwLength;
295 if (pValue)
296 delete [] pValue;
297 if (a.dwLength) {
298 pValue = a.pValue;
299 a.dwLength = 0;
300 a.pValue = NULL;
301 } else
302 pValue = NULL;
303 }
304 return *this;
305 }
306
314 void create_ms_mppe_key(_In_ BYTE bVendorType, _In_count_(nKeySize) LPCBYTE pbKey, _In_ BYTE nKeySize)
315 {
316 const BYTE nPaddingLength = static_cast<BYTE>((16 - (1 + static_cast<DWORD>(nKeySize))) % 16);
317 const DWORD dwLengthNew =
318 4 + // Vendor-Id
319 1 + // Vendor type
320 1 + // Vendor length
321 2 + // Salt
322 1 + // Key-Length
323 nKeySize + // Key
324 nPaddingLength; // Padding
325
326 #pragma warning(push)
327 #pragma warning(disable: 6386)
328 LPBYTE p = new BYTE[dwLengthNew];
329 p[0] = 0x00; // Vendor-Id (0x137 = 311 = Microsoft)
330 p[1] = 0x00; // --|
331 p[2] = 0x01; // --|
332 p[3] = 0x37; // --^
333 p[4] = bVendorType; // Vendor type
334 p[5] = static_cast<BYTE>(dwLengthNew - 4); // Vendor length
335 p[6] = 0x00; // Salt
336 p[7] = 0x00; // --^
337 p[8] = nKeySize; // Key-Length
338 #pragma warning(pop)
339 memcpy(p + 9, pbKey, nKeySize); // Key
340 memset(p + 9 + nKeySize, 0, nPaddingLength); // Padding
341
342 if (pValue)
343 delete [] pValue;
344
345 #pragma warning(suppress: 26812) // EAP_ATTRIBUTE_TYPE is unscoped.
346 eaType = eatVendorSpecific;
347 dwLength = dwLengthNew;
348 pValue = p;
349 }
350 };
351 #pragma warning(pop)
352
356 static const EAP_ATTRIBUTE blank_eap_attr = {};
357
361 class eap_method_prop : public EAP_METHOD_PROPERTY
362 {
363 public:
370 eap_method_prop(_In_ EAP_METHOD_PROPERTY_TYPE type, _In_ BOOL value) noexcept
371 {
372 eapMethodPropertyType = type;
373 eapMethodPropertyValueType = empvtBool;
374 eapMethodPropertyValue.empvBool.length = sizeof(BOOL);
375 eapMethodPropertyValue.empvBool.value = value;
376 }
377
384 eap_method_prop(_In_ EAP_METHOD_PROPERTY_TYPE type, _In_ DWORD value) noexcept
385 {
386 eapMethodPropertyType = type;
387 eapMethodPropertyValueType = empvtDword;
388 eapMethodPropertyValue.empvDword.length = sizeof(DWORD);
389 eapMethodPropertyValue.empvDword.value = value;
390 }
391
398 eap_method_prop(_In_ EAP_METHOD_PROPERTY_TYPE type, _In_z_ LPCWSTR value) noexcept
399 {
400 eapMethodPropertyType = type;
401 eapMethodPropertyValueType = empvtString;
402 eapMethodPropertyValue.empvString.length = static_cast<DWORD>(sizeof(WCHAR)*(wcslen(value) + 1));
403 eapMethodPropertyValue.empvString.value = const_cast<BYTE*>(reinterpret_cast<const BYTE*>(value));
404 }
405 };
406
410 class eap_packet : public dplhandle<EapPacket*, NULL>
411 {
413
414 public:
418 virtual ~eap_packet()
419 {
420 if (m_h != invalid)
422 }
423
437 bool create(_In_ EapCode code, _In_ BYTE id, _In_ WORD size) noexcept
438 {
439 assert(size >= 4); // EAP packets must contain at least Code, Id, and Length fields: 4B.
440
441 handle_type h = static_cast<handle_type>(HeapAlloc(GetProcessHeap(), 0, size));
442 if (h != NULL) {
443 h->Code = static_cast<BYTE>(code);
444 h->Id = id;
445 *reinterpret_cast<WORD*>(h->Length) = htons(size);
446
447 attach(h);
448 return true;
449 } else {
450 SetLastError(ERROR_OUTOFMEMORY);
451 return false;
452 }
453 }
454
458 WORD size() const noexcept
459 {
460 return m_h != NULL ? ntohs(*(WORD*)m_h->Length) : 0;
461 }
462
463 protected:
467 void free_internal() noexcept override
468 {
469 HeapFree(GetProcessHeap(), 0, m_h);
470 }
471
475 handle_type duplicate_internal(_In_ handle_type h) const noexcept override
476 {
477 const WORD n = ntohs(*reinterpret_cast<WORD*>(h->Length));
478 handle_type h2 = static_cast<handle_type>(HeapAlloc(GetProcessHeap(), 0, n));
479 if (h2 == NULL) {
480 SetLastError(ERROR_OUTOFMEMORY);
481 return NULL;
482 }
483 memcpy(h2, h, n);
484 return h2;
485 }
486 };
487
491 class eap_method_info_array : public EAP_METHOD_INFO_ARRAY
492 {
494
495 public:
500 {
501 dwNumberOfMethods = 0;
502 pEapMethods = NULL;
503 }
504
511 {
512 dwNumberOfMethods = other.dwNumberOfMethods;
513 pEapMethods = other.pEapMethods;
514 other.dwNumberOfMethods = 0;
515 other.pEapMethods = NULL;
516 }
517
522 {
523 if (pEapMethods)
524 free_internal();
525 }
526
533 {
534 if (this != std::addressof(other)) {
535 if (pEapMethods)
536 free_internal();
537 dwNumberOfMethods = other.dwNumberOfMethods;
538 pEapMethods = other.pEapMethods;
539 other.dwNumberOfMethods = 0;
540 other.pEapMethods = NULL;
541 }
542 return *this;
543 }
544
545 protected:
547
548 void free_internal() noexcept
549 {
550 for (DWORD i = 0; i < dwNumberOfMethods; i++)
551 free_internal(pEapMethods + i);
552
553 EapHostPeerFreeMemory(reinterpret_cast<BYTE*>(pEapMethods));
554 }
555
556 static void free_internal(_In_ EAP_METHOD_INFO *pMethodInfo) noexcept
557 {
558 if (pMethodInfo->pInnerMethodInfo)
559 free_internal(pMethodInfo->pInnerMethodInfo);
560
561 EapHostPeerFreeMemory(reinterpret_cast<BYTE*>(pMethodInfo->pwszAuthorName));
562 EapHostPeerFreeMemory(reinterpret_cast<BYTE*>(pMethodInfo->pwszFriendlyName));
563 }
564
566 };
567
569
572
579 {
580 public:
587 eap_runtime_error(_In_ const EAP_ERROR &err, _In_ const std::string& msg) :
588 m_type (err.type ),
589 m_reason (err.dwReasonCode ),
590 m_root_cause_id (err.rootCauseGuid ),
591 m_root_cause_desc(err.pRootCauseString ),
592 m_repair_id (err.repairGuid ),
593 m_repair_desc (err.pRepairString ),
594 m_help_link_id (err.helpLinkGuid ),
595 win_runtime_error(err.dwWinError, msg.c_str())
596 {
597 }
598
605 eap_runtime_error(_In_ const EAP_ERROR &err, _In_opt_z_ const char *msg = nullptr) :
606 m_type (err.type ),
607 m_reason (err.dwReasonCode ),
608 m_root_cause_id (err.rootCauseGuid ),
609 m_root_cause_desc(err.pRootCauseString),
610 m_repair_id (err.repairGuid ),
611 m_repair_desc (err.pRepairString ),
612 m_help_link_id (err.helpLinkGuid ),
613 win_runtime_error(err.dwWinError, msg )
614 {
615 }
616
620 const EAP_METHOD_TYPE& type() const noexcept
621 {
622 return m_type;
623 }
624
628 DWORD reason() const noexcept
629 {
630 return m_reason;
631 }
632
636 const GUID& root_cause_id() const noexcept
637 {
638 return m_root_cause_id;
639 }
640
644 const wchar_t* root_cause() const noexcept
645 {
646 return m_root_cause_desc.c_str();
647 }
648
652 const GUID& repair_id() const noexcept
653 {
654 return m_repair_id;
655 }
656
660 const wchar_t* repair() const noexcept
661 {
662 return m_repair_desc.c_str();
663 }
664
668 const GUID& help_link_id() const noexcept
669 {
670 return m_help_link_id;
671 }
672
673 protected:
674 EAP_METHOD_TYPE m_type;
675
676 DWORD m_reason;
677
679 std::wstring m_root_cause_desc;
680
682 std::wstring m_repair_desc;
683
685 };
686
688}
689
690#pragma warning(pop)
Base abstract template class to support object handle keeping for objects that support trivial handle...
Definition: Common.h:834
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:243
~eap_attr()
Destroys the EAP attribute.
Definition: EAP.h:258
eap_attr & operator=(eap_attr &&a) noexcept
Moves an existing EAP attribute.
Definition: EAP.h:290
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:314
eap_attr & operator=(const EAP_ATTRIBUTE &a)
Copies an existing EAP attribute.
Definition: EAP.h:267
EAP_METHOD_INFO_ARRAY wrapper class.
Definition: EAP.h:492
eap_method_info_array(eap_method_info_array &&other) noexcept
Move constructor.
Definition: EAP.h:510
eap_method_info_array() noexcept
Constructs an empty array.
Definition: EAP.h:499
~eap_method_info_array()
Destructor.
Definition: EAP.h:521
eap_method_info_array & operator=(eap_method_info_array &&other) noexcept
Move assignment.
Definition: EAP.h:532
EAP_METHOD_PROPERTY wrapper class.
Definition: EAP.h:362
eap_method_prop(EAP_METHOD_PROPERTY_TYPE type, BOOL value) noexcept
Constructs a BOOL method property.
Definition: EAP.h:370
eap_method_prop(EAP_METHOD_PROPERTY_TYPE type, DWORD value) noexcept
Constructs a DWORD method property.
Definition: EAP.h:384
eap_method_prop(EAP_METHOD_PROPERTY_TYPE type, LPCWSTR value) noexcept
Constructs a Unicode string method property.
Definition: EAP.h:398
EapPacket wrapper class.
Definition: EAP.h:411
WORD size() const noexcept
Returns total EAP packet size in bytes.
Definition: EAP.h:458
handle_type duplicate_internal(handle_type h) const noexcept override
Duplicates the EAP packet.
Definition: EAP.h:475
virtual ~eap_packet()
Destroys the EAP packet.
Definition: EAP.h:418
void free_internal() noexcept override
Destroys the EAP packet.
Definition: EAP.h:467
bool create(EapCode code, BYTE id, WORD size) noexcept
Create new EAP packet.
Definition: EAP.h:437
EapHost runtime error.
Definition: EAP.h:579
const EAP_METHOD_TYPE & type() const noexcept
Returns EAP method type.
Definition: EAP.h:620
GUID m_root_cause_id
A unique ID that identifies cause of error in EAPHost.
Definition: EAP.h:678
const wchar_t * root_cause() const noexcept
Returns root cause ID.
Definition: EAP.h:644
const GUID & repair_id() const noexcept
Returns repair ID.
Definition: EAP.h:652
std::wstring m_repair_desc
A localized and readable string that describes the possible repair action.
Definition: EAP.h:682
DWORD reason() const noexcept
Returns the reason code for error.
Definition: EAP.h:628
EAP_METHOD_TYPE m_type
Structure that identifies the EAP method that raised the error.
Definition: EAP.h:674
eap_runtime_error(const EAP_ERROR &err, const char *msg=nullptr)
Constructs an exception.
Definition: EAP.h:605
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:681
eap_runtime_error(const EAP_ERROR &err, const std::string &msg)
Constructs an exception.
Definition: EAP.h:587
const wchar_t * repair() const noexcept
Returns root cause ID.
Definition: EAP.h:660
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:684
const GUID & root_cause_id() const noexcept
Returns root cause ID.
Definition: EAP.h:636
std::wstring m_root_cause_desc
A localized and readable string that describes the root cause of the error.
Definition: EAP.h:679
const GUID & help_link_id() const noexcept
Returns help_link ID.
Definition: EAP.h:668
DWORD m_reason
The reason code for the error.
Definition: EAP.h:676
T handle_type
Datatype of the object handle this template class handles.
Definition: Common.h:574
handle_type m_h
Object handle.
Definition: Common.h:823
void attach(handle_type h) noexcept
Sets a new object handle for the class.
Definition: Common.h:786
Windows runtime error.
Definition: Common.h:1013
tstring msg(DWORD dwLanguageId=0) const
Returns a user-readable Windows error message.
Definition: Common.h:1058
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:356
@ 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:66
#define WINSTD_DPLHANDLE_IMPL(C, INVAL)
Implements default constructors and operators to prevent their auto-generation by compiler.
Definition: Common.h:175
static const T invalid
Invalid handle value.
Definition: Common.h:579
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