Compare commits

...

32 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
77 changed files with 3944 additions and 1121 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-31 17:41+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"
@@ -178,30 +178,38 @@ msgid "Assign your organization a unique ID to allow sharing the same credential
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:542 #: 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:" msgid "Provider unique &identifier:"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:547 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:563
msgid "Your organization ID to assign same credentials from other profiles" msgid "Your organization ID to assign same credentials from other profiles"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:551 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:588
msgid "(Examples: contoso.com, DOT-UK, etc.)"
msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:576
msgid "Configuration Lock" msgid "Configuration Lock"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:587 #: 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:594 #: 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:597 #: 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 ""
@@ -210,8 +218,8 @@ msgstr ""
msgid "%s Credentials" msgid "%s Credentials"
msgstr "" msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:123 lib/EAPBase_UI/include/EAP_UI.h:351 #: lib/EAPBase_UI/src/EAP_UI.cpp:123 lib/EAPBase_UI/include/EAP_UI.h:352
#: lib/EAPBase_UI/include/EAP_UI.h:361 lib/EAPBase_UI/res/wxEAP_UI.h:118 #: lib/EAPBase_UI/include/EAP_UI.h:362 lib/EAPBase_UI/res/wxEAP_UI.h:119
msgid "EAP Credentials" msgid "EAP Credentials"
msgstr "" msgstr ""
@@ -220,42 +228,32 @@ msgstr ""
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:168 #: lib/EAPBase_UI/src/EAP_UI.cpp:167
#, c-format
msgid "your %ls provider"
msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:168
msgid "your provider" msgid "your provider"
msgstr "" msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:187 #: 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:198 #: 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:209 #: 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:229 #: 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:231 #: lib/EAPBase_UI/src/EAP_UI.cpp:229
#, c-format
msgid "Your %ls provider"
msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:231
msgid "Your provider" msgid "Your provider"
msgstr "" msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:251 #: 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 ""
@@ -429,73 +427,77 @@ msgstr ""
msgid "Custom outer identity to use" msgid "Custom outer identity to use"
msgstr "" msgstr ""
#: lib/TTLS_UI/src/Module.cpp:272 lib/TTLS_UI/src/Module.cpp:282 #: lib/TTLS_UI/src/Module.cpp:275 lib/TTLS_UI/src/Module.cpp:285
#: lib/EAPBase_UI/include/EAP_UI.h:690 #: 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:274 lib/TTLS_UI/src/Module.cpp:284 #: lib/TTLS_UI/src/Module.cpp:277 lib/TTLS_UI/src/Module.cpp:287
#: lib/EAPBase_UI/include/EAP_UI.h:693 #: 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:288 #: lib/EAPBase_UI/include/EAP_UI.h:289
#, c-format #, c-format
msgid "Are you sure you want to permanently remove %ls provider from configuration?" msgid "Are you sure you want to permanently remove %ls provider from configuration?"
msgstr "" msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:288 #: lib/EAPBase_UI/include/EAP_UI.h:289
msgid "Warning" msgid "Warning"
msgstr "" msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:548 #: lib/EAPBase_UI/include/EAP_UI.h:549
msgid "Provider Settings" msgid "Provider Settings"
msgstr "" msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:706 #: 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:739 #: 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:743 #: lib/EAPBase_UI/include/EAP_UI.h:742
msgid "<error>" msgid "<error>"
msgstr "" msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:754 lib/EAPBase_UI/include/EAP_UI.h:763 #: lib/EAPBase_UI/include/EAP_UI.h:753 lib/EAPBase_UI/include/EAP_UI.h:762
msgid "<empty>" msgid "<empty>"
msgstr "" msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:754 lib/EAPBase_UI/include/EAP_UI.h:763 #: lib/EAPBase_UI/include/EAP_UI.h:753 lib/EAPBase_UI/include/EAP_UI.h:762
msgid "<blank ID>" msgid "<blank ID>"
msgstr "" msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:968 #: lib/EAPBase_UI/include/EAP_UI.h:962
msgid "<Your Organization>" msgid "<Your Organization>"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.h:68 #: lib/EAPBase_UI/res/wxEAP_UI.h:69
msgid "EAP Connection Configuration" msgid "EAP Connection Configuration"
msgstr "" msgstr ""

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

@@ -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

@@ -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 0x00ff1000 #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 16 #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-alpha16" #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.16" #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 "{A41E8D8D-8A6F-415E-B303-C839E2C8A931}" #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

@@ -454,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:
bool m_read_only; ///< Is profile read-only std::wstring m_namespace; ///< Provider namespace URI
std::wstring m_id; ///< Provider ID std::wstring m_id; ///< Provider ID
bool m_read_only; ///< Is profile read-only
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

View File

