WinStd
Windows Win32 API using Standard C++
Loading...
Searching...
No Matches
EAP.h
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 1991-2023 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 {
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 const WORD n = ntohs(*reinterpret_cast<WORD*>(h->Length));
474 handle_type h2 = static_cast<handle_type>(HeapAlloc(GetProcessHeap(), 0, n));
475 if (h2 != invalid) {
476 memcpy(h2, h, n);
477 return h2;
478 }
479 throw std::bad_alloc();
480 }
481 };
482
486 class eap_method_info_array : public EAP_METHOD_INFO_ARRAY
487 {
489
490 public:
495 {
496 dwNumberOfMethods = 0;
497 pEapMethods = NULL;
498 }
499
506 {
507 dwNumberOfMethods = other.dwNumberOfMethods;
508 pEapMethods = other.pEapMethods;
509 other.dwNumberOfMethods = 0;
510 other.pEapMethods = NULL;
511 }
512
517 {
518 if (pEapMethods)
519 free_internal();
520 }
521
528 {
529 if (this != std::addressof(other)) {
530 if (pEapMethods)
531 free_internal();
532 dwNumberOfMethods = other.dwNumberOfMethods;
533 pEapMethods = other.pEapMethods;
534 other.dwNumberOfMethods = 0;
535 other.pEapMethods = NULL;
536 }
537 return *this;
538 }
539
540 protected:
542
543 void free_internal() noexcept
544 {
545 for (DWORD i = 0; i < dwNumberOfMethods; i++)
546 free_internal(pEapMethods + i);
547
548 EapHostPeerFreeMemory(reinterpret_cast<BYTE*>(pEapMethods));
549 }
550
551 static void free_internal(_In_ EAP_METHOD_INFO *pMethodInfo) noexcept
552 {
553 if (pMethodInfo->pInnerMethodInfo)
554 free_internal(pMethodInfo->pInnerMethodInfo);
555
556 EapHostPeerFreeMemory(reinterpret_cast<BYTE*>(pMethodInfo->pwszAuthorName));
557 EapHostPeerFreeMemory(reinterpret_cast<BYTE*>(pMethodInfo->pwszFriendlyName));
558 }
559
561 };
562
564
567
574 {
575 public:
582 eap_runtime_error(_In_ const EAP_ERROR &err, _In_ const std::string& msg) :
583 m_type (err.type ),
584 m_reason (err.dwReasonCode ),
585 m_root_cause_id (err.rootCauseGuid ),
586 m_root_cause_desc(err.pRootCauseString ),
587 m_repair_id (err.repairGuid ),
588 m_repair_desc (err.pRepairString ),
589 m_help_link_id (err.helpLinkGuid ),
590 win_runtime_error(err.dwWinError, msg.c_str())
591 {
592 }
593
600 eap_runtime_error(_In_ const EAP_ERROR &err, _In_opt_z_ const char *msg = nullptr) :
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, msg )
609 {
610 }
611
615 const EAP_METHOD_TYPE& type() const noexcept
616 {
617 return m_type;
618 }
619
623 DWORD reason() const noexcept
624 {
625 return m_reason;
626 }
627
631 const GUID& root_cause_id() const noexcept
632 {
633 return m_root_cause_id;
634 }
635
639 const wchar_t* root_cause() const noexcept
640 {
641 return m_root_cause_desc.c_str();
642 }
643
647 const GUID& repair_id() const noexcept
648 {
649 return m_repair_id;
650 }
651
655 const wchar_t* repair() const noexcept
656 {
657 return m_repair_desc.c_str();
658 }
659
663 const GUID& help_link_id() const noexcept
664 {
665 return m_help_link_id;
666 }
667
668 protected:
669 EAP_METHOD_TYPE m_type;
670
671 DWORD m_reason;
672
674 std::wstring m_root_cause_desc;
675
677 std::wstring m_repair_desc;
678
680 };
681
683}
684
685#pragma warning(pop)
Base abstract template class to support object handle keeping for objects that support trivial handle...
Definition Common.h:900
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:487
eap_method_info_array(eap_method_info_array &&other) noexcept
Move constructor.
Definition EAP.h:505
eap_method_info_array() noexcept
Constructs an empty array.
Definition EAP.h:494
~eap_method_info_array()
Destructor.
Definition EAP.h:516
eap_method_info_array & operator=(eap_method_info_array &&other) noexcept
Move assignment.
Definition EAP.h:527
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:574
const EAP_METHOD_TYPE & type() const noexcept
Returns EAP method type.
Definition EAP.h:615
GUID m_root_cause_id
A unique ID that identifies cause of error in EAPHost.
Definition EAP.h:673
const wchar_t * root_cause() const noexcept
Returns root cause ID.
Definition EAP.h:639
const GUID & repair_id() const noexcept
Returns repair ID.
Definition EAP.h:647
std::wstring m_repair_desc
A localized and readable string that describes the possible repair action.
Definition EAP.h:677
DWORD reason() const noexcept
Returns the reason code for error.
Definition EAP.h:623
EAP_METHOD_TYPE m_type
Structure that identifies the EAP method that raised the error.
Definition EAP.h:669
eap_runtime_error(const EAP_ERROR &err, const char *msg=nullptr)
Constructs an exception.
Definition EAP.h:600
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:676
eap_runtime_error(const EAP_ERROR &err, const std::string &msg)
Constructs an exception.
Definition EAP.h:582
const wchar_t * repair() const noexcept
Returns root cause ID.
Definition EAP.h:655
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:679
const GUID & root_cause_id() const noexcept
Returns root cause ID.
Definition EAP.h:631
std::wstring m_root_cause_desc
A localized and readable string that describes the root cause of the error.
Definition EAP.h:674
const GUID & help_link_id() const noexcept
Returns help_link ID.
Definition EAP.h:663
DWORD m_reason
The reason code for the error.
Definition EAP.h:671
T handle_type
Datatype of the object handle this template class handles.
Definition Common.h:640
handle_type m_h
Object handle.
Definition Common.h:889
void attach(handle_type h) noexcept
Sets a new object handle for the class.
Definition Common.h:852
Windows runtime error.
Definition Common.h:1074
tstring msg(DWORD dwLanguageId=0) const
Returns a user-readable Windows error message.
Definition Common.h:1119
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: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:645
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