Compare commits

...

31 Commits

Author SHA1 Message Date
2339b6b347 Version set to 1.0-alpha16 2016-08-31 18:40:45 +02:00
171e924dcf Estimated flag to enable TLS 1.3 once available added 2016-08-31 18:40:28 +02:00
281c3ee083 Schannel tweaked to support TLS 1.2 now
(closes #16)
2016-08-31 18:13:24 +02:00
145c21682e Support for configuring provider ID using GUI added 2016-08-31 17:41:22 +02:00
0d221d4401 wxWidgets initialization reference counter introduced to prevent second initialization, as we recorded a case where EapHost called our GUI twice in the same DllHost.exe process. 2016-08-31 17:13:59 +02:00
d9bfcc3e49 Credential identities are more carefully prepared for display now 2016-08-31 16:50:12 +02:00
60f1b4ccfb Pre&post-processing of XML configuration introduced to allow draft-winter-opsawg-eap-metadata-02 compliant XML profiles on the outside, while maintaining internal simplicity 2016-08-31 16:33:19 +02:00
c9be6f4f7b Support for multiple identity providers of draft-winter-opsawg-eap-metadata XML configuration added 2016-08-31 14:39:27 +02:00
452fa4b9dc Inserting single-occurrence XML elements with children simplified 2016-08-31 09:48:11 +02:00
68aec5dfb4 Namespace name is static member now 2016-08-31 08:43:03 +02:00
3f49f3e975 Event Monitor shortcut description dropped as it will not be localized 2016-08-31 02:53:19 +02:00
04213715b0 UI texts updated 2016-08-31 01:25:44 +02:00
510bbe10f6 Template for creating XML configuration simplified 2016-08-31 00:41:16 +02:00
5dfd079686 Support for multi-provider management added to GUI 2016-08-31 00:36:19 +02:00
858486412e Confusion between provider ID and provider name resolved 2016-08-30 21:10:10 +02:00
8b266f086f Code clean-up 2016-08-30 17:44:21 +02:00
c40306c624 <Error getting property (error 13)> issue with log parameters solved 2016-08-30 17:43:56 +02:00
24c10b592b Version set to 1.0-alpha15 2016-08-29 20:47:01 +02:00
cafd786e19 Own TLS updated to keep it alive (now that the fuss around outer/inner methods settled) 2016-08-29 20:40:37 +02:00
a7c8052ee2 eap::method revised to support nesting, so the PAP method was made a stand-alone method 2016-08-29 20:05:58 +02:00
a33da0d8d5 CredWrite stores an empty set of credentials for TLS now, avoiding initial credential prompt 2016-08-29 15:11:58 +02:00
91f87aa3c7 WLANManager is deployed separately now 2016-08-29 15:10:27 +02:00
b6ae394eaf User identity derived from certificate is using sAN2 and sAN extensions only now 2016-08-29 13:51:19 +02:00
79499d7afd i and i disambiguation 2016-08-29 13:50:36 +02:00
92f05817fe A desperate attempt to make events shown on non-English Windows 2016-08-29 13:14:09 +02:00
a85833d41d Stale resource cleanup 2016-08-29 12:05:39 +02:00
8a8e6d08e0 Events.dll have missing VERSIONINFO resource now 2016-08-29 11:58:10 +02:00
aa7c5bebda Outer and inner TTLS credentials are combined separately now to provide finer feedback for more accurate logging (again) 2016-08-29 09:27:32 +02:00
ceece01b99 In case of previously-failed authentication attempts we are more careful now not to request credential prompt for machine authentication 2016-08-29 09:25:38 +02:00
1d46db348a Sub-module update 2016-08-29 09:23:50 +02:00
48a7ce91c3 UI text updated 2016-08-28 23:14:59 +02:00
52 changed files with 3216 additions and 953 deletions

View File

@@ -107,6 +107,9 @@
<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>
<ProjectReference Include="..\lib\TLS\build\TLS.vcxproj">
<Project>{4d40cb8a-812e-4f12-b23a-31af743878e8}</Project>
</ProjectReference>
<ProjectReference Include="..\lib\WinStd\build\WinStd.vcxproj"> <ProjectReference Include="..\lib\WinStd\build\WinStd.vcxproj">
<Project>{47399d91-7eb9-41de-b521-514ba5db0c43}</Project> <Project>{47399d91-7eb9-41de-b521-514ba5db0c43}</Project>
</ProjectReference> </ProjectReference>

View File

@@ -40,7 +40,7 @@ static int CredWrite()
return -1; return -1;
} }
eap::credentials_pap cred(g_module); eap::credentials_pap cred_pap(g_module);
// Prepare identity (user name). // Prepare identity (user name).
{ {
@@ -50,7 +50,7 @@ static int CredWrite()
bool is_last; bool is_last;
dec.decode(identity_utf8, is_last, pwcArglist[1], (size_t)-1); dec.decode(identity_utf8, is_last, pwcArglist[1], (size_t)-1);
MultiByteToWideChar(CP_UTF8, 0, identity_utf8.data(), (int)identity_utf8.size(), cred.m_identity); MultiByteToWideChar(CP_UTF8, 0, identity_utf8.data(), (int)identity_utf8.size(), cred_pap.m_identity);
} }
// Prepare password. // Prepare password.
@@ -61,7 +61,7 @@ static int CredWrite()
bool is_last; bool is_last;
dec.decode(password_utf8, is_last, pwcArglist[2], (size_t)-1); dec.decode(password_utf8, is_last, pwcArglist[2], (size_t)-1);
MultiByteToWideChar(CP_UTF8, 0, password_utf8.data(), (int)password_utf8.size(), cred.m_password); MultiByteToWideChar(CP_UTF8, 0, password_utf8.data(), (int)password_utf8.size(), cred_pap.m_password);
} }
// Generate target name (aka realm). // Generate target name (aka realm).
@@ -71,7 +71,7 @@ static int CredWrite()
target_name = pwcArglist[3]; target_name = pwcArglist[3];
} else { } else {
// Get the realm from user name. // Get the realm from user name.
LPCWSTR _identity = cred.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 = domain + 1;
else if ((domain = wcschr(_identity, L'\\')) != NULL) else if ((domain = wcschr(_identity, L'\\')) != NULL)
@@ -94,7 +94,7 @@ static int CredWrite()
} }
#endif #endif
try { try {
cred.store(target_name.c_str()); cred_pap.store(target_name.c_str());
} catch(win_runtime_error &err) { } catch(win_runtime_error &err) {
OutputDebugStr(_T("%hs (error %u)\n"), err.what(), err.number()); OutputDebugStr(_T("%hs (error %u)\n"), err.what(), err.number());
return 2; return 2;
@@ -103,6 +103,18 @@ static int CredWrite()
return 2; return 2;
} }
// Store empty TLS credentials.
eap::credentials_tls cred_tls(g_module);
try {
cred_tls.store(target_name.c_str());
} catch(win_runtime_error &err) {
OutputDebugStr(_T("%hs (error %u)\n"), err.what(), err.number());
return 3;
} catch(...) {
OutputDebugStr(_T("Writing credentials failed.\n"));
return 3;
}
return 0; return 0;
} }

View File

@@ -20,8 +20,8 @@
#pragma once #pragma once
#include "../lib/PAP/include/Config.h"
#include "../lib/PAP/include/Credentials.h" #include "../lib/PAP/include/Credentials.h"
#include "../lib/TLS/include/Credentials.h"
#include "../lib/EAPBase/include/Module.h" #include "../lib/EAPBase/include/Module.h"
#include <WinStd/Common.h> #include <WinStd/Common.h>

Binary file not shown.

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-25 10:43+0200\n" "POT-Creation-Date: 2016-08-31 17:41+0200\n"
"PO-Revision-Date: 2016-06-02 12:27+0200\n" "PO-Revision-Date: 2016-06-02 12:27+0200\n"
"Last-Translator: Simon Rozman <simon.rozman@amebis.si>\n" "Last-Translator: Simon Rozman <simon.rozman@amebis.si>\n"
"Language-Team: Amebis, d. o. o., Kamnik <info@amebis.si>\n" "Language-Team: Amebis, d. o. o., Kamnik <info@amebis.si>\n"
@@ -20,201 +20,242 @@ msgstr ""
"X-Poedit-SearchPath-4: EAPMethods\n" "X-Poedit-SearchPath-4: EAPMethods\n"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:37 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:37
msgid "Advanced..." msgid "+"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:38 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:38
msgid "Adds new provider"
msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:42
msgid "-"
msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:43
msgid "Removes selected provider"
msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:47
msgid "Advanced..."
msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:48
msgid "Opens dialog with provider settings" msgid "Opens dialog with provider settings"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:174 lib/EAPBase_UI/res/wxEAP_UI.cpp:296 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:230 lib/EAPBase_UI/res/wxEAP_UI.cpp:355
msgid "Client Credentials" msgid "Client Credentials"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:185 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:241
msgid "Manage credentials used to connect." msgid "Manage credentials used to connect."
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:198 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:254
msgid "Use &own credentials:" msgid "Use &own credentials:"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:199 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:255
msgid "Select this option if you have your unique credentials to connect" msgid "Select this option if you have your unique credentials to connect"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:204 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:260
msgid "Your credentials loaded from Windows Credential Manager" msgid "Your credentials loaded from Windows Credential Manager"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:214 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:270
msgid "&Clear Credentials" msgid "&Clear Credentials"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:215 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:271
msgid "" msgid ""
"Click to clear your credentials from Credential Manager.\n" "Click to clear your credentials from Credential Manager.\n"
"Note: You will be prompted to enter credentials when connecting." "Note: You will be prompted to enter credentials when connecting."
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:219 lib/EAPBase_UI/res/wxEAP_UI.cpp:252 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:275 lib/EAPBase_UI/res/wxEAP_UI.cpp:308
msgid "&Set Credentials..." msgid "&Set Credentials..."
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:220 lib/EAPBase_UI/res/wxEAP_UI.cpp:253 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:276 lib/EAPBase_UI/res/wxEAP_UI.cpp:309
msgid "Click here to set or modify your credentials" msgid "Click here to set or modify your credentials"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:236 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:292
msgid "Use &pre-shared credentials:" msgid "Use &pre-shared credentials:"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:237 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:293
msgid "Select this options if all clients connect using the same credentials" msgid "Select this options if all clients connect using the same credentials"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:242 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:298
msgid "Common (pre-shared) credentials" msgid "Common (pre-shared) credentials"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:307 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:366
msgid "Please provide your user ID and password." msgid "Please provide your user ID and password."
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:317 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:376
msgid "User ID:" msgid "User ID:"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:322 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:381
msgid "Enter your user name here (user@domain.org, DOMAIN\\User, etc.)" msgid "Enter your user name here (user@domain.org, DOMAIN\\User, etc.)"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:326 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:385
msgid "Password:" msgid "Password:"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:331 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:390
msgid "Enter your password here" msgid "Enter your password here"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:338 lib/TLS_UI/res/wxTLS_UI.cpp:183 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:397 lib/TLS_UI/res/wxTLS_UI.cpp:183
msgid "&Remember" msgid "&Remember"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:339 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:398
msgid "Check if you would like to save username and password" msgid "Check if you would like to save username and password"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:361 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:420
msgid "Your Organization" msgid "Your Organization"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:372 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:431
msgid "Describe your organization to customize user prompts. When organization is introduced, end-users find program messages easier to understand and act." msgid "Describe your organization to customize user prompts. When organization is introduced, end-users find program messages easier to understand and act."
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:379 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:438
msgid "Your organization &name:" msgid "Your organization &name:"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:384 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:443
msgid "Your organization name as it will appear on helpdesk contact notifications" msgid "Your organization name as it will appear on helpdesk contact notifications"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:388 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:447
msgid "(Keep it short, please)" msgid "(Keep it short, please)"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:398 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:457
msgid "Helpdesk contact &information:" msgid "Helpdesk contact &information:"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:408 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:467
msgid "¶" msgid "¶"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:415 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:474
msgid "Your helpdesk website address" msgid "Your helpdesk website address"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:419 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:478
msgid "*" msgid "*"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:426 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:485
msgid "Your helpdesk e-mail address" msgid "Your helpdesk e-mail address"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:430 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:489
msgid ")" msgid ")"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:437 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:496
msgid "Your helpdesk phone number" msgid "Your helpdesk phone number"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:471 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:524
msgid "Provider Unique Identifier"
msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:535
msgid "Assign your organization a unique ID to allow sharing the same credential set across different network profiles."
msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:542
msgid "Provider unique &identifier:"
msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:547
msgid "Your organization ID to assign same credentials from other profiles"
msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:551
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:482 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:587
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:489 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:594
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:492 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:597
msgid "(Warning: Once locked, you can not revert using this dialog!)" msgid "(Warning: Once locked, you can not revert using this dialog!)"
msgstr "" msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:88 #: lib/EAPBase_UI/src/EAP_UI.cpp:98
#, c-format #, c-format
msgid "%s Credentials" msgid "%s Credentials"
msgstr "" msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:118 #: lib/EAPBase_UI/src/EAP_UI.cpp:123 lib/EAPBase_UI/include/EAP_UI.h:351
#: lib/EAPBase_UI/include/EAP_UI.h:361 lib/EAPBase_UI/res/wxEAP_UI.h:118
msgid "EAP Credentials"
msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:166
#, c-format #, c-format
msgid "For additional help and instructions, please contact %s at:" msgid "For additional help and instructions, please contact %s at:"
msgstr "" msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:120 #: lib/EAPBase_UI/src/EAP_UI.cpp:168
#, c-format #, c-format
msgid "your %ls provider" msgid "your %ls provider"
msgstr "" msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:120 #: lib/EAPBase_UI/src/EAP_UI.cpp:168
msgid "your provider" msgid "your provider"
msgstr "" msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:139 #: lib/EAPBase_UI/src/EAP_UI.cpp:187
msgid "Open the default web browser" msgid "Open the default web browser"
msgstr "" msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:150 #: lib/EAPBase_UI/src/EAP_UI.cpp:198
msgid "Open your e-mail program" msgid "Open your e-mail program"
msgstr "" msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:161 #: lib/EAPBase_UI/src/EAP_UI.cpp:209
msgid "Dial the phone number" msgid "Dial the phone number"
msgstr "" msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:180 #: lib/EAPBase_UI/src/EAP_UI.cpp:229
#, 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:182 #: lib/EAPBase_UI/src/EAP_UI.cpp:231
#, c-format #, c-format
msgid "Your %ls provider" msgid "Your %ls provider"
msgstr "" msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:182 #: lib/EAPBase_UI/src/EAP_UI.cpp:231
msgid "Your provider" msgid "Your provider"
msgstr "" msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:201 #: lib/EAPBase_UI/src/EAP_UI.cpp:251
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 ""
@@ -323,32 +364,32 @@ msgstr ""
msgid "Validation conflict" msgid "Validation conflict"
msgstr "" msgstr ""
#: lib/TLS_UI/src/TLS_UI.cpp:514 #: lib/TLS_UI/src/TLS_UI.cpp:511
msgid "Add Certificate" msgid "Add Certificate"
msgstr "" msgstr ""
#: lib/TLS_UI/src/TLS_UI.cpp:515 #: lib/TLS_UI/src/TLS_UI.cpp:512
msgid "Certificate Files (*.cer;*.crt;*.der;*.p7b;*.pem)" msgid "Certificate Files (*.cer;*.crt;*.der;*.p7b;*.pem)"
msgstr "" msgstr ""
#: lib/TLS_UI/src/TLS_UI.cpp:516 #: lib/TLS_UI/src/TLS_UI.cpp:513
msgid "X.509 Certificate Files (*.cer;*.crt;*.der;*.pem)" msgid "X.509 Certificate Files (*.cer;*.crt;*.der;*.pem)"
msgstr "" msgstr ""
#: lib/TLS_UI/src/TLS_UI.cpp:517 #: lib/TLS_UI/src/TLS_UI.cpp:514
msgid "PKCS #7 Certificate Files (*.p7b)" msgid "PKCS #7 Certificate Files (*.p7b)"
msgstr "" msgstr ""
#: lib/TLS_UI/src/TLS_UI.cpp:518 #: lib/TLS_UI/src/TLS_UI.cpp:515
msgid "All Files (*.*)" msgid "All Files (*.*)"
msgstr "" msgstr ""
#: lib/TLS_UI/src/TLS_UI.cpp:534 #: lib/TLS_UI/src/TLS_UI.cpp:531
#, c-format #, c-format
msgid "Invalid or unsupported certificate file %s" msgid "Invalid or unsupported certificate file %s"
msgstr "" msgstr ""
#: lib/TLS_UI/src/TLS_UI.cpp:534 #: lib/TLS_UI/src/TLS_UI.cpp:531
msgid "Error" msgid "Error"
msgstr "" msgstr ""
@@ -388,70 +429,74 @@ msgstr ""
msgid "Custom outer identity to use" msgid "Custom outer identity to use"
msgstr "" msgstr ""
#: lib/TTLS_UI/src/Module.cpp:231 lib/TTLS_UI/src/Module.cpp:241 #: lib/TTLS_UI/src/Module.cpp:272 lib/TTLS_UI/src/Module.cpp:282
#: lib/EAPBase_UI/include/EAP_UI.h:582 #: lib/EAPBase_UI/include/EAP_UI.h:690
#, 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:233 lib/TTLS_UI/src/Module.cpp:243 #: lib/TTLS_UI/src/Module.cpp:274 lib/TTLS_UI/src/Module.cpp:284
#: lib/EAPBase_UI/include/EAP_UI.h:584 #: lib/EAPBase_UI/include/EAP_UI.h:693
msgid "Writing credentials failed." msgid "Writing credentials failed."
msgstr "" msgstr ""
#: lib/TTLS_UI/src/TTLS_UI.cpp:108 lib/TTLS_UI/src/TTLS_UI.cpp:215 #: lib/TTLS_UI/src/TTLS_UI.cpp:107 lib/TTLS_UI/src/TTLS_UI.cpp:220
msgid "Inner Authentication" msgid "Inner Authentication"
msgstr "" msgstr ""
#: lib/TTLS_UI/src/TTLS_UI.cpp:114 #: lib/TTLS_UI/src/TTLS_UI.cpp:113
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:116 #: lib/TTLS_UI/src/TTLS_UI.cpp:115
msgid "PAP" msgid "PAP"
msgstr "" msgstr ""
#: lib/TTLS_UI/src/TTLS_UI.cpp:121 lib/TTLS_UI/src/TTLS_UI.cpp:236 #: lib/TTLS_UI/src/TTLS_UI.cpp:120 lib/TTLS_UI/src/TTLS_UI.cpp:241
msgid "Outer Authentication" msgid "Outer Authentication"
msgstr "" msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:253 #: lib/EAPBase_UI/include/EAP_UI.h:288
msgid "EAP Credentials" #, c-format
msgid "Are you sure you want to permanently remove %ls provider from configuration?"
msgstr "" msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:422 #: lib/EAPBase_UI/include/EAP_UI.h:288
msgid "Warning"
msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:548
msgid "Provider Settings" msgid "Provider Settings"
msgstr "" msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:502 lib/EAPBase_UI/include/EAP_UI.h:529 #: lib/EAPBase_UI/include/EAP_UI.h:706
msgid "<blank>"
msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:508
#, c-format
msgid "<error %u>"
msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:568
#, c-format
msgid "Error reading credentials from Credential Manager: %hs (error %u)"
msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:570
msgid "Reading credentials failed."
msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:595
#, 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:817 #: lib/EAPBase_UI/include/EAP_UI.h:739
#, c-format
msgid "<error %u>"
msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:743
msgid "<error>"
msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:754 lib/EAPBase_UI/include/EAP_UI.h:763
msgid "<empty>"
msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:754 lib/EAPBase_UI/include/EAP_UI.h:763
msgid "<blank ID>"
msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:968
msgid "<Your Organization>" msgid "<Your Organization>"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.h:60 #: lib/EAPBase_UI/res/wxEAP_UI.h:68
msgid "EAP Method Configuration" msgid "EAP Connection Configuration"
msgstr "" msgstr ""
#: EAPMethods/MSIBuild/En.Win32.Release.Feature-2.idtx:3 #: EAPMethods/MSIBuild/En.Win32.Release.Feature-2.idtx:3