@@ -476,8 +476,34 @@ 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;
}
}
///
/// 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: public:
const config_connection& m_cfg; ///< Connection configuration const config_connection& m_cfg; ///< Connection configuration
std::wstring m_namespace; ///< Provider namespace URI
std::wstring m_id; ///< Provider ID std::wstring m_id; ///< Provider ID
std::unique_ptr<credentials> m_cred; ///< Credentials 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
struct diameter_avp_header
{ {
unsigned char code[4]; ///< AVP Code unsigned char code[4]; ///< AVP Code
unsigned char flags; ///< AVP Flags unsigned char flags; ///< AVP Flags
unsigned char length[3]; ///< AVP Length unsigned char length[3]; ///< AVP Length
};
#pragma warning(push)
#pragma warning(disable: 4201) struct diameter_avp_header_ven : public diameter_avp_header
union { {
struct {
unsigned char vendor[4]; ///< Vendor-ID unsigned char vendor[4]; ///< Vendor-ID
unsigned char v_data[1]; ///< Data (when Vendor-ID present)
};
unsigned char data[1]; ///< Data (when Vendor-ID absent)
};
#pragma warning(pop)
}; };
#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,7 +114,7 @@ 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;
/// ///
@@ -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

@@ -287,8 +287,9 @@ 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_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 ),
@@ -305,8 +306,9 @@ 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_read_only (std::move(other.m_read_only )),
m_name (std::move(other.m_name )), m_name (std::move(other.m_name )),
m_help_email (std::move(other.m_help_email )), m_help_email (std::move(other.m_help_email )),
m_help_web (std::move(other.m_help_web )), m_help_web (std::move(other.m_help_web )),
@@ -324,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;
@@ -348,8 +351,9 @@ eap::config_provider& eap::config_provider::operator=(_Inout_ config_provider &&
{ {
if (this != &other) { if (this != &other) {
(config&&)*this = std::move(other ); (config&&)*this = std::move(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_read_only = std::move(other.m_read_only );
m_name = std::move(other.m_name ); m_name = std::move(other.m_name );
m_help_email = std::move(other.m_help_email ); m_help_email = std::move(other.m_help_email );
m_help_web = std::move(other.m_help_web ); m_help_web = std::move(other.m_help_web );
@@ -376,15 +380,20 @@ void eap::config_provider::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pC
HRESULT hr; HRESULT hr;
// namespace
if (!m_namespace.empty())
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
if (!m_id.empty())
if (FAILED(hr = eapxml::put_attrib_value(pConfigRoot, bstr(L"ID"), bstr(m_id))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating ID attribute.");
// <read-only> // <read-only>
if (FAILED(hr = eapxml::put_element_value(pDoc, pConfigRoot, bstr(L"read-only"), namespace_eapmetadata, m_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."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <read-only> element.");
// <ID>
if (!m_id.empty())
if (FAILED(hr = eapxml::put_element_value(pDoc, pConfigRoot, bstr(L"ID"), namespace_eapmetadata, bstr(m_id))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <ID> 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"), namespace_eapmetadata, &pXmlElProviderInfo))) if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:ProviderInfo"), bstr(L"ProviderInfo"), namespace_eapmetadata, &pXmlElProviderInfo)))
@@ -458,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();
@@ -550,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 ;
@@ -567,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 ) +
@@ -583,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 ;

View File

@@ -93,6 +93,7 @@ void eap::credentials::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pConfi
HRESULT hr; HRESULT hr;
// <UserName> // <UserName>
if (!m_identity.empty())
if (FAILED(hr = eapxml::put_element_value(pDoc, pConfigRoot, bstr(L"UserName"), namespace_eapmetadata, bstr(m_identity)))) 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."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <UserName> element.");
} }
@@ -431,18 +432,20 @@ eap::credentials_connection::credentials_connection(_In_ module &mod, _In_ const
eap::credentials_connection::credentials_connection(_In_ const credentials_connection &other) : eap::credentials_connection::credentials_connection(_In_ const credentials_connection &other) :
m_cfg (other.m_cfg ), m_cfg (other.m_cfg ),
m_namespace(other.m_namespace),
m_id (other.m_id ), m_id (other.m_id ),
m_cred(other.m_cred ? (credentials*)other.m_cred->clone() : nullptr), m_cred (other.m_cred ? (credentials*)other.m_cred->clone() : nullptr),
config(other ) config (other )
{ {
} }
eap::credentials_connection::credentials_connection(_Inout_ credentials_connection &&other) : eap::credentials_connection::credentials_connection(_Inout_ credentials_connection &&other) :
m_cfg ( other.m_cfg ), m_cfg ( other.m_cfg ),
m_namespace(std::move(other.m_namespace)),
m_id (std::move(other.m_id )), m_id (std::move(other.m_id )),
m_cred(std::move(other.m_cred)), m_cred (std::move(other.m_cred )),
config(std::move(other )) config (std::move(other ))
{ {
} }
@@ -451,6 +454,7 @@ eap::credentials_connection& eap::credentials_connection::operator=(_In_ const c
{ {
if (this != &other) { if (this != &other) {
(config&)*this = other; (config&)*this = other;
m_namespace = other.m_namespace;
m_id = other.m_id; m_id = other.m_id;
m_cred.reset(other.m_cred ? (credentials*)other.m_cred->clone() : nullptr); m_cred.reset(other.m_cred ? (credentials*)other.m_cred->clone() : nullptr);
} }
@@ -463,8 +467,9 @@ eap::credentials_connection& eap::credentials_connection::operator=(_Inout_ cred
{ {
if (this != &other) { if (this != &other) {
(config&)*this = std::move(other ); (config&)*this = std::move(other );
m_namespace = std::move(other.m_namespace);
m_id = std::move(other.m_id ); m_id = std::move(other.m_id );
m_cred = std::move(other.m_cred); m_cred = std::move(other.m_cred );
} }
return *this; return *this;
@@ -486,11 +491,22 @@ void eap::credentials_connection::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMN
HRESULT hr; HRESULT hr;
// <IdentityProviderID> // Create <EAPIdentityProvider> node.
if (FAILED(hr = eapxml::put_element_value(pDoc, pConfigRoot, bstr(L"IdentityProviderID"), namespace_eapmetadata, bstr(m_id)))) com_obj<IXMLDOMElement> pXmlElIdentityProvider;
throw com_runtime_error(hr, __FUNCTION__ " Error creating <IdentityProviderID> element."); 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.");
m_cred->save(pDoc, pConfigRoot); // 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);
} }
@@ -501,27 +517,37 @@ void eap::credentials_connection::load(_In_ IXMLDOMNode *pConfigRoot)
config::load(pConfigRoot); config::load(pConfigRoot);
std::wstring xpath(eapxml::get_xpath(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.");
if (FAILED(hr = eapxml::get_element_value(pConfigRoot, bstr(L"eap-metadata:IdentityProviderID"), m_id))) 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(); m_id.clear();
eapxml::get_attrib_value(pXmlElClientSideCredential, bstr(L"ID"), m_id);
m_module.log_config((xpath + L"/IdentityProviderID").c_str(), m_id.c_str()); m_module.log_config((xpath + L" ID").c_str(), m_id.c_str());
// Look-up the provider. // 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) { 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 (cfg_prov != cfg_prov_end) {
if (_wcsicmp(cfg_prov->m_id.c_str(), m_id.c_str()) == 0) { if (match(*cfg_prov)) {
// Matching provider found. Create matching blank credential set, then load. // Matching provider found. Create matching blank credential set, then load.
if (cfg_prov->m_methods.empty()) if (cfg_prov->m_methods.empty())
throw invalid_argument(string_printf(__FUNCTION__ " %ls provider has no methods.", cfg_prov->m_id.c_str()).c_str()); 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()); 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.reset(cfg_method->make_credentials());
m_cred->load(pConfigRoot); m_cred->load(pXmlElClientSideCredential);
break; break;
} }
} else } else
throw invalid_argument(string_printf(__FUNCTION__ " Credentials do not match to any provider ID within this connection configuration (provider ID: %ls).", m_id.c_str()).c_str()); 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());
} }
} }
@@ -529,8 +555,9 @@ void eap::credentials_connection::load(_In_ IXMLDOMNode *pConfigRoot)
void eap::credentials_connection::operator<<(_Inout_ cursor_out &cursor) const void eap::credentials_connection::operator<<(_Inout_ cursor_out &cursor) const
{ {
config::operator<<(cursor); config::operator<<(cursor);
cursor << m_namespace;
cursor << m_id ; cursor << m_id ;
cursor << *m_cred; cursor << *m_cred ;
} }
@@ -538,29 +565,31 @@ size_t eap::credentials_connection::get_pk_size() const
{ {
return return
config::get_pk_size() + config::get_pk_size() +
pksizeof( m_namespace) +
pksizeof( m_id ) + pksizeof( m_id ) +
pksizeof(*m_cred); pksizeof(*m_cred );
} }
void eap::credentials_connection::operator>>(_Inout_ cursor_in &cursor) void eap::credentials_connection::operator>>(_Inout_ cursor_in &cursor)
{ {
config::operator>>(cursor); config::operator>>(cursor);
cursor >> m_id; cursor >> m_namespace;
cursor >> m_id ;
// Look-up the provider. // 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) { 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 (cfg_prov != cfg_prov_end) {
if (_wcsicmp(cfg_prov->m_id.c_str(), m_id.c_str()) == 0) { if (match(*cfg_prov)) {
// Matching provider found. Create matching blank credential set, then read. // Matching provider found. Create matching blank credential set, then read.
if (cfg_prov->m_methods.empty()) if (cfg_prov->m_methods.empty())
throw invalid_argument(string_printf(__FUNCTION__ " %ls provider has no methods.", cfg_prov->m_id.c_str()).c_str()); 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()); 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.reset(cfg_method->make_credentials());
cursor >> *m_cred; cursor >> *m_cred;
break; break;
} }
} else } else
throw invalid_argument(string_printf(__FUNCTION__ " Credentials do not match to any provider ID within this connection configuration (provider ID: %ls).", m_id.c_str()).c_str()); 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

@@ -199,21 +199,22 @@ public:
this->SetIcon(wxIcon(wxICON(product.ico))); this->SetIcon(wxIcon(wxICON(product.ico)));
#endif #endif
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) { 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_name) : wxEAPGetProviderName(provider->m_name) :
winstd::tstring_printf(_T("%s (%u)"), wxEAPGetProviderName(provider->m_name), count)); winstd::tstring_printf(_T("%s (%u)"), wxEAPGetProviderName(provider->m_name), count));
} }
}
this->Layout(); this->Layout();
this->GetSizer()->Fit(this); this->GetSizer()->Fit(this);
@@ -259,7 +260,8 @@ protected:
eap::config_provider cfg_provider(m_cfg.m_module); eap::config_provider cfg_provider(m_cfg.m_module);
GUID guid; GUID guid;
CoCreateGuid(&guid); CoCreateGuid(&guid);
cfg_provider.m_id = std::move(winstd::wstring_guid(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)); cfg_provider.m_methods.push_back(std::move(cfg_method));
// Append provider. // Append provider.
@@ -271,7 +273,6 @@ protected:
new _wxT( new _wxT(
cfg_provider2, cfg_provider2,
*cfg_method2, *cfg_method2,
cfg_provider2.m_id.c_str(),
m_providers), m_providers),
wxEAPGetProviderName(cfg_provider2.m_name), true); wxEAPGetProviderName(cfg_provider2.m_name), true);
@@ -291,7 +292,7 @@ protected:
for (int i = 0; i < idx; i++, ++it); for (int i = 0; i < idx; i++, ++it);
m_cfg.m_providers.erase(it); m_cfg.m_providers.erase(it);
m_providers->DeletePage(idx); m_providers->DeletePage(idx);
if (idx < m_providers->GetPageCount()) if ((size_t)idx < m_providers->GetPageCount())
m_providers->SetSelection(idx); m_providers->SetSelection(idx);
this->Layout(); this->Layout();
@@ -564,13 +565,11 @@ public:
/// ///
/// \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),
@@ -678,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) {
@@ -699,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
@@ -711,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)
@@ -728,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) {
@@ -768,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?
@@ -792,15 +790,13 @@ public:
/// \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)
{ {
@@ -845,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?
}; };
@@ -860,12 +855,11 @@ public:
/// \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;
@@ -875,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( 445 ); m_credentials_label->Wrap( 440 );
layout = true; layout = true;
} }

