Compare commits

..

49 Commits

Author SHA1 Message Date
3bdab93f04 Version set to 1.0-alpha17 2016-09-05 10:06:50 +02:00
1ae92e80d8 Slovenian translations updated 2016-09-05 10:02:46 +02:00
c9b192932b MSCHAPv2 development continues... 2016-09-04 21:51:40 +02:00
cbb35ffaef Diameter "privacy" flag is called "protected" actually 2016-09-04 21:48:48 +02:00
4076655e2e MSCHAPv2 work continues... 2016-09-04 18:00:36 +02:00
e4e9604297 method_ttls::derive_challenge() introduced 2016-09-04 18:00:10 +02:00
8ec9f54f62 Sub-module update 2016-09-04 17:58:56 +02:00
765466f535 Missing memory-sanitation added 2016-09-04 17:57:59 +02:00
c33c8b551b Clean-up 2016-09-04 17:57:04 +02:00
4ffccaf6b4 Support for vendor-specific Diameter AVP added 2016-09-04 17:56:00 +02:00
534f234641 "Privacy" Diameter AVP flag declared 2016-09-04 17:54:59 +02:00
0095ebbff6 Provider identity is now coherent to draft-winter-opsawg-eap-metadata-02 2016-09-02 19:24:47 +02:00
ac3ff2d3ca Diameter AVP generation moved to method_noneap::append_avp() 2016-09-02 14:45:01 +02:00
7a3d4e0947 Common PAP and MSCHAPv2 code merged in intermediate base class method_noneap 2016-09-02 14:24:23 +02:00
a8070e9bba Clean-up 2016-09-02 14:07:56 +02:00
bd7f3f4a38 Still trying to make Schannel resume sessions 2016-09-02 14:05:03 +02:00
621669828b Schannel and ownTLS MSK derivation unified 2016-09-02 14:03:34 +02:00
00aee5bb78 ownTLS updated 2016-09-02 11:38:28 +02:00
198b9a576e Maximum packet size parameter is now optional 2016-09-02 10:19:39 +02:00
0a0a28730b wxWidget initialization improved to share same locale 2016-09-02 10:00:19 +02:00
566785192a Requirement that eap::method processes EAP packets only dropped, work with non-EAP methods simplified 2016-09-02 09:50:21 +02:00
7cddd585b7 RADIUS/Diameter AVP header structs updated 2016-09-01 15:43:25 +02:00
1c5f0b5c81 Graceful Schannel context shutdown added, but session resumption still does not work :( 2016-09-01 15:42:57 +02:00
6c11b23267 MSCHAPv2 stub added - it's a PAP clone, so selecting it does PAP really 2016-09-01 14:59:40 +02:00
56e2448f71 Clearing session resumption for ownTLS added.
(Have yet to learn how do you do this for Schannel. Better yet: How do you make Schannel resume a session in the first place.)
2016-09-01 14:59:03 +02:00
1e60d21860 On session reconnect skip inner re-authentication now 2016-09-01 12:49:20 +02:00
0959217ee3 Clean-up 2016-09-01 12:43:26 +02:00
844b185887 EAP packet classes organized in hierarchy now 2016-09-01 10:25:33 +02:00
98bd9f1935 Clean-up 2016-09-01 09:04:39 +02:00
6b2a71cc63 <UserName> is no longer created for empty identities 2016-09-01 05:55:39 +02:00
4d6ac7db3f Signed/unsigned 32-bit compiler warning resolved 2016-09-01 05:55:00 +02:00
ae66af02a2 After careful review of draft-winter-opsawg-eap-metadata the pre/post-processing of <OuterIdentity> was found inaccurate and has been dropped 2016-09-01 05:54:36 +02:00
2339b6b347 Version set to 1.0-alpha16 2016-08-31 18:40:45 +02:00
171e924dcf Estimated flag to enable TLS 1.3 once available added 2016-08-31 18:40:28 +02:00
281c3ee083 Schannel tweaked to support TLS 1.2 now
(closes #16)
2016-08-31 18:13:24 +02:00
145c21682e Support for configuring provider ID using GUI added 2016-08-31 17:41:22 +02:00
0d221d4401 wxWidgets initialization reference counter introduced to prevent second initialization, as we recorded a case where EapHost called our GUI twice in the same DllHost.exe process. 2016-08-31 17:13:59 +02:00
d9bfcc3e49 Credential identities are more carefully prepared for display now 2016-08-31 16:50:12 +02:00
60f1b4ccfb Pre&post-processing of XML configuration introduced to allow draft-winter-opsawg-eap-metadata-02 compliant XML profiles on the outside, while maintaining internal simplicity 2016-08-31 16:33:19 +02:00
c9be6f4f7b Support for multiple identity providers of draft-winter-opsawg-eap-metadata XML configuration added 2016-08-31 14:39:27 +02:00
452fa4b9dc Inserting single-occurrence XML elements with children simplified 2016-08-31 09:48:11 +02:00
68aec5dfb4 Namespace name is static member now 2016-08-31 08:43:03 +02:00
3f49f3e975 Event Monitor shortcut description dropped as it will not be localized 2016-08-31 02:53:19 +02:00
04213715b0 UI texts updated 2016-08-31 01:25:44 +02:00
510bbe10f6 Template for creating XML configuration simplified 2016-08-31 00:41:16 +02:00
5dfd079686 Support for multi-provider management added to GUI 2016-08-31 00:36:19 +02:00
858486412e Confusion between provider ID and provider name resolved 2016-08-30 21:10:10 +02:00
8b266f086f Code clean-up 2016-08-30 17:44:21 +02:00
c40306c624 <Error getting property (error 13)> issue with log parameters solved 2016-08-30 17:43:56 +02:00
86 changed files with 5972 additions and 1420 deletions

View File

@@ -72,11 +72,10 @@ static int CredWrite()
} else { } else {
// Get the realm from user name. // Get the realm from user name.
LPCWSTR _identity = cred_pap.m_identity.c_str(), domain; LPCWSTR _identity = cred_pap.m_identity.c_str(), domain;
if ((domain = wcschr(_identity, L'@')) != NULL) if ((domain = wcschr(_identity, L'@')) != NULL) {
target_name = domain + 1; target_name = L"urn:RFC4282:realm:";
else if ((domain = wcschr(_identity, L'\\')) != NULL) target_name += domain + 1;
target_name.assign(_identity, domain); } else
else
target_name = L"*"; target_name = L"*";
} }

View File

@@ -100,6 +100,9 @@
<ProjectReference Include="..\..\lib\Events\build\Events.vcxproj"> <ProjectReference Include="..\..\lib\Events\build\Events.vcxproj">
<Project>{d63f24bd-92a0-4d6b-8b69-ed947e4d2b1b}</Project> <Project>{d63f24bd-92a0-4d6b-8b69-ed947e4d2b1b}</Project>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\..\lib\MSCHAPv2\build\MSCHAPv2.vcxproj">
<Project>{86a6d6a0-4b7d-4134-be81-a5755c77584d}</Project>
</ProjectReference>
<ProjectReference Include="..\..\lib\PAP\build\PAP.vcxproj"> <ProjectReference Include="..\..\lib\PAP\build\PAP.vcxproj">
<Project>{36b0cf8a-7794-46c3-8099-825ba962b4c7}</Project> <Project>{36b0cf8a-7794-46c3-8099-825ba962b4c7}</Project>
</ProjectReference> </ProjectReference>

View File

@@ -103,6 +103,12 @@
<ProjectReference Include="..\..\lib\Events\build\Events.vcxproj"> <ProjectReference Include="..\..\lib\Events\build\Events.vcxproj">
<Project>{d63f24bd-92a0-4d6b-8b69-ed947e4d2b1b}</Project> <Project>{d63f24bd-92a0-4d6b-8b69-ed947e4d2b1b}</Project>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\..\lib\MSCHAPv2\build\MSCHAPv2.vcxproj">
<Project>{86a6d6a0-4b7d-4134-be81-a5755c77584d}</Project>
</ProjectReference>
<ProjectReference Include="..\..\lib\MSCHAPv2_UI\build\MSCHAPv2_UI.vcxproj">
<Project>{7af5b922-7c17-428a-97e0-09e3b41a684d}</Project>
</ProjectReference>
<ProjectReference Include="..\..\lib\PAP\build\PAP.vcxproj"> <ProjectReference Include="..\..\lib\PAP\build\PAP.vcxproj">
<Project>{36b0cf8a-7794-46c3-8099-825ba962b4c7}</Project> <Project>{36b0cf8a-7794-46c3-8099-825ba962b4c7}</Project>
</ProjectReference> </ProjectReference>

View File

@@ -2,7 +2,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: EAPMethods\n" "Project-Id-Version: EAPMethods\n"
"POT-Creation-Date: 2016-08-28 23:08+0200\n" "POT-Creation-Date: 2016-09-02 19:08+0200\n"
"PO-Revision-Date: 2016-06-02 12:27+0200\n" "PO-Revision-Date: 2016-06-02 12:27+0200\n"
"Last-Translator: Simon Rozman <simon.rozman@amebis.si>\n" "Last-Translator: Simon Rozman <simon.rozman@amebis.si>\n"
"Language-Team: Amebis, d. o. o., Kamnik <info@amebis.si>\n" "Language-Team: Amebis, d. o. o., Kamnik <info@amebis.si>\n"
@@ -20,152 +20,196 @@ msgstr ""
"X-Poedit-SearchPath-4: EAPMethods\n" "X-Poedit-SearchPath-4: EAPMethods\n"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:37 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:37
msgid "Advanced..." msgid "+"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:38 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:38
msgid "Adds new provider"
msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:42
msgid "-"
msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:43
msgid "Removes selected provider"
msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:47
msgid "Advanced..."
msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:48
msgid "Opens dialog with provider settings" msgid "Opens dialog with provider settings"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:174 lib/EAPBase_UI/res/wxEAP_UI.cpp:299 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:230 lib/EAPBase_UI/res/wxEAP_UI.cpp:355
msgid "Client Credentials" msgid "Client Credentials"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:185 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:241
msgid "Manage credentials used to connect." msgid "Manage credentials used to connect."
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:198 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:254
msgid "Use &own credentials:" msgid "Use &own credentials:"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:199 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:255
msgid "Select this option if you have your unique credentials to connect" msgid "Select this option if you have your unique credentials to connect"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:204 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:260
msgid "Your credentials loaded from Windows Credential Manager" msgid "Your credentials loaded from Windows Credential Manager"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:214 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:270
msgid "&Clear Credentials" msgid "&Clear Credentials"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:215 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:271
msgid "" msgid ""
"Click to clear your credentials from Credential Manager.\n" "Click to clear your credentials from Credential Manager.\n"
"Note: You will be prompted to enter credentials when connecting." "Note: You will be prompted to enter credentials when connecting."
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:219 lib/EAPBase_UI/res/wxEAP_UI.cpp:252 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:275 lib/EAPBase_UI/res/wxEAP_UI.cpp:308
msgid "&Set Credentials..." msgid "&Set Credentials..."
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:220 lib/EAPBase_UI/res/wxEAP_UI.cpp:253 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:276 lib/EAPBase_UI/res/wxEAP_UI.cpp:309
msgid "Click here to set or modify your credentials" msgid "Click here to set or modify your credentials"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:236 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:292
msgid "Use &pre-shared credentials:" msgid "Use &pre-shared credentials:"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:237 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:293
msgid "Select this options if all clients connect using the same credentials" msgid "Select this options if all clients connect using the same credentials"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:242 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:298
msgid "Common (pre-shared) credentials" msgid "Common (pre-shared) credentials"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:310 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:366
msgid "Please provide your user ID and password." msgid "Please provide your user ID and password."
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:320 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:376
msgid "User ID:" msgid "User ID:"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:325 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:381
msgid "Enter your user name here (user@domain.org, DOMAIN\\User, etc.)" msgid "Enter your user name here (user@domain.org, DOMAIN\\User, etc.)"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:329 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:385
msgid "Password:" msgid "Password:"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:334 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:390
msgid "Enter your password here" msgid "Enter your password here"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:341 lib/TLS_UI/res/wxTLS_UI.cpp:183 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:397 lib/TLS_UI/res/wxTLS_UI.cpp:183
msgid "&Remember" msgid "&Remember"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:342 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:398
msgid "Check if you would like to save username and password" msgid "Check if you would like to save username and password"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:364 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:420
msgid "Your Organization" msgid "Your Organization"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:375 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:431
msgid "Describe your organization to customize user prompts. When organization is introduced, end-users find program messages easier to understand and act." msgid "Describe your organization to customize user prompts. When organization is introduced, end-users find program messages easier to understand and act."
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:382 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:438
msgid "Your organization &name:" msgid "Your organization &name:"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:387 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:443
msgid "Your organization name as it will appear on helpdesk contact notifications" msgid "Your organization name as it will appear on helpdesk contact notifications"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:391 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:447
msgid "(Keep it short, please)" msgid "(Keep it short, please)"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:401 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:457
msgid "Helpdesk contact &information:" msgid "Helpdesk contact &information:"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:411 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:467
msgid "¶" msgid "¶"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:418 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:474
msgid "Your helpdesk website address" msgid "Your helpdesk website address"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:422 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:478
msgid "*" msgid "*"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:429 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:485
msgid "Your helpdesk e-mail address" msgid "Your helpdesk e-mail address"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:433 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:489
msgid ")" msgid ")"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:440 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:496
msgid "Your helpdesk phone number" msgid "Your helpdesk phone number"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:468 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:524
msgid "Provider Unique Identifier"
msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:535
msgid "Assign your organization a unique ID to allow sharing the same credential set across different network profiles."
msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:542
msgid "&Namespace:"
msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:546
msgid "urn:RFC4282:realm"
msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:546
msgid "urn:uuid"
msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:558
msgid "Provider unique &identifier:"
msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:563
msgid "Your organization ID to assign same credentials from other profiles"
msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:588
msgid "Configuration Lock" msgid "Configuration Lock"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:479 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:599
msgid "Your configuration can be locked to prevent accidental modification by end-users. Users will only be allowed to enter credentials." msgid "Your configuration can be locked to prevent accidental modification by end-users. Users will only be allowed to enter credentials."
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:486 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:606
msgid "&Lock this configuration and prevent any further modification via user interface." msgid "&Lock this configuration and prevent any further modification via user interface."
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:489 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:609
msgid "(Warning: Once locked, you can not revert using this dialog!)" msgid "(Warning: Once locked, you can not revert using this dialog!)"
msgstr "" msgstr ""
@@ -174,47 +218,42 @@ msgstr ""
msgid "%s Credentials" msgid "%s Credentials"
msgstr "" msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:128 #: lib/EAPBase_UI/src/EAP_UI.cpp:123 lib/EAPBase_UI/include/EAP_UI.h:352
#: lib/EAPBase_UI/include/EAP_UI.h:362 lib/EAPBase_UI/res/wxEAP_UI.h:119
msgid "EAP Credentials"
msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:166
#, c-format #, c-format
msgid "For additional help and instructions, please contact %s at:" msgid "For additional help and instructions, please contact %s at:"
msgstr "" msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:130 #: lib/EAPBase_UI/src/EAP_UI.cpp:167
#, c-format
msgid "your %ls provider"
msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:130
msgid "your provider" msgid "your provider"
msgstr "" msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:149 #: lib/EAPBase_UI/src/EAP_UI.cpp:186
msgid "Open the default web browser" msgid "Open the default web browser"
msgstr "" msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:160 #: lib/EAPBase_UI/src/EAP_UI.cpp:197
msgid "Open your e-mail program" msgid "Open your e-mail program"
msgstr "" msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:171 #: lib/EAPBase_UI/src/EAP_UI.cpp:208
msgid "Dial the phone number" msgid "Dial the phone number"
msgstr "" msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:191 #: lib/EAPBase_UI/src/EAP_UI.cpp:228
#, c-format #, c-format
msgid "%s has pre-set parts of this configuration. Those parts are locked to prevent accidental modification." msgid "%s has pre-set parts of this configuration. Those parts are locked to prevent accidental modification."
msgstr "" msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:193 #: lib/EAPBase_UI/src/EAP_UI.cpp:229
#, c-format
msgid "Your %ls provider"
msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:193
msgid "Your provider" msgid "Your provider"
msgstr "" msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:213 #: lib/EAPBase_UI/src/EAP_UI.cpp:249
msgid "Previous attempt to connect failed. Please, make sure your credentials are correct, or try again later." msgid "Previous attempt to connect failed. Please, make sure your credentials are correct, or try again later."
msgstr "" msgstr ""
@@ -388,69 +427,78 @@ msgstr ""
msgid "Custom outer identity to use" msgid "Custom outer identity to use"
msgstr "" msgstr ""
#: lib/TTLS_UI/src/Module.cpp:249 lib/TTLS_UI/src/Module.cpp:259 #: lib/TTLS_UI/src/Module.cpp:275 lib/TTLS_UI/src/Module.cpp:285
#: lib/EAPBase_UI/include/EAP_UI.h:584 #: lib/EAPBase_UI/include/EAP_UI.h:689
#, c-format #, c-format
msgid "Error writing credentials to Credential Manager: %hs (error %u)" msgid "Error writing credentials to Credential Manager: %hs (error %u)"
msgstr "" msgstr ""
#: lib/TTLS_UI/src/Module.cpp:251 lib/TTLS_UI/src/Module.cpp:261 #: lib/TTLS_UI/src/Module.cpp:277 lib/TTLS_UI/src/Module.cpp:287
#: lib/EAPBase_UI/include/EAP_UI.h:587 #: lib/EAPBase_UI/include/EAP_UI.h:692
msgid "Writing credentials failed." msgid "Writing credentials failed."
msgstr "" msgstr ""
#: lib/TTLS_UI/src/TTLS_UI.cpp:107 lib/TTLS_UI/src/TTLS_UI.cpp:220 #: lib/TTLS_UI/src/TTLS_UI.cpp:108 lib/TTLS_UI/src/TTLS_UI.cpp:235
msgid "Inner Authentication" msgid "Inner Authentication"
msgstr "" msgstr ""
#: lib/TTLS_UI/src/TTLS_UI.cpp:113 #: lib/TTLS_UI/src/TTLS_UI.cpp:114
msgid "Select inner authentication method from the list" msgid "Select inner authentication method from the list"
msgstr "" msgstr ""
#: lib/TTLS_UI/src/TTLS_UI.cpp:115 #: lib/TTLS_UI/src/TTLS_UI.cpp:116
msgid "PAP" msgid "PAP"
msgstr "" msgstr ""
#: lib/TTLS_UI/src/TTLS_UI.cpp:120 lib/TTLS_UI/src/TTLS_UI.cpp:241 #: lib/TTLS_UI/src/TTLS_UI.cpp:118
msgid "MSCHAPv2"
msgstr ""
#: lib/TTLS_UI/src/TTLS_UI.cpp:123 lib/TTLS_UI/src/TTLS_UI.cpp:256
msgid "Outer Authentication" msgid "Outer Authentication"
msgstr "" msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:283 #: lib/EAPBase_UI/include/EAP_UI.h:289
msgid "EAP Credentials" #, c-format
msgid "Are you sure you want to permanently remove %ls provider from configuration?"
msgstr "" msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:443 #: lib/EAPBase_UI/include/EAP_UI.h:289
msgid "Warning"
msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:549
msgid "Provider Settings" msgid "Provider Settings"
msgstr "" msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:600 #: lib/EAPBase_UI/include/EAP_UI.h:705
#, c-format #, c-format
msgid "Deleting credentials failed (error %u)." msgid "Deleting credentials failed (error %u)."
msgstr "" msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:633 #: lib/EAPBase_UI/include/EAP_UI.h:738
#, c-format #, c-format
msgid "<error %u>" msgid "<error %u>"
msgstr "" msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:637 #: lib/EAPBase_UI/include/EAP_UI.h:742
msgid "<error>" msgid "<error>"
msgstr "" msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:646 lib/EAPBase_UI/include/EAP_UI.h:657 #: lib/EAPBase_UI/include/EAP_UI.h:753 lib/EAPBase_UI/include/EAP_UI.h:762
msgid "<empty credentials>" msgid "<empty>"
msgstr "" msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:649 lib/EAPBase_UI/include/EAP_UI.h:660 #: lib/EAPBase_UI/include/EAP_UI.h:753 lib/EAPBase_UI/include/EAP_UI.h:762
msgid "<blank identity>" msgid "<blank ID>"
msgstr "" msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:866 #: lib/EAPBase_UI/include/EAP_UI.h:962
msgid "<Your Organization>" msgid "<Your Organization>"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.h:64 #: lib/EAPBase_UI/res/wxEAP_UI.h:69
msgid "EAP Method Configuration" msgid "EAP Connection Configuration"
msgstr "" msgstr ""
#: EAPMethods/MSIBuild/En.Win32.Release.Feature-2.idtx:3 #: EAPMethods/MSIBuild/En.Win32.Release.Feature-2.idtx:3

View File

@@ -3,7 +3,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: EAPMethods\n" "Project-Id-Version: EAPMethods\n"
"POT-Creation-Date: 2016-08-28 23:08+0200\n" "POT-Creation-Date: 2016-09-02 19:08+0200\n"
"PO-Revision-Date: 2016-06-02 12:27+0200\n" "PO-Revision-Date: 2016-06-02 12:27+0200\n"
"Last-Translator: Simon Rozman <simon@rozman.si>, 2016\n" "Last-Translator: Simon Rozman <simon@rozman.si>, 2016\n"
"Language-Team: Slovenian (Slovenia) (https://www.transifex.com/eduroam_devel/teams/11799/sl_SI/)\n" "Language-Team: Slovenian (Slovenia) (https://www.transifex.com/eduroam_devel/teams/11799/sl_SI/)\n"
@@ -23,38 +23,54 @@ msgstr ""
"X-Poedit-SourceCharset: UTF-8\n" "X-Poedit-SourceCharset: UTF-8\n"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:37 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:37
msgid "+"
msgstr "+"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:38
msgid "Adds new provider"
msgstr "Doda novega ponudnika"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:42
msgid "-"
msgstr "-"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:43
msgid "Removes selected provider"
msgstr "Odstrani izbranega ponudnika"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:47
msgid "Advanced..." msgid "Advanced..."
msgstr "Napredno ..." msgstr "Napredno ..."
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:38 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:48
msgid "Opens dialog with provider settings" msgid "Opens dialog with provider settings"
msgstr "Odpre dialog z nastavitvami ponudnika" msgstr "Odpre dialog z nastavitvami ponudnika"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:174 lib/EAPBase_UI/res/wxEAP_UI.cpp:299 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:230 lib/EAPBase_UI/res/wxEAP_UI.cpp:355
msgid "Client Credentials" msgid "Client Credentials"
msgstr "Odjemalčeve poverilnice" msgstr "Odjemalčeve poverilnice"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:185 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:241
msgid "Manage credentials used to connect." msgid "Manage credentials used to connect."
msgstr "Upravljajte s poverilnicami za povezovanje." msgstr "Upravljajte s poverilnicami za povezovanje."
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:198 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:254
msgid "Use &own credentials:" msgid "Use &own credentials:"
msgstr "Uporabi sv&oje poverilnice:" msgstr "Uporabi sv&oje poverilnice:"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:199 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:255
msgid "Select this option if you have your unique credentials to connect" msgid "Select this option if you have your unique credentials to connect"
msgstr "Izberite to možnost, če imate svoje lastne poverilnice za povezovanje" msgstr "Izberite to možnost, če imate svoje lastne poverilnice za povezovanje"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:204 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:260
msgid "Your credentials loaded from Windows Credential Manager" msgid "Your credentials loaded from Windows Credential Manager"
msgstr "Vaše poverilnice naložene iz upravitelja poverilnic Windows" msgstr "Vaše poverilnice naložene iz upravitelja poverilnic Windows"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:214 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:270
msgid "&Clear Credentials" msgid "&Clear Credentials"
msgstr "Počisti poverilni&ce" msgstr "Počisti poverilni&ce"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:215 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:271
msgid "" msgid ""
"Click to clear your credentials from Credential Manager.\n" "Click to clear your credentials from Credential Manager.\n"
"Note: You will be prompted to enter credentials when connecting." "Note: You will be prompted to enter credentials when connecting."
@@ -62,61 +78,61 @@ msgstr ""
"Kliknite, da počistite svoje poverilnice iz upravitelja poverilnic.\n" "Kliknite, da počistite svoje poverilnice iz upravitelja poverilnic.\n"
"Opomba: Za vnos poverilnic boste pozvani ob povezovanju." "Opomba: Za vnos poverilnic boste pozvani ob povezovanju."
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:219 lib/EAPBase_UI/res/wxEAP_UI.cpp:252 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:275 lib/EAPBase_UI/res/wxEAP_UI.cpp:308
msgid "&Set Credentials..." msgid "&Set Credentials..."
msgstr "Na&stavi poverilnice ..." msgstr "Na&stavi poverilnice ..."
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:220 lib/EAPBase_UI/res/wxEAP_UI.cpp:253 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:276 lib/EAPBase_UI/res/wxEAP_UI.cpp:309
msgid "Click here to set or modify your credentials" msgid "Click here to set or modify your credentials"
msgstr "Kliknite tukaj, da nastavite ali spremenite svoje poverilnice" msgstr "Kliknite tukaj, da nastavite ali spremenite svoje poverilnice"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:236 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:292
msgid "Use &pre-shared credentials:" msgid "Use &pre-shared credentials:"
msgstr "Uporabi sku&pne poverilnice:" msgstr "Uporabi sku&pne poverilnice:"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:237 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:293
msgid "Select this options if all clients connect using the same credentials" msgid "Select this options if all clients connect using the same credentials"
msgstr "" msgstr ""
"Izberite to možnost, kadar se vsi odjemalci povezujejo z istimi " "Izberite to možnost, kadar se vsi odjemalci povezujejo z istimi "
"poverilnicami" "poverilnicami"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:242 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:298
msgid "Common (pre-shared) credentials" msgid "Common (pre-shared) credentials"
msgstr "Skupne (deljene) poverilnice" msgstr "Skupne (deljene) poverilnice"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:310 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:366
msgid "Please provide your user ID and password." msgid "Please provide your user ID and password."
msgstr "Vnesite svoj uporabniški ID in geslo." msgstr "Vnesite svoj uporabniški ID in geslo."
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:320 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:376
msgid "User ID:" msgid "User ID:"
msgstr "Uporabniški ID:" msgstr "Uporabniški ID:"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:325 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:381
msgid "Enter your user name here (user@domain.org, DOMAIN\\User, etc.)" msgid "Enter your user name here (user@domain.org, DOMAIN\\User, etc.)"
msgstr "Tukaj vnesite svoje up. ime (up. ime@domena.si, DOMENA\\Uporabnik ipd.)" msgstr "Tukaj vnesite svoje up. ime (up. ime@domena.si, DOMENA\\Uporabnik ipd.)"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:329 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:385
msgid "Password:" msgid "Password:"
msgstr "Geslo:" msgstr "Geslo:"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:334 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:390
msgid "Enter your password here" msgid "Enter your password here"
msgstr "Tukaj vnesite svoje geslo" msgstr "Tukaj vnesite svoje geslo"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:341 lib/TLS_UI/res/wxTLS_UI.cpp:183 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:397 lib/TLS_UI/res/wxTLS_UI.cpp:183
msgid "&Remember" msgid "&Remember"
msgstr "Za&pomni si" msgstr "Za&pomni si"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:342 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:398
msgid "Check if you would like to save username and password" msgid "Check if you would like to save username and password"
msgstr "Odkljukajte, če želite shraniti up. ime in geslo" msgstr "Odkljukajte, če želite shraniti up. ime in geslo"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:364 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:420
msgid "Your Organization" msgid "Your Organization"
msgstr "Vaša organizacija" msgstr "Vaša organizacija"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:375 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:431
msgid "" msgid ""
"Describe your organization to customize user prompts. When organization is " "Describe your organization to customize user prompts. When organization is "
"introduced, end-users find program messages easier to understand and act." "introduced, end-users find program messages easier to understand and act."
@@ -125,54 +141,88 @@ msgstr ""
"predstavi, uporabniki lažje razumejo sporočila programa in ustrezneje " "predstavi, uporabniki lažje razumejo sporočila programa in ustrezneje "
"reagirajo." "reagirajo."
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:382 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:438
msgid "Your organization &name:" msgid "Your organization &name:"
msgstr "Ime vaše orga&nizacije:" msgstr "Ime vaše orga&nizacije:"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:387 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:443
msgid "" msgid ""
"Your organization name as it will appear on helpdesk contact notifications" "Your organization name as it will appear on helpdesk contact notifications"
msgstr "" msgstr ""
"Ime vaše organizacije, kot bo nastopalo na obvestilih s stikom na center za " "Ime vaše organizacije, kot bo nastopalo na obvestilih s stikom na center za "
"pomoč" "pomoč"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:391 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:447
msgid "(Keep it short, please)" msgid "(Keep it short, please)"
msgstr "(Naj bo kratko, prosim)" msgstr "(Naj bo kratko, prosim)"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:401 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:457
msgid "Helpdesk contact &information:" msgid "Helpdesk contact &information:"
msgstr "Podatk&i centra za pomoč:" msgstr "Podatk&i centra za pomoč:"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:411 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:467
msgid "¶" msgid "¶"
msgstr "¶" msgstr "¶"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:418 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:474
msgid "Your helpdesk website address" msgid "Your helpdesk website address"
msgstr "Naslov spletne strani vašega centra za pomoč" msgstr "Naslov spletne strani vašega centra za pomoč"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:422 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:478
msgid "*" msgid "*"
msgstr "*" msgstr "*"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:429 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:485
msgid "Your helpdesk e-mail address" msgid "Your helpdesk e-mail address"
msgstr "E-poštni naslov vašega centra za pomoč" msgstr "E-poštni naslov vašega centra za pomoč"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:433 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:489
msgid ")" msgid ")"
msgstr ")" msgstr ")"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:440 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:496
msgid "Your helpdesk phone number" msgid "Your helpdesk phone number"
msgstr "Telefonska številka vašega centra za pomoč" msgstr "Telefonska številka vašega centra za pomoč"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:468 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:524
msgid "Provider Unique Identifier"
msgstr "Enolični identifikator ponudnika"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:535
msgid ""
"Assign your organization a unique ID to allow sharing the same credential "
"set across different network profiles."
msgstr ""
"Dodelite svoji organizaciji enoznačen identifikator, da omogočite souporabo "
"istih poverilnic različnim omrežnim profilom."
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:542
msgid "&Namespace:"
msgstr "Ime&nski prostor:"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:546
msgid "urn:RFC4282:realm"
msgstr "urn:RFC4282:realm"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:546
msgid "urn:uuid"
msgstr "urn:uuid"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:558
msgid "Provider unique &identifier:"
msgstr "Enolični &identifikator ponudnika:"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:563
msgid "Your organization ID to assign same credentials from other profiles"
msgstr ""
"Identifikator vaše organizacije za souporabo istih poverilnic različnih "
"profilov"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:588
msgid "Configuration Lock" msgid "Configuration Lock"
msgstr "Zaklep konfiguracije" msgstr "Zaklep konfiguracije"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:479 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:599
msgid "" msgid ""
"Your configuration can be locked to prevent accidental modification by end-" "Your configuration can be locked to prevent accidental modification by end-"
"users. Users will only be allowed to enter credentials." "users. Users will only be allowed to enter credentials."
@@ -180,7 +230,7 @@ msgstr ""
"Svojo konfiguracijo lahko zaklenete in preprečite končnim uporabnikom " "Svojo konfiguracijo lahko zaklenete in preprečite končnim uporabnikom "
"nenamerno spreminjanje. Uporabniki bodo lahko vnašali samo poverilnice." "nenamerno spreminjanje. Uporabniki bodo lahko vnašali samo poverilnice."
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:486 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:606
msgid "" msgid ""
"&Lock this configuration and prevent any further modification via user " "&Lock this configuration and prevent any further modification via user "
"interface." "interface."
@@ -188,7 +238,7 @@ msgstr ""
"Zak&leni to konfiguracijo in prepreči vse nadaljnje spremembe preko up. " "Zak&leni to konfiguracijo in prepreči vse nadaljnje spremembe preko up. "
"vmesnika." "vmesnika."
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:489 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:609
msgid "(Warning: Once locked, you can not revert using this dialog!)" msgid "(Warning: Once locked, you can not revert using this dialog!)"
msgstr "(Pozor: Ko zaklenete, vrnitev ne bo več možna preko tega dialoga!)" msgstr "(Pozor: Ko zaklenete, vrnitev ne bo več možna preko tega dialoga!)"
@@ -197,33 +247,33 @@ msgstr "(Pozor: Ko zaklenete, vrnitev ne bo več možna preko tega dialoga!)"
msgid "%s Credentials" msgid "%s Credentials"
msgstr "Poverilnice za %s" msgstr "Poverilnice za %s"
#: lib/EAPBase_UI/src/EAP_UI.cpp:128 #: lib/EAPBase_UI/src/EAP_UI.cpp:123 lib/EAPBase_UI/include/EAP_UI.h:352
#: lib/EAPBase_UI/include/EAP_UI.h:362 lib/EAPBase_UI/res/wxEAP_UI.h:119
msgid "EAP Credentials"
msgstr "Poverilnice EAP"
#: lib/EAPBase_UI/src/EAP_UI.cpp:166
#, c-format #, c-format
msgid "For additional help and instructions, please contact %s at:" msgid "For additional help and instructions, please contact %s at:"
msgstr "Za dodtano pomoč ali navodila se obrnite na %s na:" msgstr "Za dodtano pomoč ali navodila se obrnite na %s na:"
#: lib/EAPBase_UI/src/EAP_UI.cpp:130 #: lib/EAPBase_UI/src/EAP_UI.cpp:167
#, c-format
msgid "your %ls provider"
msgstr "vaš ponudnik %ls"
#: lib/EAPBase_UI/src/EAP_UI.cpp:130
msgid "your provider" msgid "your provider"
msgstr "vaš ponudnik" msgstr "vaš ponudnik"
#: lib/EAPBase_UI/src/EAP_UI.cpp:149 #: lib/EAPBase_UI/src/EAP_UI.cpp:186
msgid "Open the default web browser" msgid "Open the default web browser"
msgstr "Odpre privzeto nastavljen spletni brskalnik" msgstr "Odpre privzeto nastavljen spletni brskalnik"
#: lib/EAPBase_UI/src/EAP_UI.cpp:160 #: lib/EAPBase_UI/src/EAP_UI.cpp:197
msgid "Open your e-mail program" msgid "Open your e-mail program"
msgstr "Odpre vaš program za e-pošto" msgstr "Odpre vaš program za e-pošto"
#: lib/EAPBase_UI/src/EAP_UI.cpp:171 #: lib/EAPBase_UI/src/EAP_UI.cpp:208
msgid "Dial the phone number" msgid "Dial the phone number"
msgstr "Pokliče telefonsko številko" msgstr "Pokliče telefonsko številko"
#: lib/EAPBase_UI/src/EAP_UI.cpp:191 #: lib/EAPBase_UI/src/EAP_UI.cpp:228
#, c-format #, c-format
msgid "" msgid ""
"%s has pre-set parts of this configuration. Those parts are locked to " "%s has pre-set parts of this configuration. Those parts are locked to "
@@ -232,16 +282,11 @@ msgstr ""
"%s je prednastavil dele te konfiguracije. Ti deli so zaklenjeni zaradi " "%s je prednastavil dele te konfiguracije. Ti deli so zaklenjeni zaradi "
"preprečevanja nenamernih sprememb." "preprečevanja nenamernih sprememb."
#: lib/EAPBase_UI/src/EAP_UI.cpp:193 #: lib/EAPBase_UI/src/EAP_UI.cpp:229
#, c-format
msgid "Your %ls provider"
msgstr "Vaš ponudnik %ls"
#: lib/EAPBase_UI/src/EAP_UI.cpp:193
msgid "Your provider" msgid "Your provider"
msgstr "Vaš ponudnik" msgstr "Vaš ponudnik"
#: lib/EAPBase_UI/src/EAP_UI.cpp:213 #: lib/EAPBase_UI/src/EAP_UI.cpp:249
msgid "" msgid ""
"Previous attempt to connect failed. Please, make sure your credentials are " "Previous attempt to connect failed. Please, make sure your credentials are "
"correct, or try again later." "correct, or try again later."
@@ -438,71 +483,83 @@ msgstr "Navedite zunanjo identiteto po meri"
msgid "Custom outer identity to use" msgid "Custom outer identity to use"
msgstr "Zunanja identiteta po meri za uporabo" msgstr "Zunanja identiteta po meri za uporabo"
#: lib/TTLS_UI/src/Module.cpp:249 lib/TTLS_UI/src/Module.cpp:259 #: lib/TTLS_UI/src/Module.cpp:275 lib/TTLS_UI/src/Module.cpp:285
#: lib/EAPBase_UI/include/EAP_UI.h:584 #: lib/EAPBase_UI/include/EAP_UI.h:689
#, c-format #, c-format
msgid "Error writing credentials to Credential Manager: %hs (error %u)" msgid "Error writing credentials to Credential Manager: %hs (error %u)"
msgstr "" msgstr ""
"Napaka pri zapisovanju poverilnic v upravitelja poverilnic: %hs (napaka %u)" "Napaka pri zapisovanju poverilnic v upravitelja poverilnic: %hs (napaka %u)"
#: lib/TTLS_UI/src/Module.cpp:251 lib/TTLS_UI/src/Module.cpp:261 #: lib/TTLS_UI/src/Module.cpp:277 lib/TTLS_UI/src/Module.cpp:287
#: lib/EAPBase_UI/include/EAP_UI.h:587 #: lib/EAPBase_UI/include/EAP_UI.h:692
msgid "Writing credentials failed." msgid "Writing credentials failed."
msgstr "Zapisovanje poverilnic ni uspelo." msgstr "Zapisovanje poverilnic ni uspelo."
#: lib/TTLS_UI/src/TTLS_UI.cpp:107 lib/TTLS_UI/src/TTLS_UI.cpp:220 #: lib/TTLS_UI/src/TTLS_UI.cpp:108 lib/TTLS_UI/src/TTLS_UI.cpp:235
msgid "Inner Authentication" msgid "Inner Authentication"
msgstr "Notranje overovljanje" msgstr "Notranje overovljanje"
#: lib/TTLS_UI/src/TTLS_UI.cpp:113 #: lib/TTLS_UI/src/TTLS_UI.cpp:114
msgid "Select inner authentication method from the list" msgid "Select inner authentication method from the list"
msgstr "Izberite postopek notranjega overovljanja s seznama" msgstr "Izberite postopek notranjega overovljanja s seznama"
#: lib/TTLS_UI/src/TTLS_UI.cpp:115 #: lib/TTLS_UI/src/TTLS_UI.cpp:116
msgid "PAP" msgid "PAP"
msgstr "PAP" msgstr "PAP"
#: lib/TTLS_UI/src/TTLS_UI.cpp:120 lib/TTLS_UI/src/TTLS_UI.cpp:241 #: lib/TTLS_UI/src/TTLS_UI.cpp:118
msgid "MSCHAPv2"
msgstr "MSCHAPv2"
#: lib/TTLS_UI/src/TTLS_UI.cpp:123 lib/TTLS_UI/src/TTLS_UI.cpp:256
msgid "Outer Authentication" msgid "Outer Authentication"
msgstr "Zunanje overovljanje" msgstr "Zunanje overovljanje"
#: lib/EAPBase_UI/include/EAP_UI.h:283 #: lib/EAPBase_UI/include/EAP_UI.h:289
msgid "EAP Credentials" #, c-format
msgstr "Poverilnice EAP" msgid ""
"Are you sure you want to permanently remove %ls provider from configuration?"
msgstr ""
"Ali ste prepričani, da želite trajno izbrisati ponudnika %ls iz "
"konfiguracije?"
#: lib/EAPBase_UI/include/EAP_UI.h:443 #: lib/EAPBase_UI/include/EAP_UI.h:289
msgid "Warning"
msgstr "Opozorilo"
#: lib/EAPBase_UI/include/EAP_UI.h:549
msgid "Provider Settings" msgid "Provider Settings"
msgstr "Nastavitve ponudnika" msgstr "Nastavitve ponudnika"
#: lib/EAPBase_UI/include/EAP_UI.h:600 #: lib/EAPBase_UI/include/EAP_UI.h:705
#, c-format #, c-format
msgid "Deleting credentials failed (error %u)." msgid "Deleting credentials failed (error %u)."
msgstr "Izbris poverilnic ni uspel (napaka %u)." msgstr "Izbris poverilnic ni uspel (napaka %u)."
#: lib/EAPBase_UI/include/EAP_UI.h:633 #: lib/EAPBase_UI/include/EAP_UI.h:738
#, c-format #, c-format
msgid "<error %u>" msgid "<error %u>"
msgstr "<napaka %u>" msgstr "<napaka %u>"
#: lib/EAPBase_UI/include/EAP_UI.h:637 #: lib/EAPBase_UI/include/EAP_UI.h:742
msgid "<error>" msgid "<error>"
msgstr "<napaka>" msgstr "<napaka>"
#: lib/EAPBase_UI/include/EAP_UI.h:646 lib/EAPBase_UI/include/EAP_UI.h:657 #: lib/EAPBase_UI/include/EAP_UI.h:753 lib/EAPBase_UI/include/EAP_UI.h:762
msgid "<empty credentials>" msgid "<empty>"
msgstr "<prazne poverilnice>" msgstr "<napaka>"
#: lib/EAPBase_UI/include/EAP_UI.h:649 lib/EAPBase_UI/include/EAP_UI.h:660 #: lib/EAPBase_UI/include/EAP_UI.h:753 lib/EAPBase_UI/include/EAP_UI.h:762
msgid "<blank identity>" msgid "<blank ID>"
msgstr "<prazna identiteta>" msgstr "<prazen ID>"
#: lib/EAPBase_UI/include/EAP_UI.h:866 #: lib/EAPBase_UI/include/EAP_UI.h:962
msgid "<Your Organization>" msgid "<Your Organization>"
msgstr "<vaša organizacija>" msgstr "<vaša organizacija>"
#: lib/EAPBase_UI/res/wxEAP_UI.h:64 #: lib/EAPBase_UI/res/wxEAP_UI.h:69
msgid "EAP Method Configuration" msgid "EAP Connection Configuration"
msgstr "Konfiguracija postopka EAP" msgstr "Konfiguracija povezave EAP"
#: EAPMethods/MSIBuild/En.Win32.Release.Feature-2.idtx:3 #: EAPMethods/MSIBuild/En.Win32.Release.Feature-2.idtx:3
#: EAPMethods/MSIBuild/En.x64.Release.Feature-2.idtx:3 #: EAPMethods/MSIBuild/En.x64.Release.Feature-2.idtx:3

View File

@@ -193,17 +193,17 @@ DWORD WINAPI EapPeerConfigBlob2Xml(
HRESULT hr; HRESULT hr;
// Create configuration XML document. // Create configuration XML document.
com_obj<IXMLDOMDocument2> pDoc; com_obj<IXMLDOMDocument2> pConfigDoc;
if (FAILED(hr = pDoc.create(CLSID_DOMDocument60, NULL, CLSCTX_INPROC_SERVER))) { if (FAILED(hr = pConfigDoc.create(CLSID_DOMDocument60, NULL, CLSCTX_INPROC_SERVER))) {
g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = HRESULT_CODE(hr), _T(__FUNCTION__) _T(" Error creating XML document."))); g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = HRESULT_CODE(hr), _T(__FUNCTION__) _T(" Error creating XML document.")));
return dwResult; return dwResult;
} }
pDoc->put_async(VARIANT_FALSE); pConfigDoc->put_async(VARIANT_FALSE);
// Load empty XML configuration. // Load empty XML configuration.
VARIANT_BOOL isSuccess = VARIANT_FALSE; VARIANT_BOOL isSuccess = VARIANT_FALSE;
if (FAILED((hr = pDoc->loadXML(L"<Config xmlns=\"http://www.microsoft.com/provisioning/EapHostConfig\"><EAPIdentityProviderList xmlns=\"urn:ietf:params:xml:ns:yang:ietf-eap-metadata\"></EAPIdentityProviderList></Config>", &isSuccess)))) { if (FAILED((hr = pConfigDoc->loadXML(L"<Config xmlns=\"http://www.microsoft.com/provisioning/EapHostConfig\"></Config>", &isSuccess)))) {
g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = HRESULT_CODE(hr), _T(__FUNCTION__) _T(" Error loading XML document template."))); g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = HRESULT_CODE(hr), _T(__FUNCTION__) _T(" Error loading XML document template.")));
return dwResult; return dwResult;
} }
@@ -214,16 +214,16 @@ DWORD WINAPI EapPeerConfigBlob2Xml(
// Select <Config> node. // Select <Config> node.
com_obj<IXMLDOMNode> pXmlElConfig; com_obj<IXMLDOMNode> pXmlElConfig;
pDoc->setProperty(bstr(L"SelectionNamespaces"), variant(L"xmlns:eaphostconfig=\"http://www.microsoft.com/provisioning/EapHostConfig\"")); pConfigDoc->setProperty(bstr(L"SelectionNamespaces"), variant(L"xmlns:eaphostconfig=\"http://www.microsoft.com/provisioning/EapHostConfig\""));
if (FAILED(eapxml::select_node(pDoc, bstr(L"eaphostconfig:Config"), &pXmlElConfig))) { if (FAILED(eapxml::select_node(pConfigDoc, bstr(L"eaphostconfig:Config"), &pXmlElConfig))) {
g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_NOT_FOUND, _T(__FUNCTION__) _T(" Error selecting <Config> element."))); g_peer.log_error(*ppEapError = g_peer.make_error(dwResult = ERROR_NOT_FOUND, _T(__FUNCTION__) _T(" Error selecting <Config> element.")));
return dwResult; return dwResult;
} }
// Save configuration. // Save configuration.
pDoc->setProperty(bstr(L"SelectionNamespaces"), variant(L"xmlns:eap-metadata=\"urn:ietf:params:xml:ns:yang:ietf-eap-metadata\"")); pConfigDoc->setProperty(bstr(L"SelectionNamespaces"), variant(L"xmlns:eap-metadata=\"urn:ietf:params:xml:ns:yang:ietf-eap-metadata\""));
try { try {
g_peer.config_blob2xml(dwFlags, pConnectionData, dwConnectionDataSize, pDoc, pXmlElConfig); g_peer.config_blob2xml(dwFlags, pConnectionData, dwConnectionDataSize, pConfigDoc, pXmlElConfig);
} catch (std::exception &err) { } catch (std::exception &err) {
g_peer.log_error(*ppEapError = g_peer.make_error(err)); g_peer.log_error(*ppEapError = g_peer.make_error(err));
return dwResult = (*ppEapError)->dwWinError; return dwResult = (*ppEapError)->dwWinError;
@@ -231,7 +231,7 @@ DWORD WINAPI EapPeerConfigBlob2Xml(
return dwResult = ERROR_INVALID_DATA; return dwResult = ERROR_INVALID_DATA;
} }
*ppConfigDoc = pDoc.detach(); *ppConfigDoc = pConfigDoc.detach();
} }
return dwResult; return dwResult;

View File

@@ -31,7 +31,7 @@ using namespace winstd;
// Local helper functions declarations // Local helper functions declarations
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
static tstring MapToString(_In_ const EVENT_MAP_INFO *pMapInfo, _In_ LPCBYTE pData); static tstring MapToString(_In_ const EVENT_MAP_INFO *pMapInfo, _In_ ULONG ulData);
static tstring DataToString(_In_ USHORT InType, _In_ USHORT OutType, _In_count_(nDataSize) LPCBYTE pData, _In_ SIZE_T nDataSize, _In_ const EVENT_MAP_INFO *pMapInfo, _In_ BYTE nPtrSize); static tstring DataToString(_In_ USHORT InType, _In_ USHORT OutType, _In_count_(nDataSize) LPCBYTE pData, _In_ SIZE_T nDataSize, _In_ const EVENT_MAP_INFO *pMapInfo, _In_ BYTE nPtrSize);
static ULONG GetArraySize(PEVENT_RECORD pEvent, PTRACE_EVENT_INFO pInfo, ULONG i, ULONG *pulArraySize); static ULONG GetArraySize(PEVENT_RECORD pEvent, PTRACE_EVENT_INFO pInfo, ULONG i, ULONG *pulArraySize);
static tstring PropertyToString(PEVENT_RECORD pEvent, PTRACE_EVENT_INFO pInfo, ULONG ulPropIndex, LPWSTR pStructureName, ULONG ulStructIndex, BYTE nPtrSize); static tstring PropertyToString(PEVENT_RECORD pEvent, PTRACE_EVENT_INFO pInfo, ULONG ulPropIndex, LPWSTR pStructureName, ULONG ulStructIndex, BYTE nPtrSize);
@@ -762,18 +762,18 @@ bool wxPersistentETWListCtrl::Restore()
// Local helper functions // Local helper functions
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
static tstring MapToString(_In_ const EVENT_MAP_INFO *pMapInfo, _In_ LPCBYTE pData) static tstring MapToString(_In_ const EVENT_MAP_INFO *pMapInfo, _In_ ULONG ulData)
{ {
if ( (pMapInfo->Flag & EVENTMAP_INFO_FLAG_MANIFEST_VALUEMAP) || if ( (pMapInfo->Flag & EVENTMAP_INFO_FLAG_MANIFEST_VALUEMAP) ||
((pMapInfo->Flag & EVENTMAP_INFO_FLAG_WBEM_VALUEMAP ) && (pMapInfo->Flag & ~EVENTMAP_INFO_FLAG_WBEM_VALUEMAP) != EVENTMAP_INFO_FLAG_WBEM_FLAG)) ((pMapInfo->Flag & EVENTMAP_INFO_FLAG_WBEM_VALUEMAP ) && (pMapInfo->Flag & ~EVENTMAP_INFO_FLAG_WBEM_VALUEMAP) != EVENTMAP_INFO_FLAG_WBEM_FLAG))
{ {
if ((pMapInfo->Flag & EVENTMAP_INFO_FLAG_WBEM_NO_MAP) == EVENTMAP_INFO_FLAG_WBEM_NO_MAP) if ((pMapInfo->Flag & EVENTMAP_INFO_FLAG_WBEM_NO_MAP) == EVENTMAP_INFO_FLAG_WBEM_NO_MAP)
return tstring_printf(_T("%ls"), (PBYTE)pMapInfo + pMapInfo->MapEntryArray[*(PULONG)pData].OutputOffset); return tstring_printf(_T("%ls"), (PBYTE)pMapInfo + pMapInfo->MapEntryArray[ulData].OutputOffset);
else { else {
for (ULONG i = 0; ; i++) { for (ULONG i = 0; ; i++) {
if (i >= pMapInfo->EntryCount) if (i >= pMapInfo->EntryCount)
return tstring_printf(_T("%lu"), *(PULONG)pData); return tstring_printf(_T("%lu"), ulData);
else if (pMapInfo->MapEntryArray[i].Value == *(PULONG)pData) else if (pMapInfo->MapEntryArray[i].Value == ulData)
return tstring_printf(_T("%ls"), (PBYTE)pMapInfo + pMapInfo->MapEntryArray[i].OutputOffset); return tstring_printf(_T("%ls"), (PBYTE)pMapInfo + pMapInfo->MapEntryArray[i].OutputOffset);
} }
} }
@@ -786,15 +786,15 @@ static tstring MapToString(_In_ const EVENT_MAP_INFO *pMapInfo, _In_ LPCBYTE pDa
if (pMapInfo->Flag & EVENTMAP_INFO_FLAG_WBEM_NO_MAP) { if (pMapInfo->Flag & EVENTMAP_INFO_FLAG_WBEM_NO_MAP) {
for (ULONG i = 0; i < pMapInfo->EntryCount; i++) for (ULONG i = 0; i < pMapInfo->EntryCount; i++)
if (*(PULONG)pData & (1 << i)) if (ulData & (1 << i))
out.append(tstring_printf(out.empty() ? _T("%ls") : _T(" | %ls"), (PBYTE)pMapInfo + pMapInfo->MapEntryArray[i].OutputOffset)); out.append(tstring_printf(out.empty() ? _T("%ls") : _T(" | %ls"), (PBYTE)pMapInfo + pMapInfo->MapEntryArray[i].OutputOffset));
} else { } else {
for (ULONG i = 0; i < pMapInfo->EntryCount; i++) for (ULONG i = 0; i < pMapInfo->EntryCount; i++)
if ((pMapInfo->MapEntryArray[i].Value & *(PULONG)pData) == pMapInfo->MapEntryArray[i].Value) if ((pMapInfo->MapEntryArray[i].Value & ulData) == pMapInfo->MapEntryArray[i].Value)
out.append(tstring_printf(out.empty() ? _T("%ls") : _T(" | %ls"), (PBYTE)pMapInfo + pMapInfo->MapEntryArray[i].OutputOffset)); out.append(tstring_printf(out.empty() ? _T("%ls") : _T(" | %ls"), (PBYTE)pMapInfo + pMapInfo->MapEntryArray[i].OutputOffset));
} }
return out.empty() ? tstring_printf(_T("%lu"), *(PULONG)pData) : out; return out.empty() ? tstring_printf(_T("%lu"), ulData) : out;
} }
return _T("<unknown map>"); return _T("<unknown map>");
@@ -875,7 +875,7 @@ static tstring DataToString(_In_ USHORT InType, _In_ USHORT OutType, _In_count_(
case TDH_OUTTYPE_NTSTATUS : case TDH_OUTTYPE_NTSTATUS :
case TDH_OUTTYPE_HEXINT32 : return tstring_printf(_T("0x%x" ), *(PULONG)pData); case TDH_OUTTYPE_HEXINT32 : return tstring_printf(_T("0x%x" ), *(PULONG)pData);
case TDH_OUTTYPE_IPV4 : return tstring_printf(_T("%d.%d.%d.%d"), (*(PULONG)pData >> 0) & 0xff, (*(PULONG)pData >> 8) & 0xff, (*(PULONG)pData >> 16) & 0xff, (*(PULONG)pData >> 24) & 0xff); case TDH_OUTTYPE_IPV4 : return tstring_printf(_T("%d.%d.%d.%d"), (*(PULONG)pData >> 0) & 0xff, (*(PULONG)pData >> 8) & 0xff, (*(PULONG)pData >> 16) & 0xff, (*(PULONG)pData >> 24) & 0xff);
default: return pMapInfo ? MapToString(pMapInfo, pData) : tstring_printf(_T("%lu"), *(PULONG)pData); default: return pMapInfo ? MapToString(pMapInfo, *(PULONG)pData) : tstring_printf(_T("%lu"), *(PULONG)pData);
} }
case TDH_INTYPE_HEXINT32: case TDH_INTYPE_HEXINT32:
@@ -1105,8 +1105,9 @@ static tstring PropertyToString(PEVENT_RECORD pEvent, PTRACE_EVENT_INFO pInfo, U
// in the EVENT_MAP_ENTRY structure. Replace the trailing space with a null- // in the EVENT_MAP_ENTRY structure. Replace the trailing space with a null-
// terminating character, so that the bit mapped strings are correctly formatted. // terminating character, so that the bit mapped strings are correctly formatted.
for (ULONG i = 0; i < map_info->EntryCount; i++) { for (ULONG i = 0; i < map_info->EntryCount; i++) {
SIZE_T len = _tcslen((LPCTSTR)((PBYTE)map_info.get() + map_info->MapEntryArray[i].OutputOffset)) - 1; LPWSTR str = (LPWSTR)((PBYTE)map_info.get() + map_info->MapEntryArray[i].OutputOffset);
((LPWSTR)((PBYTE)map_info.get() + map_info->MapEntryArray[i].OutputOffset))[len] = 0; SIZE_T len = wcslen(str);
if (len) str[len - 1] = 0;
} }
} }

Binary file not shown.

View File

@@ -1,7 +1,8 @@
#, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: EventMonitor\n" "Project-Id-Version: EventMonitor\n"
"POT-Creation-Date: 2016-08-27 14:20+0200\n" "POT-Creation-Date: 2016-08-31 02:51+0200\n"
"PO-Revision-Date: 2016-06-02 12:27+0200\n" "PO-Revision-Date: 2016-06-02 12:27+0200\n"
"Last-Translator: Simon Rozman <simon.rozman@amebis.si>\n" "Last-Translator: Simon Rozman <simon.rozman@amebis.si>\n"
"Language-Team: Amebis, d. o. o., Kamnik <info@amebis.si>\n" "Language-Team: Amebis, d. o. o., Kamnik <info@amebis.si>\n"
@@ -16,7 +17,7 @@ msgstr ""
"X-Poedit-KeywordsList: _\n" "X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: .\n" "X-Poedit-SearchPath-0: .\n"
#: App.cpp:69 Frame.h:67 MSIBuild/En.Win32.Release.Feature-2.idtx:4 #: App.cpp:61 Frame.h:67 MSIBuild/En.Win32.Release.Feature-2.idtx:4
#: MSIBuild/En.x64.Release.Feature-2.idtx:4 #: MSIBuild/En.x64.Release.Feature-2.idtx:4
msgid "Event Monitor" msgid "Event Monitor"
msgstr "" msgstr ""
@@ -213,8 +214,6 @@ msgid "EVENTM~1|GÉANTLink Event Monitor"
msgstr "" msgstr ""
#: MSIBuild/En.Win32.Release.Feature-2.idtx:4 #: MSIBuild/En.Win32.Release.Feature-2.idtx:4
#: MSIBuild/En.Win32.Release.Shortcut-2.idtx:4
#: MSIBuild/En.x64.Release.Feature-2.idtx:4 #: MSIBuild/En.x64.Release.Feature-2.idtx:4
#: MSIBuild/En.x64.Release.Shortcut-2.idtx:4
msgid "Real-time display of internal events" msgid "Real-time display of internal events"
msgstr "" msgstr ""

View File

@@ -1,9 +1,9 @@
# Translators: #
# Simon Rozman <simon@rozman.si>, 2016 #, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: EventMonitor\n" "Project-Id-Version: EventMonitor\n"
"POT-Creation-Date: 2016-08-27 14:20+0200\n" "POT-Creation-Date: 2016-08-31 02:51+0200\n"
"PO-Revision-Date: 2016-06-02 12:27+0200\n" "PO-Revision-Date: 2016-06-02 12:27+0200\n"
"Last-Translator: Simon Rozman <simon@rozman.si>, 2016\n" "Last-Translator: Simon Rozman <simon@rozman.si>, 2016\n"
"Language-Team: Slovenian (Slovenia) (https://www.transifex.com/eduroam_devel/teams/11799/sl_SI/)\n" "Language-Team: Slovenian (Slovenia) (https://www.transifex.com/eduroam_devel/teams/11799/sl_SI/)\n"
@@ -18,7 +18,7 @@ msgstr ""
"X-Poedit-SearchPath-0: .\n" "X-Poedit-SearchPath-0: .\n"
"X-Poedit-SourceCharset: UTF-8\n" "X-Poedit-SourceCharset: UTF-8\n"
#: App.cpp:69 Frame.h:67 MSIBuild/En.Win32.Release.Feature-2.idtx:4 #: App.cpp:61 Frame.h:67 MSIBuild/En.Win32.Release.Feature-2.idtx:4
#: MSIBuild/En.x64.Release.Feature-2.idtx:4 #: MSIBuild/En.x64.Release.Feature-2.idtx:4
msgid "Event Monitor" msgid "Event Monitor"
msgstr "Nadzornik dogodkov" msgstr "Nadzornik dogodkov"
@@ -221,8 +221,6 @@ msgid "EVENTM~1|GÉANTLink Event Monitor"
msgstr "EVENTM~1|Nadzornik dogodkov GÉANTLink" msgstr "EVENTM~1|Nadzornik dogodkov GÉANTLink"
#: MSIBuild/En.Win32.Release.Feature-2.idtx:4 #: MSIBuild/En.Win32.Release.Feature-2.idtx:4
#: MSIBuild/En.Win32.Release.Shortcut-2.idtx:4
#: MSIBuild/En.x64.Release.Feature-2.idtx:4 #: MSIBuild/En.x64.Release.Feature-2.idtx:4
#: MSIBuild/En.x64.Release.Shortcut-2.idtx:4
msgid "Real-time display of internal events" msgid "Real-time display of internal events"
msgstr "Prikazovalnik notranjih dogodkov v realnem času" msgstr "Prikazovalnik notranjih dogodkov v realnem času"

View File

@@ -2,7 +2,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: GÉANTLink MSI\n" "Project-Id-Version: GÉANTLink MSI\n"
"POT-Creation-Date: 2016-07-15 10:51+0200\n" "POT-Creation-Date: 2016-08-31 14:33+0200\n"
"PO-Revision-Date: 2016-06-02 12:27+0200\n" "PO-Revision-Date: 2016-06-02 12:27+0200\n"
"Last-Translator: Simon Rozman <simon.rozman@amebis.si>\n" "Last-Translator: Simon Rozman <simon.rozman@amebis.si>\n"
"Language-Team: Amebis, d. o. o., Kamnik <info@amebis.si>\n" "Language-Team: Amebis, d. o. o., Kamnik <info@amebis.si>\n"
@@ -17,25 +17,20 @@ msgstr ""
"X-Poedit-KeywordsList: _\n" "X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: .\n" "X-Poedit-SearchPath-0: .\n"
#: En.Win32.Release.Property-2.idtx:6 En.x64.Release.Property-2.idtx:6 #: En.Win32.Release.LaunchCondition-2.idtx:4
msgid "+386 1 8311 035" #: En.x64.Release.LaunchCondition-2.idtx:4
msgid "[ProductName] requires Windows Vista or later version of Windows."
msgstr "" msgstr ""
#: En.Win32.Release.Property-2.idtx:3 En.x64.Release.Property-2.idtx:3 #: En.Win32.Release.Property-2.idtx:3 En.x64.Release.Property-2.idtx:3
#, fuzzy
msgid "1252" msgid "1252"
msgstr "1250"
#: En.Win32.Release.Property-2.idtx:5 En.x64.Release.Property-2.idtx:5
msgid "Amebis, p. p. 69, SI-1241 Kamnik, Slovenia, E.U."
msgstr "" msgstr ""
#: En.Win32.Release.Property-2.idtx:4 En.x64.Release.Property-2.idtx:4 #: En.Win32.Release.Property-2.idtx:4 En.Win32.Release.Property-2.idtx:5
msgid "Amebis, Slovenia, E.U." #: En.x64.Release.Property-2.idtx:4 En.x64.Release.Property-2.idtx:5
msgid "http://www.geant.org/"
msgstr "" msgstr ""
#: En.Win32.Release.Property-2.idtx:7 En.Win32.Release.Property-2.idtx:8 #: En.Win32.Release.Property-2.idtx:6 En.x64.Release.Property-2.idtx:6
#: En.Win32.Release.Property-2.idtx:9 En.x64.Release.Property-2.idtx:7 msgid "https://github.com/Amebis/GEANTLink/releases"
#: En.x64.Release.Property-2.idtx:8 En.x64.Release.Property-2.idtx:9
msgid "http://www.amebis.si/"
msgstr "" msgstr ""

View File

@@ -46,6 +46,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxExtend", "lib\wxExtend\bu
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WLANManager", "WLANManager\WLANManager.vcxproj", "{BFCAA3B4-97A9-4EA9-8FE1-F30280142BCC}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WLANManager", "WLANManager\WLANManager.vcxproj", "{BFCAA3B4-97A9-4EA9-8FE1-F30280142BCC}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MSCHAPv2", "lib\MSCHAPv2\build\MSCHAPv2.vcxproj", "{86A6D6A0-4B7D-4134-BE81-A5755C77584D}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MSCHAPv2_UI", "lib\MSCHAPv2_UI\build\MSCHAPv2_UI.vcxproj", "{7AF5B922-7C17-428A-97E0-09E3B41A684D}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32 Debug|Win32 = Debug|Win32
@@ -190,6 +194,22 @@ Global
{BFCAA3B4-97A9-4EA9-8FE1-F30280142BCC}.Release|Win32.Build.0 = Release|Win32 {BFCAA3B4-97A9-4EA9-8FE1-F30280142BCC}.Release|Win32.Build.0 = Release|Win32
{BFCAA3B4-97A9-4EA9-8FE1-F30280142BCC}.Release|x64.ActiveCfg = Release|x64 {BFCAA3B4-97A9-4EA9-8FE1-F30280142BCC}.Release|x64.ActiveCfg = Release|x64
{BFCAA3B4-97A9-4EA9-8FE1-F30280142BCC}.Release|x64.Build.0 = Release|x64 {BFCAA3B4-97A9-4EA9-8FE1-F30280142BCC}.Release|x64.Build.0 = Release|x64
{86A6D6A0-4B7D-4134-BE81-A5755C77584D}.Debug|Win32.ActiveCfg = Debug|Win32
{86A6D6A0-4B7D-4134-BE81-A5755C77584D}.Debug|Win32.Build.0 = Debug|Win32
{86A6D6A0-4B7D-4134-BE81-A5755C77584D}.Debug|x64.ActiveCfg = Debug|x64
{86A6D6A0-4B7D-4134-BE81-A5755C77584D}.Debug|x64.Build.0 = Debug|x64
{86A6D6A0-4B7D-4134-BE81-A5755C77584D}.Release|Win32.ActiveCfg = Release|Win32
{86A6D6A0-4B7D-4134-BE81-A5755C77584D}.Release|Win32.Build.0 = Release|Win32
{86A6D6A0-4B7D-4134-BE81-A5755C77584D}.Release|x64.ActiveCfg = Release|x64
{86A6D6A0-4B7D-4134-BE81-A5755C77584D}.Release|x64.Build.0 = Release|x64
{7AF5B922-7C17-428A-97E0-09E3B41A684D}.Debug|Win32.ActiveCfg = Debug|Win32
{7AF5B922-7C17-428A-97E0-09E3B41A684D}.Debug|Win32.Build.0 = Debug|Win32
{7AF5B922-7C17-428A-97E0-09E3B41A684D}.Debug|x64.ActiveCfg = Debug|x64
{7AF5B922-7C17-428A-97E0-09E3B41A684D}.Debug|x64.Build.0 = Debug|x64
{7AF5B922-7C17-428A-97E0-09E3B41A684D}.Release|Win32.ActiveCfg = Release|Win32
{7AF5B922-7C17-428A-97E0-09E3B41A684D}.Release|Win32.Build.0 = Release|Win32
{7AF5B922-7C17-428A-97E0-09E3B41A684D}.Release|x64.ActiveCfg = Release|x64
{7AF5B922-7C17-428A-97E0-09E3B41A684D}.Release|x64.Build.0 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@@ -208,6 +228,8 @@ Global
{9A25C261-8ADE-4938-8393-E857EF0E37E9} = {E66A3FE1-4EE4-401F-8EAD-BE518B230393} {9A25C261-8ADE-4938-8393-E857EF0E37E9} = {E66A3FE1-4EE4-401F-8EAD-BE518B230393}
{42F0F0F4-C928-4860-A4E4-94991C2C3D90} = {E66A3FE1-4EE4-401F-8EAD-BE518B230393} {42F0F0F4-C928-4860-A4E4-94991C2C3D90} = {E66A3FE1-4EE4-401F-8EAD-BE518B230393}
{D3E29951-D9F5-486D-A167-20AE8E90B1FA} = {E66A3FE1-4EE4-401F-8EAD-BE518B230393} {D3E29951-D9F5-486D-A167-20AE8E90B1FA} = {E66A3FE1-4EE4-401F-8EAD-BE518B230393}
{86A6D6A0-4B7D-4134-BE81-A5755C77584D} = {E66A3FE1-4EE4-401F-8EAD-BE518B230393}
{7AF5B922-7C17-428A-97E0-09E3B41A684D} = {E66A3FE1-4EE4-401F-8EAD-BE518B230393}
{2D3CE079-7EB1-4F47-B79E-F0310671ECCB} = {7B5EC9B7-208C-426A-941D-DAF9271BD4A4} {2D3CE079-7EB1-4F47-B79E-F0310671ECCB} = {7B5EC9B7-208C-426A-941D-DAF9271BD4A4}
{679D03C5-CD70-4FFA-93F8-A4AB3637509B} = {7B5EC9B7-208C-426A-941D-DAF9271BD4A4} {679D03C5-CD70-4FFA-93F8-A4AB3637509B} = {7B5EC9B7-208C-426A-941D-DAF9271BD4A4}
{E0D0725B-B2FC-4225-9481-CA9B1B6306F2} = {7B5EC9B7-208C-426A-941D-DAF9271BD4A4} {E0D0725B-B2FC-4225-9481-CA9B1B6306F2} = {7B5EC9B7-208C-426A-941D-DAF9271BD4A4}

View File

@@ -29,7 +29,7 @@
// Product version as a single DWORD // Product version as a single DWORD
// Note: Used for version comparison within C/C++ code. // Note: Used for version comparison within C/C++ code.
// //
#define PRODUCT_VERSION 0x00ff0f00 #define PRODUCT_VERSION 0x00ff1100
// //
// Product version by components // Product version by components
@@ -39,26 +39,26 @@
// //
#define PRODUCT_VERSION_MAJ 0 #define PRODUCT_VERSION_MAJ 0
#define PRODUCT_VERSION_MIN 255 #define PRODUCT_VERSION_MIN 255
#define PRODUCT_VERSION_REV 15 #define PRODUCT_VERSION_REV 17
#define PRODUCT_VERSION_BUILD 0 #define PRODUCT_VERSION_BUILD 0
// //
// Human readable product version and build year for UI // Human readable product version and build year for UI
// //
#define PRODUCT_VERSION_STR "1.0-alpha15" #define PRODUCT_VERSION_STR "1.0-alpha17"
#define PRODUCT_BUILD_YEAR_STR "2016" #define PRODUCT_BUILD_YEAR_STR "2016"
// //
// Numerical version presentation for ProductVersion propery in // Numerical version presentation for ProductVersion propery in
// MSI packages (syntax: N.N[.N[.N]]) // MSI packages (syntax: N.N[.N[.N]])
// //
#define PRODUCT_VERSION_INST "0.255.15" #define PRODUCT_VERSION_INST "0.255.17"
// //
// The product code for ProductCode property in MSI packages // The product code for ProductCode property in MSI packages
// Replace with new on every version change, regardless how minor it is. // Replace with new on every version change, regardless how minor it is.
// //
#define PRODUCT_VERSION_GUID "{2C45C10E-80B7-4E3B-A06F-08A1A795EDE5}" #define PRODUCT_VERSION_GUID "{7968E51E-8A49-4316-9444-057295392387}"
// //
// Product vendor // Product vendor

View File

@@ -90,6 +90,7 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="..\src\Config.cpp" /> <ClCompile Include="..\src\Config.cpp" />
<ClCompile Include="..\src\Credentials.cpp" /> <ClCompile Include="..\src\Credentials.cpp" />
<ClCompile Include="..\src\EAP.cpp" />
<ClCompile Include="..\src\Module.cpp" /> <ClCompile Include="..\src\Module.cpp" />
<ClCompile Include="..\src\Method.cpp" /> <ClCompile Include="..\src\Method.cpp" />
<ClCompile Include="..\src\StdAfx.cpp"> <ClCompile Include="..\src\StdAfx.cpp">

View File

@@ -49,5 +49,8 @@
<ClCompile Include="..\src\Module.cpp"> <ClCompile Include="..\src\Module.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\src\EAP.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -89,6 +89,7 @@ inline void operator>>(_Inout_ eap::cursor_in &cursor, _Out_ eap::config &val);
#include <eaptypes.h> // Must include after <Windows.h> #include <eaptypes.h> // Must include after <Windows.h>
#include <tchar.h> #include <tchar.h>
#include <list>
#include <string> #include <string>
#include <memory> #include <memory>
@@ -192,6 +193,9 @@ namespace eap
public: public:
module &m_module; ///< EAP module module &m_module; ///< EAP module
protected:
static const winstd::bstr namespace_eapmetadata;
}; };
@@ -450,9 +454,25 @@ namespace eap
/// @} /// @}
///
/// Returns provider namespace and ID concatenated
///
inline std::wstring get_id() const
{
if (m_namespace.empty())
return m_id;
else {
std::wstring id(m_namespace);
id += L':';
id += m_id;
return id;
}
}
public: public:
std::wstring m_namespace; ///< Provider namespace URI
std::wstring m_id; ///< Provider ID
bool m_read_only; ///< Is profile read-only bool m_read_only; ///< Is profile read-only
std::wstring m_id; ///< Profile ID
winstd::tstring m_name; ///< Provider name winstd::tstring m_name; ///< Provider name
winstd::tstring m_help_email; ///< Helpdesk e-mail winstd::tstring m_help_email; ///< Helpdesk e-mail
winstd::tstring m_help_web; ///< Helpdesk website URL winstd::tstring m_help_web; ///< Helpdesk website URL
@@ -466,6 +486,9 @@ namespace eap
class config_connection : public config class config_connection : public config
{ {
public:
typedef std::list<eap::config_provider> provider_list;
public: public:
/// ///
/// Constructs configuration /// Constructs configuration
@@ -560,7 +583,7 @@ namespace eap
/// @} /// @}
public: public:
std::vector<eap::config_provider> m_providers; ///< Array of provider configurations std::list<eap::config_provider> m_providers; ///< Provider configurations
}; };
} }

View File

@@ -31,6 +31,11 @@ namespace eap
/// Password based method credentials /// Password based method credentials
/// ///
class credentials_pass; class credentials_pass;
///
/// Connection credentials
///
class credentials_connection;
} }
#pragma once #pragma once
@@ -47,6 +52,7 @@ namespace eap
#include <tchar.h> #include <tchar.h>
#include <wincred.h> #include <wincred.h>
#include <memory>
#include <string> #include <string>
@@ -372,4 +378,133 @@ namespace eap
static const unsigned char s_entropy[1024]; static const unsigned char s_entropy[1024];
/// \endcond /// \endcond
}; };
class credentials_connection : public config
{
public:
///
/// Constructs credentials
///
/// \param[in] mod EAP module to use for global services
/// \param[in] cfg Connection configuration
///
credentials_connection(_In_ module &mod, _In_ const config_connection &cfg);
///
/// Copies credentials
///
/// \param[in] other Credentials to copy from
///
credentials_connection(_In_ const credentials_connection &other);
///
/// Moves credentials
///
/// \param[in] other Credentials to move from
///
credentials_connection(_Inout_ credentials_connection &&other);
///
/// Copies credentials
///
/// \param[in] other Credentials to copy from
///
/// \returns Reference to this object
///
credentials_connection& operator=(_In_ const credentials_connection &other);
///
/// Moves credentials
///
/// \param[in] other Credentials to move from
///
/// \returns Reference to this object
///
credentials_connection& operator=(_Inout_ credentials_connection &&other);
///
/// Clones configuration
///
/// \returns Pointer to cloned configuration
///
virtual config* clone() const;
/// \name XML configuration management
/// @{
///
/// Save to XML document
///
/// \param[in] pDoc XML document
/// \param[in] pConfigRoot Suggested root element for saving
///
virtual void save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pConfigRoot) const;
///
/// Load from XML document
///
/// \param[in] pConfigRoot Root element for loading
///
virtual void load(_In_ IXMLDOMNode *pConfigRoot);
/// @}
/// \name BLOB management
/// @{
///
/// Packs a configuration
///
/// \param[inout] cursor Memory cursor
///
virtual void operator<<(_Inout_ cursor_out &cursor) const;
///
/// Returns packed size of a configuration
///
/// \returns Size of data when packed (in bytes)
///
virtual size_t get_pk_size() const;
///
/// Unpacks a configuration
///
/// \param[inout] cursor Memory cursor
///
virtual void operator>>(_Inout_ cursor_in &cursor);
/// @}
///
/// Returns provider namespace and ID concatenated
///
inline std::wstring get_id() const
{
if (m_namespace.empty())
return m_id;
else {
std::wstring id(m_namespace);
id += L':';
id += m_id;
return id;
}
}
///
/// Checks if credentials match given provider.
///
inline bool match(_In_ const config_provider &cfg_provider) const
{
return
_wcsicmp(m_namespace.c_str(), cfg_provider.m_namespace.c_str()) == 0 &&
_wcsicmp(m_id .c_str(), cfg_provider.m_id .c_str()) == 0;
}
public:
const config_connection& m_cfg; ///< Connection configuration
std::wstring m_namespace; ///< Provider namespace URI
std::wstring m_id; ///< Provider ID
std::unique_ptr<credentials> m_cred; ///< Credentials
};
} }

View File

@@ -82,9 +82,19 @@ namespace eap
enum diameter_avp_flags_t; enum diameter_avp_flags_t;
/// ///
/// Diameter AVP /// Diameter AVP header
/// ///
struct diameter_avp; struct diameter_avp_header;
///
/// Diameter AVP header with Vendor-ID
///
struct diameter_avp_header_ven;
///
/// EAP packet
///
class packet;
} }
/// ///
@@ -418,15 +428,23 @@ inline void operator>>(_Inout_ eap::cursor_in &cursor, _Out_ GUID &val);
#ifndef htonll #ifndef htonll
/// ///
/// Convert host converts an unsigned __int64 from host to TCP/IP network byte order. /// Converts an unsigned __int64 from host to TCP/IP network byte order.
/// ///
/// \param[in] val A 64-bit unsigned number in host byte order. /// \param[in] val A 64-bit unsigned number in host byte order
/// ///
/// \returns The value in TCP/IP's network byte order. /// \returns The value in TCP/IP's network byte order
/// ///
inline unsigned __int64 htonll(unsigned __int64 val); inline unsigned __int64 htonll(unsigned __int64 val);
#endif #endif
///
/// Converts an 24-bit integer from host to TCP/IP network byte order.
///
/// \param[in ] val A 24-bit unsigned number in host byte order
/// \param[out] out A 24-bit unsigned number in network byte order
///
inline void hton24(_In_ unsigned int val, _Out_ unsigned char out[3]);
#pragma once #pragma once
@@ -615,29 +633,79 @@ namespace eap
enum diameter_avp_flags_t : unsigned char { enum diameter_avp_flags_t : unsigned char {
diameter_avp_flag_vendor = 0x80, ///< Vendor-ID present diameter_avp_flag_vendor = 0x80, ///< Vendor-ID present
diameter_avp_flag_mandatory = 0x40, ///< Mandatory diameter_avp_flag_mandatory = 0x40, ///< Mandatory
diameter_avp_flag_protected = 0x20, ///< Protected
}; };
#pragma pack(push) #pragma pack(push)
#pragma pack(1) #pragma pack(1)
struct diameter_avp
{
unsigned char code[4]; ///< AVP Code
unsigned char flags; ///< AVP Flags
unsigned char length[3]; ///< AVP Length
#pragma warning(push) struct diameter_avp_header
#pragma warning(disable: 4201) {
union { unsigned char code[4]; ///< AVP Code
struct { unsigned char flags; ///< AVP Flags
unsigned char vendor[4]; ///< Vendor-ID unsigned char length[3]; ///< AVP Length
unsigned char v_data[1]; ///< Data (when Vendor-ID present)
};
unsigned char data[1]; ///< Data (when Vendor-ID absent)
};
#pragma warning(pop)
}; };
struct diameter_avp_header_ven : public diameter_avp_header
{
unsigned char vendor[4]; ///< Vendor-ID
};
#pragma pack(pop) #pragma pack(pop)
class packet
{
public:
///
/// Constructs an empty packet
///
packet();
///
/// Copies a packet
///
/// \param[in] other Packet to copy from
///
packet(_In_ const packet &other);
///
/// Moves a packet
///
/// \param[in] other Packet to move from
///
packet(_Inout_ packet &&other);
///
/// Copies a packet
///
/// \param[in] other Packet to copy from
///
/// \returns Reference to this object
///
packet& operator=(_In_ const packet &other);
///
/// Moves a packet
///
/// \param[in] other Packet to move from
///
/// \returns Reference to this object
///
packet& operator=(_Inout_ packet &&other);
///
/// Empty the packet
///
virtual void clear();
public:
EapCode m_code; ///< Packet code
unsigned char m_id; ///< Packet ID
sanitizing_blob m_data; ///< Packet data
};
} }
@@ -1036,4 +1104,13 @@ inline unsigned __int64 htonll(unsigned __int64 val)
#endif #endif
inline void hton24(_In_ unsigned int val, _Out_ unsigned char out[3])
{
assert(val <= 0xffffff);
out[0] = (val >> 16) & 0xff;
out[1] = (val >> 8) & 0xff;
out[2] = (val ) & 0xff;
}
#endif #endif

View File

@@ -48,6 +48,17 @@ namespace eapxml
inline HRESULT put_element_value(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pCurrentDOMNode, _In_z_ const BSTR bstrElementName, _In_opt_z_ const BSTR bstrNamespace, _In_ bool bValue); inline HRESULT put_element_value(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pCurrentDOMNode, _In_z_ const BSTR bstrElementName, _In_opt_z_ const BSTR bstrNamespace, _In_ bool bValue);
inline HRESULT put_element_base64(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pCurrentDOMNode, _In_z_ const BSTR bstrElementName, _In_opt_z_ const BSTR bstrNamespace, _In_count_(nValueLen) LPCVOID pValue, _In_ SIZE_T nValueLen); inline HRESULT put_element_base64(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pCurrentDOMNode, _In_z_ const BSTR bstrElementName, _In_opt_z_ const BSTR bstrNamespace, _In_count_(nValueLen) LPCVOID pValue, _In_ SIZE_T nValueLen);
inline HRESULT put_element_hex(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pCurrentDOMNode, _In_z_ const BSTR bstrElementName, _In_opt_z_ const BSTR bstrNamespace, _In_count_(nValueLen) LPCVOID pValue, _In_ SIZE_T nValueLen); inline HRESULT put_element_hex(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pCurrentDOMNode, _In_z_ const BSTR bstrElementName, _In_opt_z_ const BSTR bstrNamespace, _In_count_(nValueLen) LPCVOID pValue, _In_ SIZE_T nValueLen);
inline HRESULT get_attrib_value(_In_ IXMLDOMNode *pXmlParent, _In_z_ const BSTR bstrAttributeName, _Out_ BSTR *pbstrValue);
template<class _Traits, class _Ax> inline HRESULT get_attrib_value(_In_ IXMLDOMNode *pXmlParent, _In_z_ const BSTR bstrAttributeName, _Out_ std::basic_string<wchar_t, _Traits, _Ax> &sValue);
inline HRESULT get_attrib_value(_In_ IXMLDOMNode *pXmlParent, _In_z_ const BSTR bstrAttributeName, _Out_ DWORD *pdwValue);
inline HRESULT get_attrib_value(_In_ IXMLDOMNode *pXmlParent, _In_z_ const BSTR bstrAttributeName, _Out_ bool *pbValue);
template<class _Ty, class _Ax> inline HRESULT get_attrib_base64(_In_ IXMLDOMNode *pXmlParent, _In_z_ const BSTR bstrAttributeName, _Out_ std::vector<_Ty, _Ax> &aValue);
template<class _Ty, class _Ax> inline HRESULT get_attrib_hex(_In_ IXMLDOMNode *pXmlParent, _In_z_ const BSTR bstrAttributeName, _Out_ std::vector<_Ty, _Ax> &aValue);
inline HRESULT put_attrib_value(_In_ IXMLDOMNode *pCurrentDOMNode, _In_z_ const BSTR bstrAttributeName, _In_opt_z_ _In_z_ const BSTR bstrValue);
inline HRESULT put_attrib_value(_In_ IXMLDOMNode *pCurrentDOMNode, _In_z_ const BSTR bstrAttributeName, _In_opt_z_ _In_ DWORD dwValue);
inline HRESULT put_attrib_value(_In_ IXMLDOMNode *pCurrentDOMNode, _In_z_ const BSTR bstrAttributeName, _In_opt_z_ _In_ bool bValue);
inline HRESULT put_attrib_base64(_In_ IXMLDOMNode *pCurrentDOMNode, _In_z_ const BSTR bstrAttributeName, _In_opt_z_ _In_count_(nValueLen) LPCVOID pValue, _In_ SIZE_T nValueLen);
inline HRESULT put_attrib_hex(_In_ IXMLDOMNode *pCurrentDOMNode, _In_z_ const BSTR bstrAttributeName, _In_count_(nValueLen) LPCVOID pValue, _In_ SIZE_T nValueLen);
inline std::wstring get_xpath(_In_ IXMLDOMNode *pXmlNode); inline std::wstring get_xpath(_In_ IXMLDOMNode *pXmlNode);
} }
@@ -384,6 +395,144 @@ namespace eapxml
} }
inline HRESULT get_attrib_value(_In_ IXMLDOMNode *pXmlParent, _In_z_ const BSTR bstrAttributeName, _Out_ BSTR *pbstrValue)
{
assert(pbstrValue);
HRESULT hr;
winstd::com_obj<IXMLDOMNamedNodeMap> pXmlAttributes;
winstd::com_obj<IXMLDOMNode> pXmlAt;
VARIANT varValue;
V_VT(&varValue) = VT_EMPTY;
return
SUCCEEDED(hr = pXmlParent->get_attributes(&pXmlAttributes)) ?
SUCCEEDED(hr = pXmlAttributes->getNamedItem(bstrAttributeName, &pXmlAt)) ?
pXmlAt ?
SUCCEEDED(hr = pXmlAt->get_nodeValue(&varValue)) ?
V_VT(&varValue) == VT_BSTR ? *pbstrValue = V_BSTR(&varValue), S_OK : E_UNEXPECTED : hr : E_NOT_SET : hr : hr;
}
template<class _Traits, class _Ax>
inline HRESULT get_attrib_value(_In_ IXMLDOMNode *pXmlParent, _In_z_ const BSTR bstrAttributeName, _Out_ std::basic_string<wchar_t, _Traits, _Ax> &sValue)
{
winstd::bstr bstr;
HRESULT hr = get_attrib_value(pXmlParent, bstrAttributeName, &bstr);
if (SUCCEEDED(hr))
sValue.assign(bstr, bstr.length());
return hr;
}
inline HRESULT get_attrib_value(_In_ IXMLDOMNode *pXmlParent, _In_z_ const BSTR bstrAttributeName, _Out_ DWORD *pdwValue)
{
assert(pdwValue);
winstd::bstr bstr;
HRESULT hr = get_attrib_value(pXmlParent, bstrAttributeName, &bstr);
if (SUCCEEDED(hr))
*pdwValue = wcstoul(bstr, NULL, 10);
return hr;
}
inline HRESULT get_attrib_value(_In_ IXMLDOMNode *pXmlParent, _In_z_ const BSTR bstrAttributeName, _Out_ bool *pbValue)
{
assert(pbValue);
winstd::bstr bstr;
HRESULT hr = get_attrib_value(pXmlParent, bstrAttributeName, &bstr);
if (SUCCEEDED(hr)) {
if (CompareStringEx(LOCALE_NAME_INVARIANT, NORM_IGNORECASE, bstr, bstr.length(), L"true" , -1, NULL, NULL, 0) == CSTR_EQUAL ||
CompareStringEx(LOCALE_NAME_INVARIANT, NORM_IGNORECASE, bstr, bstr.length(), L"1" , -1, NULL, NULL, 0) == CSTR_EQUAL)
*pbValue = true;
else if (
CompareStringEx(LOCALE_NAME_INVARIANT, NORM_IGNORECASE, bstr, bstr.length(), L"false", -1, NULL, NULL, 0) == CSTR_EQUAL ||
CompareStringEx(LOCALE_NAME_INVARIANT, NORM_IGNORECASE, bstr, bstr.length(), L"0" , -1, NULL, NULL, 0) == CSTR_EQUAL)
*pbValue = false;
else
hr = E_NOT_VALID_STATE;
}
return hr;
}
template<class _Ty, class _Ax>
inline HRESULT get_attrib_base64(_In_ IXMLDOMNode *pXmlParent, _In_z_ const BSTR bstrAttributeName, _Out_ std::vector<_Ty, _Ax> &aValue)
{
winstd::bstr bstr;
HRESULT hr = get_attrib_value(pXmlParent, bstrAttributeName, &bstr);
if (SUCCEEDED(hr)) {
winstd::base64_dec dec;
bool is_last;
dec.decode(aValue, is_last, (BSTR)bstr, bstr.length());
}
return hr;
}
template<class _Ty, class _Ax>
inline HRESULT get_attrib_hex(_In_ IXMLDOMNode *pXmlParent, _In_z_ const BSTR bstrAttributeName, _Out_ std::vector<_Ty, _Ax> &aValue)
{
winstd::bstr bstr;
HRESULT hr = get_attrib_value(pXmlParent, bstrAttributeName, &bstr);
if (SUCCEEDED(hr)) {
winstd::hex_dec dec;
bool is_last;
dec.decode(aValue, is_last, (BSTR)bstr, bstr.length());
}
return hr;
}
inline HRESULT put_attrib_value(_In_ IXMLDOMNode *pCurrentDOMNode, _In_z_ const BSTR bstrAttributeName, _In_z_ const BSTR bstrValue)
{
HRESULT hr;
winstd::com_obj<IXMLDOMElement> pXmlEl;
VARIANT varValue;
V_VT(&varValue) = VT_BSTR;
V_BSTR(&varValue) = bstrValue;
return
SUCCEEDED(hr = pCurrentDOMNode->QueryInterface(__uuidof(IXMLDOMElement), (void**)&pXmlEl)) &&
SUCCEEDED(hr = pXmlEl->setAttribute(bstrAttributeName, varValue)) ? S_OK : hr;
}
inline HRESULT put_attrib_value(_In_ IXMLDOMNode *pCurrentDOMNode, _In_z_ const BSTR bstrAttributeName, _In_ DWORD dwValue)
{
return put_attrib_value(pCurrentDOMNode, bstrAttributeName, winstd::bstr(winstd::wstring_printf(L"%d", dwValue)));
}
inline HRESULT put_attrib_value(_In_ IXMLDOMNode *pCurrentDOMNode, _In_z_ const BSTR bstrAttributeName, _In_ bool bValue)
{
return put_attrib_value(pCurrentDOMNode, bstrAttributeName, winstd::bstr(bValue ? L"true": L"false"));
}
inline HRESULT put_attrib_base64(_In_ IXMLDOMNode *pCurrentDOMNode, _In_z_ const BSTR bstrAttributeName, _In_count_(nValueLen) LPCVOID pValue, _In_ SIZE_T nValueLen)
{
std::wstring sBase64;
winstd::base64_enc enc;
enc.encode(sBase64, pValue, nValueLen);
return put_attrib_value(pCurrentDOMNode, bstrAttributeName, winstd::bstr(sBase64));
}
inline HRESULT put_attrib_hex(_In_ IXMLDOMNode *pCurrentDOMNode, _In_z_ const BSTR bstrAttributeName, _In_count_(nValueLen) LPCVOID pValue, _In_ SIZE_T nValueLen)
{
std::wstring sHex;
winstd::hex_enc enc;
enc.encode(sHex, pValue, nValueLen);
return put_attrib_value(pCurrentDOMNode, bstrAttributeName, winstd::bstr(sHex));
}
inline std::wstring get_xpath(_In_ IXMLDOMNode *pXmlNode) inline std::wstring get_xpath(_In_ IXMLDOMNode *pXmlNode)
{ {
if (pXmlNode) { if (pXmlNode) {

View File

@@ -21,9 +21,14 @@
namespace eap namespace eap
{ {
/// ///
/// EAP method base class /// EAP and non-EAP method base class
/// ///
class method; class method;
///
/// Non-EAP method base class
///
class method_noneap;
} }
#pragma once #pragma once
@@ -84,7 +89,7 @@ namespace eap
_In_ DWORD dwFlags, _In_ DWORD dwFlags,
_In_ const EapAttributes *pAttributeArray, _In_ const EapAttributes *pAttributeArray,
_In_ HANDLE hTokenImpersonateUser, _In_ HANDLE hTokenImpersonateUser,
_In_ DWORD dwMaxSendPacketSize); _In_opt_ DWORD dwMaxSendPacketSize = MAXDWORD);
/// ///
/// Ends an EAP authentication session for the EAP method. /// Ends an EAP authentication session for the EAP method.
@@ -99,7 +104,7 @@ namespace eap
/// \sa [EapPeerProcessRequestPacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363621.aspx) /// \sa [EapPeerProcessRequestPacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363621.aspx)
/// ///
virtual void process_request_packet( virtual void process_request_packet(
_In_bytecount_(dwReceivedPacketSize) const EapPacket *pReceivedPacket, _In_bytecount_(dwReceivedPacketSize) const void *pReceivedPacket,
_In_ DWORD dwReceivedPacketSize, _In_ DWORD dwReceivedPacketSize,
_Inout_ EapPeerMethodOutput *pEapOutput) = 0; _Inout_ EapPeerMethodOutput *pEapOutput) = 0;
@@ -109,8 +114,8 @@ namespace eap
/// \sa [EapPeerGetResponsePacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363610.aspx) /// \sa [EapPeerGetResponsePacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363610.aspx)
/// ///
virtual void get_response_packet( virtual void get_response_packet(
_Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket, _Inout_bytecap_(*dwSendPacketSize) void *pSendPacket,
_Inout_ DWORD *pdwSendPacketSize) = 0; _Inout_ DWORD *pdwSendPacketSize) = 0;
/// ///
/// Obtains the result of an authentication session from the EAP method. /// Obtains the result of an authentication session from the EAP method.
@@ -134,4 +139,73 @@ namespace eap
credentials &m_cred; ///< User credentials credentials &m_cred; ///< User credentials
std::vector<winstd::eap_attr> m_eap_attr; ///< EAP attributes std::vector<winstd::eap_attr> m_eap_attr; ///< EAP attributes
}; };
class method_noneap : public method
{
public:
///
/// Constructs an EAP method
///
/// \param[in] mod EAP module to use for global services
/// \param[in] cfg Method configuration
/// \param[in] cred User credentials
///
method_noneap(_In_ module &module, _In_ config_method_with_cred &cfg, _In_ credentials &cred);
///
/// Moves an EAP method
///
/// \param[in] other EAP method to move from
///
method_noneap(_Inout_ method_noneap &&other);
///
/// Moves an EAP method
///
/// \param[in] other EAP method to move from
///
/// \returns Reference to this object
///
method_noneap& operator=(_Inout_ method_noneap &&other);
/// \name Packet processing
/// @{
///
/// Obtains a response packet from the EAP method.
///
/// \sa [EapPeerGetResponsePacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363610.aspx)
///
virtual void get_response_packet(
_Inout_bytecap_(*dwSendPacketSize) void *pSendPacket,
_Inout_ DWORD *pdwSendPacketSize);
/// @}
protected:
///
/// Appends Diameter AVP to response packet
///
/// \param[in] code AVP code
/// \param[in] flags AVP flags
/// \param[in] data AVP data (<16777212B)
/// \param[in] size Size of \p data in bytes
///
void append_avp(_In_ unsigned int code, _In_ unsigned char flags, _In_bytecount_(size) const void *data, _In_ unsigned int size);
///
/// Appends Diameter AVP to response packet
///
/// \param[in] code AVP code
/// \param[in] vendor_id Vendor-ID
/// \param[in] flags AVP flags
/// \param[in] data AVP data (<16777212B)
/// \param[in] size Size of \p data in bytes
///
void append_avp(_In_ unsigned int code, _In_ unsigned int vendor_id, _In_ unsigned char flags, _In_bytecount_(size) const void *data, _In_ unsigned int size);
protected:
sanitizing_blob m_packet_res; ///< Response packet
};
} }

View File

@@ -95,6 +95,9 @@ void eap::config::operator>>(_Inout_ cursor_in &cursor)
} }
const bstr eap::config::namespace_eapmetadata(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata");
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// eap::config_method // eap::config_method
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
@@ -156,11 +159,11 @@ eap::config_method_with_cred::config_method_with_cred(_In_ const config_method_w
eap::config_method_with_cred::config_method_with_cred(_Inout_ config_method_with_cred &&other) : eap::config_method_with_cred::config_method_with_cred(_Inout_ config_method_with_cred &&other) :
m_allow_save(std::move(other.m_allow_save)), m_allow_save (std::move(other.m_allow_save )),
m_use_preshared(std::move(other.m_use_preshared)), m_use_preshared(std::move(other.m_use_preshared)),
m_preshared(std::move(other.m_preshared)), m_preshared (std::move(other.m_preshared )),
m_auth_failed(std::move(other.m_auth_failed)), m_auth_failed (std::move(other.m_auth_failed )),
config_method(std::move(other)) config_method (std::move(other ))
{ {
} }
@@ -198,16 +201,15 @@ void eap::config_method_with_cred::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOM
assert(pDoc); assert(pDoc);
assert(pConfigRoot); assert(pConfigRoot);
const winstd::bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata");
HRESULT hr; HRESULT hr;
// <ClientSideCredential> // <ClientSideCredential>
winstd::com_obj<IXMLDOMElement> pXmlElClientSideCredential; winstd::com_obj<IXMLDOMElement> pXmlElClientSideCredential;
if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, winstd::bstr(L"eap-metadata:ClientSideCredential"), winstd::bstr(L"ClientSideCredential"), bstrNamespace, &pXmlElClientSideCredential))) if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, winstd::bstr(L"eap-metadata:ClientSideCredential"), winstd::bstr(L"ClientSideCredential"), namespace_eapmetadata, &pXmlElClientSideCredential)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <ClientSideCredential> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <ClientSideCredential> element.");
// <ClientSideCredential>/<allow-save> // <ClientSideCredential>/<allow-save>
if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElClientSideCredential, winstd::bstr(L"allow-save"), bstrNamespace, m_allow_save))) if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElClientSideCredential, winstd::bstr(L"allow-save"), namespace_eapmetadata, m_allow_save)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <allow-save> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <allow-save> element.");
if (m_use_preshared) if (m_use_preshared)
@@ -285,16 +287,17 @@ eap::config_provider::config_provider(_In_ module &mod) :
eap::config_provider::config_provider(_In_ const config_provider &other) : eap::config_provider::config_provider(_In_ const config_provider &other) :
m_read_only(other.m_read_only), m_namespace (other.m_namespace ),
m_id(other.m_id), m_id (other.m_id ),
m_name(other.m_name), m_read_only (other.m_read_only ),
m_help_email(other.m_help_email), m_name (other.m_name ),
m_help_web(other.m_help_web), m_help_email (other.m_help_email ),
m_help_phone(other.m_help_phone), m_help_web (other.m_help_web ),
m_help_phone (other.m_help_phone ),
m_lbl_alt_credential(other.m_lbl_alt_credential), m_lbl_alt_credential(other.m_lbl_alt_credential),
m_lbl_alt_identity(other.m_lbl_alt_identity), m_lbl_alt_identity (other.m_lbl_alt_identity ),
m_lbl_alt_password(other.m_lbl_alt_password), m_lbl_alt_password (other.m_lbl_alt_password ),
config(other) config (other )
{ {
m_methods.reserve(other.m_methods.size()); m_methods.reserve(other.m_methods.size());
for (vector<unique_ptr<config_method> >::const_iterator method = other.m_methods.cbegin(), method_end = other.m_methods.cend(); method != method_end; ++method) for (vector<unique_ptr<config_method> >::const_iterator method = other.m_methods.cbegin(), method_end = other.m_methods.cend(); method != method_end; ++method)
@@ -303,17 +306,18 @@ eap::config_provider::config_provider(_In_ const config_provider &other) :
eap::config_provider::config_provider(_Inout_ config_provider &&other) : eap::config_provider::config_provider(_Inout_ config_provider &&other) :
m_read_only(std::move(other.m_read_only)), m_namespace (std::move(other.m_namespace )),
m_id(std::move(other.m_id)), m_id (std::move(other.m_id )),
m_name(std::move(other.m_name)), m_read_only (std::move(other.m_read_only )),
m_help_email(std::move(other.m_help_email)), m_name (std::move(other.m_name )),
m_help_web(std::move(other.m_help_web)), m_help_email (std::move(other.m_help_email )),
m_help_phone(std::move(other.m_help_phone)), m_help_web (std::move(other.m_help_web )),
m_help_phone (std::move(other.m_help_phone )),
m_lbl_alt_credential(std::move(other.m_lbl_alt_credential)), m_lbl_alt_credential(std::move(other.m_lbl_alt_credential)),
m_lbl_alt_identity(std::move(other.m_lbl_alt_identity)), m_lbl_alt_identity (std::move(other.m_lbl_alt_identity )),
m_lbl_alt_password(std::move(other.m_lbl_alt_password)), m_lbl_alt_password (std::move(other.m_lbl_alt_password )),
m_methods(std::move(other.m_methods)), m_methods (std::move(other.m_methods )),
config(std::move(other)) config (std::move(other ))
{ {
} }
@@ -322,8 +326,9 @@ eap::config_provider& eap::config_provider::operator=(_In_ const config_provider
{ {
if (this != &other) { if (this != &other) {
(config&)*this = other; (config&)*this = other;
m_read_only = other.m_read_only; m_namespace = other.m_namespace;
m_id = other.m_id; m_id = other.m_id;
m_read_only = other.m_read_only;
m_name = other.m_name; m_name = other.m_name;
m_help_email = other.m_help_email; m_help_email = other.m_help_email;
m_help_web = other.m_help_web; m_help_web = other.m_help_web;
@@ -345,17 +350,18 @@ eap::config_provider& eap::config_provider::operator=(_In_ const config_provider
eap::config_provider& eap::config_provider::operator=(_Inout_ config_provider &&other) eap::config_provider& eap::config_provider::operator=(_Inout_ config_provider &&other)
{ {
if (this != &other) { if (this != &other) {
(config&&)*this = std::move(other); (config&&)*this = std::move(other );
m_read_only = std::move(m_read_only); m_namespace = std::move(other.m_namespace );
m_id = std::move(other.m_id); m_id = std::move(other.m_id );
m_name = std::move(other.m_name); m_read_only = std::move(other.m_read_only );
m_help_email = std::move(other.m_help_email); m_name = std::move(other.m_name );
m_help_web = std::move(other.m_help_web); m_help_email = std::move(other.m_help_email );
m_help_phone = std::move(other.m_help_phone); m_help_web = std::move(other.m_help_web );
m_help_phone = std::move(other.m_help_phone );
m_lbl_alt_credential = std::move(other.m_lbl_alt_credential); m_lbl_alt_credential = std::move(other.m_lbl_alt_credential);
m_lbl_alt_identity = std::move(other.m_lbl_alt_identity); m_lbl_alt_identity = std::move(other.m_lbl_alt_identity );
m_lbl_alt_password = std::move(other.m_lbl_alt_password); m_lbl_alt_password = std::move(other.m_lbl_alt_password );
m_methods = std::move(other.m_methods); m_methods = std::move(other.m_methods );
} }
return *this; return *this;
@@ -372,72 +378,76 @@ void eap::config_provider::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pC
{ {
config::save(pDoc, pConfigRoot); config::save(pDoc, pConfigRoot);
const bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata");
HRESULT hr; HRESULT hr;
// <read-only> // namespace
if (FAILED(hr = eapxml::put_element_value(pDoc, pConfigRoot, bstr(L"read-only"), bstrNamespace, m_read_only))) if (!m_namespace.empty())
throw com_runtime_error(hr, __FUNCTION__ " Error creating <read-only> element."); if (FAILED(hr = eapxml::put_attrib_value(pConfigRoot, bstr(L"namespace"), bstr(m_namespace))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating namespace attribute.");
// <ID> // ID
if (!m_id.empty()) if (!m_id.empty())
if (FAILED(hr = eapxml::put_element_value(pDoc, pConfigRoot, bstr(L"ID"), bstrNamespace, bstr(m_id)))) if (FAILED(hr = eapxml::put_attrib_value(pConfigRoot, bstr(L"ID"), bstr(m_id))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <ID> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating ID attribute.");
// <read-only>
if (FAILED(hr = eapxml::put_element_value(pDoc, pConfigRoot, bstr(L"read-only"), namespace_eapmetadata, m_read_only)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <read-only> element.");
// <ProviderInfo> // <ProviderInfo>
com_obj<IXMLDOMElement> pXmlElProviderInfo; com_obj<IXMLDOMElement> pXmlElProviderInfo;
if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:ProviderInfo"), bstr(L"ProviderInfo"), bstrNamespace, &pXmlElProviderInfo))) if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:ProviderInfo"), bstr(L"ProviderInfo"), namespace_eapmetadata, &pXmlElProviderInfo)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <ProviderInfo> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <ProviderInfo> element.");
// <ProviderInfo>/<DisplayName> // <ProviderInfo>/<DisplayName>
if (!m_name.empty()) if (!m_name.empty())
if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElProviderInfo, bstr(L"DisplayName"), bstrNamespace, bstr(m_name)))) if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElProviderInfo, bstr(L"DisplayName"), namespace_eapmetadata, bstr(m_name))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <DisplayName> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <DisplayName> element.");
// <ProviderInfo>/<Helpdesk> // <ProviderInfo>/<Helpdesk>
com_obj<IXMLDOMElement> pXmlElHelpdesk; com_obj<IXMLDOMElement> pXmlElHelpdesk;
if (FAILED(hr = eapxml::create_element(pDoc, pXmlElProviderInfo, bstr(L"eap-metadata:Helpdesk"), bstr(L"Helpdesk"), bstrNamespace, &pXmlElHelpdesk))) if (FAILED(hr = eapxml::create_element(pDoc, pXmlElProviderInfo, bstr(L"eap-metadata:Helpdesk"), bstr(L"Helpdesk"), namespace_eapmetadata, &pXmlElHelpdesk)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <Helpdesk> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <Helpdesk> element.");
// <ProviderInfo>/<Helpdesk>/<EmailAddress> // <ProviderInfo>/<Helpdesk>/<EmailAddress>
if (!m_help_email.empty()) if (!m_help_email.empty())
if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElHelpdesk, bstr(L"EmailAddress"), bstrNamespace, bstr(m_help_email)))) if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElHelpdesk, bstr(L"EmailAddress"), namespace_eapmetadata, bstr(m_help_email))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <EmailAddress> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <EmailAddress> element.");
// <ProviderInfo>/<Helpdesk>/<WebAddress> // <ProviderInfo>/<Helpdesk>/<WebAddress>
if (!m_help_web.empty()) if (!m_help_web.empty())
if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElHelpdesk, bstr(L"WebAddress"), bstrNamespace, bstr(m_help_web)))) if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElHelpdesk, bstr(L"WebAddress"), namespace_eapmetadata, bstr(m_help_web))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <WebAddress> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <WebAddress> element.");
// <ProviderInfo>/<Helpdesk>/<Phone> // <ProviderInfo>/<Helpdesk>/<Phone>
if (!m_help_phone.empty()) if (!m_help_phone.empty())
if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElHelpdesk, bstr(L"Phone"), bstrNamespace, bstr(m_help_phone)))) if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElHelpdesk, bstr(L"Phone"), namespace_eapmetadata, bstr(m_help_phone))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <Phone> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <Phone> element.");
// <ProviderInfo>/<CredentialPrompt> // <ProviderInfo>/<CredentialPrompt>
if (!m_lbl_alt_credential.empty()) if (!m_lbl_alt_credential.empty())
if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElProviderInfo, bstr(L"CredentialPrompt"), bstrNamespace, bstr(m_lbl_alt_credential)))) if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElProviderInfo, bstr(L"CredentialPrompt"), namespace_eapmetadata, bstr(m_lbl_alt_credential))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <CredentialPrompt> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <CredentialPrompt> element.");
// <ProviderInfo>/<UserNameLabel> // <ProviderInfo>/<UserNameLabel>
if (!m_lbl_alt_identity.empty()) if (!m_lbl_alt_identity.empty())
if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElProviderInfo, bstr(L"UserNameLabel"), bstrNamespace, bstr(m_lbl_alt_identity)))) if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElProviderInfo, bstr(L"UserNameLabel"), namespace_eapmetadata, bstr(m_lbl_alt_identity))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <UserNameLabel> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <UserNameLabel> element.");
// <ProviderInfo>/<PasswordLabel> // <ProviderInfo>/<PasswordLabel>
if (!m_lbl_alt_password.empty()) if (!m_lbl_alt_password.empty())
if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElProviderInfo, bstr(L"PasswordLabel"), bstrNamespace, bstr(m_lbl_alt_password)))) if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElProviderInfo, bstr(L"PasswordLabel"), namespace_eapmetadata, bstr(m_lbl_alt_password))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <PasswordLabel> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <PasswordLabel> element.");
// <AuthenticationMethods> // <AuthenticationMethods>
com_obj<IXMLDOMElement> pXmlElAuthenticationMethods; com_obj<IXMLDOMElement> pXmlElAuthenticationMethods;
if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:AuthenticationMethods"), bstr(L"AuthenticationMethods"), bstrNamespace, &pXmlElAuthenticationMethods))) if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:AuthenticationMethods"), bstr(L"AuthenticationMethods"), namespace_eapmetadata, &pXmlElAuthenticationMethods)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <AuthenticationMethods> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <AuthenticationMethods> element.");
for (vector<unique_ptr<config_method> >::const_iterator method = m_methods.cbegin(), method_end = m_methods.cend(); method != method_end; ++method) { for (vector<unique_ptr<config_method> >::const_iterator method = m_methods.cbegin(), method_end = m_methods.cend(); method != method_end; ++method) {
// <AuthenticationMethod> // <AuthenticationMethod>
com_obj<IXMLDOMElement> pXmlElAuthenticationMethod; com_obj<IXMLDOMElement> pXmlElAuthenticationMethod;
if (FAILED(hr = eapxml::create_element(pDoc, bstr(L"AuthenticationMethod"), bstrNamespace, &pXmlElAuthenticationMethod))) if (FAILED(hr = eapxml::create_element(pDoc, bstr(L"AuthenticationMethod"), namespace_eapmetadata, &pXmlElAuthenticationMethod)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <AuthenticationMethod> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <AuthenticationMethod> element.");
// <AuthenticationMethod>/... // <AuthenticationMethod>/...
@@ -457,16 +467,21 @@ void eap::config_provider::load(_In_ IXMLDOMNode *pConfigRoot)
config::load(pConfigRoot); config::load(pConfigRoot);
// namespace
m_namespace.clear();
eapxml::get_attrib_value(pConfigRoot, bstr(L"namespace"), m_namespace);
m_module.log_config((xpath + L" namespace").c_str(), m_namespace.c_str());
// ID
m_id.clear();
eapxml::get_attrib_value(pConfigRoot, bstr(L"ID"), m_id);
m_module.log_config((xpath + L" ID").c_str(), m_id.c_str());
// <read-only> // <read-only>
if (FAILED(hr = eapxml::get_element_value(pConfigRoot, bstr(L"eap-metadata:read-only"), &m_read_only))) if (FAILED(hr = eapxml::get_element_value(pConfigRoot, bstr(L"eap-metadata:read-only"), &m_read_only)))
m_read_only = true; m_read_only = true;
m_module.log_config((xpath + L"/read-only").c_str(), m_read_only); m_module.log_config((xpath + L"/read-only").c_str(), m_read_only);
// <ID>
m_id.clear();
eapxml::get_element_value(pConfigRoot, bstr(L"eap-metadata:ID"), m_id);
m_module.log_config((xpath + L"/ID").c_str(), m_id.c_str());
// <ProviderInfo> // <ProviderInfo>
m_name.clear(); m_name.clear();
m_help_email.clear(); m_help_email.clear();
@@ -549,8 +564,9 @@ void eap::config_provider::load(_In_ IXMLDOMNode *pConfigRoot)
void eap::config_provider::operator<<(_Inout_ cursor_out &cursor) const void eap::config_provider::operator<<(_Inout_ cursor_out &cursor) const
{ {
config::operator<<(cursor); config::operator<<(cursor);
cursor << m_read_only ; cursor << m_namespace ;
cursor << m_id ; cursor << m_id ;
cursor << m_read_only ;
cursor << m_name ; cursor << m_name ;
cursor << m_help_email ; cursor << m_help_email ;
cursor << m_help_web ; cursor << m_help_web ;
@@ -566,8 +582,9 @@ size_t eap::config_provider::get_pk_size() const
{ {
return return
config::get_pk_size() + config::get_pk_size() +
pksizeof(m_read_only ) + pksizeof(m_namespace ) +
pksizeof(m_id ) + pksizeof(m_id ) +
pksizeof(m_read_only ) +
pksizeof(m_name ) + pksizeof(m_name ) +
pksizeof(m_help_email ) + pksizeof(m_help_email ) +
pksizeof(m_help_web ) + pksizeof(m_help_web ) +
@@ -582,8 +599,9 @@ size_t eap::config_provider::get_pk_size() const
void eap::config_provider::operator>>(_Inout_ cursor_in &cursor) void eap::config_provider::operator>>(_Inout_ cursor_in &cursor)
{ {
config::operator>>(cursor); config::operator>>(cursor);
cursor >> m_read_only ; cursor >> m_namespace ;
cursor >> m_id ; cursor >> m_id ;
cursor >> m_read_only ;
cursor >> m_name ; cursor >> m_name ;
cursor >> m_help_email ; cursor >> m_help_email ;
cursor >> m_help_web ; cursor >> m_help_web ;
@@ -619,14 +637,14 @@ eap::config_connection::config_connection(_In_ module &mod) : config(mod)
eap::config_connection::config_connection(_In_ const config_connection &other) : eap::config_connection::config_connection(_In_ const config_connection &other) :
m_providers(other.m_providers), m_providers(other.m_providers),
config(other) config (other )
{ {
} }
eap::config_connection::config_connection(_Inout_ config_connection &&other) : eap::config_connection::config_connection(_Inout_ config_connection &&other) :
m_providers(std::move(other.m_providers)), m_providers(std::move(other.m_providers)),
config(std::move(other)) config (std::move(other ))
{ {
} }
@@ -645,7 +663,7 @@ eap::config_connection& eap::config_connection::operator=(_In_ const config_conn
eap::config_connection& eap::config_connection::operator=(_Inout_ config_connection &&other) eap::config_connection& eap::config_connection::operator=(_Inout_ config_connection &&other)
{ {
if (this != &other) { if (this != &other) {
(config&&)*this = std::move(other); (config&&)*this = std::move(other );
m_providers = std::move(other.m_providers); m_providers = std::move(other.m_providers);
} }
@@ -663,18 +681,17 @@ void eap::config_connection::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *
{ {
config::save(pDoc, pConfigRoot); config::save(pDoc, pConfigRoot);
const bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata");
HRESULT hr; HRESULT hr;
// Select <EAPIdentityProviderList> node. // Create <EAPIdentityProviderList> node.
com_obj<IXMLDOMNode> pXmlElIdentityProviderList; com_obj<IXMLDOMElement> pXmlElIdentityProviderList;
if (FAILED(hr = eapxml::select_node(pConfigRoot, bstr(L"eap-metadata:EAPIdentityProviderList"), &pXmlElIdentityProviderList))) if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:EAPIdentityProviderList"), bstr(L"EAPIdentityProviderList"), namespace_eapmetadata, &pXmlElIdentityProviderList)))
throw com_runtime_error(hr, __FUNCTION__ " Error selecting <EAPIdentityProviderList> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <EAPIdentityProviderList> element.");
for (vector<config_provider>::const_iterator provider = m_providers.cbegin(), provider_end = m_providers.cend(); provider != provider_end; ++provider) { for (provider_list::const_iterator provider = m_providers.cbegin(), provider_end = m_providers.cend(); provider != provider_end; ++provider) {
// <EAPIdentityProvider> // <EAPIdentityProvider>
com_obj<IXMLDOMElement> pXmlElIdentityProvider; com_obj<IXMLDOMElement> pXmlElIdentityProvider;
if (FAILED(hr = eapxml::create_element(pDoc, bstr(L"EAPIdentityProvider"), bstrNamespace, &pXmlElIdentityProvider))) if (FAILED(hr = eapxml::create_element(pDoc, bstr(L"EAPIdentityProvider"), namespace_eapmetadata, &pXmlElIdentityProvider)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <EAPIdentityProvider> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <EAPIdentityProvider> element.");
// <EAPIdentityProvider>/... // <EAPIdentityProvider>/...
@@ -733,10 +750,10 @@ void eap::config_connection::operator>>(_Inout_ cursor_in &cursor)
{ {
config::operator>>(cursor); config::operator>>(cursor);
list<config_provider>::size_type count; provider_list::size_type count;
cursor >> count; cursor >> count;
m_providers.clear(); m_providers.clear();
for (list<config_provider>::size_type i = 0; i < count; i++) { for (provider_list::size_type i = 0; i < count; i++) {
config_provider el(m_module); config_provider el(m_module);
cursor >> el; cursor >> el;
m_providers.push_back(std::move(el)); m_providers.push_back(std::move(el));

View File

@@ -90,12 +90,12 @@ void eap::credentials::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pConfi
config::save(pDoc, pConfigRoot); config::save(pDoc, pConfigRoot);
const bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata");
HRESULT hr; HRESULT hr;
// <UserName> // <UserName>
if (FAILED(hr = eapxml::put_element_value(pDoc, pConfigRoot, bstr(L"UserName"), bstrNamespace, bstr(m_identity)))) if (!m_identity.empty())
throw com_runtime_error(hr, __FUNCTION__ " Error creating <UserName> element."); if (FAILED(hr = eapxml::put_element_value(pDoc, pConfigRoot, bstr(L"UserName"), namespace_eapmetadata, bstr(m_identity))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <UserName> element.");
} }
@@ -145,9 +145,10 @@ wstring eap::credentials::get_identity() const
tstring eap::credentials::get_name() const tstring eap::credentials::get_name() const
{ {
if (empty()) return _T("<empty credentials>");
tstring identity(std::move(get_identity())); tstring identity(std::move(get_identity()));
return !identity.empty() ? identity : _T("<blank identity>"); return
!identity.empty() ? identity :
empty() ? _T("<empty>") : _T("<blank ID>");
} }
@@ -216,12 +217,11 @@ void eap::credentials_pass::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *p
credentials::save(pDoc, pConfigRoot); credentials::save(pDoc, pConfigRoot);
const bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata");
HRESULT hr; HRESULT hr;
// <Password> // <Password>
bstr pass(m_password); bstr pass(m_password);
hr = eapxml::put_element_value(pDoc, pConfigRoot, bstr(L"Password"), bstrNamespace, pass); hr = eapxml::put_element_value(pDoc, pConfigRoot, bstr(L"Password"), namespace_eapmetadata, pass);
SecureZeroMemory((BSTR)pass, sizeof(OLECHAR)*pass.length()); SecureZeroMemory((BSTR)pass, sizeof(OLECHAR)*pass.length());
if (FAILED(hr)) if (FAILED(hr))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <Password> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <Password> element.");
@@ -417,3 +417,179 @@ const unsigned char eap::credentials_pass::s_entropy[1024] = {
0x30, 0x29, 0x39, 0x9a, 0xd6, 0xab, 0x2e, 0xc6, 0x42, 0x47, 0x5e, 0x54, 0xbb, 0x90, 0xe6, 0x98, 0x30, 0x29, 0x39, 0x9a, 0xd6, 0xab, 0x2e, 0xc6, 0x42, 0x47, 0x5e, 0x54, 0xbb, 0x90, 0xe6, 0x98,
0xe6, 0x52, 0x58, 0x58, 0x1e, 0xd0, 0x00, 0x9c, 0x8f, 0x4a, 0x17, 0x7e, 0x8a, 0x5a, 0xef, 0x3e, 0xe6, 0x52, 0x58, 0x58, 0x1e, 0xd0, 0x00, 0x9c, 0x8f, 0x4a, 0x17, 0x7e, 0x8a, 0x5a, 0xef, 0x3e,
}; };
//////////////////////////////////////////////////////////////////////
// eap::credentials_connection
//////////////////////////////////////////////////////////////////////
eap::credentials_connection::credentials_connection(_In_ module &mod, _In_ const config_connection &cfg) :
m_cfg(cfg),
config(mod)
{
}
eap::credentials_connection::credentials_connection(_In_ const credentials_connection &other) :
m_cfg (other.m_cfg ),
m_namespace(other.m_namespace),
m_id (other.m_id ),
m_cred (other.m_cred ? (credentials*)other.m_cred->clone() : nullptr),
config (other )
{
}
eap::credentials_connection::credentials_connection(_Inout_ credentials_connection &&other) :
m_cfg ( other.m_cfg ),
m_namespace(std::move(other.m_namespace)),
m_id (std::move(other.m_id )),
m_cred (std::move(other.m_cred )),
config (std::move(other ))
{
}
eap::credentials_connection& eap::credentials_connection::operator=(_In_ const credentials_connection &other)
{
if (this != &other) {
(config&)*this = other;
m_namespace = other.m_namespace;
m_id = other.m_id;
m_cred.reset(other.m_cred ? (credentials*)other.m_cred->clone() : nullptr);
}
return *this;
}
eap::credentials_connection& eap::credentials_connection::operator=(_Inout_ credentials_connection &&other)
{
if (this != &other) {
(config&)*this = std::move(other );
m_namespace = std::move(other.m_namespace);
m_id = std::move(other.m_id );
m_cred = std::move(other.m_cred );
}
return *this;
}
eap::config* eap::credentials_connection::clone() const
{
return new credentials_connection(*this);
}
void eap::credentials_connection::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pConfigRoot) const
{
assert(pDoc);
assert(pConfigRoot);
config::save(pDoc, pConfigRoot);
HRESULT hr;
// Create <EAPIdentityProvider> node.
com_obj<IXMLDOMElement> pXmlElIdentityProvider;
if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:EAPIdentityProvider"), bstr(L"EAPIdentityProvider"), namespace_eapmetadata, &pXmlElIdentityProvider)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <EAPIdentityProvider> element.");
// namespace
if (!m_namespace.empty())
if (FAILED(hr = eapxml::put_attrib_value(pXmlElIdentityProvider, bstr(L"namespace"), bstr(m_namespace))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating namespace attribute.");
// ID
if (!m_id.empty())
if (FAILED(hr = eapxml::put_attrib_value(pXmlElIdentityProvider, bstr(L"ID"), bstr(m_id))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating ID attribute.");
m_cred->save(pDoc, pXmlElIdentityProvider);
}
void eap::credentials_connection::load(_In_ IXMLDOMNode *pConfigRoot)
{
assert(pConfigRoot);
HRESULT hr;
config::load(pConfigRoot);
// <EAPIdentityProvider>
winstd::com_obj<IXMLDOMElement> pXmlElClientSideCredential;
if (FAILED(hr = eapxml::select_element(pConfigRoot, winstd::bstr(L"eap-metadata:EAPIdentityProvider"), &pXmlElClientSideCredential)))
throw com_runtime_error(hr, __FUNCTION__ " Error loading <EAPIdentityProvider> element.");
std::wstring xpath(eapxml::get_xpath(pXmlElClientSideCredential));
// namespace
m_namespace.clear();
eapxml::get_attrib_value(pXmlElClientSideCredential, bstr(L"namespace"), m_namespace);
m_module.log_config((xpath + L" namespace").c_str(), m_namespace.c_str());
// ID
m_id.clear();
eapxml::get_attrib_value(pXmlElClientSideCredential, bstr(L"ID"), m_id);
m_module.log_config((xpath + L" ID").c_str(), m_id.c_str());
// Look-up the provider.
for (config_connection::provider_list::const_iterator cfg_prov = m_cfg.m_providers.cbegin(), cfg_prov_end = m_cfg.m_providers.cend(); ; ++cfg_prov) {
if (cfg_prov != cfg_prov_end) {
if (match(*cfg_prov)) {
// Matching provider found. Create matching blank credential set, then load.
if (cfg_prov->m_methods.empty())
throw invalid_argument(string_printf(__FUNCTION__ " %ls provider has no methods.", cfg_prov->get_id().c_str()).c_str());
const config_method_with_cred *cfg_method = dynamic_cast<const config_method_with_cred*>(cfg_prov->m_methods.front().get());
m_cred.reset(cfg_method->make_credentials());
m_cred->load(pXmlElClientSideCredential);
break;
}
} else
throw invalid_argument(string_printf(__FUNCTION__ " Credentials do not match to any provider within this connection configuration (provider: %ls).", get_id().c_str()).c_str());
}
}
void eap::credentials_connection::operator<<(_Inout_ cursor_out &cursor) const
{
config::operator<<(cursor);
cursor << m_namespace;
cursor << m_id ;
cursor << *m_cred ;
}
size_t eap::credentials_connection::get_pk_size() const
{
return
config::get_pk_size() +
pksizeof( m_namespace) +
pksizeof( m_id ) +
pksizeof(*m_cred );
}
void eap::credentials_connection::operator>>(_Inout_ cursor_in &cursor)
{
config::operator>>(cursor);
cursor >> m_namespace;
cursor >> m_id ;
// Look-up the provider.
for (config_connection::provider_list::const_iterator cfg_prov = m_cfg.m_providers.cbegin(), cfg_prov_end = m_cfg.m_providers.cend(); ; ++cfg_prov) {
if (cfg_prov != cfg_prov_end) {
if (match(*cfg_prov)) {
// Matching provider found. Create matching blank credential set, then read.
if (cfg_prov->m_methods.empty())
throw invalid_argument(string_printf(__FUNCTION__ " %ls provider has no methods.", cfg_prov->get_id().c_str()).c_str());
const config_method_with_cred *cfg_method = dynamic_cast<const config_method_with_cred*>(cfg_prov->m_methods.front().get());
m_cred.reset(cfg_method->make_credentials());
cursor >> *m_cred;
break;
}
} else
throw invalid_argument(string_printf(__FUNCTION__ " Credentials do not match to any provider within this connection configuration (provider: %ls).", get_id().c_str()).c_str());
}
}

83
lib/EAPBase/src/EAP.cpp Normal file
View File

@@ -0,0 +1,83 @@
/*
Copyright 2015-2016 Amebis
Copyright 2016 G<>ANT
This file is part of G<>ANTLink.
G<>ANTLink is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
G<>ANTLink is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with G<>ANTLink. If not, see <http://www.gnu.org/licenses/>.
*/
#include "StdAfx.h"
using namespace std;
using namespace winstd;
//////////////////////////////////////////////////////////////////////
// eap::packet
//////////////////////////////////////////////////////////////////////
eap::packet::packet() :
m_code((EapCode)0),
m_id(0)
{
}
eap::packet::packet(_In_ const packet &other) :
m_code(other.m_code),
m_id (other.m_id ),
m_data(other.m_data)
{
}
eap::packet::packet(_Inout_ packet &&other) :
m_code(std::move(other.m_code)),
m_id (std::move(other.m_id )),
m_data(std::move(other.m_data))
{
}
eap::packet& eap::packet::operator=(_In_ const packet &other)
{
if (this != std::addressof(other)) {
m_code = other.m_code;
m_id = other.m_id ;
m_data = other.m_data;
}
return *this;
}
eap::packet& eap::packet::operator=(_Inout_ packet &&other)
{
if (this != std::addressof(other)) {
m_code = std::move(other.m_code);
m_id = std::move(other.m_id );
m_data = std::move(other.m_data);
}
return *this;
}
void eap::packet::clear()
{
m_code = (EapCode)0;
m_id = 0;
m_data.clear();
}

View File

@@ -62,7 +62,7 @@ void eap::method::begin_session(
_In_ DWORD dwFlags, _In_ DWORD dwFlags,
_In_ const EapAttributes *pAttributeArray, _In_ const EapAttributes *pAttributeArray,
_In_ HANDLE hTokenImpersonateUser, _In_ HANDLE hTokenImpersonateUser,
_In_ DWORD dwMaxSendPacketSize) _In_opt_ DWORD dwMaxSendPacketSize)
{ {
UNREFERENCED_PARAMETER(dwFlags); UNREFERENCED_PARAMETER(dwFlags);
UNREFERENCED_PARAMETER(pAttributeArray); UNREFERENCED_PARAMETER(pAttributeArray);
@@ -74,3 +74,101 @@ void eap::method::begin_session(
void eap::method::end_session() void eap::method::end_session()
{ {
} }
//////////////////////////////////////////////////////////////////////
// eap::method_noneap
//////////////////////////////////////////////////////////////////////
eap::method_noneap::method_noneap(_In_ module &module, _In_ config_method_with_cred &cfg, _In_ credentials &cred) : method(module, cfg, cred)
{
}
eap::method_noneap::method_noneap(_Inout_ method_noneap &&other) :
m_packet_res(std::move(other.m_packet_res)),
method (std::move(other ))
{
}
eap::method_noneap& eap::method_noneap::operator=(_Inout_ method_noneap &&other)
{
if (this != std::addressof(other)) {
assert(std::addressof(m_cred) == std::addressof(other.m_cred)); // Move method with same credentials only!
(method&)*this = std::move(other );
m_packet_res = std::move(other.m_packet_res);
}
return *this;
}
void eap::method_noneap::get_response_packet(
_Inout_bytecap_(*dwSendPacketSize) void *pSendPacket,
_Inout_ DWORD *pdwSendPacketSize)
{
assert(pdwSendPacketSize);
assert(pSendPacket);
size_t size_packet = m_packet_res.size();
if (size_packet > *pdwSendPacketSize)
throw invalid_argument(string_printf(__FUNCTION__ " This method does not support packet fragmentation, but the data size is too big to fit in one packet (packet: %u, maximum: %u).", size_packet, *pdwSendPacketSize).c_str());
memcpy(pSendPacket, m_packet_res.data(), size_packet);
*pdwSendPacketSize = (DWORD)size_packet;
m_packet_res.clear();
}
void eap::method_noneap::append_avp(_In_ unsigned int code, _In_ unsigned char flags, _In_bytecount_(size) const void *data, _In_ unsigned int size)
{
unsigned int
padding = (unsigned int)((4 - size) % 4),
size_outer;
m_packet_res.reserve(
m_packet_res.size() +
(size_outer =
sizeof(diameter_avp_header) + // Diameter header
size) + // Data
padding); // Data padding
// Diameter AVP header
diameter_avp_header hdr;
*(unsigned int*)hdr.code = htonl(code);
hdr.flags = flags;
hton24(size_outer, hdr.length);
m_packet_res.insert(m_packet_res.end(), (unsigned char*)&hdr, (unsigned char*)(&hdr + 1));
// Data
m_packet_res.insert(m_packet_res.end(), (unsigned char*)data, (unsigned char*)data + size);
m_packet_res.insert(m_packet_res.end(), padding, 0);
}
void eap::method_noneap::append_avp(_In_ unsigned int code, _In_ unsigned int vendor_id, _In_ unsigned char flags, _In_bytecount_(size) const void *data, _In_ unsigned int size)
{
unsigned int
padding = (unsigned int)((4 - size) % 4),
size_outer;
m_packet_res.reserve(
m_packet_res.size() +
(size_outer =
sizeof(diameter_avp_header_ven) + // Diameter header
size) + // Data
padding); // Data padding
// Diameter AVP header
diameter_avp_header_ven hdr;
*(unsigned int*)hdr.code = htonl(code);
hdr.flags = flags | diameter_avp_flag_vendor;
hton24(size_outer, hdr.length);
*(unsigned int*)hdr.vendor = htonl(vendor_id);
m_packet_res.insert(m_packet_res.end(), (unsigned char*)&hdr, (unsigned char*)(&hdr + 1));
// Data
m_packet_res.insert(m_packet_res.end(), (unsigned char*)data, (unsigned char*)data + size);
m_packet_res.insert(m_packet_res.end(), padding, 0);
}

View File

@@ -21,7 +21,9 @@
#include <wx/hyperlink.h> #include <wx/hyperlink.h>
#include <wx/icon.h> #include <wx/icon.h>
#include <wx/intl.h> #include <wx/intl.h>
#include <wx/msgdlg.h>
#include <wx/scrolwin.h> #include <wx/scrolwin.h>
#include <wx/textdlg.h>
#include <Windows.h> #include <Windows.h>
@@ -41,10 +43,15 @@ template <class _wxT> class wxEAPConfigDialog;
class wxEAPGeneralDialog; class wxEAPGeneralDialog;
/// ///
/// EAP top-most credential dialog /// EAP method credential dialog
/// ///
class wxEAPCredentialsDialog; class wxEAPCredentialsDialog;
///
/// EAP connection credential dialog
///
class wxEAPCredentialsConnectionDialog;
/// ///
/// EAP general note /// EAP general note
/// ///
@@ -65,10 +72,15 @@ class wxEAPCredentialWarningPanel;
/// ///
class wxEAPConfigWindow; class wxEAPConfigWindow;
///
/// EAP provider contact info config panel
///
class wxEAPProviderContactInfoPanel;
/// ///
/// EAP provider identity config panel /// EAP provider identity config panel
/// ///
class wxEAPProviderIdentityPanel; class wxEAPProviderIDPanel;
/// ///
/// EAP provider configuration dialog /// EAP provider configuration dialog
@@ -187,20 +199,21 @@ public:
this->SetIcon(wxIcon(wxICON(product.ico))); this->SetIcon(wxIcon(wxICON(product.ico)));
#endif #endif
for (std::vector<eap::config_provider>::iterator provider = m_cfg.m_providers.begin(), provider_end = m_cfg.m_providers.end(); provider != provider_end; ++provider) { wstring target_name;
for (eap::config_connection::provider_list::iterator provider = m_cfg.m_providers.begin(), provider_end = m_cfg.m_providers.end(); provider != provider_end; ++provider) {
bool is_single = provider->m_methods.size() == 1; bool is_single = provider->m_methods.size() == 1;
std::vector<std::unique_ptr<eap::config_method> >::size_type count = 0; std::vector<std::unique_ptr<eap::config_method> >::size_type count = 0;
std::vector<std::unique_ptr<eap::config_method> >::iterator method = provider->m_methods.begin(), method_end = provider->m_methods.end(); std::vector<std::unique_ptr<eap::config_method> >::iterator method = provider->m_methods.begin(), method_end = provider->m_methods.end();
for (; method != method_end; ++method, count++) for (; method != method_end; ++method, count++) {
m_providers->AddPage( m_providers->AddPage(
new _wxT( new _wxT(
*provider, *provider,
*method->get(), *method->get(),
provider->m_id.c_str(),
m_providers), m_providers),
is_single ? is_single ?
wxEAPGetProviderName(provider->m_id) : wxEAPGetProviderName(provider->m_name) :
winstd::tstring_printf(_T("%s (%u)"), wxEAPGetProviderName(provider->m_id), count)); winstd::tstring_printf(_T("%s (%u)"), wxEAPGetProviderName(provider->m_name), count));
}
} }
this->Layout(); this->Layout();
@@ -223,27 +236,83 @@ protected:
} }
} }
virtual void OnUpdateUI(wxUpdateUIEvent& /*event*/) virtual void OnUpdateUI(wxUpdateUIEvent& /*event*/)
{
int idx = m_providers->GetSelection();
if (idx != wxNOT_FOUND) {
eap::config_provider &cfg_provider = ((_wxT*)m_providers->GetPage(idx))->GetProvider();
m_prov_remove->Enable(true);
m_prov_advanced->Enable(!cfg_provider.m_read_only);
} else {
m_prov_remove->Enable(false);
m_prov_advanced->Enable(false);
}
}
virtual void OnProvAdd(wxCommandEvent& /*event*/)
{
// One method
std::unique_ptr<eap::config_method> cfg_method(m_cfg.m_module.make_config_method());
// Create provider.
eap::config_provider cfg_provider(m_cfg.m_module);
GUID guid;
CoCreateGuid(&guid);
cfg_provider.m_namespace = L"urn:uuid";
cfg_provider.m_id = winstd::wstring_guid(guid).substr(1, 36);
cfg_provider.m_methods.push_back(std::move(cfg_method));
// Append provider.
m_cfg.m_providers.push_back(std::move(cfg_provider));
eap::config_provider &cfg_provider2 = m_cfg.m_providers.back();
eap::config_method *cfg_method2 = cfg_provider2.m_methods.front().get();
m_providers->InsertPage(
m_providers->GetSelection() + 1,
new _wxT(
cfg_provider2,
*cfg_method2,
m_providers),
wxEAPGetProviderName(cfg_provider2.m_name), true);
this->Layout();
this->Fit();
}
virtual void OnProvRemove(wxCommandEvent& /*event*/)
{ {
int idx = m_providers->GetSelection(); int idx = m_providers->GetSelection();
eap::config_provider &cfg_provider = ((_wxT*)m_providers->GetPage(idx))->GetProvider(); eap::config_provider &cfg_provider = ((_wxT*)m_providers->GetPage(idx))->GetProvider();
m_advanced->Enable(!cfg_provider.m_read_only); if (wxMessageBox(tstring_printf(_("Are you sure you want to permanently remove %ls provider from configuration?"), cfg_provider.m_name.c_str()), _("Warning"), wxYES_NO, this) == wxYES) {
// Delete provider.
eap::config_connection::provider_list::iterator it(m_cfg.m_providers.begin());
for (int i = 0; i < idx; i++, ++it);
m_cfg.m_providers.erase(it);
m_providers->DeletePage(idx);
if ((size_t)idx < m_providers->GetPageCount())
m_providers->SetSelection(idx);
this->Layout();
this->Fit();
}
} }
virtual void OnAdvanced(wxCommandEvent& /*event*/)
virtual void OnProvAdvanced(wxCommandEvent& /*event*/)
{ {
int idx = m_providers->GetSelection(); int idx = m_providers->GetSelection();
eap::config_provider &cfg_provider = ((_wxT*)m_providers->GetPage(idx))->GetProvider(); eap::config_provider &cfg_provider = ((_wxT*)m_providers->GetPage(idx))->GetProvider();
wxEAPConfigProvider dlg(cfg_provider, this); wxEAPConfigProvider dlg(cfg_provider, this);
if (dlg.ShowModal() == wxID_OK) if (dlg.ShowModal() == wxID_OK)
m_providers->SetPageText(idx, wxEAPGetProviderName(cfg_provider.m_id)); m_providers->SetPageText(idx, wxEAPGetProviderName(cfg_provider.m_name));
} }
/// \endcond /// \endcond
protected: protected:
eap::config_connection &m_cfg; ///< Connection configuration eap::config_connection &m_cfg; ///< Connection configuration
}; };
@@ -284,6 +353,21 @@ public:
}; };
class wxEAPCredentialsConnectionDialog : public wxEAPCredentialsConnectionDialogBase
{
public:
///
/// Constructs a credential dialog
///
wxEAPCredentialsConnectionDialog(wxWindow *parent, wxWindowID id = wxID_ANY, const wxString &title = _("EAP Credentials"), const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE);
protected:
/// \cond internal
virtual void OnInitDialog(wxInitDialogEvent& event);
/// \endcond
};
class wxEAPNotePanel : public wxEAPNotePanelBase class wxEAPNotePanel : public wxEAPNotePanelBase
{ {
public: public:
@@ -385,16 +469,16 @@ protected:
}; };
class wxEAPProviderIdentityPanel : public wxEAPProviderIdentityPanelBase class wxEAPProviderContactInfoPanel : public wxEAPProviderContactInfoPanelBase
{ {
public: public:
/// ///
/// Constructs a provider identity pannel /// Constructs a provider contact info pannel
/// ///
/// \param[inout] prov Provider configuration data /// \param[inout] prov Provider configuration data
/// \param[in] parent Parent window /// \param[in] parent Parent window
/// ///
wxEAPProviderIdentityPanel(eap::config_provider &prov, wxWindow* parent); wxEAPProviderContactInfoPanel(eap::config_provider &prov, wxWindow* parent);
friend class wxEAPConfigProvider; // Allows direct setting of keyboard focus friend class wxEAPConfigProvider; // Allows direct setting of keyboard focus
@@ -405,7 +489,29 @@ protected:
/// \endcond /// \endcond
protected: protected:
eap::config_provider &m_prov; ///< EAP method configuration eap::config_provider &m_prov; ///< Provider configuration
};
class wxEAPProviderIDPanel : public wxEAPProviderIDPanelBase
{
public:
///
/// Constructs a provider identity pannel
///
/// \param[inout] prov Provider configuration data
/// \param[in] parent Parent window
///
wxEAPProviderIDPanel(eap::config_provider &prov, wxWindow* parent);
protected:
/// \cond internal
virtual bool TransferDataToWindow();
virtual bool TransferDataFromWindow();
/// \endcond
protected:
eap::config_provider &m_prov; ///< Provider configuration
}; };
@@ -443,9 +549,10 @@ public:
wxEAPConfigProvider(eap::config_provider &prov, wxWindow *parent, wxWindowID id = wxID_ANY, const wxString &title = _("Provider Settings"), const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE); wxEAPConfigProvider(eap::config_provider &prov, wxWindow *parent, wxWindowID id = wxID_ANY, const wxString &title = _("Provider Settings"), const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE);
protected: protected:
eap::config_provider &m_prov; ///< EAP method configuration eap::config_provider &m_prov; ///< EAP method configuration
wxEAPProviderIdentityPanel *m_identity; ///< Provider identity panel wxEAPProviderContactInfoPanel *m_contact; ///< Provider contact info panel
wxEAPProviderLockPanel *m_lock; ///< Provider lock panel wxEAPProviderIDPanel *m_identity; ///< Provider identity panel
wxEAPProviderLockPanel *m_lock; ///< Provider lock panel
}; };
@@ -456,15 +563,13 @@ public:
/// ///
/// Constructs a credential configuration panel /// Constructs a credential configuration panel
/// ///
/// \param[in] prov Provider configuration data /// \param[in] prov Provider configuration data
/// \param[inout] cfg Configuration data /// \param[inout] cfg Configuration data
/// \param[in] pszCredTarget Target name of credentials in Windows Credential Manager. Can be further decorated to create final target name. /// \param[in] parent Parent window
/// \param[in] parent Parent window
/// ///
wxEAPCredentialsConfigPanel(const eap::config_provider &prov, eap::config_method_with_cred &cfg, LPCTSTR pszCredTarget, wxWindow *parent) : wxEAPCredentialsConfigPanel(const eap::config_provider &prov, eap::config_method_with_cred &cfg, wxWindow *parent) :
m_prov(prov), m_prov(prov),
m_cfg(cfg), m_cfg(cfg),
m_target(pszCredTarget),
m_has_own(false), m_has_own(false),
m_cred_own(cfg.m_module), m_cred_own(cfg.m_module),
m_cred_preshared(cfg.m_module), m_cred_preshared(cfg.m_module),
@@ -572,12 +677,12 @@ protected:
// Display credential prompt. // Display credential prompt.
wxEAPCredentialsDialog dlg(m_prov, this); wxEAPCredentialsDialog dlg(m_prov, this);
_wxT *panel = new _wxT(m_prov, m_cfg, m_cred_own, m_target.c_str(), &dlg, true); _wxT *panel = new _wxT(m_prov, m_cfg, m_cred_own, &dlg, true);
dlg.AddContent(panel); dlg.AddContent(panel);
if (dlg.ShowModal() == wxID_OK && panel->GetRemember()) { if (dlg.ShowModal() == wxID_OK && panel->GetRemember()) {
// Write credentials to credential manager. // Write credentials to credential manager.
try { try {
m_cred_own.store(m_target.c_str()); m_cred_own.store(m_prov.get_id().c_str());
m_has_own = TRUE; m_has_own = TRUE;
UpdateOwnIdentity(); UpdateOwnIdentity();
} catch (winstd::win_runtime_error &err) { } catch (winstd::win_runtime_error &err) {
@@ -593,7 +698,7 @@ protected:
virtual void OnClearOwn(wxCommandEvent& /*event*/) virtual void OnClearOwn(wxCommandEvent& /*event*/)
{ {
if (CredDelete(m_cred_own.target_name(m_target.c_str()).c_str(), CRED_TYPE_GENERIC, 0)) { if (CredDelete(m_cred_own.target_name(m_prov.get_id().c_str()).c_str(), CRED_TYPE_GENERIC, 0)) {
m_own_identity->Clear(); m_own_identity->Clear();
m_has_own = false; m_has_own = false;
} else } else
@@ -605,7 +710,7 @@ protected:
{ {
wxEAPCredentialsDialog dlg(m_prov, this); wxEAPCredentialsDialog dlg(m_prov, this);
_wxT *panel = new _wxT(m_prov, m_cfg, m_cred_preshared, _T(""), &dlg, true); _wxT *panel = new _wxT(m_prov, m_cfg, m_cred_preshared, &dlg, true);
dlg.AddContent(panel); dlg.AddContent(panel);
if (dlg.ShowModal() == wxID_OK) if (dlg.ShowModal() == wxID_OK)
@@ -622,7 +727,7 @@ protected:
void RetrieveOwnCredentials() void RetrieveOwnCredentials()
{ {
try { try {
m_cred_own.retrieve(m_target.c_str()); m_cred_own.retrieve(m_prov.get_id().c_str());
m_has_own = true; m_has_own = true;
UpdateOwnIdentity(); UpdateOwnIdentity();
} catch (winstd::win_runtime_error &err) { } catch (winstd::win_runtime_error &err) {
@@ -642,23 +747,19 @@ protected:
inline void UpdateOwnIdentity() inline void UpdateOwnIdentity()
{ {
if (m_cred_own.empty()) wxString identity(m_cred_own.get_identity());
m_own_identity->SetValue(_("<empty credentials>")); m_own_identity->SetValue(
else { !identity.empty() ? identity :
wxString identity(m_cred_own.get_name()); m_cred_own.empty() ? _("<empty>") : _("<blank ID>"));
m_own_identity->SetValue(!identity.empty() ? identity : _("<blank identity>"));
}
} }
inline void UpdatePresharedIdentity() inline void UpdatePresharedIdentity()
{ {
if (m_cred_preshared.empty()) wxString identity(m_cred_preshared.get_identity());
m_preshared_identity->SetValue(_("<empty credentials>")); m_preshared_identity->SetValue(
else { !identity.empty() ? identity :
wxString identity(m_cred_preshared.get_name()); m_cred_preshared.empty() ? _("<empty>") : _("<blank ID>"));
m_preshared_identity->SetValue(!identity.empty() ? identity : _("<blank identity>"));
}
} }
/// \endcond /// \endcond
@@ -666,7 +767,6 @@ protected:
protected: protected:
const eap::config_provider &m_prov; ///< EAP provider const eap::config_provider &m_prov; ///< EAP provider
eap::config_method_with_cred &m_cfg; ///< EAP method configuration eap::config_method_with_cred &m_cfg; ///< EAP method configuration
winstd::tstring m_target; ///< Credential Manager target
private: private:
bool m_has_own; ///< Does the user has (some sort of) credentials stored in Credential Manager? bool m_has_own; ///< Does the user has (some sort of) credentials stored in Credential Manager?
@@ -687,18 +787,16 @@ public:
/// ///
/// Constructs a credentials panel /// Constructs a credentials panel
/// ///
/// \param[in] prov Provider configuration data /// \param[in] prov Provider configuration data
/// \param[in] cfg Configuration data /// \param[in] cfg Configuration data
/// \param[inout] cred Credentials data /// \param[inout] cred Credentials data
/// \param[in] pszCredTarget Target name of credentials in Windows Credential Manager. Can be further decorated to create final target name. /// \param[in] parent Parent window
/// \param[in] parent Parent window /// \param[in] is_config Is this panel used to pre-enter credentials? When \c true, the "Remember" checkbox is always selected and disabled.
/// \param[in] is_config Is this panel used to pre-enter credentials? When \c true, the "Remember" checkbox is always selected and disabled.
/// ///
wxEAPCredentialsPanel(const eap::config_provider &prov, const eap::config_method_with_cred &cfg, _Tcred &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config = false) : wxEAPCredentialsPanel(const eap::config_provider &prov, const eap::config_method_with_cred &cfg, _Tcred &cred, wxWindow* parent, bool is_config = false) :
m_prov(prov), m_prov(prov),
m_cfg(cfg), m_cfg(cfg),
m_cred(cred), m_cred(cred),
m_target(pszCredTarget),
m_is_config(is_config), m_is_config(is_config),
_Tbase(parent) _Tbase(parent)
{ {
@@ -743,7 +841,6 @@ protected:
const eap::config_provider &m_prov; ///< Provider configuration const eap::config_provider &m_prov; ///< Provider configuration
const eap::config_method_with_cred &m_cfg; ///< Method configuration const eap::config_method_with_cred &m_cfg; ///< Method configuration
_Tcred &m_cred; ///< Credentials _Tcred &m_cred; ///< Credentials
winstd::tstring m_target; ///< Credential Manager target
bool m_is_config; ///< Is this a configuration dialog? bool m_is_config; ///< Is this a configuration dialog?
}; };
@@ -755,15 +852,14 @@ public:
/// ///
/// Constructs a password credentials panel /// Constructs a password credentials panel
/// ///
/// \param[in] prov Provider configuration data /// \param[in] prov Provider configuration data
/// \param[in] cfg Configuration data /// \param[in] cfg Configuration data
/// \param[inout] cred Credentials data /// \param[inout] cred Credentials data
/// \param[in] pszCredTarget Target name of credentials in Windows Credential Manager. Can be further decorated to create final target name. /// \param[in] parent Parent window
/// \param[in] parent Parent window /// \param[in] is_config Is this panel used to pre-enter credentials? When \c true, the "Remember" checkbox is always selected and disabled.
/// \param[in] is_config Is this panel used to pre-enter credentials? When \c true, the "Remember" checkbox is always selected and disabled.
/// ///
wxPasswordCredentialsPanel(const eap::config_provider &prov, const eap::config_method_with_cred &cfg, _Tcred &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config = false) : wxPasswordCredentialsPanel(const eap::config_provider &prov, const eap::config_method_with_cred &cfg, _Tcred &cred, wxWindow* parent, bool is_config = false) :
wxEAPCredentialsPanel<_Tcred, _Tbase>(prov, cfg, cred, pszCredTarget, parent, is_config) wxEAPCredentialsPanel<_Tcred, _Tbase>(prov, cfg, cred, parent, is_config)
{ {
// Load and set icon. // Load and set icon.
winstd::library lib_shell32; winstd::library lib_shell32;
@@ -773,7 +869,7 @@ public:
bool layout = false; bool layout = false;
if (!m_prov.m_lbl_alt_credential.empty()) { if (!m_prov.m_lbl_alt_credential.empty()) {
m_credentials_label->SetLabel(m_prov.m_lbl_alt_credential); m_credentials_label->SetLabel(m_prov.m_lbl_alt_credential);
m_credentials_label->Wrap( 446 ); m_credentials_label->Wrap( 440 );
layout = true; layout = true;
} }

View File

@@ -34,10 +34,20 @@ wxEAPConfigDialogBase::wxEAPConfigDialogBase( wxWindow* parent, wxWindowID id, c
wxBoxSizer* sb_bottom_horiz_inner; wxBoxSizer* sb_bottom_horiz_inner;
sb_bottom_horiz_inner = new wxBoxSizer( wxHORIZONTAL ); sb_bottom_horiz_inner = new wxBoxSizer( wxHORIZONTAL );
m_advanced = new wxButton( this, wxID_ANY, _("Advanced..."), wxDefaultPosition, wxDefaultSize, 0 ); m_prov_add = new wxButton( this, wxID_ANY, _("+"), wxDefaultPosition, wxSize( 30,-1 ), 0 );
m_advanced->SetToolTip( _("Opens dialog with provider settings") ); m_prov_add->SetToolTip( _("Adds new provider") );
sb_bottom_horiz_inner->Add( m_advanced, 0, wxALL, 5 ); sb_bottom_horiz_inner->Add( m_prov_add, 0, wxALL, 5 );
m_prov_remove = new wxButton( this, wxID_ANY, _("-"), wxDefaultPosition, wxSize( 30,-1 ), 0 );
m_prov_remove->SetToolTip( _("Removes selected provider") );
sb_bottom_horiz_inner->Add( m_prov_remove, 0, wxALL, 5 );
m_prov_advanced = new wxButton( this, wxID_ANY, _("Advanced..."), wxDefaultPosition, wxDefaultSize, 0 );
m_prov_advanced->SetToolTip( _("Opens dialog with provider settings") );
sb_bottom_horiz_inner->Add( m_prov_advanced, 0, wxALL, 5 );
sb_bottom_horiz->Add( sb_bottom_horiz_inner, 1, wxEXPAND, 5 ); sb_bottom_horiz->Add( sb_bottom_horiz_inner, 1, wxEXPAND, 5 );
@@ -62,7 +72,9 @@ wxEAPConfigDialogBase::wxEAPConfigDialogBase( wxWindow* parent, wxWindowID id, c
// Connect Events // Connect Events
this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( wxEAPConfigDialogBase::OnInitDialog ) ); this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( wxEAPConfigDialogBase::OnInitDialog ) );
this->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( wxEAPConfigDialogBase::OnUpdateUI ) ); this->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( wxEAPConfigDialogBase::OnUpdateUI ) );
m_advanced->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPConfigDialogBase::OnAdvanced ), NULL, this ); m_prov_add->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPConfigDialogBase::OnProvAdd ), NULL, this );
m_prov_remove->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPConfigDialogBase::OnProvRemove ), NULL, this );
m_prov_advanced->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPConfigDialogBase::OnProvAdvanced ), NULL, this );
} }
wxEAPConfigDialogBase::~wxEAPConfigDialogBase() wxEAPConfigDialogBase::~wxEAPConfigDialogBase()
@@ -70,7 +82,9 @@ wxEAPConfigDialogBase::~wxEAPConfigDialogBase()
// Disconnect Events // Disconnect Events
this->Disconnect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( wxEAPConfigDialogBase::OnInitDialog ) ); this->Disconnect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( wxEAPConfigDialogBase::OnInitDialog ) );
this->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( wxEAPConfigDialogBase::OnUpdateUI ) ); this->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( wxEAPConfigDialogBase::OnUpdateUI ) );
m_advanced->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPConfigDialogBase::OnAdvanced ), NULL, this ); m_prov_add->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPConfigDialogBase::OnProvAdd ), NULL, this );
m_prov_remove->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPConfigDialogBase::OnProvRemove ), NULL, this );
m_prov_advanced->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPConfigDialogBase::OnProvAdvanced ), NULL, this );
} }
@@ -115,6 +129,48 @@ wxEAPGeneralDialogBase::~wxEAPGeneralDialogBase()
} }
wxEAPCredentialsConnectionDialogBase::wxEAPCredentialsConnectionDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
wxBoxSizer* sb_content;
sb_content = new wxBoxSizer( wxVERTICAL );
m_banner = new wxEAPBannerPanel( this );
sb_content->Add( m_banner, 0, wxEXPAND|wxBOTTOM, 5 );
m_providers = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_providers->SetExtraStyle( wxWS_EX_VALIDATE_RECURSIVELY );
sb_content->Add( m_providers, 1, wxEXPAND | wxALL, 5 );
m_buttons = new wxStdDialogButtonSizer();
m_buttonsOK = new wxButton( this, wxID_OK );
m_buttons->AddButton( m_buttonsOK );
m_buttonsCancel = new wxButton( this, wxID_CANCEL );
m_buttons->AddButton( m_buttonsCancel );
m_buttons->Realize();
sb_content->Add( m_buttons, 0, wxEXPAND|wxALL, 5 );
this->SetSizer( sb_content );
this->Layout();
sb_content->Fit( this );
// Connect Events
this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( wxEAPCredentialsConnectionDialogBase::OnInitDialog ) );
}
wxEAPCredentialsConnectionDialogBase::~wxEAPCredentialsConnectionDialogBase()
{
// Disconnect Events
this->Disconnect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( wxEAPCredentialsConnectionDialogBase::OnInitDialog ) );
}
wxEAPBannerPanelBase::wxEAPBannerPanelBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style ) wxEAPBannerPanelBase::wxEAPBannerPanelBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style )
{ {
this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) ); this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
@@ -183,7 +239,7 @@ wxEAPCredentialsConfigPanelBase::wxEAPCredentialsConfigPanelBase( wxWindow* pare
sb_credentials_vert = new wxBoxSizer( wxVERTICAL ); sb_credentials_vert = new wxBoxSizer( wxVERTICAL );
m_credentials_label = new wxStaticText( sb_credentials->GetStaticBox(), wxID_ANY, _("Manage credentials used to connect."), wxDefaultPosition, wxDefaultSize, 0 ); m_credentials_label = new wxStaticText( sb_credentials->GetStaticBox(), wxID_ANY, _("Manage credentials used to connect."), wxDefaultPosition, wxDefaultSize, 0 );
m_credentials_label->Wrap( 446 ); m_credentials_label->Wrap( 440 );
sb_credentials_vert->Add( m_credentials_label, 0, wxALL|wxEXPAND, 5 ); sb_credentials_vert->Add( m_credentials_label, 0, wxALL|wxEXPAND, 5 );
wxBoxSizer* sb_cred_radio; wxBoxSizer* sb_cred_radio;
@@ -308,7 +364,7 @@ wxEAPCredentialsPassPanelBase::wxEAPCredentialsPassPanelBase( wxWindow* parent,
sb_credentials_vert = new wxBoxSizer( wxVERTICAL ); sb_credentials_vert = new wxBoxSizer( wxVERTICAL );
m_credentials_label = new wxStaticText( sb_credentials->GetStaticBox(), wxID_ANY, _("Please provide your user ID and password."), wxDefaultPosition, wxDefaultSize, 0 ); m_credentials_label = new wxStaticText( sb_credentials->GetStaticBox(), wxID_ANY, _("Please provide your user ID and password."), wxDefaultPosition, wxDefaultSize, 0 );
m_credentials_label->Wrap( 446 ); m_credentials_label->Wrap( 440 );
sb_credentials_vert->Add( m_credentials_label, 0, wxALL|wxEXPAND, 5 ); sb_credentials_vert->Add( m_credentials_label, 0, wxALL|wxEXPAND, 5 );
wxFlexGridSizer* sb_credentials_tbl; wxFlexGridSizer* sb_credentials_tbl;
@@ -358,10 +414,114 @@ wxEAPCredentialsPassPanelBase::~wxEAPCredentialsPassPanelBase()
{ {
} }
wxEAPProviderIdentityPanelBase::wxEAPProviderIdentityPanelBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style ) wxEAPProviderContactInfoPanelBase::wxEAPProviderContactInfoPanelBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style )
{
wxStaticBoxSizer* sb_provider_contact;
sb_provider_contact = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Your Organization") ), wxVERTICAL );
wxBoxSizer* sb_provider_contact_horiz;
sb_provider_contact_horiz = new wxBoxSizer( wxHORIZONTAL );
m_provider_contact_icon = new wxStaticBitmap( sb_provider_contact->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
sb_provider_contact_horiz->Add( m_provider_contact_icon, 0, wxALL, 5 );
wxBoxSizer* sb_provider_contact_vert;
sb_provider_contact_vert = new wxBoxSizer( wxVERTICAL );
m_provider_contact_label = new wxStaticText( sb_provider_contact->GetStaticBox(), wxID_ANY, _("Describe your organization to customize user prompts. When organization is introduced, end-users find program messages easier to understand and act."), wxDefaultPosition, wxDefaultSize, 0 );
m_provider_contact_label->Wrap( 440 );
sb_provider_contact_vert->Add( m_provider_contact_label, 0, wxALL|wxEXPAND, 5 );
wxBoxSizer* sb_provider_name;
sb_provider_name = new wxBoxSizer( wxVERTICAL );
m_provider_name_label = new wxStaticText( sb_provider_contact->GetStaticBox(), wxID_ANY, _("Your organization &name:"), wxDefaultPosition, wxDefaultSize, 0 );
m_provider_name_label->Wrap( -1 );
sb_provider_name->Add( m_provider_name_label, 0, wxBOTTOM, 5 );
m_provider_name = new wxTextCtrl( sb_provider_contact->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_provider_name->SetToolTip( _("Your organization name as it will appear on helpdesk contact notifications") );
sb_provider_name->Add( m_provider_name, 0, wxEXPAND|wxBOTTOM, 5 );
m_provider_name_note = new wxStaticText( sb_provider_contact->GetStaticBox(), wxID_ANY, _("(Keep it short, please)"), wxDefaultPosition, wxDefaultSize, 0 );
m_provider_name_note->Wrap( -1 );
sb_provider_name->Add( m_provider_name_note, 0, wxALIGN_RIGHT, 5 );
sb_provider_contact_vert->Add( sb_provider_name, 0, wxEXPAND|wxALL, 5 );
wxBoxSizer* sb_provider_helpdesk;
sb_provider_helpdesk = new wxBoxSizer( wxVERTICAL );
m_provider_helpdesk_label = new wxStaticText( sb_provider_contact->GetStaticBox(), wxID_ANY, _("Helpdesk contact &information:"), wxDefaultPosition, wxDefaultSize, 0 );
m_provider_helpdesk_label->Wrap( -1 );
sb_provider_helpdesk->Add( m_provider_helpdesk_label, 0, wxBOTTOM, 5 );
wxFlexGridSizer* sb_provider_helpdesk_inner;
sb_provider_helpdesk_inner = new wxFlexGridSizer( 0, 2, 0, 0 );
sb_provider_helpdesk_inner->AddGrowableCol( 1 );
sb_provider_helpdesk_inner->SetFlexibleDirection( wxBOTH );
sb_provider_helpdesk_inner->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_provider_web_icon = new wxStaticText( sb_provider_contact->GetStaticBox(), wxID_ANY, _(""), wxDefaultPosition, wxDefaultSize, 0 );
m_provider_web_icon->Wrap( -1 );
m_provider_web_icon->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxT("Wingdings") ) );
sb_provider_helpdesk_inner->Add( m_provider_web_icon, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT, 5 );
m_provider_web = new wxTextCtrl( sb_provider_contact->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_provider_web->SetToolTip( _("Your helpdesk website address") );
sb_provider_helpdesk_inner->Add( m_provider_web, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxBOTTOM, 5 );
m_provider_email_icon = new wxStaticText( sb_provider_contact->GetStaticBox(), wxID_ANY, _("*"), wxDefaultPosition, wxDefaultSize, 0 );
m_provider_email_icon->Wrap( -1 );
m_provider_email_icon->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxT("Wingdings") ) );
sb_provider_helpdesk_inner->Add( m_provider_email_icon, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT, 5 );
m_provider_email = new wxTextCtrl( sb_provider_contact->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_provider_email->SetToolTip( _("Your helpdesk e-mail address") );
sb_provider_helpdesk_inner->Add( m_provider_email, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxBOTTOM, 5 );
m_provider_phone_icon = new wxStaticText( sb_provider_contact->GetStaticBox(), wxID_ANY, _(")"), wxDefaultPosition, wxDefaultSize, 0 );
m_provider_phone_icon->Wrap( -1 );
m_provider_phone_icon->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxT("Wingdings") ) );
sb_provider_helpdesk_inner->Add( m_provider_phone_icon, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_provider_phone = new wxTextCtrl( sb_provider_contact->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_provider_phone->SetToolTip( _("Your helpdesk phone number") );
sb_provider_helpdesk_inner->Add( m_provider_phone, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 );
sb_provider_helpdesk->Add( sb_provider_helpdesk_inner, 0, wxEXPAND, 5 );
sb_provider_contact_vert->Add( sb_provider_helpdesk, 0, wxEXPAND|wxALL, 5 );
sb_provider_contact_horiz->Add( sb_provider_contact_vert, 1, wxEXPAND, 5 );
sb_provider_contact->Add( sb_provider_contact_horiz, 1, wxEXPAND, 5 );
this->SetSizer( sb_provider_contact );
this->Layout();
}
wxEAPProviderContactInfoPanelBase::~wxEAPProviderContactInfoPanelBase()
{
}
wxEAPProviderIDPanelBase::wxEAPProviderIDPanelBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style )
{ {
wxStaticBoxSizer* sb_provider_id; wxStaticBoxSizer* sb_provider_id;
sb_provider_id = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Your Organization") ), wxVERTICAL ); sb_provider_id = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Provider Unique Identifier") ), wxVERTICAL );
wxBoxSizer* sb_provider_id_horiz; wxBoxSizer* sb_provider_id_horiz;
sb_provider_id_horiz = new wxBoxSizer( wxHORIZONTAL ); sb_provider_id_horiz = new wxBoxSizer( wxHORIZONTAL );
@@ -372,80 +532,40 @@ wxEAPProviderIdentityPanelBase::wxEAPProviderIdentityPanelBase( wxWindow* parent
wxBoxSizer* sb_provider_id_vert; wxBoxSizer* sb_provider_id_vert;
sb_provider_id_vert = new wxBoxSizer( wxVERTICAL ); sb_provider_id_vert = new wxBoxSizer( wxVERTICAL );
m_provider_id_label = new wxStaticText( sb_provider_id->GetStaticBox(), wxID_ANY, _("Describe your organization to customize user prompts. When organization is introduced, end-users find program messages easier to understand and act."), wxDefaultPosition, wxDefaultSize, 0 ); m_provider_id_label_outer = new wxStaticText( sb_provider_id->GetStaticBox(), wxID_ANY, _("Assign your organization a unique ID to allow sharing the same credential set across different network profiles."), wxDefaultPosition, wxDefaultSize, 0 );
m_provider_id_label->Wrap( 446 ); m_provider_id_label_outer->Wrap( 440 );
sb_provider_id_vert->Add( m_provider_id_label, 0, wxALL|wxEXPAND, 5 ); sb_provider_id_vert->Add( m_provider_id_label_outer, 0, wxALL|wxEXPAND, 5 );
wxBoxSizer* sb_provider_name; wxBoxSizer* sb_provider_namespace;
sb_provider_name = new wxBoxSizer( wxVERTICAL ); sb_provider_namespace = new wxBoxSizer( wxVERTICAL );
m_provider_name_label = new wxStaticText( sb_provider_id->GetStaticBox(), wxID_ANY, _("Your organization &name:"), wxDefaultPosition, wxDefaultSize, 0 ); m_provider_namespace_label = new wxStaticText( sb_provider_id->GetStaticBox(), wxID_ANY, _("&Namespace:"), wxDefaultPosition, wxDefaultSize, 0 );
m_provider_name_label->Wrap( -1 ); m_provider_namespace_label->Wrap( -1 );
sb_provider_name->Add( m_provider_name_label, 0, wxBOTTOM, 5 ); sb_provider_namespace->Add( m_provider_namespace_label, 0, wxBOTTOM, 5 );
m_provider_name = new wxTextCtrl( sb_provider_id->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); wxString m_provider_namespaceChoices[] = { _("urn:RFC4282:realm"), _("urn:uuid") };
m_provider_name->SetToolTip( _("Your organization name as it will appear on helpdesk contact notifications") ); int m_provider_namespaceNChoices = sizeof( m_provider_namespaceChoices ) / sizeof( wxString );
m_provider_namespace = new wxChoice( sb_provider_id->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_provider_namespaceNChoices, m_provider_namespaceChoices, 0 );
sb_provider_name->Add( m_provider_name, 0, wxEXPAND|wxBOTTOM, 5 ); m_provider_namespace->SetSelection( 0 );
sb_provider_namespace->Add( m_provider_namespace, 0, wxEXPAND, 5 );
m_provider_name_note = new wxStaticText( sb_provider_id->GetStaticBox(), wxID_ANY, _("(Keep it short, please)"), wxDefaultPosition, wxDefaultSize, 0 );
m_provider_name_note->Wrap( -1 );
sb_provider_name->Add( m_provider_name_note, 0, wxALIGN_RIGHT, 5 );
sb_provider_id_vert->Add( sb_provider_name, 0, wxEXPAND|wxALL, 5 ); sb_provider_id_vert->Add( sb_provider_namespace, 0, wxEXPAND|wxALL, 5 );
wxBoxSizer* sb_provider_helpdesk; wxBoxSizer* sb_provider_id_inner;
sb_provider_helpdesk = new wxBoxSizer( wxVERTICAL ); sb_provider_id_inner = new wxBoxSizer( wxVERTICAL );
m_provider_helpdesk_label = new wxStaticText( sb_provider_id->GetStaticBox(), wxID_ANY, _("Helpdesk contact &information:"), wxDefaultPosition, wxDefaultSize, 0 ); m_provider_id_label = new wxStaticText( sb_provider_id->GetStaticBox(), wxID_ANY, _("Provider unique &identifier:"), wxDefaultPosition, wxDefaultSize, 0 );
m_provider_helpdesk_label->Wrap( -1 ); m_provider_id_label->Wrap( -1 );
sb_provider_helpdesk->Add( m_provider_helpdesk_label, 0, wxBOTTOM, 5 ); sb_provider_id_inner->Add( m_provider_id_label, 0, wxBOTTOM, 5 );
wxFlexGridSizer* sb_provider_helpdesk_inner; m_provider_id = new wxTextCtrl( sb_provider_id->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
sb_provider_helpdesk_inner = new wxFlexGridSizer( 0, 2, 0, 0 ); m_provider_id->SetToolTip( _("Your organization ID to assign same credentials from other profiles") );
sb_provider_helpdesk_inner->AddGrowableCol( 1 );
sb_provider_helpdesk_inner->SetFlexibleDirection( wxBOTH );
sb_provider_helpdesk_inner->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_provider_web_icon = new wxStaticText( sb_provider_id->GetStaticBox(), wxID_ANY, _(""), wxDefaultPosition, wxDefaultSize, 0 ); sb_provider_id_inner->Add( m_provider_id, 0, wxEXPAND, 5 );
m_provider_web_icon->Wrap( -1 );
m_provider_web_icon->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxT("Wingdings") ) );
sb_provider_helpdesk_inner->Add( m_provider_web_icon, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT, 5 );
m_provider_web = new wxTextCtrl( sb_provider_id->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_provider_web->SetToolTip( _("Your helpdesk website address") );
sb_provider_helpdesk_inner->Add( m_provider_web, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxBOTTOM, 5 );
m_provider_email_icon = new wxStaticText( sb_provider_id->GetStaticBox(), wxID_ANY, _("*"), wxDefaultPosition, wxDefaultSize, 0 );
m_provider_email_icon->Wrap( -1 );
m_provider_email_icon->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxT("Wingdings") ) );
sb_provider_helpdesk_inner->Add( m_provider_email_icon, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT, 5 );
m_provider_email = new wxTextCtrl( sb_provider_id->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_provider_email->SetToolTip( _("Your helpdesk e-mail address") );
sb_provider_helpdesk_inner->Add( m_provider_email, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxBOTTOM, 5 );
m_provider_phone_icon = new wxStaticText( sb_provider_id->GetStaticBox(), wxID_ANY, _(")"), wxDefaultPosition, wxDefaultSize, 0 );
m_provider_phone_icon->Wrap( -1 );
m_provider_phone_icon->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxT("Wingdings") ) );
sb_provider_helpdesk_inner->Add( m_provider_phone_icon, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_provider_phone = new wxTextCtrl( sb_provider_id->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_provider_phone->SetToolTip( _("Your helpdesk phone number") );
sb_provider_helpdesk_inner->Add( m_provider_phone, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 );
sb_provider_helpdesk->Add( sb_provider_helpdesk_inner, 1, wxEXPAND, 5 ); sb_provider_id_vert->Add( sb_provider_id_inner, 0, wxEXPAND|wxALL, 5 );
sb_provider_id_vert->Add( sb_provider_helpdesk, 1, wxEXPAND, 5 );
sb_provider_id_horiz->Add( sb_provider_id_vert, 1, wxEXPAND, 5 ); sb_provider_id_horiz->Add( sb_provider_id_vert, 1, wxEXPAND, 5 );
@@ -458,7 +578,7 @@ wxEAPProviderIdentityPanelBase::wxEAPProviderIdentityPanelBase( wxWindow* parent
this->Layout(); this->Layout();
} }
wxEAPProviderIdentityPanelBase::~wxEAPProviderIdentityPanelBase() wxEAPProviderIDPanelBase::~wxEAPProviderIDPanelBase()
{ {
} }
@@ -477,21 +597,21 @@ wxEAPProviderLockPanelBase::wxEAPProviderLockPanelBase( wxWindow* parent, wxWind
sb_provider_lock_vert = new wxBoxSizer( wxVERTICAL ); sb_provider_lock_vert = new wxBoxSizer( wxVERTICAL );
m_provider_lock_label = new wxStaticText( sb_provider_lock->GetStaticBox(), wxID_ANY, _("Your configuration can be locked to prevent accidental modification by end-users. Users will only be allowed to enter credentials."), wxDefaultPosition, wxDefaultSize, 0 ); m_provider_lock_label = new wxStaticText( sb_provider_lock->GetStaticBox(), wxID_ANY, _("Your configuration can be locked to prevent accidental modification by end-users. Users will only be allowed to enter credentials."), wxDefaultPosition, wxDefaultSize, 0 );
m_provider_lock_label->Wrap( 446 ); m_provider_lock_label->Wrap( 440 );
sb_provider_lock_vert->Add( m_provider_lock_label, 0, wxALL|wxEXPAND, 5 ); sb_provider_lock_vert->Add( m_provider_lock_label, 0, wxALL|wxEXPAND, 5 );
wxBoxSizer* sb_provider_name; wxBoxSizer* sb_provider_lock_inner;
sb_provider_name = new wxBoxSizer( wxVERTICAL ); sb_provider_lock_inner = new wxBoxSizer( wxVERTICAL );
m_provider_lock = new wxCheckBox( sb_provider_lock->GetStaticBox(), wxID_ANY, _("&Lock this configuration and prevent any further modification via user interface."), wxDefaultPosition, wxDefaultSize, 0 ); m_provider_lock = new wxCheckBox( sb_provider_lock->GetStaticBox(), wxID_ANY, _("&Lock this configuration and prevent any further modification via user interface."), wxDefaultPosition, wxDefaultSize, 0 );
sb_provider_name->Add( m_provider_lock, 0, wxEXPAND|wxBOTTOM, 5 ); sb_provider_lock_inner->Add( m_provider_lock, 0, wxEXPAND|wxBOTTOM, 5 );
m_provider_lock_note = new wxStaticText( sb_provider_lock->GetStaticBox(), wxID_ANY, _("(Warning: Once locked, you can not revert using this dialog!)"), wxDefaultPosition, wxDefaultSize, 0 ); m_provider_lock_note = new wxStaticText( sb_provider_lock->GetStaticBox(), wxID_ANY, _("(Warning: Once locked, you can not revert using this dialog!)"), wxDefaultPosition, wxDefaultSize, 0 );
m_provider_lock_note->Wrap( -1 ); m_provider_lock_note->Wrap( -1 );
sb_provider_name->Add( m_provider_lock_note, 0, wxALIGN_RIGHT, 5 ); sb_provider_lock_inner->Add( m_provider_lock_note, 0, wxALIGN_RIGHT, 5 );
sb_provider_lock_vert->Add( sb_provider_name, 0, wxEXPAND|wxALL, 5 ); sb_provider_lock_vert->Add( sb_provider_lock_inner, 0, wxEXPAND|wxALL, 5 );
sb_provider_lock_horiz->Add( sb_provider_lock_vert, 1, wxEXPAND, 5 ); sb_provider_lock_horiz->Add( sb_provider_lock_vert, 1, wxEXPAND, 5 );

File diff suppressed because it is too large Load Diff

View File

@@ -35,6 +35,7 @@ class wxEAPBannerPanel;
#include <wx/statbox.h> #include <wx/statbox.h>
#include <wx/timer.h> #include <wx/timer.h>
#include <wx/checkbox.h> #include <wx/checkbox.h>
#include <wx/choice.h>
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@@ -48,7 +49,9 @@ class wxEAPConfigDialogBase : public wxDialog
protected: protected:
wxEAPBannerPanel *m_banner; wxEAPBannerPanel *m_banner;
wxNotebook* m_providers; wxNotebook* m_providers;
wxButton* m_advanced; wxButton* m_prov_add;
wxButton* m_prov_remove;
wxButton* m_prov_advanced;
wxStdDialogButtonSizer* m_buttons; wxStdDialogButtonSizer* m_buttons;
wxButton* m_buttonsOK; wxButton* m_buttonsOK;
wxButton* m_buttonsCancel; wxButton* m_buttonsCancel;
@@ -56,12 +59,14 @@ class wxEAPConfigDialogBase : public wxDialog
// Virtual event handlers, overide them in your derived class // Virtual event handlers, overide them in your derived class
virtual void OnInitDialog( wxInitDialogEvent& event ) { event.Skip(); } virtual void OnInitDialog( wxInitDialogEvent& event ) { event.Skip(); }
virtual void OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); } virtual void OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void OnAdvanced( wxCommandEvent& event ) { event.Skip(); } virtual void OnProvAdd( wxCommandEvent& event ) { event.Skip(); }
virtual void OnProvRemove( wxCommandEvent& event ) { event.Skip(); }
virtual void OnProvAdvanced( wxCommandEvent& event ) { event.Skip(); }
public: public:
wxEAPConfigDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("EAP Method Configuration"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); wxEAPConfigDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("EAP Connection Configuration"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE );
~wxEAPConfigDialogBase(); ~wxEAPConfigDialogBase();
}; };
@@ -91,6 +96,31 @@ class wxEAPGeneralDialogBase : public wxDialog
}; };
///////////////////////////////////////////////////////////////////////////////
/// Class wxEAPCredentialsConnectionDialogBase
///////////////////////////////////////////////////////////////////////////////
class wxEAPCredentialsConnectionDialogBase : public wxDialog
{
private:
protected:
wxEAPBannerPanel *m_banner;
wxStdDialogButtonSizer* m_buttons;
wxButton* m_buttonsOK;
wxButton* m_buttonsCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnInitDialog( wxInitDialogEvent& event ) { event.Skip(); }
public:
wxNotebook* m_providers;
wxEAPCredentialsConnectionDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("EAP Credentials"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE );
~wxEAPCredentialsConnectionDialogBase();
};
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// Class wxEAPBannerPanelBase /// Class wxEAPBannerPanelBase
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@@ -185,15 +215,15 @@ class wxEAPCredentialsPassPanelBase : public wxEAPCredentialsPanelBase
}; };
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// Class wxEAPProviderIdentityPanelBase /// Class wxEAPProviderContactInfoPanelBase
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
class wxEAPProviderIdentityPanelBase : public wxPanel class wxEAPProviderContactInfoPanelBase : public wxPanel
{ {
private: private:
protected: protected:
wxStaticBitmap* m_provider_id_icon; wxStaticBitmap* m_provider_contact_icon;
wxStaticText* m_provider_id_label; wxStaticText* m_provider_contact_label;
wxStaticText* m_provider_name_label; wxStaticText* m_provider_name_label;
wxTextCtrl* m_provider_name; wxTextCtrl* m_provider_name;
wxStaticText* m_provider_name_note; wxStaticText* m_provider_name_note;
@@ -207,8 +237,30 @@ class wxEAPProviderIdentityPanelBase : public wxPanel
public: public:
wxEAPProviderIdentityPanelBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 500,-1 ), long style = wxTAB_TRAVERSAL ); wxEAPProviderContactInfoPanelBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 500,-1 ), long style = wxTAB_TRAVERSAL );
~wxEAPProviderIdentityPanelBase(); ~wxEAPProviderContactInfoPanelBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class wxEAPProviderIDPanelBase
///////////////////////////////////////////////////////////////////////////////
class wxEAPProviderIDPanelBase : public wxPanel
{
private:
protected:
wxStaticBitmap* m_provider_id_icon;
wxStaticText* m_provider_id_label_outer;
wxStaticText* m_provider_namespace_label;
wxChoice* m_provider_namespace;
wxStaticText* m_provider_id_label;
wxTextCtrl* m_provider_id;
public:
wxEAPProviderIDPanelBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 500,-1 ), long style = wxTAB_TRAVERSAL );
~wxEAPProviderIDPanelBase();
}; };

View File

@@ -95,7 +95,45 @@ wxEAPCredentialsDialog::wxEAPCredentialsDialog(const eap::config_provider &prov,
wxEAPGeneralDialog(parent, id, title, pos, size, style) wxEAPGeneralDialog(parent, id, title, pos, size, style)
{ {
// Set banner title. // Set banner title.
m_banner->m_title->SetLabel(wxString::Format(_("%s Credentials"), wxEAPGetProviderName(prov.m_id).c_str())); m_banner->m_title->SetLabel(wxString::Format(_("%s Credentials"), wxEAPGetProviderName(prov.m_name).c_str()));
}
//////////////////////////////////////////////////////////////////////
// wxEAPCredentialsConnectionDialog
//////////////////////////////////////////////////////////////////////
wxEAPCredentialsConnectionDialog::wxEAPCredentialsConnectionDialog(wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &pos, const wxSize &size, long style) :
wxEAPCredentialsConnectionDialogBase(parent, id, title, pos, size, style)
{
// Set extra style here, as wxFormBuilder overrides all default flags.
this->SetExtraStyle(this->GetExtraStyle() | wxWS_EX_VALIDATE_RECURSIVELY);
// Load window icons.
#ifdef __WINDOWS__
wxIconBundle icons;
icons.AddIcon(wxIcon(wxT("product.ico"), wxBITMAP_TYPE_ICO_RESOURCE, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON)));
icons.AddIcon(wxIcon(wxT("product.ico"), wxBITMAP_TYPE_ICO_RESOURCE, ::GetSystemMetrics(SM_CXICON ), ::GetSystemMetrics(SM_CYICON )));
this->SetIcons(icons);
#else
this->SetIcon(wxIcon(wxICON(product.ico)));
#endif
// Set banner title.
m_banner->m_title->SetLabel(_("EAP Credentials"));
m_buttonsOK->SetDefault();
}
void wxEAPCredentialsConnectionDialog::OnInitDialog(wxInitDialogEvent& event)
{
// Forward the event to child panels.
for (wxWindowList::compatibility_iterator provider = m_providers->GetChildren().GetFirst(); provider; provider = provider->GetNext()) {
wxWindow *prov = wxDynamicCast(provider->GetData(), wxWindow);
if (prov)
prov->GetEventHandler()->ProcessEvent(event);
}
} }
@@ -126,8 +164,7 @@ void wxEAPNotePanel::CreateContactFields(const eap::config_provider &prov)
{ {
if (!prov.m_help_email.empty() || !prov.m_help_web.empty() || !prov.m_help_phone.empty()) { if (!prov.m_help_email.empty() || !prov.m_help_web.empty() || !prov.m_help_phone.empty()) {
m_provider_notice = new wxStaticText(this, wxID_ANY, wxString::Format(_("For additional help and instructions, please contact %s at:"), m_provider_notice = new wxStaticText(this, wxID_ANY, wxString::Format(_("For additional help and instructions, please contact %s at:"),
!prov.m_name.empty() ? prov.m_name.c_str() : !prov.m_name.empty() ? prov.m_name.c_str() : _("your provider")), wxDefaultPosition, wxDefaultSize, 0);
!prov.m_id .empty() ? winstd::tstring_printf(_("your %ls provider"), prov.m_id.c_str()).c_str() : _("your provider")), wxDefaultPosition, wxDefaultSize, 0);
m_provider_notice->Wrap(449); m_provider_notice->Wrap(449);
m_note_vert->Add(m_provider_notice, 0, wxUP|wxLEFT|wxRIGHT|wxEXPAND, 5); m_note_vert->Add(m_provider_notice, 0, wxUP|wxLEFT|wxRIGHT|wxEXPAND, 5);
@@ -189,8 +226,7 @@ wxEAPProviderLockedPanel::wxEAPProviderLockedPanel(const eap::config_provider &p
m_note_icon->SetIcon(wxLoadIconFromResource(lib_shell32, MAKEINTRESOURCE(48))); m_note_icon->SetIcon(wxLoadIconFromResource(lib_shell32, MAKEINTRESOURCE(48)));
m_note_label->SetLabel(wxString::Format(_("%s has pre-set parts of this configuration. Those parts are locked to prevent accidental modification."), m_note_label->SetLabel(wxString::Format(_("%s has pre-set parts of this configuration. Those parts are locked to prevent accidental modification."),
!prov.m_name.empty() ? prov.m_name.c_str() : !prov.m_name.empty() ? prov.m_name.c_str() : _("Your provider")));
!prov.m_id .empty() ? winstd::tstring_printf(_("Your %ls provider"), prov.m_id.c_str()).c_str() : _("Your provider")));
m_note_label->Wrap(449); m_note_label->Wrap(449);
CreateContactFields(prov); CreateContactFields(prov);
@@ -250,36 +286,36 @@ void wxEAPConfigWindow::OnInitDialog(wxInitDialogEvent& /*event*/)
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// wxEAPProviderIdentityPanel // wxEAPProviderContactInfoPanel
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
wxEAPProviderIdentityPanel::wxEAPProviderIdentityPanel(eap::config_provider &prov, wxWindow* parent) : wxEAPProviderContactInfoPanel::wxEAPProviderContactInfoPanel(eap::config_provider &prov, wxWindow* parent) :
m_prov(prov), m_prov(prov),
wxEAPProviderIdentityPanelBase(parent) wxEAPProviderContactInfoPanelBase(parent)
{ {
// Load and set icon. // Load and set icon.
winstd::library lib_shell32; winstd::library lib_shell32;
if (lib_shell32.load(_T("shell32.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE)) if (lib_shell32.load(_T("shell32.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE))
m_provider_id_icon->SetIcon(wxLoadIconFromResource(lib_shell32, MAKEINTRESOURCE(259))); m_provider_contact_icon->SetIcon(wxLoadIconFromResource(lib_shell32, MAKEINTRESOURCE(259)));
} }
bool wxEAPProviderIdentityPanel::TransferDataToWindow() bool wxEAPProviderContactInfoPanel::TransferDataToWindow()
{ {
m_provider_name ->SetValue(m_prov.m_id ); m_provider_name ->SetValue(m_prov.m_name );
m_provider_web ->SetValue(m_prov.m_help_web ); m_provider_web ->SetValue(m_prov.m_help_web );
m_provider_email->SetValue(m_prov.m_help_email); m_provider_email->SetValue(m_prov.m_help_email);
m_provider_phone->SetValue(m_prov.m_help_phone); m_provider_phone->SetValue(m_prov.m_help_phone);
return wxEAPProviderIdentityPanelBase::TransferDataToWindow(); return wxEAPProviderContactInfoPanelBase::TransferDataToWindow();
} }
bool wxEAPProviderIdentityPanel::TransferDataFromWindow() bool wxEAPProviderContactInfoPanel::TransferDataFromWindow()
{ {
wxCHECK(wxEAPProviderIdentityPanelBase::TransferDataFromWindow(), false); wxCHECK(wxEAPProviderContactInfoPanelBase::TransferDataFromWindow(), false);
m_prov.m_id = m_provider_name ->GetValue(); m_prov.m_name = m_provider_name ->GetValue();
m_prov.m_help_web = m_provider_web ->GetValue(); m_prov.m_help_web = m_provider_web ->GetValue();
m_prov.m_help_email = m_provider_email->GetValue(); m_prov.m_help_email = m_provider_email->GetValue();
m_prov.m_help_phone = m_provider_phone->GetValue(); m_prov.m_help_phone = m_provider_phone->GetValue();
@@ -288,6 +324,41 @@ bool wxEAPProviderIdentityPanel::TransferDataFromWindow()
} }
//////////////////////////////////////////////////////////////////////
// wxEAPProviderIDPanel
//////////////////////////////////////////////////////////////////////
wxEAPProviderIDPanel::wxEAPProviderIDPanel(eap::config_provider &prov, wxWindow* parent) :
m_prov(prov),
wxEAPProviderIDPanelBase(parent)
{
// Load and set icon.
winstd::library lib_shell32;
if (lib_shell32.load(_T("shell32.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE))
m_provider_id_icon->SetIcon(wxLoadIconFromResource(lib_shell32, MAKEINTRESOURCE(29)));
}
bool wxEAPProviderIDPanel::TransferDataToWindow()
{
m_provider_namespace->SetStringSelection(m_prov.m_namespace);
m_provider_id ->SetValue(m_prov.m_id);
return wxEAPProviderIDPanelBase::TransferDataToWindow();
}
bool wxEAPProviderIDPanel::TransferDataFromWindow()
{
wxCHECK(wxEAPProviderIDPanelBase::TransferDataFromWindow(), false);
m_prov.m_namespace = m_provider_namespace->GetStringSelection();
m_prov.m_id = m_provider_id ->GetValue();
return true;
}
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// wxEAPProviderLockPanel // wxEAPProviderLockPanel
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
@@ -332,13 +403,16 @@ wxEAPConfigProvider::wxEAPConfigProvider(eap::config_provider &prov, wxWindow *p
// Set banner title. // Set banner title.
m_banner->m_title->SetLabel(title); m_banner->m_title->SetLabel(title);
m_identity = new wxEAPProviderIdentityPanel(prov, this); m_contact = new wxEAPProviderContactInfoPanel(prov, this);
AddContent(m_contact);
m_identity = new wxEAPProviderIDPanel(prov, this);
AddContent(m_identity); AddContent(m_identity);
m_lock = new wxEAPProviderLockPanel(prov, this); m_lock = new wxEAPProviderLockPanel(prov, this);
AddContent(m_lock); AddContent(m_lock);
m_identity->m_provider_name->SetFocusFromKbd(); m_contact->m_provider_name->SetFocusFromKbd();
} }

Binary file not shown.

2
lib/MSCHAPv2/build/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/temp
/*.user

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>..\..\Events\build\temp\Events.$(Platform).$(Configuration).$(PlatformToolset);..\..\WinStd\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup />
</Project>

View File

@@ -0,0 +1,103 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{86A6D6A0-4B7D-4134-BE81-A5755C77584D}</ProjectGuid>
<RootNamespace>MSCHAPv2</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\..\include\Win32.props" />
<Import Project="..\..\..\include\Debug.props" />
<Import Project="MSCHAPv2.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\..\include\x64.props" />
<Import Project="..\..\..\include\Debug.props" />
<Import Project="MSCHAPv2.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\..\include\Win32.props" />
<Import Project="..\..\..\include\Release.props" />
<Import Project="MSCHAPv2.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\..\include\x64.props" />
<Import Project="..\..\..\include\Release.props" />
<Import Project="MSCHAPv2.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
<ItemGroup>
<ClInclude Include="..\include\Config.h" />
<ClInclude Include="..\include\Credentials.h" />
<ClInclude Include="..\include\Method.h" />
<ClInclude Include="..\include\MSCHAPv2.h" />
<ClInclude Include="..\src\StdAfx.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\Config.cpp" />
<ClCompile Include="..\src\Credentials.cpp" />
<ClCompile Include="..\src\Method.cpp" />
<ClCompile Include="..\src\MSCHAPv2.cpp" />
<ClCompile Include="..\src\StdAfx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\StdAfx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\Config.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\Credentials.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\Method.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\MSCHAPv2.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\StdAfx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\Config.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\Credentials.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\Method.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\MSCHAPv2.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,109 @@
/*
Copyright 2015-2016 Amebis
Copyright 2016 GÉANT
This file is part of GÉANTLink.
GÉANTLink is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
GÉANTLink is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GÉANTLink. If not, see <http://www.gnu.org/licenses/>.
*/
#include <sal.h>
namespace eap
{
///
/// MSCHAPv2 configuration
///
class config_method_mschapv2;
}
#pragma once
#include "Credentials.h"
#include "../../EAPBase/include/Config.h"
#include <Windows.h>
#include <sal.h>
#include <tchar.h>
namespace eap
{
class config_method_mschapv2 : public config_method_with_cred
{
public:
///
/// Constructs configuration
///
/// \param[in] mod EAP module to use for global services
///
config_method_mschapv2(_In_ module &mod);
///
/// Copies configuration
///
/// \param[in] other Configuration to copy from
///
config_method_mschapv2(_In_ const config_method_mschapv2 &other);
///
/// Moves configuration
///
/// \param[in] other Configuration to move from
///
config_method_mschapv2(_Inout_ config_method_mschapv2 &&other);
///
/// Copies configuration
///
/// \param[in] other Configuration to copy from
///
/// \returns Reference to this object
///
config_method_mschapv2& operator=(_In_ const config_method_mschapv2 &other);
///
/// Moves configuration
///
/// \param[in] other Configuration to move from
///
/// \returns Reference to this object
///
config_method_mschapv2& operator=(_Inout_ config_method_mschapv2 &&other);
///
/// Clones configuration
///
/// \returns Pointer to cloned configuration
///
virtual config* clone() const;
///
/// Returns EAP method type of this configuration
///
/// \returns `eap::type_mschapv2`
///
virtual winstd::eap_type_t get_method_id() const;
///
/// Returns a string \c L"MSCHAPv2"
///
virtual const wchar_t* get_method_str() const;
///
/// Creates a blank set of credentials suitable for this method
///
virtual credentials* make_credentials() const;
};
}

View File

@@ -0,0 +1,122 @@
/*
Copyright 2015-2016 Amebis
Copyright 2016 GÉANT
This file is part of GÉANTLink.
GÉANTLink is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
GÉANTLink is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GÉANTLink. If not, see <http://www.gnu.org/licenses/>.
*/
namespace eap
{
///
/// MSCHAPv2 credentials
///
class credentials_mschapv2;
}
#pragma once
#include "Config.h"
#include "../../EAPBase/include/Credentials.h"
#include <Windows.h>
#include <sal.h>
#include <tchar.h>
namespace eap
{
class credentials_mschapv2 : public credentials_pass
{
public:
///
/// Constructs credentials
///
/// \param[in] mod EAP module to use for global services
///
credentials_mschapv2(_In_ module &mod);
///
/// Copies credentials
///
/// \param[in] other Credentials to copy from
///
credentials_mschapv2(_In_ const credentials_mschapv2 &other);
///
/// Moves credentials
///
/// \param[in] other Credentials to move from
///
credentials_mschapv2(_Inout_ credentials_mschapv2 &&other);
///
/// Copies credentials
///
/// \param[in] other Credentials to copy from
///
/// \returns Reference to this object
///
credentials_mschapv2& operator=(_In_ const credentials_mschapv2 &other);
///
/// Moves credentials
///
/// \param[in] other Credentials to move from
///
/// \returns Reference to this object
///
credentials_mschapv2& operator=(_Inout_ credentials_mschapv2 &&other);
///
/// Clones credentials
///
/// \returns Pointer to cloned credentials
///
virtual config* clone() const;
/// \name Storage
/// @{
///
/// Return target suffix for Windows Credential Manager credential name
///
virtual LPCTSTR target_suffix() const;
/// @}
///
/// Combine credentials in the following order:
///
/// 1. Cached credentials
/// 2. Pre-configured credentials
/// 3. Stored credentials
///
/// \param[in] cred_cached Cached credentials (optional, can be \c NULL, must be credentials_mschapv2* type)
/// \param[in] cfg Method configuration (must be config_method_mschapv2 type)
/// \param[in] pszTargetName The name in Windows Credential Manager to retrieve credentials from (optional, can be \c NULL)
///
/// \returns
/// - \c source_cache Credentials were obtained from EapHost cache
/// - \c source_preshared Credentials were set by method configuration
/// - \c source_storage Credentials were loaded from Windows Credential Manager
///
virtual source_t combine(
_In_ const credentials *cred_cached,
_In_ const config_method_with_cred &cfg,
_In_opt_z_ LPCTSTR pszTargetName);
};
}

View File

@@ -0,0 +1,260 @@
/*
Copyright 2015-2016 Amebis
Copyright 2016 G<>ANT
This file is part of G<>ANTLink.
G<>ANTLink is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
G<>ANTLink is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with G<>ANTLink. If not, see <http://www.gnu.org/licenses/>.
*/
#include <WinStd/Crypt.h>
namespace eap
{
///
/// MSCHAPv2 Challenge
///
struct challenge_mschapv2;
///
/// MSCHAPv2 Challenge Hash
///
struct challenge_hash;
///
/// NT-Password Hash
///
struct nt_password_hash;
///
/// NT-Response
///
struct nt_response;
///
/// Authenticator Response
///
struct authenticator_response;
///
/// Creates DES encryption key with given plaintext key
///
/// \param[in] cp Handle of the cryptographics provider
/// \param[in] key The key (without parity bits)
/// \param[in] size Size of \p key (maximum 7B)
///
winstd::crypt_key create_des_key(_In_ HCRYPTPROV cp, _In_count_(size) const unsigned char *key, _In_ size_t size);
}
#pragma once
#include "../../EAPBase/include/EAP.h"
namespace eap
{
#pragma pack(push)
#pragma pack(1)
struct __declspec(novtable) challenge_mschapv2 : public sanitizing_blob_xf<16>
{
///
/// Generates random challenge
///
/// \param[in] cp Handle of the cryptographics provider
///
void randomize(_In_ HCRYPTPROV cp);
};
struct __declspec(novtable) challenge_hash : public sanitizing_blob_xf<8>
{
///
/// Constructor
///
challenge_hash();
///
/// Constructs a challenge hash
///
/// \sa [Microsoft PPP CHAP Extensions, Version 2 (Chapter 8.2. ChallengeHash())](https://tools.ietf.org/html/rfc2759#section-8.2)
///
/// \param[in] cp Handle of the cryptographics provider
/// \param[in] challenge_server Authenticator challenge
/// \param[in] challenge_client Peer challenge
/// \param[in] username Username
///
challenge_hash(
_In_ HCRYPTPROV cp,
_In_ const challenge_mschapv2 &challenge_server,
_In_ const challenge_mschapv2 &challenge_client,
_In_z_ const char *username);
///
/// Copies a challenge hash
///
/// \param[in] other Challenge hash to copy from
///
challenge_hash(_In_ const sanitizing_blob_f<8> &other);
#ifdef _DEBUG
///
/// Moves the challenge hash
///
/// \param[inout] other Challenge hash to move from
///
challenge_hash(_Inout_ sanitizing_blob_zf<8> &&other);
#endif
};
struct __declspec(novtable) nt_password_hash : public sanitizing_blob_xf<16>
{
///
/// Constructor
///
nt_password_hash();
///
/// Constructs a NT-Password hash
///
/// \sa [Microsoft PPP CHAP Extensions, Version 2 (Chapter 8.3. NtPasswordHash())](https://tools.ietf.org/html/rfc2759#section-8.3)
///
/// \param[in] cp Handle of the cryptographics provider
/// \param[in] password Password
///
nt_password_hash(
_In_ HCRYPTPROV cp,
_In_z_ const wchar_t *password);
///
/// Constructs a hash of NT-Password hash
///
/// \sa [Microsoft PPP CHAP Extensions, Version 2 (Chapter 8.4. HashNtPasswordHash())](https://tools.ietf.org/html/rfc2759#section-8.4)
///
/// \param[in] cp Handle of the cryptographics provider
/// \param[in] pwd_hash NT-Password hash
///
nt_password_hash(
_In_ HCRYPTPROV cp,
_In_ const nt_password_hash &pwd_hash);
///
/// Copies a NT-Password hash
///
/// \param[in] other NT-Password to copy from
///
nt_password_hash(_In_ const sanitizing_blob_f<16> &other);
#ifdef _DEBUG
///
/// Moves the NT-Password hash
///
/// \param[inout] other NT-Password hash to move from
///
nt_password_hash(_Inout_ sanitizing_blob_zf<16> &&other);
#endif
};
struct __declspec(novtable) nt_response : public sanitizing_blob_xf<24>
{
///
/// Constructor
///
nt_response();
///
/// Constructs a NT-Response
///
/// \sa [Microsoft PPP CHAP Extensions, Version 2 (Chapter 8.1. GenerateNTResponse())](https://tools.ietf.org/html/rfc2759#section-8.1)
///
/// \param[in] cp Handle of the cryptographics provider
/// \param[in] challenge_server Authenticator challenge
/// \param[in] challenge_client Peer challenge
/// \param[in] username Username
/// \param[in] password Password
///
nt_response(
_In_ HCRYPTPROV cp,
_In_ const challenge_mschapv2 &challenge_server,
_In_ const challenge_mschapv2 &challenge_client,
_In_z_ const char *username,
_In_z_ const wchar_t *password);
///
/// Copies a NT-Response
///
/// \param[in] other NT-Response to copy from
///
nt_response(_In_ const sanitizing_blob_f<24> &other);
#ifdef _DEBUG
///
/// Moves the NT-Response
///
/// \param[inout] other NT-Response to move from
///
nt_response(_Inout_ sanitizing_blob_zf<24> &&other);
#endif
};
struct __declspec(novtable) authenticator_response : public sanitizing_blob_xf<20>
{
///
/// Constructor
///
authenticator_response();
///
/// Constructs an authenticator response
///
/// \sa [Microsoft PPP CHAP Extensions, Version 2 (Chapter 8.7. GenerateAuthenticatorResponse())](https://tools.ietf.org/html/rfc2759#section-8.7)
///
/// \param[in] cp Handle of the cryptographics provider
/// \param[in] challenge_server Authenticator challenge
/// \param[in] challenge_client Peer challenge
/// \param[in] username Username
/// \param[in] password Password
/// \param[in] nt_resp NT-Response
///
authenticator_response(
_In_ HCRYPTPROV cp,
_In_ const challenge_mschapv2 &challenge_server,
_In_ const challenge_mschapv2 &challenge_client,
_In_z_ const char *username,
_In_z_ const wchar_t *password,
_In_ const nt_response &nt_resp);
///
/// Copies an authenticator response
///
/// \param[in] other Authenticator response to copy from
///
authenticator_response(_In_ const sanitizing_blob_f<20> &other);
#ifdef _DEBUG
///
/// Moves the authenticator response
///
/// \param[inout] other Authenticator response to move from
///
authenticator_response(_Inout_ sanitizing_blob_zf<20> &&other);
#endif
};
#pragma pack(pop)
}

View File

@@ -0,0 +1,151 @@
/*
Copyright 2015-2016 Amebis
Copyright 2016 G<>ANT
This file is part of G<>ANTLink.
G<>ANTLink is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
G<>ANTLink is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with G<>ANTLink. If not, see <http://www.gnu.org/licenses/>.
*/
namespace eap
{
///
/// MSCHAPv2 method
///
class method_mschapv2;
}
#pragma once
#include "Config.h"
#include "Credentials.h"
#include "MSCHAPv2.h"
#include "../../EAPBase/include/Method.h"
namespace eap
{
class method_mschapv2 : public method_noneap
{
public:
///
/// Constructs an EAP method
///
/// \param[in] mod EAP module to use for global services
/// \param[in] cfg Method configuration
/// \param[in] cred User credentials
///
method_mschapv2(_In_ module &module, _In_ config_method_mschapv2 &cfg, _In_ credentials_mschapv2 &cred);
///
/// Moves an EAP method
///
/// \param[in] other EAP method to move from
///
method_mschapv2(_Inout_ method_mschapv2 &&other);
///
/// Moves an EAP method
///
/// \param[in] other EAP method to move from
///
/// \returns Reference to this object
///
method_mschapv2& operator=(_Inout_ method_mschapv2 &&other);
/// \name Packet processing
/// @{
///
/// Starts an EAP authentication session on the peer EapHost using the EAP method.
///
/// \sa [EapPeerBeginSession function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363600.aspx)
///
virtual void begin_session(
_In_ DWORD dwFlags,
_In_ const EapAttributes *pAttributeArray,
_In_ HANDLE hTokenImpersonateUser,
_In_opt_ DWORD dwMaxSendPacketSize = MAXDWORD);
///
/// Processes a packet received by EapHost from a supplicant.
///
/// \sa [EapPeerProcessRequestPacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363621.aspx)
///
virtual void process_request_packet(
_In_bytecount_(dwReceivedPacketSize) const void *pReceivedPacket,
_In_ DWORD dwReceivedPacketSize,
_Inout_ EapPeerMethodOutput *pEapOutput);
///
/// Obtains the result of an authentication session from the EAP method.
///
/// \sa [EapPeerGetResult function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363611.aspx)
///
virtual void get_result(
_In_ EapPeerMethodResultReason reason,
_Inout_ EapPeerMethodResult *ppResult);
/// @}
friend class method_ttls; // Setting of initial challenge derived from TLS PRF
protected:
///
/// Processes AVPs in a Diameter packet
///
/// \param[in] pck Packet data
/// \param[in] size_pck \p pck size in bytes
///
void process_packet(_In_bytecount_(size_pck) const void *pck, _In_ size_t size_pck);
///
/// Processes MS-CHAP2-Success AVP
///
/// \sa [Microsoft PPP CHAP Extensions, Version 2 (Chapter 5. Success Packet)](https://tools.ietf.org/html/rfc2759#section-5)
///
/// \param[in] pck Packet data
/// \param[in] size_pck \p pck size in bytes
///
void process_success(_In_ int argc, _In_count_(argc) const wchar_t *argv[]);
///
/// Processes MS-CHAP-Error AVP
///
/// \sa [Microsoft PPP CHAP Extensions, Version 2 (Chapter 6. Failure Packet)](https://tools.ietf.org/html/rfc2759#section-6)
///
/// \param[in] pck Packet data
/// \param[in] size_pck \p pck size in bytes
///
void process_error(_In_ int argc, _In_count_(argc) const wchar_t *argv[]);
protected:
credentials_mschapv2 &m_cred; ///< EAP-TLS user credentials
winstd::crypt_prov m_cp; ///< Cryptography provider for general services
challenge_mschapv2 m_challenge_server; ///< MSCHAP server challenge
challenge_mschapv2 m_challenge_client; ///< MSCHAP client challenge
unsigned char m_ident; ///< Ident
nt_response m_nt_resp; ///< NT-Response
bool m_success; ///< Did we receive MS-CHAP2-Success?
enum {
phase_unknown = -1, ///< Unknown phase
phase_init = 0, ///< Send client challenge
phase_challenge_server, ///< Verify server challenge
phase_finished, ///< Connection shut down
} m_phase, m_phase_prev; ///< What phase is our communication at?
};
}

View File

@@ -0,0 +1,88 @@
/*
Copyright 2015-2016 Amebis
Copyright 2016 GÉANT
This file is part of GÉANTLink.
GÉANTLink is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
GÉANTLink is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GÉANTLink. If not, see <http://www.gnu.org/licenses/>.
*/
#include "StdAfx.h"
using namespace std;
using namespace winstd;
//////////////////////////////////////////////////////////////////////
// eap::config_method_mschapv2
//////////////////////////////////////////////////////////////////////
eap::config_method_mschapv2::config_method_mschapv2(_In_ module &mod) : config_method_with_cred(mod)
{
m_preshared.reset(new credentials_mschapv2(mod));
}
eap::config_method_mschapv2::config_method_mschapv2(_In_ const config_method_mschapv2 &other) :
config_method_with_cred(other)
{
}
eap::config_method_mschapv2::config_method_mschapv2(_Inout_ config_method_mschapv2 &&other) :
config_method_with_cred(std::move(other))
{
}
eap::config_method_mschapv2& eap::config_method_mschapv2::operator=(_In_ const config_method_mschapv2 &other)
{
if (this != &other)
(config_method_with_cred&)*this = other;
return *this;
}
eap::config_method_mschapv2& eap::config_method_mschapv2::operator=(_Inout_ config_method_mschapv2 &&other)
{
if (this != &other)
(config_method_with_cred&&)*this = std::move(other);
return *this;
}
eap::config* eap::config_method_mschapv2::clone() const
{
return new config_method_mschapv2(*this);
}
eap_type_t eap::config_method_mschapv2::get_method_id() const
{
return eap_type_legacy_mschapv2;
}
const wchar_t* eap::config_method_mschapv2::get_method_str() const
{
return L"MSCHAPv2";
}
eap::credentials* eap::config_method_mschapv2::make_credentials() const
{
return new credentials_mschapv2(m_module);
}

View File

@@ -0,0 +1,112 @@
/*
Copyright 2015-2016 Amebis
Copyright 2016 GÉANT
This file is part of GÉANTLink.
GÉANTLink is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
GÉANTLink is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GÉANTLink. If not, see <http://www.gnu.org/licenses/>.
*/
#include "StdAfx.h"
using namespace std;
using namespace winstd;
//////////////////////////////////////////////////////////////////////
// eap::credentials_mschapv2
//////////////////////////////////////////////////////////////////////
eap::credentials_mschapv2::credentials_mschapv2(_In_ module &mod) : credentials_pass(mod)
{
}
eap::credentials_mschapv2::credentials_mschapv2(_In_ const credentials_mschapv2 &other) :
credentials_pass(other)
{
}
eap::credentials_mschapv2::credentials_mschapv2(_Inout_ credentials_mschapv2 &&other) :
credentials_pass(std::move(other))
{
}
eap::credentials_mschapv2& eap::credentials_mschapv2::operator=(_In_ const credentials_mschapv2 &other)
{
if (this != &other)
(credentials_pass&)*this = other;
return *this;
}
eap::credentials_mschapv2& eap::credentials_mschapv2::operator=(_Inout_ credentials_mschapv2 &&other)
{
if (this != &other)
(credentials_pass&&)*this = std::move(other);
return *this;
}
eap::config* eap::credentials_mschapv2::clone() const
{
return new credentials_mschapv2(*this);
}
LPCTSTR eap::credentials_mschapv2::target_suffix() const
{
return _T("MSCHAPv2");
}
eap::credentials::source_t eap::credentials_mschapv2::combine(
_In_ const credentials *cred_cached,
_In_ const config_method_with_cred &cfg,
_In_opt_z_ LPCTSTR pszTargetName)
{
if (cred_cached) {
// Using EAP service cached credentials.
*this = *(credentials_mschapv2*)cred_cached;
m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_CACHED1, event_data((unsigned int)eap_type_legacy_mschapv2), event_data(credentials_mschapv2::get_name()), event_data::blank);
return source_cache;
}
if (cfg.m_use_preshared) {
// Using preshared credentials.
*this = *(credentials_mschapv2*)cfg.m_preshared.get();
m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_PRESHARED1, event_data((unsigned int)eap_type_legacy_mschapv2), event_data(credentials_mschapv2::get_name()), event_data::blank);
return source_preshared;
}
if (pszTargetName) {
try {
credentials_mschapv2 cred_loaded(m_module);
cred_loaded.retrieve(pszTargetName);
// Using stored credentials.
*this = std::move(cred_loaded);
m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_STORED1, event_data((unsigned int)eap_type_legacy_mschapv2), event_data(credentials_mschapv2::get_name()), event_data::blank);
return source_storage;
} catch (...) {
// Not actually an error.
}
}
return source_unknown;
}

View File

@@ -0,0 +1,336 @@
/*
Copyright 2015-2016 Amebis
Copyright 2016 G<>ANT
This file is part of G<>ANTLink.
G<>ANTLink is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
G<>ANTLink is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with G<>ANTLink. If not, see <http://www.gnu.org/licenses/>.
*/
#include "StdAfx.h"
using namespace std;
using namespace winstd;
//////////////////////////////////////////////////////////////////////
// eap::create_des_key
//////////////////////////////////////////////////////////////////////
crypt_key eap::create_des_key(_In_ HCRYPTPROV cp, _In_count_(size) const unsigned char *key, _In_ size_t size)
{
// Prepare exported key BLOB.
struct key_blob_prefix {
PUBLICKEYSTRUC header;
DWORD size;
} static const s_prefix = {
{
PLAINTEXTKEYBLOB,
CUR_BLOB_VERSION,
0,
CALG_DES,
},
8,
};
sanitizing_blob key_blob;
key_blob.reserve(sizeof(key_blob_prefix) + 8);
key_blob.assign((const unsigned char*)&s_prefix, (const unsigned char*)(&s_prefix + 1));
// Inject parity bits.
unsigned char out = 0, parity = 1;
size_t i = 0, j = 7, bits = std::min<size_t>(size * 8, 56);
for (; i < bits; i++) {
unsigned char bit = (key[i/8] & (1 << (7 - i%8))) ? 1 : 0;
parity ^= bit;
out |= bit << j;
if (--j == 0) {
out |= parity;
key_blob.push_back(out);
out = 0; parity = 1; j = 7;
}
}
for (; i < 56; i++) {
if (--j == 0) {
out |= parity;
key_blob.push_back(out);
out = 0; parity = 1; j = 7;
}
}
// Import key.
crypt_key k;
if (!k.import(cp, key_blob.data(), (DWORD)key_blob.size(), NULL, 0))
throw winstd::win_runtime_error(__FUNCTION__ " Error importing key 1/3.");
return k;
}
//////////////////////////////////////////////////////////////////////
// eap::challenge_mschapv2
//////////////////////////////////////////////////////////////////////
void eap::challenge_mschapv2::randomize(_In_ HCRYPTPROV cp)
{
if (!CryptGenRandom(cp, sizeof(data), data))
throw win_runtime_error(__FUNCTION__ " Error creating randomness.");
}
//////////////////////////////////////////////////////////////////////
// eap::challenge_hash
//////////////////////////////////////////////////////////////////////
eap::challenge_hash::challenge_hash()
{
}
eap::challenge_hash::challenge_hash(
_In_ HCRYPTPROV cp,
_In_ const challenge_mschapv2 &challenge_server,
_In_ const challenge_mschapv2 &challenge_client,
_In_z_ const char *username)
{
const char *domain = strchr(username, '@');
size_t len_username = domain ? domain - username : strlen(username);
crypt_hash hash;
if (!hash.create(cp, CALG_SHA))
throw win_runtime_error(__FUNCTION__ " Creating SHA hash failed.");
if (!CryptHashData(hash, (const BYTE*)&challenge_client, (DWORD)sizeof(challenge_client), 0) ||
!CryptHashData(hash, (const BYTE*)&challenge_server, (DWORD)sizeof(challenge_server), 0) ||
!CryptHashData(hash, (const BYTE*)username , (DWORD)len_username , 0))
throw win_runtime_error(__FUNCTION__ " Error hashing data.");
unsigned char hash_val[20];
DWORD size_hash_val = sizeof(hash_val);
if (!CryptGetHashParam(hash, HP_HASHVAL, hash_val, &size_hash_val, 0))
throw win_runtime_error(__FUNCTION__ " Error hashing data.");
memcpy(data, hash_val, sizeof(data));
SecureZeroMemory(hash_val, size_hash_val);
}
eap::challenge_hash::challenge_hash(_In_ const sanitizing_blob_f<8> &other) :
sanitizing_blob_xf<8>(other)
{
}
#ifdef _DEBUG
eap::challenge_hash::challenge_hash(_Inout_ sanitizing_blob_zf<8> &&other) :
sanitizing_blob_xf<8>(std::move(other))
{
}
#endif
//////////////////////////////////////////////////////////////////////
// eap::nt_password_hash
//////////////////////////////////////////////////////////////////////
eap::nt_password_hash::nt_password_hash()
{
}
eap::nt_password_hash::nt_password_hash(
_In_ HCRYPTPROV cp,
_In_z_ const wchar_t *password)
{
crypt_hash hash;
if (!hash.create(cp, CALG_MD4))
throw win_runtime_error(__FUNCTION__ " Creating MD4 hash failed.");
if (!CryptHashData(hash, (const BYTE*)password, (DWORD)(wcslen(password) * sizeof(wchar_t)), 0))
throw win_runtime_error(__FUNCTION__ " Error hashing data.");
DWORD size_data = sizeof(data);
if (!CryptGetHashParam(hash, HP_HASHVAL, data, &size_data, 0))
throw win_runtime_error(__FUNCTION__ " Error hashing data.");
}
eap::nt_password_hash::nt_password_hash(
_In_ HCRYPTPROV cp,
_In_ const nt_password_hash &pwd_hash)
{
crypt_hash hash;
if (!hash.create(cp, CALG_MD4))
throw win_runtime_error(__FUNCTION__ " Creating MD4 hash failed.");
if (!CryptHashData(hash, (const BYTE*)&pwd_hash, (DWORD)sizeof(pwd_hash), 0))
throw win_runtime_error(__FUNCTION__ " Error hashing data.");
DWORD size_data = sizeof(data);
if (!CryptGetHashParam(hash, HP_HASHVAL, data, &size_data, 0))
throw win_runtime_error(__FUNCTION__ " Error hashing data.");
}
eap::nt_password_hash::nt_password_hash(_In_ const sanitizing_blob_f<16> &other) :
sanitizing_blob_xf<16>(other)
{
}
#ifdef _DEBUG
eap::nt_password_hash::nt_password_hash(_Inout_ sanitizing_blob_zf<16> &&other) :
sanitizing_blob_xf<16>(std::move(other))
{
}
#endif
//////////////////////////////////////////////////////////////////////
// eap::nt_response
//////////////////////////////////////////////////////////////////////
eap::nt_response::nt_response()
{
}
eap::nt_response::nt_response(
_In_ HCRYPTPROV cp,
_In_ const challenge_mschapv2 &challenge_server,
_In_ const challenge_mschapv2 &challenge_client,
_In_z_ const char *username,
_In_z_ const wchar_t *password)
{
challenge_hash challenge(cp, challenge_server, challenge_client, username);
nt_password_hash hash_pwd(cp, password);
// Prepare exported key BLOB.
crypt_key key;
DWORD size_data_enc;
static const DWORD mode_ecb = CRYPT_MODE_ECB;
// DesEncrypt(Challenge, 1st 7-octets of ZPasswordHash, giving 1st 8-octets of Response)
key = create_des_key(cp, (const unsigned char*)&hash_pwd, 7);
if (!CryptSetKeyParam(key, KP_MODE, (const BYTE*)&mode_ecb, 0))
throw win_runtime_error(__FUNCTION__ " Error setting ECB mode.");
memcpy(data, &challenge, 8);
size_data_enc = 8;
if (!CryptEncrypt(key, NULL, FALSE, 0, data, &size_data_enc, 8))
throw win_runtime_error(__FUNCTION__ " Error encrypting message 1/3.");
// DesEncrypt(Challenge, 2nd 7-octets of ZPasswordHash, giving 2nd 8-octets of Response)
key = create_des_key(cp, (const unsigned char*)&hash_pwd + 7, 7);
if (!CryptSetKeyParam(key, KP_MODE, (const BYTE*)&mode_ecb, 0))
throw win_runtime_error(__FUNCTION__ " Error setting ECB mode.");
memcpy(data + 8, &challenge, 8);
size_data_enc = 8;
if (!CryptEncrypt(key, NULL, FALSE, 0, data + 8, &size_data_enc, 8))
throw win_runtime_error(__FUNCTION__ " Error encrypting message 2/3.");
// DesEncrypt(Challenge, 2nd 7-octets of ZPasswordHash, giving 2nd 8-octets of Response)
key = create_des_key(cp, (const unsigned char*)&hash_pwd + 14, 2);
if (!CryptSetKeyParam(key, KP_MODE, (const BYTE*)&mode_ecb, 0))
throw win_runtime_error(__FUNCTION__ " Error setting ECB mode.");
memcpy(data + 16, &challenge, 8);
size_data_enc = 8;
if (!CryptEncrypt(key, NULL, FALSE, 0, data + 16, &size_data_enc, 8))
throw win_runtime_error(__FUNCTION__ " Error encrypting message 3/3.");
}
eap::nt_response::nt_response(_In_ const sanitizing_blob_f<24> &other) :
sanitizing_blob_xf<24>(other)
{
}
#ifdef _DEBUG
eap::nt_response::nt_response(_Inout_ sanitizing_blob_zf<24> &&other) :
sanitizing_blob_xf<24>(std::move(other))
{
}
#endif
//////////////////////////////////////////////////////////////////////
// eap::authenticator_response
//////////////////////////////////////////////////////////////////////
eap::authenticator_response::authenticator_response()
{
}
eap::authenticator_response::authenticator_response(
_In_ HCRYPTPROV cp,
_In_ const challenge_mschapv2 &challenge_server,
_In_ const challenge_mschapv2 &challenge_client,
_In_z_ const char *username,
_In_z_ const wchar_t *password,
_In_ const nt_response &nt_resp)
{
static const unsigned char s_magic1[39] = {
0x4d, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76,
0x65, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x6c, 0x69, 0x65,
0x6e, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67,
0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74
};
nt_password_hash hash_hash_pwd(cp, nt_password_hash(cp, password));
crypt_hash hash;
if (!hash.create(cp, CALG_SHA))
throw win_runtime_error(__FUNCTION__ " Creating SHA hash failed.");
if (!CryptHashData(hash, (const BYTE*)&hash_hash_pwd, (DWORD)sizeof(hash_hash_pwd), 0) ||
!CryptHashData(hash, (const BYTE*)&nt_resp , (DWORD)sizeof(nt_resp ), 0) ||
!CryptHashData(hash, s_magic1 , (DWORD)sizeof(s_magic1 ), 0))
throw win_runtime_error(__FUNCTION__ " Error hashing data.");
unsigned char hash_val[20];
DWORD size_hash_val = sizeof(hash_val);
if (!CryptGetHashParam(hash, HP_HASHVAL, hash_val, &size_hash_val, 0))
throw win_runtime_error(__FUNCTION__ " Error hashing data.");
static const unsigned char s_magic2[41] = {
0x50, 0x61, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6d, 0x61, 0x6b,
0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6f, 0x20, 0x6d, 0x6f,
0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x6f, 0x6e,
0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f,
0x6e
};
challenge_hash challenge(cp, challenge_server, challenge_client, username);
if (!hash.create(cp, CALG_SHA))
throw win_runtime_error(__FUNCTION__ " Creating SHA hash failed.");
if (!CryptHashData(hash, hash_val , size_hash_val , 0) ||
!CryptHashData(hash, (const BYTE*)&challenge, (DWORD)sizeof(challenge), 0) ||
!CryptHashData(hash, s_magic2 , (DWORD)sizeof(s_magic2 ), 0))
throw win_runtime_error(__FUNCTION__ " Error hashing data.");
size_hash_val = sizeof(data);
if (!CryptGetHashParam(hash, HP_HASHVAL, data, &size_hash_val, 0))
throw win_runtime_error(__FUNCTION__ " Error hashing data.");
}
eap::authenticator_response::authenticator_response(_In_ const sanitizing_blob_f<20> &other) :
sanitizing_blob_xf<20>(other)
{
}
#ifdef _DEBUG
eap::authenticator_response::authenticator_response(_Inout_ sanitizing_blob_zf<20> &&other) :
sanitizing_blob_xf<20>(std::move(other))
{
}
#endif

279
lib/MSCHAPv2/src/Method.cpp Normal file
View File

@@ -0,0 +1,279 @@
/*
Copyright 2015-2016 Amebis
Copyright 2016 G<>ANT
This file is part of G<>ANTLink.
G<>ANTLink is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
G<>ANTLink is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with G<>ANTLink. If not, see <http://www.gnu.org/licenses/>.
*/
#include "StdAfx.h"
using namespace std;
using namespace winstd;
//////////////////////////////////////////////////////////////////////
// eap::method_mschapv2
//////////////////////////////////////////////////////////////////////
eap::method_mschapv2::method_mschapv2(_In_ module &module, _In_ config_method_mschapv2 &cfg, _In_ credentials_mschapv2 &cred) :
m_cred(cred),
m_ident(0),
m_success(false),
m_phase(phase_unknown),
m_phase_prev(phase_unknown),
method_noneap(module, cfg, cred)
{
}
eap::method_mschapv2::method_mschapv2(_Inout_ method_mschapv2 &&other) :
m_cred ( other.m_cred ),
m_cp (std::move(other.m_cp )),
m_challenge_server(std::move(other.m_challenge_server)),
m_challenge_client(std::move(other.m_challenge_client)),
m_ident (std::move(other.m_ident )),
m_nt_resp (std::move(other.m_nt_resp )),
m_success (std::move(other.m_success )),
m_phase (std::move(other.m_phase )),
m_phase_prev (std::move(other.m_phase_prev )),
method_noneap (std::move(other ))
{
}
eap::method_mschapv2& eap::method_mschapv2::operator=(_Inout_ method_mschapv2 &&other)
{
if (this != std::addressof(other)) {
assert(std::addressof(m_cred) == std::addressof(other.m_cred)); // Move method with same credentials only!
(method_noneap&)*this = std::move(other );
m_cp = std::move(other.m_cp );
m_challenge_server = std::move(other.m_challenge_server);
m_challenge_client = std::move(other.m_challenge_client);
m_ident = std::move(other.m_ident );
m_nt_resp = std::move(other.m_nt_resp );
m_success = std::move(other.m_success );
m_phase = std::move(other.m_phase );
m_phase_prev = std::move(other.m_phase_prev );
}
return *this;
}
void eap::method_mschapv2::begin_session(
_In_ DWORD dwFlags,
_In_ const EapAttributes *pAttributeArray,
_In_ HANDLE hTokenImpersonateUser,
_In_opt_ DWORD dwMaxSendPacketSize)
{
method_noneap::begin_session(dwFlags, pAttributeArray, hTokenImpersonateUser, dwMaxSendPacketSize);
// Create cryptographics provider for support needs (client challenge ...).
if (!m_cp.create(NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
throw win_runtime_error(__FUNCTION__ " Error creating cryptographics provider.");
m_module.log_event(&EAPMETHOD_METHOD_HANDSHAKE_START2, event_data((unsigned int)eap_type_legacy_mschapv2), event_data::blank);
m_phase = phase_init;
}
void eap::method_mschapv2::process_request_packet(
_In_bytecount_(dwReceivedPacketSize) const void *pReceivedPacket,
_In_ DWORD dwReceivedPacketSize,
_Inout_ EapPeerMethodOutput *pEapOutput)
{
assert(pReceivedPacket || dwReceivedPacketSize == 0);
assert(pEapOutput);
m_module.log_event(&EAPMETHOD_PACKET_RECV, event_data((unsigned int)eap_type_legacy_mschapv2), event_data((unsigned int)dwReceivedPacketSize), event_data::blank);
process_packet(pReceivedPacket, dwReceivedPacketSize);
m_phase_prev = m_phase;
switch (m_phase) {
case phase_init: {
// Convert username to UTF-8.
sanitizing_string identity_utf8;
WideCharToMultiByte(CP_UTF8, 0, m_cred.m_identity.c_str(), (int)m_cred.m_identity.length(), identity_utf8, NULL, NULL);
// Calculate Peer-Challenge and Response
m_challenge_client.randomize(m_cp);
m_nt_resp = nt_response(m_cp, m_challenge_server, m_challenge_client, identity_utf8.c_str(), m_cred.m_password.c_str());
// Prepare MS-CHAP2-Response
sanitizing_blob response;
response.reserve(
1 + // Ident
1 + // Flags
sizeof(challenge_mschapv2) + // Peer-Challenge
8 + // Reserved
sizeof(nt_response)); // Response
response.push_back(m_ident);
response.push_back(0); // Flags
response.insert(response.end(), (unsigned char*)&m_challenge_client, (unsigned char*)(&m_challenge_client + 1)); // Peer-Challenge
response.insert(response.end(), 8, 0); // Reserved
response.insert(response.end(), (unsigned char*)&m_nt_resp, (unsigned char*)(&m_nt_resp + 1)); // NT-Response
// Diameter AVP (User-Name=1, MS-CHAP-Challenge=11/311, MS-CHAP2-Response=25/311)
append_avp( 1, diameter_avp_flag_mandatory, identity_utf8.data(), (unsigned int )identity_utf8.size() );
append_avp(11, 311, diameter_avp_flag_mandatory, (unsigned char*)&m_challenge_server , (unsigned char)sizeof(m_challenge_server));
append_avp(25, 311, diameter_avp_flag_mandatory, response.data() , (unsigned char)response.size() );
m_phase = phase_challenge_server;
break;
}
case phase_challenge_server: {
// We do not need to do anything.
break;
}
case phase_finished:
break;
}
pEapOutput->fAllowNotifications = TRUE;
pEapOutput->action = EapPeerMethodResponseActionSend;
}
void eap::method_mschapv2::get_result(
_In_ EapPeerMethodResultReason reason,
_Inout_ EapPeerMethodResult *ppResult)
{
assert(ppResult);
switch (reason) {
case EapPeerMethodResultSuccess: {
m_module.log_event(&EAPMETHOD_METHOD_SUCCESS, event_data((unsigned int)eap_type_legacy_mschapv2), event_data::blank);
m_cfg.m_auth_failed = false;
ppResult->fIsSuccess = TRUE;
ppResult->dwFailureReasonCode = ERROR_SUCCESS;
break;
}
case EapPeerMethodResultFailure:
m_module.log_event(
m_phase_prev < phase_finished ? &EAPMETHOD_METHOD_FAILURE_INIT : &EAPMETHOD_METHOD_FAILURE,
event_data((unsigned int)eap_type_legacy_mschapv2), event_data::blank);
// Mark credentials as failed, so GUI can re-prompt user.
// But be careful: do so only after credentials were actually tried.
m_cfg.m_auth_failed = m_phase_prev < phase_finished && m_phase >= phase_finished;
// Do not report failure to EapHost, as it will not save updated configuration then. But we need it to save it, to alert user on next connection attempt.
// EapHost is well aware of the failed condition.
//ppResult->fIsSuccess = FALSE;
//ppResult->dwFailureReasonCode = EAP_E_AUTHENTICATION_FAILED;
break;
default:
throw win_runtime_error(ERROR_NOT_SUPPORTED, __FUNCTION__ " Not supported.");
}
// Always ask EAP host to save the connection data.
ppResult->fSaveConnectionData = TRUE;
}
void eap::method_mschapv2::process_packet(_In_bytecount_(size_pck) const void *_pck, _In_ size_t size_pck)
{
sanitizing_blob data;
wstring msg_w;
for (const unsigned char *pck = (const unsigned char*)_pck, *pck_end = pck + size_pck; pck < pck_end; ) {
if (pck + sizeof(diameter_avp_header) > pck_end)
throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, __FUNCTION__ " Incomplete message header.");
const diameter_avp_header *hdr = (const diameter_avp_header*)pck;
unsigned int code = ntohl(*(unsigned int*)hdr->code);
unsigned int vendor;
const unsigned char *msg;
if (hdr->flags & diameter_avp_flag_vendor) {
if (pck + sizeof(diameter_avp_header_ven) > pck_end)
throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, __FUNCTION__ " Incomplete message header.");
const diameter_avp_header_ven *hdr_ven = (const diameter_avp_header_ven*)pck;
vendor = ntohl(*(unsigned int*)hdr_ven->vendor);
msg = (const unsigned char*)(hdr_ven + 1);
} else {
vendor = 0;
msg = (const unsigned char*)(hdr + 1);
}
const unsigned char *msg_end = pck + ntohs(*(unsigned short*)hdr->length);
if (msg_end > pck_end)
throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, __FUNCTION__ " Incomplete message data.");
if (code == 26 && vendor == 311) {
// MS-CHAP2-Success
MultiByteToWideChar(CP_UTF8, 0, (const char*)msg, (int)(msg_end - msg), msg_w);
int argc;
unique_ptr<LPWSTR[], LocalFree_delete<LPWSTR[]> > argv(CommandLineToArgvW(msg_w.c_str(), &argc));
if (!argv) argc = 0;
process_success(argc, (const wchar_t**)argv.get());
} else if (code == 2 && vendor == 311) {
// MS-CHAP2-Error
MultiByteToWideChar(CP_UTF8, 0, (const char*)msg, (int)(msg_end - msg), msg_w);
int argc;
unique_ptr<LPWSTR[], LocalFree_delete<LPWSTR[]> > argv(CommandLineToArgvW(msg_w.c_str(), &argc));
if (!argv) argc = 0;
process_error(argc, (const wchar_t**)argv.get());
} else if (hdr->flags & diameter_avp_flag_mandatory)
throw win_runtime_error(ERROR_NOT_SUPPORTED, string_printf(__FUNCTION__ " Server sent mandatory Diameter AVP we do not support (code: %u, vendor: %u).", code, vendor).c_str());
pck = msg_end;
}
}
void eap::method_mschapv2::process_success(_In_ int argc, _In_count_(argc) const wchar_t *argv[])
{
m_success = false;
for (int i = 0; i < argc; i++) {
if ((argv[i][0] == L'S' || argv[i][0] == L's') && argv[i][1] == L'=') {
// "S="
hex_dec dec;
sanitizing_blob resp;
bool is_last;
dec.decode(resp, is_last, argv[i] + 2, (size_t)-1);
// Calculate expected authenticator response.
sanitizing_string identity_utf8;
WideCharToMultiByte(CP_UTF8, 0, m_cred.m_identity.c_str(), (int)m_cred.m_identity.length(), identity_utf8, NULL, NULL);
authenticator_response resp_exp(m_cp, m_challenge_server, m_challenge_client, identity_utf8.c_str(), m_cred.m_password.c_str(), m_nt_resp);
// Compare against provided authemticator response.
if (resp.size() != sizeof(resp_exp) || memcpy(resp.data(), &resp_exp, sizeof(resp_exp)) != 0)
throw invalid_argument(__FUNCTION__ " MS-CHAP2-Success authentication response string failed.");
m_success = true;
}
}
if (!m_success)
throw invalid_argument(__FUNCTION__ " MS-CHAP2-Success authentication response string not found.");
//m_module.log_event(&EAPMETHOD_TLS_ALERT, event_data((unsigned int)eap_type_tls), event_data((unsigned char)msg[0]), event_data((unsigned char)msg[1]), event_data::blank);
}
void eap::method_mschapv2::process_error(_In_ int argc, _In_count_(argc) const wchar_t *argv[])
{
UNREFERENCED_PARAMETER(argc);
UNREFERENCED_PARAMETER(argv);
}

60
lib/MSCHAPv2/src/PAP.cpp Normal file
View File

@@ -0,0 +1,60 @@
/*
Copyright 2015-2016 Amebis
Copyright 2016 GÉANT
This file is part of GÉANTLink.
GÉANTLink is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
GÉANTLink is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GÉANTLink. If not, see <http://www.gnu.org/licenses/>.
*/
#include "StdAfx.h"
//////////////////////////////////////////////////////////////////////
// eap::credentials_mschapv2
//////////////////////////////////////////////////////////////////////
eap::credentials_mschapv2::credentials_mschapv2(_In_ module &mod) : credentials_pass(mod)
{
}
eap::credentials_mschapv2::credentials_mschapv2(_In_ const credentials_mschapv2 &other) :
credentials_pass(other)
{
}
eap::credentials_mschapv2::credentials_mschapv2(_Inout_ credentials_mschapv2 &&other) :
credentials_pass(std::move(other))
{
}
eap::credentials_mschapv2& eap::credentials_mschapv2::operator=(_In_ const credentials_mschapv2 &other)
{
if (this != &other)
(credentials_pass&)*this = other;
return *this;
}
eap::credentials_mschapv2& eap::credentials_mschapv2::operator=(_Inout_ credentials_mschapv2 &&other)
{
if (this != &other)
(credentials_pass&&)*this = std::move(other);
return *this;
}

View File

@@ -0,0 +1,21 @@
/*
Copyright 2015-2016 Amebis
Copyright 2016 GÉANT
This file is part of GÉANTLink.
GÉANTLink is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
GÉANTLink is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GÉANTLink. If not, see <http://www.gnu.org/licenses/>.
*/
#include "StdAfx.h"

31
lib/MSCHAPv2/src/StdAfx.h Normal file
View File

@@ -0,0 +1,31 @@
/*
Copyright 2015-2016 Amebis
Copyright 2016 GÉANT
This file is part of GÉANTLink.
GÉANTLink is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
GÉANTLink is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GÉANTLink. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "../include/Config.h"
#include "../include/Credentials.h"
#include "../include/Method.h"
#include "../include/MSCHAPv2.h"
#include <WinStd/Hex.h>
#include <Windows.h>
#include <EapHostError.h> // include after Windows.h

2
lib/MSCHAPv2_UI/build/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/temp
/*.user

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>..\..\Events\build\temp\Events.$(Platform).$(Configuration).$(PlatformToolset);..\..\WinStd\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup />
</Project>

View File

@@ -0,0 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{7AF5B922-7C17-428A-97E0-09E3B41A684D}</ProjectGuid>
<RootNamespace>MSCHAPv2_UI</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\..\include\Win32.props" />
<Import Project="..\..\..\include\Debug.props" />
<Import Project="MSCHAPv2_UI.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\..\include\x64.props" />
<Import Project="..\..\..\include\Debug.props" />
<Import Project="MSCHAPv2_UI.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\..\include\Win32.props" />
<Import Project="..\..\..\include\Release.props" />
<Import Project="MSCHAPv2_UI.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\..\include\x64.props" />
<Import Project="..\..\..\include\Release.props" />
<Import Project="MSCHAPv2_UI.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
<ItemGroup>
<ClInclude Include="..\include\MSCHAPv2_UI.h" />
<ClInclude Include="..\src\StdAfx.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\MSCHAPv2_UI.cpp" />
<ClCompile Include="..\src\StdAfx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Events\build\Events.vcxproj">
<Project>{d63f24bd-92a0-4d6b-8b69-ed947e4d2b1b}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\StdAfx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\MSCHAPv2_UI.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\StdAfx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\MSCHAPv2_UI.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,68 @@
/*
Copyright 2015-2016 Amebis
Copyright 2016 GÉANT
This file is part of GÉANTLink.
GÉANTLink is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
GÉANTLink is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GÉANTLink. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../../EAPBase_UI/include/EAP_UI.h"
#include "../../MSCHAPv2/include/Config.h"
#include "../../MSCHAPv2/include/Credentials.h"
///
/// MSCHAPv2 credential configuration panel
///
typedef wxEAPCredentialsConfigPanel<eap::credentials_mschapv2, wxPasswordCredentialsPanel<eap::credentials_mschapv2, wxEAPCredentialsPassPanelBase> > wxMSCHAPv2CredentialsConfigPanel;
///
/// MSCHAPv2 configuration panel
///
class wxMSCHAPv2ConfigPanel;
///
/// MSCHAPv2 credential entry panel
///
typedef wxPasswordCredentialsPanel<eap::credentials_mschapv2, wxEAPCredentialsPassPanelBase> wxMSCHAPv2CredentialsPanel;
#pragma once
#include <wx/panel.h>
#include <wx/stattext.h>
#include <Windows.h>
class wxMSCHAPv2ConfigPanel : public wxPanel
{
public:
///
/// Constructs a configuration panel
///
wxMSCHAPv2ConfigPanel(const eap::config_provider &prov, eap::config_method_mschapv2 &cfg, wxWindow* parent);
///
/// Destructs the configuration panel
///
virtual ~wxMSCHAPv2ConfigPanel();
protected:
/// \cond internal
virtual void OnInitDialog(wxInitDialogEvent& event);
/// \endcond
protected:
wxMSCHAPv2CredentialsConfigPanel *m_credentials; ///< Credentials configuration panel
};

View File

@@ -0,0 +1,56 @@
/*
Copyright 2015-2016 Amebis
Copyright 2016 G<>ANT
This file is part of G<>ANTLink.
G<>ANTLink is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
G<>ANTLink is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with G<>ANTLink. If not, see <http://www.gnu.org/licenses/>.
*/
#include "StdAfx.h"
//////////////////////////////////////////////////////////////////////
// wxMSCHAPv2ConfigPanel
//////////////////////////////////////////////////////////////////////
wxMSCHAPv2ConfigPanel::wxMSCHAPv2ConfigPanel(const eap::config_provider &prov, eap::config_method_mschapv2 &cfg, wxWindow* parent) : wxPanel(parent)
{
wxBoxSizer* sb_content;
sb_content = new wxBoxSizer( wxVERTICAL );
m_credentials = new wxMSCHAPv2CredentialsConfigPanel(prov, cfg, this);
sb_content->Add(m_credentials, 0, wxEXPAND, 5);
this->SetSizer(sb_content);
this->Layout();
// Connect Events
this->Connect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(wxMSCHAPv2ConfigPanel::OnInitDialog));
}
wxMSCHAPv2ConfigPanel::~wxMSCHAPv2ConfigPanel()
{
// Disconnect Events
this->Disconnect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(wxMSCHAPv2ConfigPanel::OnInitDialog));
}
void wxMSCHAPv2ConfigPanel::OnInitDialog(wxInitDialogEvent& event)
{
// Forward the event to child panels.
if (m_credentials)
m_credentials->GetEventHandler()->ProcessEvent(event);
}

View File

@@ -0,0 +1,21 @@
/*
Copyright 2015-2016 Amebis
Copyright 2016 GÉANT
This file is part of GÉANTLink.
GÉANTLink is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
GÉANTLink is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GÉANTLink. If not, see <http://www.gnu.org/licenses/>.
*/
#include "StdAfx.h"

View File

@@ -0,0 +1,25 @@
/*
Copyright 2015-2016 Amebis
Copyright 2016 GÉANT
This file is part of GÉANTLink.
GÉANTLink is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
GÉANTLink is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GÉANTLink. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#define _CRT_SECURE_NO_WARNINGS // Prevent warnings from wxWidgets headers
#include "../include/MSCHAPv2_UI.h"

View File

@@ -37,63 +37,8 @@ namespace eap
namespace eap namespace eap
{ {
class method_pap : public method class method_pap : public method_noneap
{ {
public:
///
/// EAP-PAP packet (data)
///
class packet
{
public:
///
/// Constructs an empty packet
///
packet();
///
/// Copies a packet
///
/// \param[in] other Packet to copy from
///
packet(_In_ const packet &other);
///
/// Moves a packet
///
/// \param[in] other Packet to move from
///
packet(_Inout_ packet &&other);
///
/// Copies a packet
///
/// \param[in] other Packet to copy from
///
/// \returns Reference to this object
///
packet& operator=(_In_ const packet &other);
///
/// Moves a packet
///
/// \param[in] other Packet to move from
///
/// \returns Reference to this object
///
packet& operator=(_Inout_ packet &&other);
///
/// Empty the packet
///
void clear();
public:
EapCode m_code; ///< Packet code
unsigned char m_id; ///< Packet ID
sanitizing_blob m_data; ///< Packet data
};
public: public:
/// ///
/// Constructs an EAP method /// Constructs an EAP method
@@ -123,25 +68,27 @@ namespace eap
/// \name Packet processing /// \name Packet processing
/// @{ /// @{
///
/// Starts an EAP authentication session on the peer EapHost using the EAP method.
///
/// \sa [EapPeerBeginSession function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363600.aspx)
///
virtual void begin_session(
_In_ DWORD dwFlags,
_In_ const EapAttributes *pAttributeArray,
_In_ HANDLE hTokenImpersonateUser,
_In_opt_ DWORD dwMaxSendPacketSize = MAXDWORD);
/// ///
/// Processes a packet received by EapHost from a supplicant. /// Processes a packet received by EapHost from a supplicant.
/// ///
/// \sa [EapPeerProcessRequestPacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363621.aspx) /// \sa [EapPeerProcessRequestPacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363621.aspx)
/// ///
virtual void process_request_packet( virtual void process_request_packet(
_In_bytecount_(dwReceivedPacketSize) const EapPacket *pReceivedPacket, _In_bytecount_(dwReceivedPacketSize) const void *pReceivedPacket,
_In_ DWORD dwReceivedPacketSize, _In_ DWORD dwReceivedPacketSize,
_Inout_ EapPeerMethodOutput *pEapOutput); _Inout_ EapPeerMethodOutput *pEapOutput);
///
/// Obtains a response packet from the EAP method.
///
/// \sa [EapPeerGetResponsePacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363610.aspx)
///
virtual void get_response_packet(
_Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket,
_Inout_ DWORD *pdwSendPacketSize);
/// ///
/// Obtains the result of an authentication session from the EAP method. /// Obtains the result of an authentication session from the EAP method.
/// ///
@@ -154,14 +101,12 @@ namespace eap
/// @} /// @}
protected: protected:
credentials_pap &m_cred; ///< EAP-TLS user credentials credentials_pap &m_cred; ///< EAP-TLS user credentials
packet m_packet_res; ///< Response packet
enum { enum {
phase_unknown = -1, ///< Unknown phase phase_unknown = -1, ///< Unknown phase
phase_init = 0, ///< Handshake initialize phase_init = 0, ///< Handshake initialize
phase_finished, ///< Connection shut down phase_finished, ///< Connection shut down
} m_phase, m_phase_prev; ///< What phase is our communication at? } m_phase, m_phase_prev; ///< What phase is our communication at?
}; };
} }

View File

@@ -72,7 +72,7 @@ eap::config* eap::config_method_pap::clone() const
eap_type_t eap::config_method_pap::get_method_id() const eap_type_t eap::config_method_pap::get_method_id() const
{ {
return eap_type_pap; return eap_type_legacy_pap;
} }

View File

@@ -83,14 +83,14 @@ eap::credentials::source_t eap::credentials_pap::combine(
if (cred_cached) { if (cred_cached) {
// Using EAP service cached credentials. // Using EAP service cached credentials.
*this = *(credentials_pap*)cred_cached; *this = *(credentials_pap*)cred_cached;
m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_CACHED1, event_data((unsigned int)eap_type_pap), event_data(credentials_pap::get_name()), event_data::blank); m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_CACHED1, event_data((unsigned int)eap_type_legacy_pap), event_data(credentials_pap::get_name()), event_data::blank);
return source_cache; return source_cache;
} }
if (cfg.m_use_preshared) { if (cfg.m_use_preshared) {
// Using preshared credentials. // Using preshared credentials.
*this = *(credentials_pap*)cfg.m_preshared.get(); *this = *(credentials_pap*)cfg.m_preshared.get();
m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_PRESHARED1, event_data((unsigned int)eap_type_pap), event_data(credentials_pap::get_name()), event_data::blank); m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_PRESHARED1, event_data((unsigned int)eap_type_legacy_pap), event_data(credentials_pap::get_name()), event_data::blank);
return source_preshared; return source_preshared;
} }
@@ -101,7 +101,7 @@ eap::credentials::source_t eap::credentials_pap::combine(
// Using stored credentials. // Using stored credentials.
*this = std::move(cred_loaded); *this = std::move(cred_loaded);
m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_STORED1, event_data((unsigned int)eap_type_pap), event_data(credentials_pap::get_name()), event_data::blank); m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_STORED1, event_data((unsigned int)eap_type_legacy_pap), event_data(credentials_pap::get_name()), event_data::blank);
return source_storage; return source_storage;
} catch (...) { } catch (...) {
// Not actually an error. // Not actually an error.

View File

@@ -24,65 +24,6 @@ using namespace std;
using namespace winstd; using namespace winstd;
//////////////////////////////////////////////////////////////////////
// eap::method_pap::packet
//////////////////////////////////////////////////////////////////////
eap::method_pap::packet::packet() :
m_code((EapCode)0),
m_id(0)
{
}
eap::method_pap::packet::packet(_In_ const packet &other) :
m_code(other.m_code),
m_id (other.m_id ),
m_data(other.m_data)
{
}
eap::method_pap::packet::packet(_Inout_ packet &&other) :
m_code(std::move(other.m_code)),
m_id (std::move(other.m_id )),
m_data(std::move(other.m_data))
{
}
eap::method_pap::packet& eap::method_pap::packet::operator=(_In_ const packet &other)
{
if (this != std::addressof(other)) {
m_code = other.m_code;
m_id = other.m_id ;
m_data = other.m_data;
}
return *this;
}
eap::method_pap::packet& eap::method_pap::packet::operator=(_Inout_ packet &&other)
{
if (this != std::addressof(other)) {
m_code = std::move(other.m_code);
m_id = std::move(other.m_id );
m_data = std::move(other.m_data);
}
return *this;
}
void eap::method_pap::packet::clear()
{
m_code = (EapCode)0;
m_id = 0;
m_data.clear();
}
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// eap::method_pap // eap::method_pap
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
@@ -91,17 +32,16 @@ eap::method_pap::method_pap(_In_ module &module, _In_ config_method_pap &cfg, _I
m_cred(cred), m_cred(cred),
m_phase(phase_unknown), m_phase(phase_unknown),
m_phase_prev(phase_unknown), m_phase_prev(phase_unknown),
method(module, cfg, cred) method_noneap(module, cfg, cred)
{ {
} }
eap::method_pap::method_pap(_Inout_ method_pap &&other) : eap::method_pap::method_pap(_Inout_ method_pap &&other) :
m_cred ( other.m_cred ), m_cred ( other.m_cred ),
m_packet_res(std::move(other.m_packet_res)), m_phase (std::move(other.m_phase )),
m_phase (std::move(other.m_phase )), m_phase_prev (std::move(other.m_phase_prev)),
m_phase_prev(std::move(other.m_phase_prev)), method_noneap(std::move(other ))
method (std::move(other ))
{ {
} }
@@ -110,30 +50,37 @@ eap::method_pap& eap::method_pap::operator=(_Inout_ method_pap &&other)
{ {
if (this != std::addressof(other)) { if (this != std::addressof(other)) {
assert(std::addressof(m_cred) == std::addressof(other.m_cred)); // Move method with same credentials only! assert(std::addressof(m_cred) == std::addressof(other.m_cred)); // Move method with same credentials only!
(method&)*this = std::move(other ); (method_noneap&)*this = std::move(other );
m_packet_res = std::move(other.m_packet_res); m_phase = std::move(other.m_phase );
m_phase = std::move(other.m_phase ); m_phase_prev = std::move(other.m_phase_prev);
m_phase_prev = std::move(other.m_phase_prev);
} }
return *this; return *this;
} }
void eap::method_pap::begin_session(
_In_ DWORD dwFlags,
_In_ const EapAttributes *pAttributeArray,
_In_ HANDLE hTokenImpersonateUser,
_In_opt_ DWORD dwMaxSendPacketSize)
{
method_noneap::begin_session(dwFlags, pAttributeArray, hTokenImpersonateUser, dwMaxSendPacketSize);
m_module.log_event(&EAPMETHOD_METHOD_HANDSHAKE_START2, event_data((unsigned int)eap_type_legacy_pap), event_data::blank);
m_phase = phase_init;
}
void eap::method_pap::process_request_packet( void eap::method_pap::process_request_packet(
_In_bytecount_(dwReceivedPacketSize) const EapPacket *pReceivedPacket, _In_bytecount_(dwReceivedPacketSize) const void *pReceivedPacket,
_In_ DWORD dwReceivedPacketSize, _In_ DWORD dwReceivedPacketSize,
_Inout_ EapPeerMethodOutput *pEapOutput) _Inout_ EapPeerMethodOutput *pEapOutput)
{ {
assert(pReceivedPacket && dwReceivedPacketSize >= 4); assert(pReceivedPacket || dwReceivedPacketSize == 0);
assert(pEapOutput); assert(pEapOutput);
m_module.log_event(&EAPMETHOD_PACKET_RECV, event_data((unsigned int)eap_type_pap), event_data((unsigned int)dwReceivedPacketSize - 4), event_data::blank); m_module.log_event(&EAPMETHOD_PACKET_RECV, event_data((unsigned int)eap_type_legacy_pap), event_data((unsigned int)dwReceivedPacketSize), event_data::blank);
if (pReceivedPacket->Id == 0) {
m_module.log_event(&EAPMETHOD_METHOD_HANDSHAKE_START2, event_data((unsigned int)eap_type_pap), event_data::blank);
m_phase = phase_init;
}
m_phase_prev = m_phase; m_phase_prev = m_phase;
switch (m_phase) { switch (m_phase) {
@@ -147,56 +94,11 @@ void eap::method_pap::process_request_packet(
size_t padding_password_ex = (16 - password_utf8.length()) % 16; size_t padding_password_ex = (16 - password_utf8.length()) % 16;
password_utf8.append(padding_password_ex, 0); password_utf8.append(padding_password_ex, 0);
size_t m_packet_res.clear();
size_identity = identity_utf8.length(),
size_password = password_utf8.length(),
padding_identity = (4 - size_identity ) % 4,
padding_password = (4 - password_utf8.length()) % 4,
size_identity_outer,
size_password_outer;
m_packet_res.m_code = EapCodeResponse; // Diameter AVP (User-Name=1, User-Password=2)
m_packet_res.m_id = pReceivedPacket->Id; append_avp(1, diameter_avp_flag_mandatory, identity_utf8.data(), (unsigned int)identity_utf8.size());
m_packet_res.m_data.clear(); append_avp(2, diameter_avp_flag_mandatory, password_utf8.data(), (unsigned int)password_utf8.size());
m_packet_res.m_data.reserve(
(size_identity_outer =
4 + // Diameter AVP Code
4 + // Diameter AVP Flags & Length
size_identity) + // Identity
padding_identity + // Identity padding
(size_password_outer =
4 + // Diameter AVP Code
4 + // Diameter AVP Flags & Length
size_password) + // Password
padding_password); // Password padding
// Diameter AVP Code User-Name (0x00000001)
m_packet_res.m_data.push_back(0x00);
m_packet_res.m_data.push_back(0x00);
m_packet_res.m_data.push_back(0x00);
m_packet_res.m_data.push_back(0x01);
// Diameter AVP Flags & Length
unsigned int identity_hdr = htonl((diameter_avp_flag_mandatory << 24) | (unsigned int)size_identity_outer);
m_packet_res.m_data.insert(m_packet_res.m_data.end(), (unsigned char*)&identity_hdr, (unsigned char*)(&identity_hdr + 1));
// Identity
m_packet_res.m_data.insert(m_packet_res.m_data.end(), identity_utf8.begin(), identity_utf8.end());
m_packet_res.m_data.insert(m_packet_res.m_data.end(), padding_identity, 0);
// Diameter AVP Code User-Password (0x00000002)
m_packet_res.m_data.push_back(0x00);
m_packet_res.m_data.push_back(0x00);
m_packet_res.m_data.push_back(0x00);
m_packet_res.m_data.push_back(0x02);
// Diameter AVP Flags & Length
unsigned int password_hdr = htonl((diameter_avp_flag_mandatory << 24) | (unsigned int)size_password_outer);
m_packet_res.m_data.insert(m_packet_res.m_data.end(), (unsigned char*)&password_hdr, (unsigned char*)(&password_hdr + 1));
// Password
m_packet_res.m_data.insert(m_packet_res.m_data.end(), password_utf8.begin(), password_utf8.end());
m_packet_res.m_data.insert(m_packet_res.m_data.end(), padding_password, 0);
m_phase = phase_finished; m_phase = phase_finished;
break; break;
@@ -211,36 +113,6 @@ void eap::method_pap::process_request_packet(
} }
void eap::method_pap::get_response_packet(
_Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket,
_Inout_ DWORD *pdwSendPacketSize)
{
assert(pdwSendPacketSize);
assert(pSendPacket);
unsigned int
size_data = (unsigned int)m_packet_res.m_data.size(),
size_packet = size_data + 4;
unsigned short size_packet_limit = (unsigned short)std::min<unsigned int>(*pdwSendPacketSize, USHRT_MAX);
// Not fragmented.
if (size_packet <= size_packet_limit) {
// No need to fragment the packet.
m_module.log_event(&EAPMETHOD_PACKET_SEND, event_data((unsigned int)eap_type_pap), event_data((unsigned int)size_data), event_data::blank);
} else {
// But it should be fragmented.
throw com_runtime_error(TYPE_E_SIZETOOBIG, __FUNCTION__ " PAP message exceeds 64kB.");
}
pSendPacket->Code = (BYTE)m_packet_res.m_code;
pSendPacket->Id = m_packet_res.m_id;
*(unsigned short*)pSendPacket->Length = htons((unsigned short)size_packet);
memcpy(pSendPacket->Data, m_packet_res.m_data.data(), size_data);
m_packet_res.m_data.erase(m_packet_res.m_data.begin(), m_packet_res.m_data.begin() + size_data);
*pdwSendPacketSize = size_packet;
}
void eap::method_pap::get_result( void eap::method_pap::get_result(
_In_ EapPeerMethodResultReason reason, _In_ EapPeerMethodResultReason reason,
_Inout_ EapPeerMethodResult *ppResult) _Inout_ EapPeerMethodResult *ppResult)
@@ -249,10 +121,10 @@ void eap::method_pap::get_result(
switch (reason) { switch (reason) {
case EapPeerMethodResultSuccess: { case EapPeerMethodResultSuccess: {
m_module.log_event(&EAPMETHOD_METHOD_SUCCESS, event_data((unsigned int)eap_type_pap), event_data::blank); m_module.log_event(&EAPMETHOD_METHOD_SUCCESS, event_data((unsigned int)eap_type_legacy_pap), event_data::blank);
m_cfg.m_auth_failed = false; m_cfg.m_auth_failed = false;
ppResult->fIsSuccess = TRUE; ppResult->fIsSuccess = TRUE;
ppResult->dwFailureReasonCode = ERROR_SUCCESS; ppResult->dwFailureReasonCode = ERROR_SUCCESS;
break; break;
@@ -261,15 +133,15 @@ void eap::method_pap::get_result(
case EapPeerMethodResultFailure: case EapPeerMethodResultFailure:
m_module.log_event( m_module.log_event(
m_phase_prev < phase_finished ? &EAPMETHOD_METHOD_FAILURE_INIT : &EAPMETHOD_METHOD_FAILURE, m_phase_prev < phase_finished ? &EAPMETHOD_METHOD_FAILURE_INIT : &EAPMETHOD_METHOD_FAILURE,
event_data((unsigned int)eap_type_pap), event_data::blank); event_data((unsigned int)eap_type_legacy_pap), event_data::blank);
// Mark credentials as failed, so GUI can re-prompt user. // Mark credentials as failed, so GUI can re-prompt user.
// But be careful: do so only after credentials were actually tried. // But be careful: do so only after credentials were actually tried.
m_cfg.m_auth_failed = m_phase == phase_finished; m_cfg.m_auth_failed = m_phase_prev < phase_finished && m_phase >= phase_finished;
// Do not report failure to EapHost, as it will not save updated configuration then. But we need it to save it, to alert user on next connection attempt. // Do not report failure to EapHost, as it will not save updated configuration then. But we need it to save it, to alert user on next connection attempt.
// EapHost is well aware of the failed condition. // EapHost is well aware of the failed condition.
//ppResult->fIsSuccess = FALSE; //ppResult->fIsSuccess = FALSE;
//ppResult->dwFailureReasonCode = EAP_E_AUTHENTICATION_FAILED; //ppResult->dwFailureReasonCode = EAP_E_AUTHENTICATION_FAILED;
break; break;

View File

@@ -51,7 +51,7 @@ public:
/// ///
/// Constructs a configuration panel /// Constructs a configuration panel
/// ///
wxPAPConfigPanel(const eap::config_provider &prov, eap::config_method_pap &cfg, LPCTSTR pszCredTarget, wxWindow* parent); wxPAPConfigPanel(const eap::config_provider &prov, eap::config_method_pap &cfg, wxWindow* parent);
/// ///
/// Destructs the configuration panel /// Destructs the configuration panel

View File

@@ -25,12 +25,12 @@
// wxPAPConfigPanel // wxPAPConfigPanel
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
wxPAPConfigPanel::wxPAPConfigPanel(const eap::config_provider &prov, eap::config_method_pap &cfg, LPCTSTR pszCredTarget, wxWindow* parent) : wxPanel(parent) wxPAPConfigPanel::wxPAPConfigPanel(const eap::config_provider &prov, eap::config_method_pap &cfg, wxWindow* parent) : wxPanel(parent)
{ {
wxBoxSizer* sb_content; wxBoxSizer* sb_content;
sb_content = new wxBoxSizer( wxVERTICAL ); sb_content = new wxBoxSizer( wxVERTICAL );
m_credentials = new wxPAPCredentialsConfigPanel(prov, cfg, pszCredTarget, this); m_credentials = new wxPAPCredentialsConfigPanel(prov, cfg, this);
sb_content->Add(m_credentials, 0, wxEXPAND, 5); sb_content->Add(m_credentials, 0, wxEXPAND, 5);
this->SetSizer(sb_content); this->SetSizer(sb_content);

View File

@@ -47,87 +47,6 @@ namespace eap
class method_tls : public method class method_tls : public method
{ {
public: public:
#pragma warning(push)
#pragma warning(disable: 4480)
///
/// EAP-TLS request packet flags
///
/// \sa [The EAP-TLS Authentication Protocol (Chapter: 3.1 EAP-TLS Request Packet)](https://tools.ietf.org/html/rfc5216#section-3.1)
///
enum flags_req_t : unsigned char {
flags_req_length_incl = 0x80, ///< Length included
flags_req_more_frag = 0x40, ///< More fragments
flags_req_start = 0x20, ///< Start
};
///
/// EAP-TLS response packet flags
///
/// \sa [The EAP-TLS Authentication Protocol (Chapter: 3.2 EAP-TLS Response Packet)](https://tools.ietf.org/html/rfc5216#section-3.2)
///
enum flags_res_t : unsigned char {
flags_res_length_incl = 0x80, ///< Length included
flags_res_more_frag = 0x40, ///< More fragments
};
#pragma warning(pop)
///
/// EAP-TLS packet (data)
///
class packet
{
public:
///
/// Constructs an empty packet
///
packet();
///
/// Copies a packet
///
/// \param[in] other Packet to copy from
///
packet(_In_ const packet &other);
///
/// Moves a packet
///
/// \param[in] other Packet to move from
///
packet(_Inout_ packet &&other);
///
/// Copies a packet
///
/// \param[in] other Packet to copy from
///
/// \returns Reference to this object
///
packet& operator=(_In_ const packet &other);
///
/// Moves a packet
///
/// \param[in] other Packet to move from
///
/// \returns Reference to this object
///
packet& operator=(_Inout_ packet &&other);
///
/// Empty the packet
///
void clear();
public:
EapCode m_code; ///< Packet code
unsigned char m_id; ///< Packet ID
unsigned char m_flags; ///< Packet flags
std::vector<unsigned char> m_data; ///< Packet data
};
#pragma pack(push) #pragma pack(push)
#pragma pack(1) #pragma pack(1)
/// ///
@@ -179,7 +98,7 @@ namespace eap
_In_ DWORD dwFlags, _In_ DWORD dwFlags,
_In_ const EapAttributes *pAttributeArray, _In_ const EapAttributes *pAttributeArray,
_In_ HANDLE hTokenImpersonateUser, _In_ HANDLE hTokenImpersonateUser,
_In_ DWORD dwMaxSendPacketSize); _In_opt_ DWORD dwMaxSendPacketSize = MAXDWORD);
/// ///
/// Processes a packet received by EapHost from a supplicant. /// Processes a packet received by EapHost from a supplicant.
@@ -187,7 +106,7 @@ namespace eap
/// \sa [EapPeerProcessRequestPacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363621.aspx) /// \sa [EapPeerProcessRequestPacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363621.aspx)
/// ///
virtual void process_request_packet( virtual void process_request_packet(
_In_bytecount_(dwReceivedPacketSize) const EapPacket *pReceivedPacket, _In_bytecount_(dwReceivedPacketSize) const void *pReceivedPacket,
_In_ DWORD dwReceivedPacketSize, _In_ DWORD dwReceivedPacketSize,
_Inout_ EapPeerMethodOutput *pEapOutput); _Inout_ EapPeerMethodOutput *pEapOutput);
@@ -197,8 +116,8 @@ namespace eap
/// \sa [EapPeerGetResponsePacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363610.aspx) /// \sa [EapPeerGetResponsePacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363610.aspx)
/// ///
virtual void get_response_packet( virtual void get_response_packet(
_Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket, _Inout_bytecap_(*dwSendPacketSize) void *pSendPacket,
_Inout_ DWORD *pdwSendPacketSize); _Inout_ DWORD *pdwSendPacketSize);
/// ///
/// Obtains the result of an authentication session from the EAP method. /// Obtains the result of an authentication session from the EAP method.
@@ -304,6 +223,8 @@ namespace eap
/// @} /// @}
#endif
/// \name Key derivation /// \name Key derivation
/// @{ /// @{
@@ -316,6 +237,8 @@ namespace eap
/// @} /// @}
#if EAP_TLS < EAP_TLS_SCHANNEL
/// \name Server message processing /// \name Server message processing
/// @{ /// @{
@@ -333,9 +256,9 @@ namespace eap
/// \sa [The Transport Layer Security (TLS) Protocol Version 1.2 (Chapter 7.1. Change Cipher Spec Protocol)](https://tools.ietf.org/html/rfc5246#section-7.1) /// \sa [The Transport Layer Security (TLS) Protocol Version 1.2 (Chapter 7.1. Change Cipher Spec Protocol)](https://tools.ietf.org/html/rfc5246#section-7.1)
/// ///
/// \param[in] msg TLS change_cipher_spec message data /// \param[in] msg TLS change_cipher_spec message data
/// \param[in] msg_size TLS change_cipher_spec message data size /// \param[in] size_msg TLS change_cipher_spec message data size
/// ///
virtual void process_change_cipher_spec(_In_bytecount_(msg_size) const void *msg, _In_ size_t msg_size); virtual void process_change_cipher_spec(_In_bytecount_(size_msg) const void *msg, _In_ size_t size_msg);
/// ///
/// Processes a TLS alert message /// Processes a TLS alert message
@@ -343,9 +266,9 @@ namespace eap
/// \sa [The Transport Layer Security (TLS) Protocol Version 1.2 (Chapter 7.2. Alert Protocol)](https://tools.ietf.org/html/rfc5246#section-7.2) /// \sa [The Transport Layer Security (TLS) Protocol Version 1.2 (Chapter 7.2. Alert Protocol)](https://tools.ietf.org/html/rfc5246#section-7.2)
/// ///
/// \param[in] msg TLS alert message data /// \param[in] msg TLS alert message data
/// \param[in] msg_size TLS alert message data size /// \param[in] size_msg TLS alert message data size
/// ///
virtual void process_alert(_In_bytecount_(msg_size) const void *msg, _In_ size_t msg_size); virtual void process_alert(_In_bytecount_(size_msg) const void *msg, _In_ size_t size_msg);
/// ///
/// Processes a TLS handshake message /// Processes a TLS handshake message
@@ -353,9 +276,9 @@ namespace eap
/// \sa [The Transport Layer Security (TLS) Protocol Version 1.2 (Chapter 7.4. Handshake Protocol)](https://tools.ietf.org/html/rfc5246#section-7.4) /// \sa [The Transport Layer Security (TLS) Protocol Version 1.2 (Chapter 7.4. Handshake Protocol)](https://tools.ietf.org/html/rfc5246#section-7.4)
/// ///
/// \param[in] msg TLS handshake message data /// \param[in] msg TLS handshake message data
/// \param[in] msg_size TLS handshake message data size /// \param[in] size_msg TLS handshake message data size
/// ///
virtual void process_handshake(_In_bytecount_(msg_size) const void *msg, _In_ size_t msg_size); virtual void process_handshake(_In_bytecount_(size_msg) const void *msg, _In_ size_t size_msg);
#else #else
/// ///
@@ -375,9 +298,9 @@ namespace eap
/// \sa [The Transport Layer Security (TLS) Protocol Version 1.2 (Chapter 10. Application Data Protocol)](https://tools.ietf.org/html/rfc5246#section-10) /// \sa [The Transport Layer Security (TLS) Protocol Version 1.2 (Chapter 10. Application Data Protocol)](https://tools.ietf.org/html/rfc5246#section-10)
/// ///
/// \param[in] msg TLS application_data message data /// \param[in] msg TLS application_data message data
/// \param[in] msg_size TLS application_data message data size /// \param[in] size_msg TLS application_data message data size
/// ///
virtual void process_application_data(_In_bytecount_(msg_size) const void *msg, _In_ size_t msg_size); virtual void process_application_data(_In_bytecount_(size_msg) const void *msg, _In_ size_t size_msg);
/// @} /// @}
@@ -408,6 +331,15 @@ namespace eap
/// ///
void decrypt_message(_In_ tls_message_type_t type, _Inout_ sanitizing_blob &data); void decrypt_message(_In_ tls_message_type_t type, _Inout_ sanitizing_blob &data);
///
/// Returns maximum netto size of a message for a given TLS message size
///
/// \param[in] size_message Size of the final TLS message
///
/// \returns Netto size of message data
///
size_t get_max_message(_In_ size_t size_message) const;
/// @} /// @}
/// \name Pseudo-random generation /// \name Pseudo-random generation
@@ -489,8 +421,11 @@ namespace eap
credentials_tls &m_cred; ///< EAP-TLS user credentials credentials_tls &m_cred; ///< EAP-TLS user credentials
HANDLE m_user_ctx; ///< Handle to user context HANDLE m_user_ctx; ///< Handle to user context
packet m_packet_req; ///< Request packet packet_tls m_packet_req; ///< Request packet
packet m_packet_res; ///< Response packet packet_tls m_packet_res; ///< Response packet
tls_random m_key_mppe_client; ///< MS-MPPE-Recv-Key
tls_random m_key_mppe_server; ///< MS-MPPE-Send-Key
#if EAP_TLS < EAP_TLS_SCHANNEL #if EAP_TLS < EAP_TLS_SCHANNEL
winstd::crypt_prov m_cp; ///< Cryptography provider for general services winstd::crypt_prov m_cp; ///< Cryptography provider for general services
@@ -510,10 +445,8 @@ namespace eap
tls_random m_random_client; ///< Client random tls_random m_random_client; ///< Client random
tls_random m_random_server; ///< Server random tls_random m_random_server; ///< Server random
tls_random m_key_mppe_client; ///< MS-MPPE-Recv-Key
tls_random m_key_mppe_server; ///< MS-MPPE-Send-Key
sanitizing_blob m_session_id; ///< TLS session ID sanitizing_blob m_session_id; ///< TLS session ID
bool m_session_resumed; ///< Did TLS session resume?
std::list<winstd::cert_context> m_server_cert_chain; ///< Server certificate chain std::list<winstd::cert_context> m_server_cert_chain; ///< Server certificate chain

View File

@@ -91,6 +91,11 @@ namespace eap
/// \sa [The Transport Layer Security (TLS) Protocol Version 1.2 (Chapter 6.1. Connection States)](https://tools.ietf.org/html/rfc5246#section-6.1) /// \sa [The Transport Layer Security (TLS) Protocol Version 1.2 (Chapter 6.1. Connection States)](https://tools.ietf.org/html/rfc5246#section-6.1)
/// ///
class tls_conn_state; class tls_conn_state;
///
/// EAP-TLS packet
///
class packet_tls;
} }
///// /////
@@ -523,4 +528,116 @@ namespace eap
size_t m_size_mac_hash; ///< Message authenticy check algorithm result size (has to comply with `m_alg_mac`) size_t m_size_mac_hash; ///< Message authenticy check algorithm result size (has to comply with `m_alg_mac`)
hmac_padding m_padding_hmac; ///< Padding (key) for HMAC calculation hmac_padding m_padding_hmac; ///< Padding (key) for HMAC calculation
}; };
class packet_tls : public packet
{
public:
#pragma warning(push)
#pragma warning(disable: 4480)
///
/// EAP-TLS request packet flags
///
/// \sa [The EAP-TLS Authentication Protocol (Chapter: 3.1 EAP-TLS Request Packet)](https://tools.ietf.org/html/rfc5216#section-3.1)
///
enum flags_req_t : unsigned char {
flags_req_length_incl = 0x80, ///< Length included
flags_req_more_frag = 0x40, ///< More fragments
flags_req_start = 0x20, ///< Start
};
///
/// EAP-TLS response packet flags
///
/// \sa [The EAP-TLS Authentication Protocol (Chapter: 3.2 EAP-TLS Response Packet)](https://tools.ietf.org/html/rfc5216#section-3.2)
///
enum flags_res_t : unsigned char {
flags_res_length_incl = 0x80, ///< Length included
flags_res_more_frag = 0x40, ///< More fragments
};
#pragma warning(pop)
public:
///
/// Constructs an empty packet
///
packet_tls();
///
/// Copies a packet
///
/// \param[in] other Packet to copy from
///
packet_tls(_In_ const packet_tls &other);
///
/// Moves a packet
///
/// \param[in] other Packet to move from
///
packet_tls(_Inout_ packet_tls &&other);
///
/// Copies a packet
///
/// \param[in] other Packet to copy from
///
/// \returns Reference to this object
///
packet_tls& operator=(_In_ const packet_tls &other);
///
/// Moves a packet
///
/// \param[in] other Packet to move from
///
/// \returns Reference to this object
///
packet_tls& operator=(_Inout_ packet_tls &&other);
///
/// Empty the packet
///
virtual void clear();
///
/// Appends fragment
///
/// \param[in] pck EAP packet fragment
///
/// \returns
/// - \c true if this was the last fragment of a packet
/// - \c false if more fragments are to follow
///
bool append_frag(_In_ const EapPacket *pck);
///
/// Gets next fragment of the packet
///
/// \param[out ] pck Memory to write EAP packet to
/// \param[inout] size_max Available size of \p pck (in bytes)
///
/// \returns Final size of the packet (fragment)
///
unsigned short get_frag(_Out_bytecap_(size_max) EapPacket *pck, _In_ size_t size_max);
///
/// Is this packet an ACK
///
/// \param[in] id ID of originating EAP packet
///
inline bool is_ack(_In_ unsigned char id) const
{
return
m_code == EapCodeRequest &&
m_id == id &&
m_data.empty() &&
!(m_flags & (flags_req_length_incl | flags_req_more_frag | flags_req_start));
}
public:
unsigned char m_flags; ///< Packet flags
};
} }

View File

@@ -141,27 +141,26 @@ void eap::config_method_tls::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *
config_method_with_cred::save(pDoc, pConfigRoot); config_method_with_cred::save(pDoc, pConfigRoot);
const bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata");
HRESULT hr; HRESULT hr;
// <ServerSideCredential> // <ServerSideCredential>
com_obj<IXMLDOMElement> pXmlElServerSideCredential; com_obj<IXMLDOMElement> pXmlElServerSideCredential;
if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:ServerSideCredential"), bstr(L"ServerSideCredential"), bstrNamespace, &pXmlElServerSideCredential))) if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:ServerSideCredential"), bstr(L"ServerSideCredential"), namespace_eapmetadata, &pXmlElServerSideCredential)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <ServerSideCredential> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <ServerSideCredential> element.");
for (list<cert_context>::const_iterator i = m_trusted_root_ca.begin(), i_end = m_trusted_root_ca.end(); i != i_end; ++i) { for (list<cert_context>::const_iterator i = m_trusted_root_ca.begin(), i_end = m_trusted_root_ca.end(); i != i_end; ++i) {
// <CA> // <CA>
com_obj<IXMLDOMElement> pXmlElCA; com_obj<IXMLDOMElement> pXmlElCA;
if (FAILED(hr = eapxml::create_element(pDoc, bstr(L"CA"), bstrNamespace, &pXmlElCA))) if (FAILED(hr = eapxml::create_element(pDoc, bstr(L"CA"), namespace_eapmetadata, &pXmlElCA)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <CA> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <CA> element.");
// <CA>/<format> // <CA>/<format>
if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElCA, bstr(L"format"), bstrNamespace, bstr(L"PEM")))) if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElCA, bstr(L"format"), namespace_eapmetadata, bstr(L"PEM"))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <format> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <format> element.");
// <CA>/<cert-data> // <CA>/<cert-data>
const cert_context &cc = *i; const cert_context &cc = *i;
if (FAILED(hr = eapxml::put_element_base64(pDoc, pXmlElCA, bstr(L"cert-data"), bstrNamespace, cc->pbCertEncoded, cc->cbCertEncoded))) if (FAILED(hr = eapxml::put_element_base64(pDoc, pXmlElCA, bstr(L"cert-data"), namespace_eapmetadata, cc->pbCertEncoded, cc->cbCertEncoded)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <cert-data> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <cert-data> element.");
if (FAILED(hr = pXmlElServerSideCredential->appendChild(pXmlElCA, NULL))) if (FAILED(hr = pXmlElServerSideCredential->appendChild(pXmlElCA, NULL)))
@@ -170,7 +169,7 @@ void eap::config_method_tls::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *
// <ServerName> // <ServerName>
for (list<wstring>::const_iterator i = m_server_names.begin(), i_end = m_server_names.end(); i != i_end; ++i) { for (list<wstring>::const_iterator i = m_server_names.begin(), i_end = m_server_names.end(); i != i_end; ++i) {
if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElServerSideCredential, bstr(L"ServerName"), bstrNamespace, bstr(*i)))) if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElServerSideCredential, bstr(L"ServerName"), namespace_eapmetadata, bstr(*i))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <ServerName> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <ServerName> element.");
} }
} }

View File

@@ -95,26 +95,22 @@ void eap::credentials_tls::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pC
credentials::save(pDoc, pConfigRoot); credentials::save(pDoc, pConfigRoot);
const bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata");
HRESULT hr; HRESULT hr;
// <ClientCertificate> // <ClientCertificate>
com_obj<IXMLDOMElement> pXmlElClientCertificate; com_obj<IXMLDOMElement> pXmlElClientCertificate;
if (FAILED(hr = eapxml::create_element(pDoc, bstr(L"ClientCertificate"), bstrNamespace, &pXmlElClientCertificate))) if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:ClientCertificate"), bstr(L"ClientCertificate"), namespace_eapmetadata, &pXmlElClientCertificate)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <ClientCertificate> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <ClientCertificate> element.");
if (m_cert) { if (m_cert) {
// <ClientCertificate>/<format> // <ClientCertificate>/<format>
if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElClientCertificate, bstr(L"format"), bstrNamespace, bstr(L"PEM")))) if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElClientCertificate, bstr(L"format"), namespace_eapmetadata, bstr(L"PEM"))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <format> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <format> element.");
// <ClientCertificate>/<cert-data> // <ClientCertificate>/<cert-data>
if (FAILED(hr = eapxml::put_element_base64(pDoc, pXmlElClientCertificate, bstr(L"cert-data"), bstrNamespace, m_cert->pbCertEncoded, m_cert->cbCertEncoded))) if (FAILED(hr = eapxml::put_element_base64(pDoc, pXmlElClientCertificate, bstr(L"cert-data"), namespace_eapmetadata, m_cert->pbCertEncoded, m_cert->cbCertEncoded)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <cert-data> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <cert-data> element.");
} }
if (FAILED(hr = pConfigRoot->appendChild(pXmlElClientCertificate, NULL)))
throw com_runtime_error(hr, __FUNCTION__ " Error appending <ClientCertificate> element.");
} }
@@ -303,14 +299,14 @@ eap::credentials::source_t eap::credentials_tls::combine(
if (cred_cached) { if (cred_cached) {
// Using EAP service cached credentials. // Using EAP service cached credentials.
*this = *(credentials_tls*)cred_cached; *this = *(credentials_tls*)cred_cached;
m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_CACHED1, event_data((unsigned int)eap_type_tls), event_data(credentials_tls::get_name()), event_data::blank); m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_CACHED2, event_data((unsigned int)eap_type_tls), event_data(credentials_tls::get_name()), event_data(pszTargetName), event_data::blank);
return source_cache; return source_cache;
} }
if (cfg.m_use_preshared) { if (cfg.m_use_preshared) {
// Using preshared credentials. // Using preshared credentials.
*this = *(credentials_tls*)cfg.m_preshared.get(); *this = *(credentials_tls*)cfg.m_preshared.get();
m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_PRESHARED1, event_data((unsigned int)eap_type_tls), event_data(credentials_tls::get_name()), event_data::blank); m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_PRESHARED2, event_data((unsigned int)eap_type_tls), event_data(credentials_tls::get_name()), event_data(pszTargetName), event_data::blank);
return source_preshared; return source_preshared;
} }
@@ -321,7 +317,7 @@ eap::credentials::source_t eap::credentials_tls::combine(
// Using stored credentials. // Using stored credentials.
*this = std::move(cred_loaded); *this = std::move(cred_loaded);
m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_STORED1, event_data((unsigned int)eap_type_tls), event_data(credentials_tls::get_name()), event_data::blank); m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_STORED2, event_data((unsigned int)eap_type_tls), event_data(credentials_tls::get_name()), event_data(pszTargetName), event_data::blank);
return source_storage; return source_storage;
} catch (...) { } catch (...) {
// Not actually an error. // Not actually an error.

View File

@@ -56,71 +56,6 @@ static const unsigned char s_compression_suite[] = {
#endif #endif
//////////////////////////////////////////////////////////////////////
// eap::method_tls::packet
//////////////////////////////////////////////////////////////////////
eap::method_tls::packet::packet() :
m_code((EapCode)0),
m_id(0),
m_flags(0)
{
}
eap::method_tls::packet::packet(_In_ const packet &other) :
m_code (other.m_code ),
m_id (other.m_id ),
m_flags(other.m_flags),
m_data (other.m_data )
{
}
eap::method_tls::packet::packet(_Inout_ packet &&other) :
m_code (std::move(other.m_code )),
m_id (std::move(other.m_id )),
m_flags(std::move(other.m_flags)),
m_data (std::move(other.m_data ))
{
}
eap::method_tls::packet& eap::method_tls::packet::operator=(_In_ const packet &other)
{
if (this != std::addressof(other)) {
m_code = other.m_code ;
m_id = other.m_id ;
m_flags = other.m_flags;
m_data = other.m_data ;
}
return *this;
}
eap::method_tls::packet& eap::method_tls::packet::operator=(_Inout_ packet &&other)
{
if (this != std::addressof(other)) {
m_code = std::move(other.m_code );
m_id = std::move(other.m_id );
m_flags = std::move(other.m_flags);
m_data = std::move(other.m_data );
}
return *this;
}
void eap::method_tls::packet::clear()
{
m_code = (EapCode)0;
m_id = 0;
m_flags = 0;
m_data.clear();
}
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// eap::method_tls // eap::method_tls
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
@@ -130,6 +65,7 @@ eap::method_tls::method_tls(_In_ module &module, _In_ config_method_tls &cfg, _I
m_cred(cred), m_cred(cred),
m_user_ctx(NULL), m_user_ctx(NULL),
#if EAP_TLS < EAP_TLS_SCHANNEL #if EAP_TLS < EAP_TLS_SCHANNEL
m_session_resumed(false),
m_phase(phase_unknown), m_phase(phase_unknown),
m_seq_num_client(0), m_seq_num_client(0),
m_seq_num_server(0), m_seq_num_server(0),
@@ -154,6 +90,8 @@ eap::method_tls::method_tls(_Inout_ method_tls &&other) :
m_user_ctx (std::move(other.m_user_ctx )), m_user_ctx (std::move(other.m_user_ctx )),
m_packet_req (std::move(other.m_packet_req )), m_packet_req (std::move(other.m_packet_req )),
m_packet_res (std::move(other.m_packet_res )), m_packet_res (std::move(other.m_packet_res )),
m_key_mppe_client (std::move(other.m_key_mppe_client )),
m_key_mppe_server (std::move(other.m_key_mppe_server )),
#if EAP_TLS < EAP_TLS_SCHANNEL #if EAP_TLS < EAP_TLS_SCHANNEL
m_cp (std::move(other.m_cp )), m_cp (std::move(other.m_cp )),
m_cp_enc_client (std::move(other.m_cp_enc_client )), m_cp_enc_client (std::move(other.m_cp_enc_client )),
@@ -168,9 +106,8 @@ eap::method_tls::method_tls(_Inout_ method_tls &&other) :
m_master_secret (std::move(other.m_master_secret )), m_master_secret (std::move(other.m_master_secret )),
m_random_client (std::move(other.m_random_client )), m_random_client (std::move(other.m_random_client )),
m_random_server (std::move(other.m_random_server )), m_random_server (std::move(other.m_random_server )),
m_key_mppe_client (std::move(other.m_key_mppe_client )),
m_key_mppe_server (std::move(other.m_key_mppe_server )),
m_session_id (std::move(other.m_session_id )), m_session_id (std::move(other.m_session_id )),
m_session_resumed (std::move(other.m_session_resumed )),
m_server_cert_chain (std::move(other.m_server_cert_chain )), m_server_cert_chain (std::move(other.m_server_cert_chain )),
m_hash_handshake_msgs_md5 (std::move(other.m_hash_handshake_msgs_md5 )), m_hash_handshake_msgs_md5 (std::move(other.m_hash_handshake_msgs_md5 )),
m_hash_handshake_msgs_sha1 (std::move(other.m_hash_handshake_msgs_sha1 )), m_hash_handshake_msgs_sha1 (std::move(other.m_hash_handshake_msgs_sha1 )),
@@ -205,6 +142,8 @@ eap::method_tls& eap::method_tls::operator=(_Inout_ method_tls &&other)
m_user_ctx = std::move(other.m_user_ctx ); m_user_ctx = std::move(other.m_user_ctx );
m_packet_req = std::move(other.m_packet_req ); m_packet_req = std::move(other.m_packet_req );
m_packet_res = std::move(other.m_packet_res ); m_packet_res = std::move(other.m_packet_res );
m_key_mppe_client = std::move(other.m_key_mppe_client );
m_key_mppe_server = std::move(other.m_key_mppe_server );
#if EAP_TLS < EAP_TLS_SCHANNEL #if EAP_TLS < EAP_TLS_SCHANNEL
m_cp = std::move(other.m_cp ); m_cp = std::move(other.m_cp );
m_cp_enc_client = std::move(other.m_cp_enc_client ); m_cp_enc_client = std::move(other.m_cp_enc_client );
@@ -219,9 +158,8 @@ eap::method_tls& eap::method_tls::operator=(_Inout_ method_tls &&other)
m_master_secret = std::move(other.m_master_secret ); m_master_secret = std::move(other.m_master_secret );
m_random_client = std::move(other.m_random_client ); m_random_client = std::move(other.m_random_client );
m_random_server = std::move(other.m_random_server ); m_random_server = std::move(other.m_random_server );
m_key_mppe_client = std::move(other.m_key_mppe_client );
m_key_mppe_server = std::move(other.m_key_mppe_server );
m_session_id = std::move(other.m_session_id ); m_session_id = std::move(other.m_session_id );
m_session_resumed = std::move(other.m_session_resumed );
m_server_cert_chain = std::move(other.m_server_cert_chain ); m_server_cert_chain = std::move(other.m_server_cert_chain );
m_hash_handshake_msgs_md5 = std::move(other.m_hash_handshake_msgs_md5 ); m_hash_handshake_msgs_md5 = std::move(other.m_hash_handshake_msgs_md5 );
m_hash_handshake_msgs_sha1 = std::move(other.m_hash_handshake_msgs_sha1 ); m_hash_handshake_msgs_sha1 = std::move(other.m_hash_handshake_msgs_sha1 );
@@ -252,7 +190,7 @@ void eap::method_tls::begin_session(
_In_ DWORD dwFlags, _In_ DWORD dwFlags,
_In_ const EapAttributes *pAttributeArray, _In_ const EapAttributes *pAttributeArray,
_In_ HANDLE hTokenImpersonateUser, _In_ HANDLE hTokenImpersonateUser,
_In_ DWORD dwMaxSendPacketSize) _In_opt_ DWORD dwMaxSendPacketSize)
{ {
method::begin_session(dwFlags, pAttributeArray, hTokenImpersonateUser, dwMaxSendPacketSize); method::begin_session(dwFlags, pAttributeArray, hTokenImpersonateUser, dwMaxSendPacketSize);
@@ -298,7 +236,7 @@ void eap::method_tls::begin_session(
NULL, // aphMappers NULL, // aphMappers
0, // cSupportedAlgs: Use system configured default 0, // cSupportedAlgs: Use system configured default
NULL, // palgSupportedAlgs: Use system configured default NULL, // palgSupportedAlgs: Use system configured default
0, // grbitEnabledProtocols: Use default SP_PROT_TLS1_X_CLIENT | (SP_PROT_TLS1_2_CLIENT<<2), // grbitEnabledProtocols: TLS 1.x
0, // dwMinimumCipherStrength: Use system configured default 0, // dwMinimumCipherStrength: Use system configured default
0, // dwMaximumCipherStrength: Use system configured default 0, // dwMaximumCipherStrength: Use system configured default
0, // dwSessionLifespan: Use system configured default = 10hr 0, // dwSessionLifespan: Use system configured default = 10hr
@@ -323,7 +261,7 @@ void eap::method_tls::begin_session(
void eap::method_tls::process_request_packet( void eap::method_tls::process_request_packet(
_In_bytecount_(dwReceivedPacketSize) const EapPacket *pReceivedPacket, _In_bytecount_(dwReceivedPacketSize) const void *pReceivedPacket,
_In_ DWORD dwReceivedPacketSize, _In_ DWORD dwReceivedPacketSize,
_Inout_ EapPeerMethodOutput *pEapOutput) _Inout_ EapPeerMethodOutput *pEapOutput)
{ {
@@ -336,67 +274,20 @@ void eap::method_tls::process_request_packet(
//else if (pReceivedPacket->Data[0] != eap_type_tls) // Skip method check, to allow TTLS extension. //else if (pReceivedPacket->Data[0] != eap_type_tls) // Skip method check, to allow TTLS extension.
// throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, string_printf(__FUNCTION__ " Packet is not EAP-TLS (expected: %u, received: %u).", eap_type_tls, pReceivedPacket->Data[0])); // throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, string_printf(__FUNCTION__ " Packet is not EAP-TLS (expected: %u, received: %u).", eap_type_tls, pReceivedPacket->Data[0]));
// Get packet data pointer and size for more readable code later on. if (!m_packet_req.append_frag((const EapPacket*)pReceivedPacket)) {
const unsigned char *packet_data_ptr; // This was not the only/last fragment. Reply with ACK packet.
size_t packet_data_size;
if (pReceivedPacket->Data[1] & flags_req_length_incl) {
// Length field is included.
packet_data_ptr = pReceivedPacket->Data + 6;
packet_data_size = dwReceivedPacketSize - 10;
} else {
// Length field not included.
packet_data_ptr = pReceivedPacket->Data + 2;
packet_data_size = dwReceivedPacketSize - 6;
}
// Do the EAP-TLS defragmentation.
if (pReceivedPacket->Data[1] & flags_req_more_frag) {
if (m_packet_req.m_data.empty()) {
// Start a new packet.
if (pReceivedPacket->Data[1] & flags_req_length_incl) {
// Preallocate data according to the Length field.
size_t size_tot = ntohl(*(unsigned int*)(pReceivedPacket->Data + 2));
m_packet_req.m_data.reserve(size_tot);
m_module.log_event(&EAPMETHOD_PACKET_RECV_FRAG_FIRST, event_data((unsigned int)eap_type_tls), event_data((unsigned int)packet_data_size), event_data((unsigned int)size_tot), event_data::blank);
} else {
// The Length field was not included. Odd. Nevermind, no pre-allocation then.
m_module.log_event(&EAPMETHOD_PACKET_RECV_FRAG_FIRST1, event_data((unsigned int)eap_type_tls), event_data((unsigned int)packet_data_size), event_data::blank);
}
} else {
// Mid fragment received.
m_module.log_event(&EAPMETHOD_PACKET_RECV_FRAG_MID, event_data((unsigned int)eap_type_tls), event_data((unsigned int)packet_data_size), event_data((unsigned int)m_packet_req.m_data.size()), event_data::blank);
}
m_packet_req.m_data.insert(m_packet_req.m_data.end(), packet_data_ptr, packet_data_ptr + packet_data_size);
// Reply with ACK packet.
m_packet_res.m_code = EapCodeResponse; m_packet_res.m_code = EapCodeResponse;
m_packet_res.m_id = pReceivedPacket->Id; m_packet_res.m_id = ((const EapPacket*)pReceivedPacket)->Id;
m_packet_res.m_flags = 0; m_packet_res.m_flags = 0;
m_packet_res.m_data.clear(); m_packet_res.m_data.clear();
pEapOutput->fAllowNotifications = FALSE; pEapOutput->fAllowNotifications = FALSE;
pEapOutput->action = EapPeerMethodResponseActionSend; pEapOutput->action = EapPeerMethodResponseActionSend;
return; return;
} else if (!m_packet_req.m_data.empty()) {
// Last fragment received. Append data.
m_packet_req.m_data.insert(m_packet_req.m_data.end(), packet_data_ptr, packet_data_ptr + packet_data_size);
m_module.log_event(&EAPMETHOD_PACKET_RECV_FRAG_LAST, event_data((unsigned int)eap_type_tls), event_data((unsigned int)packet_data_size), event_data((unsigned int)m_packet_req.m_data.size()), event_data::blank);
} else {
// This is a complete non-fragmented packet.
m_packet_req.m_data.assign(packet_data_ptr, packet_data_ptr + packet_data_size);
m_module.log_event(&EAPMETHOD_PACKET_RECV, event_data((unsigned int)eap_type_tls), event_data((unsigned int)packet_data_size), event_data::blank);
} }
m_packet_req.m_code = (EapCode)pReceivedPacket->Code; if (m_packet_res.m_flags & packet_tls::flags_res_more_frag) {
m_packet_req.m_id = pReceivedPacket->Id;
m_packet_req.m_flags = pReceivedPacket->Data[1];
if (m_packet_res.m_flags & flags_res_more_frag) {
// We are sending a fragmented message. // We are sending a fragmented message.
if ( m_packet_req.m_code == EapCodeRequest && if (m_packet_req.is_ack(m_packet_res.m_id)) {
m_packet_req.m_id == m_packet_res.m_id &&
m_packet_req.m_data.empty() &&
!(m_packet_req.m_flags & (flags_req_length_incl | flags_req_more_frag | flags_req_start)))
{
// This is the ACK of our fragmented message packet. Send the next fragment. // This is the ACK of our fragmented message packet. Send the next fragment.
m_packet_res.m_id++; m_packet_res.m_id++;
pEapOutput->fAllowNotifications = FALSE; pEapOutput->fAllowNotifications = FALSE;
@@ -413,10 +304,13 @@ void eap::method_tls::process_request_packet(
user_impersonator impersonating(m_user_ctx); user_impersonator impersonating(m_user_ctx);
#if EAP_TLS < EAP_TLS_SCHANNEL #if EAP_TLS < EAP_TLS_SCHANNEL
if (pReceivedPacket->Code == EapCodeRequest && (m_packet_req.m_flags & flags_req_start)) { if (((const EapPacket*)pReceivedPacket)->Code == EapCodeRequest && (m_packet_req.m_flags & packet_tls::flags_req_start)) {
// This is the EAP-TLS start message: (re)initialize method. // This is the EAP-TLS start message: (re)initialize method.
m_module.log_event(&EAPMETHOD_METHOD_HANDSHAKE_START2, event_data((unsigned int)eap_type_tls), event_data::blank); m_module.log_event(&EAPMETHOD_METHOD_HANDSHAKE_START2, event_data((unsigned int)eap_type_tls), event_data::blank);
m_phase = phase_client_hello; m_phase = phase_client_hello;
m_key_mppe_client.clear();
m_key_mppe_server.clear();
} else { } else {
// Process the packet. // Process the packet.
memset(m_handshake, 0, sizeof(m_handshake)); memset(m_handshake, 0, sizeof(m_handshake));
@@ -428,9 +322,6 @@ void eap::method_tls::process_request_packet(
case phase_client_hello: { case phase_client_hello: {
m_tls_version = tls_version_1_2; m_tls_version = tls_version_1_2;
m_key_mppe_client.clear();
m_key_mppe_server.clear();
m_server_cert_chain.clear(); m_server_cert_chain.clear();
// Create handshake hashing objects. // Create handshake hashing objects.
@@ -547,8 +438,10 @@ void eap::method_tls::process_request_packet(
if (m_handshake[tls_handshake_type_finished]) { if (m_handshake[tls_handshake_type_finished]) {
// Go to application data phase. And allow piggybacking of the first data message. // Go to application data phase. And allow piggybacking of the first data message.
m_phase = phase_application_data; m_phase = phase_application_data;
m_session_resumed = true;
process_application_data(NULL, 0); process_application_data(NULL, 0);
} else { } else {
m_session_resumed = false;
m_phase = phase_change_cipher_spec; m_phase = phase_change_cipher_spec;
} }
break; break;
@@ -567,10 +460,12 @@ void eap::method_tls::process_request_packet(
m_phase = phase_client_hello; m_phase = phase_client_hello;
} }
#else #else
if (pReceivedPacket->Code == EapCodeRequest && (m_packet_req.m_flags & flags_req_start)) { if (((const EapPacket*)pReceivedPacket)->Code == EapCodeRequest && (m_packet_req.m_flags & packet_tls::flags_req_start)) {
// This is the EAP-TLS start message: (re)initialize method. // This is the EAP-TLS start message: (re)initialize method.
m_module.log_event(&EAPMETHOD_METHOD_HANDSHAKE_START2, event_data((unsigned int)eap_type_tls), event_data::blank); m_module.log_event(&EAPMETHOD_METHOD_HANDSHAKE_START2, event_data((unsigned int)eap_type_tls), event_data::blank);
m_phase = phase_handshake_init; m_phase = phase_handshake_init;
m_key_mppe_client.clear();
m_key_mppe_server.clear();
m_sc_queue.assign(m_packet_req.m_data.begin(), m_packet_req.m_data.end()); m_sc_queue.assign(m_packet_req.m_data.begin(), m_packet_req.m_data.end());
} else } else
m_sc_queue.insert(m_sc_queue.end(), m_packet_req.m_data.begin(), m_packet_req.m_data.end()); m_sc_queue.insert(m_sc_queue.end(), m_packet_req.m_data.begin(), m_packet_req.m_data.end());
@@ -597,58 +492,13 @@ void eap::method_tls::process_request_packet(
void eap::method_tls::get_response_packet( void eap::method_tls::get_response_packet(
_Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket, _Inout_bytecap_(*dwSendPacketSize) void *pSendPacket,
_Inout_ DWORD *pdwSendPacketSize) _Inout_ DWORD *pdwSendPacketSize)
{ {
assert(pdwSendPacketSize); assert(pdwSendPacketSize);
assert(pSendPacket); assert(pSendPacket);
unsigned int *pdwSendPacketSize = m_packet_res.get_frag((EapPacket*)pSendPacket, *pdwSendPacketSize);
size_data = (unsigned int)m_packet_res.m_data.size(),
size_packet = size_data + 6;
unsigned short size_packet_limit = (unsigned short)std::min<unsigned int>(*pdwSendPacketSize, USHRT_MAX);
unsigned char *data_dst;
if (!(m_packet_res.m_flags & flags_res_more_frag)) {
// Not fragmented.
if (size_packet <= size_packet_limit) {
// No need to fragment the packet.
m_packet_res.m_flags &= ~flags_res_length_incl; // No need to explicitly include the Length field either.
data_dst = pSendPacket->Data + 2;
m_module.log_event(&EAPMETHOD_PACKET_SEND, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_data), event_data::blank);
} else {
// But it should be fragmented.
m_packet_res.m_flags |= flags_res_length_incl | flags_res_more_frag;
*(unsigned int*)(pSendPacket->Data + 2) = (unsigned int)size_packet;
data_dst = pSendPacket->Data + 6;
size_data = size_packet_limit - 10;
size_packet = size_packet_limit;
m_module.log_event(&EAPMETHOD_PACKET_SEND_FRAG_FIRST, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_data), event_data((unsigned int)(m_packet_res.m_data.size() - size_data)), event_data::blank);
}
} else {
// Continuing the fragmented packet...
if (size_packet > size_packet_limit) {
// This is a mid fragment.
m_packet_res.m_flags &= ~flags_res_length_incl;
size_data = size_packet_limit - 6;
size_packet = size_packet_limit;
m_module.log_event(&EAPMETHOD_PACKET_SEND_FRAG_MID, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_data), event_data((unsigned int)(m_packet_res.m_data.size() - size_data)), event_data::blank);
} else {
// This is the last fragment.
m_packet_res.m_flags &= ~(flags_res_length_incl | flags_res_more_frag);
m_module.log_event(&EAPMETHOD_PACKET_SEND_FRAG_LAST, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_data), event_data((unsigned int)(m_packet_res.m_data.size() - size_data)), event_data::blank);
}
data_dst = pSendPacket->Data + 2;
}
pSendPacket->Code = (BYTE)m_packet_res.m_code;
pSendPacket->Id = m_packet_res.m_id;
*(unsigned short*)pSendPacket->Length = htons((unsigned short)size_packet);
pSendPacket->Data[0] = (BYTE)eap_type_tls;
pSendPacket->Data[1] = m_packet_res.m_flags;
memcpy(data_dst, m_packet_res.m_data.data(), size_data);
m_packet_res.m_data.erase(m_packet_res.m_data.begin(), m_packet_res.m_data.begin() + size_data);
*pdwSendPacketSize = size_packet;
} }
@@ -662,7 +512,6 @@ void eap::method_tls::get_result(
case EapPeerMethodResultSuccess: { case EapPeerMethodResultSuccess: {
m_module.log_event(&EAPMETHOD_METHOD_SUCCESS, event_data((unsigned int)eap_type_tls), event_data::blank); m_module.log_event(&EAPMETHOD_METHOD_SUCCESS, event_data((unsigned int)eap_type_tls), event_data::blank);
#if EAP_TLS < EAP_TLS_SCHANNEL
// Derive MSK/EMSK for line encryption. // Derive MSK/EMSK for line encryption.
derive_msk(); derive_msk();
@@ -674,36 +523,43 @@ void eap::method_tls::get_result(
a.create_ms_mppe_key(17, (LPCBYTE)&m_key_mppe_server, sizeof(tls_random)); a.create_ms_mppe_key(17, (LPCBYTE)&m_key_mppe_server, sizeof(tls_random));
m_eap_attr.push_back(std::move(a)); m_eap_attr.push_back(std::move(a));
m_eap_attr.push_back(eap_attr::blank); m_eap_attr.push_back(eap_attr::blank);
#else
// Derive MSK/EMSK for line encryption.
SecPkgContext_EapKeyBlock key_block;
SECURITY_STATUS status = QueryContextAttributes(m_sc_ctx, SECPKG_ATTR_EAP_KEY_BLOCK, &key_block);
if (FAILED(status))
throw sec_runtime_error(status, __FUNCTION__ "Error generating MSK in Schannel.");
const unsigned char *_key_block = key_block.rgbKeys;
// Fill array with RADIUS attributes.
eap_attr a;
m_eap_attr.reserve(m_eap_attr.size() + 3);
a.create_ms_mppe_key(16, _key_block, sizeof(tls_random));
m_eap_attr.push_back(std::move(a));
_key_block += sizeof(tls_random);
a.create_ms_mppe_key(17, _key_block, sizeof(tls_random));
m_eap_attr.push_back(std::move(a));
_key_block += sizeof(tls_random);
m_eap_attr.push_back(eap_attr::blank);
#endif
// Clear credentials as failed. // Clear credentials as failed.
m_cfg.m_auth_failed = false; m_cfg.m_auth_failed = false;
ppResult->fIsSuccess = TRUE; ppResult->fIsSuccess = TRUE;
ppResult->dwFailureReasonCode = ERROR_SUCCESS; ppResult->dwFailureReasonCode = ERROR_SUCCESS;
#if EAP_TLS < EAP_TLS_SCHANNEL #if EAP_TLS < EAP_TLS_SCHANNEL
// Update configuration with session resumption data and prepare BLOB. // Update configuration with session resumption data.
m_cfg.m_session_id = m_session_id; m_cfg.m_session_id = m_session_id;
m_cfg.m_master_secret = m_master_secret; m_cfg.m_master_secret = m_master_secret;
#else
// Make a graceful Schannel shutdown...
// ...as a desparate attempt Schannel would resume session next time then?!
DWORD dwType = SCHANNEL_SHUTDOWN;
SecBuffer token = {
sizeof(dwType),
SECBUFFER_TOKEN,
&dwType };
SecBufferDesc token_desc = { SECBUFFER_VERSION, 1, &token };
SECURITY_STATUS status;
if (SUCCEEDED(status = ApplyControlToken(m_sc_ctx, &token_desc))) {
// Prepare output buffer(s).
SecBuffer buf_out[] = { { 0, SECBUFFER_TOKEN, NULL }, };
sec_buffer_desc buf_out_desc(buf_out, _countof(buf_out));
// Build an SSL close notify message.
status = m_sc_ctx.process(
m_sc_cred,
!m_sc_target_name.empty() ? m_sc_target_name.c_str() : NULL,
ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_CONFIDENTIALITY | ISC_REQ_INTEGRITY | ISC_REQ_STREAM | /*ISC_REQ_USE_SUPPLIED_CREDS |*/ ISC_REQ_EXTENDED_ERROR | ISC_REQ_ALLOCATE_MEMORY,
0,
NULL,
&buf_out_desc);
if (SUCCEEDED(status))
m_packet_res.m_data.insert(m_packet_res.m_data.end(), (const unsigned char*)buf_out[0].pvBuffer, (const unsigned char*)buf_out[0].pvBuffer + buf_out[0].cbBuffer);
}
#endif #endif
break; break;
@@ -718,7 +574,7 @@ void eap::method_tls::get_result(
// Mark credentials as failed, so GUI can re-prompt user. // Mark credentials as failed, so GUI can re-prompt user.
// But be careful: do so only if this happened after transition from handshake to application data phase. // But be careful: do so only if this happened after transition from handshake to application data phase.
m_cfg.m_auth_failed = m_phase >= phase_application_data; m_cfg.m_auth_failed = m_phase_prev < phase_application_data && m_phase >= phase_application_data;
// Clear session resumption data. // Clear session resumption data.
m_cfg.m_session_id.clear(); m_cfg.m_session_id.clear();
@@ -732,11 +588,13 @@ void eap::method_tls::get_result(
// Mark credentials as failed, so GUI can re-prompt user. // Mark credentials as failed, so GUI can re-prompt user.
// But be careful: do so only if this happened after transition from handshake to application data phase. // But be careful: do so only if this happened after transition from handshake to application data phase.
m_cfg.m_auth_failed = m_phase_prev < phase_application_data && m_phase >= phase_application_data; m_cfg.m_auth_failed = m_phase_prev < phase_application_data && m_phase >= phase_application_data;
// TODO: Research how a Schannel session context can be cleared not to resume.
#endif #endif
// Do not report failure to EapHost, as it will not save updated configuration then. But we need it to save it, to alert user on next connection attempt. // Do not report failure to EapHost, as it will not save updated configuration then. But we need it to save it, to alert user on next connection attempt.
// EapHost is well aware of the failed condition. // EapHost is well aware of the failed condition.
//ppResult->fIsSuccess = FALSE; //ppResult->fIsSuccess = FALSE;
//ppResult->dwFailureReasonCode = EAP_E_AUTHENTICATION_FAILED; //ppResult->dwFailureReasonCode = EAP_E_AUTHENTICATION_FAILED;
break; break;
@@ -942,15 +800,27 @@ eap::sanitizing_blob eap::method_tls::make_message(_In_ tls_message_type_t type,
return msg; return msg;
} }
#endif
void eap::method_tls::derive_msk() void eap::method_tls::derive_msk()
{ {
const unsigned char *_key_block;
#if EAP_TLS < EAP_TLS_SCHANNEL
static const unsigned char s_label[] = "client EAP encryption"; static const unsigned char s_label[] = "client EAP encryption";
sanitizing_blob seed(s_label, s_label + _countof(s_label) - 1); sanitizing_blob seed(s_label, s_label + _countof(s_label) - 1);
seed.insert(seed.end(), (const unsigned char*)&m_random_client, (const unsigned char*)(&m_random_client + 1)); seed.insert(seed.end(), (const unsigned char*)&m_random_client, (const unsigned char*)(&m_random_client + 1));
seed.insert(seed.end(), (const unsigned char*)&m_random_server, (const unsigned char*)(&m_random_server + 1)); seed.insert(seed.end(), (const unsigned char*)&m_random_server, (const unsigned char*)(&m_random_server + 1));
sanitizing_blob key_block(prf(m_cp, m_alg_prf, m_master_secret, seed, 2*sizeof(tls_random))); sanitizing_blob key_block(prf(m_cp, m_alg_prf, m_master_secret, seed, 2*sizeof(tls_random)));
const unsigned char *_key_block = key_block.data(); _key_block = key_block.data();
#else
// Derive MSK/EMSK for line encryption.
SecPkgContext_EapKeyBlock key_block;
SECURITY_STATUS status = QueryContextAttributes(m_sc_ctx, SECPKG_ATTR_EAP_KEY_BLOCK, &key_block);
if (FAILED(status))
throw sec_runtime_error(status, __FUNCTION__ " Error generating MSK in Schannel.");
_key_block = key_block.rgbKeys;
#endif
// MS-MPPE-Recv-Key // MS-MPPE-Recv-Key
memcpy(&m_key_mppe_client, _key_block, sizeof(tls_random)); memcpy(&m_key_mppe_client, _key_block, sizeof(tls_random));
@@ -961,6 +831,7 @@ void eap::method_tls::derive_msk()
_key_block += sizeof(tls_random); _key_block += sizeof(tls_random);
} }
#if EAP_TLS < EAP_TLS_SCHANNEL
void eap::method_tls::process_packet(_In_bytecount_(size_pck) const void *_pck, _In_ size_t size_pck) void eap::method_tls::process_packet(_In_bytecount_(size_pck) const void *_pck, _In_ size_t size_pck)
{ {
@@ -1023,9 +894,9 @@ void eap::method_tls::process_packet(_In_bytecount_(size_pck) const void *_pck,
} }
void eap::method_tls::process_change_cipher_spec(_In_bytecount_(msg_size) const void *_msg, _In_ size_t msg_size) void eap::method_tls::process_change_cipher_spec(_In_bytecount_(size_msg) const void *_msg, _In_ size_t size_msg)
{ {
if (msg_size < 1) if (size_msg < 1)
throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, __FUNCTION__ " Incomplete change cipher spec."); throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, __FUNCTION__ " Incomplete change cipher spec.");
const unsigned char *msg = (const unsigned char*)_msg; const unsigned char *msg = (const unsigned char*)_msg;
@@ -1081,9 +952,9 @@ void eap::method_tls::process_change_cipher_spec(_In_bytecount_(msg_size) const
} }
void eap::method_tls::process_alert(_In_bytecount_(msg_size) const void *_msg, _In_ size_t msg_size) void eap::method_tls::process_alert(_In_bytecount_(size_msg) const void *_msg, _In_ size_t size_msg)
{ {
if (msg_size < 2) if (size_msg < 2)
throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, __FUNCTION__ " Incomplete alert."); throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, __FUNCTION__ " Incomplete alert.");
const unsigned char *msg = (const unsigned char*)_msg; const unsigned char *msg = (const unsigned char*)_msg;
@@ -1097,9 +968,9 @@ void eap::method_tls::process_alert(_In_bytecount_(msg_size) const void *_msg, _
} }
void eap::method_tls::process_handshake(_In_bytecount_(msg_size) const void *_msg, _In_ size_t msg_size) void eap::method_tls::process_handshake(_In_bytecount_(size_msg) const void *_msg, _In_ size_t size_msg)
{ {
for (const unsigned char *msg = (const unsigned char*)_msg, *msg_end = msg + msg_size; msg < msg_end; ) { for (const unsigned char *msg = (const unsigned char*)_msg, *msg_end = msg + size_msg; msg < msg_end; ) {
// Parse record header. // Parse record header.
if (msg + sizeof(unsigned int) > msg_end) if (msg + sizeof(unsigned int) > msg_end)
throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, __FUNCTION__ " Incomplete record header."); throw win_runtime_error(EAP_E_EAPHOST_METHOD_INVALID_PACKET, __FUNCTION__ " Incomplete record header.");
@@ -1286,11 +1157,7 @@ void eap::method_tls::process_handshake()
}, },
{ 0, SECBUFFER_EMPTY, NULL }, { 0, SECBUFFER_EMPTY, NULL },
}; };
SecBufferDesc buf_in_desc = { SecBufferDesc buf_in_desc = { SECBUFFER_VERSION, _countof(buf_in), buf_in };
SECBUFFER_VERSION,
_countof(buf_in),
buf_in
};
// Prepare output buffer(s). // Prepare output buffer(s).
SecBuffer buf_out[] = { SecBuffer buf_out[] = {
@@ -1308,6 +1175,12 @@ void eap::method_tls::process_handshake()
0, 0,
&buf_in_desc, &buf_in_desc,
&buf_out_desc); &buf_out_desc);
// In a desparate attempt to make Schannel remember and resume the TLS session, we send it the SCHANNEL_SESSION_TOKEN/SSL_SESSION_ENABLE_RECONNECTS
SCHANNEL_SESSION_TOKEN token_session = { SCHANNEL_SESSION, SSL_SESSION_ENABLE_RECONNECTS };
SecBuffer token[] = { { sizeof(token_session), SECBUFFER_TOKEN, &token_session } };
SecBufferDesc token_desc = { SECBUFFER_VERSION, _countof(token), token };
ApplyControlToken(m_sc_ctx, &token_desc);
} else { } else {
status = m_sc_ctx.process( status = m_sc_ctx.process(
m_sc_cred, m_sc_cred,
@@ -1747,6 +1620,29 @@ void eap::method_tls::decrypt_message(_In_ tls_message_type_t type, _Inout_ sani
} }
size_t eap::method_tls::get_max_message(_In_ size_t size_message) const
{
if (m_state_client.m_size_enc_block) {
// Padding
size_message -= size_message % m_state_client.m_size_enc_block;
size_message--;
// HMAC
size_message -= m_state_client.m_size_mac_hash;
if (m_tls_version >= tls_version_1_1) {
// IV (TLS 1.1+)
size_message -= m_state_client.m_size_enc_iv;
}
} else {
// HMAC
size_message -= m_state_client.m_size_mac_hash;
}
return size_message;
}
eap::sanitizing_blob eap::method_tls::prf( eap::sanitizing_blob eap::method_tls::prf(
_In_ HCRYPTPROV cp, _In_ HCRYPTPROV cp,
_In_ ALG_ID alg, _In_ ALG_ID alg,

View File

@@ -430,3 +430,165 @@ void eap::tls_conn_state::set_cipher(_In_ const unsigned char cipher[2])
} else } else
throw win_runtime_error(ERROR_NOT_SUPPORTED, string_printf(__FUNCTION__ " Unknown cipher (received 0x%02x%02x).", cipher[0], cipher[1])); throw win_runtime_error(ERROR_NOT_SUPPORTED, string_printf(__FUNCTION__ " Unknown cipher (received 0x%02x%02x).", cipher[0], cipher[1]));
} }
//////////////////////////////////////////////////////////////////////
// eap::packet_tls
//////////////////////////////////////////////////////////////////////
eap::packet_tls::packet_tls() :
m_flags(0),
packet()
{
}
eap::packet_tls::packet_tls(_In_ const packet_tls &other) :
m_flags(other.m_flags),
packet (other )
{
}
eap::packet_tls::packet_tls(_Inout_ packet_tls &&other) :
m_flags(std::move(other.m_flags)),
packet (std::move(other ))
{
}
eap::packet_tls& eap::packet_tls::operator=(_In_ const packet_tls &other)
{
if (this != std::addressof(other)) {
(packet&)*this = other;
m_flags = other.m_flags;
}
return *this;
}
eap::packet_tls& eap::packet_tls::operator=(_Inout_ packet_tls &&other)
{
if (this != std::addressof(other)) {
(packet&)*this = std::move(other);
m_flags = std::move(other.m_flags);
}
return *this;
}
void eap::packet_tls::clear()
{
packet::clear();
m_flags = 0;
}
bool eap::packet_tls::append_frag(_In_ const EapPacket *pck)
{
assert(pck);
// Get packet data pointer and size for more readable code later on.
const unsigned char *packet_data_ptr;
size_t size_packet_data;
if (pck->Data[1] & flags_req_length_incl) {
// Length field is included.
packet_data_ptr = pck->Data + 6;
size_packet_data = ntohs(*(unsigned short*)pck->Length) - 10;
} else {
// Length field not included.
packet_data_ptr = pck->Data + 2;
size_packet_data = ntohs(*(unsigned short*)pck->Length) - 6;
}
// Do the EAP-TLS defragmentation.
if (pck->Data[1] & flags_req_more_frag) {
if (m_data.empty()) {
// Start a new packet.
if (pck->Data[1] & flags_req_length_incl) {
// Preallocate data according to the Length field.
size_t size_tot = ntohl(*(unsigned int*)(pck->Data + 2));
m_data.reserve(size_tot);
//m_module.log_event(&EAPMETHOD_PACKET_RECV_FRAG_FIRST, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_packet_data), event_data((unsigned int)size_tot), event_data::blank);
} else {
// The Length field was not included. Odd. Nevermind, no pre-allocation then.
//m_module.log_event(&EAPMETHOD_PACKET_RECV_FRAG_FIRST1, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_packet_data), event_data::blank);
}
} else {
// Mid fragment received.
//m_module.log_event(&EAPMETHOD_PACKET_RECV_FRAG_MID, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_packet_data), event_data((unsigned int)m_data.size()), event_data::blank);
}
m_data.insert(m_data.end(), packet_data_ptr, packet_data_ptr + size_packet_data);
return false;
} else if (!m_data.empty()) {
// Last fragment received. Append data.
m_data.insert(m_data.end(), packet_data_ptr, packet_data_ptr + size_packet_data);
//m_module.log_event(&EAPMETHOD_PACKET_RECV_FRAG_LAST, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_packet_data), event_data((unsigned int)m_data.size()), event_data::blank);
} else {
// This is a complete non-fragmented packet.
m_data.assign(packet_data_ptr, packet_data_ptr + size_packet_data);
//m_module.log_event(&EAPMETHOD_PACKET_RECV, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_packet_data), event_data::blank);
}
m_code = (EapCode)pck->Code;
m_id = pck->Id;
m_flags = pck->Data[1];
return true;
}
unsigned short eap::packet_tls::get_frag(_Out_bytecap_(size_pck) EapPacket *pck, _In_ size_t size_max)
{
assert(pck);
size_t size_data = m_data.size();
assert(size_data <= UINT_MAX - 6); // Packets spanning over 4GB are not supported by EAP.
unsigned int size_packet = (unsigned int)size_data + 6;
unsigned short size_packet_limit = (unsigned short)std::min<size_t>(size_max, USHRT_MAX);
unsigned char *data_dst;
if (!(m_flags & flags_res_more_frag)) {
// Not fragmented.
if (size_packet <= size_packet_limit) {
// No need to fragment the packet.
m_flags &= ~flags_res_length_incl; // No need to explicitly include the Length field either.
data_dst = pck->Data + 2;
//m_module.log_event(&EAPMETHOD_PACKET_SEND, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_data), event_data::blank);
} else {
// But it should be fragmented.
m_flags |= flags_res_length_incl | flags_res_more_frag;
*(unsigned int*)(pck->Data + 2) = htonl(size_packet);
data_dst = pck->Data + 6;
size_data = size_packet_limit - 10;
size_packet = size_packet_limit;
//m_module.log_event(&EAPMETHOD_PACKET_SEND_FRAG_FIRST, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_data), event_data((unsigned int)(m_data.size() - size_data)), event_data::blank);
}
} else {
// Continuing the fragmented packet...
if (size_packet > size_packet_limit) {
// This is a mid fragment.
m_flags &= ~flags_res_length_incl;
size_data = size_packet_limit - 6;
size_packet = size_packet_limit;
//m_module.log_event(&EAPMETHOD_PACKET_SEND_FRAG_MID, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_data), event_data((unsigned int)(m_data.size() - size_data)), event_data::blank);
} else {
// This is the last fragment.
m_flags &= ~(flags_res_length_incl | flags_res_more_frag);
//m_module.log_event(&EAPMETHOD_PACKET_SEND_FRAG_LAST, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_data), event_data((unsigned int)(m_data.size() - size_data)), event_data::blank);
}
data_dst = pck->Data + 2;
}
pck->Code = (BYTE)m_code;
pck->Id = m_id;
*(unsigned short*)pck->Length = htons((unsigned short)size_packet);
pck->Data[0] = (BYTE)eap_type_tls;
pck->Data[1] = m_flags;
memcpy(data_dst, m_data.data(), size_data);
m_data.erase(m_data.begin(), m_data.begin() + size_data);
return (unsigned short)size_packet;
}

View File

@@ -254,14 +254,13 @@ public:
/// ///
/// Constructs a configuration panel /// Constructs a configuration panel
/// ///
/// \param[in] prov Provider configuration data /// \param[in] prov Provider configuration data
/// \param[in] cfg Configuration data /// \param[in] cfg Configuration data
/// \param[inout] cred Credentials data /// \param[inout] cred Credentials data
/// \param[in] pszCredTarget Target name of credentials in Windows Credential Manager. Can be further decorated to create final target name. /// \param[in] parent Parent window
/// \param[in] parent Parent window /// \param[in] is_config Is this panel used to pre-enter credentials? When \c true, the "Remember" checkbox is always selected and disabled.
/// \param[in] is_config Is this panel used to pre-enter credentials? When \c true, the "Remember" checkbox is always selected and disabled.
/// ///
wxTLSCredentialsPanel(const eap::config_provider &prov, const eap::config_method_with_cred &cfg, eap::credentials_tls &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config = false); wxTLSCredentialsPanel(const eap::config_provider &prov, const eap::config_method_with_cred &cfg, eap::credentials_tls &cred, wxWindow* parent, bool is_config = false);
protected: protected:
/// \cond internal /// \cond internal
@@ -315,7 +314,7 @@ public:
/// ///
/// Constructs a configuration panel /// Constructs a configuration panel
/// ///
wxTLSConfigPanel(const eap::config_provider &prov, eap::config_method_tls &cfg, LPCTSTR pszCredTarget, wxWindow* parent); wxTLSConfigPanel(const eap::config_provider &prov, eap::config_method_tls &cfg, wxWindow* parent);
/// ///
/// Destructs the configuration panel /// Destructs the configuration panel

View File

@@ -26,7 +26,7 @@ wxEAPTLSServerTrustConfigPanelBase::wxEAPTLSServerTrustConfigPanelBase( wxWindow
sb_server_trust_vert = new wxBoxSizer( wxVERTICAL ); sb_server_trust_vert = new wxBoxSizer( wxVERTICAL );
m_server_trust_label = new wxStaticText( sb_server_trust->GetStaticBox(), wxID_ANY, _("Describe the servers you trust to prevent credential interception in case of man-in-the-middle attacks."), wxDefaultPosition, wxDefaultSize, 0 ); m_server_trust_label = new wxStaticText( sb_server_trust->GetStaticBox(), wxID_ANY, _("Describe the servers you trust to prevent credential interception in case of man-in-the-middle attacks."), wxDefaultPosition, wxDefaultSize, 0 );
m_server_trust_label->Wrap( 446 ); m_server_trust_label->Wrap( 440 );
sb_server_trust_vert->Add( m_server_trust_label, 0, wxALL|wxEXPAND, 5 ); sb_server_trust_vert->Add( m_server_trust_label, 0, wxALL|wxEXPAND, 5 );
wxBoxSizer* sb_root_ca; wxBoxSizer* sb_root_ca;
@@ -129,7 +129,7 @@ wxTLSCredentialsPanelBase::wxTLSCredentialsPanelBase( wxWindow* parent, wxWindow
sb_credentials_vert = new wxBoxSizer( wxVERTICAL ); sb_credentials_vert = new wxBoxSizer( wxVERTICAL );
m_credentials_label = new wxStaticText( sb_credentials->GetStaticBox(), wxID_ANY, _("Please select your client certificate to use for authentication."), wxDefaultPosition, wxDefaultSize, 0 ); m_credentials_label = new wxStaticText( sb_credentials->GetStaticBox(), wxID_ANY, _("Please select your client certificate to use for authentication."), wxDefaultPosition, wxDefaultSize, 0 );
m_credentials_label->Wrap( 446 ); m_credentials_label->Wrap( 440 );
sb_credentials_vert->Add( m_credentials_label, 0, wxALL|wxEXPAND, 5 ); sb_credentials_vert->Add( m_credentials_label, 0, wxALL|wxEXPAND, 5 );
wxBoxSizer* sb_cert_radio; wxBoxSizer* sb_cert_radio;

View File

@@ -242,7 +242,7 @@
<property name="window_extra_style"></property> <property name="window_extra_style"></property>
<property name="window_name"></property> <property name="window_name"></property>
<property name="window_style"></property> <property name="window_style"></property>
<property name="wrap">446</property> <property name="wrap">440</property>
<event name="OnChar"></event> <event name="OnChar"></event>
<event name="OnEnterWindow"></event> <event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event> <event name="OnEraseBackground"></event>
@@ -1215,7 +1215,7 @@
<property name="window_extra_style"></property> <property name="window_extra_style"></property>
<property name="window_name"></property> <property name="window_name"></property>
<property name="window_style"></property> <property name="window_style"></property>
<property name="wrap">446</property> <property name="wrap">440</property>
<event name="OnChar"></event> <event name="OnChar"></event>
<event name="OnEnterWindow"></event> <event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event> <event name="OnEraseBackground"></event>

View File

@@ -311,8 +311,8 @@ bool wxFQDNListValidator::Parse(const wxString &val_in, size_t i_start, size_t i
// wxTLSCredentialsPanel // wxTLSCredentialsPanel
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
wxTLSCredentialsPanel::wxTLSCredentialsPanel(const eap::config_provider &prov, const eap::config_method_with_cred &cfg, eap::credentials_tls &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config) : wxTLSCredentialsPanel::wxTLSCredentialsPanel(const eap::config_provider &prov, const eap::config_method_with_cred &cfg, eap::credentials_tls &cred, wxWindow* parent, bool is_config) :
wxEAPCredentialsPanel<eap::credentials_tls, wxTLSCredentialsPanelBase>(prov, cfg, cred, pszCredTarget, parent, is_config) wxEAPCredentialsPanel<eap::credentials_tls, wxTLSCredentialsPanelBase>(prov, cfg, cred, parent, is_config)
{ {
// Load and set icon. // Load and set icon.
winstd::library lib_shell32; winstd::library lib_shell32;
@@ -568,7 +568,7 @@ bool wxTLSServerTrustPanel::AddRootCA(PCCERT_CONTEXT cert)
// wxTLSConfigPanel // wxTLSConfigPanel
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
wxTLSConfigPanel::wxTLSConfigPanel(const eap::config_provider &prov, eap::config_method_tls &cfg, LPCTSTR pszCredTarget, wxWindow* parent) : wxTLSConfigPanel::wxTLSConfigPanel(const eap::config_provider &prov, eap::config_method_tls &cfg, wxWindow* parent) :
m_prov(prov), m_prov(prov),
m_cfg(cfg), m_cfg(cfg),
wxPanel(parent) wxPanel(parent)
@@ -579,7 +579,7 @@ wxTLSConfigPanel::wxTLSConfigPanel(const eap::config_provider &prov, eap::config
m_server_trust = new wxTLSServerTrustPanel(prov, cfg, this); m_server_trust = new wxTLSServerTrustPanel(prov, cfg, this);
sb_content->Add(m_server_trust, 0, wxDOWN|wxEXPAND, 5); sb_content->Add(m_server_trust, 0, wxDOWN|wxEXPAND, 5);
m_credentials = new wxTLSCredentialsConfigPanel(prov, cfg, pszCredTarget, this); m_credentials = new wxTLSCredentialsConfigPanel(prov, cfg, this);
sb_content->Add(m_credentials, 0, wxUP|wxEXPAND, 5); sb_content->Add(m_credentials, 0, wxUP|wxEXPAND, 5);
this->SetSizer(sb_content); this->SetSizer(sb_content);

View File

@@ -83,6 +83,7 @@
<ClInclude Include="..\include\Credentials.h" /> <ClInclude Include="..\include\Credentials.h" />
<ClInclude Include="..\include\Method.h" /> <ClInclude Include="..\include\Method.h" />
<ClInclude Include="..\include\Module.h" /> <ClInclude Include="..\include\Module.h" />
<ClInclude Include="..\include\TTLS.h" />
<ClInclude Include="..\src\StdAfx.h" /> <ClInclude Include="..\src\StdAfx.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -26,6 +26,9 @@
<ClInclude Include="..\include\Module.h"> <ClInclude Include="..\include\Module.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\include\TTLS.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\src\StdAfx.cpp"> <ClCompile Include="..\src\StdAfx.cpp">

View File

@@ -30,6 +30,7 @@ namespace eap
#include "Config.h" #include "Config.h"
#include "Credentials.h" #include "Credentials.h"
#include "TTLS.h"
#include "../../TLS/include/Method.h" #include "../../TLS/include/Method.h"
#include "../../EAPBase/include/Method.h" #include "../../EAPBase/include/Method.h"
@@ -39,20 +40,6 @@ namespace eap
{ {
class method_ttls : public method_tls class method_ttls : public method_tls
{ {
public:
///
/// EAP-TTLS packet flags
///
/// \sa [Extensible Authentication Protocol Tunneled Transport Layer Security Authenticated Protocol Version 0 (EAP-TTLSv0) (Chapter: 9.1 Packet Format)](https://tools.ietf.org/html/rfc5281#section-9.1)
///
#pragma warning(suppress: 4480)
enum flags_t : unsigned char {
flags_length_incl = method_tls::flags_req_length_incl, ///< Length included
flags_more_frag = method_tls::flags_req_more_frag, ///< More fragments
flags_start = method_tls::flags_req_start, ///< Start
flags_ver_mask = 0x07, ///< Version mask
};
public: public:
/// ///
/// Constructs an EAP method /// Constructs an EAP method
@@ -91,7 +78,7 @@ namespace eap
_In_ DWORD dwFlags, _In_ DWORD dwFlags,
_In_ const EapAttributes *pAttributeArray, _In_ const EapAttributes *pAttributeArray,
_In_ HANDLE hTokenImpersonateUser, _In_ HANDLE hTokenImpersonateUser,
_In_ DWORD dwMaxSendPacketSize); _In_opt_ DWORD dwMaxSendPacketSize = MAXDWORD);
/// ///
/// Ends an EAP authentication session for the EAP method. /// Ends an EAP authentication session for the EAP method.
@@ -106,7 +93,7 @@ namespace eap
/// \sa [EapPeerProcessRequestPacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363621.aspx) /// \sa [EapPeerProcessRequestPacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363621.aspx)
/// ///
virtual void process_request_packet( virtual void process_request_packet(
_In_bytecount_(dwReceivedPacketSize) const EapPacket *pReceivedPacket, _In_bytecount_(dwReceivedPacketSize) const void *pReceivedPacket,
_In_ DWORD dwReceivedPacketSize, _In_ DWORD dwReceivedPacketSize,
_Inout_ EapPeerMethodOutput *pEapOutput); _Inout_ EapPeerMethodOutput *pEapOutput);
@@ -116,8 +103,8 @@ namespace eap
/// \sa [EapPeerGetResponsePacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363610.aspx) /// \sa [EapPeerGetResponsePacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363610.aspx)
/// ///
virtual void get_response_packet( virtual void get_response_packet(
_Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket, _Inout_bytecap_(*dwSendPacketSize) void *pSendPacket,
_Inout_ DWORD *pdwSendPacketSize); _Inout_ DWORD *pdwSendPacketSize);
/// ///
/// Obtains the result of an authentication session from the EAP method. /// Obtains the result of an authentication session from the EAP method.
@@ -131,8 +118,6 @@ namespace eap
/// @} /// @}
protected: protected:
#if EAP_TLS < EAP_TLS_SCHANNEL
/// ///
/// Generates master session key /// Generates master session key
/// ///
@@ -140,7 +125,14 @@ namespace eap
/// ///
virtual void derive_msk(); virtual void derive_msk();
#endif ///
/// Generates keying material for inner authentication
///
/// \param[in] size Number of bytes of keying material required
///
/// \returns Keing material
///
virtual sanitizing_blob derive_challenge(_In_ size_t size);
/// ///
/// Processes an application message /// Processes an application message
@@ -160,7 +152,5 @@ namespace eap
} m_version; ///< EAP-TTLS version } m_version; ///< EAP-TTLS version
std::unique_ptr<method> m_inner; ///< Inner authentication method std::unique_ptr<method> m_inner; ///< Inner authentication method
unsigned char m_inner_packet_id; ///< Inner packet ID
DWORD m_size_inner_packet_max; ///< Maximum size of inner response packet
}; };
} }

View File

@@ -211,6 +211,18 @@ namespace eap
/// @} /// @}
protected:
///
/// Checks all configured providers and tries to combine credentials.
///
const config_method_ttls* combine_credentials(
_In_ DWORD dwFlags,
_In_ const config_connection &cfg,
_In_count_(dwUserDataSize) const BYTE *pUserData,
_In_ DWORD dwUserDataSize,
_Out_ credentials_connection& cred_out,
_In_ HANDLE hTokenImpersonateUser);
protected: protected:
class session { class session {
public: public:
@@ -220,7 +232,7 @@ namespace eap
public: public:
module &m_module; ///< Module module &m_module; ///< Module
config_connection m_cfg; ///< Connection configuration config_connection m_cfg; ///< Connection configuration
credentials_ttls m_cred; ///< User credentials credentials_connection m_cred; ///< Connection credentials
std::unique_ptr<method_ttls> m_method; ///< EAP-TTLS method std::unique_ptr<method_ttls> m_method; ///< EAP-TTLS method
// The following members are required to avoid memory leakage in get_result() // The following members are required to avoid memory leakage in get_result()

52
lib/TTLS/include/TTLS.h Normal file
View File

@@ -0,0 +1,52 @@
/*
Copyright 2015-2016 Amebis
Copyright 2016 G<>ANT
This file is part of G<>ANTLink.
G<>ANTLink is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
G<>ANTLink is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with G<>ANTLink. If not, see <http://www.gnu.org/licenses/>.
*/
namespace eap
{
///
/// EAP-TTLS packet
///
class packet_ttls;
}
#pragma once
#include "../../TLS/include/TLS.h"
namespace eap
{
class packet_ttls : public packet_tls
{
public:
///
/// EAP-TTLS packet flags
///
/// \sa [Extensible Authentication Protocol Tunneled Transport Layer Security Authenticated Protocol Version 0 (EAP-TTLSv0) (Chapter: 9.1 Packet Format)](https://tools.ietf.org/html/rfc5281#section-9.1)
///
#pragma warning(suppress: 4480)
enum flags_t : unsigned char {
flags_length_incl = packet_tls::flags_req_length_incl, ///< Length included
flags_more_frag = packet_tls::flags_req_more_frag, ///< More fragments
flags_start = packet_tls::flags_req_start, ///< Start
flags_ver_mask = 0x07, ///< Version mask
};
};
}

View File

@@ -29,8 +29,11 @@ using namespace winstd;
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
eap::config_method_ttls::config_method_ttls(_In_ module &mod) : eap::config_method_ttls::config_method_ttls(_In_ module &mod) :
m_inner(new config_method_pap(mod)),
config_method_tls(mod) config_method_tls(mod)
{ {
// TTLS is using blank pre-shared credentials per default.
m_use_preshared = true;
} }
@@ -87,37 +90,56 @@ void eap::config_method_ttls::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode
config_method_tls::save(pDoc, pConfigRoot); config_method_tls::save(pDoc, pConfigRoot);
const bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata");
HRESULT hr; HRESULT hr;
// <ClientSideCredential> // <ClientSideCredential>
com_obj<IXMLDOMElement> pXmlElClientSideCredential; com_obj<IXMLDOMElement> pXmlElClientSideCredential;
if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:ClientSideCredential"), bstr(L"ClientSideCredential"), bstrNamespace, &pXmlElClientSideCredential))) if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:ClientSideCredential"), bstr(L"ClientSideCredential"), namespace_eapmetadata, &pXmlElClientSideCredential)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <ClientSideCredential> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <ClientSideCredential> element.");
// <ClientSideCredential>/<AnonymousIdentity> // <ClientSideCredential>/<AnonymousIdentity>
if (!m_anonymous_identity.empty()) if (!m_anonymous_identity.empty())
if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElClientSideCredential, bstr(L"AnonymousIdentity"), bstrNamespace, bstr(m_anonymous_identity)))) if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElClientSideCredential, bstr(L"AnonymousIdentity"), namespace_eapmetadata, bstr(m_anonymous_identity))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <AnonymousIdentity> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <AnonymousIdentity> element.");
// <InnerAuthenticationMethod> // <InnerAuthenticationMethod>
com_obj<IXMLDOMElement> pXmlElInnerAuthenticationMethod; com_obj<IXMLDOMElement> pXmlElInnerAuthenticationMethod;
if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:InnerAuthenticationMethod"), bstr(L"InnerAuthenticationMethod"), bstrNamespace, &pXmlElInnerAuthenticationMethod))) if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:InnerAuthenticationMethod"), bstr(L"InnerAuthenticationMethod"), namespace_eapmetadata, &pXmlElInnerAuthenticationMethod)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <InnerAuthenticationMethod> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <InnerAuthenticationMethod> element.");
eap_type_t eap_type = m_inner->get_method_id(); eap_type_t eap_type = m_inner->get_method_id();
if (eap_type_noneap_start <= eap_type && eap_type < eap_type_noneap_end) { if (eap_type_noneap_start <= eap_type && eap_type < eap_type_noneap_end) {
// <InnerAuthenticationMethod>/<NonEAPAuthMethod> // <InnerAuthenticationMethod>/<NonEAPAuthMethod>
if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElInnerAuthenticationMethod, bstr(L"NonEAPAuthMethod"), bstrNamespace, bstr(m_inner->get_method_str())))) if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElInnerAuthenticationMethod, bstr(L"NonEAPAuthMethod"), namespace_eapmetadata, bstr(m_inner->get_method_str()))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <NonEAPAuthMethod> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <NonEAPAuthMethod> element.");
} else { } else {
// <InnerAuthenticationMethod>/<EAPMethod> // <InnerAuthenticationMethod>/<EAPMethod>
if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElInnerAuthenticationMethod, bstr(L"EAPMethod"), bstrNamespace, (DWORD)m_inner->get_method_id()))) if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElInnerAuthenticationMethod, bstr(L"EAPMethod"), namespace_eapmetadata, (DWORD)m_inner->get_method_id())))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <EAPMethod> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <EAPMethod> element.");
} }
// <InnerAuthenticationMethod>/... // <InnerAuthenticationMethod>/...
m_inner->save(pDoc, pXmlElInnerAuthenticationMethod); m_inner->save(pDoc, pXmlElInnerAuthenticationMethod);
{
com_obj<IXMLDOMNode> pXmlElClientSideCredential;
if (SUCCEEDED(hr = eapxml::select_node(pConfigRoot, bstr(L"eap-metadata:ClientSideCredential"), &pXmlElClientSideCredential))) {
// Fix 1: Pre-shared outer credentials in draft-winter-opsawg-eap-metadata has some bizarre presence/absence/blank logic for EAP-TTLS methods only.
// To keep our code clean, we do some post-processing, to make draft compliant XML on output, while keeping things simple on the inside.
if (m_use_preshared && m_preshared->empty()) {
// For empty pre-shared client certificate <ClientCertificate/> must not be present.
com_obj<IXMLDOMNode> pXmlElClientCertificate;
if (SUCCEEDED(hr = eapxml::select_node(pXmlElClientSideCredential, bstr(L"eap-metadata:ClientCertificate"), &pXmlElClientCertificate))) {
com_obj<IXMLDOMNode> pXmlElClientCertificateOld;
hr = pXmlElClientSideCredential->removeChild(pXmlElClientCertificate, &pXmlElClientCertificateOld);
}
} else if (!m_use_preshared) {
// When not using pre-shared (user must supply one), add empty <ClientCertificate/>.
com_obj<IXMLDOMElement> pXmlElClientCertificate;
hr = eapxml::create_element(pDoc, pXmlElClientSideCredential, bstr(L"eap-metadata:ClientCertificate"), bstr(L"ClientCertificate"), namespace_eapmetadata, &pXmlElClientCertificate);
}
}
}
} }
@@ -126,6 +148,30 @@ void eap::config_method_ttls::load(_In_ IXMLDOMNode *pConfigRoot)
assert(pConfigRoot); assert(pConfigRoot);
HRESULT hr; HRESULT hr;
{
com_obj<IXMLDOMNode> pXmlElClientSideCredential;
if (SUCCEEDED(hr = eapxml::select_node(pConfigRoot, bstr(L"eap-metadata:ClientSideCredential"), &pXmlElClientSideCredential))) {
com_obj<IXMLDOMDocument> pDoc;
if (SUCCEEDED(hr = pXmlElClientSideCredential->get_ownerDocument(&pDoc))) {
// Fix 1: Pre-shared outer credentials in draft-winter-opsawg-eap-metadata has some bizarre presence/absence/blank logic for EAP-TTLS methods only.
// To keep our code clean, we do some pre-processing, to accept draft compliant XML on input, while keeping things simple on the inside.
com_obj<IXMLDOMNode> pXmlElClientCertificate;
if (SUCCEEDED(hr = eapxml::select_node(pXmlElClientSideCredential, bstr(L"eap-metadata:ClientCertificate"), &pXmlElClientCertificate))) {
VARIANT_BOOL has_children;
if (SUCCEEDED(hr = pXmlElClientCertificate->hasChildNodes(&has_children)) && !has_children) {
// Empty <ClientCertificate/> means: do not use pre-shared credentials.
com_obj<IXMLDOMNode> pXmlElClientCertificateOld;
hr = pXmlElClientSideCredential->removeChild(pXmlElClientCertificate, &pXmlElClientCertificateOld);
}
} else {
// Nonexisting <ClientSideCredential> means: use blank pre-shared credentials.
com_obj<IXMLDOMElement> pXmlElClientCertificate;
hr = eapxml::create_element(pDoc, pXmlElClientSideCredential, bstr(L"eap-metadata:ClientCertificate"), bstr(L"ClientCertificate"), namespace_eapmetadata, &pXmlElClientCertificate);
}
}
}
}
config_method_tls::load(pConfigRoot); config_method_tls::load(pConfigRoot);
std::wstring xpath(eapxml::get_xpath(pConfigRoot)); std::wstring xpath(eapxml::get_xpath(pConfigRoot));
@@ -210,31 +256,31 @@ const wchar_t* eap::config_method_ttls::get_method_str() const
eap::credentials* eap::config_method_ttls::make_credentials() const eap::credentials* eap::config_method_ttls::make_credentials() const
{ {
return new credentials_ttls(m_module); credentials_ttls *cred = new credentials_ttls(m_module);
cred->m_inner.reset(m_inner->make_credentials());
return cred;
} }
eap::config_method_with_cred* eap::config_method_ttls::make_config_method(_In_ winstd::eap_type_t eap_type) const eap::config_method_with_cred* eap::config_method_ttls::make_config_method(_In_ winstd::eap_type_t eap_type) const
{ {
switch (eap_type) { switch (eap_type) {
case eap_type_tls : return new config_method_tls (m_module); case eap_type_tls : return new config_method_tls (m_module);
case eap_type_ttls: return new config_method_ttls(m_module); case eap_type_ttls : return new config_method_ttls (m_module);
case eap_type_pap : return new config_method_pap (m_module); case eap_type_legacy_pap : return new config_method_pap (m_module);
default : throw invalid_argument(__FUNCTION__ " Unsupported inner authentication method."); case eap_type_legacy_mschapv2: return new config_method_mschapv2(m_module);
default : throw invalid_argument(__FUNCTION__ " Unsupported inner authentication method.");
} }
} }
eap::config_method_with_cred* eap::config_method_ttls::make_config_method(_In_ const wchar_t *eap_type) const eap::config_method_with_cred* eap::config_method_ttls::make_config_method(_In_ const wchar_t *eap_type) const
{ {
if (_wcsicmp(eap_type, L"EAP-TLS") == 0) if (_wcsicmp(eap_type, L"EAP-TLS" ) == 0) return new config_method_tls (m_module);
return new config_method_tls(m_module); else if (_wcsicmp(eap_type, L"EAP-TTLS") == 0) return new config_method_ttls (m_module);
else if (_wcsicmp(eap_type, L"EAP-TTLS") == 0) else if (_wcsicmp(eap_type, L"PAP" ) == 0) return new config_method_pap (m_module);
return new config_method_ttls(m_module); else if (_wcsicmp(eap_type, L"MSCHAPv2") == 0) return new config_method_mschapv2(m_module);
else if (_wcsicmp(eap_type, L"PAP") == 0) else throw invalid_argument(__FUNCTION__ " Unsupported inner authentication method.");
return new config_method_pap(m_module);
else
throw invalid_argument(__FUNCTION__ " Unsupported inner authentication method.");
} }

View File

@@ -96,18 +96,15 @@ void eap::credentials_ttls::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *p
credentials_tls::save(pDoc, pConfigRoot); credentials_tls::save(pDoc, pConfigRoot);
const bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata");
HRESULT hr; HRESULT hr;
// <InnerAuthenticationMethod> // <InnerAuthenticationMethod>
winstd::com_obj<IXMLDOMElement> pXmlElInnerAuthenticationMethod; com_obj<IXMLDOMElement> pXmlElInnerAuthenticationMethod;
if (FAILED(hr = eapxml::create_element(pDoc, winstd::bstr(L"InnerAuthenticationMethod"), bstrNamespace, &pXmlElInnerAuthenticationMethod))) if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:InnerAuthenticationMethod"), bstr(L"InnerAuthenticationMethod"), namespace_eapmetadata, &pXmlElInnerAuthenticationMethod)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <InnerAuthenticationMethod> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <InnerAuthenticationMethod> element.");
// <InnerAuthenticationMethod>/...
m_inner->save(pDoc, pXmlElInnerAuthenticationMethod); m_inner->save(pDoc, pXmlElInnerAuthenticationMethod);
if (FAILED(hr = pConfigRoot->appendChild(pXmlElInnerAuthenticationMethod, NULL)))
throw com_runtime_error(hr, __FUNCTION__ " Error appending <InnerAuthenticationMethod> element.");
} }

View File

@@ -32,21 +32,17 @@ eap::method_ttls::method_ttls(_In_ module &module, _In_ config_method_ttls &cfg,
m_cfg(cfg), m_cfg(cfg),
m_cred(cred), m_cred(cred),
m_version(version_0), m_version(version_0),
m_inner_packet_id(0),
m_size_inner_packet_max(0),
method_tls(module, cfg, cred) method_tls(module, cfg, cred)
{ {
} }
eap::method_ttls::method_ttls(_Inout_ method_ttls &&other) : eap::method_ttls::method_ttls(_Inout_ method_ttls &&other) :
m_cfg ( other.m_cfg ), m_cfg ( other.m_cfg ),
m_cred ( other.m_cred ), m_cred ( other.m_cred ),
m_version (std::move(other.m_version )), m_version (std::move(other.m_version)),
m_inner (std::move(other.m_inner )), m_inner (std::move(other.m_inner )),
m_inner_packet_id (std::move(other.m_inner_packet_id )), method_tls(std::move(other ))
m_size_inner_packet_max(std::move(other.m_size_inner_packet_max)),
method_tls (std::move(other ))
{ {
} }
@@ -54,11 +50,9 @@ eap::method_ttls::method_ttls(_Inout_ method_ttls &&other) :
eap::method_ttls& eap::method_ttls::operator=(_Inout_ method_ttls &&other) eap::method_ttls& eap::method_ttls::operator=(_Inout_ method_ttls &&other)
{ {
if (this != std::addressof(other)) { if (this != std::addressof(other)) {
(method_tls&)*this = std::move(other ); (method_tls&)*this = std::move(other );
m_version = std::move(other.m_version ); m_version = std::move(other.m_version);
m_inner = std::move(other.m_inner ); m_inner = std::move(other.m_inner );
m_inner_packet_id = std::move(other.m_inner_packet_id );
m_size_inner_packet_max = std::move(other.m_size_inner_packet_max);
} }
return *this; return *this;
@@ -69,17 +63,17 @@ void eap::method_ttls::begin_session(
_In_ DWORD dwFlags, _In_ DWORD dwFlags,
_In_ const EapAttributes *pAttributeArray, _In_ const EapAttributes *pAttributeArray,
_In_ HANDLE hTokenImpersonateUser, _In_ HANDLE hTokenImpersonateUser,
_In_ DWORD dwMaxSendPacketSize) _In_opt_ DWORD dwMaxSendPacketSize)
{ {
method_tls::begin_session(dwFlags, pAttributeArray, hTokenImpersonateUser, dwMaxSendPacketSize); method_tls::begin_session(dwFlags, pAttributeArray, hTokenImpersonateUser, dwMaxSendPacketSize);
// Initialize inner method. // Initialize inner method.
switch (m_cfg.m_inner->get_method_id()) { switch (m_cfg.m_inner->get_method_id()) {
case eap_type_pap: m_inner.reset(new method_pap(m_module, (config_method_pap&)*m_cfg.m_inner, (credentials_pap&)*m_cred.m_inner.get())); case eap_type_legacy_pap : m_inner.reset(new method_pap (m_module, (config_method_pap &)*m_cfg.m_inner, (credentials_pap &)*m_cred.m_inner.get())); break;
default: invalid_argument(__FUNCTION__ " Unsupported inner authentication method."); case eap_type_legacy_mschapv2: m_inner.reset(new method_mschapv2(m_module, (config_method_mschapv2&)*m_cfg.m_inner, (credentials_mschapv2&)*m_cred.m_inner.get())); break;
default: throw invalid_argument(__FUNCTION__ " Unsupported inner authentication method.");
} }
m_inner->begin_session(dwFlags, pAttributeArray, hTokenImpersonateUser, m_size_inner_packet_max = dwMaxSendPacketSize); // TODO: Maximum inner packet size should have subtracted TLS overhead m_inner->begin_session(dwFlags, pAttributeArray, hTokenImpersonateUser, MAXDWORD);
m_inner_packet_id = 0;
} }
@@ -91,15 +85,15 @@ void eap::method_ttls::end_session()
void eap::method_ttls::process_request_packet( void eap::method_ttls::process_request_packet(
_In_bytecount_(dwReceivedPacketSize) const EapPacket *pReceivedPacket, _In_bytecount_(dwReceivedPacketSize) const void *pReceivedPacket,
_In_ DWORD dwReceivedPacketSize, _In_ DWORD dwReceivedPacketSize,
_Inout_ EapPeerMethodOutput *pEapOutput) _Inout_ EapPeerMethodOutput *pEapOutput)
{ {
if (pReceivedPacket->Code == EapCodeRequest && (pReceivedPacket->Data[1] & flags_start)) { if (((const EapPacket*)pReceivedPacket)->Code == EapCodeRequest && (((const EapPacket*)pReceivedPacket)->Data[1] & packet_ttls::flags_start)) {
// This is a start EAP-TTLS packet. // This is a start EAP-TTLS packet.
// Determine minimum EAP-TTLS version supported by server and us. // Determine minimum EAP-TTLS version supported by server and us.
version_t ver_remote = (version_t)(pReceivedPacket->Data[1] & flags_ver_mask); version_t ver_remote = (version_t)(((const EapPacket*)pReceivedPacket)->Data[1] & packet_ttls::flags_ver_mask);
m_version = std::min<version_t>(ver_remote, version_0); m_version = std::min<version_t>(ver_remote, version_0);
m_module.log_event(&EAPMETHOD_TTLS_HANDSHAKE_START, event_data((unsigned int)eap_type_ttls), event_data((unsigned char)m_version), event_data((unsigned char)ver_remote), event_data::blank); m_module.log_event(&EAPMETHOD_TTLS_HANDSHAKE_START, event_data((unsigned int)eap_type_ttls), event_data((unsigned char)m_version), event_data((unsigned char)ver_remote), event_data::blank);
} }
@@ -110,15 +104,15 @@ void eap::method_ttls::process_request_packet(
void eap::method_ttls::get_response_packet( void eap::method_ttls::get_response_packet(
_Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket, _Inout_bytecap_(*dwSendPacketSize) void *pSendPacket,
_Inout_ DWORD *pdwSendPacketSize) _Inout_ DWORD *pdwSendPacketSize)
{ {
method_tls::get_response_packet(pSendPacket, pdwSendPacketSize); method_tls::get_response_packet(pSendPacket, pdwSendPacketSize);
// Change packet type to EAP-TTLS, and add EAP-TTLS version. // Change packet type to EAP-TTLS, and add EAP-TTLS version.
pSendPacket->Data[0] = (BYTE)eap_type_ttls; ((EapPacket*)pSendPacket)->Data[0] = (BYTE)eap_type_ttls;
pSendPacket->Data[1] &= ~flags_ver_mask; ((EapPacket*)pSendPacket)->Data[1] &= ~packet_ttls::flags_ver_mask;
pSendPacket->Data[1] |= m_version; ((EapPacket*)pSendPacket)->Data[1] |= m_version;
} }
@@ -126,41 +120,24 @@ void eap::method_ttls::get_result(
_In_ EapPeerMethodResultReason reason, _In_ EapPeerMethodResultReason reason,
_Inout_ EapPeerMethodResult *ppResult) _Inout_ EapPeerMethodResult *ppResult)
{ {
if (m_phase != phase_application_data) { // Do the TLS.
// Do the TLS. method_tls::get_result(reason, ppResult);
method_tls::get_result(reason, ppResult);
} else { if (m_phase == phase_application_data) {
// Get inner method result. // Get inner method result.
EapPeerMethodResult result = {}; EapPeerMethodResult result = {};
m_inner->get_result(reason, &result); m_inner->get_result(reason, &result);
if (result.fSaveConnectionData) if (result.fSaveConnectionData)
ppResult->fSaveConnectionData = TRUE; ppResult->fSaveConnectionData = TRUE;
#if EAP_TLS >= EAP_TLS_SCHANNEL
// EAP-TTLS uses different label in PRF for MSK derivation than EAP-TLS.
static const DWORD s_key_id = 0x01; // EAP-TTLSv0 Keying Material
static const SecPkgContext_EapPrfInfo s_prf_info = { 0, sizeof(s_key_id), (PBYTE)&s_key_id };
SECURITY_STATUS status = SetContextAttributes(m_sc_ctx, SECPKG_ATTR_EAP_PRF_INFO, (void*)&s_prf_info, sizeof(s_prf_info));
if (FAILED(status))
throw sec_runtime_error(status, __FUNCTION__ "Error setting EAP-TTLS PRF in Schannel.");
#endif
method_tls::get_result(EapPeerMethodResultSuccess, ppResult);
// Do not report failure to EapHost, as it will not save updated configuration then. But we need it to save it, to alert user on next connection attempt.
// EapHost is well aware of the failed condition.
//if (reason == EapPeerMethodResultFailure) {
// ppResult->fIsSuccess = FALSE;
// ppResult->dwFailureReasonCode = EAP_E_AUTHENTICATION_FAILED;
//}
} }
} }
#if EAP_TLS < EAP_TLS_SCHANNEL
void eap::method_ttls::derive_msk() void eap::method_ttls::derive_msk()
{ {
const unsigned char *_key_block;
#if EAP_TLS < EAP_TLS_SCHANNEL
// //
// TLS versions 1.0 [RFC2246] and 1.1 [RFC4346] define the same PRF // TLS versions 1.0 [RFC2246] and 1.1 [RFC4346] define the same PRF
// function, and any EAP-TTLSv0 implementation based on these versions // function, and any EAP-TTLSv0 implementation based on these versions
@@ -181,7 +158,21 @@ void eap::method_ttls::derive_msk()
seed.insert(seed.end(), (const unsigned char*)&m_random_client, (const unsigned char*)(&m_random_client + 1)); seed.insert(seed.end(), (const unsigned char*)&m_random_client, (const unsigned char*)(&m_random_client + 1));
seed.insert(seed.end(), (const unsigned char*)&m_random_server, (const unsigned char*)(&m_random_server + 1)); seed.insert(seed.end(), (const unsigned char*)&m_random_server, (const unsigned char*)(&m_random_server + 1));
sanitizing_blob key_block(prf(m_cp, CALG_TLS1PRF, m_master_secret, seed, 2*sizeof(tls_random))); sanitizing_blob key_block(prf(m_cp, CALG_TLS1PRF, m_master_secret, seed, 2*sizeof(tls_random)));
const unsigned char *_key_block = key_block.data(); _key_block = key_block.data();
#else
// EAP-TTLS uses different label in PRF for MSK derivation than EAP-TLS.
static const DWORD s_key_id = 0x01; // EAP-TTLSv0 Keying Material
static const SecPkgContext_EapPrfInfo s_prf_info = { 0, sizeof(s_key_id), (PBYTE)&s_key_id };
SECURITY_STATUS status = SetContextAttributes(m_sc_ctx, SECPKG_ATTR_EAP_PRF_INFO, (void*)&s_prf_info, sizeof(s_prf_info));
if (FAILED(status))
throw sec_runtime_error(status, __FUNCTION__ " Error setting EAP-TTLS PRF in Schannel.");
SecPkgContext_EapKeyBlock key_block;
status = QueryContextAttributes(m_sc_ctx, SECPKG_ATTR_EAP_KEY_BLOCK, &key_block);
if (FAILED(status))
throw sec_runtime_error(status, __FUNCTION__ " Error generating MSK in Schannel.");
_key_block = key_block.rgbKeys;
#endif
// MSK: MPPE-Recv-Key // MSK: MPPE-Recv-Key
memcpy(&m_key_mppe_client, _key_block, sizeof(tls_random)); memcpy(&m_key_mppe_client, _key_block, sizeof(tls_random));
@@ -190,40 +181,79 @@ void eap::method_ttls::derive_msk()
// MSK: MPPE-Send-Key // MSK: MPPE-Send-Key
memcpy(&m_key_mppe_server, _key_block, sizeof(tls_random)); memcpy(&m_key_mppe_server, _key_block, sizeof(tls_random));
_key_block += sizeof(tls_random); _key_block += sizeof(tls_random);
#if EAP_TLS >= EAP_TLS_SCHANNEL
SecureZeroMemory(&key_block, sizeof(key_block));
#endif
} }
eap::sanitizing_blob eap::method_ttls::derive_challenge(_In_ size_t size)
{
#if EAP_TLS < EAP_TLS_SCHANNEL
static const unsigned char s_label[] = "ttls challenge";
sanitizing_blob seed(s_label, s_label + _countof(s_label) - 1);
seed.insert(seed.end(), (const unsigned char*)&m_random_client, (const unsigned char*)(&m_random_client + 1));
seed.insert(seed.end(), (const unsigned char*)&m_random_server, (const unsigned char*)(&m_random_server + 1));
return prf(m_cp, CALG_TLS1PRF, m_master_secret, seed, size);
#else
static const DWORD s_key_id = 0x02; // EAP-TTLSv0 Challenge Data
static const SecPkgContext_EapPrfInfo s_prf_info = { 0, sizeof(s_key_id), (PBYTE)&s_key_id };
SECURITY_STATUS status = SetContextAttributes(m_sc_ctx, SECPKG_ATTR_EAP_PRF_INFO, (void*)&s_prf_info, sizeof(s_prf_info));
if (FAILED(status))
throw sec_runtime_error(status, __FUNCTION__ " Error setting EAP-TTLS PRF in Schannel.");
SecPkgContext_EapKeyBlock key_block;
status = QueryContextAttributes(m_sc_ctx, SECPKG_ATTR_EAP_KEY_BLOCK, &key_block);
if (FAILED(status))
throw sec_runtime_error(status, __FUNCTION__ " Error generating PRF in Schannel.");
sanitizing_blob key;
key.reserve(size);
if (size <= sizeof(key_block.rgbKeys))
key.assign(key_block.rgbKeys, key_block.rgbKeys + size);
else if (size <= sizeof(key_block.rgbKeys) + sizeof(key_block.rgbIVs)) {
key.assign( key_block.rgbKeys, key_block.rgbKeys + sizeof(key_block.rgbKeys));
key.insert(key.end(), key_block.rgbIVs , key_block.rgbIVs + size - sizeof(key_block.rgbKeys));
} else
throw invalid_argument(string_printf(__FUNCTION__ " Schannel cannot generate PRF this big (maximum: %u, requested: %u).", sizeof(key_block.rgbKeys) + sizeof(key_block.rgbIVs), size).c_str());
SecureZeroMemory(&key_block, sizeof(key_block));
return key;
#endif #endif
}
void eap::method_ttls::process_application_data(_In_bytecount_(size_msg) const void *msg, _In_ size_t size_msg) void eap::method_ttls::process_application_data(_In_bytecount_(size_msg) const void *msg, _In_ size_t size_msg)
{ {
// Prepare inner authentication. // Prepare inner authentication.
#if EAP_TLS < EAP_TLS_SCHANNEL #if EAP_TLS < EAP_TLS_SCHANNEL
if (!m_state_client.m_alg_encrypt) if (!m_state_client.m_alg_encrypt)
#else
if (!(m_sc_ctx.m_attrib & ISC_RET_CONFIDENTIALITY))
#endif
throw runtime_error(__FUNCTION__ " Refusing to continue with inner authentication unencrypted."); throw runtime_error(__FUNCTION__ " Refusing to continue with inner authentication unencrypted.");
EapPeerMethodOutput eap_output = {}; if (m_session_resumed) {
eap_type_t eap_type = m_cfg.m_inner->get_method_id(); // On reconnect we do not need to do inner re-authentication.
if (eap_type_noneap_start <= eap_type && eap_type < eap_type_noneap_end) { return;
// Inner method is natively non-EAP. Server sent raw data, but all our eap::method derived classes expect EAP encapsulated. }
// Encapsulate in an EAP packet. #else
assert(size_msg < 0xffff); if (!(m_sc_ctx.m_attrib & ISC_RET_CONFIDENTIALITY))
unsigned short size_packet = (unsigned short)size_msg + 4; throw runtime_error(__FUNCTION__ " Refusing to continue with inner authentication unencrypted.");
sanitizing_blob packet;
packet.reserve(size_packet); SecPkgContext_SessionInfo session_info;
packet.push_back(EapCodeRequest); if (SUCCEEDED(QueryContextAttributes(m_sc_ctx, SECPKG_ATTR_SESSION_INFO, &session_info)) && (session_info.dwFlags & SSL_SESSION_RECONNECT)) {
packet.push_back(m_inner_packet_id++); // On reconnect we do not need to do inner re-authentication.
unsigned short size2 = htons(size_packet); // According to MSDN QueryContextAttributes(SECPKG_ATTR_SESSION_INFO) works from Windows 7 on. Therefore behaviour might vary.
packet.insert(packet.end(), (unsigned char*)&size2, (unsigned char*)(&size2 + 1)); return;
packet.insert(packet.end(), (unsigned char*)msg, (unsigned char*)msg + size_msg); }
m_inner->process_request_packet((const EapPacket*)packet.data(), size_packet, &eap_output); #endif
} else {
// Inner packet is EAP-aware. method_mschapv2 *inner_mschapv2 = dynamic_cast<method_mschapv2*>(m_inner.get());
m_inner->process_request_packet((const EapPacket*)msg, (DWORD)size_msg, &eap_output); if (inner_mschapv2) {
sanitizing_blob keying(derive_challenge(sizeof(challenge_mschapv2) + 1));
memcpy(&inner_mschapv2->m_challenge_server, keying.data(), sizeof(challenge_mschapv2));
inner_mschapv2->m_ident = keying[sizeof(challenge_mschapv2) + 0];
} }
EapPeerMethodOutput eap_output = {};
m_inner->process_request_packet(msg, (DWORD)size_msg, &eap_output);
switch (eap_output.action) { switch (eap_output.action) {
case EapPeerMethodResponseActionSend: { case EapPeerMethodResponseActionSend: {
// Retrieve inner packet and send it. // Retrieve inner packet and send it.
@@ -234,7 +264,7 @@ void eap::method_ttls::process_application_data(_In_bytecount_(size_msg) const v
m_packet_res.m_id = m_packet_req.m_id; m_packet_res.m_id = m_packet_req.m_id;
m_packet_res.m_flags = 0; m_packet_res.m_flags = 0;
DWORD size_data = m_size_inner_packet_max; DWORD size_data = (DWORD)get_max_message(16384 - sizeof(message_header));
sanitizing_blob data(size_data, 0); sanitizing_blob data(size_data, 0);
unsigned char *ptr_data = data.data(); unsigned char *ptr_data = data.data();
#else #else
@@ -243,16 +273,11 @@ void eap::method_ttls::process_application_data(_In_bytecount_(size_msg) const v
if (FAILED(status)) if (FAILED(status))
throw sec_runtime_error(status, __FUNCTION__ " Error getting Schannel required encryption sizes."); throw sec_runtime_error(status, __FUNCTION__ " Error getting Schannel required encryption sizes.");
sanitizing_blob data(sizes.cbHeader + m_size_inner_packet_max + sizes.cbTrailer, 0); sanitizing_blob data(sizes.cbHeader + sizes.cbMaximumMessage + sizes.cbTrailer, 0);
DWORD size_data = m_size_inner_packet_max; DWORD size_data = sizes.cbMaximumMessage;
unsigned char *ptr_data = data.data() + sizes.cbHeader; unsigned char *ptr_data = data.data() + sizes.cbHeader;
#endif #endif
m_inner->get_response_packet((EapPacket*)ptr_data, &size_data); m_inner->get_response_packet(ptr_data, &size_data);
if (eap_type_noneap_start <= eap_type && eap_type < eap_type_noneap_end) {
// Inner method is non-EAP. Strip EAP header, since server expect raw data.
memmove(ptr_data, ptr_data + 4, size_data -= 4);
}
#if EAP_TLS < EAP_TLS_SCHANNEL #if EAP_TLS < EAP_TLS_SCHANNEL
data.resize(size_data); data.resize(size_data);

View File

@@ -77,97 +77,28 @@ void eap::peer_ttls::get_identity(
config_connection cfg(*this); config_connection cfg(*this);
unpack(cfg, pConnectionData, dwConnectionDataSize); unpack(cfg, pConnectionData, dwConnectionDataSize);
// Get method configuration. // Combine credentials.
if (cfg.m_providers.empty() || cfg.m_providers.front().m_methods.empty()) credentials_connection cred_out(*this, cfg);
throw invalid_argument(__FUNCTION__ " Configuration has no providers and/or methods."); const config_method_ttls *cfg_method = combine_credentials(dwFlags, cfg, pUserData, dwUserDataSize, cred_out, hTokenImpersonateUser);
const config_provider &cfg_prov(cfg.m_providers.front());
const config_method_ttls *cfg_method = dynamic_cast<const config_method_ttls*>(cfg_prov.m_methods.front().get());
assert(cfg_method);
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE if (cfg_method) {
// Unpack cached credentials. // No UI will be necessary.
credentials_ttls cred_in(*this); *pfInvokeUI = FALSE;
if (dwUserDataSize) { } else {
cred_in.m_inner.reset(cfg_method->m_inner->make_credentials()); // Credentials missing or incomplete.
unpack(cred_in, pUserData, dwUserDataSize);
}
#else
UNREFERENCED_PARAMETER(pUserData);
UNREFERENCED_PARAMETER(dwUserDataSize);
#endif
credentials_ttls cred_out(*this);
cred_out.m_inner.reset(cfg_method->m_inner->make_credentials());
// Assume no UI will be necessary.
*pfInvokeUI = FALSE;
{
// Combine credentials. We could use eap::credentials_ttls() to do all the work, but we would not know which credentials is missing then.
user_impersonator impersonating(hTokenImpersonateUser);
// Combine outer credentials.
LPCTSTR target_name = (dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? cfg_prov.m_id.c_str() : NULL;
eap::credentials::source_t src_outer = cred_out.credentials_tls::combine(
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
&cred_in,
#else
NULL,
#endif
*cfg_method,
target_name);
if (src_outer == eap::credentials::source_unknown) {
log_event(&EAPMETHOD_TRACE_EVT_CRED_INVOKE_UI1, event_data((unsigned int)eap_type_tls), event_data::blank);
*pfInvokeUI = TRUE;
}
// Combine inner credentials.
eap::credentials::source_t src_inner = cred_out.m_inner->combine(
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
cred_in.m_inner.get(),
#else
NULL,
#endif
*cfg_method->m_inner,
target_name);
if (src_inner == eap::credentials::source_unknown) {
log_event(&EAPMETHOD_TRACE_EVT_CRED_INVOKE_UI1, event_data((unsigned int)cfg_method->m_inner->get_method_id()), event_data::blank);
*pfInvokeUI = TRUE;
}
}
// If either of credentials is unknown, request UI.
if (*pfInvokeUI) {
if ((dwFlags & EAP_FLAG_MACHINE_AUTH) == 0) { if ((dwFlags & EAP_FLAG_MACHINE_AUTH) == 0) {
// Per-user authentication // Per-user authentication, request UI.
log_event(&EAPMETHOD_TRACE_EVT_CRED_INVOKE_UI2, event_data::blank); log_event(&EAPMETHOD_TRACE_EVT_CRED_INVOKE_UI2, event_data::blank);
*pfInvokeUI = TRUE;
return; return;
} else { } else {
// Per-machine authentication // Per-machine authentication, cannot use UI.
throw win_runtime_error(ERROR_NO_SUCH_USER, __FUNCTION__ " Credentials for per-machine authentication not available."); throw win_runtime_error(ERROR_NO_SUCH_USER, __FUNCTION__ " Credentials for per-machine authentication not available.");
} }
} }
// If we got here, we have all credentials we need. But, wait!
if ((dwFlags & EAP_FLAG_MACHINE_AUTH) == 0) {
if (cfg_method->m_auth_failed) {
// Outer: Credentials failed on last connection attempt.
log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM, event_data((unsigned int)eap_type_tls), event_data::blank);
*pfInvokeUI = TRUE;
return;
}
if (cfg_method->m_inner->m_auth_failed) {
// Inner: Credentials failed on last connection attempt.
log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM, event_data((unsigned int)cfg_method->m_inner->get_method_id()), event_data::blank);
*pfInvokeUI = TRUE;
return;
}
}
// Build our identity. ;) // Build our identity. ;)
wstring identity(std::move(cfg_method->get_public_identity(cred_out))); wstring identity(std::move(cfg_method->get_public_identity((const credentials_ttls&)*cred_out.m_cred)));
log_event(&EAPMETHOD_TRACE_EVT_CRED_OUTER_ID1, event_data((unsigned int)eap_type_ttls), event_data(identity), event_data::blank); log_event(&EAPMETHOD_TRACE_EVT_CRED_OUTER_ID1, event_data((unsigned int)eap_type_ttls), event_data(identity), event_data::blank);
size_t size = sizeof(WCHAR)*(identity.length() + 1); size_t size = sizeof(WCHAR)*(identity.length() + 1);
*ppwszIdentity = (WCHAR*)alloc_memory(size); *ppwszIdentity = (WCHAR*)alloc_memory(size);
@@ -268,19 +199,26 @@ EAP_SESSION_HANDLE eap::peer_ttls::begin_session(
// Unpack configuration. // Unpack configuration.
unpack(s->m_cfg, pConnectionData, dwConnectionDataSize); unpack(s->m_cfg, pConnectionData, dwConnectionDataSize);
// Get method configuration.
if (s->m_cfg.m_providers.empty() || s->m_cfg.m_providers.front().m_methods.empty())
throw invalid_argument(__FUNCTION__ " Configuration has no providers and/or methods.");
config_provider &cfg_prov(s->m_cfg.m_providers.front());
config_method_ttls *cfg_method = dynamic_cast<config_method_ttls*>(cfg_prov.m_methods.front().get());
assert(cfg_method);
// Unpack credentials. // Unpack credentials.
s->m_cred.m_inner.reset(cfg_method->m_inner->make_credentials());
unpack(s->m_cred, pUserData, dwUserDataSize); unpack(s->m_cred, pUserData, dwUserDataSize);
config_method_ttls *cfg_method;
for (config_connection::provider_list::iterator cfg_prov = s->m_cfg.m_providers.begin(), cfg_prov_end = s->m_cfg.m_providers.end();; ++cfg_prov) {
if (cfg_prov != cfg_prov_end) {
if (s->m_cred.match(*cfg_prov)) {
// Matching provider found.
if (cfg_prov->m_methods.empty())
throw invalid_argument(string_printf(__FUNCTION__ " %ls provider has no methods.", cfg_prov->get_id().c_str()).c_str());
cfg_method = dynamic_cast<config_method_ttls*>(cfg_prov->m_methods.front().get());
break;
}
} else
throw invalid_argument(string_printf(__FUNCTION__ " Credentials do not match to any provider within this connection configuration (provider: %ls).", s->m_cred.get_id().c_str()).c_str());
}
// We have configuration, we have credentials, create method. // We have configuration, we have credentials, create method.
s->m_method.reset(new method_ttls(*this, *cfg_method, s->m_cred)); s->m_method.reset(new method_ttls(*this, *cfg_method, *(credentials_ttls*)s->m_cred.m_cred.get()));
// Initialize method. // Initialize method.
s->m_method->begin_session(dwFlags, pAttributeArray, hTokenImpersonateUser, dwMaxSendPacketSize); s->m_method->begin_session(dwFlags, pAttributeArray, hTokenImpersonateUser, dwMaxSendPacketSize);
@@ -401,6 +339,98 @@ void eap::peer_ttls::set_response_attributes(
} }
const eap::config_method_ttls* eap::peer_ttls::combine_credentials(
_In_ DWORD dwFlags,
_In_ const config_connection &cfg,
_In_count_(dwUserDataSize) const BYTE *pUserData,
_In_ DWORD dwUserDataSize,
_Out_ credentials_connection& cred_out,
_In_ HANDLE hTokenImpersonateUser)
{
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
// Unpack cached credentials.
credentials_connection cred_in(*this, cfg);
if (dwUserDataSize)
unpack(cred_in, pUserData, dwUserDataSize);
#else
UNREFERENCED_PARAMETER(pUserData);
UNREFERENCED_PARAMETER(dwUserDataSize);
#endif
user_impersonator impersonating(hTokenImpersonateUser);
for (config_connection::provider_list::const_iterator cfg_prov = cfg.m_providers.cbegin(), cfg_prov_end = cfg.m_providers.cend(); cfg_prov != cfg_prov_end; ++cfg_prov) {
wstring target_name(std::move(cfg_prov->get_id()));
// Get method configuration.
if (cfg_prov->m_methods.empty()) {
log_event(&EAPMETHOD_TRACE_EVT_CRED_NO_METHOD, event_data(target_name), event_data::blank);
continue;
}
const config_method_ttls *cfg_method = dynamic_cast<const config_method_ttls*>(cfg_prov->m_methods.front().get());
assert(cfg_method);
// Combine credentials. We could use eap::credentials_ttls() to do all the work, but we would not know which credentials is missing then.
credentials_ttls *cred = (credentials_ttls*)cfg_method->make_credentials();
cred_out.m_cred.reset(cred);
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
bool is_own = cred_in.m_cred && cred_in.match(*cfg_prov);
#endif
// Combine outer credentials.
LPCTSTR _target_name = (dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? target_name.c_str() : NULL;
eap::credentials::source_t src_outer = cred->credentials_tls::combine(
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
is_own ? cred_in.m_cred.get() : NULL,
#else
NULL,
#endif
*cfg_method,
_target_name);
if (src_outer == eap::credentials::source_unknown) {
log_event(&EAPMETHOD_TRACE_EVT_CRED_UNKNOWN3, event_data(target_name), event_data((unsigned int)eap_type_tls), event_data::blank);
continue;
}
// Combine inner credentials.
eap::credentials::source_t src_inner = cred->m_inner->combine(
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
is_own ? ((credentials_ttls*)cred_in.m_cred.get())->m_inner.get() : NULL,
#else
NULL,
#endif
*cfg_method->m_inner,
_target_name);
if (src_inner == eap::credentials::source_unknown) {
log_event(&EAPMETHOD_TRACE_EVT_CRED_UNKNOWN3, event_data(target_name), event_data((unsigned int)cfg_method->m_inner->get_method_id()), event_data::blank);
continue;
}
// If we got here, we have all credentials we need. But, wait!
if ((dwFlags & EAP_FLAG_MACHINE_AUTH) == 0) {
if (cfg_method->m_auth_failed) {
// Outer: Credentials failed on last connection attempt.
log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM1, event_data(target_name), event_data((unsigned int)eap_type_tls), event_data::blank);
continue;
}
if (cfg_method->m_inner->m_auth_failed) {
// Inner: Credentials failed on last connection attempt.
log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM1, event_data(target_name), event_data((unsigned int)cfg_method->m_inner->get_method_id()), event_data::blank);
continue;
}
}
cred_out.m_namespace = cfg_prov->m_namespace;
cred_out.m_id = cfg_prov->m_id;
return cfg_method;
}
return NULL;
}
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// eap::peer_ttls::session // eap::peer_ttls::session
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
@@ -408,7 +438,7 @@ void eap::peer_ttls::set_response_attributes(
eap::peer_ttls::session::session(_In_ module &mod) : eap::peer_ttls::session::session(_In_ module &mod) :
m_module(mod), m_module(mod),
m_cfg(mod), m_cfg(mod),
m_cred(mod), m_cred(mod, m_cfg),
m_blob_cfg(NULL) m_blob_cfg(NULL)
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE #ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
, m_blob_cred(NULL) , m_blob_cred(NULL)

View File

@@ -24,11 +24,17 @@
#include "../include/Credentials.h" #include "../include/Credentials.h"
#include "../include/Method.h" #include "../include/Method.h"
#include "../include/Module.h" #include "../include/Module.h"
#include "../include/TTLS.h"
#include "../../PAP/include/Config.h" #include "../../PAP/include/Config.h"
#include "../../PAP/include/Credentials.h" #include "../../PAP/include/Credentials.h"
#include "../../PAP/include/Method.h" #include "../../PAP/include/Method.h"
#include "../../MSCHAPv2/include/Config.h"
#include "../../MSCHAPv2/include/Credentials.h"
#include "../../MSCHAPv2/include/Method.h"
#include "../../MSCHAPv2/include/MSCHAPv2.h"
#include "../../EAPBase/include/EAPXML.h" #include "../../EAPBase/include/EAPXML.h"
#include <WinStd/EAP.h> #include <WinStd/EAP.h>

View File

@@ -41,6 +41,7 @@ class wxTTLSCredentialsPanel;
#include "../../TTLS/include/Config.h" #include "../../TTLS/include/Config.h"
#include "../../PAP/include/Config.h" #include "../../PAP/include/Config.h"
#include "../../MSCHAPv2/include/Config.h"
#include <WinStd/Win.h> #include <WinStd/Win.h>
@@ -78,12 +79,11 @@ public:
/// ///
/// Constructs a configuration window /// Constructs a configuration window
/// ///
/// \param[in] prov Provider configuration data /// \param[in] prov Provider configuration data
/// \param[inout] cfg Configuration data /// \param[inout] cfg Configuration data
/// \param[in] pszCredTarget Target name of credentials in Windows Credential Manager. Can be further decorated to create final target name. /// \param[in] parent Parent window
/// \param[in] parent Parent window
/// ///
wxTTLSConfigWindow(eap::config_provider &prov, eap::config_method &cfg, LPCTSTR pszCredTarget, wxWindow* parent); wxTTLSConfigWindow(eap::config_provider &prov, eap::config_method &cfg, wxWindow* parent);
/// ///
/// Destructs the configuration window /// Destructs the configuration window
@@ -107,7 +107,8 @@ protected:
wxChoicebook *m_inner_type; ///< Inner authentication type wxChoicebook *m_inner_type; ///< Inner authentication type
// Temporary inner method configurations to hold data until applied // Temporary inner method configurations to hold data until applied
eap::config_method_pap m_cfg_pap; ///< PAP configuration eap::config_method_pap m_cfg_pap; ///< PAP configuration
eap::config_method_mschapv2 m_cfg_mschapv2; ///< MSCHAPv2 configuration
}; };
@@ -117,14 +118,13 @@ public:
/// ///
/// Constructs a configuration panel /// Constructs a configuration panel
/// ///
/// \param[in] prov Provider configuration data /// \param[in] prov Provider configuration data
/// \param[in] cfg Configuration data /// \param[in] cfg Configuration data
/// \param[inout] cred Credentials data /// \param[inout] cred Credentials data
/// \param[in] pszCredTarget Target name of credentials in Windows Credential Manager. Can be further decorated to create final target name. /// \param[in] parent Parent window
/// \param[in] parent Parent window /// \param[in] is_config Is this panel used to pre-enter credentials? When \c true, the "Remember" checkbox is always selected and disabled.
/// \param[in] is_config Is this panel used to pre-enter credentials? When \c true, the "Remember" checkbox is always selected and disabled.
/// ///
wxTTLSCredentialsPanel(const eap::config_provider &prov, const eap::config_method &cfg, eap::credentials &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config = false); wxTTLSCredentialsPanel(const eap::config_provider &prov, const eap::config_method &cfg, eap::credentials &cred, wxWindow* parent, bool is_config = false);
/// ///
/// Destructs the configuration panel /// Destructs the configuration panel

View File

@@ -26,7 +26,7 @@ wxTTLSConfigPanelBase::wxTTLSConfigPanelBase( wxWindow* parent, wxWindowID id, c
sb_outer_identity_vert = new wxBoxSizer( wxVERTICAL ); sb_outer_identity_vert = new wxBoxSizer( wxVERTICAL );
m_outer_identity_label = new wxStaticText( sb_outer_identity->GetStaticBox(), wxID_ANY, _("Select the user ID supplicant introduces itself as to authenticator:"), wxDefaultPosition, wxDefaultSize, 0 ); m_outer_identity_label = new wxStaticText( sb_outer_identity->GetStaticBox(), wxID_ANY, _("Select the user ID supplicant introduces itself as to authenticator:"), wxDefaultPosition, wxDefaultSize, 0 );
m_outer_identity_label->Wrap( 446 ); m_outer_identity_label->Wrap( 440 );
sb_outer_identity_vert->Add( m_outer_identity_label, 0, wxALL|wxEXPAND, 5 ); sb_outer_identity_vert->Add( m_outer_identity_label, 0, wxALL|wxEXPAND, 5 );
wxBoxSizer* sb_outer_identity_radio; wxBoxSizer* sb_outer_identity_radio;

View File

@@ -242,7 +242,7 @@
<property name="window_extra_style"></property> <property name="window_extra_style"></property>
<property name="window_name"></property> <property name="window_name"></property>
<property name="window_style"></property> <property name="window_style"></property>
<property name="wrap">446</property> <property name="wrap">440</property>
<event name="OnChar"></event> <event name="OnChar"></event>
<event name="OnEnterWindow"></event> <event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event> <event name="OnEraseBackground"></event>

View File

@@ -35,7 +35,9 @@ public:
virtual ~wxInitializerPeer(); virtual ~wxInitializerPeer();
protected: protected:
wxLocale m_locale; ///< Locale static wxCriticalSection s_lock; ///< Initialization lock
static unsigned long s_init_ref_count; ///< Initialization reference counter
static wxLocale s_locale; ///< Locale
}; };
@@ -102,26 +104,7 @@ void eap::peer_ttls_ui::invoke_config_ui(
// Load existing configuration. // Load existing configuration.
unpack(cfg, pConnectionDataIn, dwConnectionDataInSize); unpack(cfg, pConnectionDataIn, dwConnectionDataInSize);
} else { } else {
// This is a blank network profile. Create default configuraton. // This is a blank network profile. `cfg` is already set to defaults.
// Inner configuration: PAP
config_method_pap *cfg_method_inner = new config_method_pap(*this);
cfg_method_inner->m_use_preshared = false;
cfg_method_inner->m_preshared(new credentials_pap(*this));
// Outer configuration
unique_ptr<config_method_ttls> cfg_method(new config_method_ttls(*this));
cfg_method->m_anonymous_identity = L"@";
cfg_method->m_use_preshared = true;
cfg_method->m_preshared.reset(new credentials_tls(*this));
cfg_method->m_inner.reset(cfg_method_inner);
// One method
config_provider cfg_provider(*this);
cfg_provider.m_methods.push_back(std::move(cfg_method));
// One provider
cfg.m_providers.push_back(std::move(cfg_provider));
} }
int result; int result;
@@ -170,51 +153,21 @@ void eap::peer_ttls_ui::invoke_identity_ui(
config_connection cfg(*this); config_connection cfg(*this);
unpack(cfg, pConnectionData, dwConnectionDataSize); unpack(cfg, pConnectionData, dwConnectionDataSize);
// Get method configuration.
if (cfg.m_providers.empty() || cfg.m_providers.front().m_methods.empty())
throw invalid_argument(__FUNCTION__ " Configuration has no providers and/or methods.");
const config_provider &cfg_prov(cfg.m_providers.front());
config_method_ttls *cfg_method = dynamic_cast<config_method_ttls*>(cfg_prov.m_methods.front().get());
assert(cfg_method);
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE #ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
// Unpack cached credentials. // Unpack cached credentials.
credentials_ttls cred_in(*this); credentials_connection cred_in(*this, cfg);
if (dwUserDataSize) { if (dwUserDataSize)
s->m_cred.m_inner.reset(cfg_method->m_inner->make_credentials());
unpack(cred_in, pUserData, dwUserDataSize); unpack(cred_in, pUserData, dwUserDataSize);
}
#else #else
UNREFERENCED_PARAMETER(pUserData); UNREFERENCED_PARAMETER(pUserData);
UNREFERENCED_PARAMETER(dwUserDataSize); UNREFERENCED_PARAMETER(dwUserDataSize);
#endif #endif
credentials_ttls cred_out(*this); credentials_connection cred_out(*this, cfg);
cred_out.m_inner.reset(cfg_method->m_inner->make_credentials()); config_method_ttls *cfg_method = NULL;
// Combine credentials. Outer and inner separately to get the idea which one is missing. vector<pair<config_method_ttls*, credentials_connection> > cred_method_store;
eap::credentials::source_t cred_source = cred_out.credentials_tls::combine( cred_method_store.reserve(cfg.m_providers.size());
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
&cred_in,
#else
NULL,
#endif
*cfg_method,
(dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? cfg_prov.m_id.c_str() : NULL);
eap::credentials::source_t cred_source_inner = cred_out.m_inner->combine(
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
cred_in.m_inner.get(),
#else
NULL,
#endif
*cfg_method->m_inner,
(dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? cfg_prov.m_id.c_str() : NULL);
if (dwFlags & EAP_FLAG_GUEST_ACCESS) {
// Disable credential saving for guests.
cfg_method->m_allow_save = false;
cfg_method->m_inner->m_allow_save = false;
}
int result; int result;
{ {
@@ -228,39 +181,114 @@ void eap::peer_ttls_ui::invoke_identity_ui(
parent.AdoptAttributesFromHWND(); parent.AdoptAttributesFromHWND();
wxTopLevelWindows.Append(&parent); wxTopLevelWindows.Append(&parent);
// Create credentials dialog. // Create credentials dialog and populate it with providers.
wxEAPCredentialsDialog dlg(cfg_prov, &parent); bool combined = false;
wxTTLSCredentialsPanel *panel = new wxTTLSCredentialsPanel(cfg_prov, *cfg_method, cred_out, cfg_prov.m_id.c_str(), &dlg); wxEAPCredentialsConnectionDialog dlg(&parent);
dlg.AddContent(panel); for (config_connection::provider_list::iterator cfg_prov = cfg.m_providers.begin(), cfg_prov_end = cfg.m_providers.end(); cfg_prov != cfg_prov_end; ++cfg_prov) {
wstring target_name(std::move(cfg_prov->get_id()));
// Set "Remember" checkboxes according to credential source, // Get method configuration.
panel->m_outer_cred->SetRemember(cred_source == eap::credentials::source_storage); if (cfg_prov->m_methods.empty()) {
panel->m_inner_cred->SetRemember(cred_source_inner == eap::credentials::source_storage); log_event(&EAPMETHOD_TRACE_EVT_CRED_NO_METHOD, event_data(target_name), event_data::blank);
continue;
}
config_method_ttls *cfg_method = dynamic_cast<config_method_ttls*>(cfg_prov->m_methods.front().get());
assert(cfg_method);
// Prepare new set of credentials for given provider.
credentials_connection cred_method(*this, cfg);
cred_method.m_namespace = cfg_prov->m_namespace;
cred_method.m_id = cfg_prov->m_id;
credentials_ttls *_cred_method = (credentials_ttls*)cfg_method->make_credentials();
cred_method.m_cred.reset(_cred_method);
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
bool is_own = cred_in.m_cred && cred_in.match(*cfg_prov);
#endif
// Combine outer credentials.
LPCTSTR _target_name = (dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? target_name.c_str() : NULL;
eap::credentials::source_t src_outer = _cred_method->credentials_tls::combine(
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
is_own ? cred_in.m_cred.get() : NULL,
#else
NULL,
#endif
*cfg_method,
_target_name);
// Combine inner credentials.
eap::credentials::source_t src_inner = _cred_method->m_inner->combine(
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
is_own ? ((credentials_ttls*)cred_in.m_cred.get())->m_inner.get() : NULL,
#else
NULL,
#endif
*cfg_method->m_inner,
_target_name);
if (dwFlags & EAP_FLAG_GUEST_ACCESS) {
// Disable credential saving for guests.
cfg_method->m_allow_save = false;
cfg_method->m_inner->m_allow_save = false;
}
// Create method credentials panel.
wxTTLSCredentialsPanel *panel = new wxTTLSCredentialsPanel(*cfg_prov, *cfg_method, *_cred_method, dlg.m_providers);
// Set "Remember" checkboxes according to credential source,
panel->m_outer_cred->SetRemember(src_outer == eap::credentials::source_storage);
panel->m_inner_cred->SetRemember(src_inner == eap::credentials::source_storage);
// Add panel to choice-book. Select the first one to have known sources.
if (!combined && src_outer != eap::credentials::source_unknown && src_inner != eap::credentials::source_unknown) {
if (dlg.m_providers->AddPage(panel, wxEAPGetProviderName(cfg_prov->m_name), true)) {
cred_method_store.push_back(pair<config_method_ttls*, credentials_connection>(cfg_method, std::move(cred_method)));
combined = true;
}
} else
if (dlg.m_providers->AddPage(panel, wxEAPGetProviderName(cfg_prov->m_name), false))
cred_method_store.push_back(pair<config_method_ttls*, credentials_connection>(cfg_method, std::move(cred_method)));
}
// Update dialog layout.
dlg.Layout();
dlg.GetSizer()->Fit(&dlg);
// Centre and display dialog. // Centre and display dialog.
dlg.Centre(wxBOTH); dlg.Centre(wxBOTH);
result = dlg.ShowModal(); result = dlg.ShowModal();
if (result == wxID_OK) { if (result == wxID_OK) {
// Write credentials to credential manager. int idx_prov = dlg.m_providers->GetSelection();
if (panel->m_outer_cred->GetRemember()) { if (idx_prov != wxNOT_FOUND) {
try { wxTTLSCredentialsPanel *panel = dynamic_cast<wxTTLSCredentialsPanel*>(dlg.m_providers->GetPage(idx_prov));
cred_out.credentials_tls::store(cfg_prov.m_id.c_str()); pair<config_method_ttls*, credentials_connection> &res = cred_method_store[idx_prov];
} catch (winstd::win_runtime_error &err) { cfg_method = res.first;
wxLogError(winstd::tstring_printf(_("Error writing credentials to Credential Manager: %hs (error %u)"), err.what(), err.number()).c_str()); cred_out = res.second;
} catch (...) { credentials_ttls *_cred_out = dynamic_cast<credentials_ttls*>(cred_out.m_cred.get());
wxLogError(_("Writing credentials failed.")); wstring target_name(std::move(cred_out.get_id()));
}
}
if (panel->m_inner_cred->GetRemember()) { // Write credentials to credential manager.
try { if (panel->m_outer_cred->GetRemember()) {
cred_out.m_inner->store(cfg_prov.m_id.c_str()); try {
} catch (winstd::win_runtime_error &err) { _cred_out->credentials_tls::store(target_name.c_str());
wxLogError(winstd::tstring_printf(_("Error writing credentials to Credential Manager: %hs (error %u)"), err.what(), err.number()).c_str()); } catch (winstd::win_runtime_error &err) {
} catch (...) { wxLogError(winstd::tstring_printf(_("Error writing credentials to Credential Manager: %hs (error %u)"), err.what(), err.number()).c_str());
wxLogError(_("Writing credentials failed.")); } catch (...) {
wxLogError(_("Writing credentials failed."));
}
} }
}
if (panel->m_inner_cred->GetRemember()) {
try {
_cred_out->m_inner->store(target_name.c_str());
} catch (winstd::win_runtime_error &err) {
wxLogError(winstd::tstring_printf(_("Error writing credentials to Credential Manager: %hs (error %u)"), err.what(), err.number()).c_str());
} catch (...) {
wxLogError(_("Writing credentials failed."));
}
}
} else
result = wxID_CANCEL;
} }
wxTopLevelWindows.DeleteObject(&parent); wxTopLevelWindows.DeleteObject(&parent);
@@ -272,7 +300,7 @@ void eap::peer_ttls_ui::invoke_identity_ui(
throw win_runtime_error(ERROR_CANCELLED, __FUNCTION__ " Cancelled."); throw win_runtime_error(ERROR_CANCELLED, __FUNCTION__ " Cancelled.");
// Build our identity. ;) // Build our identity. ;)
wstring identity(move(cfg_method->get_public_identity(cred_out))); wstring identity(std::move(cfg_method->get_public_identity((const credentials_ttls&)*cred_out.m_cred)));
log_event(&EAPMETHOD_TRACE_EVT_CRED_OUTER_ID1, event_data((unsigned int)eap_type_ttls), event_data(identity), event_data::blank); log_event(&EAPMETHOD_TRACE_EVT_CRED_OUTER_ID1, event_data((unsigned int)eap_type_ttls), event_data(identity), event_data::blank);
size_t size = sizeof(WCHAR)*(identity.length() + 1); size_t size = sizeof(WCHAR)*(identity.length() + 1);
*ppwszIdentity = (WCHAR*)alloc_memory(size); *ppwszIdentity = (WCHAR*)alloc_memory(size);
@@ -306,20 +334,33 @@ void eap::peer_ttls_ui::invoke_interactive_ui(
wxInitializerPeer::wxInitializerPeer(_In_ HINSTANCE instance) wxInitializerPeer::wxInitializerPeer(_In_ HINSTANCE instance)
{ {
wxCriticalSectionLocker locker(s_lock);
if (s_init_ref_count++)
return;
// Initialize application. // Initialize application.
new wxApp(); new wxApp();
wxEntryStart(instance); wxEntryStart(instance);
// Do our wxWidgets configuration and localization initialization. // Do our wxWidgets configuration and localization initialization.
wxInitializeConfig(); wxInitializeConfig();
if (wxInitializeLocale(m_locale)) { if (wxInitializeLocale(s_locale)) {
//m_locale.AddCatalog(wxT("wxExtend") wxT(wxExtendVersion)); //s_locale.AddCatalog(wxT("wxExtend") wxT(wxExtendVersion));
m_locale.AddCatalog(wxT("EAPTTLSUI")); s_locale.AddCatalog(wxT("EAPTTLSUI"));
} }
} }
wxInitializerPeer::~wxInitializerPeer() wxInitializerPeer::~wxInitializerPeer()
{ {
wxCriticalSectionLocker locker(s_lock);
if (--s_init_ref_count)
return;
wxEntryCleanup(); wxEntryCleanup();
} }
wxCriticalSection wxInitializerPeer::s_lock;
unsigned long wxInitializerPeer::s_init_ref_count = 0;
wxLocale wxInitializerPeer::s_locale;

View File

@@ -26,5 +26,7 @@
#include "../include/TTLS_UI.h" #include "../include/TTLS_UI.h"
#include "../../PAP_UI/include/PAP_UI.h" #include "../../PAP_UI/include/PAP_UI.h"
#include "../../MSCHAPv2_UI/include/MSCHAPv2_UI.h"
#include <wx/app.h> #include <wx/app.h>
#include <wx/thread.h>

View File

@@ -93,9 +93,10 @@ void wxTTLSConfigPanel::OnUpdateUI(wxUpdateUIEvent& /*event*/)
// wxTTLSConfigWindow // wxTTLSConfigWindow
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
wxTTLSConfigWindow::wxTTLSConfigWindow(eap::config_provider &prov, eap::config_method &cfg, LPCTSTR pszCredTarget, wxWindow* parent) : wxTTLSConfigWindow::wxTTLSConfigWindow(eap::config_provider &prov, eap::config_method &cfg, wxWindow* parent) :
m_cfg((eap::config_method_ttls&)cfg), m_cfg((eap::config_method_ttls&)cfg),
m_cfg_pap(cfg.m_module), m_cfg_pap(cfg.m_module),
m_cfg_mschapv2(cfg.m_module),
wxEAPConfigWindow(prov, cfg, parent) wxEAPConfigWindow(prov, cfg, parent)
{ {
wxBoxSizer* sb_content; wxBoxSizer* sb_content;
@@ -111,8 +112,10 @@ wxTTLSConfigWindow::wxTTLSConfigWindow(eap::config_provider &prov, eap::config_m
m_inner_type = new wxChoicebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxCHB_DEFAULT); m_inner_type = new wxChoicebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxCHB_DEFAULT);
m_inner_type->SetToolTip( _("Select inner authentication method from the list") ); m_inner_type->SetToolTip( _("Select inner authentication method from the list") );
wxPAPConfigPanel *panel_pap = new wxPAPConfigPanel(m_prov, m_cfg_pap, pszCredTarget, m_inner_type); wxPAPConfigPanel *panel_pap = new wxPAPConfigPanel(m_prov, m_cfg_pap, m_inner_type);
m_inner_type->AddPage(panel_pap, _("PAP")); m_inner_type->AddPage(panel_pap, _("PAP"));
wxMSCHAPv2ConfigPanel *panel_mschapv2 = new wxMSCHAPv2ConfigPanel(m_prov, m_cfg_mschapv2, m_inner_type);
m_inner_type->AddPage(panel_mschapv2, _("MSCHAPv2"));
sb_content->Add(m_inner_type, 0, wxALL|wxEXPAND, 5); sb_content->Add(m_inner_type, 0, wxALL|wxEXPAND, 5);
sb_content->Add(20, 20, 1, wxALL|wxEXPAND, 5); sb_content->Add(20, 20, 1, wxALL|wxEXPAND, 5);
@@ -125,7 +128,7 @@ wxTTLSConfigWindow::wxTTLSConfigWindow(eap::config_provider &prov, eap::config_m
m_outer_identity = new wxTTLSConfigPanel(m_prov, m_cfg, this); m_outer_identity = new wxTTLSConfigPanel(m_prov, m_cfg, this);
sb_content->Add(m_outer_identity, 0, wxALL|wxEXPAND, 5); sb_content->Add(m_outer_identity, 0, wxALL|wxEXPAND, 5);
m_tls = new wxTLSConfigPanel(m_prov, m_cfg, pszCredTarget, this); m_tls = new wxTLSConfigPanel(m_prov, m_cfg, this);
sb_content->Add(m_tls, 0, wxALL|wxEXPAND, 5); sb_content->Add(m_tls, 0, wxALL|wxEXPAND, 5);
wxSize size = sb_content->CalcMin(); wxSize size = sb_content->CalcMin();
@@ -154,12 +157,20 @@ wxTTLSConfigWindow::~wxTTLSConfigWindow()
bool wxTTLSConfigWindow::TransferDataToWindow() bool wxTTLSConfigWindow::TransferDataToWindow()
{ {
eap::config_method_pap *cfg_pap = dynamic_cast<eap::config_method_pap*>(m_cfg.m_inner.get()); switch (m_cfg.m_inner->get_method_id()) {
if (cfg_pap) { case winstd::eap_type_legacy_pap:
m_cfg_pap = *cfg_pap; m_cfg_pap = *(eap::config_method_pap*)m_cfg.m_inner.get();
m_inner_type->SetSelection(0); // 0=PAP m_inner_type->SetSelection(0); // 0=PAP
} else break;
case winstd::eap_type_legacy_mschapv2:
m_cfg_mschapv2 = *(eap::config_method_mschapv2*)m_cfg.m_inner.get();
m_inner_type->SetSelection(1); // 1=MSCHAPv2
break;
default:
wxFAIL_MSG(wxT("Unsupported inner authentication method type.")); wxFAIL_MSG(wxT("Unsupported inner authentication method type."));
}
// Do not invoke inherited TransferDataToWindow(), as it will call others TransferDataToWindow(). // Do not invoke inherited TransferDataToWindow(), as it will call others TransferDataToWindow().
// This will handle wxTTLSConfigWindow::OnInitDialog() via wxEVT_INIT_DIALOG forwarding. // This will handle wxTTLSConfigWindow::OnInitDialog() via wxEVT_INIT_DIALOG forwarding.
@@ -178,6 +189,10 @@ bool wxTTLSConfigWindow::TransferDataFromWindow()
m_cfg.m_inner.reset(new eap::config_method_pap(m_cfg_pap)); m_cfg.m_inner.reset(new eap::config_method_pap(m_cfg_pap));
break; break;
case 1: // 1=MSCHAPv2
m_cfg.m_inner.reset(new eap::config_method_mschapv2(m_cfg_mschapv2));
break;
default: default:
wxFAIL_MSG(wxT("Unsupported inner authentication method type.")); wxFAIL_MSG(wxT("Unsupported inner authentication method type."));
} }
@@ -209,7 +224,7 @@ void wxTTLSConfigWindow::OnUpdateUI(wxUpdateUIEvent& /*event*/)
// wxTTLSCredentialsPanel // wxTTLSCredentialsPanel
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
wxTTLSCredentialsPanel::wxTTLSCredentialsPanel(const eap::config_provider &prov, const eap::config_method &cfg, eap::credentials &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config) : wxTTLSCredentialsPanel::wxTTLSCredentialsPanel(const eap::config_provider &prov, const eap::config_method &cfg, eap::credentials &cred, wxWindow* parent, bool is_config) :
m_prov(prov), m_prov(prov),
m_cfg((eap::config_method_ttls&)cfg), m_cfg((eap::config_method_ttls&)cfg),
wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize) wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize)
@@ -231,7 +246,7 @@ wxTTLSCredentialsPanel::wxTTLSCredentialsPanel(const eap::config_provider &prov,
if (cfg_inner_pap) { if (cfg_inner_pap) {
eap::credentials_ttls &cred_ttls = (eap::credentials_ttls&)cred; eap::credentials_ttls &cred_ttls = (eap::credentials_ttls&)cred;
if (!cred_ttls.m_inner) cred_ttls.m_inner.reset(new eap::credentials_pap(cred.m_module)); if (!cred_ttls.m_inner) cred_ttls.m_inner.reset(new eap::credentials_pap(cred.m_module));
m_inner_cred = new wxPAPCredentialsPanel(m_prov, *cfg_inner_pap, *(eap::credentials_pap*)cred_ttls.m_inner.get(), pszCredTarget, this, is_config); m_inner_cred = new wxPAPCredentialsPanel(m_prov, *cfg_inner_pap, *(eap::credentials_pap*)cred_ttls.m_inner.get(), this, is_config);
sb_content->Add(m_inner_cred, 0, wxALL|wxEXPAND, 5); sb_content->Add(m_inner_cred, 0, wxALL|wxEXPAND, 5);
} else } else
assert(0); // Unsupported inner authentication method type. assert(0); // Unsupported inner authentication method type.
@@ -246,7 +261,7 @@ wxTTLSCredentialsPanel::wxTTLSCredentialsPanel(const eap::config_provider &prov,
if (m_cfg.m_auth_failed) if (m_cfg.m_auth_failed)
sb_content->Add(new wxEAPCredentialWarningPanel(m_prov, this), 0, wxALL|wxEXPAND, 5); sb_content->Add(new wxEAPCredentialWarningPanel(m_prov, this), 0, wxALL|wxEXPAND, 5);
m_outer_cred = new wxTLSCredentialsPanel(m_prov, (const eap::config_method_tls&)m_cfg, (eap::credentials_tls&)cred, pszCredTarget, this, is_config); m_outer_cred = new wxTLSCredentialsPanel(m_prov, (const eap::config_method_tls&)m_cfg, (eap::credentials_tls&)cred, this, is_config);
sb_content->Add(m_outer_cred, 0, wxALL|wxEXPAND, 5); sb_content->Add(m_outer_cred, 0, wxALL|wxEXPAND, 5);
this->SetSizer(sb_content); this->SetSizer(sb_content);