View File

@@ -3,7 +3,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: EAPMethods\n" "Project-Id-Version: EAPMethods\n"
"POT-Creation-Date: 2016-08-25 10:43+0200\n" "POT-Creation-Date: 2016-08-28 23: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"
@@ -30,7 +30,7 @@ msgstr "Napredno ..."
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:296 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:174 lib/EAPBase_UI/res/wxEAP_UI.cpp:299
msgid "Client Credentials" msgid "Client Credentials"
msgstr "Odjemalčeve poverilnice" msgstr "Odjemalčeve poverilnice"
@@ -84,39 +84,39 @@ msgstr ""
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:307 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:310
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:317 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:320
msgid "User ID:" msgid "User ID:"
msgstr "Uporabniški ID:" msgstr "Uporabniški ID:"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:322 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:325
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:326 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:329
msgid "Password:" msgid "Password:"
msgstr "Geslo:" msgstr "Geslo:"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:331 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:334
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:338 lib/TLS_UI/res/wxTLS_UI.cpp:183 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:341 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:339 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:342
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:361 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:364
msgid "Your Organization" msgid "Your Organization"
msgstr "Vaša organizacija" msgstr "Vaša organizacija"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:372 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:375
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 +125,54 @@ 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:379 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:382
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:384 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:387
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:388 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:391
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:398 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:401
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:408 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:411
msgid "¶" msgid "¶"
msgstr "¶" msgstr "¶"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:415 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:418
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:419 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:422
msgid "*" msgid "*"
msgstr "*" msgstr "*"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:426 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:429
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:430 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:433
msgid ")" msgid ")"
msgstr ")" msgstr ")"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:437 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:440
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:471 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:468
msgid "Configuration Lock" msgid "Configuration Lock"
msgstr "Zaklep konfiguracije" msgstr "Zaklep konfiguracije"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:482 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:479
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 +180,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:489 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:486
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,42 +188,42 @@ 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:492 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:489
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!)"
#: lib/EAPBase_UI/src/EAP_UI.cpp:88 #: lib/EAPBase_UI/src/EAP_UI.cpp:98
#, c-format #, c-format
msgid "%s Credentials" msgid "%s Credentials"
msgstr "Poverilnice za %s" msgstr "Poverilnice za %s"
#: lib/EAPBase_UI/src/EAP_UI.cpp:118 #: lib/EAPBase_UI/src/EAP_UI.cpp:128
#, 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:120 #: lib/EAPBase_UI/src/EAP_UI.cpp:130
#, c-format #, c-format
msgid "your %ls provider" msgid "your %ls provider"
msgstr "vaš ponudnik %ls" msgstr "vaš ponudnik %ls"
#: lib/EAPBase_UI/src/EAP_UI.cpp:120 #: 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:139 #: lib/EAPBase_UI/src/EAP_UI.cpp:149
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:150 #: lib/EAPBase_UI/src/EAP_UI.cpp:160
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:161 #: lib/EAPBase_UI/src/EAP_UI.cpp:171
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:180 #: lib/EAPBase_UI/src/EAP_UI.cpp:191
#, 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 +232,16 @@ 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:182 #: lib/EAPBase_UI/src/EAP_UI.cpp:193
#, c-format #, c-format
msgid "Your %ls provider" msgid "Your %ls provider"
msgstr "Vaš ponudnik %ls" msgstr "Vaš ponudnik %ls"
#: lib/EAPBase_UI/src/EAP_UI.cpp:182 #: 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:201 #: lib/EAPBase_UI/src/EAP_UI.cpp:213
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."
@@ -371,32 +371,32 @@ msgstr "Napačen znak v imenu gostitelja: %c"
msgid "Validation conflict" msgid "Validation conflict"
msgstr "Nesoglasje pri preverjanju" msgstr "Nesoglasje pri preverjanju"
#: lib/TLS_UI/src/TLS_UI.cpp:514 #: lib/TLS_UI/src/TLS_UI.cpp:511
msgid "Add Certificate" msgid "Add Certificate"
msgstr "Dodaj potrdilo" msgstr "Dodaj potrdilo"
#: lib/TLS_UI/src/TLS_UI.cpp:515 #: lib/TLS_UI/src/TLS_UI.cpp:512
msgid "Certificate Files (*.cer;*.crt;*.der;*.p7b;*.pem)" msgid "Certificate Files (*.cer;*.crt;*.der;*.p7b;*.pem)"
msgstr "Datoteke s potrdili (*.cer;*.crt;*.der;*.p7b;*.pem)" msgstr "Datoteke s potrdili (*.cer;*.crt;*.der;*.p7b;*.pem)"
#: lib/TLS_UI/src/TLS_UI.cpp:516 #: lib/TLS_UI/src/TLS_UI.cpp:513
msgid "X.509 Certificate Files (*.cer;*.crt;*.der;*.pem)" msgid "X.509 Certificate Files (*.cer;*.crt;*.der;*.pem)"
msgstr "Datoteke s potrdili X.509 (*.cer;*.crt;*.der;*.pem)" msgstr "Datoteke s potrdili X.509 (*.cer;*.crt;*.der;*.pem)"
#: lib/TLS_UI/src/TLS_UI.cpp:517 #: lib/TLS_UI/src/TLS_UI.cpp:514
msgid "PKCS #7 Certificate Files (*.p7b)" msgid "PKCS #7 Certificate Files (*.p7b)"
msgstr "Datoteke s potrdili PKCS #7 (*.p7b)" msgstr "Datoteke s potrdili PKCS #7 (*.p7b)"
#: lib/TLS_UI/src/TLS_UI.cpp:518 #: lib/TLS_UI/src/TLS_UI.cpp:515
msgid "All Files (*.*)" msgid "All Files (*.*)"
msgstr "Vse datoteke (*.*)" msgstr "Vse datoteke (*.*)"
#: lib/TLS_UI/src/TLS_UI.cpp:534 #: lib/TLS_UI/src/TLS_UI.cpp:531
#, c-format #, c-format
msgid "Invalid or unsupported certificate file %s" msgid "Invalid or unsupported certificate file %s"
msgstr "Napačna ali nepodprta datoteka s potrdilom %s" msgstr "Napačna ali nepodprta datoteka s potrdilom %s"
#: lib/TLS_UI/src/TLS_UI.cpp:534 #: lib/TLS_UI/src/TLS_UI.cpp:531
msgid "Error" msgid "Error"
msgstr "Napaka" msgstr "Napaka"
@@ -438,71 +438,69 @@ 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:231 lib/TTLS_UI/src/Module.cpp:241 #: lib/TTLS_UI/src/Module.cpp:249 lib/TTLS_UI/src/Module.cpp:259
#: lib/EAPBase_UI/include/EAP_UI.h:582 #: lib/EAPBase_UI/include/EAP_UI.h:584
#, 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:233 lib/TTLS_UI/src/Module.cpp:243 #: lib/TTLS_UI/src/Module.cpp:251 lib/TTLS_UI/src/Module.cpp:261
#: lib/EAPBase_UI/include/EAP_UI.h:584 #: lib/EAPBase_UI/include/EAP_UI.h:587
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:108 lib/TTLS_UI/src/TTLS_UI.cpp:215 #: lib/TTLS_UI/src/TTLS_UI.cpp:107 lib/TTLS_UI/src/TTLS_UI.cpp:220
msgid "Inner Authentication" msgid "Inner Authentication"
msgstr "Notranje overovljanje" msgstr "Notranje overovljanje"
#: lib/TTLS_UI/src/TTLS_UI.cpp:114 #: lib/TTLS_UI/src/TTLS_UI.cpp:113
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:116 #: lib/TTLS_UI/src/TTLS_UI.cpp:115
msgid "PAP" msgid "PAP"
msgstr "PAP" msgstr "PAP"
#: lib/TTLS_UI/src/TTLS_UI.cpp:121 lib/TTLS_UI/src/TTLS_UI.cpp:236 #: lib/TTLS_UI/src/TTLS_UI.cpp:120 lib/TTLS_UI/src/TTLS_UI.cpp:241
msgid "Outer Authentication" msgid "Outer Authentication"
msgstr "Zunanje overovljanje" msgstr "Zunanje overovljanje"
#: lib/EAPBase_UI/include/EAP_UI.h:253 #: lib/EAPBase_UI/include/EAP_UI.h:283
msgid "EAP Credentials" msgid "EAP Credentials"
msgstr "Poverilnice EAP" msgstr "Poverilnice EAP"
#: lib/EAPBase_UI/include/EAP_UI.h:422 #: lib/EAPBase_UI/include/EAP_UI.h:443
msgid "Provider Settings" msgid "Provider Settings"
msgstr "Nastavitve ponudnika" msgstr "Nastavitve ponudnika"
#: lib/EAPBase_UI/include/EAP_UI.h:502 lib/EAPBase_UI/include/EAP_UI.h:529 #: lib/EAPBase_UI/include/EAP_UI.h:600
msgid "<blank>"
msgstr "<prazno>"
#: lib/EAPBase_UI/include/EAP_UI.h:508
#, c-format
msgid "<error %u>"
msgstr "<napaka %u>"
#: lib/EAPBase_UI/include/EAP_UI.h:568
#, c-format
msgid "Error reading credentials from Credential Manager: %hs (error %u)"
msgstr ""
"Napaka pri branju poverilnic iz upravitelja poverilnic: %hs (napaka %u)"
#: lib/EAPBase_UI/include/EAP_UI.h:570
msgid "Reading credentials failed."
msgstr "Branje poverilnic ni uspelo."
#: lib/EAPBase_UI/include/EAP_UI.h:595
#, 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:817 #: lib/EAPBase_UI/include/EAP_UI.h:633
#, c-format
msgid "<error %u>"
msgstr "<napaka %u>"
#: lib/EAPBase_UI/include/EAP_UI.h:637
msgid "<error>"
msgstr "<napaka>"
#: lib/EAPBase_UI/include/EAP_UI.h:646 lib/EAPBase_UI/include/EAP_UI.h:657
msgid "<empty credentials>"
msgstr "<prazne poverilnice>"
#: lib/EAPBase_UI/include/EAP_UI.h:649 lib/EAPBase_UI/include/EAP_UI.h:660
msgid "<blank identity>"
msgstr "<prazna identiteta>"
#: lib/EAPBase_UI/include/EAP_UI.h:866
msgid "<Your Organization>" msgid "<Your Organization>"
msgstr "<vaša organizacija>" msgstr "<vaša organizacija>"
#: lib/EAPBase_UI/res/wxEAP_UI.h:60 #: lib/EAPBase_UI/res/wxEAP_UI.h:64
msgid "EAP Method Configuration" msgid "EAP Method Configuration"
msgstr "Konfiguracija postopka EAP" msgstr "Konfiguracija postopka EAP"

View File

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

View File

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

Binary file not shown.

View File

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

View File

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

BIN
Makefile

Binary file not shown.

Binary file not shown.

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 0x00ff0e00 #define PRODUCT_VERSION 0x00ff1000
// //
// 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 14 #define PRODUCT_VERSION_REV 16
#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-alpha14" #define PRODUCT_VERSION_STR "1.0-alpha16"
#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.14" #define PRODUCT_VERSION_INST "0.255.16"
// //
// The product code for ProductCode property in MSI packages // The product code for ProductCode property in MSI packages
// Replace with new on every version change, regardless how minor it is. // Replace with new on every version change, regardless how minor it is.
// //
#define PRODUCT_VERSION_GUID "{2C45C10E-80B7-4E3B-A06F-08A1A795EDE5}" #define PRODUCT_VERSION_GUID "{A41E8D8D-8A6F-415E-B303-C839E2C8A931}"
// //
// Product vendor // Product vendor

View File

@@ -89,6 +89,7 @@ inline void operator>>(_Inout_ eap::cursor_in &cursor, _Out_ eap::config &val);
#include <eaptypes.h> // Must include after <Windows.h> #include <eaptypes.h> // Must include after <Windows.h>
#include <tchar.h> #include <tchar.h>
#include <list>
#include <string> #include <string>
#include <memory> #include <memory>
@@ -192,6 +193,9 @@ namespace eap
public: public:
module &m_module; ///< EAP module module &m_module; ///< EAP module
protected:
static const winstd::bstr namespace_eapmetadata;
}; };
@@ -452,7 +456,7 @@ namespace eap
public: public:
bool m_read_only; ///< Is profile read-only bool m_read_only; ///< Is profile read-only
std::wstring m_id; ///< Profile ID std::wstring m_id; ///< Provider ID
winstd::tstring m_name; ///< Provider name winstd::tstring m_name; ///< Provider name
winstd::tstring m_help_email; ///< Helpdesk e-mail winstd::tstring m_help_email; ///< Helpdesk e-mail
winstd::tstring m_help_web; ///< Helpdesk website URL winstd::tstring m_help_web; ///< Helpdesk website URL
@@ -466,6 +470,9 @@ namespace eap
class config_connection : public config class config_connection : public config
{ {
public:
typedef std::list<eap::config_provider> provider_list;
public: public:
/// ///
/// Constructs configuration /// Constructs configuration
@@ -560,7 +567,7 @@ namespace eap
/// @} /// @}
public: public:
std::vector<eap::config_provider> m_providers; ///< Array of provider configurations std::list<eap::config_provider> m_providers; ///< Provider configurations
}; };
} }

View File

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

View File

@@ -51,11 +51,10 @@ namespace eap
/// Constructs an EAP method /// Constructs an EAP method
/// ///
/// \param[in] mod EAP module to use for global services /// \param[in] mod EAP module to use for global services
/// \param[in] cfg Connection configuration /// \param[in] cfg Method configuration
/// \param[in] cred User credentials /// \param[in] cred User credentials
/// ///
method(_In_ module &module, _In_ config_connection &cfg, _In_ credentials &cred); method(_In_ module &module, _In_ config_method_with_cred &cfg, _In_ credentials &cred);
/// ///
/// Moves an EAP method /// Moves an EAP method
@@ -131,7 +130,8 @@ namespace eap
public: public:
module &m_module; ///< EAP module module &m_module; ///< EAP module
config_connection &m_cfg; ///< Connection configuration config_method_with_cred &m_cfg; ///< Connection configuration
credentials &m_cred; ///< User credentials credentials &m_cred; ///< User credentials
std::vector<winstd::eap_attr> m_eap_attr; ///< EAP attributes
}; };
} }

View File