View File

@@ -239,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( 445 ); 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;
@@ -364,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( 445 ); 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;
@@ -429,7 +429,7 @@ wxEAPProviderContactInfoPanelBase::wxEAPProviderContactInfoPanelBase( wxWindow*
sb_provider_contact_vert = new wxBoxSizer( wxVERTICAL ); 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 = 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( 445 ); m_provider_contact_label->Wrap( 440 );
sb_provider_contact_vert->Add( m_provider_contact_label, 0, wxALL|wxEXPAND, 5 ); sb_provider_contact_vert->Add( m_provider_contact_label, 0, wxALL|wxEXPAND, 5 );
wxBoxSizer* sb_provider_name; wxBoxSizer* sb_provider_name;
@@ -533,9 +533,25 @@ wxEAPProviderIDPanelBase::wxEAPProviderIDPanelBase( wxWindow* parent, wxWindowID
sb_provider_id_vert = new wxBoxSizer( wxVERTICAL ); sb_provider_id_vert = new wxBoxSizer( wxVERTICAL );
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_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_outer->Wrap( 445 ); m_provider_id_label_outer->Wrap( 440 );
sb_provider_id_vert->Add( m_provider_id_label_outer, 0, wxALL|wxEXPAND, 5 ); sb_provider_id_vert->Add( m_provider_id_label_outer, 0, wxALL|wxEXPAND, 5 );
wxBoxSizer* sb_provider_namespace;
sb_provider_namespace = new wxBoxSizer( wxVERTICAL );
m_provider_namespace_label = new wxStaticText( sb_provider_id->GetStaticBox(), wxID_ANY, _("&Namespace:"), wxDefaultPosition, wxDefaultSize, 0 );
m_provider_namespace_label->Wrap( -1 );
sb_provider_namespace->Add( m_provider_namespace_label, 0, wxBOTTOM, 5 );
wxString m_provider_namespaceChoices[] = { _("urn:RFC4282:realm"), _("urn:uuid") };
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 );
m_provider_namespace->SetSelection( 0 );
sb_provider_namespace->Add( m_provider_namespace, 0, wxEXPAND, 5 );
sb_provider_id_vert->Add( sb_provider_namespace, 0, wxEXPAND|wxALL, 5 );
wxBoxSizer* sb_provider_id_inner; wxBoxSizer* sb_provider_id_inner;
sb_provider_id_inner = new wxBoxSizer( wxVERTICAL ); sb_provider_id_inner = new wxBoxSizer( wxVERTICAL );
@@ -546,11 +562,7 @@ wxEAPProviderIDPanelBase::wxEAPProviderIDPanelBase( wxWindow* parent, wxWindowID
m_provider_id = new wxTextCtrl( sb_provider_id->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_provider_id = new wxTextCtrl( sb_provider_id->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_provider_id->SetToolTip( _("Your organization ID to assign same credentials from other profiles") ); m_provider_id->SetToolTip( _("Your organization ID to assign same credentials from other profiles") );
sb_provider_id_inner->Add( m_provider_id, 0, wxEXPAND|wxBOTTOM, 5 ); sb_provider_id_inner->Add( m_provider_id, 0, wxEXPAND, 5 );
m_provider_id_note = new wxStaticText( sb_provider_id->GetStaticBox(), wxID_ANY, _("(Examples: contoso.com, DOT-UK, etc.)"), wxDefaultPosition, wxDefaultSize, 0 );
m_provider_id_note->Wrap( -1 );
sb_provider_id_inner->Add( m_provider_id_note, 0, wxALIGN_RIGHT, 5 );
sb_provider_id_vert->Add( sb_provider_id_inner, 0, wxEXPAND|wxALL, 5 ); sb_provider_id_vert->Add( sb_provider_id_inner, 0, wxEXPAND|wxALL, 5 );
@@ -585,7 +597,7 @@ 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( 445 ); 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_lock_inner; wxBoxSizer* sb_provider_lock_inner;

View File

@@ -1623,7 +1623,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">445</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>
@@ -2579,7 +2579,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">445</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>
@@ -3281,7 +3281,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">445</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>
@@ -4431,7 +4431,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">445</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>
@@ -4457,6 +4457,188 @@
<event name="OnUpdateUI"></event> <event name="OnUpdateUI"></event>
</object> </object>
</object> </object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxALL</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">sb_provider_namespace</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxBOTTOM</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">&amp;Namespace:</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_provider_namespace_label</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxChoice" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="choices">&quot;urn:RFC4282:realm&quot; &quot;urn:uuid&quot;</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_provider_namespace</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="selection">0</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnChoice"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="1">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxEXPAND|wxALL</property> <property name="flag">wxEXPAND|wxALL</property>
@@ -4551,7 +4733,7 @@
</object> </object>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="1">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxEXPAND|wxBOTTOM</property> <property name="flag">wxEXPAND</property>
<property name="proportion">0</property> <property name="proportion">0</property>
<object class="wxTextCtrl" expanded="1"> <object class="wxTextCtrl" expanded="1">
<property name="BottomDockable">1</property> <property name="BottomDockable">1</property>
@@ -4640,89 +4822,6 @@
<event name="OnUpdateUI"></event> <event name="OnUpdateUI"></event>
</object> </object>
</object> </object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALIGN_RIGHT</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">(Examples: contoso.com, DOT-UK, etc.)</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_provider_id_note</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
</object> </object>
</object> </object>
</object> </object>
@@ -4947,7 +5046,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">445</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,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>
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@@ -251,9 +252,10 @@ class wxEAPProviderIDPanelBase : public wxPanel
protected: protected:
wxStaticBitmap* m_provider_id_icon; wxStaticBitmap* m_provider_id_icon;
wxStaticText* m_provider_id_label_outer; wxStaticText* m_provider_id_label_outer;
wxStaticText* m_provider_namespace_label;
wxChoice* m_provider_namespace;
wxStaticText* m_provider_id_label; wxStaticText* m_provider_id_label;
wxTextCtrl* m_provider_id; wxTextCtrl* m_provider_id;
wxStaticText* m_provider_id_note;
public: public:

View File

@@ -164,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);
@@ -227,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);
@@ -343,7 +341,8 @@ wxEAPProviderIDPanel::wxEAPProviderIDPanel(eap::config_provider &prov, wxWindow*
bool wxEAPProviderIDPanel::TransferDataToWindow() bool wxEAPProviderIDPanel::TransferDataToWindow()
{ {
m_provider_id->SetValue(m_prov.m_id); m_provider_namespace->SetStringSelection(m_prov.m_namespace);
m_provider_id ->SetValue(m_prov.m_id);
return wxEAPProviderIDPanelBase::TransferDataToWindow(); return wxEAPProviderIDPanelBase::TransferDataToWindow();
} }
@@ -353,7 +352,8 @@ bool wxEAPProviderIDPanel::TransferDataFromWindow()
{ {
wxCHECK(wxEAPProviderIDPanelBase::TransferDataFromWindow(), false); wxCHECK(wxEAPProviderIDPanelBase::TransferDataFromWindow(), false);
m_prov.m_id = m_provider_id->GetValue(); m_prov.m_namespace = m_provider_namespace->GetStringSelection();
m_prov.m_id = m_provider_id ->GetValue();
return true; return true;
} }

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.
/// ///
@@ -156,8 +103,6 @@ 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

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 (std::move(other )) method_noneap(std::move(other ))
{ {
} }
@@ -110,8 +50,7 @@ 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);
} }
@@ -120,20 +59,28 @@ eap::method_pap& eap::method_pap::operator=(_Inout_ method_pap &&other)
} }
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,7 +121,7 @@ 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;
@@ -261,11 +133,11 @@ 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.

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,7 +116,7 @@ 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);
/// ///
@@ -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

@@ -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);
@@ -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,25 +523,6 @@ 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;
@@ -701,9 +531,35 @@ void eap::method_tls::get_result(
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,6 +588,8 @@ 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.
@@ -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

@@ -257,11 +257,10 @@ public:
/// \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( 445 ); 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( 445 ); 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">445</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">445</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,7 +103,7 @@ 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);
/// ///
@@ -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
}; };
} }

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

@@ -138,19 +138,6 @@ void eap::config_method_ttls::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode
com_obj<IXMLDOMElement> pXmlElClientCertificate; com_obj<IXMLDOMElement> pXmlElClientCertificate;
hr = eapxml::create_element(pDoc, pXmlElClientSideCredential, bstr(L"eap-metadata:ClientCertificate"), bstr(L"ClientCertificate"), namespace_eapmetadata, &pXmlElClientCertificate); hr = eapxml::create_element(pDoc, pXmlElClientSideCredential, bstr(L"eap-metadata:ClientCertificate"), bstr(L"ClientCertificate"), namespace_eapmetadata, &pXmlElClientCertificate);
} }
// Fix 2: draft-winter-opsawg-eap-metadata is using <OuterIdentity> name for <UserName> when referring to outer identity of EAP-TTLS.
// GÉANTLink is using <UserName> for identities and usernames uniformly. Create <OuterIdentity> and remove <UserName>.
com_obj<IXMLDOMElement> pXmlElUserName;
if (SUCCEEDED(hr = eapxml::select_element(pXmlElClientSideCredential, bstr(L"eap-metadata:UserName"), &pXmlElUserName))) {
bstr identity;
if (SUCCEEDED(hr = pXmlElUserName->get_text(&identity))) {
if (SUCCEEDED(hr = eapxml::put_element_value(pDoc, pXmlElClientSideCredential, bstr(L"OuterIdentity"), namespace_eapmetadata, identity))) {
com_obj<IXMLDOMNode> pXmlElClientCertificateOld;
hr = pXmlElClientSideCredential->removeChild(pXmlElUserName, &pXmlElClientCertificateOld);
}
}
}
} }
} }
} }
@@ -181,19 +168,6 @@ void eap::config_method_ttls::load(_In_ IXMLDOMNode *pConfigRoot)
com_obj<IXMLDOMElement> pXmlElClientCertificate; com_obj<IXMLDOMElement> pXmlElClientCertificate;
hr = eapxml::create_element(pDoc, pXmlElClientSideCredential, bstr(L"eap-metadata:ClientCertificate"), bstr(L"ClientCertificate"), namespace_eapmetadata, &pXmlElClientCertificate); hr = eapxml::create_element(pDoc, pXmlElClientSideCredential, bstr(L"eap-metadata:ClientCertificate"), bstr(L"ClientCertificate"), namespace_eapmetadata, &pXmlElClientCertificate);
} }
// Fix 2: draft-winter-opsawg-eap-metadata is using <OuterIdentity> name for <UserName> when referring to outer identity of EAP-TTLS.
// GÉANTLink is using <UserName> for identities and usernames uniformly. Create <UserName> and remove <OuterIdentity>.
com_obj<IXMLDOMElement> pXmlElOuterIdentity;
if (SUCCEEDED(hr = eapxml::select_element(pXmlElClientSideCredential, bstr(L"eap-metadata:OuterIdentity"), &pXmlElOuterIdentity))) {
bstr identity;
if (SUCCEEDED(hr = pXmlElOuterIdentity->get_text(&identity))) {
if (SUCCEEDED(hr = eapxml::put_element_value(pDoc, pXmlElClientSideCredential, bstr(L"UserName"), namespace_eapmetadata, identity))) {
com_obj<IXMLDOMNode> pXmlElClientCertificateOld;
hr = pXmlElClientSideCredential->removeChild(pXmlElOuterIdentity, &pXmlElClientCertificateOld);
}
}
}
} }
} }
} }
@@ -292,8 +266,9 @@ eap::config_method_with_cred* eap::config_method_ttls::make_config_method(_In_ w
{ {
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);
case eap_type_legacy_mschapv2: return new config_method_mschapv2(m_module);
default : throw invalid_argument(__FUNCTION__ " Unsupported inner authentication method."); default : throw invalid_argument(__FUNCTION__ " Unsupported inner authentication method.");
} }
} }
@@ -302,8 +277,9 @@ eap::config_method_with_cred* eap::config_method_ttls::make_config_method(_In_ w
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) return new config_method_tls (m_module); if (_wcsicmp(eap_type, L"EAP-TLS" ) == 0) 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) return new config_method_ttls (m_module);
else if (_wcsicmp(eap_type, L"PAP" ) == 0) return new config_method_pap (m_module); else if (_wcsicmp(eap_type, L"PAP" ) == 0) return new config_method_pap (m_module);
else if (_wcsicmp(eap_type, L"MSCHAPv2") == 0) return new config_method_mschapv2(m_module);
else throw invalid_argument(__FUNCTION__ " Unsupported inner authentication method."); else throw invalid_argument(__FUNCTION__ " Unsupported inner authentication method.");
} }