@@ -95,6 +95,9 @@ void eap::config::operator>>(_Inout_ cursor_in &cursor)
} }
const bstr eap::config::namespace_eapmetadata(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata");
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// eap::config_method // eap::config_method
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
@@ -156,11 +159,11 @@ eap::config_method_with_cred::config_method_with_cred(_In_ const config_method_w
eap::config_method_with_cred::config_method_with_cred(_Inout_ config_method_with_cred &&other) : eap::config_method_with_cred::config_method_with_cred(_Inout_ config_method_with_cred &&other) :
m_allow_save(std::move(other.m_allow_save)), m_allow_save (std::move(other.m_allow_save )),
m_use_preshared(std::move(other.m_use_preshared)), m_use_preshared(std::move(other.m_use_preshared)),
m_preshared(std::move(other.m_preshared)), m_preshared (std::move(other.m_preshared )),
m_auth_failed(std::move(other.m_auth_failed)), m_auth_failed (std::move(other.m_auth_failed )),
config_method(std::move(other)) config_method (std::move(other ))
{ {
} }
@@ -198,16 +201,15 @@ void eap::config_method_with_cred::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOM
assert(pDoc); assert(pDoc);
assert(pConfigRoot); assert(pConfigRoot);
const winstd::bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata");
HRESULT hr; HRESULT hr;
// <ClientSideCredential> // <ClientSideCredential>
winstd::com_obj<IXMLDOMElement> pXmlElClientSideCredential; winstd::com_obj<IXMLDOMElement> pXmlElClientSideCredential;
if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, winstd::bstr(L"eap-metadata:ClientSideCredential"), winstd::bstr(L"ClientSideCredential"), bstrNamespace, &pXmlElClientSideCredential))) if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, winstd::bstr(L"eap-metadata:ClientSideCredential"), winstd::bstr(L"ClientSideCredential"), namespace_eapmetadata, &pXmlElClientSideCredential)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <ClientSideCredential> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <ClientSideCredential> element.");
// <ClientSideCredential>/<allow-save> // <ClientSideCredential>/<allow-save>
if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElClientSideCredential, winstd::bstr(L"allow-save"), bstrNamespace, m_allow_save))) if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElClientSideCredential, winstd::bstr(L"allow-save"), namespace_eapmetadata, m_allow_save)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <allow-save> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <allow-save> element.");
if (m_use_preshared) if (m_use_preshared)
@@ -285,16 +287,16 @@ 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_read_only (other.m_read_only ),
m_id(other.m_id), m_id (other.m_id ),
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 ),
m_help_phone(other.m_help_phone), m_help_phone (other.m_help_phone ),
m_lbl_alt_credential(other.m_lbl_alt_credential), m_lbl_alt_credential(other.m_lbl_alt_credential),
m_lbl_alt_identity(other.m_lbl_alt_identity), m_lbl_alt_identity (other.m_lbl_alt_identity ),
m_lbl_alt_password(other.m_lbl_alt_password), m_lbl_alt_password (other.m_lbl_alt_password ),
config(other) config (other )
{ {
m_methods.reserve(other.m_methods.size()); m_methods.reserve(other.m_methods.size());
for (vector<unique_ptr<config_method> >::const_iterator method = other.m_methods.cbegin(), method_end = other.m_methods.cend(); method != method_end; ++method) for (vector<unique_ptr<config_method> >::const_iterator method = other.m_methods.cbegin(), method_end = other.m_methods.cend(); method != method_end; ++method)
@@ -303,17 +305,17 @@ 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_read_only (std::move(other.m_read_only )),
m_id(std::move(other.m_id)), m_id (std::move(other.m_id )),
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 )),
m_help_phone(std::move(other.m_help_phone)), m_help_phone (std::move(other.m_help_phone )),
m_lbl_alt_credential(std::move(other.m_lbl_alt_credential)), m_lbl_alt_credential(std::move(other.m_lbl_alt_credential)),
m_lbl_alt_identity(std::move(other.m_lbl_alt_identity)), m_lbl_alt_identity (std::move(other.m_lbl_alt_identity )),
m_lbl_alt_password(std::move(other.m_lbl_alt_password)), m_lbl_alt_password (std::move(other.m_lbl_alt_password )),
m_methods(std::move(other.m_methods)), m_methods (std::move(other.m_methods )),
config(std::move(other)) config (std::move(other ))
{ {
} }
@@ -345,17 +347,17 @@ eap::config_provider& eap::config_provider::operator=(_In_ const config_provider
eap::config_provider& eap::config_provider::operator=(_Inout_ config_provider &&other) eap::config_provider& eap::config_provider::operator=(_Inout_ config_provider &&other)
{ {
if (this != &other) { if (this != &other) {
(config&&)*this = std::move(other); (config&&)*this = std::move(other );
m_read_only = std::move(m_read_only); m_read_only = std::move(other.m_read_only );
m_id = std::move(other.m_id); m_id = std::move(other.m_id );
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 );
m_help_phone = std::move(other.m_help_phone); m_help_phone = std::move(other.m_help_phone );
m_lbl_alt_credential = std::move(other.m_lbl_alt_credential); m_lbl_alt_credential = std::move(other.m_lbl_alt_credential);
m_lbl_alt_identity = std::move(other.m_lbl_alt_identity); m_lbl_alt_identity = std::move(other.m_lbl_alt_identity );
m_lbl_alt_password = std::move(other.m_lbl_alt_password); m_lbl_alt_password = std::move(other.m_lbl_alt_password );
m_methods = std::move(other.m_methods); m_methods = std::move(other.m_methods );
} }
return *this; return *this;
@@ -372,72 +374,71 @@ void eap::config_provider::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pC
{ {
config::save(pDoc, pConfigRoot); config::save(pDoc, pConfigRoot);
const bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata");
HRESULT hr; HRESULT hr;
// <read-only> // <read-only>
if (FAILED(hr = eapxml::put_element_value(pDoc, pConfigRoot, bstr(L"read-only"), bstrNamespace, 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> // <ID>
if (!m_id.empty()) if (!m_id.empty())
if (FAILED(hr = eapxml::put_element_value(pDoc, pConfigRoot, bstr(L"ID"), bstrNamespace, bstr(m_id)))) if (FAILED(hr = eapxml::put_element_value(pDoc, pConfigRoot, bstr(L"ID"), namespace_eapmetadata, bstr(m_id))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <ID> element."); 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"), bstrNamespace, &pXmlElProviderInfo))) if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:ProviderInfo"), bstr(L"ProviderInfo"), namespace_eapmetadata, &pXmlElProviderInfo)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <ProviderInfo> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <ProviderInfo> element.");
// <ProviderInfo>/<DisplayName> // <ProviderInfo>/<DisplayName>
if (!m_name.empty()) if (!m_name.empty())
if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElProviderInfo, bstr(L"DisplayName"), bstrNamespace, bstr(m_name)))) if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElProviderInfo, bstr(L"DisplayName"), namespace_eapmetadata, bstr(m_name))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <DisplayName> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <DisplayName> element.");
// <ProviderInfo>/<Helpdesk> // <ProviderInfo>/<Helpdesk>
com_obj<IXMLDOMElement> pXmlElHelpdesk; com_obj<IXMLDOMElement> pXmlElHelpdesk;
if (FAILED(hr = eapxml::create_element(pDoc, pXmlElProviderInfo, bstr(L"eap-metadata:Helpdesk"), bstr(L"Helpdesk"), bstrNamespace, &pXmlElHelpdesk))) if (FAILED(hr = eapxml::create_element(pDoc, pXmlElProviderInfo, bstr(L"eap-metadata:Helpdesk"), bstr(L"Helpdesk"), namespace_eapmetadata, &pXmlElHelpdesk)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <Helpdesk> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <Helpdesk> element.");
// <ProviderInfo>/<Helpdesk>/<EmailAddress> // <ProviderInfo>/<Helpdesk>/<EmailAddress>
if (!m_help_email.empty()) if (!m_help_email.empty())
if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElHelpdesk, bstr(L"EmailAddress"), bstrNamespace, bstr(m_help_email)))) if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElHelpdesk, bstr(L"EmailAddress"), namespace_eapmetadata, bstr(m_help_email))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <EmailAddress> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <EmailAddress> element.");
// <ProviderInfo>/<Helpdesk>/<WebAddress> // <ProviderInfo>/<Helpdesk>/<WebAddress>
if (!m_help_web.empty()) if (!m_help_web.empty())
if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElHelpdesk, bstr(L"WebAddress"), bstrNamespace, bstr(m_help_web)))) if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElHelpdesk, bstr(L"WebAddress"), namespace_eapmetadata, bstr(m_help_web))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <WebAddress> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <WebAddress> element.");
// <ProviderInfo>/<Helpdesk>/<Phone> // <ProviderInfo>/<Helpdesk>/<Phone>
if (!m_help_phone.empty()) if (!m_help_phone.empty())
if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElHelpdesk, bstr(L"Phone"), bstrNamespace, bstr(m_help_phone)))) if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElHelpdesk, bstr(L"Phone"), namespace_eapmetadata, bstr(m_help_phone))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <Phone> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <Phone> element.");
// <ProviderInfo>/<CredentialPrompt> // <ProviderInfo>/<CredentialPrompt>
if (!m_lbl_alt_credential.empty()) if (!m_lbl_alt_credential.empty())
if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElProviderInfo, bstr(L"CredentialPrompt"), bstrNamespace, bstr(m_lbl_alt_credential)))) if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElProviderInfo, bstr(L"CredentialPrompt"), namespace_eapmetadata, bstr(m_lbl_alt_credential))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <CredentialPrompt> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <CredentialPrompt> element.");
// <ProviderInfo>/<UserNameLabel> // <ProviderInfo>/<UserNameLabel>
if (!m_lbl_alt_identity.empty()) if (!m_lbl_alt_identity.empty())
if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElProviderInfo, bstr(L"UserNameLabel"), bstrNamespace, bstr(m_lbl_alt_identity)))) if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElProviderInfo, bstr(L"UserNameLabel"), namespace_eapmetadata, bstr(m_lbl_alt_identity))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <UserNameLabel> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <UserNameLabel> element.");
// <ProviderInfo>/<PasswordLabel> // <ProviderInfo>/<PasswordLabel>
if (!m_lbl_alt_password.empty()) if (!m_lbl_alt_password.empty())
if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElProviderInfo, bstr(L"PasswordLabel"), bstrNamespace, bstr(m_lbl_alt_password)))) if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElProviderInfo, bstr(L"PasswordLabel"), namespace_eapmetadata, bstr(m_lbl_alt_password))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <PasswordLabel> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <PasswordLabel> element.");
// <AuthenticationMethods> // <AuthenticationMethods>
com_obj<IXMLDOMElement> pXmlElAuthenticationMethods; com_obj<IXMLDOMElement> pXmlElAuthenticationMethods;
if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:AuthenticationMethods"), bstr(L"AuthenticationMethods"), bstrNamespace, &pXmlElAuthenticationMethods))) if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:AuthenticationMethods"), bstr(L"AuthenticationMethods"), namespace_eapmetadata, &pXmlElAuthenticationMethods)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <AuthenticationMethods> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <AuthenticationMethods> element.");
for (vector<unique_ptr<config_method> >::const_iterator method = m_methods.cbegin(), method_end = m_methods.cend(); method != method_end; ++method) { for (vector<unique_ptr<config_method> >::const_iterator method = m_methods.cbegin(), method_end = m_methods.cend(); method != method_end; ++method) {
// <AuthenticationMethod> // <AuthenticationMethod>
com_obj<IXMLDOMElement> pXmlElAuthenticationMethod; com_obj<IXMLDOMElement> pXmlElAuthenticationMethod;
if (FAILED(hr = eapxml::create_element(pDoc, bstr(L"AuthenticationMethod"), bstrNamespace, &pXmlElAuthenticationMethod))) if (FAILED(hr = eapxml::create_element(pDoc, bstr(L"AuthenticationMethod"), namespace_eapmetadata, &pXmlElAuthenticationMethod)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <AuthenticationMethod> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <AuthenticationMethod> element.");
// <AuthenticationMethod>/... // <AuthenticationMethod>/...
@@ -619,14 +620,14 @@ eap::config_connection::config_connection(_In_ module &mod) : config(mod)
eap::config_connection::config_connection(_In_ const config_connection &other) : eap::config_connection::config_connection(_In_ const config_connection &other) :
m_providers(other.m_providers), m_providers(other.m_providers),
config(other) config (other )
{ {
} }
eap::config_connection::config_connection(_Inout_ config_connection &&other) : eap::config_connection::config_connection(_Inout_ config_connection &&other) :
m_providers(std::move(other.m_providers)), m_providers(std::move(other.m_providers)),
config(std::move(other)) config (std::move(other ))
{ {
} }
@@ -645,7 +646,7 @@ eap::config_connection& eap::config_connection::operator=(_In_ const config_conn
eap::config_connection& eap::config_connection::operator=(_Inout_ config_connection &&other) eap::config_connection& eap::config_connection::operator=(_Inout_ config_connection &&other)
{ {
if (this != &other) { if (this != &other) {
(config&&)*this = std::move(other); (config&&)*this = std::move(other );
m_providers = std::move(other.m_providers); m_providers = std::move(other.m_providers);
} }
@@ -663,18 +664,17 @@ void eap::config_connection::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *
{ {
config::save(pDoc, pConfigRoot); config::save(pDoc, pConfigRoot);
const bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata");
HRESULT hr; HRESULT hr;
// Select <EAPIdentityProviderList> node. // Create <EAPIdentityProviderList> node.
com_obj<IXMLDOMNode> pXmlElIdentityProviderList; com_obj<IXMLDOMElement> pXmlElIdentityProviderList;
if (FAILED(hr = eapxml::select_node(pConfigRoot, bstr(L"eap-metadata:EAPIdentityProviderList"), &pXmlElIdentityProviderList))) if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:EAPIdentityProviderList"), bstr(L"EAPIdentityProviderList"), namespace_eapmetadata, &pXmlElIdentityProviderList)))
throw com_runtime_error(hr, __FUNCTION__ " Error selecting <EAPIdentityProviderList> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <EAPIdentityProviderList> element.");
for (vector<config_provider>::const_iterator provider = m_providers.cbegin(), provider_end = m_providers.cend(); provider != provider_end; ++provider) { for (provider_list::const_iterator provider = m_providers.cbegin(), provider_end = m_providers.cend(); provider != provider_end; ++provider) {
// <EAPIdentityProvider> // <EAPIdentityProvider>
com_obj<IXMLDOMElement> pXmlElIdentityProvider; com_obj<IXMLDOMElement> pXmlElIdentityProvider;
if (FAILED(hr = eapxml::create_element(pDoc, bstr(L"EAPIdentityProvider"), bstrNamespace, &pXmlElIdentityProvider))) if (FAILED(hr = eapxml::create_element(pDoc, bstr(L"EAPIdentityProvider"), namespace_eapmetadata, &pXmlElIdentityProvider)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <EAPIdentityProvider> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <EAPIdentityProvider> element.");
// <EAPIdentityProvider>/... // <EAPIdentityProvider>/...
@@ -733,10 +733,10 @@ void eap::config_connection::operator>>(_Inout_ cursor_in &cursor)
{ {
config::operator>>(cursor); config::operator>>(cursor);
list<config_provider>::size_type count; provider_list::size_type count;
cursor >> count; cursor >> count;
m_providers.clear(); m_providers.clear();
for (list<config_provider>::size_type i = 0; i < count; i++) { for (provider_list::size_type i = 0; i < count; i++) {
config_provider el(m_module); config_provider el(m_module);
cursor >> el; cursor >> el;
m_providers.push_back(std::move(el)); m_providers.push_back(std::move(el));

View File

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

View File

@@ -28,7 +28,7 @@ using namespace winstd;
// eap::method // eap::method
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
eap::method::method(_In_ module &module, _In_ config_connection &cfg, _In_ credentials &cred) : eap::method::method(_In_ module &module, _In_ config_method_with_cred &cfg, _In_ credentials &cred) :
m_module(module), m_module(module),
m_cfg(cfg), m_cfg(cfg),
m_cred(cred) m_cred(cred)
@@ -37,9 +37,10 @@ eap::method::method(_In_ module &module, _In_ config_connection &cfg, _In_ crede
eap::method::method(_Inout_ method &&other) : eap::method::method(_Inout_ method &&other) :
m_module(other.m_module), m_module ( other.m_module ),
m_cfg(other.m_cfg), m_cfg ( other.m_cfg ),
m_cred(other.m_cred) m_cred ( other.m_cred ),
m_eap_attr(std::move(other.m_eap_attr))
{ {
} }
@@ -50,6 +51,7 @@ eap::method& eap::method::operator=(_Inout_ method &&other)
assert(std::addressof(m_module) == std::addressof(other.m_module)); // Move method within same module only! assert(std::addressof(m_module) == std::addressof(other.m_module)); // Move method within same module only!
assert(std::addressof(m_cfg ) == std::addressof(other.m_cfg )); // Move method with same configuration only! assert(std::addressof(m_cfg ) == std::addressof(other.m_cfg )); // Move method with same configuration only!
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!
m_eap_attr = std::move(other.m_eap_attr);
} }
return *this; return *this;

View File

@@ -21,7 +21,9 @@
#include <wx/hyperlink.h> #include <wx/hyperlink.h>
#include <wx/icon.h> #include <wx/icon.h>
#include <wx/intl.h> #include <wx/intl.h>
#include <wx/msgdlg.h>
#include <wx/scrolwin.h> #include <wx/scrolwin.h>
#include <wx/textdlg.h>
#include <Windows.h> #include <Windows.h>
@@ -41,10 +43,15 @@ template <class _wxT> class wxEAPConfigDialog;
class wxEAPGeneralDialog; class wxEAPGeneralDialog;
/// ///
/// EAP top-most credential dialog /// EAP method credential dialog
/// ///
class wxEAPCredentialsDialog; class wxEAPCredentialsDialog;
///
/// EAP connection credential dialog
///
class wxEAPCredentialsConnectionDialog;
/// ///
/// EAP general note /// EAP general note
/// ///
@@ -65,10 +72,15 @@ class wxEAPCredentialWarningPanel;
/// ///
class wxEAPConfigWindow; class wxEAPConfigWindow;
///
/// EAP provider contact info config panel
///
class wxEAPProviderContactInfoPanel;
/// ///
/// EAP provider identity config panel /// EAP provider identity config panel
/// ///
class wxEAPProviderIdentityPanel; class wxEAPProviderIDPanel;
/// ///
/// EAP provider configuration dialog /// EAP provider configuration dialog
@@ -187,7 +199,7 @@ public:
this->SetIcon(wxIcon(wxICON(product.ico))); this->SetIcon(wxIcon(wxICON(product.ico)));
#endif #endif
for (std::vector<eap::config_provider>::iterator provider = m_cfg.m_providers.begin(), provider_end = m_cfg.m_providers.end(); provider != provider_end; ++provider) { 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();
@@ -199,8 +211,8 @@ public:
provider->m_id.c_str(), provider->m_id.c_str(),
m_providers), m_providers),
is_single ? is_single ?
wxEAPGetProviderName(provider->m_id) : wxEAPGetProviderName(provider->m_name) :
winstd::tstring_printf(_T("%s (%u)"), wxEAPGetProviderName(provider->m_id), count)); winstd::tstring_printf(_T("%s (%u)"), wxEAPGetProviderName(provider->m_name), count));
} }
this->Layout(); this->Layout();
@@ -223,27 +235,83 @@ protected:
} }
} }
virtual void OnUpdateUI(wxUpdateUIEvent& /*event*/) virtual void OnUpdateUI(wxUpdateUIEvent& /*event*/)
{
int idx = m_providers->GetSelection();
if (idx != wxNOT_FOUND) {
eap::config_provider &cfg_provider = ((_wxT*)m_providers->GetPage(idx))->GetProvider();
m_prov_remove->Enable(true);
m_prov_advanced->Enable(!cfg_provider.m_read_only);
} else {
m_prov_remove->Enable(false);
m_prov_advanced->Enable(false);
}
}
virtual void OnProvAdd(wxCommandEvent& /*event*/)
{
// One method
std::unique_ptr<eap::config_method> cfg_method(m_cfg.m_module.make_config_method());
// Create provider.
eap::config_provider cfg_provider(m_cfg.m_module);
GUID guid;
CoCreateGuid(&guid);
cfg_provider.m_id = std::move(winstd::wstring_guid(guid));
cfg_provider.m_methods.push_back(std::move(cfg_method));
// Append provider.
m_cfg.m_providers.push_back(std::move(cfg_provider));
eap::config_provider &cfg_provider2 = m_cfg.m_providers.back();
eap::config_method *cfg_method2 = cfg_provider2.m_methods.front().get();
m_providers->InsertPage(
m_providers->GetSelection() + 1,
new _wxT(
cfg_provider2,
*cfg_method2,
cfg_provider2.m_id.c_str(),
m_providers),
wxEAPGetProviderName(cfg_provider2.m_name), true);
this->Layout();
this->Fit();
}
virtual void OnProvRemove(wxCommandEvent& /*event*/)
{ {
int idx = m_providers->GetSelection(); int idx = m_providers->GetSelection();
eap::config_provider &cfg_provider = ((_wxT*)m_providers->GetPage(idx))->GetProvider(); eap::config_provider &cfg_provider = ((_wxT*)m_providers->GetPage(idx))->GetProvider();
m_advanced->Enable(!cfg_provider.m_read_only); if (wxMessageBox(tstring_printf(_("Are you sure you want to permanently remove %ls provider from configuration?"), cfg_provider.m_name.c_str()), _("Warning"), wxYES_NO, this) == wxYES) {
// Delete provider.
eap::config_connection::provider_list::iterator it(m_cfg.m_providers.begin());
for (int i = 0; i < idx; i++, ++it);
m_cfg.m_providers.erase(it);
m_providers->DeletePage(idx);
if (idx < m_providers->GetPageCount())
m_providers->SetSelection(idx);
this->Layout();
this->Fit();
}
} }
virtual void OnAdvanced(wxCommandEvent& /*event*/)
virtual void OnProvAdvanced(wxCommandEvent& /*event*/)
{ {
int idx = m_providers->GetSelection(); int idx = m_providers->GetSelection();
eap::config_provider &cfg_provider = ((_wxT*)m_providers->GetPage(idx))->GetProvider(); eap::config_provider &cfg_provider = ((_wxT*)m_providers->GetPage(idx))->GetProvider();
wxEAPConfigProvider dlg(cfg_provider, this); wxEAPConfigProvider dlg(cfg_provider, this);
if (dlg.ShowModal() == wxID_OK) if (dlg.ShowModal() == wxID_OK)
m_providers->SetPageText(idx, wxEAPGetProviderName(cfg_provider.m_id)); m_providers->SetPageText(idx, wxEAPGetProviderName(cfg_provider.m_name));
} }
/// \endcond /// \endcond
protected: protected:
eap::config_connection &m_cfg; ///< Connection configuration eap::config_connection &m_cfg; ///< Connection configuration
}; };
@@ -284,6 +352,21 @@ public:
}; };
class wxEAPCredentialsConnectionDialog : public wxEAPCredentialsConnectionDialogBase
{
public:
///
/// Constructs a credential dialog
///
wxEAPCredentialsConnectionDialog(wxWindow *parent, wxWindowID id = wxID_ANY, const wxString &title = _("EAP Credentials"), const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE);
protected:
/// \cond internal
virtual void OnInitDialog(wxInitDialogEvent& event);
/// \endcond
};
class wxEAPNotePanel : public wxEAPNotePanelBase class wxEAPNotePanel : public wxEAPNotePanelBase
{ {
public: public:
@@ -385,16 +468,16 @@ protected:
}; };
class wxEAPProviderIdentityPanel : public wxEAPProviderIdentityPanelBase class wxEAPProviderContactInfoPanel : public wxEAPProviderContactInfoPanelBase
{ {
public: public:
/// ///
/// Constructs a provider identity pannel /// Constructs a provider contact info pannel
/// ///
/// \param[inout] prov Provider configuration data /// \param[inout] prov Provider configuration data
/// \param[in] parent Parent window /// \param[in] parent Parent window
/// ///
wxEAPProviderIdentityPanel(eap::config_provider &prov, wxWindow* parent); wxEAPProviderContactInfoPanel(eap::config_provider &prov, wxWindow* parent);
friend class wxEAPConfigProvider; // Allows direct setting of keyboard focus friend class wxEAPConfigProvider; // Allows direct setting of keyboard focus
@@ -405,7 +488,29 @@ protected:
/// \endcond /// \endcond
protected: protected:
eap::config_provider &m_prov; ///< EAP method configuration eap::config_provider &m_prov; ///< Provider configuration
};
class wxEAPProviderIDPanel : public wxEAPProviderIDPanelBase
{
public:
///
/// Constructs a provider identity pannel
///
/// \param[inout] prov Provider configuration data
/// \param[in] parent Parent window
///
wxEAPProviderIDPanel(eap::config_provider &prov, wxWindow* parent);
protected:
/// \cond internal
virtual bool TransferDataToWindow();
virtual bool TransferDataFromWindow();
/// \endcond
protected:
eap::config_provider &m_prov; ///< Provider configuration
}; };
@@ -444,7 +549,8 @@ public:
protected: protected:
eap::config_provider &m_prov; ///< EAP method configuration eap::config_provider &m_prov; ///< EAP method configuration
wxEAPProviderIdentityPanel *m_identity; ///< Provider identity panel wxEAPProviderContactInfoPanel *m_contact; ///< Provider contact info panel
wxEAPProviderIDPanel *m_identity; ///< Provider identity panel
wxEAPProviderLockPanel *m_lock; ///< Provider lock panel wxEAPProviderLockPanel *m_lock; ///< Provider lock panel
}; };
@@ -642,23 +748,19 @@ protected:
inline void UpdateOwnIdentity() inline void UpdateOwnIdentity()
{ {
if (m_cred_own.empty()) wxString identity(m_cred_own.get_identity());
m_own_identity->SetValue(_T("<empty credentials>")); m_own_identity->SetValue(
else { !identity.empty() ? identity :
wxString identity(m_cred_own.get_name()); m_cred_own.empty() ? _("<empty>") : _("<blank ID>"));
m_own_identity->SetValue(!identity.empty() ? identity : _("<blank identity>"));
}
} }
inline void UpdatePresharedIdentity() inline void UpdatePresharedIdentity()
{ {
if (m_cred_preshared.empty()) wxString identity(m_cred_preshared.get_identity());
m_preshared_identity->SetValue(_T("<empty credentials>")); m_preshared_identity->SetValue(
else { !identity.empty() ? identity :
wxString identity(m_cred_preshared.get_name()); m_cred_preshared.empty() ? _("<empty>") : _("<blank ID>"));
m_preshared_identity->SetValue(!identity.empty() ? identity : _("<blank identity>"));
}
} }
/// \endcond /// \endcond
@@ -773,7 +875,7 @@ public:
bool layout = false; bool layout = false;
if (!m_prov.m_lbl_alt_credential.empty()) { if (!m_prov.m_lbl_alt_credential.empty()) {
m_credentials_label->SetLabel(m_prov.m_lbl_alt_credential); m_credentials_label->SetLabel(m_prov.m_lbl_alt_credential);
m_credentials_label->Wrap( 446 ); m_credentials_label->Wrap( 445 );
layout = true; layout = true;
} }

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -95,7 +95,45 @@ wxEAPCredentialsDialog::wxEAPCredentialsDialog(const eap::config_provider &prov,
wxEAPGeneralDialog(parent, id, title, pos, size, style) wxEAPGeneralDialog(parent, id, title, pos, size, style)
{ {
// Set banner title. // Set banner title.
m_banner->m_title->SetLabel(wxString::Format(_("%s Credentials"), wxEAPGetProviderName(prov.m_id).c_str())); m_banner->m_title->SetLabel(wxString::Format(_("%s Credentials"), wxEAPGetProviderName(prov.m_name).c_str()));
}
//////////////////////////////////////////////////////////////////////
// wxEAPCredentialsConnectionDialog
//////////////////////////////////////////////////////////////////////
wxEAPCredentialsConnectionDialog::wxEAPCredentialsConnectionDialog(wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &pos, const wxSize &size, long style) :
wxEAPCredentialsConnectionDialogBase(parent, id, title, pos, size, style)
{
// Set extra style here, as wxFormBuilder overrides all default flags.
this->SetExtraStyle(this->GetExtraStyle() | wxWS_EX_VALIDATE_RECURSIVELY);
// Load window icons.
#ifdef __WINDOWS__
wxIconBundle icons;
icons.AddIcon(wxIcon(wxT("product.ico"), wxBITMAP_TYPE_ICO_RESOURCE, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON)));
icons.AddIcon(wxIcon(wxT("product.ico"), wxBITMAP_TYPE_ICO_RESOURCE, ::GetSystemMetrics(SM_CXICON ), ::GetSystemMetrics(SM_CYICON )));
this->SetIcons(icons);
#else
this->SetIcon(wxIcon(wxICON(product.ico)));
#endif
// Set banner title.
m_banner->m_title->SetLabel(_("EAP Credentials"));
m_buttonsOK->SetDefault();
}
void wxEAPCredentialsConnectionDialog::OnInitDialog(wxInitDialogEvent& event)
{
// Forward the event to child panels.
for (wxWindowList::compatibility_iterator provider = m_providers->GetChildren().GetFirst(); provider; provider = provider->GetNext()) {
wxWindow *prov = wxDynamicCast(provider->GetData(), wxWindow);
if (prov)
prov->GetEventHandler()->ProcessEvent(event);
}
} }
@@ -250,36 +288,36 @@ void wxEAPConfigWindow::OnInitDialog(wxInitDialogEvent& /*event*/)
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// wxEAPProviderIdentityPanel // wxEAPProviderContactInfoPanel
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
wxEAPProviderIdentityPanel::wxEAPProviderIdentityPanel(eap::config_provider &prov, wxWindow* parent) : wxEAPProviderContactInfoPanel::wxEAPProviderContactInfoPanel(eap::config_provider &prov, wxWindow* parent) :
m_prov(prov), m_prov(prov),
wxEAPProviderIdentityPanelBase(parent) wxEAPProviderContactInfoPanelBase(parent)
{ {
// Load and set icon. // Load and set icon.
winstd::library lib_shell32; winstd::library lib_shell32;
if (lib_shell32.load(_T("shell32.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE)) if (lib_shell32.load(_T("shell32.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE))
m_provider_id_icon->SetIcon(wxLoadIconFromResource(lib_shell32, MAKEINTRESOURCE(259))); m_provider_contact_icon->SetIcon(wxLoadIconFromResource(lib_shell32, MAKEINTRESOURCE(259)));
} }
bool wxEAPProviderIdentityPanel::TransferDataToWindow() bool wxEAPProviderContactInfoPanel::TransferDataToWindow()
{ {
m_provider_name ->SetValue(m_prov.m_id ); m_provider_name ->SetValue(m_prov.m_name );
m_provider_web ->SetValue(m_prov.m_help_web ); m_provider_web ->SetValue(m_prov.m_help_web );
m_provider_email->SetValue(m_prov.m_help_email); m_provider_email->SetValue(m_prov.m_help_email);
m_provider_phone->SetValue(m_prov.m_help_phone); m_provider_phone->SetValue(m_prov.m_help_phone);
return wxEAPProviderIdentityPanelBase::TransferDataToWindow(); return wxEAPProviderContactInfoPanelBase::TransferDataToWindow();
} }
bool wxEAPProviderIdentityPanel::TransferDataFromWindow() bool wxEAPProviderContactInfoPanel::TransferDataFromWindow()
{ {
wxCHECK(wxEAPProviderIdentityPanelBase::TransferDataFromWindow(), false); wxCHECK(wxEAPProviderContactInfoPanelBase::TransferDataFromWindow(), false);
m_prov.m_id = m_provider_name ->GetValue(); m_prov.m_name = m_provider_name ->GetValue();
m_prov.m_help_web = m_provider_web ->GetValue(); m_prov.m_help_web = m_provider_web ->GetValue();
m_prov.m_help_email = m_provider_email->GetValue(); m_prov.m_help_email = m_provider_email->GetValue();
m_prov.m_help_phone = m_provider_phone->GetValue(); m_prov.m_help_phone = m_provider_phone->GetValue();
@@ -288,6 +326,39 @@ bool wxEAPProviderIdentityPanel::TransferDataFromWindow()
} }
//////////////////////////////////////////////////////////////////////
// wxEAPProviderIDPanel
//////////////////////////////////////////////////////////////////////
wxEAPProviderIDPanel::wxEAPProviderIDPanel(eap::config_provider &prov, wxWindow* parent) :
m_prov(prov),
wxEAPProviderIDPanelBase(parent)
{
// Load and set icon.
winstd::library lib_shell32;
if (lib_shell32.load(_T("shell32.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE))
m_provider_id_icon->SetIcon(wxLoadIconFromResource(lib_shell32, MAKEINTRESOURCE(29)));
}
bool wxEAPProviderIDPanel::TransferDataToWindow()
{
m_provider_id->SetValue(m_prov.m_id);
return wxEAPProviderIDPanelBase::TransferDataToWindow();
}
bool wxEAPProviderIDPanel::TransferDataFromWindow()
{
wxCHECK(wxEAPProviderIDPanelBase::TransferDataFromWindow(), false);
m_prov.m_id = m_provider_id->GetValue();
return true;
}
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// wxEAPProviderLockPanel // wxEAPProviderLockPanel
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
@@ -332,13 +403,16 @@ wxEAPConfigProvider::wxEAPConfigProvider(eap::config_provider &prov, wxWindow *p
// Set banner title. // Set banner title.
m_banner->m_title->SetLabel(title); m_banner->m_title->SetLabel(title);
m_identity = new wxEAPProviderIdentityPanel(prov, this); m_contact = new wxEAPProviderContactInfoPanel(prov, this);
AddContent(m_contact);
m_identity = new wxEAPProviderIDPanel(prov, this);
AddContent(m_identity); AddContent(m_identity);
m_lock = new wxEAPProviderLockPanel(prov, this); m_lock = new wxEAPProviderLockPanel(prov, this);
AddContent(m_lock); AddContent(m_lock);
m_identity->m_provider_name->SetFocusFromKbd(); m_contact->m_provider_name->SetFocusFromKbd();
} }

View File

@@ -10,6 +10,7 @@
<ItemDefinitionGroup> <ItemDefinitionGroup>
<ResourceCompile> <ResourceCompile>
<AdditionalIncludeDirectories>temp\Events.$(Platform).$(Configuration).$(PlatformToolset);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>temp\Events.$(Platform).$(Configuration).$(PlatformToolset);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>AFX_TARG_NEU;AFX_TARG_ENU;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile> </ResourceCompile>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup /> <ItemGroup />

Binary file not shown.

View File

@@ -81,11 +81,13 @@
<ItemGroup> <ItemGroup>
<ClInclude Include="..\include\Config.h" /> <ClInclude Include="..\include\Config.h" />
<ClInclude Include="..\include\Credentials.h" /> <ClInclude Include="..\include\Credentials.h" />
<ClInclude Include="..\include\Method.h" />
<ClInclude Include="..\src\StdAfx.h" /> <ClInclude Include="..\src\StdAfx.h" />
</ItemGroup> </ItemGroup>
<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\Method.cpp" />
<ClCompile Include="..\src\StdAfx.cpp"> <ClCompile Include="..\src\StdAfx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>

View File

@@ -20,6 +20,9 @@
<ClInclude Include="..\include\Credentials.h"> <ClInclude Include="..\include\Credentials.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\include\Method.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\src\StdAfx.cpp"> <ClCompile Include="..\src\StdAfx.cpp">
@@ -31,5 +34,8 @@
<ClCompile Include="..\src\Credentials.cpp"> <ClCompile Include="..\src\Credentials.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\src\Method.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
</Project> </Project>

167
lib/PAP/include/Method.h Normal file
View File

@@ -0,0 +1,167 @@
/*
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
{
///
/// PAP method
///
class method_pap;
}
#pragma once
#include "Config.h"
#include "Credentials.h"
#include "../../EAPBase/include/Method.h"
namespace eap
{
class method_pap : public method
{
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:
///
/// 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_pap(_In_ module &module, _In_ config_method_pap &cfg, _In_ credentials_pap &cred);
///
/// Moves an EAP method
///
/// \param[in] other EAP method to move from
///
method_pap(_Inout_ method_pap &&other);
///
/// Moves an EAP method
///
/// \param[in] other EAP method to move from
///
/// \returns Reference to this object
///
method_pap& operator=(_Inout_ method_pap &&other);
/// \name Packet processing
/// @{
///
/// 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 EapPacket *pReceivedPacket,
_In_ DWORD dwReceivedPacketSize,
_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.
///
/// \sa [EapPeerGetResult function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363611.aspx)
///
virtual void get_result(
_In_ EapPeerMethodResultReason reason,
_Inout_ EapPeerMethodResult *ppResult);
/// @}
protected:
credentials_pap &m_cred; ///< EAP-TLS user credentials
packet m_packet_res; ///< Response packet
enum {
phase_unknown = -1, ///< Unknown phase
phase_init = 0, ///< Handshake initialize
phase_finished, ///< Connection shut down
} m_phase, m_phase_prev; ///< What phase is our communication at?
};
}

283
lib/PAP/src/Method.cpp Normal file
View File

@@ -0,0 +1,283 @@
/*
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_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::method_pap(_In_ module &module, _In_ config_method_pap &cfg, _In_ credentials_pap &cred) :
m_cred(cred),
m_phase(phase_unknown),
m_phase_prev(phase_unknown),
method(module, cfg, cred)
{
}
eap::method_pap::method_pap(_Inout_ method_pap &&other) :
m_cred ( other.m_cred ),
m_packet_res(std::move(other.m_packet_res)),
m_phase (std::move(other.m_phase )),
m_phase_prev(std::move(other.m_phase_prev)),
method (std::move(other ))
{
}
eap::method_pap& eap::method_pap::operator=(_Inout_ method_pap &&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);
m_phase = std::move(other.m_phase );
m_phase_prev = std::move(other.m_phase_prev);
}
return *this;
}
void eap::method_pap::process_request_packet(
_In_bytecount_(dwReceivedPacketSize) const EapPacket *pReceivedPacket,
_In_ DWORD dwReceivedPacketSize,
_Inout_ EapPeerMethodOutput *pEapOutput)
{
assert(pReceivedPacket && dwReceivedPacketSize >= 4);
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);
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;
switch (m_phase) {
case phase_init: {
// Convert username and password to UTF-8.
sanitizing_string identity_utf8, password_utf8;
WideCharToMultiByte(CP_UTF8, 0, m_cred.m_identity.c_str(), (int)m_cred.m_identity.length(), identity_utf8, NULL, NULL);
WideCharToMultiByte(CP_UTF8, 0, m_cred.m_password.c_str(), (int)m_cred.m_password.length(), password_utf8, NULL, NULL);
// PAP passwords must be padded to 16B boundary according to RFC 5281. Will not add random extra padding here, as length obfuscation should be done by outer transport layers.
size_t padding_password_ex = (16 - password_utf8.length()) % 16;
password_utf8.append(padding_password_ex, 0);
size_t
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;
m_packet_res.m_id = pReceivedPacket->Id;
m_packet_res.m_data.clear();
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;
break;
}
case phase_finished:
break;
}
pEapOutput->fAllowNotifications = TRUE;
pEapOutput->action = EapPeerMethodResponseActionSend;
}
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(
_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_pap), 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_pap), 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 == 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;
}

View File

@@ -22,3 +22,7 @@
#include "../include/Config.h" #include "../include/Config.h"
#include "../include/Credentials.h" #include "../include/Credentials.h"
#include "../include/Method.h"
#include <Windows.h>
#include <EapHostError.h> // include after Windows.h

View File

@@ -146,10 +146,10 @@ namespace eap
/// Constructs an EAP method /// Constructs an EAP method
/// ///
/// \param[in] mod EAP module to use for global services /// \param[in] mod EAP module to use for global services
/// \param[in] cfg Connection configuration /// \param[in] cfg Method configuration
/// \param[in] cred User credentials /// \param[in] cred User credentials
/// ///
method_tls(_In_ module &module, _In_ config_connection &cfg, _In_ credentials_tls &cred); method_tls(_In_ module &module, _In_ config_method_tls &cfg, _In_ credentials_tls &cred);
/// ///
/// Moves an EAP method /// Moves an EAP method
@@ -158,11 +158,6 @@ namespace eap
/// ///
method_tls(_Inout_ method_tls &&other); method_tls(_Inout_ method_tls &&other);
///
/// Destructor
///
virtual ~method_tls();
/// ///
/// Moves an EAP method /// Moves an EAP method
/// ///
@@ -367,12 +362,12 @@ namespace eap
/// Process handshake /// Process handshake
/// ///
void process_handshake(); void process_handshake();
#endif
/// ///
/// Process application data /// Process application data
/// ///
void process_application_data(); void process_application_data();
#endif
/// ///
/// Processes a TLS application_data message /// Processes a TLS application_data message
@@ -490,6 +485,7 @@ namespace eap
#endif #endif
protected: protected:
config_method_tls &m_cfg; ///< EAP-TLS method configuration
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
@@ -551,13 +547,5 @@ namespace eap
phase_shutdown, ///< Connection shut down phase_shutdown, ///< Connection shut down
} m_phase, m_phase_prev; ///< What phase is our communication at? } m_phase, m_phase_prev; ///< What phase is our communication at?
#endif #endif
// The following members are required to avoid memory leakage in get_result()
EAP_ATTRIBUTES m_eap_attr_desc; ///< EAP Radius attributes descriptor
std::vector<winstd::eap_attr> m_eap_attr; ///< EAP Radius attributes
BYTE *m_blob_cfg; ///< Configuration BLOB
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
BYTE *m_blob_cred; ///< Credentials BLOB
#endif
}; };
} }

View File

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

View File

@@ -95,26 +95,22 @@ void eap::credentials_tls::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pC
credentials::save(pDoc, pConfigRoot); credentials::save(pDoc, pConfigRoot);
const bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata");
HRESULT hr; HRESULT hr;
// <ClientCertificate> // <ClientCertificate>
com_obj<IXMLDOMElement> pXmlElClientCertificate; com_obj<IXMLDOMElement> pXmlElClientCertificate;
if (FAILED(hr = eapxml::create_element(pDoc, bstr(L"ClientCertificate"), bstrNamespace, &pXmlElClientCertificate))) if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:ClientCertificate"), bstr(L"ClientCertificate"), namespace_eapmetadata, &pXmlElClientCertificate)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <ClientCertificate> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <ClientCertificate> element.");
if (m_cert) { if (m_cert) {
// <ClientCertificate>/<format> // <ClientCertificate>/<format>
if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElClientCertificate, bstr(L"format"), bstrNamespace, bstr(L"PEM")))) if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElClientCertificate, bstr(L"format"), namespace_eapmetadata, bstr(L"PEM"))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <format> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <format> element.");
// <ClientCertificate>/<cert-data> // <ClientCertificate>/<cert-data>
if (FAILED(hr = eapxml::put_element_base64(pDoc, pXmlElClientCertificate, bstr(L"cert-data"), bstrNamespace, m_cert->pbCertEncoded, m_cert->cbCertEncoded))) if (FAILED(hr = eapxml::put_element_base64(pDoc, pXmlElClientCertificate, bstr(L"cert-data"), namespace_eapmetadata, m_cert->pbCertEncoded, m_cert->cbCertEncoded)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <cert-data> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <cert-data> element.");
} }
if (FAILED(hr = pConfigRoot->appendChild(pXmlElClientCertificate, NULL)))
throw com_runtime_error(hr, __FUNCTION__ " Error appending <ClientCertificate> element.");
} }
@@ -253,10 +249,44 @@ std::wstring eap::credentials_tls::get_identity() const
if (!m_identity.empty()) { if (!m_identity.empty()) {
return m_identity; return m_identity;
} else if (m_cert) { } else if (m_cert) {
wstring identity; for (DWORD idx_ext = 0; idx_ext < m_cert->pCertInfo->cExtension; idx_ext++) {
CertGetNameString(m_cert, CERT_NAME_EMAIL_TYPE, 0, NULL, identity); unique_ptr<CERT_ALT_NAME_INFO, LocalFree_delete<CERT_ALT_NAME_INFO> > san_info;
return identity; if (strcmp(m_cert->pCertInfo->rgExtension[idx_ext].pszObjId, szOID_SUBJECT_ALT_NAME2) == 0) {
} else unsigned char *output = NULL;
DWORD size_output;
if (!CryptDecodeObjectEx(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
szOID_SUBJECT_ALT_NAME2,
m_cert->pCertInfo->rgExtension[idx_ext].Value.pbData, m_cert->pCertInfo->rgExtension[idx_ext].Value.cbData,
CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_ENABLE_PUNYCODE_FLAG,
NULL,
&output, &size_output))
throw win_runtime_error(__FUNCTION__ " Error decoding subjectAltName2 certificate extension.");
san_info.reset((CERT_ALT_NAME_INFO*)output);
} else if (strcmp(m_cert->pCertInfo->rgExtension[idx_ext].pszObjId, szOID_SUBJECT_ALT_NAME) == 0) {
unsigned char *output = NULL;
DWORD size_output;
if (!CryptDecodeObjectEx(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
szOID_SUBJECT_ALT_NAME,
m_cert->pCertInfo->rgExtension[idx_ext].Value.pbData, m_cert->pCertInfo->rgExtension[idx_ext].Value.cbData,
CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_ENABLE_PUNYCODE_FLAG,
NULL,
&output, &size_output))
throw win_runtime_error(__FUNCTION__ " Error decoding subjectAltName certificate extension.");
san_info.reset((CERT_ALT_NAME_INFO*)output);
} else {
// Skip this extension.
continue;
}
for (DWORD idx_entry = 0; idx_entry < san_info->cAltEntry; idx_entry++) {
if (san_info->rgAltEntry[idx_entry].dwAltNameChoice == CERT_ALT_NAME_RFC822_NAME)
return san_info->rgAltEntry[idx_entry].pwszRfc822Name;
}
}
}
return L""; return L"";
} }
@@ -269,14 +299,14 @@ eap::credentials::source_t eap::credentials_tls::combine(
if (cred_cached) { if (cred_cached) {
// Using EAP service cached credentials. // Using EAP service cached credentials.
*this = *(credentials_tls*)cred_cached; *this = *(credentials_tls*)cred_cached;
m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_CACHED1, event_data((unsigned int)eap_type_tls), event_data(credentials_tls::get_name()), event_data::blank); m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_CACHED2, event_data((unsigned int)eap_type_tls), event_data(credentials_tls::get_name()), event_data(pszTargetName), event_data::blank);
return source_cache; return source_cache;
} }
if (cfg.m_use_preshared) { if (cfg.m_use_preshared) {
// Using preshared credentials. // Using preshared credentials.
*this = *(credentials_tls*)cfg.m_preshared.get(); *this = *(credentials_tls*)cfg.m_preshared.get();
m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_PRESHARED1, event_data((unsigned int)eap_type_tls), event_data(credentials_tls::get_name()), event_data::blank); m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_PRESHARED2, event_data((unsigned int)eap_type_tls), event_data(credentials_tls::get_name()), event_data(pszTargetName), event_data::blank);
return source_preshared; return source_preshared;
} }
@@ -287,7 +317,7 @@ eap::credentials::source_t eap::credentials_tls::combine(
// Using stored credentials. // Using stored credentials.
*this = std::move(cred_loaded); *this = std::move(cred_loaded);
m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_STORED1, event_data((unsigned int)eap_type_tls), event_data(credentials_tls::get_name()), event_data::blank); m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_STORED2, event_data((unsigned int)eap_type_tls), event_data(credentials_tls::get_name()), event_data(pszTargetName), event_data::blank);
return source_storage; return source_storage;
} catch (...) { } catch (...) {
// Not actually an error. // Not actually an error.

View File

@@ -125,7 +125,8 @@ void eap::method_tls::packet::clear()
// eap::method_tls // eap::method_tls
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
eap::method_tls::method_tls(_In_ module &module, _In_ config_connection &cfg, _In_ credentials_tls &cred) : eap::method_tls::method_tls(_In_ module &module, _In_ config_method_tls &cfg, _In_ credentials_tls &cred) :
m_cfg(cfg),
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
@@ -135,10 +136,6 @@ eap::method_tls::method_tls(_In_ module &module, _In_ config_connection &cfg, _I
#else #else
m_phase(phase_unknown), m_phase(phase_unknown),
m_phase_prev(phase_unknown), m_phase_prev(phase_unknown),
#endif
m_blob_cfg(NULL),
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
m_blob_cred(NULL),
#endif #endif
method(module, cfg, cred) method(module, cfg, cred)
{ {
@@ -153,6 +150,7 @@ eap::method_tls::method_tls(_In_ module &module, _In_ config_connection &cfg, _I
eap::method_tls::method_tls(_Inout_ method_tls &&other) : eap::method_tls::method_tls(_Inout_ method_tls &&other) :
m_cred ( other.m_cred ), m_cred ( other.m_cred ),
m_cfg ( other.m_cfg ),
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 )),
@@ -199,18 +197,6 @@ eap::method_tls::method_tls(_Inout_ method_tls &&other) :
} }
eap::method_tls::~method_tls()
{
if (m_blob_cfg)
m_module.free_memory(m_blob_cfg);
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
if (m_blob_cred)
m_module.free_memory(m_blob_cred);
#endif
}
eap::method_tls& eap::method_tls::operator=(_Inout_ method_tls &&other) eap::method_tls& eap::method_tls::operator=(_Inout_ method_tls &&other)
{ {
if (this != std::addressof(other)) { if (this != std::addressof(other)) {
@@ -273,13 +259,6 @@ void eap::method_tls::begin_session(
m_user_ctx = hTokenImpersonateUser; m_user_ctx = hTokenImpersonateUser;
user_impersonator impersonating(m_user_ctx); user_impersonator impersonating(m_user_ctx);
// Get method configuration.
if (m_cfg.m_providers.empty() || m_cfg.m_providers.front().m_methods.empty())
throw invalid_argument(__FUNCTION__ " Configuration has no providers and/or methods.");
const config_provider &cfg_prov(m_cfg.m_providers.front());
const config_method_tls *cfg_method = dynamic_cast<const config_method_tls*>(cfg_prov.m_methods.front().get());
assert(cfg_method);
#if EAP_TLS < EAP_TLS_SCHANNEL #if EAP_TLS < EAP_TLS_SCHANNEL
// Create cryptographics provider for support needs (handshake hashing, client random, temporary keys...). // Create cryptographics provider for support needs (handshake hashing, client random, temporary keys...).
if (!m_cp.create(NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) if (!m_cp.create(NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
@@ -291,13 +270,13 @@ void eap::method_tls::begin_session(
throw win_runtime_error(__FUNCTION__ " Error creating exponent-of-one key."); throw win_runtime_error(__FUNCTION__ " Error creating exponent-of-one key.");
// Restore previous session ID and master secret. We might get lucky. // Restore previous session ID and master secret. We might get lucky.
m_session_id = cfg_method->m_session_id; m_session_id = m_cfg.m_session_id;
m_master_secret = cfg_method->m_master_secret; m_master_secret = m_cfg.m_master_secret;
#else #else
// Build (expected) server name(s) for Schannel. // Build (expected) server name(s) for Schannel.
m_sc_target_name.clear(); m_sc_target_name.clear();
for (list<wstring>::const_iterator name = cfg_method->m_server_names.cbegin(), name_end = cfg_method->m_server_names.cend(); name != name_end; ++name) { for (list<wstring>::const_iterator name = m_cfg.m_server_names.cbegin(), name_end = m_cfg.m_server_names.cend(); name != name_end; ++name) {
if (name != cfg_method->m_server_names.cbegin()) if (name != m_cfg.m_server_names.cbegin())
m_sc_target_name += _T(';'); m_sc_target_name += _T(';');
#ifdef _UNICODE #ifdef _UNICODE
m_sc_target_name.insert(m_sc_target_name.end(), name->begin(), name->end()); m_sc_target_name.insert(m_sc_target_name.end(), name->begin(), name->end());
@@ -319,7 +298,7 @@ void eap::method_tls::begin_session(
NULL, // aphMappers NULL, // aphMappers
0, // cSupportedAlgs: Use system configured default 0, // cSupportedAlgs: Use system configured default
NULL, // palgSupportedAlgs: Use system configured default NULL, // palgSupportedAlgs: Use system configured default
0, // grbitEnabledProtocols: Use default SP_PROT_TLS1_X_CLIENT | (SP_PROT_TLS1_2_CLIENT<<2), // grbitEnabledProtocols: TLS 1.x
0, // dwMinimumCipherStrength: Use system configured default 0, // dwMinimumCipherStrength: Use system configured default
0, // dwMaximumCipherStrength: Use system configured default 0, // dwMaximumCipherStrength: Use system configured default
0, // dwSessionLifespan: Use system configured default = 10hr 0, // dwSessionLifespan: Use system configured default = 10hr
@@ -332,7 +311,7 @@ void eap::method_tls::begin_session(
SCH_CRED_IGNORE_NO_REVOCATION_CHECK | // dwFlags: Ignore no-revocation-check errors (TODO: Test if this flag is required.) SCH_CRED_IGNORE_NO_REVOCATION_CHECK | // dwFlags: Ignore no-revocation-check errors (TODO: Test if this flag is required.)
SCH_CRED_IGNORE_REVOCATION_OFFLINE | // dwFlags: Ignore offline-revocation errors - we do not expect to have network connection yet SCH_CRED_IGNORE_REVOCATION_OFFLINE | // dwFlags: Ignore offline-revocation errors - we do not expect to have network connection yet
SCH_CRED_NO_DEFAULT_CREDS | // dwFlags: If client certificate we provided is not acceptable, do not try to select one on your own SCH_CRED_NO_DEFAULT_CREDS | // dwFlags: If client certificate we provided is not acceptable, do not try to select one on your own
(cfg_method->m_server_names.empty() ? SCH_CRED_NO_SERVERNAME_CHECK : 0) | // dwFlags: When no expected server name is given, do not do the server name check. (m_cfg.m_server_names.empty() ? SCH_CRED_NO_SERVERNAME_CHECK : 0) | // dwFlags: When no expected server name is given, do not do the server name check.
0x00400000 /*SCH_USE_STRONG_CRYPTO*/, // dwFlags: Do not use broken ciphers 0x00400000 /*SCH_USE_STRONG_CRYPTO*/, // dwFlags: Do not use broken ciphers
0 // dwCredFormat 0 // dwCredFormat
}; };
@@ -378,14 +357,14 @@ void eap::method_tls::process_request_packet(
// Preallocate data according to the Length field. // Preallocate data according to the Length field.
size_t size_tot = ntohl(*(unsigned int*)(pReceivedPacket->Data + 2)); size_t size_tot = ntohl(*(unsigned int*)(pReceivedPacket->Data + 2));
m_packet_req.m_data.reserve(size_tot); m_packet_req.m_data.reserve(size_tot);
m_module.log_event(&EAPMETHOD_TLS_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); 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 { } else {
// The Length field was not included. Odd. Nevermind, no pre-allocation then. // The Length field was not included. Odd. Nevermind, no pre-allocation then.
m_module.log_event(&EAPMETHOD_TLS_PACKET_RECV_FRAG_FIRST1, event_data((unsigned int)eap_type_tls), event_data((unsigned int)packet_data_size), event_data::blank); 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 { } else {
// Mid fragment received. // Mid fragment received.
m_module.log_event(&EAPMETHOD_TLS_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_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); m_packet_req.m_data.insert(m_packet_req.m_data.end(), packet_data_ptr, packet_data_ptr + packet_data_size);
@@ -400,11 +379,11 @@ void eap::method_tls::process_request_packet(
} else if (!m_packet_req.m_data.empty()) { } else if (!m_packet_req.m_data.empty()) {
// Last fragment received. Append data. // 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_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_TLS_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); 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 { } else {
// This is a complete non-fragmented packet. // This is a complete non-fragmented packet.
m_packet_req.m_data.assign(packet_data_ptr, packet_data_ptr + packet_data_size); m_packet_req.m_data.assign(packet_data_ptr, packet_data_ptr + packet_data_size);
m_module.log_event(&EAPMETHOD_TLS_PACKET_RECV, event_data((unsigned int)eap_type_tls), event_data((unsigned int)packet_data_size), event_data::blank); 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; m_packet_req.m_code = (EapCode)pReceivedPacket->Code;
@@ -436,7 +415,7 @@ void eap::method_tls::process_request_packet(
#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 (pReceivedPacket->Code == EapCodeRequest && (m_packet_req.m_flags & 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_TLS_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;
} else { } else {
// Process the packet. // Process the packet.
@@ -565,14 +544,22 @@ void eap::method_tls::process_request_packet(
sanitizing_blob msg_finished(make_message(tls_message_type_handshake, make_finished())); sanitizing_blob msg_finished(make_message(tls_message_type_handshake, make_finished()));
m_packet_res.m_data.insert(m_packet_res.m_data.end(), msg_finished.begin(), msg_finished.end()); m_packet_res.m_data.insert(m_packet_res.m_data.end(), msg_finished.begin(), msg_finished.end());
m_phase = m_handshake[tls_handshake_type_finished] ? phase_application_data : phase_change_cipher_spec; if (m_handshake[tls_handshake_type_finished]) {
// Go to application data phase. And allow piggybacking of the first data message.
m_phase = phase_application_data;
process_application_data(NULL, 0);
} else {
m_phase = phase_change_cipher_spec;
}
break; break;
} }
case phase_change_cipher_spec: case phase_change_cipher_spec:
// Wait in this phase until server sends change cipher spec and finish. // Wait in this phase until server sends change cipher spec and finish.
if (m_state_server.m_alg_encrypt && m_handshake[tls_handshake_type_finished]) if (m_state_server.m_alg_encrypt && m_handshake[tls_handshake_type_finished]) {
m_phase = phase_application_data; m_phase = phase_application_data;
process_application_data(NULL, 0);
}
break; break;
case phase_application_data: case phase_application_data:
@@ -582,7 +569,7 @@ void eap::method_tls::process_request_packet(
#else #else
if (pReceivedPacket->Code == EapCodeRequest && (m_packet_req.m_flags & flags_req_start)) { if (pReceivedPacket->Code == EapCodeRequest && (m_packet_req.m_flags & 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_TLS_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_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
@@ -628,7 +615,7 @@ void eap::method_tls::get_response_packet(
// No need to fragment the packet. // No need to fragment the packet.
m_packet_res.m_flags &= ~flags_res_length_incl; // No need to explicitly include the Length field either. m_packet_res.m_flags &= ~flags_res_length_incl; // No need to explicitly include the Length field either.
data_dst = pSendPacket->Data + 2; data_dst = pSendPacket->Data + 2;
m_module.log_event(&EAPMETHOD_TLS_PACKET_SEND, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_data), event_data::blank); m_module.log_event(&EAPMETHOD_PACKET_SEND, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_data), event_data::blank);
} else { } else {
// But it should be fragmented. // But it should be fragmented.
m_packet_res.m_flags |= flags_res_length_incl | flags_res_more_frag; m_packet_res.m_flags |= flags_res_length_incl | flags_res_more_frag;
@@ -636,7 +623,7 @@ void eap::method_tls::get_response_packet(
data_dst = pSendPacket->Data + 6; data_dst = pSendPacket->Data + 6;
size_data = size_packet_limit - 10; size_data = size_packet_limit - 10;
size_packet = size_packet_limit; size_packet = size_packet_limit;
m_module.log_event(&EAPMETHOD_TLS_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); 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 { } else {
// Continuing the fragmented packet... // Continuing the fragmented packet...
@@ -645,11 +632,11 @@ void eap::method_tls::get_response_packet(
m_packet_res.m_flags &= ~flags_res_length_incl; m_packet_res.m_flags &= ~flags_res_length_incl;
size_data = size_packet_limit - 6; size_data = size_packet_limit - 6;
size_packet = size_packet_limit; size_packet = size_packet_limit;
m_module.log_event(&EAPMETHOD_TLS_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); 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 { } else {
// This is the last fragment. // This is the last fragment.
m_packet_res.m_flags &= ~(flags_res_length_incl | flags_res_more_frag); m_packet_res.m_flags &= ~(flags_res_length_incl | flags_res_more_frag);
m_module.log_event(&EAPMETHOD_TLS_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); 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; data_dst = pSendPacket->Data + 2;
} }
@@ -671,13 +658,9 @@ void eap::method_tls::get_result(
{ {
assert(ppResult); assert(ppResult);
config_provider &cfg_prov(m_cfg.m_providers.front());
config_method_tls *cfg_method = dynamic_cast<config_method_tls*>(cfg_prov.m_methods.front().get());
assert(cfg_method);
switch (reason) { switch (reason) {
case EapPeerMethodResultSuccess: { case EapPeerMethodResultSuccess: {
m_module.log_event(&EAPMETHOD_TLS_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 #if EAP_TLS < EAP_TLS_SCHANNEL
// Derive MSK/EMSK for line encryption. // Derive MSK/EMSK for line encryption.
@@ -685,8 +668,7 @@ void eap::method_tls::get_result(
// Fill array with RADIUS attributes. // Fill array with RADIUS attributes.
eap_attr a; eap_attr a;
m_eap_attr.clear(); m_eap_attr.reserve(m_eap_attr.size() + 3);
m_eap_attr.reserve(3);
a.create_ms_mppe_key(16, (LPCBYTE)&m_key_mppe_client, sizeof(tls_random)); a.create_ms_mppe_key(16, (LPCBYTE)&m_key_mppe_client, sizeof(tls_random));
m_eap_attr.push_back(std::move(a)); m_eap_attr.push_back(std::move(a));
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));
@@ -702,8 +684,7 @@ void eap::method_tls::get_result(
// Fill array with RADIUS attributes. // Fill array with RADIUS attributes.
eap_attr a; eap_attr a;
m_eap_attr.clear(); m_eap_attr.reserve(m_eap_attr.size() + 3);
m_eap_attr.reserve(3);
a.create_ms_mppe_key(16, _key_block, sizeof(tls_random)); a.create_ms_mppe_key(16, _key_block, sizeof(tls_random));
m_eap_attr.push_back(std::move(a)); m_eap_attr.push_back(std::move(a));
_key_block += sizeof(tls_random); _key_block += sizeof(tls_random);
@@ -713,40 +694,45 @@ void eap::method_tls::get_result(
m_eap_attr.push_back(eap_attr::blank); m_eap_attr.push_back(eap_attr::blank);
#endif #endif
m_eap_attr_desc.dwNumberOfAttributes = (DWORD)m_eap_attr.size();
m_eap_attr_desc.pAttribs = m_eap_attr.data();
ppResult->pAttribArray = &m_eap_attr_desc;
// Clear credentials as failed. // Clear credentials as failed.
cfg_method->m_auth_failed = false; m_cfg.m_auth_failed = false;
ppResult->fIsSuccess = TRUE; ppResult->fIsSuccess = TRUE;
ppResult->dwFailureReasonCode = ERROR_SUCCESS; ppResult->dwFailureReasonCode = ERROR_SUCCESS;
#if EAP_TLS < EAP_TLS_SCHANNEL #if EAP_TLS < EAP_TLS_SCHANNEL
// Update configuration with session resumption data and prepare BLOB. // Update configuration with session resumption data and prepare BLOB.
cfg_method->m_session_id = m_session_id; m_cfg.m_session_id = m_session_id;
cfg_method->m_master_secret = m_master_secret; m_cfg.m_master_secret = m_master_secret;
#endif #endif
break; break;
} }
case EapPeerMethodResultFailure: case EapPeerMethodResultFailure:
m_module.log_event(
m_phase_prev < phase_handshake_cont ? &EAPMETHOD_TLS_FAILURE_INIT :
m_phase_prev < phase_application_data ? &EAPMETHOD_TLS_FAILURE_HANDSHAKE : &EAPMETHOD_TLS_FAILURE,
event_data((unsigned int)eap_type_tls), event_data::blank);
#if EAP_TLS < EAP_TLS_SCHANNEL #if EAP_TLS < EAP_TLS_SCHANNEL
// Clear session resumption data. m_module.log_event(
cfg_method->m_session_id.clear(); m_phase < phase_change_cipher_spec ? &EAPMETHOD_METHOD_FAILURE_INIT :
cfg_method->m_master_secret.clear(); m_phase < phase_application_data ? &EAPMETHOD_METHOD_FAILURE_HANDSHAKE : &EAPMETHOD_METHOD_FAILURE,
#endif event_data((unsigned int)eap_type_tls), 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 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.
cfg_method->m_auth_failed = m_phase_prev < phase_application_data && m_phase >= phase_application_data; m_cfg.m_auth_failed = m_phase >= phase_application_data;
// Clear session resumption data.
m_cfg.m_session_id.clear();
m_cfg.m_master_secret.clear();
#else
m_module.log_event(
m_phase_prev < phase_handshake_cont ? &EAPMETHOD_METHOD_FAILURE_INIT :
m_phase_prev < phase_application_data ? &EAPMETHOD_METHOD_FAILURE_HANDSHAKE : &EAPMETHOD_METHOD_FAILURE,
event_data((unsigned int)eap_type_tls), event_data::blank);
// 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.
m_cfg.m_auth_failed = m_phase_prev < phase_application_data && m_phase >= phase_application_data;
#endif
// Do not report failure to EapHost, as it will not save updated configuration then. But we need it to save it, to alert user on next connection attempt. // Do not report failure to EapHost, as it will not save updated configuration then. But we need it to save it, to alert user on next connection attempt.
// EapHost is well aware of the failed condition. // EapHost is well aware of the failed condition.
@@ -761,18 +747,6 @@ void eap::method_tls::get_result(
// Always ask EAP host to save the connection data. // Always ask EAP host to save the connection data.
ppResult->fSaveConnectionData = TRUE; ppResult->fSaveConnectionData = TRUE;
m_module.pack(m_cfg, &ppResult->pConnectionData, &ppResult->dwSizeofConnectionData);
if (m_blob_cfg)
m_module.free_memory(m_blob_cfg);
m_blob_cfg = ppResult->pConnectionData;
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
ppResult->fSaveUserData = TRUE;
m_module.pack(m_cred, &ppResult->pUserData, &ppResult->dwSizeofUserData);
if (m_blob_cred)
m_module.free_memory(m_blob_cred);
m_blob_cred = ppResult->pUserData;
#endif
} }
@@ -1483,38 +1457,34 @@ void eap::method_tls::verify_server_trust() const
throw sec_runtime_error(status, __FUNCTION__ " Error retrieving server certificate from Schannel."); throw sec_runtime_error(status, __FUNCTION__ " Error retrieving server certificate from Schannel.");
#endif #endif
const config_provider &cfg_prov(m_cfg.m_providers.front());
const config_method_tls *cfg_method = dynamic_cast<const config_method_tls*>(cfg_prov.m_methods.front().get());
assert(cfg_method);
// Check server name. // Check server name.
if (!cfg_method->m_server_names.empty()) { if (!m_cfg.m_server_names.empty()) {
bool bool
has_san = false, has_san = false,
found = false; found = false;
// Search subjectAltName2 and subjectAltName. // Search subjectAltName2 and subjectAltName.
for (DWORD i = 0; !found && i < cert->pCertInfo->cExtension; i++) { for (DWORD idx_ext = 0; !found && idx_ext < cert->pCertInfo->cExtension; idx_ext++) {
unique_ptr<CERT_ALT_NAME_INFO, LocalFree_delete<CERT_ALT_NAME_INFO> > san_info; unique_ptr<CERT_ALT_NAME_INFO, LocalFree_delete<CERT_ALT_NAME_INFO> > san_info;
if (strcmp(cert->pCertInfo->rgExtension[i].pszObjId, szOID_SUBJECT_ALT_NAME2) == 0) { if (strcmp(cert->pCertInfo->rgExtension[idx_ext].pszObjId, szOID_SUBJECT_ALT_NAME2) == 0) {
unsigned char *output = NULL; unsigned char *output = NULL;
DWORD size_output; DWORD size_output;
if (!CryptDecodeObjectEx( if (!CryptDecodeObjectEx(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
szOID_SUBJECT_ALT_NAME2, szOID_SUBJECT_ALT_NAME2,
cert->pCertInfo->rgExtension[i].Value.pbData, cert->pCertInfo->rgExtension[i].Value.cbData, cert->pCertInfo->rgExtension[idx_ext].Value.pbData, cert->pCertInfo->rgExtension[idx_ext].Value.cbData,
CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_ENABLE_PUNYCODE_FLAG, CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_ENABLE_PUNYCODE_FLAG,
NULL, NULL,
&output, &size_output)) &output, &size_output))
throw win_runtime_error(__FUNCTION__ " Error decoding subjectAltName2 certificate extension."); throw win_runtime_error(__FUNCTION__ " Error decoding subjectAltName2 certificate extension.");
san_info.reset((CERT_ALT_NAME_INFO*)output); san_info.reset((CERT_ALT_NAME_INFO*)output);
} else if (strcmp(cert->pCertInfo->rgExtension[i].pszObjId, szOID_SUBJECT_ALT_NAME) == 0) { } else if (strcmp(cert->pCertInfo->rgExtension[idx_ext].pszObjId, szOID_SUBJECT_ALT_NAME) == 0) {
unsigned char *output = NULL; unsigned char *output = NULL;
DWORD size_output; DWORD size_output;
if (!CryptDecodeObjectEx( if (!CryptDecodeObjectEx(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
szOID_SUBJECT_ALT_NAME, szOID_SUBJECT_ALT_NAME,
cert->pCertInfo->rgExtension[i].Value.pbData, cert->pCertInfo->rgExtension[i].Value.cbData, cert->pCertInfo->rgExtension[idx_ext].Value.pbData, cert->pCertInfo->rgExtension[idx_ext].Value.cbData,
CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_ENABLE_PUNYCODE_FLAG, CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_ENABLE_PUNYCODE_FLAG,
NULL, NULL,
&output, &size_output)) &output, &size_output))
@@ -1526,12 +1496,12 @@ void eap::method_tls::verify_server_trust() const
} }
has_san = true; has_san = true;
for (list<wstring>::const_iterator s = cfg_method->m_server_names.cbegin(), s_end = cfg_method->m_server_names.cend(); !found && s != s_end; ++s) { for (list<wstring>::const_iterator s = m_cfg.m_server_names.cbegin(), s_end = m_cfg.m_server_names.cend(); !found && s != s_end; ++s) {
for (DWORD i = 0; !found && i < san_info->cAltEntry; i++) { for (DWORD idx_entry = 0; !found && idx_entry < san_info->cAltEntry; idx_entry++) {
if (san_info->rgAltEntry[i].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME && if (san_info->rgAltEntry[idx_entry].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME &&
_wcsicmp(s->c_str(), san_info->rgAltEntry[i].pwszDNSName) == 0) _wcsicmp(s->c_str(), san_info->rgAltEntry[idx_entry].pwszDNSName) == 0)
{ {
m_module.log_event(&EAPMETHOD_TLS_SERVER_NAME_TRUSTED1, event_data(san_info->rgAltEntry[i].pwszDNSName), event_data::blank); m_module.log_event(&EAPMETHOD_TLS_SERVER_NAME_TRUSTED1, event_data(san_info->rgAltEntry[idx_entry].pwszDNSName), event_data::blank);
found = true; found = true;
} }
} }
@@ -1544,7 +1514,7 @@ void eap::method_tls::verify_server_trust() const
if (!CertGetNameStringW(cert, CERT_NAME_DNS_TYPE, CERT_NAME_STR_ENABLE_PUNYCODE_FLAG, NULL, subj)) if (!CertGetNameStringW(cert, CERT_NAME_DNS_TYPE, CERT_NAME_STR_ENABLE_PUNYCODE_FLAG, NULL, subj))
throw win_runtime_error(__FUNCTION__ " Error retrieving server's certificate subject name."); throw win_runtime_error(__FUNCTION__ " Error retrieving server's certificate subject name.");
for (list<wstring>::const_iterator s = cfg_method->m_server_names.cbegin(), s_end = cfg_method->m_server_names.cend(); !found && s != s_end; ++s) { for (list<wstring>::const_iterator s = m_cfg.m_server_names.cbegin(), s_end = m_cfg.m_server_names.cend(); !found && s != s_end; ++s) {
if (_wcsicmp(s->c_str(), subj.c_str()) == 0) { if (_wcsicmp(s->c_str(), subj.c_str()) == 0) {
m_module.log_event(&EAPMETHOD_TLS_SERVER_NAME_TRUSTED1, event_data(subj), event_data::blank); m_module.log_event(&EAPMETHOD_TLS_SERVER_NAME_TRUSTED1, event_data(subj), event_data::blank);
found = true; found = true;
@@ -1564,7 +1534,7 @@ void eap::method_tls::verify_server_trust() const
cert_store store; cert_store store;
if (!store.create(CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, NULL, 0, NULL)) if (!store.create(CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, NULL, 0, NULL))
throw win_runtime_error(__FUNCTION__ " Error creating temporary certificate store."); throw win_runtime_error(__FUNCTION__ " Error creating temporary certificate store.");
for (list<cert_context>::const_iterator c = cfg_method->m_trusted_root_ca.cbegin(), c_end = cfg_method->m_trusted_root_ca.cend(); c != c_end; ++c) for (list<cert_context>::const_iterator c = m_cfg.m_trusted_root_ca.cbegin(), c_end = m_cfg.m_trusted_root_ca.cend(); c != c_end; ++c)
CertAddCertificateContextToStore(store, *c, CERT_STORE_ADD_REPLACE_EXISTING, NULL); CertAddCertificateContextToStore(store, *c, CERT_STORE_ADD_REPLACE_EXISTING, NULL);
// Add all intermediate certificates from the server's certificate chain. // Add all intermediate certificates from the server's certificate chain.
@@ -1636,7 +1606,7 @@ void eap::method_tls::verify_server_trust() const
throw sec_runtime_error(SEC_E_CERT_UNKNOWN, __FUNCTION__ " Can not verify empty certificate chain."); throw sec_runtime_error(SEC_E_CERT_UNKNOWN, __FUNCTION__ " Can not verify empty certificate chain.");
PCCERT_CONTEXT cert_root = context->rgpChain[0]->rgpElement[context->rgpChain[0]->cElement-1]->pCertContext; PCCERT_CONTEXT cert_root = context->rgpChain[0]->rgpElement[context->rgpChain[0]->cElement-1]->pCertContext;
for (list<cert_context>::const_iterator c = cfg_method->m_trusted_root_ca.cbegin(), c_end = cfg_method->m_trusted_root_ca.cend();; ++c) { for (list<cert_context>::const_iterator c = m_cfg.m_trusted_root_ca.cbegin(), c_end = m_cfg.m_trusted_root_ca.cend();; ++c) {
if (c != c_end) { if (c != c_end) {
if (cert_root->cbCertEncoded == (*c)->cbCertEncoded && if (cert_root->cbCertEncoded == (*c)->cbCertEncoded &&
memcmp(cert_root->pbCertEncoded, (*c)->pbCertEncoded, cert_root->cbCertEncoded) == 0) memcmp(cert_root->pbCertEncoded, (*c)->pbCertEncoded, cert_root->cbCertEncoded) == 0)

View File

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

View File

@@ -242,7 +242,7 @@
<property name="window_extra_style"></property> <property name="window_extra_style"></property>
<property name="window_name"></property> <property name="window_name"></property>
<property name="window_style"></property> <property name="window_style"></property>
<property name="wrap">446</property> <property name="wrap">445</property>
<event name="OnChar"></event> <event name="OnChar"></event>
<event name="OnEnterWindow"></event> <event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event> <event name="OnEraseBackground"></event>
@@ -1215,7 +1215,7 @@
<property name="window_extra_style"></property> <property name="window_extra_style"></property>
<property name="window_name"></property> <property name="window_name"></property>
<property name="window_style"></property> <property name="window_style"></property>
<property name="wrap">446</property> <property name="wrap">445</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

@@ -58,10 +58,10 @@ namespace eap
/// Constructs an EAP method /// Constructs an EAP method
/// ///
/// \param[in] mod EAP module to use for global services /// \param[in] mod EAP module to use for global services
/// \param[in] cfg Connection configuration /// \param[in] cfg Method configuration
/// \param[in] cred User credentials /// \param[in] cred User credentials
/// ///
method_ttls(_In_ module &module, _In_ config_connection &cfg, _In_ credentials_ttls &cred); method_ttls(_In_ module &module, _In_ config_method_ttls &cfg, _In_ credentials_ttls &cred);
/// ///
/// Moves an EAP method /// Moves an EAP method
@@ -82,6 +82,24 @@ 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_ DWORD dwMaxSendPacketSize);
///
/// Ends an EAP authentication session for the EAP method.
///
/// \sa [EapPeerEndSession function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363604.aspx)
///
virtual void end_session();
/// ///
/// Processes a packet received by EapHost from a supplicant. /// Processes a packet received by EapHost from a supplicant.
/// ///
@@ -122,7 +140,7 @@ namespace eap
/// ///
virtual void derive_msk(); virtual void derive_msk();
#else #endif
/// ///
/// Processes an application message /// Processes an application message
@@ -132,23 +150,17 @@ namespace eap
/// ///
virtual void process_application_data(_In_bytecount_(size_msg) const void *msg, _In_ size_t size_msg); virtual void process_application_data(_In_bytecount_(size_msg) const void *msg, _In_ size_t size_msg);
#endif protected:
config_method_ttls &m_cfg; ///< EAP-TTLS method configuration
/// credentials_ttls &m_cred; ///< EAP-TTLS credentials
/// Makes a PAP client message
///
/// \sa [Extensible Authentication Protocol Tunneled Transport Layer Security Authenticated Protocol Version 0 (EAP-TTLSv0) (Chapter 11.2.5. PAP)](https://tools.ietf.org/html/rfc5281#section-11.2.5)
///
/// \returns PAP client message
///
sanitizing_blob make_pap_client() const;
public:
credentials_ttls &m_cred; ///< TTLS credentials
#pragma warning(suppress: 4480) #pragma warning(suppress: 4480)
enum version_t :unsigned char { enum version_t :unsigned char {
version_0 = 0, ///< EAP-TTLS v0 version_0 = 0, ///< EAP-TTLS v0
} m_version; ///< EAP-TTLS version } m_version; ///< EAP-TTLS version
std::unique_ptr<method> m_inner; ///< Inner authentication method
unsigned char m_inner_packet_id; ///< Inner packet ID
DWORD m_size_inner_packet_max; ///< Maximum size of inner response packet
}; };
} }

View File

@@ -211,19 +211,36 @@ namespace eap
/// @} /// @}
protected:
///
/// Checks all configured providers and tries to combine credentials.
///
const config_method_ttls* combine_credentials(
_In_ DWORD dwFlags,
_In_ const config_connection &cfg,
_In_count_(dwUserDataSize) const BYTE *pUserData,
_In_ DWORD dwUserDataSize,
_Out_ credentials_connection& cred_out,
_In_ HANDLE hTokenImpersonateUser);
protected: protected:
class session { class session {
public: public:
inline session(_In_ module &mod) : session(_In_ module &mod);
m_cfg(mod), virtual ~session();
m_cred(mod),
m_method(mod, m_cfg, m_cred)
{}
public: public:
module &m_module; ///< Module
config_connection m_cfg; ///< Connection configuration config_connection m_cfg; ///< Connection configuration
credentials_ttls m_cred; ///< User credentials credentials_connection m_cred; ///< Connection credentials
method_ttls m_method; ///< EAP-TTLS method std::unique_ptr<method_ttls> m_method; ///< EAP-TTLS method
// The following members are required to avoid memory leakage in get_result()
EAP_ATTRIBUTES m_eap_attr_desc; ///< EAP attributes descriptor
BYTE *m_blob_cfg; ///< Configuration BLOB
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
BYTE *m_blob_cred; ///< Credentials BLOB
#endif
}; };
}; };
} }

View File

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

View File

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

View File

@@ -28,18 +28,25 @@ using namespace winstd;
// eap::method_ttls // eap::method_ttls
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
eap::method_ttls::method_ttls(_In_ module &module, _In_ config_connection &cfg, _In_ credentials_ttls &cred) : eap::method_ttls::method_ttls(_In_ module &module, _In_ config_method_ttls &cfg, _In_ credentials_ttls &cred) :
m_cfg(cfg),
m_cred(cred), m_cred(cred),
m_version(version_0), m_version(version_0),
m_inner_packet_id(0),
m_size_inner_packet_max(0),
method_tls(module, cfg, cred) method_tls(module, cfg, cred)
{ {
} }
eap::method_ttls::method_ttls(_Inout_ method_ttls &&other) : eap::method_ttls::method_ttls(_Inout_ method_ttls &&other) :
m_cred(other.m_cred), m_cfg ( other.m_cfg ),
m_version(std::move(other.m_version)), m_cred ( other.m_cred ),
method_tls(std::move(other)) m_version (std::move(other.m_version )),
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)),
method_tls (std::move(other ))
{ {
} }
@@ -47,14 +54,42 @@ eap::method_ttls::method_ttls(_Inout_ method_ttls &&other) :
eap::method_ttls& eap::method_ttls::operator=(_Inout_ method_ttls &&other) eap::method_ttls& eap::method_ttls::operator=(_Inout_ method_ttls &&other)
{ {
if (this != std::addressof(other)) { if (this != std::addressof(other)) {
(method_tls&)*this = std::move(other); (method_tls&)*this = std::move(other );
m_version = std::move(other.m_version); m_version = std::move(other.m_version );
m_inner = std::move(other.m_inner );
m_inner_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;
} }
void eap::method_ttls::begin_session(
_In_ DWORD dwFlags,
_In_ const EapAttributes *pAttributeArray,
_In_ HANDLE hTokenImpersonateUser,
_In_ DWORD dwMaxSendPacketSize)
{
method_tls::begin_session(dwFlags, pAttributeArray, hTokenImpersonateUser, dwMaxSendPacketSize);
// Initialize inner method.
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()));
default: 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_packet_id = 0;
}
void eap::method_ttls::end_session()
{
m_inner->end_session();
method_tls::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 EapPacket *pReceivedPacket,
_In_ DWORD dwReceivedPacketSize, _In_ DWORD dwReceivedPacketSize,
@@ -71,22 +106,6 @@ void eap::method_ttls::process_request_packet(
// Do the TLS. // Do the TLS.
method_tls::process_request_packet(pReceivedPacket, dwReceivedPacketSize, pEapOutput); method_tls::process_request_packet(pReceivedPacket, dwReceivedPacketSize, pEapOutput);
#if EAP_TLS < EAP_TLS_SCHANNEL
if (m_phase == phase_application_data) {
// Send inner authentication.
if (!m_state_client.m_alg_encrypt)
throw runtime_error(__FUNCTION__ " Refusing to send credentials unencrypted.");
m_module.log_event(&EAPMETHOD_TTLS_INNER_CRED, event_data((unsigned int)eap_type_ttls), event_data(m_cred.m_inner->get_name()), event_data::blank);
m_packet_res.m_code = EapCodeResponse;
m_packet_res.m_id = m_packet_req.m_id;
m_packet_res.m_flags = 0;
sanitizing_blob msg_application(make_message(tls_message_type_application_data, make_pap_client()));
m_packet_res.m_data.insert(m_packet_res.m_data.end(), msg_application.begin(), msg_application.end());
}
#endif
} }
@@ -111,29 +130,12 @@ void eap::method_ttls::get_result(
// Do the TLS. // Do the TLS.
method_tls::get_result(reason, ppResult); method_tls::get_result(reason, ppResult);
} else { } else {
// The TLS finished, this is inner authentication's bussines. // Get inner method result.
config_provider &cfg_prov(m_cfg.m_providers.front()); EapPeerMethodResult result = {};
config_method_ttls *cfg_method = dynamic_cast<config_method_ttls*>(cfg_prov.m_methods.front().get()); m_inner->get_result(reason, &result);
assert(cfg_method);
switch (reason) { if (result.fSaveConnectionData)
case EapPeerMethodResultSuccess: { ppResult->fSaveConnectionData = TRUE;
m_module.log_event(&EAPMETHOD_TTLS_INNER_SUCCESS, event_data((unsigned int)eap_type_ttls), event_data::blank);
cfg_method->m_inner->m_auth_failed = false;
break;
}
case EapPeerMethodResultFailure:
m_module.log_event(&EAPMETHOD_TTLS_INNER_FAILURE, event_data((unsigned int)eap_type_ttls), event_data::blank);
// 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.
cfg_method->m_inner->m_auth_failed = m_phase_prev < phase_application_data;
break;
default:
throw win_runtime_error(ERROR_NOT_SUPPORTED, __FUNCTION__ " Not supported.");
}
#if EAP_TLS >= EAP_TLS_SCHANNEL #if EAP_TLS >= EAP_TLS_SCHANNEL
// EAP-TTLS uses different label in PRF for MSK derivation than EAP-TLS. // EAP-TTLS uses different label in PRF for MSK derivation than EAP-TLS.
@@ -143,8 +145,6 @@ void eap::method_ttls::get_result(
if (FAILED(status)) if (FAILED(status))
throw sec_runtime_error(status, __FUNCTION__ "Error setting EAP-TTLS PRF in Schannel."); throw sec_runtime_error(status, __FUNCTION__ "Error setting EAP-TTLS PRF in Schannel.");
#endif #endif
// The TLS was OK.
method_tls::get_result(EapPeerMethodResultSuccess, ppResult); 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. // 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.
@@ -192,40 +192,78 @@ void eap::method_ttls::derive_msk()
_key_block += sizeof(tls_random); _key_block += sizeof(tls_random);
} }
#else #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)
{ {
UNREFERENCED_PARAMETER(msg);
UNREFERENCED_PARAMETER(size_msg);
// Prepare inner authentication. // Prepare inner authentication.
#if EAP_TLS < EAP_TLS_SCHANNEL
if (!m_state_client.m_alg_encrypt)
#else
if (!(m_sc_ctx.m_attrib & ISC_RET_CONFIDENTIALITY)) if (!(m_sc_ctx.m_attrib & ISC_RET_CONFIDENTIALITY))
throw runtime_error(__FUNCTION__ " Refusing to send credentials unencrypted."); #endif
throw runtime_error(__FUNCTION__ " Refusing to continue with inner authentication unencrypted.");
m_module.log_event(&EAPMETHOD_TTLS_INNER_CRED, event_data((unsigned int)eap_type_ttls), event_data(m_cred.m_inner->get_name()), event_data::blank); EapPeerMethodOutput eap_output = {};
eap_type_t eap_type = m_cfg.m_inner->get_method_id();
if (eap_type_noneap_start <= eap_type && eap_type < eap_type_noneap_end) {
// 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.
assert(size_msg < 0xffff);
unsigned short size_packet = (unsigned short)size_msg + 4;
sanitizing_blob packet;
packet.reserve(size_packet);
packet.push_back(EapCodeRequest);
packet.push_back(m_inner_packet_id++);
unsigned short size2 = htons(size_packet);
packet.insert(packet.end(), (unsigned char*)&size2, (unsigned char*)(&size2 + 1));
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);
} else {
// Inner packet is EAP-aware.
m_inner->process_request_packet((const EapPacket*)msg, (DWORD)size_msg, &eap_output);
}
SECURITY_STATUS status; switch (eap_output.action) {
case EapPeerMethodResponseActionSend: {
// Retrieve inner packet and send it.
// Get maximum message sizes. // Get maximum message size and allocate memory for response packet.
#if EAP_TLS < EAP_TLS_SCHANNEL
m_packet_res.m_code = EapCodeResponse;
m_packet_res.m_id = m_packet_req.m_id;
m_packet_res.m_flags = 0;
DWORD size_data = m_size_inner_packet_max;
sanitizing_blob data(size_data, 0);
unsigned char *ptr_data = data.data();
#else
SecPkgContext_StreamSizes sizes; SecPkgContext_StreamSizes sizes;
status = QueryContextAttributes(m_sc_ctx, SECPKG_ATTR_STREAM_SIZES, &sizes); SECURITY_STATUS status = QueryContextAttributes(m_sc_ctx, SECPKG_ATTR_STREAM_SIZES, &sizes);
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.");
// Make PAP message. sanitizing_blob data(sizes.cbHeader + m_size_inner_packet_max + sizes.cbTrailer, 0);
sanitizing_blob msg_pap(make_pap_client()); DWORD size_data = m_size_inner_packet_max;
assert(msg_pap.size() < sizes.cbMaximumMessage); unsigned char *ptr_data = data.data() + sizes.cbHeader;
unsigned long size_data = std::min<unsigned long>(sizes.cbMaximumMessage, (unsigned long)msg_pap.size()); // Truncate #endif
m_inner->get_response_packet((EapPacket*)ptr_data, &size_data);
sanitizing_blob data(sizes.cbHeader + size_data + sizes.cbTrailer, 0); if (eap_type_noneap_start <= eap_type && eap_type < eap_type_noneap_end) {
memcpy(data.data() + sizes.cbHeader, msg_pap.data(), size_data); // 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
data.resize(size_data);
sanitizing_blob msg_application(make_message(tls_message_type_application_data, std::move(data)));
m_packet_res.m_data.insert(m_packet_res.m_data.end(), msg_application.begin(), msg_application.end());
#else
// Prepare input/output buffer(s). // Prepare input/output buffer(s).
SecBuffer buf[] = { SecBuffer buf[] = {
{ sizes.cbHeader, SECBUFFER_STREAM_HEADER , data.data() }, { sizes.cbHeader, SECBUFFER_STREAM_HEADER , data.data() },
{ size_data, SECBUFFER_DATA , data.data() + sizes.cbHeader }, { size_data, SECBUFFER_DATA , ptr_data },
{ sizes.cbTrailer, SECBUFFER_STREAM_TRAILER, data.data() + sizes.cbHeader + size_data }, { sizes.cbTrailer, SECBUFFER_STREAM_TRAILER, ptr_data + size_data },
{ 0, SECBUFFER_EMPTY , NULL }, { 0, SECBUFFER_EMPTY , NULL },
}; };
SecBufferDesc buf_desc = { SecBufferDesc buf_desc = {
@@ -239,74 +277,12 @@ 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 encrypting message."); throw sec_runtime_error(status, __FUNCTION__ " Error encrypting message.");
m_packet_res.m_data.insert(m_packet_res.m_data.end(), (const unsigned char*)buf[0].pvBuffer, (const unsigned char*)buf[0].pvBuffer + buf[0].cbBuffer + buf[1].cbBuffer + buf[2].cbBuffer); m_packet_res.m_data.insert(m_packet_res.m_data.end(), (const unsigned char*)buf[0].pvBuffer, (const unsigned char*)buf[0].pvBuffer + buf[0].cbBuffer + buf[1].cbBuffer + buf[2].cbBuffer);
}
#endif #endif
break;
}
eap::sanitizing_blob eap::method_ttls::make_pap_client() const default:
{ throw invalid_argument(string_printf(__FUNCTION__ " Inner method returned an unsupported action (action %u).", eap_output.action).c_str());
const credentials_pap *cred = dynamic_cast<credentials_pap*>(m_cred.m_inner.get()); }
if (!cred)
throw invalid_argument(__FUNCTION__ " Inner credentials missing or not PAP.");
// Convert username and password to UTF-8.
sanitizing_string identity_utf8, password_utf8;
WideCharToMultiByte(CP_UTF8, 0, cred->m_identity.c_str(), (int)cred->m_identity.length(), identity_utf8, NULL, NULL);
WideCharToMultiByte(CP_UTF8, 0, cred->m_password.c_str(), (int)cred->m_password.length(), password_utf8, NULL, NULL);
// PAP passwords must be padded to 16B boundary according to RFC 5281. Will not add random extra padding here, as length obfuscation should be done by TLS encryption layer.
size_t padding_password_ex = (16 - password_utf8.length()) % 16;
password_utf8.append(padding_password_ex, 0);
size_t
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;
sanitizing_blob msg;
msg.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)
msg.push_back(0x00);
msg.push_back(0x00);
msg.push_back(0x00);
msg.push_back(0x01);
// Diameter AVP Flags & Length
unsigned int identity_hdr = htonl((diameter_avp_flag_mandatory << 24) | (unsigned int)size_identity_outer);
msg.insert(msg.end(), (unsigned char*)&identity_hdr, (unsigned char*)(&identity_hdr + 1));
// Identity
msg.insert(msg.end(), identity_utf8.begin(), identity_utf8.end());
msg.insert(msg.end(), padding_identity, 0);
// Diameter AVP Code User-Password (0x00000002)
msg.push_back(0x00);
msg.push_back(0x00);
msg.push_back(0x00);
msg.push_back(0x02);
// Diameter AVP Flags & Length
unsigned int password_hdr = htonl((diameter_avp_flag_mandatory << 24) | (unsigned int)size_password_outer);
msg.insert(msg.end(), (unsigned char*)&password_hdr, (unsigned char*)(&password_hdr + 1));
// Password
msg.insert(msg.end(), password_utf8.begin(), password_utf8.end());
msg.insert(msg.end(), padding_password, 0);
return msg;
} }

View File

@@ -77,77 +77,28 @@ void eap::peer_ttls::get_identity(
config_connection cfg(*this); config_connection cfg(*this);
unpack(cfg, pConnectionData, dwConnectionDataSize); unpack(cfg, pConnectionData, dwConnectionDataSize);
// Get method configuration.
if (cfg.m_providers.empty() || cfg.m_providers.front().m_methods.empty())
throw invalid_argument(__FUNCTION__ " Configuration has no providers and/or methods.");
const config_provider &cfg_prov(cfg.m_providers.front());
const config_method_ttls *cfg_method = dynamic_cast<const config_method_ttls*>(cfg_prov.m_methods.front().get());
assert(cfg_method);
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
// Unpack cached credentials.
credentials_ttls cred_in(*this);
if (dwUserDataSize) {
cred_in.m_inner.reset(cfg_method->m_inner->make_credentials());
unpack(cred_in, pUserData, dwUserDataSize);
}
#else
UNREFERENCED_PARAMETER(pUserData);
UNREFERENCED_PARAMETER(dwUserDataSize);
#endif
credentials_ttls cred_out(*this);
cred_out.m_inner.reset(cfg_method->m_inner->make_credentials());
// Assume no UI will be necessary.
*pfInvokeUI = FALSE;
{
// Combine credentials. // Combine credentials.
user_impersonator impersonating(hTokenImpersonateUser); credentials_connection cred_out(*this, cfg);
eap::credentials::source_t cred_source = cred_out.combine( const config_method_ttls *cfg_method = combine_credentials(dwFlags, cfg, pUserData, dwUserDataSize, cred_out, hTokenImpersonateUser);
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
&cred_in,
#else
NULL,
#endif
*cfg_method,
(dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? cfg_prov.m_id.c_str() : NULL);
// If either of credentials is unknown, request UI. if (cfg_method) {
if (cred_source == eap::credentials::source_unknown) // No UI will be necessary.
*pfInvokeUI = TRUE; *pfInvokeUI = FALSE;
} } else {
// Credentials missing or incomplete.
if (*pfInvokeUI) {
if ((dwFlags & EAP_FLAG_MACHINE_AUTH) == 0) { if ((dwFlags & EAP_FLAG_MACHINE_AUTH) == 0) {
// Per-user authentication // Per-user authentication, request UI.
log_event(&EAPMETHOD_TRACE_EVT_CRED_INVOKE_UI2, event_data::blank); log_event(&EAPMETHOD_TRACE_EVT_CRED_INVOKE_UI2, event_data::blank);
*pfInvokeUI = TRUE;
return; return;
} else { } else {
// Per-machine authentication // Per-machine authentication, cannot use UI.
throw win_runtime_error(ERROR_NO_SUCH_USER, __FUNCTION__ " Credentials for per-machine authentication not available."); throw win_runtime_error(ERROR_NO_SUCH_USER, __FUNCTION__ " Credentials for per-machine authentication not available.");
} }
} }
// If we got here, we have all credentials we need. But, wait!
if (cfg_method->m_auth_failed) {
// Outer TLS: Credentials failed on last connection attempt.
log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM, event_data((unsigned int)eap_type_tls), event_data::blank);
*pfInvokeUI = TRUE;
return;
}
if (cfg_method->m_inner->m_auth_failed) {
// Inner: Credentials failed on last connection attempt.
log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM, event_data((unsigned int)cfg_method->m_inner->get_method_id()), event_data::blank);
*pfInvokeUI = TRUE;
return;
}
// Build our identity. ;) // Build our identity. ;)
wstring identity(std::move(cfg_method->get_public_identity(cred_out))); wstring identity(std::move(cfg_method->get_public_identity((const credentials_ttls&)*cred_out.m_cred)));
log_event(&EAPMETHOD_TRACE_EVT_CRED_OUTER_ID1, event_data((unsigned int)eap_type_ttls), event_data(identity), event_data::blank); log_event(&EAPMETHOD_TRACE_EVT_CRED_OUTER_ID1, event_data((unsigned int)eap_type_ttls), event_data(identity), event_data::blank);
size_t size = sizeof(WCHAR)*(identity.length() + 1); size_t size = sizeof(WCHAR)*(identity.length() + 1);
*ppwszIdentity = (WCHAR*)alloc_memory(size); *ppwszIdentity = (WCHAR*)alloc_memory(size);
@@ -248,19 +199,29 @@ EAP_SESSION_HANDLE eap::peer_ttls::begin_session(
// Unpack configuration. // Unpack configuration.
unpack(s->m_cfg, pConnectionData, dwConnectionDataSize); unpack(s->m_cfg, pConnectionData, dwConnectionDataSize);
// Get method configuration.
if (s->m_cfg.m_providers.empty() || s->m_cfg.m_providers.front().m_methods.empty())
throw invalid_argument(__FUNCTION__ " Configuration has no providers and/or methods.");
const config_provider &cfg_prov(s->m_cfg.m_providers.front());
const config_method_ttls *cfg_method = dynamic_cast<const config_method_ttls*>(cfg_prov.m_methods.front().get());
assert(cfg_method);
// Unpack credentials. // Unpack credentials.
s->m_cred.m_inner.reset(cfg_method->m_inner->make_credentials());
unpack(s->m_cred, pUserData, dwUserDataSize); unpack(s->m_cred, pUserData, dwUserDataSize);
config_method_ttls *cfg_method;
for (config_connection::provider_list::iterator cfg_prov = s->m_cfg.m_providers.begin(), cfg_prov_end = s->m_cfg.m_providers.end();; ++cfg_prov) {
if (cfg_prov != cfg_prov_end) {
if (_wcsicmp(cfg_prov->m_id.c_str(), s->m_cred.m_id.c_str()) == 0) {
// Matching provider found.
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());
cfg_method = dynamic_cast<config_method_ttls*>(cfg_prov->m_methods.front().get());
break;
}
} else
throw invalid_argument(string_printf(__FUNCTION__ " Credentials do not match to any provider ID within this connection configuration (provider ID: %ls).", s->m_cred.m_id.c_str()).c_str());
}
// We have configuration, we have credentials, create method.
s->m_method.reset(new method_ttls(*this, *cfg_method, *(credentials_ttls*)s->m_cred.m_cred.get()));
// Initialize method. // Initialize method.
s->m_method.begin_session(dwFlags, pAttributeArray, hTokenImpersonateUser, dwMaxSendPacketSize); s->m_method->begin_session(dwFlags, pAttributeArray, hTokenImpersonateUser, dwMaxSendPacketSize);
return s.release(); return s.release();
} }
@@ -284,7 +245,7 @@ void eap::peer_ttls::process_request_packet(
_Inout_ EapPeerMethodOutput *pEapOutput) _Inout_ EapPeerMethodOutput *pEapOutput)
{ {
assert(dwReceivedPacketSize == ntohs(*(WORD*)pReceivedPacket->Length)); assert(dwReceivedPacketSize == ntohs(*(WORD*)pReceivedPacket->Length));
static_cast<session*>(hSession)->m_method.process_request_packet(pReceivedPacket, dwReceivedPacketSize, pEapOutput); static_cast<session*>(hSession)->m_method->process_request_packet(pReceivedPacket, dwReceivedPacketSize, pEapOutput);
} }
@@ -293,7 +254,7 @@ void eap::peer_ttls::get_response_packet(
_Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket, _Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket,
_Inout_ DWORD *pdwSendPacketSize) _Inout_ DWORD *pdwSendPacketSize)
{ {
static_cast<session*>(hSession)->m_method.get_response_packet(pSendPacket, pdwSendPacketSize); static_cast<session*>(hSession)->m_method->get_response_packet(pSendPacket, pdwSendPacketSize);
} }
@@ -302,7 +263,27 @@ void eap::peer_ttls::get_result(
_In_ EapPeerMethodResultReason reason, _In_ EapPeerMethodResultReason reason,
_Inout_ EapPeerMethodResult *ppResult) _Inout_ EapPeerMethodResult *ppResult)
{ {
static_cast<session*>(hSession)->m_method.get_result(reason, ppResult); session *s = static_cast<session*>(hSession);
s->m_method->get_result(reason, ppResult);
s->m_eap_attr_desc.dwNumberOfAttributes = (DWORD)s->m_method->m_eap_attr.size();
s->m_eap_attr_desc.pAttribs = s->m_method->m_eap_attr.data();
ppResult->pAttribArray = &s->m_eap_attr_desc;
if (ppResult->fSaveConnectionData) {
pack(s->m_cfg, &ppResult->pConnectionData, &ppResult->dwSizeofConnectionData);
if (s->m_blob_cfg)
free_memory(s->m_blob_cfg);
s->m_blob_cfg = ppResult->pConnectionData;
}
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
ppResult->fSaveUserData = TRUE;
pack(s->m_cred, &ppResult->pUserData, &ppResult->dwSizeofUserData);
if (s->m_blob_cred)
free_memory(s->m_blob_cred);
s->m_blob_cred = ppResult->pUserData;
#endif
} }
@@ -356,3 +337,119 @@ void eap::peer_ttls::set_response_attributes(
throw win_runtime_error(ERROR_NOT_SUPPORTED, __FUNCTION__ " Not supported."); throw win_runtime_error(ERROR_NOT_SUPPORTED, __FUNCTION__ " Not supported.");
} }
const eap::config_method_ttls* eap::peer_ttls::combine_credentials(
_In_ DWORD dwFlags,
_In_ const config_connection &cfg,
_In_count_(dwUserDataSize) const BYTE *pUserData,
_In_ DWORD dwUserDataSize,
_Out_ credentials_connection& cred_out,
_In_ HANDLE hTokenImpersonateUser)
{
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
// Unpack cached credentials.
credentials_connection cred_in(*this, cfg);
if (dwUserDataSize)
unpack(cred_in, pUserData, dwUserDataSize);
#else
UNREFERENCED_PARAMETER(pUserData);
UNREFERENCED_PARAMETER(dwUserDataSize);
#endif
user_impersonator impersonating(hTokenImpersonateUser);
for (config_connection::provider_list::const_iterator cfg_prov = cfg.m_providers.cbegin(), cfg_prov_end = cfg.m_providers.cend(); cfg_prov != cfg_prov_end; ++cfg_prov) {
// Get method configuration.
if (cfg_prov->m_methods.empty()) {
log_event(&EAPMETHOD_TRACE_EVT_CRED_NO_METHOD, event_data(cfg_prov->m_id), event_data::blank);
continue;
}
const config_method_ttls *cfg_method = dynamic_cast<const config_method_ttls*>(cfg_prov->m_methods.front().get());
assert(cfg_method);
// Combine credentials. We could use eap::credentials_ttls() to do all the work, but we would not know which credentials is missing then.
credentials_ttls *cred = (credentials_ttls*)cfg_method->make_credentials();
cred_out.m_cred.reset(cred);
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
bool is_own = cred_in.m_cred && _wcsicmp(cred_in.m_id.c_str(), cfg_prov->m_id.c_str()) == 0;
#endif
// Combine outer credentials.
LPCTSTR target_name = (dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? cfg_prov->m_id.c_str() : NULL;
eap::credentials::source_t src_outer = cred->credentials_tls::combine(
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
is_own ? cred_in.m_cred.get() : NULL,
#else
NULL,
#endif
*cfg_method,
target_name);
if (src_outer == eap::credentials::source_unknown) {
log_event(&EAPMETHOD_TRACE_EVT_CRED_UNKNOWN3, event_data(cfg_prov->m_id), event_data((unsigned int)eap_type_tls), event_data::blank);
continue;
}
// Combine inner credentials.
eap::credentials::source_t src_inner = cred->m_inner->combine(
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
is_own ? ((credentials_ttls*)cred_in.m_cred.get())->m_inner.get() : NULL,
#else
NULL,
#endif
*cfg_method->m_inner,
target_name);
if (src_inner == eap::credentials::source_unknown) {
log_event(&EAPMETHOD_TRACE_EVT_CRED_UNKNOWN3, event_data(cfg_prov->m_id), event_data((unsigned int)cfg_method->m_inner->get_method_id()), event_data::blank);
continue;
}
// If we got here, we have all credentials we need. But, wait!
if ((dwFlags & EAP_FLAG_MACHINE_AUTH) == 0) {
if (cfg_method->m_auth_failed) {
// Outer: Credentials failed on last connection attempt.
log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM1, event_data(cfg_prov->m_id), event_data((unsigned int)eap_type_tls), event_data::blank);
continue;
}
if (cfg_method->m_inner->m_auth_failed) {
// Inner: Credentials failed on last connection attempt.
log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM1, event_data(cfg_prov->m_id), event_data((unsigned int)cfg_method->m_inner->get_method_id()), event_data::blank);
continue;
}
}
cred_out.m_id = cfg_prov->m_id;
return cfg_method;
}
return NULL;
}
//////////////////////////////////////////////////////////////////////
// eap::peer_ttls::session
//////////////////////////////////////////////////////////////////////
eap::peer_ttls::session::session(_In_ module &mod) :
m_module(mod),
m_cfg(mod),
m_cred(mod, m_cfg),
m_blob_cfg(NULL)
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
, m_blob_cred(NULL)
#endif
{}
eap::peer_ttls::session::~session()
{
if (m_blob_cfg)
m_module.free_memory(m_blob_cfg);
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
if (m_blob_cred)
m_module.free_memory(m_blob_cred);
#endif
}

View File

@@ -27,6 +27,7 @@
#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 "../../EAPBase/include/EAPXML.h" #include "../../EAPBase/include/EAPXML.h"

View File

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

View File

@@ -242,7 +242,7 @@
<property name="window_extra_style"></property> <property name="window_extra_style"></property>
<property name="window_name"></property> <property name="window_name"></property>
<property name="window_style"></property> <property name="window_style"></property>
<property name="wrap">446</property> <property name="wrap">445</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,6 +23,9 @@
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
@@ -102,26 +105,7 @@ void eap::peer_ttls_ui::invoke_config_ui(
// Load existing configuration. // Load existing configuration.
unpack(cfg, pConnectionDataIn, dwConnectionDataInSize); unpack(cfg, pConnectionDataIn, dwConnectionDataInSize);
} else { } else {
// This is a blank network profile. Create default configuraton. // This is a blank network profile. `cfg` is already set to defaults.
// Inner configuration: PAP
config_method_pap *cfg_method_inner = new config_method_pap(*this);
cfg_method_inner->m_use_preshared = false;
cfg_method_inner->m_preshared(new credentials_pap(*this));
// Outer configuration
unique_ptr<config_method_ttls> cfg_method(new config_method_ttls(*this));
cfg_method->m_anonymous_identity = L"@";
cfg_method->m_use_preshared = true;
cfg_method->m_preshared.reset(new credentials_tls(*this));
cfg_method->m_inner.reset(cfg_method_inner);
// One method
config_provider cfg_provider(*this);
cfg_provider.m_methods.push_back(std::move(cfg_method));
// One provider
cfg.m_providers.push_back(std::move(cfg_provider));
} }
int result; int result;
@@ -170,51 +154,21 @@ void eap::peer_ttls_ui::invoke_identity_ui(
config_connection cfg(*this); config_connection cfg(*this);
unpack(cfg, pConnectionData, dwConnectionDataSize); unpack(cfg, pConnectionData, dwConnectionDataSize);
// Get method configuration.
if (cfg.m_providers.empty() || cfg.m_providers.front().m_methods.empty())
throw invalid_argument(__FUNCTION__ " Configuration has no providers and/or methods.");
const config_provider &cfg_prov(cfg.m_providers.front());
config_method_ttls *cfg_method = dynamic_cast<config_method_ttls*>(cfg_prov.m_methods.front().get());
assert(cfg_method);
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE #ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
// Unpack cached credentials. // Unpack cached credentials.
credentials_ttls cred_in(*this); credentials_connection cred_in(*this, cfg);
if (dwUserDataSize) { if (dwUserDataSize)
s->m_cred.m_inner.reset(cfg_method->m_inner->make_credentials());
unpack(cred_in, pUserData, dwUserDataSize); unpack(cred_in, pUserData, dwUserDataSize);
}
#else #else
UNREFERENCED_PARAMETER(pUserData); UNREFERENCED_PARAMETER(pUserData);
UNREFERENCED_PARAMETER(dwUserDataSize); UNREFERENCED_PARAMETER(dwUserDataSize);
#endif #endif
credentials_ttls cred_out(*this); credentials_connection cred_out(*this, cfg);
cred_out.m_inner.reset(cfg_method->m_inner->make_credentials()); config_method_ttls *cfg_method = NULL;
// Combine credentials. Outer and inner separately to get the idea which one is missing. vector<pair<config_method_ttls*, credentials_connection> > cred_method_store;
eap::credentials::source_t cred_source = cred_out.credentials_tls::combine( cred_method_store.reserve(cfg.m_providers.size());
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
&cred_in,
#else
NULL,
#endif
*cfg_method,
(dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? cfg_prov.m_id.c_str() : NULL);
eap::credentials::source_t cred_source_inner = cred_out.m_inner->combine(
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
cred_in.m_inner.get(),
#else
NULL,
#endif
*cfg_method->m_inner,
(dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? cfg_prov.m_id.c_str() : NULL);
if (dwFlags & EAP_FLAG_GUEST_ACCESS) {
// Disable credential saving for guests.
cfg_method->m_allow_save = false;
cfg_method->m_inner->m_allow_save = false;
}
int result; int result;
{ {
@@ -228,23 +182,92 @@ void eap::peer_ttls_ui::invoke_identity_ui(
parent.AdoptAttributesFromHWND(); parent.AdoptAttributesFromHWND();
wxTopLevelWindows.Append(&parent); wxTopLevelWindows.Append(&parent);
// Create credentials dialog. // Create credentials dialog and populate it with providers.
wxEAPCredentialsDialog dlg(cfg_prov, &parent); bool combined = false;
wxTTLSCredentialsPanel *panel = new wxTTLSCredentialsPanel(cfg_prov, *cfg_method, cred_out, cfg_prov.m_id.c_str(), &dlg); wxEAPCredentialsConnectionDialog dlg(&parent);
dlg.AddContent(panel); for (config_connection::provider_list::iterator cfg_prov = cfg.m_providers.begin(), cfg_prov_end = cfg.m_providers.end(); cfg_prov != cfg_prov_end; ++cfg_prov) {
// Get method configuration.
if (cfg_prov->m_methods.empty()) {
log_event(&EAPMETHOD_TRACE_EVT_CRED_NO_METHOD, event_data(cfg_prov->m_id), event_data::blank);
continue;
}
config_method_ttls *cfg_method = dynamic_cast<config_method_ttls*>(cfg_prov->m_methods.front().get());
assert(cfg_method);
// Prepare new set of credentials for given provider.
credentials_connection cred_method(*this, cfg);
cred_method.m_id = cfg_prov->m_id;
credentials_ttls *_cred_method = (credentials_ttls*)cfg_method->make_credentials();
cred_method.m_cred.reset(_cred_method);
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
bool is_own = cred_in.m_cred && _wcsicmp(cred_in.m_id.c_str(), cfg_prov->m_id.c_str()) == 0;
#endif
// Combine outer credentials.
LPCTSTR target_name = (dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? cfg_prov->m_id.c_str() : NULL;
eap::credentials::source_t src_outer = _cred_method->credentials_tls::combine(
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
is_own ? cred_in.m_cred.get() : NULL,
#else
NULL,
#endif
*cfg_method,
target_name);
// Combine inner credentials.
eap::credentials::source_t src_inner = _cred_method->m_inner->combine(
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
is_own ? ((credentials_ttls*)cred_in.m_cred.get())->m_inner.get() : NULL,
#else
NULL,
#endif
*cfg_method->m_inner,
target_name);
if (dwFlags & EAP_FLAG_GUEST_ACCESS) {
// Disable credential saving for guests.
cfg_method->m_allow_save = false;
cfg_method->m_inner->m_allow_save = false;
}
// Create method credentials panel.
wxTTLSCredentialsPanel *panel = new wxTTLSCredentialsPanel(*cfg_prov, *cfg_method, *_cred_method, cfg_prov->m_id.c_str(), dlg.m_providers);
// Set "Remember" checkboxes according to credential source, // Set "Remember" checkboxes according to credential source,
panel->m_outer_cred->SetRemember(cred_source == eap::credentials::source_storage); panel->m_outer_cred->SetRemember(src_outer == eap::credentials::source_storage);
panel->m_inner_cred->SetRemember(cred_source_inner == eap::credentials::source_storage); panel->m_inner_cred->SetRemember(src_inner == eap::credentials::source_storage);
// Add panel to choice-book. Select the first one to have known sources.
if (!combined && src_outer != eap::credentials::source_unknown && src_inner != eap::credentials::source_unknown) {
if (dlg.m_providers->AddPage(panel, wxEAPGetProviderName(cfg_prov->m_name), true)) {
cred_method_store.push_back(pair<config_method_ttls*, credentials_connection>(cfg_method, std::move(cred_method)));
combined = true;
}
} else
if (dlg.m_providers->AddPage(panel, wxEAPGetProviderName(cfg_prov->m_name), false))
cred_method_store.push_back(pair<config_method_ttls*, credentials_connection>(cfg_method, std::move(cred_method)));
}
// Update dialog layout.
dlg.Layout();
dlg.GetSizer()->Fit(&dlg);
// Centre and display dialog. // Centre and display dialog.
dlg.Centre(wxBOTH); dlg.Centre(wxBOTH);
result = dlg.ShowModal(); result = dlg.ShowModal();
if (result == wxID_OK) { if (result == wxID_OK) {
int idx_prov = dlg.m_providers->GetSelection();
if (idx_prov != wxNOT_FOUND) {
wxTTLSCredentialsPanel *panel = dynamic_cast<wxTTLSCredentialsPanel*>(dlg.m_providers->GetPage(idx_prov));
pair<config_method_ttls*, credentials_connection> &res = cred_method_store[idx_prov];
cfg_method = res.first;
cred_out = res.second;
credentials_ttls *_cred_out = dynamic_cast<credentials_ttls*>(cred_out.m_cred.get());
// 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(cfg_prov.m_id.c_str()); _cred_out->credentials_tls::store(cred_out.m_id.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 (...) {
@@ -254,13 +277,15 @@ 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(cfg_prov.m_id.c_str()); _cred_out->m_inner->store(cred_out.m_id.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 (...) {
wxLogError(_("Writing credentials failed.")); wxLogError(_("Writing credentials failed."));
} }
} }
} else
result = wxID_CANCEL;
} }
wxTopLevelWindows.DeleteObject(&parent); wxTopLevelWindows.DeleteObject(&parent);
@@ -272,7 +297,7 @@ void eap::peer_ttls_ui::invoke_identity_ui(
throw win_runtime_error(ERROR_CANCELLED, __FUNCTION__ " Cancelled."); throw win_runtime_error(ERROR_CANCELLED, __FUNCTION__ " Cancelled.");
// Build our identity. ;) // Build our identity. ;)
wstring identity(move(cfg_method->get_public_identity(cred_out))); wstring identity(std::move(cfg_method->get_public_identity((const credentials_ttls&)*cred_out.m_cred)));
log_event(&EAPMETHOD_TRACE_EVT_CRED_OUTER_ID1, event_data((unsigned int)eap_type_ttls), event_data(identity), event_data::blank); log_event(&EAPMETHOD_TRACE_EVT_CRED_OUTER_ID1, event_data((unsigned int)eap_type_ttls), event_data(identity), event_data::blank);
size_t size = sizeof(WCHAR)*(identity.length() + 1); size_t size = sizeof(WCHAR)*(identity.length() + 1);
*ppwszIdentity = (WCHAR*)alloc_memory(size); *ppwszIdentity = (WCHAR*)alloc_memory(size);
@@ -306,6 +331,10 @@ void eap::peer_ttls_ui::invoke_interactive_ui(
wxInitializerPeer::wxInitializerPeer(_In_ HINSTANCE instance) wxInitializerPeer::wxInitializerPeer(_In_ HINSTANCE instance)
{ {
wxCriticalSectionLocker locker(s_lock);
if (s_init_ref_count++)
return;
// Initialize application. // Initialize application.
new wxApp(); new wxApp();
wxEntryStart(instance); wxEntryStart(instance);
@@ -321,5 +350,9 @@ wxInitializerPeer::wxInitializerPeer(_In_ HINSTANCE instance)
wxInitializerPeer::~wxInitializerPeer() wxInitializerPeer::~wxInitializerPeer()
{ {
wxCriticalSectionLocker locker(s_lock);
if (--s_init_ref_count)
return;
wxEntryCleanup(); wxEntryCleanup();
} }

View File

@@ -28,3 +28,4 @@
#include "../../PAP_UI/include/PAP_UI.h" #include "../../PAP_UI/include/PAP_UI.h"
#include <wx/app.h> #include <wx/app.h>
#include <wx/thread.h>

View File

@@ -1,3 +1,4 @@
/GEANTLink*.msi /GEANTLink*.msi
/CredWrite.exe /CredWrite.exe
/MsiUseFeature.exe /MsiUseFeature.exe
/WLANManager.exe