View File

@@ -32,8 +32,6 @@ 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)
{ {
} }
@@ -42,11 +40,9 @@ eap::method_ttls::method_ttls(_In_ module &module, _In_ config_method_ttls &cfg,
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 ))
{ {
} }
@@ -55,10 +51,8 @@ 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

@@ -206,15 +206,15 @@ EAP_SESSION_HANDLE eap::peer_ttls::begin_session(
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) { 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 (cfg_prov != cfg_prov_end) {
if (_wcsicmp(cfg_prov->m_id.c_str(), s->m_cred.m_id.c_str()) == 0) { if (s->m_cred.match(*cfg_prov)) {
// Matching provider found. // Matching provider found.
if (cfg_prov->m_methods.empty()) if (cfg_prov->m_methods.empty())
throw invalid_argument(string_printf(__FUNCTION__ " %ls provider has no methods.", cfg_prov->m_id.c_str()).c_str()); 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()); cfg_method = dynamic_cast<config_method_ttls*>(cfg_prov->m_methods.front().get());
break; break;
} }
} else } else
throw invalid_argument(string_printf(__FUNCTION__ " Credentials do not match to any provider ID within this connection configuration (provider ID: %ls).", s->m_cred.m_id.c_str()).c_str()); 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.
@@ -360,9 +360,11 @@ const eap::config_method_ttls* eap::peer_ttls::combine_credentials(
user_impersonator impersonating(hTokenImpersonateUser); 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) { 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. // Get method configuration.
if (cfg_prov->m_methods.empty()) { if (cfg_prov->m_methods.empty()) {
log_event(&EAPMETHOD_TRACE_EVT_CRED_NO_METHOD, event_data(cfg_prov->m_id), event_data::blank); log_event(&EAPMETHOD_TRACE_EVT_CRED_NO_METHOD, event_data(target_name), event_data::blank);
continue; continue;
} }
const config_method_ttls *cfg_method = dynamic_cast<const config_method_ttls*>(cfg_prov->m_methods.front().get()); const config_method_ttls *cfg_method = dynamic_cast<const config_method_ttls*>(cfg_prov->m_methods.front().get());
@@ -372,11 +374,11 @@ const eap::config_method_ttls* eap::peer_ttls::combine_credentials(
credentials_ttls *cred = (credentials_ttls*)cfg_method->make_credentials(); credentials_ttls *cred = (credentials_ttls*)cfg_method->make_credentials();
cred_out.m_cred.reset(cred); cred_out.m_cred.reset(cred);
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE #ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
bool is_own = cred_in.m_cred && _wcsicmp(cred_in.m_id.c_str(), cfg_prov->m_id.c_str()) == 0; bool is_own = cred_in.m_cred && cred_in.match(*cfg_prov);
#endif #endif
// Combine outer credentials. // Combine outer credentials.
LPCTSTR target_name = (dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? cfg_prov->m_id.c_str() : NULL; LPCTSTR _target_name = (dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? target_name.c_str() : NULL;
eap::credentials::source_t src_outer = cred->credentials_tls::combine( eap::credentials::source_t src_outer = cred->credentials_tls::combine(
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE #ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
is_own ? cred_in.m_cred.get() : NULL, is_own ? cred_in.m_cred.get() : NULL,
@@ -384,9 +386,9 @@ const eap::config_method_ttls* eap::peer_ttls::combine_credentials(
NULL, NULL,
#endif #endif
*cfg_method, *cfg_method,
target_name); _target_name);
if (src_outer == eap::credentials::source_unknown) { if (src_outer == eap::credentials::source_unknown) {
log_event(&EAPMETHOD_TRACE_EVT_CRED_UNKNOWN3, event_data(cfg_prov->m_id), event_data((unsigned int)eap_type_tls), event_data::blank); log_event(&EAPMETHOD_TRACE_EVT_CRED_UNKNOWN3, event_data(target_name), event_data((unsigned int)eap_type_tls), event_data::blank);
continue; continue;
} }
@@ -398,9 +400,9 @@ const eap::config_method_ttls* eap::peer_ttls::combine_credentials(
NULL, NULL,
#endif #endif
*cfg_method->m_inner, *cfg_method->m_inner,
target_name); _target_name);
if (src_inner == eap::credentials::source_unknown) { if (src_inner == eap::credentials::source_unknown) {
log_event(&EAPMETHOD_TRACE_EVT_CRED_UNKNOWN3, event_data(cfg_prov->m_id), event_data((unsigned int)cfg_method->m_inner->get_method_id()), event_data::blank); 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; continue;
} }
@@ -409,17 +411,18 @@ const eap::config_method_ttls* eap::peer_ttls::combine_credentials(
if ((dwFlags & EAP_FLAG_MACHINE_AUTH) == 0) { if ((dwFlags & EAP_FLAG_MACHINE_AUTH) == 0) {
if (cfg_method->m_auth_failed) { if (cfg_method->m_auth_failed) {
// Outer: Credentials failed on last connection attempt. // Outer: Credentials failed on last connection attempt.
log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM1, event_data(cfg_prov->m_id), event_data((unsigned int)eap_type_tls), event_data::blank); log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM1, event_data(target_name), event_data((unsigned int)eap_type_tls), event_data::blank);
continue; continue;
} }
if (cfg_method->m_inner->m_auth_failed) { if (cfg_method->m_inner->m_auth_failed) {
// Inner: Credentials failed on last connection attempt. // Inner: Credentials failed on last connection attempt.
log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM1, event_data(cfg_prov->m_id), event_data((unsigned int)cfg_method->m_inner->get_method_id()), event_data::blank); 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; continue;
} }
} }
cred_out.m_namespace = cfg_prov->m_namespace;
cred_out.m_id = cfg_prov->m_id; cred_out.m_id = cfg_prov->m_id;
return cfg_method; return cfg_method;
} }

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>
@@ -80,10 +81,9 @@ public:
/// ///
/// \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
@@ -108,6 +108,7 @@ protected:
// 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
}; };
@@ -120,11 +121,10 @@ public:
/// \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( 445 ); 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">445</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

@@ -23,9 +23,6 @@
using namespace std; using namespace std;
using namespace winstd; using namespace winstd;
static wxCriticalSection s_lock;
static unsigned long s_init_ref_count = 0;
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// wxInitializerPeer // wxInitializerPeer
@@ -38,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
}; };
@@ -186,9 +185,11 @@ void eap::peer_ttls_ui::invoke_identity_ui(
bool combined = false; bool combined = false;
wxEAPCredentialsConnectionDialog dlg(&parent); wxEAPCredentialsConnectionDialog dlg(&parent);
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) { 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()));
// Get method configuration. // Get method configuration.
if (cfg_prov->m_methods.empty()) { if (cfg_prov->m_methods.empty()) {
log_event(&EAPMETHOD_TRACE_EVT_CRED_NO_METHOD, event_data(cfg_prov->m_id), event_data::blank); log_event(&EAPMETHOD_TRACE_EVT_CRED_NO_METHOD, event_data(target_name), event_data::blank);
continue; continue;
} }
config_method_ttls *cfg_method = dynamic_cast<config_method_ttls*>(cfg_prov->m_methods.front().get()); config_method_ttls *cfg_method = dynamic_cast<config_method_ttls*>(cfg_prov->m_methods.front().get());
@@ -196,15 +197,16 @@ void eap::peer_ttls_ui::invoke_identity_ui(
// Prepare new set of credentials for given provider. // Prepare new set of credentials for given provider.
credentials_connection cred_method(*this, cfg); credentials_connection cred_method(*this, cfg);
cred_method.m_namespace = cfg_prov->m_namespace;
cred_method.m_id = cfg_prov->m_id; cred_method.m_id = cfg_prov->m_id;
credentials_ttls *_cred_method = (credentials_ttls*)cfg_method->make_credentials(); credentials_ttls *_cred_method = (credentials_ttls*)cfg_method->make_credentials();
cred_method.m_cred.reset(_cred_method); cred_method.m_cred.reset(_cred_method);
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE #ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
bool is_own = cred_in.m_cred && _wcsicmp(cred_in.m_id.c_str(), cfg_prov->m_id.c_str()) == 0; bool is_own = cred_in.m_cred && cred_in.match(*cfg_prov);
#endif #endif
// Combine outer credentials. // Combine outer credentials.
LPCTSTR target_name = (dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? cfg_prov->m_id.c_str() : NULL; 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( eap::credentials::source_t src_outer = _cred_method->credentials_tls::combine(
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE #ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
is_own ? cred_in.m_cred.get() : NULL, is_own ? cred_in.m_cred.get() : NULL,
@@ -212,7 +214,7 @@ void eap::peer_ttls_ui::invoke_identity_ui(
NULL, NULL,
#endif #endif
*cfg_method, *cfg_method,
target_name); _target_name);
// Combine inner credentials. // Combine inner credentials.
eap::credentials::source_t src_inner = _cred_method->m_inner->combine( eap::credentials::source_t src_inner = _cred_method->m_inner->combine(
@@ -222,7 +224,7 @@ void eap::peer_ttls_ui::invoke_identity_ui(
NULL, NULL,
#endif #endif
*cfg_method->m_inner, *cfg_method->m_inner,
target_name); _target_name);
if (dwFlags & EAP_FLAG_GUEST_ACCESS) { if (dwFlags & EAP_FLAG_GUEST_ACCESS) {
// Disable credential saving for guests. // Disable credential saving for guests.
@@ -231,7 +233,7 @@ void eap::peer_ttls_ui::invoke_identity_ui(
} }
// Create method credentials panel. // Create method credentials panel.
wxTTLSCredentialsPanel *panel = new wxTTLSCredentialsPanel(*cfg_prov, *cfg_method, *_cred_method, cfg_prov->m_id.c_str(), dlg.m_providers); wxTTLSCredentialsPanel *panel = new wxTTLSCredentialsPanel(*cfg_prov, *cfg_method, *_cred_method, dlg.m_providers);
// Set "Remember" checkboxes according to credential source, // Set "Remember" checkboxes according to credential source,
panel->m_outer_cred->SetRemember(src_outer == eap::credentials::source_storage); panel->m_outer_cred->SetRemember(src_outer == eap::credentials::source_storage);
@@ -263,11 +265,12 @@ void eap::peer_ttls_ui::invoke_identity_ui(
cfg_method = res.first; cfg_method = res.first;
cred_out = res.second; cred_out = res.second;
credentials_ttls *_cred_out = dynamic_cast<credentials_ttls*>(cred_out.m_cred.get()); credentials_ttls *_cred_out = dynamic_cast<credentials_ttls*>(cred_out.m_cred.get());
wstring target_name(std::move(cred_out.get_id()));
// Write credentials to credential manager. // Write credentials to credential manager.
if (panel->m_outer_cred->GetRemember()) { if (panel->m_outer_cred->GetRemember()) {
try { try {
_cred_out->credentials_tls::store(cred_out.m_id.c_str()); _cred_out->credentials_tls::store(target_name.c_str());
} catch (winstd::win_runtime_error &err) { } 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()); wxLogError(winstd::tstring_printf(_("Error writing credentials to Credential Manager: %hs (error %u)"), err.what(), err.number()).c_str());
} catch (...) { } catch (...) {
@@ -277,7 +280,7 @@ void eap::peer_ttls_ui::invoke_identity_ui(
if (panel->m_inner_cred->GetRemember()) { if (panel->m_inner_cred->GetRemember()) {
try { try {
_cred_out->m_inner->store(cred_out.m_id.c_str()); _cred_out->m_inner->store(target_name.c_str());
} catch (winstd::win_runtime_error &err) { } 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()); wxLogError(winstd::tstring_printf(_("Error writing credentials to Credential Manager: %hs (error %u)"), err.what(), err.number()).c_str());
} catch (...) { } catch (...) {
@@ -341,9 +344,9 @@ wxInitializerPeer::wxInitializerPeer(_In_ HINSTANCE 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"));
} }
} }
@@ -356,3 +359,8 @@ wxInitializerPeer::~wxInitializerPeer()
wxEntryCleanup(); wxEntryCleanup();
} }
wxCriticalSection wxInitializerPeer::s_lock;
unsigned long wxInitializerPeer::s_init_ref_count = 0;
wxLocale wxInitializerPeer::s_locale;

View File

@@ -26,6 +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> #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);