Compare commits

...

36 Commits

Author SHA1 Message Date
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
75892b78c0 Version set to 1.0-alpha14 2016-08-28 23:00:27 +02:00
7c938fe291 OnUpdateUI() event handlers optimized to reduce ridiculous CPU consumption of GUI & Incorrect page-provider mapping in wxEAPConfigDialog<> fixed 2016-08-28 22:58:41 +02:00
497f4eca8a wxEAPCredentialsConfigPanel upgraded to use full retrieval of credentials from the store, allowing certificate credentials to display their name again 2016-08-28 20:11:10 +02:00
770b56e2cf credentials::get_name() now distinguish between empty credentials and blank identity 2016-08-28 20:06:54 +02:00
df680e74f6 TLS credentials are considered empty regardless the state of custom identity setting now 2016-08-28 20:05:41 +02:00
e66a7eb9ba dePAPization continues to pave the road for seamless MSCHAPv2 integration 2016-08-28 20:04:45 +02:00
6c66862eed TTLS config and credentials are now expected to always have inner config and credentials object present; it can be blank, but it must not be nullptr 2016-08-28 17:43:06 +02:00
fc5e54db05 Inner configuration/credential management virtualized to reduce cluttering code 2016-08-28 17:20:24 +02:00
d20aafb3ff Identity selection revised to support cases where TLS certificate is present but contains no usable username 2016-08-28 16:38:13 +02:00
8ce7154a77 Loading credentials from XML allows <UserName> absence and assumes blank identity in this case now 2016-08-28 15:46:30 +02:00
d926ea66b0 Sub-module update 2016-08-28 13:42:47 +02:00
3baa77d3bb WLANManager utility introduced
(closes #7)
2016-08-28 12:22:04 +02:00
25eb6d8d72 32-bit C++ compiler warning resolved 2016-08-27 21:18:06 +02:00
349508701c Support for localization added to MSI setup
(closes #9)
2016-08-27 21:17:46 +02:00
9f770bbb3f peer_ttls_ui now initializes wxWidgets further to support localization 2016-08-27 17:54:00 +02:00
bc1c56174a UI language in registry is ll_CC format now 2016-08-27 17:28:30 +02:00
db585975e8 Saving event source set to registry simplified to reduce registry clutter 2016-08-27 17:22:28 +02:00
8bf99423c8 Slovenian localization files added 2016-08-27 16:47:48 +02:00
249c4db1de Default column widths adjusted to better fit the content initially 2016-08-27 16:42:39 +02:00
3dd8f26c94 Registry settings key names changed as separate manufacturer name introduced 2016-08-27 16:41:26 +02:00
4a9d496ba1 Log trace control named for more logical name of settings in registry 2016-08-27 15:49:54 +02:00
6f5bbeffa2 UI text updated 2016-08-27 15:45:31 +02:00
94 changed files with 2985 additions and 968 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

@@ -127,8 +127,13 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\build\EAPMethodUI.def" /> <None Include="..\build\EAPMethodUI.def" />
<None Include="..\locale\EAPMethods.pot" />
</ItemGroup>
<ItemGroup>
<POCompile Include="..\locale\sl_SI.po" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
<Import Project="..\..\include\xgettext.targets" />
</ImportGroup> </ImportGroup>
</Project> </Project>

View File

@@ -13,6 +13,10 @@
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter> </Filter>
<Filter Include="Resource Files\Localization">
<UniqueIdentifier>{e43059ae-37ac-4b28-84fb-18d1b3972b30}</UniqueIdentifier>
<Extensions>po;pot</Extensions>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="StdAfx.h"> <ClInclude Include="StdAfx.h">
@@ -36,5 +40,13 @@
<None Include="..\build\EAPMethodUI.def"> <None Include="..\build\EAPMethodUI.def">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</None> </None>
<None Include="..\locale\EAPMethods.pot">
<Filter>Resource Files\Localization</Filter>
</None>
</ItemGroup>
<ItemGroup>
<POCompile Include="..\locale\sl_SI.po">
<Filter>Resource Files\Localization</Filter>
</POCompile>
</ItemGroup> </ItemGroup>
</Project> </Project>

Binary file not shown.

1
EAPMethods/locale/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/*.mo

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-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@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"
@@ -27,7 +27,7 @@ msgstr ""
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:174 lib/EAPBase_UI/res/wxEAP_UI.cpp:299
msgid "Client Credentials" msgid "Client Credentials"
msgstr "" msgstr ""
@@ -77,144 +77,144 @@ msgstr ""
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:310
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:320
msgid "User ID:" msgid "User ID:"
msgstr "" msgstr ""
#: 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 "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:326 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:329
msgid "Password:" msgid "Password:"
msgstr "" msgstr ""
#: 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 "" msgstr ""
#: 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 "" msgstr ""
#: 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 "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:361 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:364
msgid "Your Organization" msgid "Your Organization"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:372 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:375
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:382
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:387
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:391
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:401
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: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 "" msgstr ""
#: 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 "" msgstr ""
#: 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 "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:471 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:468
msgid "Configuration Lock" msgid "Configuration Lock"
msgstr "" msgstr ""
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:482 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:479
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:486
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:489
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: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 "" msgstr ""
#: 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 "" msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:120 #: lib/EAPBase_UI/src/EAP_UI.cpp:130
msgid "your provider" msgid "your provider"
msgstr "" msgstr ""
#: 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 "" msgstr ""
#: 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 "" msgstr ""
#: 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 "" msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:180 #: lib/EAPBase_UI/src/EAP_UI.cpp:191
#, 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:193
#, 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:193
msgid "Your provider" msgid "Your provider"
msgstr "" msgstr ""
#: lib/EAPBase_UI/src/EAP_UI.cpp:201 #: lib/EAPBase_UI/src/EAP_UI.cpp:213
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 +323,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,69 +388,68 @@ 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: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 ""
#: 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 "" 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:283
msgid "EAP Credentials" msgid "EAP Credentials"
msgstr "" msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:422 #: lib/EAPBase_UI/include/EAP_UI.h:443
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:600
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:633
#, c-format
msgid "<error %u>"
msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:637
msgid "<error>"
msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:646 lib/EAPBase_UI/include/EAP_UI.h:657
msgid "<empty credentials>"
msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:649 lib/EAPBase_UI/include/EAP_UI.h:660
msgid "<blank identity>"
msgstr ""
#: lib/EAPBase_UI/include/EAP_UI.h:866
msgid "<Your Organization>" msgid "<Your Organization>"
msgstr "" msgstr ""
#: 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 "" msgstr ""

530
EAPMethods/locale/sl_SI.po Normal file
View File

@@ -0,0 +1,530 @@
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: EAPMethods\n"
"POT-Creation-Date: 2016-08-28 23:08+0200\n"
"PO-Revision-Date: 2016-06-02 12:27+0200\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"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: sl_SI\n"
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n"
"X-Generator: Poedit 1.8.8\n"
"X-Poedit-Basepath: ../..\n"
"X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: lib/EAPBase_UI\n"
"X-Poedit-SearchPath-1: lib/PAP_UI\n"
"X-Poedit-SearchPath-2: lib/TLS_UI\n"
"X-Poedit-SearchPath-3: lib/TTLS_UI\n"
"X-Poedit-SearchPath-4: EAPMethods\n"
"X-Poedit-SourceCharset: UTF-8\n"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:37
msgid "Advanced..."
msgstr "Napredno ..."
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:38
msgid "Opens dialog with provider settings"
msgstr "Odpre dialog z nastavitvami ponudnika"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:174 lib/EAPBase_UI/res/wxEAP_UI.cpp:299
msgid "Client Credentials"
msgstr "Odjemalčeve poverilnice"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:185
msgid "Manage credentials used to connect."
msgstr "Upravljajte s poverilnicami za povezovanje."
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:198
msgid "Use &own credentials:"
msgstr "Uporabi sv&oje poverilnice:"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:199
msgid "Select this option if you have your unique credentials to connect"
msgstr "Izberite to možnost, če imate svoje lastne poverilnice za povezovanje"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:204
msgid "Your credentials loaded from Windows Credential Manager"
msgstr "Vaše poverilnice naložene iz upravitelja poverilnic Windows"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:214
msgid "&Clear Credentials"
msgstr "Počisti poverilni&ce"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:215
msgid ""
"Click to clear your credentials from Credential Manager.\n"
"Note: You will be prompted to enter credentials when connecting."
msgstr ""
"Kliknite, da počistite svoje poverilnice iz upravitelja poverilnic.\n"
"Opomba: Za vnos poverilnic boste pozvani ob povezovanju."
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:219 lib/EAPBase_UI/res/wxEAP_UI.cpp:252
msgid "&Set Credentials..."
msgstr "Na&stavi poverilnice ..."
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:220 lib/EAPBase_UI/res/wxEAP_UI.cpp:253
msgid "Click here to set or modify your credentials"
msgstr "Kliknite tukaj, da nastavite ali spremenite svoje poverilnice"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:236
msgid "Use &pre-shared credentials:"
msgstr "Uporabi sku&pne poverilnice:"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:237
msgid "Select this options if all clients connect using the same credentials"
msgstr ""
"Izberite to možnost, kadar se vsi odjemalci povezujejo z istimi "
"poverilnicami"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:242
msgid "Common (pre-shared) credentials"
msgstr "Skupne (deljene) poverilnice"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:310
msgid "Please provide your user ID and password."
msgstr "Vnesite svoj uporabniški ID in geslo."
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:320
msgid "User ID:"
msgstr "Uporabniški ID:"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:325
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.)"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:329
msgid "Password:"
msgstr "Geslo:"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:334
msgid "Enter your password here"
msgstr "Tukaj vnesite svoje geslo"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:341 lib/TLS_UI/res/wxTLS_UI.cpp:183
msgid "&Remember"
msgstr "Za&pomni si"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:342
msgid "Check if you would like to save username and password"
msgstr "Odkljukajte, če želite shraniti up. ime in geslo"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:364
msgid "Your Organization"
msgstr "Vaša organizacija"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:375
msgid ""
"Describe your organization to customize user prompts. When organization is "
"introduced, end-users find program messages easier to understand and act."
msgstr ""
"Opišite svojo organizacijo za up. pozive po meri. Kadar se organizacija "
"predstavi, uporabniki lažje razumejo sporočila programa in ustrezneje "
"reagirajo."
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:382
msgid "Your organization &name:"
msgstr "Ime vaše orga&nizacije:"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:387
msgid ""
"Your organization name as it will appear on helpdesk contact notifications"
msgstr ""
"Ime vaše organizacije, kot bo nastopalo na obvestilih s stikom na center za "
"pomoč"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:391
msgid "(Keep it short, please)"
msgstr "(Naj bo kratko, prosim)"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:401
msgid "Helpdesk contact &information:"
msgstr "Podatk&i centra za pomoč:"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:411
msgid "¶"
msgstr "¶"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:418
msgid "Your helpdesk website address"
msgstr "Naslov spletne strani vašega centra za pomoč"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:422
msgid "*"
msgstr "*"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:429
msgid "Your helpdesk e-mail address"
msgstr "E-poštni naslov vašega centra za pomoč"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:433
msgid ")"
msgstr ")"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:440
msgid "Your helpdesk phone number"
msgstr "Telefonska številka vašega centra za pomoč"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:468
msgid "Configuration Lock"
msgstr "Zaklep konfiguracije"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:479
msgid ""
"Your configuration can be locked to prevent accidental modification by end-"
"users. Users will only be allowed to enter credentials."
msgstr ""
"Svojo konfiguracijo lahko zaklenete in preprečite končnim uporabnikom "
"nenamerno spreminjanje. Uporabniki bodo lahko vnašali samo poverilnice."
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:486
msgid ""
"&Lock this configuration and prevent any further modification via user "
"interface."
msgstr ""
"Zak&leni to konfiguracijo in prepreči vse nadaljnje spremembe preko up. "
"vmesnika."
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:489
msgid "(Warning: Once locked, you can not revert using this dialog!)"
msgstr "(Pozor: Ko zaklenete, vrnitev ne bo več možna preko tega dialoga!)"
#: lib/EAPBase_UI/src/EAP_UI.cpp:98
#, c-format
msgid "%s Credentials"
msgstr "Poverilnice za %s"
#: lib/EAPBase_UI/src/EAP_UI.cpp:128
#, c-format
msgid "For additional help and instructions, please contact %s at:"
msgstr "Za dodtano pomoč ali navodila se obrnite na %s na:"
#: lib/EAPBase_UI/src/EAP_UI.cpp:130
#, c-format
msgid "your %ls provider"
msgstr "vaš ponudnik %ls"
#: lib/EAPBase_UI/src/EAP_UI.cpp:130
msgid "your provider"
msgstr "vaš ponudnik"
#: lib/EAPBase_UI/src/EAP_UI.cpp:149
msgid "Open the default web browser"
msgstr "Odpre privzeto nastavljen spletni brskalnik"
#: lib/EAPBase_UI/src/EAP_UI.cpp:160
msgid "Open your e-mail program"
msgstr "Odpre vaš program za e-pošto"
#: lib/EAPBase_UI/src/EAP_UI.cpp:171
msgid "Dial the phone number"
msgstr "Pokliče telefonsko številko"
#: lib/EAPBase_UI/src/EAP_UI.cpp:191
#, c-format
msgid ""
"%s has pre-set parts of this configuration. Those parts are locked to "
"prevent accidental modification."
msgstr ""
"%s je prednastavil dele te konfiguracije. Ti deli so zaklenjeni zaradi "
"preprečevanja nenamernih sprememb."
#: lib/EAPBase_UI/src/EAP_UI.cpp:193
#, c-format
msgid "Your %ls provider"
msgstr "Vaš ponudnik %ls"
#: lib/EAPBase_UI/src/EAP_UI.cpp:193
msgid "Your provider"
msgstr "Vaš ponudnik"
#: lib/EAPBase_UI/src/EAP_UI.cpp:213
msgid ""
"Previous attempt to connect failed. Please, make sure your credentials are "
"correct, or try again later."
msgstr ""
"Prejšnji poskus povezave ni uspel. Preverite, ali so vaše poverilnice "
"pravilne ali poskusite kasneje."
#: lib/TLS_UI/res/wxTLS_UI.cpp:17
msgid "Server Trust"
msgstr "Zaupanje strežniku"
#: lib/TLS_UI/res/wxTLS_UI.cpp:28
msgid ""
"Describe the servers you trust to prevent credential interception in case of"
" man-in-the-middle attacks."
msgstr ""
"Opišite strežnike, ki jim zaupate in preprečite prestrezanje poverilnic v "
"primeru napada \"vmesnega člena\"."
#: lib/TLS_UI/res/wxTLS_UI.cpp:35
msgid "Acceptable Certificate Authorities:"
msgstr "Sprejemljivi izdajatelji potrdil:"
#: lib/TLS_UI/res/wxTLS_UI.cpp:40
msgid "List of certificate authorities server's certificate must be issued by"
msgstr ""
"Seznam izdajateljev potrdil, od katerih mora biti izdano strežnikovo "
"potrdilo"
#: lib/TLS_UI/res/wxTLS_UI.cpp:47
msgid "Add CA from Store..."
msgstr "Dodaj CA iz shrambe ..."
#: lib/TLS_UI/res/wxTLS_UI.cpp:48
msgid ""
"Adds a new certificate authority from the certificate store to the list"
msgstr "Doda novega izdajatelja potrdil iz shrambe potrdil na seznam"
#: lib/TLS_UI/res/wxTLS_UI.cpp:52
msgid "Add CA from File..."
msgstr "Dodaj CA iz datoteke ..."
#: lib/TLS_UI/res/wxTLS_UI.cpp:53
msgid "Adds a new certificate authority from the file to the list"
msgstr "Doda novega izdajatelja potrdil iz datoteke na seznam"
#: lib/TLS_UI/res/wxTLS_UI.cpp:57
msgid "&Remove CA"
msgstr "Odst&rani CA"
#: lib/TLS_UI/res/wxTLS_UI.cpp:59
msgid "Removes selected certificate authorities from the list"
msgstr "Odstrani izbrane izdajatelje potrdil s seznama"
#: lib/TLS_UI/res/wxTLS_UI.cpp:72
msgid "Acceptable server &names:"
msgstr "Sprejemljiva ime&na strežnika:"
#: lib/TLS_UI/res/wxTLS_UI.cpp:77
msgid ""
"A semicolon delimited list of acceptable server FQDN names; blank to skip "
"name check; Unicode characters allowed"
msgstr ""
"S podpičji ločen seznam sprejemljivih strežnikovih imen FQDN; prazno, da "
"izpusti preverjanje imena; znaki Unicode dovoljeni"
#: lib/TLS_UI/res/wxTLS_UI.cpp:81
msgid "(Example: foo.bar.com;server2.bar.com)"
msgstr "(Primer: vzo.rec.si;streznik2.rec.si)"
#: lib/TLS_UI/res/wxTLS_UI.cpp:120
msgid "TLS Client Certificate"
msgstr "Odjemalčevo potrdilo TLS"
#: lib/TLS_UI/res/wxTLS_UI.cpp:131
msgid "Please select your client certificate to use for authentication."
msgstr "Izberite svoje odjemalčevo potrdilo za uporabo med overovljanjem."
#: lib/TLS_UI/res/wxTLS_UI.cpp:138
msgid "Co&nnect without providing a client certificate"
msgstr "Poveži brez dostave &odjemalčevega potrdila"
#: lib/TLS_UI/res/wxTLS_UI.cpp:139
msgid ""
"Select if your server does not require you to provide a client certificate"
msgstr ""
"Izberite, če vaš strežnik ne zahteva, da mu dostavite odjemalčevo potrdilo"
#: lib/TLS_UI/res/wxTLS_UI.cpp:146
msgid "Use the following &certificate:"
msgstr "Uporabi naslednje &potrdilo:"
#: lib/TLS_UI/res/wxTLS_UI.cpp:147
msgid "Select if you need to provide a client certificate when connecting"
msgstr "Izberite, če morate dostaviti odjemalčevo potrdilo ob povezavi"
#: lib/TLS_UI/res/wxTLS_UI.cpp:154
msgid "Client certificate to use for authentication"
msgstr "Odjemalčevo potrdilo za overovljanje"
#: lib/TLS_UI/res/wxTLS_UI.cpp:167
msgid "Custom &identity:"
msgstr "&Identiteta po meri:"
#: lib/TLS_UI/res/wxTLS_UI.cpp:172
msgid ""
"Your identity (username@domain) to override one from certificate; or blank "
"to use one provided in certificate"
msgstr ""
"Vaša identiteta (up. ime@domena), ki bo nadomestila tisto s potrdila; ali "
"prazno, če želite uporabiti tisto s potrdila"
#: lib/TLS_UI/res/wxTLS_UI.cpp:176
msgid "(Example: user@contoso.com)"
msgstr "(Primer: uporabnik@vzorec.si)"
#: lib/TLS_UI/res/wxTLS_UI.cpp:184
msgid "Check if you would like to save certificate selection"
msgstr "Odkljukajte, če želite shraniti izbor potrdila"
#: lib/TLS_UI/src/TLS_UI.cpp:118
#, c-format
msgid "Invalid character in host name found: %c"
msgstr "Napačen znak v imenu gostitelja: %c"
#: lib/TLS_UI/src/TLS_UI.cpp:118
msgid "Validation conflict"
msgstr "Nesoglasje pri preverjanju"
#: lib/TLS_UI/src/TLS_UI.cpp:511
msgid "Add Certificate"
msgstr "Dodaj potrdilo"
#: lib/TLS_UI/src/TLS_UI.cpp:512
msgid "Certificate Files (*.cer;*.crt;*.der;*.p7b;*.pem)"
msgstr "Datoteke s potrdili (*.cer;*.crt;*.der;*.p7b;*.pem)"
#: lib/TLS_UI/src/TLS_UI.cpp:513
msgid "X.509 Certificate Files (*.cer;*.crt;*.der;*.pem)"
msgstr "Datoteke s potrdili X.509 (*.cer;*.crt;*.der;*.pem)"
#: lib/TLS_UI/src/TLS_UI.cpp:514
msgid "PKCS #7 Certificate Files (*.p7b)"
msgstr "Datoteke s potrdili PKCS #7 (*.p7b)"
#: lib/TLS_UI/src/TLS_UI.cpp:515
msgid "All Files (*.*)"
msgstr "Vse datoteke (*.*)"
#: lib/TLS_UI/src/TLS_UI.cpp:531
#, c-format
msgid "Invalid or unsupported certificate file %s"
msgstr "Napačna ali nepodprta datoteka s potrdilom %s"
#: lib/TLS_UI/src/TLS_UI.cpp:531
msgid "Error"
msgstr "Napaka"
#: lib/TTLS_UI/res/wxTTLS_UI.cpp:17
msgid "Outer Identity"
msgstr "Zunanja identiteta"
#: lib/TTLS_UI/res/wxTTLS_UI.cpp:28
msgid "Select the user ID supplicant introduces itself as to authenticator:"
msgstr ""
"Izberite uporabniško identiteto, s katerim se prosilec predstavi "
"overovitelju:"
#: lib/TTLS_UI/res/wxTTLS_UI.cpp:35
msgid "&True identity"
msgstr "Prava iden&titeta"
#: lib/TTLS_UI/res/wxTTLS_UI.cpp:36
msgid "Use my true user name"
msgstr "Uporabi moje pravo uporabniško ime"
#: lib/TTLS_UI/res/wxTTLS_UI.cpp:40
msgid "Use &empty outer identity (RFC 4822)"
msgstr "Uporabi prazno zunanjo id&entiteto (RFC 4822)"
#: lib/TTLS_UI/res/wxTTLS_UI.cpp:41
msgid "Ommit my user name and use @mydomain.org only"
msgstr "Izpusti moje uporabniško ime in uporabi samo @mojadomena.si"
#: lib/TTLS_UI/res/wxTTLS_UI.cpp:48
msgid "&Custom outer identity:"
msgstr "Zunanja identiteta po &meri:"
#: lib/TTLS_UI/res/wxTTLS_UI.cpp:49
msgid "Specify custom outer identity"
msgstr "Navedite zunanjo identiteto po meri"
#: lib/TTLS_UI/res/wxTTLS_UI.cpp:54
msgid "Custom outer identity to use"
msgstr "Zunanja identiteta po meri za uporabo"
#: lib/TTLS_UI/src/Module.cpp:249 lib/TTLS_UI/src/Module.cpp:259
#: lib/EAPBase_UI/include/EAP_UI.h:584
#, c-format
msgid "Error writing credentials to Credential Manager: %hs (error %u)"
msgstr ""
"Napaka pri zapisovanju poverilnic v upravitelja poverilnic: %hs (napaka %u)"
#: lib/TTLS_UI/src/Module.cpp:251 lib/TTLS_UI/src/Module.cpp:261
#: lib/EAPBase_UI/include/EAP_UI.h:587
msgid "Writing credentials failed."
msgstr "Zapisovanje poverilnic ni uspelo."
#: lib/TTLS_UI/src/TTLS_UI.cpp:107 lib/TTLS_UI/src/TTLS_UI.cpp:220
msgid "Inner Authentication"
msgstr "Notranje overovljanje"
#: lib/TTLS_UI/src/TTLS_UI.cpp:113
msgid "Select inner authentication method from the list"
msgstr "Izberite postopek notranjega overovljanja s seznama"
#: lib/TTLS_UI/src/TTLS_UI.cpp:115
msgid "PAP"
msgstr "PAP"
#: lib/TTLS_UI/src/TTLS_UI.cpp:120 lib/TTLS_UI/src/TTLS_UI.cpp:241
msgid "Outer Authentication"
msgstr "Zunanje overovljanje"
#: lib/EAPBase_UI/include/EAP_UI.h:283
msgid "EAP Credentials"
msgstr "Poverilnice EAP"
#: lib/EAPBase_UI/include/EAP_UI.h:443
msgid "Provider Settings"
msgstr "Nastavitve ponudnika"
#: lib/EAPBase_UI/include/EAP_UI.h:600
#, c-format
msgid "Deleting credentials failed (error %u)."
msgstr "Izbris poverilnic ni uspel (napaka %u)."
#: 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>"
msgstr "<vaša organizacija>"
#: lib/EAPBase_UI/res/wxEAP_UI.h:64
msgid "EAP Method Configuration"
msgstr "Konfiguracija postopka EAP"
#: EAPMethods/MSIBuild/En.Win32.Release.Feature-2.idtx:3
#: EAPMethods/MSIBuild/En.x64.Release.Feature-2.idtx:3
msgid "1252"
msgstr "1250"
#: EAPMethods/MSIBuild/En.Win32.Release.Feature-2.idtx:4
#: EAPMethods/MSIBuild/En.x64.Release.Feature-2.idtx:4
msgid "EAP Methods"
msgstr "Postopki EAP"
#: EAPMethods/MSIBuild/En.Win32.Release.Feature-2.idtx:4
#: EAPMethods/MSIBuild/En.x64.Release.Feature-2.idtx:4
msgid "Modules to support individual EAP methods"
msgstr "Moduli, ki omogočajo posamezne postopke EAP"
#: EAPMethods/MSIBuild/En.Win32.Release.Feature-2.idtx:5
#: EAPMethods/MSIBuild/En.x64.Release.Feature-2.idtx:5
msgid "TTLS"
msgstr "TTLS"
#: EAPMethods/MSIBuild/En.Win32.Release.Feature-2.idtx:5
#: EAPMethods/MSIBuild/En.x64.Release.Feature-2.idtx:5
msgid "Tunneled Transport Layer Security"
msgstr "Tunneled Transport Layer Security"

View File

@@ -46,22 +46,14 @@ bool wxEventMonitorApp::OnInit()
::MsiUseFeature(_T(PRODUCT_VERSION_GUID), _T("featEventMonitor")); ::MsiUseFeature(_T(PRODUCT_VERSION_GUID), _T("featEventMonitor"));
#endif #endif
wxConfigBase *cfgPrev = wxConfigBase::Set(new wxConfig(wxT("EventMonitor"), wxT(PRODUCT_NAME_STR))); wxInitializeConfig();
if (cfgPrev) wxDELETE(cfgPrev);
if (!wxApp::OnInit()) if (!wxApp::OnInit())
return false; return false;
// Set desired locale. if (wxInitializeLocale(m_locale)) {
wxLanguage language = (wxLanguage)wxConfigBase::Get()->Read(wxT("Language"), wxLANGUAGE_DEFAULT); //wxVERIFY(m_locale.AddCatalog(wxT("wxExtend") wxT(wxExtendVersion)));
if (wxLocale::IsAvailable(language)) { wxVERIFY(m_locale.AddCatalog(wxT("EventMonitor")));
wxString sPath;
if (wxConfigBase::Get()->Read(wxT("LocalizationRepositoryPath"), &sPath))
m_locale.AddCatalogLookupPathPrefix(sPath);
if (m_locale.Init(language)) {
wxVERIFY(m_locale.AddCatalog(wxT("wxExtend") wxT(wxExtendVersion)));
wxVERIFY(m_locale.AddCatalog(wxT("EventMonitor")));
}
} }
#ifdef __WXMSW__ #ifdef __WXMSW__

View File

@@ -164,11 +164,11 @@ wxETWListCtrl::wxETWListCtrl(wxWindow *parent, wxWindowID id, const wxPoint& pos
m_rec_idx(wxETWEVENT_RECORDS_MAX), m_rec_idx(wxETWEVENT_RECORDS_MAX),
wxListCtrl(parent, id, pos, size, style, validator, name) wxListCtrl(parent, id, pos, size, style, validator, name)
{ {
this->AppendColumn(_("Time" ), wxLIST_FORMAT_LEFT, 100); this->AppendColumn(_("Time" ), wxLIST_FORMAT_LEFT, 160);
this->AppendColumn(_("PID" ), wxLIST_FORMAT_LEFT, 50 ); this->AppendColumn(_("PID" ), wxLIST_FORMAT_LEFT, 50);
this->AppendColumn(_("TID" ), wxLIST_FORMAT_LEFT, 50 ); this->AppendColumn(_("TID" ), wxLIST_FORMAT_LEFT, 50);
this->AppendColumn(_("Source"), wxLIST_FORMAT_LEFT, 100); this->AppendColumn(_("Source"), wxLIST_FORMAT_LEFT, 80);
this->AppendColumn(_("Event" ), wxLIST_FORMAT_LEFT, wxLIST_AUTOSIZE_USEHEADER); this->AppendColumn(_("Event" ), wxLIST_FORMAT_LEFT, 350);
// Maximum expected column widths for pre-formatted row display // Maximum expected column widths for pre-formatted row display
m_col_format_width[0] = 26; m_col_format_width[0] = 26;
@@ -411,7 +411,7 @@ void wxETWListCtrl::RebuildItems()
item_center = std::min<long>( item_center = std::min<long>(
item_top + item_page_count / 2, // Index of item in the centre of the view item_top + item_page_count / 2, // Index of item in the centre of the view
(item_top + m_rec_idx.size()) / 2); // Index of the item in the centre between top viewed item and the last (when list is not overflowed) (item_top + m_rec_idx.size()) / 2); // Index of the item in the centre between top viewed item and the last (when list is not overflowed)
size_t center = item_center < m_rec_idx.size() ? m_rec_idx[item_center] : -1; size_t center = (size_t)item_center < m_rec_idx.size() ? m_rec_idx[item_center] : -1;
// Rebuild the index. // Rebuild the index.
m_rec_idx.clear(); m_rec_idx.clear();
@@ -706,12 +706,12 @@ void wxPersistentETWListCtrl::Save() const
SaveValue(wxString::Format(wxT("Column%sWidth"), col.GetText().c_str()), col.GetWidth()); SaveValue(wxString::Format(wxT("Column%sWidth"), col.GetText().c_str()), col.GetWidth());
} }
SaveValue(wxT("ScrollAuto" ), wnd->m_scroll_auto); SaveValue(wxT("ScrollAuto"), wnd->m_scroll_auto);
SaveValue(wxT("SourceCount"), (long)wnd->m_sources.size()); wxString data_str;
long i = 0; for (wxETWListCtrl::guidset::const_iterator src = wnd->m_sources.cbegin(), src_end = wnd->m_sources.cend(); src != src_end; ++src)
for (wxETWListCtrl::guidset::const_iterator src = wnd->m_sources.cbegin(), src_end = wnd->m_sources.cend(); src != src_end; ++src, i++) data_str += tstring_guid(*src);
SaveValue(wxString::Format(wxT("Source%u"), i), tstring_guid(*src)); SaveValue(wxT("Sources"), data_str);
SaveValue(wxT("Level"), (int)wnd->m_level); SaveValue(wxT("Level"), (int)wnd->m_level);
} }
@@ -735,24 +735,24 @@ bool wxPersistentETWListCtrl::Restore()
RestoreValue(wxT("ScrollAuto"), &(wnd->m_scroll_auto)); RestoreValue(wxT("ScrollAuto"), &(wnd->m_scroll_auto));
wnd->m_sources.clear(); wnd->m_sources.clear();
long n; wxString data_str;
if (RestoreValue(wxT("SourceCount"), &n)) { if (RestoreValue(wxT("Sources"), &data_str)) {
wxString guid_str; for (size_t i = 0; (i = data_str.find(wxT('{'), i)) != std::string::npos;) {
for (long i = 0; i < n; i++) { GUID guid;
if (RestoreValue(wxString::Format(wxT("Source%u"), i), &guid_str)) { if (StringToGuid(data_str.data() + i, &guid)) {
GUID guid; wnd->m_sources.insert(guid);
if (StringToGuid(guid_str.c_str(), &guid)) i += 38;
wnd->m_sources.insert(guid); } else
} i++;
} }
} else { } else {
// Insert our provider by default. // Insert our provider by default.
wnd->m_sources.insert(EAPMETHOD_TRACE_EVENT_PROVIDER); wnd->m_sources.insert(EAPMETHOD_TRACE_EVENT_PROVIDER);
} }
int dummy_int; int data_int;
if (RestoreValue(wxT("Level"), &dummy_int)) if (RestoreValue(wxT("Level"), &data_int))
wnd->m_level = (UCHAR)std::min<int>(std::max<int>(dummy_int, TRACE_LEVEL_ERROR), TRACE_LEVEL_VERBOSE); wnd->m_level = (UCHAR)std::min<int>(std::max<int>(data_int, TRACE_LEVEL_ERROR), TRACE_LEVEL_VERBOSE);
return true; return true;
} }

View File

@@ -122,7 +122,11 @@
<None Include="res\EventMonitor.ico" /> <None Include="res\EventMonitor.ico" />
<None Include="wxEventMonitor_UI.fbp" /> <None Include="wxEventMonitor_UI.fbp" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<POCompile Include="locale\sl_SI.po" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
<Import Project="..\include\xgettext.targets" />
</ImportGroup> </ImportGroup>
</Project> </Project>

View File

@@ -74,4 +74,9 @@
<Filter>Resource Files</Filter> <Filter>Resource Files</Filter>
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup>
<POCompile Include="locale\sl_SI.po">
<Filter>Resource Files\Localization</Filter>
</POCompile>
</ItemGroup>
</Project> </Project>

View File

@@ -139,11 +139,11 @@ wxEventMonitorFrame::wxEventMonitorFrame(wxWindow* parent, wxWindowID id, const
m_menuView->AppendSeparator(); m_menuView->AppendSeparator();
wxMenuItem* m_menuViewToolbarEdit; wxMenuItem* m_menuViewToolbarEdit;
m_menuViewToolbarEdit = new wxMenuItem(m_menuView, wxID_VIEW_TOOLBAR_EDIT, _("&Edit toolbar"), _("Toggles display of Edit toolbar"), wxITEM_CHECK); m_menuViewToolbarEdit = new wxMenuItem(m_menuView, wxID_VIEW_TOOLBAR_EDIT, wxString::Format(_("%s toolbar"), _("&Edit")), wxString::Format(_("Toggles display of %s toolbar"), _("View")), wxITEM_CHECK);
m_menuView->Append(m_menuViewToolbarEdit); m_menuView->Append(m_menuViewToolbarEdit);
wxMenuItem* m_menuViewToolbarView; wxMenuItem* m_menuViewToolbarView;
m_menuViewToolbarView = new wxMenuItem(m_menuView, wxID_VIEW_TOOLBAR_VIEW, _("&View toolbar"), _("Toggles display of View toolbar"), wxITEM_CHECK); m_menuViewToolbarView = new wxMenuItem(m_menuView, wxID_VIEW_TOOLBAR_VIEW, wxString::Format(_("%s toolbar"), _("&View")), wxString::Format(_("Toggles display of %s toolbar"), _("View")), wxITEM_CHECK);
m_menuView->Append(m_menuViewToolbarView); m_menuView->Append(m_menuViewToolbarView);
m_menubar->Append(m_menuView, _("&View")); m_menubar->Append(m_menuView, _("&View"));
@@ -186,7 +186,7 @@ wxEventMonitorFrame::wxEventMonitorFrame(wxWindow* parent, wxWindowID id, const
m_panel = new wxEventMonitorLogPanel(this); m_panel = new wxEventMonitorLogPanel(this);
m_mgr.AddPane(m_panel, wxAuiPaneInfo() .Name(wxT("LogPanel")).Center() .Caption(_("Log Trace")).CaptionVisible(false).CloseButton(false).PaneBorder(false).Dock().Resizable().FloatingSize(wxDefaultSize).Floatable(false)); m_mgr.AddPane(m_panel, wxAuiPaneInfo() .Name(wxT("LogPanel")).Center() .Caption(_("Trace Log")).CaptionVisible(false).CloseButton(false).PaneBorder(false).Dock().Resizable().FloatingSize(wxDefaultSize).Floatable(false));
m_statusBar = this->CreateStatusBar(1, wxST_SIZEGRIP, wxID_ANY); m_statusBar = this->CreateStatusBar(1, wxST_SIZEGRIP, wxID_ANY);

Binary file not shown.

1
EventMonitor/locale/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/*.mo

View File

@@ -1,8 +1,7 @@
#, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: EventMonitor\n" "Project-Id-Version: EventMonitor\n"
"POT-Creation-Date: 2016-08-27 07:52+0200\n" "POT-Creation-Date: 2016-08-27 14:20+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"
@@ -27,41 +26,41 @@ msgstr ""
msgid "Error opening event trace (error %u)." msgid "Error opening event trace (error %u)."
msgstr "" msgstr ""
#: ETWLog.cpp:171 #: ETWLog.cpp:167
msgid "Time" msgid "Time"
msgstr "" msgstr ""
#: ETWLog.cpp:172 #: ETWLog.cpp:168
msgid "PID" msgid "PID"
msgstr "" msgstr ""
#: ETWLog.cpp:173 #: ETWLog.cpp:169
msgid "TID" msgid "TID"
msgstr "" msgstr ""
#: ETWLog.cpp:174 #: ETWLog.cpp:170
msgid "Source" msgid "Source"
msgstr "" msgstr ""
#: ETWLog.cpp:175 #: ETWLog.cpp:171
msgid "Event" msgid "Event"
msgstr "" msgstr ""
#: ETWLog.cpp:232 #: ETWLog.cpp:228
msgid "Access denied creating event session: you need administrative privileges (Run As Administrator) or be a member of Performance Log Users group to start event tracing session." msgid "Access denied creating event session: you need administrative privileges (Run As Administrator) or be a member of Performance Log Users group to start event tracing session."
msgstr "" msgstr ""
#: ETWLog.cpp:235 #: ETWLog.cpp:231
#, c-format #, c-format
msgid "The %s event session already exists." msgid "The %s event session already exists."
msgstr "" msgstr ""
#: ETWLog.cpp:239 #: ETWLog.cpp:235
#, c-format #, c-format
msgid "Error creating event session (error %u)." msgid "Error creating event session (error %u)."
msgstr "" msgstr ""
#: ETWLog.cpp:255 ETWLog.cpp:270 ETWLog.cpp:284 #: ETWLog.cpp:251 ETWLog.cpp:267 ETWLog.cpp:281
#, c-format #, c-format
msgid "Error enabling %s event provider (error %u)." msgid "Error enabling %s event provider (error %u)."
msgstr "" msgstr ""
@@ -80,9 +79,8 @@ msgid "Quits this program"
msgstr "" msgstr ""
#: Frame.cpp:69 #: Frame.cpp:69
#, fuzzy
msgid "&Program" msgid "&Program"
msgstr "You don't have %s subscription yet." msgstr ""
#: Frame.cpp:78 #: Frame.cpp:78
msgid "Copy A&ll" msgid "Copy A&ll"
@@ -116,7 +114,7 @@ msgstr ""
msgid "Clears record selection" msgid "Clears record selection"
msgstr "" msgstr ""
#: Frame.cpp:97 #: Frame.cpp:97 Frame.cpp:142
msgid "&Edit" msgid "&Edit"
msgstr "" msgstr ""
@@ -153,31 +151,28 @@ msgid "Displays all records up to warning level"
msgstr "" msgstr ""
#: Frame.cpp:135 Frame.cpp:182 #: Frame.cpp:135 Frame.cpp:182
#, fuzzy
msgid "Error" msgid "Error"
msgstr "Napaka pri nalaganju knjižnice MSI.DLL (%1!ld!)." msgstr ""
#: Frame.cpp:135 Frame.cpp:182 #: Frame.cpp:135 Frame.cpp:182
msgid "Displays error level records only" msgid "Displays error level records only"
msgstr "" msgstr ""
#: Frame.cpp:142 #: Frame.cpp:142 Frame.cpp:146
msgid "&Edit toolbar" #, c-format
msgid "%s toolbar"
msgstr "" msgstr ""
#: Frame.cpp:142 #: Frame.cpp:142 Frame.cpp:146
msgid "Toggles display of Edit toolbar" #, c-format
msgid "Toggles display of %s toolbar"
msgstr "" msgstr ""
#: Frame.cpp:146 #: Frame.cpp:142 Frame.cpp:146 Frame.cpp:185
msgid "&View toolbar" msgid "View"
msgstr "" msgstr ""
#: Frame.cpp:146 #: Frame.cpp:146 Frame.cpp:149
msgid "Toggles display of View toolbar"
msgstr ""
#: Frame.cpp:149
msgid "&View" msgid "&View"
msgstr "" msgstr ""
@@ -201,21 +196,16 @@ msgstr ""
msgid "Auto Scroll" msgid "Auto Scroll"
msgstr "" msgstr ""
#: Frame.cpp:185
msgid "View"
msgstr ""
#: Frame.cpp:189 #: Frame.cpp:189
msgid "Log Trace" msgid "Trace Log"
msgstr "" msgstr ""
#: MSIBuild/En.Win32.Release.Feature-2.idtx:3 #: MSIBuild/En.Win32.Release.Feature-2.idtx:3
#: MSIBuild/En.Win32.Release.Shortcut-2.idtx:3 #: MSIBuild/En.Win32.Release.Shortcut-2.idtx:3
#: MSIBuild/En.x64.Release.Feature-2.idtx:3 #: MSIBuild/En.x64.Release.Feature-2.idtx:3
#: MSIBuild/En.x64.Release.Shortcut-2.idtx:3 #: MSIBuild/En.x64.Release.Shortcut-2.idtx:3
#, fuzzy
msgid "1252" msgid "1252"
msgstr "1250" msgstr ""
#: MSIBuild/En.Win32.Release.Shortcut-2.idtx:4 #: MSIBuild/En.Win32.Release.Shortcut-2.idtx:4
#: MSIBuild/En.x64.Release.Shortcut-2.idtx:4 #: MSIBuild/En.x64.Release.Shortcut-2.idtx:4

View File

@@ -0,0 +1,228 @@
# Translators:
# Simon Rozman <simon@rozman.si>, 2016
msgid ""
msgstr ""
"Project-Id-Version: EventMonitor\n"
"POT-Creation-Date: 2016-08-27 14:20+0200\n"
"PO-Revision-Date: 2016-06-02 12:27+0200\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"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: sl_SI\n"
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n"
"X-Generator: Poedit 1.8.8\n"
"X-Poedit-Basepath: ..\n"
"X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: .\n"
"X-Poedit-SourceCharset: UTF-8\n"
#: App.cpp:69 Frame.h:67 MSIBuild/En.Win32.Release.Feature-2.idtx:4
#: MSIBuild/En.x64.Release.Feature-2.idtx:4
msgid "Event Monitor"
msgstr "Nadzornik dogodkov"
#: ETWLog.cpp:83
#, c-format
msgid "Error opening event trace (error %u)."
msgstr "Napaka pri odpiranju sledenja dogodkom (napaka %u)."
#: ETWLog.cpp:167
msgid "Time"
msgstr "Čas"
#: ETWLog.cpp:168
msgid "PID"
msgstr "PID"
#: ETWLog.cpp:169
msgid "TID"
msgstr "TID"
#: ETWLog.cpp:170
msgid "Source"
msgstr "Vir"
#: ETWLog.cpp:171
msgid "Event"
msgstr "Dogodek"
#: ETWLog.cpp:228
msgid ""
"Access denied creating event session: you need administrative privileges "
"(Run As Administrator) or be a member of Performance Log Users group to "
"start event tracing session."
msgstr ""
"Dostop pri ustvarjanju seje dogodkov zavrnjen: potrebujete skrbniške pravice"
" (Zaženi kot skrbnik) ali biti član skupine »Performance Log Users« za zagon"
" seje sledenja dogodkov."
#: ETWLog.cpp:231
#, c-format
msgid "The %s event session already exists."
msgstr "Seja dogodkov %s že obstaja."
#: ETWLog.cpp:235
#, c-format
msgid "Error creating event session (error %u)."
msgstr "Napaka pri ustvarjanju seje dogodkov (napaka %u)."
#: ETWLog.cpp:251 ETWLog.cpp:267 ETWLog.cpp:281
#, c-format
msgid "Error enabling %s event provider (error %u)."
msgstr "Napaka pri omogočanju ponudnika dogodkov %s (napaka %u)."
#: Frame.cpp:48 Frame.cpp:108 Frame.cpp:113 Frame.cpp:168 Frame.cpp:170
#, c-format
msgid "Toggles display of %s records"
msgstr "Obrne prikaz zapisov %s"
#: Frame.cpp:65
msgid "E&xit"
msgstr "I&zhod"
#: Frame.cpp:65
msgid "Quits this program"
msgstr "Konča ta program"
#: Frame.cpp:69
msgid "&Program"
msgstr "&Program"
#: Frame.cpp:78
msgid "Copy A&ll"
msgstr "Kopiraj &vse"
#: Frame.cpp:78 Frame.cpp:156
msgid "Copies all records to clipboard (including hidden)"
msgstr "Kopira vse zapise na odložišče (tudi skrite)"
#: Frame.cpp:83 Frame.cpp:158
msgid "Clear"
msgstr "Počisti"
#: Frame.cpp:83 Frame.cpp:158
msgid "Clears all records from the log"
msgstr "Počisti vse zapise iz dnevnika"
#: Frame.cpp:90
msgid "Select &All"
msgstr "Izberi &vse"
#: Frame.cpp:90
msgid "Selects all visible records"
msgstr "Izbere vse vidne zapise"
#: Frame.cpp:94
msgid "Select &None"
msgstr "Izberi &nič"
#: Frame.cpp:94
msgid "Clears record selection"
msgstr "Počisti izbor zapisov"
#: Frame.cpp:97 Frame.cpp:142
msgid "&Edit"
msgstr "Ur&edi"
#: Frame.cpp:101
msgid "Auto &Scroll"
msgstr "&Samodrsenje"
#: Frame.cpp:101 Frame.cpp:164
msgid "Automatically scrolls to the most recent records as they come-in"
msgstr "Samodejno pomikaj do najbolj zadnjega zapisa, ko prihajajo"
#: Frame.cpp:123 Frame.cpp:176
msgid "Verbose"
msgstr "Podrobno"
#: Frame.cpp:123 Frame.cpp:176
msgid "Displays all levels of records"
msgstr "Prikaže vse ravni zapisov"
#: Frame.cpp:127 Frame.cpp:178
msgid "Informational"
msgstr "Informativno"
#: Frame.cpp:127 Frame.cpp:178
msgid "Displays all records up to informational level"
msgstr "Prikaže vse zapise do informativne ravni"
#: Frame.cpp:131 Frame.cpp:180
msgid "Warning"
msgstr "Opozorilo"
#: Frame.cpp:131 Frame.cpp:180
msgid "Displays all records up to warning level"
msgstr "Prikaže vse zapise do opozorilne ravni"
#: Frame.cpp:135 Frame.cpp:182
msgid "Error"
msgstr "Napaka"
#: Frame.cpp:135 Frame.cpp:182
msgid "Displays error level records only"
msgstr "Prikaže samo zapise ravni napak"
#: Frame.cpp:142 Frame.cpp:146
#, c-format
msgid "%s toolbar"
msgstr "Orodna vrstica %s"
#: Frame.cpp:142 Frame.cpp:146
#, c-format
msgid "Toggles display of %s toolbar"
msgstr "Obrne prikaz orodne vrstice %s"
#: Frame.cpp:142 Frame.cpp:146 Frame.cpp:185
msgid "View"
msgstr "Pogled"
#: Frame.cpp:146 Frame.cpp:149
msgid "&View"
msgstr "Po&gled"
#: Frame.cpp:154
msgid "Copy"
msgstr "Kopiraj"
#: Frame.cpp:154
msgid "Copies selected records to clipboard"
msgstr "Kopira izbrane zapise na odložišče"
#: Frame.cpp:156
msgid "Copy All"
msgstr "Kopiraj vse"
#: Frame.cpp:161
msgid "Edit"
msgstr "Uredi"
#: Frame.cpp:164
msgid "Auto Scroll"
msgstr "Samodrsenje"
#: Frame.cpp:189
msgid "Trace Log"
msgstr "Dnevnik sledenja"
#: MSIBuild/En.Win32.Release.Feature-2.idtx:3
#: MSIBuild/En.Win32.Release.Shortcut-2.idtx:3
#: MSIBuild/En.x64.Release.Feature-2.idtx:3
#: MSIBuild/En.x64.Release.Shortcut-2.idtx:3
msgid "1252"
msgstr "1250"
#: MSIBuild/En.Win32.Release.Shortcut-2.idtx:4
#: MSIBuild/En.x64.Release.Shortcut-2.idtx:4
msgid "EVENTM~1|GÉANTLink Event Monitor"
msgstr "EVENTM~1|Nadzornik dogodkov GÉANTLink"
#: 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.Shortcut-2.idtx:4
msgid "Real-time display of internal events"
msgstr "Prikazovalnik notranjih dogodkov v realnem času"

View File

@@ -18,7 +18,7 @@ wxEventMonitorLogPanelBase::wxEventMonitorLogPanelBase( wxWindow* parent, wxWind
wxBoxSizer* bSizerMain; wxBoxSizer* bSizerMain;
bSizerMain = new wxBoxSizer( wxVERTICAL ); bSizerMain = new wxBoxSizer( wxVERTICAL );
m_log = new wxETWListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_VIRTUAL|wxNO_BORDER ); m_log = new wxETWListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_VIRTUAL|wxNO_BORDER, wxDefaultValidator, wxT("EventMonitorLog") );
bSizerMain->Add( m_log, 1, wxEXPAND, 5 ); bSizerMain->Add( m_log, 1, wxEXPAND, 5 );

View File

@@ -141,7 +141,7 @@
<property name="validator_type">wxDefaultValidator</property> <property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property> <property name="validator_variable"></property>
<property name="window_extra_style"></property> <property name="window_extra_style"></property>
<property name="window_name"></property> <property name="window_name">EventMonitorLog</property>
<property name="window_style">wxNO_BORDER</property> <property name="window_style">wxNO_BORDER</property>
<event name="OnChar"></event> <event name="OnChar"></event>
<event name="OnEnterWindow"></event> <event name="OnEnterWindow"></event>

Binary file not shown.

BIN
Makefile

Binary file not shown.

View File

@@ -42,7 +42,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MsiUseFeature", "MsiUseFeat
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EventMonitor", "EventMonitor\EventMonitor.vcxproj", "{E0D0725B-B2FC-4225-9481-CA9B1B6306F2}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EventMonitor", "EventMonitor\EventMonitor.vcxproj", "{E0D0725B-B2FC-4225-9481-CA9B1B6306F2}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxExtendLib", "lib\wxExtend\build\wxExtendLib.vcxproj", "{D3E29951-D9F5-486D-A167-20AE8E90B1FA}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxExtend", "lib\wxExtend\build\wxExtendLib.vcxproj", "{D3E29951-D9F5-486D-A167-20AE8E90B1FA}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WLANManager", "WLANManager\WLANManager.vcxproj", "{BFCAA3B4-97A9-4EA9-8FE1-F30280142BCC}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -180,6 +182,14 @@ Global
{D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Release|Win32.Build.0 = Release|Win32 {D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Release|Win32.Build.0 = Release|Win32
{D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Release|x64.ActiveCfg = Release|x64 {D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Release|x64.ActiveCfg = Release|x64
{D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Release|x64.Build.0 = Release|x64 {D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Release|x64.Build.0 = Release|x64
{BFCAA3B4-97A9-4EA9-8FE1-F30280142BCC}.Debug|Win32.ActiveCfg = Debug|Win32
{BFCAA3B4-97A9-4EA9-8FE1-F30280142BCC}.Debug|Win32.Build.0 = Debug|Win32
{BFCAA3B4-97A9-4EA9-8FE1-F30280142BCC}.Debug|x64.ActiveCfg = Debug|x64
{BFCAA3B4-97A9-4EA9-8FE1-F30280142BCC}.Debug|x64.Build.0 = Debug|x64
{BFCAA3B4-97A9-4EA9-8FE1-F30280142BCC}.Release|Win32.ActiveCfg = Release|Win32
{BFCAA3B4-97A9-4EA9-8FE1-F30280142BCC}.Release|Win32.Build.0 = Release|Win32
{BFCAA3B4-97A9-4EA9-8FE1-F30280142BCC}.Release|x64.ActiveCfg = Release|x64
{BFCAA3B4-97A9-4EA9-8FE1-F30280142BCC}.Release|x64.Build.0 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@@ -201,5 +211,6 @@ Global
{2D3CE079-7EB1-4F47-B79E-F0310671ECCB} = {7B5EC9B7-208C-426A-941D-DAF9271BD4A4} {2D3CE079-7EB1-4F47-B79E-F0310671ECCB} = {7B5EC9B7-208C-426A-941D-DAF9271BD4A4}
{679D03C5-CD70-4FFA-93F8-A4AB3637509B} = {7B5EC9B7-208C-426A-941D-DAF9271BD4A4} {679D03C5-CD70-4FFA-93F8-A4AB3637509B} = {7B5EC9B7-208C-426A-941D-DAF9271BD4A4}
{E0D0725B-B2FC-4225-9481-CA9B1B6306F2} = {7B5EC9B7-208C-426A-941D-DAF9271BD4A4} {E0D0725B-B2FC-4225-9481-CA9B1B6306F2} = {7B5EC9B7-208C-426A-941D-DAF9271BD4A4}
{BFCAA3B4-97A9-4EA9-8FE1-F30280142BCC} = {7B5EC9B7-208C-426A-941D-DAF9271BD4A4}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

2
WLANManager/.gitignore vendored Normal file
View File

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

9
WLANManager/MSIBuild/.gitignore vendored Normal file
View File

@@ -0,0 +1,9 @@
/*-1.idt
/*-2.idt
/*-2.idtx
/*.Binary-1
/*.Binary-2
/*.Icon-1
/*.Icon-2
/*.lst
/*.msm

Binary file not shown.

136
WLANManager/Main.cpp Normal file
View File

@@ -0,0 +1,136 @@
/*
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"
#pragma comment(lib, "Wlanapi.lib")
#pragma comment(lib, "Wlanui.lib")
using namespace std;
using namespace winstd;
DWORD (WINAPI *pfnWlanReasonCodeToString)(__in DWORD dwReasonCode, __in DWORD dwBufferSize, __in_ecount(dwBufferSize) PWCHAR pStringBuffer, __reserved PVOID pReserved);
static int DisplayError(_In_z_ _Printf_format_string_ LPCTSTR format, ...)
{
va_list arg;
va_start(arg, format);
tstring msg;
vsprintf(msg, format, arg);
va_end(arg);
return MessageBox(NULL, msg.c_str(), _T("WLANManager"), MB_OK);
}
static int WLANManager()
{
int nArgs;
unique_ptr<LPWSTR[], LocalFree_delete<LPWSTR[]> > pwcArglist(CommandLineToArgvW(GetCommandLineW(), &nArgs));
if (pwcArglist == NULL) {
DisplayError(_T("%s function failed (error %u)."), _T("CommandLineToArgvW"), GetLastError());
return 1;
}
if (nArgs < 3) {
DisplayError(_T("Not enough parameters."));
return -1;
}
if (_wcsicmp(pwcArglist[1], L"profile") != 0) {
DisplayError(_T("Unknown command (%ls)."), pwcArglist[1]);
return -1;
}
// Open WLAN handle.
DWORD dwNegotiatedVersion;
wlan_handle wlan;
if (!wlan.open(WLAN_API_MAKE_VERSION(2, 0), &dwNegotiatedVersion)) {
DisplayError(_T("%s function failed (error %u)."), _T("WlanOpenHandle"), GetLastError());
return 2;
} else if (dwNegotiatedVersion < WLAN_API_MAKE_VERSION(2, 0)) {
DisplayError(_T("WlanOpenHandle negotiated unsupported version (expected: %u, negotiated: %u)."), WLAN_API_MAKE_VERSION(2, 0), dwNegotiatedVersion);
return 3;
}
unique_ptr<WLAN_INTERFACE_INFO_LIST, WlanFreeMemory_delete<WLAN_INTERFACE_INFO_LIST> > interfaces;
{
// Get a list of WLAN interfaces.
WLAN_INTERFACE_INFO_LIST *pInterfaceList;
DWORD dwResult = WlanEnumInterfaces(wlan, NULL, &pInterfaceList);
if (dwResult != ERROR_SUCCESS) {
DisplayError(_T("%s function failed (error %u)."), _T("WlanEnumInterfaces"), dwResult);
return 4;
}
interfaces.reset(pInterfaceList);
}
for (DWORD i = 0; i < interfaces->dwNumberOfItems; i++) {
if (interfaces->InterfaceInfo[i].isState == wlan_interface_state_not_ready) {
// This interface is not ready.
continue;
}
// Launch WLAN profile config dialog.
// Note: When a debugger is attached to this process the WlanUIEditProfile() will raise an exception and fail.
WLAN_REASON_CODE wlrc;
DWORD dwResult = WlanUIEditProfile(WLAN_UI_API_VERSION, pwcArglist[2], &(interfaces->InterfaceInfo[i].InterfaceGuid), NULL, WLSecurityPage, NULL, &wlrc);
if (dwResult != ERROR_SUCCESS) {
DisplayError(_T("%s function failed (error %u)."), _T("WlanUIEditProfile"), dwResult);
return 5;
}
if (wlrc != WLAN_REASON_CODE_SUCCESS) {
tstring reason;
if (WlanReasonCodeToString(wlrc, reason, NULL) == ERROR_SUCCESS)
DisplayError(_T("%s function failed: %s"), _T("WlanUIEditProfile"), reason.c_str());
else
DisplayError(_T("%s function failed (reason code: %u)."), _T("WlanUIEditProfile"), wlrc);
}
break;
}
return 0;
}
int CALLBACK WinMain(_In_ HINSTANCE hInstance, _In_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hInstance);
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
UNREFERENCED_PARAMETER(nCmdShow);
{
// Initialize Windows XP visual styles
INITCOMMONCONTROLSEX icc;
icc.dwSize = sizeof(INITCOMMONCONTROLSEX);
icc.dwICC = ICC_WIN95_CLASSES | ICC_STANDARD_CLASSES | ICC_LINK_CLASS;
InitCommonControlsEx(&icc);
}
pfnWlanReasonCodeToString = WlanReasonCodeToString;
int res = WLANManager();
assert(!_CrtDumpMemoryLeaks());
return res;
}

18
WLANManager/README.md Normal file
View File

@@ -0,0 +1,18 @@
#WLANManager
Invokes standard Windows Wireless Network Properties dialog
##Usage
```
WLANManager profile <name>
```
- `name` - The name of the network profile (not neccessarely the same as SSID)
Return codes:
- -1 = Invalid parameters
- 0 = Success
- 1 = Error parsing command line
- 2 = WLAN handle could not be opened
- 3 = WLAN provider negotiated unsupported version
- 4 = Interface enumeration failed
- 5 = Edit profile UI failed

21
WLANManager/StdAfx.cpp Normal file
View File

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

33
WLANManager/StdAfx.h Normal file
View File

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

View File

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

BIN
WLANManager/WLANManager.rc Normal file

Binary file not shown.

View File

@@ -0,0 +1,112 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{BFCAA3B4-97A9-4EA9-8FE1-F30280142BCC}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>WLANManager</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\include\Win32.props" />
<Import Project="..\include\Debug.props" />
<Import Project="WLANManager.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\include\x64.props" />
<Import Project="..\include\Debug.props" />
<Import Project="WLANManager.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\include\Win32.props" />
<Import Project="..\include\Release.props" />
<Import Project="WLANManager.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\include\x64.props" />
<Import Project="..\include\Release.props" />
<Import Project="WLANManager.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
<ItemGroup>
<ClInclude Include="StdAfx.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="Main.cpp" />
<ClCompile Include="StdAfx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="WLANManager.rc" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\lib\WinStd\build\WinStd.vcxproj">
<Project>{47399d91-7eb9-41de-b521-514ba5db0c43}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="README.md" />
<None Include="res\WLANManager.ico" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

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

1
WLANManager/locale/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/*.mo

View File

@@ -0,0 +1,32 @@
msgid ""
msgstr ""
"Project-Id-Version: WLANManager\n"
"POT-Creation-Date: 2016-08-28 12:03+0200\n"
"PO-Revision-Date: 2016-06-02 12:27+0200\n"
"Last-Translator: Simon Rozman <simon.rozman@amebis.si>\n"
"Language-Team: Amebis, d. o. o., Kamnik <info@amebis.si>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.8.8\n"
"X-Poedit-Basepath: ..\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Language: en_US\n"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: .\n"
#: MSIBuild/En.Win32.Release.Feature-2.idtx:3
#: MSIBuild/En.x64.Release.Feature-2.idtx:3
msgid "1252"
msgstr ""
#: MSIBuild/En.Win32.Release.Feature-2.idtx:4
#: MSIBuild/En.x64.Release.Feature-2.idtx:4
msgid "Helper utility to support direct shortcuts to Wireless Network Properties"
msgstr ""
#: MSIBuild/En.Win32.Release.Feature-2.idtx:4
#: MSIBuild/En.x64.Release.Feature-2.idtx:4
msgid "WLAN Manager"
msgstr ""

View File

@@ -0,0 +1,37 @@
# Translators:
# Simon Rozman <simon@rozman.si>, 2016
msgid ""
msgstr ""
"Project-Id-Version: WLANManager\n"
"POT-Creation-Date: 2016-08-28 12:03+0200\n"
"PO-Revision-Date: 2016-06-02 12:27+0200\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"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: sl_SI\n"
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n"
"X-Generator: Poedit 1.8.8\n"
"X-Poedit-Basepath: ..\n"
"X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: .\n"
"X-Poedit-SourceCharset: UTF-8\n"
#: MSIBuild/En.Win32.Release.Feature-2.idtx:3
#: MSIBuild/En.x64.Release.Feature-2.idtx:3
msgid "1252"
msgstr "1250"
#: MSIBuild/En.Win32.Release.Feature-2.idtx:4
#: MSIBuild/En.x64.Release.Feature-2.idtx:4
msgid ""
"Helper utility to support direct shortcuts to Wireless Network Properties"
msgstr ""
"Orodje za pomoč, ki omogoča neposredne bližnjice do nastavitev brezžičnega "
"omrežja"
#: MSIBuild/En.Win32.Release.Feature-2.idtx:4
#: MSIBuild/En.x64.Release.Feature-2.idtx:4
msgid "WLAN Manager"
msgstr "Upravitelj WLAN"

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- <!--
Copyright 2016 Amebis Copyright 2016 Amebis
Copyright 2016 GÉANT Copyright 2016 GÉANT
This file is part of GÉANTLink. This file is part of GÉANTLink.
@@ -43,6 +43,9 @@
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
</Link> </Link>
<ResourceCompile /> <ResourceCompile />
<POCompile>
<OutputFile>$(OutDir)..\locale\%(Filename)\$(ProjectName).mo</OutputFile>
</POCompile>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup /> <ItemGroup />
</Project> </Project>

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 0x00ff0d00 #define PRODUCT_VERSION 0x00ff0f00
// //
// Product version by components // Product version by components
@@ -39,26 +39,31 @@
// //
#define PRODUCT_VERSION_MAJ 0 #define PRODUCT_VERSION_MAJ 0
#define PRODUCT_VERSION_MIN 255 #define PRODUCT_VERSION_MIN 255
#define PRODUCT_VERSION_REV 13 #define PRODUCT_VERSION_REV 15
#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-alpha13" #define PRODUCT_VERSION_STR "1.0-alpha15"
#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.13" #define PRODUCT_VERSION_INST "0.255.15"
// //
// 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 "{13ADDFF3-B249-4AB5-9FAD-E4CDCED62B11}" #define PRODUCT_VERSION_GUID "{2C45C10E-80B7-4E3B-A06F-08A1A795EDE5}"
//
// Product vendor
//
#define VENDOR_NAME_STR "GÉANT"
// //
// Since the product name is not finally confirmed at the time of // Since the product name is not finally confirmed at the time of

View File

@@ -243,6 +243,11 @@ namespace eap
/// \returns One of `winstd::eap_type_t` constants. /// \returns One of `winstd::eap_type_t` constants.
/// ///
virtual winstd::eap_type_t get_method_id() const = 0; virtual winstd::eap_type_t get_method_id() const = 0;
///
/// Returns a string identifier of the EAP method type of this configuration
///
virtual const wchar_t* get_method_str() const = 0;
}; };
@@ -337,6 +342,11 @@ namespace eap
/// @} /// @}
///
/// Creates a blank set of credentials suitable for this method
///
virtual credentials* make_credentials() const = 0;
public: public:
bool m_allow_save; ///< Are credentials allowed to be saved to Windows Credential Manager? bool m_allow_save; ///< Are credentials allowed to be saved to Windows Credential Manager?
bool m_use_preshared; ///< Use pre-shared credentials bool m_use_preshared; ///< Use pre-shared credentials

View File

@@ -58,7 +58,7 @@ namespace eap
/// ///
/// Credential source when combined /// Credential source when combined
/// ///
enum source_t { enum source_t {
source_unknown = -1, ///< Unknown source source_unknown = -1, ///< Unknown source
source_cache = 0, ///< Credentials were obtained from EapHost cache source_cache = 0, ///< Credentials were obtained from EapHost cache
source_preshared, ///< Credentials were set by method configuration source_preshared, ///< Credentials were set by method configuration
@@ -217,6 +217,27 @@ namespace eap
/// ///
virtual winstd::tstring get_name() const; virtual winstd::tstring get_name() const;
///
/// Combine credentials in the following order:
///
/// 1. Cached credentials
/// 2. Pre-configured credentials
/// 3. Stored credentials
///
/// \param[in] cred_cached Cached credentials (optional, can be \c NULL, must be the same type of credentials as `this`)
/// \param[in] cfg Method configuration (must be the same type of configuration as `this` credentials belong to)
/// \param[in] pszTargetName The name in Windows Credential Manager to retrieve credentials from (optional, can be \c NULL)
///
/// \returns
/// - \c source_cache Credentials were obtained from EapHost cache
/// - \c source_preshared Credentials were set by method configuration
/// - \c source_storage Credentials were loaded from Windows Credential Manager
///
virtual source_t combine(
_In_ const credentials *cred_cached,
_In_ const config_method_with_cred &cfg,
_In_opt_z_ LPCTSTR pszTargetName) = 0;
public: public:
std::wstring m_identity; ///< Identity (username\@domain, certificate name etc.) std::wstring m_identity; ///< Identity (username\@domain, certificate name etc.)
}; };

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
@@ -130,8 +129,9 @@ namespace eap
method& operator=(_In_ const method &other); method& operator=(_In_ const method &other);
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

@@ -109,7 +109,7 @@ void eap::credentials::load(_In_ IXMLDOMNode *pConfigRoot)
std::wstring xpath(eapxml::get_xpath(pConfigRoot)); std::wstring xpath(eapxml::get_xpath(pConfigRoot));
if (FAILED(hr = eapxml::get_element_value(pConfigRoot, bstr(L"eap-metadata:UserName"), m_identity))) if (FAILED(hr = eapxml::get_element_value(pConfigRoot, bstr(L"eap-metadata:UserName"), m_identity)))
throw com_runtime_error(hr, __FUNCTION__ " Error reading <UserName> element."); m_identity.clear();
m_module.log_config((xpath + L"/UserName").c_str(), m_identity.c_str()); m_module.log_config((xpath + L"/UserName").c_str(), m_identity.c_str());
} }
@@ -145,7 +145,9 @@ wstring eap::credentials::get_identity() const
tstring eap::credentials::get_name() const tstring eap::credentials::get_name() const
{ {
return !empty() ? get_identity() : _T("<blank>"); if (empty()) return _T("<empty credentials>");
tstring identity(std::move(get_identity()));
return !identity.empty() ? identity : _T("<blank identity>");
} }

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

@@ -81,6 +81,7 @@
<ItemGroup> <ItemGroup>
<ClInclude Include="..\include\EAP_UI.h" /> <ClInclude Include="..\include\EAP_UI.h" />
<ClInclude Include="..\include\Module.h" /> <ClInclude Include="..\include\Module.h" />
<ClInclude Include="..\include\wxEAP_UIBase.h" />
<ClInclude Include="..\res\wxEAP_UI.h" /> <ClInclude Include="..\res\wxEAP_UI.h" />
<ClInclude Include="..\src\StdAfx.h" /> <ClInclude Include="..\src\StdAfx.h" />
</ItemGroup> </ItemGroup>

View File

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

View File

@@ -20,6 +20,7 @@
#include <wx/hyperlink.h> #include <wx/hyperlink.h>
#include <wx/icon.h> #include <wx/icon.h>
#include <wx/intl.h>
#include <wx/scrolwin.h> #include <wx/scrolwin.h>
#include <Windows.h> #include <Windows.h>
@@ -80,9 +81,9 @@ class wxEAPConfigProvider;
template <class _Tcred, class _wxT> class wxEAPCredentialsConfigPanel; template <class _Tcred, class _wxT> class wxEAPCredentialsConfigPanel;
/// ///
/// Base template for all credential entry panels /// Helper template for all credential entry panels
/// ///
template <class _Tcred, class _Tbase> class wxEAPCredentialsPanelBase; template <class _Tcred, class _Tbase> class wxEAPCredentialsPanel;
/// ///
/// Generic password credential entry panel /// Generic password credential entry panel
@@ -104,6 +105,17 @@ inline wxIcon wxLoadIconFromResource(HINSTANCE hinst, PCWSTR pszName, const wxSi
/// ///
inline wxString wxEAPGetProviderName(const std::wstring &id); inline wxString wxEAPGetProviderName(const std::wstring &id);
///
/// Initializes wxWidgets application configuration scheme
///
inline void wxInitializeConfig();
///
/// Inizializes wxWidgets localization scheme
///
inline bool wxInitializeLocale(wxLocale &locale);
namespace eap namespace eap
{ {
/// ///
@@ -124,6 +136,7 @@ namespace eap
#include <WinStd/Cred.h> #include <WinStd/Cred.h>
#include <WinStd/Win.h> #include <WinStd/Win.h>
#include <wx/config.h>
#include <wx/log.h> #include <wx/log.h>
#include <CommCtrl.h> #include <CommCtrl.h>
@@ -210,19 +223,22 @@ protected:
} }
} }
virtual void OnUpdateUI(wxUpdateUIEvent& event) virtual void OnUpdateUI(wxUpdateUIEvent& /*event*/)
{ {
UNREFERENCED_PARAMETER(event); int idx = m_providers->GetSelection();
eap::config_provider &cfg_provider = ((_wxT*)m_providers->GetPage(idx))->GetProvider();
m_advanced->Enable(!m_cfg.m_providers.at(m_providers->GetSelection()).m_read_only); m_advanced->Enable(!cfg_provider.m_read_only);
} }
virtual void OnAdvanced(wxCommandEvent& event) virtual void OnAdvanced(wxCommandEvent& /*event*/)
{ {
UNREFERENCED_PARAMETER(event); int idx = m_providers->GetSelection();
eap::config_provider &cfg_provider = ((_wxT*)m_providers->GetPage(idx))->GetProvider();
wxEAPConfigProvider dlg(m_cfg.m_providers.at(m_providers->GetSelection()), this); wxEAPConfigProvider dlg(cfg_provider, this);
dlg.ShowModal(); if (dlg.ShowModal() == wxID_OK)
m_providers->SetPageText(idx, wxEAPGetProviderName(cfg_provider.m_id));
} }
/// \endcond /// \endcond
@@ -347,22 +363,25 @@ public:
/// \param[inout] cfg Configuration data /// \param[inout] cfg Configuration data
/// \param[in] parent Parent window /// \param[in] parent Parent window
/// ///
wxEAPConfigWindow(const eap::config_provider &prov, eap::config_method &cfg, wxWindow* parent); wxEAPConfigWindow(eap::config_provider &prov, eap::config_method &cfg, wxWindow* parent);
/// ///
/// Destructs the configuration window /// Destructs the configuration window
/// ///
virtual ~wxEAPConfigWindow(); virtual ~wxEAPConfigWindow();
public:
inline eap::config_provider& GetProvider() const { return m_prov; }
inline eap::config_method & GetConfig () const { return m_cfg ; }
protected: protected:
/// \cond internal /// \cond internal
virtual void OnInitDialog(wxInitDialogEvent& event); virtual void OnInitDialog(wxInitDialogEvent& event);
virtual void OnUpdateUI(wxUpdateUIEvent& event);
/// \endcond /// \endcond
protected: protected:
const eap::config_provider &m_prov; ///< EAP provider eap::config_provider &m_prov; ///< EAP provider
eap::config_method &m_cfg; ///< Method configuration eap::config_method &m_cfg; ///< Method configuration
}; };
@@ -446,7 +465,9 @@ public:
m_prov(prov), m_prov(prov),
m_cfg(cfg), m_cfg(cfg),
m_target(pszCredTarget), m_target(pszCredTarget),
m_cred(cfg.m_module), m_has_own(false),
m_cred_own(cfg.m_module),
m_cred_preshared(cfg.m_module),
wxEAPCredentialsConfigPanelBase(parent) wxEAPCredentialsConfigPanelBase(parent)
{ {
// Load and set icon. // Load and set icon.
@@ -473,7 +494,13 @@ protected:
else else
m_preshared->SetValue(true); m_preshared->SetValue(true);
m_cred = *(_Tcred*)m_cfg.m_preshared.get(); if (m_cfg.m_allow_save) {
RetrieveOwnCredentials();
m_timer_own.Start(3000);
}
m_cred_preshared = *(_Tcred*)m_cfg.m_preshared.get();
UpdatePresharedIdentity();
return wxEAPCredentialsConfigPanelBase::TransferDataToWindow(); return wxEAPCredentialsConfigPanelBase::TransferDataToWindow();
} }
@@ -486,51 +513,31 @@ protected:
if (!m_prov.m_read_only) { if (!m_prov.m_read_only) {
// This is not a provider-locked configuration. Save the data. // This is not a provider-locked configuration. Save the data.
m_cfg.m_use_preshared = !m_own->GetValue(); m_cfg.m_use_preshared = !m_own->GetValue();
*m_cfg.m_preshared = m_cred; *m_cfg.m_preshared = m_cred_preshared;
} }
return true; return true;
} }
virtual void OnUpdateUI(wxUpdateUIEvent& event) virtual void OnUpdateUI(wxUpdateUIEvent& /*event*/)
{ {
UNREFERENCED_PARAMETER(event);
DWORD dwResult;
if (m_cfg.m_allow_save) { if (m_cfg.m_allow_save) {
bool has_own;
std::unique_ptr<CREDENTIAL, winstd::CredFree_delete<CREDENTIAL> > cred;
if (CredRead(m_cred.target_name(m_target.c_str()).c_str(), CRED_TYPE_GENERIC, 0, (PCREDENTIAL*)&cred)) {
m_own_identity->SetValue(cred->UserName && cred->UserName[0] != 0 ? cred->UserName : _("<blank>"));
has_own = true;
} else if ((dwResult = GetLastError()) == ERROR_NOT_FOUND) {
m_own_identity->Clear();
has_own = false;
} else {
m_own_identity->SetValue(wxString::Format(_("<error %u>"), dwResult));
has_own = true;
}
if (m_own->GetValue()) { if (m_own->GetValue()) {
m_own_identity->Enable(true); m_own_identity->Enable(true);
m_own_set ->Enable(true); m_own_set ->Enable(true);
m_own_clear ->Enable(has_own); m_own_clear ->Enable(m_has_own);
} else { } else {
m_own_identity->Enable(false); m_own_identity->Enable(false);
m_own_set ->Enable(false); m_own_set ->Enable(false);
m_own_clear ->Enable(false); m_own_clear ->Enable(false);
} }
} else { } else {
m_own_identity->Clear();
m_own_identity->Enable(false); m_own_identity->Enable(false);
m_own_set ->Enable(false); m_own_set ->Enable(false);
m_own_clear ->Enable(false); m_own_clear ->Enable(false);
} }
m_preshared_identity->SetValue(!m_cred.empty() ? m_cred.get_name() : _("<blank>"));
if (m_prov.m_read_only) { if (m_prov.m_read_only) {
// This is provider-locked configuration. Disable controls. // This is provider-locked configuration. Disable controls.
// To avoid run-away selection of radio buttons, disable the selected one last. // To avoid run-away selection of radio buttons, disable the selected one last.
@@ -545,8 +552,8 @@ protected:
m_preshared_set ->Enable(false); m_preshared_set ->Enable(false);
} else { } else {
// This is not a provider-locked configuration. Selectively enable/disable controls. // This is not a provider-locked configuration. Selectively enable/disable controls.
m_own ->Enable(true); m_own ->Enable(true);
m_preshared ->Enable(true); m_preshared->Enable(true);
if (m_own->GetValue()) { if (m_own->GetValue()) {
m_preshared_identity->Enable(false); m_preshared_identity->Enable(false);
m_preshared_set ->Enable(false); m_preshared_set ->Enable(false);
@@ -558,57 +565,100 @@ protected:
} }
virtual void OnSetOwn(wxCommandEvent& event) virtual void OnSetOwn(wxCommandEvent& /*event*/)
{ {
UNREFERENCED_PARAMETER(event); // Read credentials from Credential Manager.
RetrieveOwnCredentials();
// Read credentials from Credential Manager
_Tcred cred(m_cfg.m_module);
try {
cred.retrieve(m_target.c_str());
} catch (winstd::win_runtime_error &err) {
if (err.number() != ERROR_NOT_FOUND)
wxLogError(winstd::tstring_printf(_("Error reading credentials from Credential Manager: %hs (error %u)"), err.what(), err.number()).c_str());
} catch (...) {
wxLogError(_("Reading credentials failed."));
}
// Display credential prompt. // Display credential prompt.
wxEAPCredentialsDialog dlg(m_prov, this); wxEAPCredentialsDialog dlg(m_prov, this);
_wxT *panel = new _wxT(m_prov, m_cfg, cred, m_target.c_str(), &dlg, true); _wxT *panel = new _wxT(m_prov, m_cfg, m_cred_own, m_target.c_str(), &dlg, true);
dlg.AddContent(panel); dlg.AddContent(panel);
if (dlg.ShowModal() == wxID_OK && panel->GetRememberValue()) { if (dlg.ShowModal() == wxID_OK && panel->GetRemember()) {
// Write credentials to credential manager. // Write credentials to credential manager.
try { try {
cred.store(m_target.c_str()); m_cred_own.store(m_target.c_str());
m_has_own = TRUE;
UpdateOwnIdentity();
} 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());
RetrieveOwnCredentials();
} catch (...) { } catch (...) {
wxLogError(_("Writing credentials failed.")); wxLogError(_("Writing credentials failed."));
RetrieveOwnCredentials();
} }
} }
} }
virtual void OnClearOwn(wxCommandEvent& event) virtual void OnClearOwn(wxCommandEvent& /*event*/)
{ {
UNREFERENCED_PARAMETER(event); if (CredDelete(m_cred_own.target_name(m_target.c_str()).c_str(), CRED_TYPE_GENERIC, 0)) {
m_own_identity->Clear();
if (!CredDelete(m_cred.target_name(m_target.c_str()).c_str(), CRED_TYPE_GENERIC, 0)) m_has_own = false;
} else
wxLogError(_("Deleting credentials failed (error %u)."), GetLastError()); wxLogError(_("Deleting credentials failed (error %u)."), GetLastError());
} }
virtual void OnSetPreshared(wxCommandEvent& event) virtual void OnSetPreshared(wxCommandEvent& /*event*/)
{ {
UNREFERENCED_PARAMETER(event);
wxEAPCredentialsDialog dlg(m_prov, this); wxEAPCredentialsDialog dlg(m_prov, this);
_wxT *panel = new _wxT(m_prov, m_cfg, m_cred, _T(""), &dlg, true); _wxT *panel = new _wxT(m_prov, m_cfg, m_cred_preshared, _T(""), &dlg, true);
dlg.AddContent(panel); dlg.AddContent(panel);
dlg.ShowModal(); if (dlg.ShowModal() == wxID_OK)
UpdatePresharedIdentity();
}
virtual void OnTimerOwn(wxTimerEvent& /*event*/)
{
RetrieveOwnCredentials();
}
void RetrieveOwnCredentials()
{
try {
m_cred_own.retrieve(m_target.c_str());
m_has_own = true;
UpdateOwnIdentity();
} catch (winstd::win_runtime_error &err) {
if (err.number() == ERROR_NOT_FOUND) {
m_own_identity->Clear();
m_has_own = false;
} else {
m_own_identity->SetValue(wxString::Format(_("<error %u>"), err.number()));
m_has_own = true;
}
} catch (...) {
m_own_identity->SetValue(_("<error>"));
m_has_own = true;
}
}
inline void UpdateOwnIdentity()
{
if (m_cred_own.empty())
m_own_identity->SetValue(_("<empty credentials>"));
else {
wxString identity(m_cred_own.get_name());
m_own_identity->SetValue(!identity.empty() ? identity : _("<blank identity>"));
}
}
inline void UpdatePresharedIdentity()
{
if (m_cred_preshared.empty())
m_preshared_identity->SetValue(_("<empty credentials>"));
else {
wxString identity(m_cred_preshared.get_name());
m_preshared_identity->SetValue(!identity.empty() ? identity : _("<blank identity>"));
}
} }
/// \endcond /// \endcond
@@ -619,16 +669,18 @@ protected:
winstd::tstring m_target; ///< Credential Manager target winstd::tstring m_target; ///< Credential Manager target
private: private:
_Tcred m_cred; ///< Temporary credential data bool m_has_own; ///< Does the user has (some sort of) credentials stored in Credential Manager?
_Tcred m_cred_own; ///< Temporary own credential data
_Tcred m_cred_preshared; ///< Temporary pre-shared credential data
}; };
template <class _Tcred, class _Tbase> template <class _Tcred, class _Tbase>
class wxEAPCredentialsPanelBase : public _Tbase class wxEAPCredentialsPanel : public _Tbase
{ {
private: private:
/// \cond internal /// \cond internal
typedef wxEAPCredentialsPanelBase<_Tcred, _Tbase> _Tthis; typedef wxEAPCredentialsPanel<_Tcred, _Tbase> _Tthis;
/// \endcond /// \endcond
public: public:
@@ -642,7 +694,7 @@ public:
/// \param[in] parent Parent window /// \param[in] parent Parent window
/// \param[in] is_config Is this panel used to pre-enter credentials? When \c true, the "Remember" checkbox is always selected and disabled. /// \param[in] is_config Is this panel used to pre-enter credentials? When \c true, the "Remember" checkbox is always selected and disabled.
/// ///
wxEAPCredentialsPanelBase(const eap::config_provider &prov, const eap::config_method_with_cred &cfg, _Tcred &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config = false) : wxEAPCredentialsPanel(const eap::config_provider &prov, const eap::config_method_with_cred &cfg, _Tcred &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config = false) :
m_prov(prov), m_prov(prov),
m_cfg(cfg), m_cfg(cfg),
m_cred(cred), m_cred(cred),
@@ -650,20 +702,14 @@ public:
m_is_config(is_config), m_is_config(is_config),
_Tbase(parent) _Tbase(parent)
{ {
this->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(_Tthis::OnUpdateUI));
} }
virtual ~wxEAPCredentialsPanelBase() virtual void SetRemember(bool val)
{
this->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(_Tthis::OnUpdateUI));
}
inline void SetRememberValue(bool val)
{ {
return m_remember->SetValue(val); return m_remember->SetValue(val);
} }
inline bool GetRememberValue() const virtual bool GetRemember() const
{ {
return m_remember->GetValue(); return m_remember->GetValue();
} }
@@ -671,10 +717,8 @@ public:
protected: protected:
/// \cond internal /// \cond internal
virtual void OnUpdateUI(wxUpdateUIEvent& event) virtual bool TransferDataToWindow()
{ {
UNREFERENCED_PARAMETER(event);
if (m_is_config) { if (m_is_config) {
// Configuration mode // Configuration mode
// Always store credentials (somewhere). // Always store credentials (somewhere).
@@ -689,6 +733,8 @@ protected:
m_remember->SetValue(false); m_remember->SetValue(false);
m_remember->Enable(false); m_remember->Enable(false);
} }
return _Tbase::TransferDataToWindow();
} }
/// \endcond /// \endcond
@@ -703,7 +749,7 @@ protected:
template <class _Tcred, class _Tbase> template <class _Tcred, class _Tbase>
class wxPasswordCredentialsPanel : public wxEAPCredentialsPanelBase<_Tcred, _Tbase> class wxPasswordCredentialsPanel : public wxEAPCredentialsPanel<_Tcred, _Tbase>
{ {
public: public:
/// ///
@@ -717,7 +763,7 @@ public:
/// \param[in] is_config Is this panel used to pre-enter credentials? When \c true, the "Remember" checkbox is always selected and disabled. /// \param[in] is_config Is this panel used to pre-enter credentials? When \c true, the "Remember" checkbox is always selected and disabled.
/// ///
wxPasswordCredentialsPanel(const eap::config_provider &prov, const eap::config_method_with_cred &cfg, _Tcred &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config = false) : wxPasswordCredentialsPanel(const eap::config_provider &prov, const eap::config_method_with_cred &cfg, _Tcred &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config = false) :
wxEAPCredentialsPanelBase<_Tcred, _Tbase>(prov, cfg, cred, pszCredTarget, parent, is_config) wxEAPCredentialsPanel<_Tcred, _Tbase>(prov, cfg, cred, pszCredTarget, parent, is_config)
{ {
// Load and set icon. // Load and set icon.
winstd::library lib_shell32; winstd::library lib_shell32;
@@ -754,12 +800,20 @@ protected:
m_identity->SetSelection(0, -1); m_identity->SetSelection(0, -1);
m_password->SetValue(m_cred.m_password.empty() ? wxEmptyString : s_dummy_password); m_password->SetValue(m_cred.m_password.empty() ? wxEmptyString : s_dummy_password);
return wxEAPCredentialsPanelBase<_Tcred, wxEAPCredentialsPassPanelBase>::TransferDataToWindow(); if (!m_is_config && m_cfg.m_use_preshared) {
// Credential prompt mode & Using pre-shared credentials
m_identity_label->Enable(false);
m_identity ->Enable(false);
m_password_label->Enable(false);
m_password ->Enable(false);
}
return wxEAPCredentialsPanel<_Tcred, wxEAPCredentialsPassPanelBase>::TransferDataToWindow();
} }
virtual bool TransferDataFromWindow() virtual bool TransferDataFromWindow()
{ {
if (!wxEAPCredentialsPanelBase<_Tcred, wxEAPCredentialsPassPanelBase>::TransferDataFromWindow()) if (!wxEAPCredentialsPanel<_Tcred, wxEAPCredentialsPassPanelBase>::TransferDataFromWindow())
return false; return false;
m_cred.m_identity = m_identity->GetValue(); m_cred.m_identity = m_identity->GetValue();
@@ -772,19 +826,6 @@ protected:
return true; return true;
} }
virtual void OnUpdateUI(wxUpdateUIEvent& event)
{
if (!m_is_config && m_cfg.m_use_preshared) {
// Credential prompt mode & Using pre-shared credentials
m_identity_label->Enable(false);
m_identity ->Enable(false);
m_password_label->Enable(false);
m_password ->Enable(false);
}
wxEAPCredentialsPanelBase<_Tcred, wxEAPCredentialsPassPanelBase>::OnUpdateUI(event);
}
/// \endcond /// \endcond
private: private:
@@ -826,6 +867,36 @@ inline wxString wxEAPGetProviderName(const std::wstring &id)
} }
inline void wxInitializeConfig()
{
wxConfigBase *cfgPrev = wxConfigBase::Set(new wxConfig(wxT(PRODUCT_NAME_STR), wxT(VENDOR_NAME_STR)));
if (cfgPrev) wxDELETE(cfgPrev);
}
inline bool wxInitializeLocale(wxLocale &locale)
{
// Read language from configuration.
wxLanguage lang_code;
wxString lang;
if (wxConfigBase::Get()->Read(wxT("Language"), &lang)) {
const wxLanguageInfo *lang_info = wxLocale::FindLanguageInfo(lang);
lang_code = lang_info ? (wxLanguage)lang_info->Language : wxLANGUAGE_DEFAULT;
} else
lang_code = wxLANGUAGE_DEFAULT;
if (wxLocale::IsAvailable(lang_code)) {
// Language is "available". Well... Known actually.
wxString sPath;
if (wxConfigBase::Get()->Read(wxT("LocalizationRepositoryPath"), &sPath))
locale.AddCatalogLookupPathPrefix(sPath);
return locale.Init(lang_code);
}
return false;
}
namespace eap namespace eap
{ {
class monitor_ui class monitor_ui

View File

@@ -0,0 +1,48 @@
/*
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/>.
*/
///
/// Base class for all credential entry panel that must provide "Remember" credentials checkbox
///
class wxEAPCredentialsPanelBase;
#pragma once
#include <wx/panel.h>
class wxEAPCredentialsPanelBase : public wxPanel
{
public:
///
/// Constructs a wxPanel with "Remember" credentials checkbox
///
wxEAPCredentialsPanelBase(wxWindow *parent,
wxWindowID winid = wxID_ANY,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxTAB_TRAVERSAL | wxNO_BORDER,
const wxString& name = wxPanelNameStr) : wxPanel(parent, winid, pos, size, style, name)
{
}
virtual void SetRemember(bool val) = 0;
virtual bool GetRemember() const = 0;
};

View File

@@ -272,12 +272,14 @@ wxEAPCredentialsConfigPanelBase::wxEAPCredentialsConfigPanelBase( wxWindow* pare
this->SetSizer( sb_credentials ); this->SetSizer( sb_credentials );
this->Layout(); this->Layout();
m_timer_own.SetOwner( this, wxID_ANY );
// Connect Events // Connect Events
this->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( wxEAPCredentialsConfigPanelBase::OnUpdateUI ) ); this->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( wxEAPCredentialsConfigPanelBase::OnUpdateUI ) );
m_own_clear->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPCredentialsConfigPanelBase::OnClearOwn ), NULL, this ); m_own_clear->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPCredentialsConfigPanelBase::OnClearOwn ), NULL, this );
m_own_set->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPCredentialsConfigPanelBase::OnSetOwn ), NULL, this ); m_own_set->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPCredentialsConfigPanelBase::OnSetOwn ), NULL, this );
m_preshared_set->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPCredentialsConfigPanelBase::OnSetPreshared ), NULL, this ); m_preshared_set->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPCredentialsConfigPanelBase::OnSetPreshared ), NULL, this );
this->Connect( wxID_ANY, wxEVT_TIMER, wxTimerEventHandler( wxEAPCredentialsConfigPanelBase::OnTimerOwn ) );
} }
wxEAPCredentialsConfigPanelBase::~wxEAPCredentialsConfigPanelBase() wxEAPCredentialsConfigPanelBase::~wxEAPCredentialsConfigPanelBase()
@@ -287,10 +289,11 @@ wxEAPCredentialsConfigPanelBase::~wxEAPCredentialsConfigPanelBase()
m_own_clear->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPCredentialsConfigPanelBase::OnClearOwn ), NULL, this ); m_own_clear->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPCredentialsConfigPanelBase::OnClearOwn ), NULL, this );
m_own_set->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPCredentialsConfigPanelBase::OnSetOwn ), NULL, this ); m_own_set->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPCredentialsConfigPanelBase::OnSetOwn ), NULL, this );
m_preshared_set->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPCredentialsConfigPanelBase::OnSetPreshared ), NULL, this ); m_preshared_set->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPCredentialsConfigPanelBase::OnSetPreshared ), NULL, this );
this->Disconnect( wxID_ANY, wxEVT_TIMER, wxTimerEventHandler( wxEAPCredentialsConfigPanelBase::OnTimerOwn ) );
} }
wxEAPCredentialsPassPanelBase::wxEAPCredentialsPassPanelBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style ) wxEAPCredentialsPassPanelBase::wxEAPCredentialsPassPanelBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxEAPCredentialsPanelBase( parent, id, pos, size, style )
{ {
wxStaticBoxSizer* sb_credentials; wxStaticBoxSizer* sb_credentials;
sb_credentials = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Client Credentials") ), wxVERTICAL ); sb_credentials = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Client Credentials") ), wxVERTICAL );
@@ -453,16 +456,10 @@ wxEAPProviderIdentityPanelBase::wxEAPProviderIdentityPanelBase( wxWindow* parent
this->SetSizer( sb_provider_id ); this->SetSizer( sb_provider_id );
this->Layout(); this->Layout();
// Connect Events
this->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( wxEAPProviderIdentityPanelBase::OnUpdateUI ) );
} }
wxEAPProviderIdentityPanelBase::~wxEAPProviderIdentityPanelBase() wxEAPProviderIdentityPanelBase::~wxEAPProviderIdentityPanelBase()
{ {
// Disconnect Events
this->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( wxEAPProviderIdentityPanelBase::OnUpdateUI ) );
} }
wxEAPProviderLockPanelBase::wxEAPProviderLockPanelBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style ) wxEAPProviderLockPanelBase::wxEAPProviderLockPanelBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style )
@@ -505,14 +502,8 @@ wxEAPProviderLockPanelBase::wxEAPProviderLockPanelBase( wxWindow* parent, wxWind
this->SetSizer( sb_provider_lock ); this->SetSizer( sb_provider_lock );
this->Layout(); this->Layout();
// Connect Events
this->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( wxEAPProviderLockPanelBase::OnUpdateUI ) );
} }
wxEAPProviderLockPanelBase::~wxEAPProviderLockPanelBase() wxEAPProviderLockPanelBase::~wxEAPProviderLockPanelBase()
{ {
// Disconnect Events
this->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( wxEAPProviderLockPanelBase::OnUpdateUI ) );
} }

View File

@@ -1913,6 +1913,15 @@
</object> </object>
</object> </object>
</object> </object>
<object class="wxTimer" expanded="1">
<property name="enabled">0</property>
<property name="id">wxID_ANY</property>
<property name="name">m_timer_own</property>
<property name="oneshot">0</property>
<property name="period">3000</property>
<property name="permission">protected</property>
<event name="OnTimer">OnTimerOwn</event>
</object>
</object> </object>
<object class="Panel" expanded="1"> <object class="Panel" expanded="1">
<property name="aui_managed">0</property> <property name="aui_managed">0</property>
@@ -1931,7 +1940,7 @@
<property name="name">wxEAPCredentialsPassPanelBase</property> <property name="name">wxEAPCredentialsPassPanelBase</property>
<property name="pos"></property> <property name="pos"></property>
<property name="size">500,-1</property> <property name="size">500,-1</property>
<property name="subclass"></property> <property name="subclass">wxEAPCredentialsPanelBase; ../include/wxEAP_UIBase.h</property>
<property name="tooltip"></property> <property name="tooltip"></property>
<property name="window_extra_style"></property> <property name="window_extra_style"></property>
<property name="window_name"></property> <property name="window_name"></property>
@@ -2667,7 +2676,7 @@
<event name="OnRightUp"></event> <event name="OnRightUp"></event>
<event name="OnSetFocus"></event> <event name="OnSetFocus"></event>
<event name="OnSize"></event> <event name="OnSize"></event>
<event name="OnUpdateUI">OnUpdateUI</event> <event name="OnUpdateUI"></event>
<object class="wxStaticBoxSizer" expanded="1"> <object class="wxStaticBoxSizer" expanded="1">
<property name="id">wxID_ANY</property> <property name="id">wxID_ANY</property>
<property name="label">Your Organization</property> <property name="label">Your Organization</property>
@@ -3817,7 +3826,7 @@
<event name="OnRightUp"></event> <event name="OnRightUp"></event>
<event name="OnSetFocus"></event> <event name="OnSetFocus"></event>
<event name="OnSize"></event> <event name="OnSize"></event>
<event name="OnUpdateUI">OnUpdateUI</event> <event name="OnUpdateUI"></event>
<object class="wxStaticBoxSizer" expanded="1"> <object class="wxStaticBoxSizer" expanded="1">
<property name="id">wxID_ANY</property> <property name="id">wxID_ANY</property>
<property name="label">Configuration Lock</property> <property name="label">Configuration Lock</property>

View File

@@ -11,6 +11,9 @@
#include <wx/artprov.h> #include <wx/artprov.h>
#include <wx/xrc/xmlres.h> #include <wx/xrc/xmlres.h>
#include <wx/intl.h> #include <wx/intl.h>
class wxEAPCredentialsPanelBase;
#include "../include/wxEAP_UIBase.h"
class wxEAPBannerPanel; class wxEAPBannerPanel;
#include <wx/gdicmn.h> #include <wx/gdicmn.h>
#include <wx/font.h> #include <wx/font.h>
@@ -30,6 +33,7 @@ class wxEAPBannerPanel;
#include <wx/radiobut.h> #include <wx/radiobut.h>
#include <wx/textctrl.h> #include <wx/textctrl.h>
#include <wx/statbox.h> #include <wx/statbox.h>
#include <wx/timer.h>
#include <wx/checkbox.h> #include <wx/checkbox.h>
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@@ -140,12 +144,14 @@ class wxEAPCredentialsConfigPanelBase : public wxPanel
wxRadioButton* m_preshared; wxRadioButton* m_preshared;
wxTextCtrl* m_preshared_identity; wxTextCtrl* m_preshared_identity;
wxButton* m_preshared_set; wxButton* m_preshared_set;
wxTimer m_timer_own;
// Virtual event handlers, overide them in your derived class // Virtual event handlers, overide them in your derived class
virtual void OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); } virtual void OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void OnClearOwn( wxCommandEvent& event ) { event.Skip(); } virtual void OnClearOwn( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSetOwn( wxCommandEvent& event ) { event.Skip(); } virtual void OnSetOwn( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSetPreshared( wxCommandEvent& event ) { event.Skip(); } virtual void OnSetPreshared( wxCommandEvent& event ) { event.Skip(); }
virtual void OnTimerOwn( wxTimerEvent& event ) { event.Skip(); }
public: public:
@@ -158,7 +164,7 @@ class wxEAPCredentialsConfigPanelBase : public wxPanel
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// Class wxEAPCredentialsPassPanelBase /// Class wxEAPCredentialsPassPanelBase
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
class wxEAPCredentialsPassPanelBase : public wxPanel class wxEAPCredentialsPassPanelBase : public wxEAPCredentialsPanelBase
{ {
private: private:
@@ -198,10 +204,6 @@ class wxEAPProviderIdentityPanelBase : public wxPanel
wxTextCtrl* m_provider_email; wxTextCtrl* m_provider_email;
wxStaticText* m_provider_phone_icon; wxStaticText* m_provider_phone_icon;
wxTextCtrl* m_provider_phone; wxTextCtrl* m_provider_phone;
// Virtual event handlers, overide them in your derived class
virtual void OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); }
public: public:
@@ -222,10 +224,6 @@ class wxEAPProviderLockPanelBase : public wxPanel
wxStaticText* m_provider_lock_label; wxStaticText* m_provider_lock_label;
wxCheckBox* m_provider_lock; wxCheckBox* m_provider_lock;
wxStaticText* m_provider_lock_note; wxStaticText* m_provider_lock_note;
// Virtual event handlers, overide them in your derived class
virtual void OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); }
public: public:

View File

@@ -223,7 +223,7 @@ wxEAPCredentialWarningPanel::wxEAPCredentialWarningPanel(const eap::config_provi
// wxEAPConfigWindow // wxEAPConfigWindow
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
wxEAPConfigWindow::wxEAPConfigWindow(const eap::config_provider &prov, eap::config_method &cfg, wxWindow* parent) : wxEAPConfigWindow::wxEAPConfigWindow(eap::config_provider &prov, eap::config_method &cfg, wxWindow* parent) :
m_prov(prov), m_prov(prov),
m_cfg(cfg), m_cfg(cfg),
wxScrolledWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL) wxScrolledWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL)
@@ -232,42 +232,23 @@ wxEAPConfigWindow::wxEAPConfigWindow(const eap::config_provider &prov, eap::conf
// Connect Events // Connect Events
this->Connect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(wxEAPConfigWindow::OnInitDialog)); this->Connect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(wxEAPConfigWindow::OnInitDialog));
this->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(wxEAPConfigWindow::OnUpdateUI));
} }
wxEAPConfigWindow::~wxEAPConfigWindow() wxEAPConfigWindow::~wxEAPConfigWindow()
{ {
// Disconnect Events // Disconnect Events
this->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(wxEAPConfigWindow::OnUpdateUI));
this->Disconnect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(wxEAPConfigWindow::OnInitDialog)); this->Disconnect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(wxEAPConfigWindow::OnInitDialog));
} }
void wxEAPConfigWindow::OnInitDialog(wxInitDialogEvent& event) void wxEAPConfigWindow::OnInitDialog(wxInitDialogEvent& /*event*/)
{ {
UNREFERENCED_PARAMETER(event);
// Call TransferDataToWindow() manually, as wxScrolledWindow somehow skips that. // Call TransferDataToWindow() manually, as wxScrolledWindow somehow skips that.
TransferDataToWindow(); TransferDataToWindow();
} }
void wxEAPConfigWindow::OnUpdateUI(wxUpdateUIEvent& event)
{
UNREFERENCED_PARAMETER(event);
if (m_parent && m_parent->IsKindOf(wxCLASSINFO(wxNotebook))) {
// We're a notebook page. Set the ID of our provider as our page label.
wxNotebook *notebook = (wxNotebook*)m_parent;
int idx = notebook->FindPage(this);
if (idx != wxNOT_FOUND)
notebook->SetPageText(idx, wxEAPGetProviderName(m_prov.m_id));
} else
this->SetLabel(wxEAPGetProviderName(m_prov.m_id));
}
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// wxEAPProviderIdentityPanel // wxEAPProviderIdentityPanel
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////

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>

View File

@@ -95,5 +95,15 @@ namespace eap
/// \returns `eap::type_pap` /// \returns `eap::type_pap`
/// ///
virtual winstd::eap_type_t get_method_id() const; virtual winstd::eap_type_t get_method_id() const;
///
/// Returns a string \c L"PAP"
///
virtual const wchar_t* get_method_str() const;
///
/// Creates a blank set of credentials suitable for this method
///
virtual credentials* make_credentials() const;
}; };
} }

View File

@@ -105,17 +105,18 @@ namespace eap
/// 2. Pre-configured credentials /// 2. Pre-configured credentials
/// 3. Stored credentials /// 3. Stored credentials
/// ///
/// \param[in] cred_cached Cached credentials (optional, can be \c NULL) /// \param[in] cred_cached Cached credentials (optional, can be \c NULL, must be credentials_pap* type)
/// \param[in] cfg Method configuration /// \param[in] cfg Method configuration (must be config_method_pap type)
/// \param[in] pszTargetName The name in Windows Credential Manager to retrieve credentials from (optional, can be \c NULL) /// \param[in] pszTargetName The name in Windows Credential Manager to retrieve credentials from (optional, can be \c NULL)
/// ///
/// \returns /// \returns
/// - \c true if credentials were set; /// - \c source_cache Credentials were obtained from EapHost cache
/// - \c false otherwise /// - \c source_preshared Credentials were set by method configuration
/// - \c source_storage Credentials were loaded from Windows Credential Manager
/// ///
source_t combine( virtual source_t combine(
_In_ const credentials_pap *cred_cached, _In_ const credentials *cred_cached,
_In_ const config_method_pap &cfg, _In_ const config_method_with_cred &cfg,
_In_opt_z_ LPCTSTR pszTargetName); _In_opt_z_ LPCTSTR pszTargetName);
}; };
} }

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?
};
}

View File

@@ -74,3 +74,15 @@ eap_type_t eap::config_method_pap::get_method_id() const
{ {
return eap_type_pap; return eap_type_pap;
} }
const wchar_t* eap::config_method_pap::get_method_str() const
{
return L"PAP";
}
eap::credentials* eap::config_method_pap::make_credentials() const
{
return new credentials_pap(m_module);
}

View File

@@ -76,13 +76,13 @@ LPCTSTR eap::credentials_pap::target_suffix() const
eap::credentials::source_t eap::credentials_pap::combine( eap::credentials::source_t eap::credentials_pap::combine(
_In_ const credentials_pap *cred_cached, _In_ const credentials *cred_cached,
_In_ const config_method_pap &cfg, _In_ const config_method_with_cred &cfg,
_In_opt_z_ LPCTSTR pszTargetName) _In_opt_z_ LPCTSTR pszTargetName)
{ {
if (cred_cached) { if (cred_cached) {
// Using EAP service cached credentials. // Using EAP service cached credentials.
*this = *cred_cached; *this = *(credentials_pap*)cred_cached;
m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_CACHED1, event_data((unsigned int)eap_type_pap), event_data(credentials_pap::get_name()), event_data::blank); m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_CACHED1, event_data((unsigned int)eap_type_pap), event_data(credentials_pap::get_name()), event_data::blank);
return source_cache; return source_cache;
} }

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

@@ -162,6 +162,16 @@ namespace eap
/// ///
virtual winstd::eap_type_t get_method_id() const; virtual winstd::eap_type_t get_method_id() const;
///
/// Returns a string \c L"EAP-TLS"
///
virtual const wchar_t* get_method_str() const;
///
/// Creates a blank set of credentials suitable for this method
///
virtual credentials* make_credentials() const;
/// ///
/// Adds CA to the list of trusted root CA's /// Adds CA to the list of trusted root CA's
/// ///

View File

@@ -187,18 +187,19 @@ namespace eap
/// 2. Pre-configured credentials /// 2. Pre-configured credentials
/// 3. Stored credentials /// 3. Stored credentials
/// ///
/// \param[in] cred_cached Cached credentials (optional, can be \c NULL) /// \param[in] cred_cached Cached credentials (optional, can be \c NULL, must be credentials_tls* type)
/// \param[in] cfg Method configuration /// \param[in] cfg Method configuration (must be config_method_tls type)
/// \param[in] pszTargetName The name in Windows Credential Manager to retrieve credentials from (optional, can be \c NULL) /// \param[in] pszTargetName The name in Windows Credential Manager to retrieve credentials from (optional, can be \c NULL)
/// ///
/// \returns /// \returns
/// - \c true if credentials were set; /// - \c source_cache Credentials were obtained from EapHost cache
/// - \c false otherwise /// - \c source_preshared Credentials were set by method configuration
/// - \c source_storage Credentials were loaded from Windows Credential Manager
/// ///
source_t combine( virtual source_t combine(
_In_ const credentials_tls *cred_cached, _In_ const credentials *cred_cached,
_In_ const config_method_tls &cfg, _In_ const config_method_with_cred &cfg,
_In_opt_z_ LPCTSTR pszTargetName); _In_opt_z_ LPCTSTR pszTargetName);
public: public:
winstd::cert_context m_cert; ///< Client certificate winstd::cert_context m_cert; ///< Client certificate

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

@@ -292,6 +292,18 @@ eap_type_t eap::config_method_tls::get_method_id() const
} }
const wchar_t* eap::config_method_tls::get_method_str() const
{
return L"EAP-TLS";
}
eap::credentials* eap::config_method_tls::make_credentials() const
{
return new credentials_tls(m_module);
}
bool eap::config_method_tls::add_trusted_ca(_In_ DWORD dwCertEncodingType, _In_ const BYTE *pbCertEncoded, _In_ DWORD cbCertEncoded) bool eap::config_method_tls::add_trusted_ca(_In_ DWORD dwCertEncodingType, _In_ const BYTE *pbCertEncoded, _In_ DWORD cbCertEncoded)
{ {
cert_context cert; cert_context cert;

View File

@@ -84,7 +84,7 @@ void eap::credentials_tls::clear()
bool eap::credentials_tls::empty() const bool eap::credentials_tls::empty() const
{ {
return credentials::empty() && !m_cert; return !m_cert;
} }
@@ -174,12 +174,14 @@ void eap::credentials_tls::store(_In_z_ LPCTSTR pszTargetName) const
{ {
assert(pszTargetName); assert(pszTargetName);
// Encrypt the certificate using user's key.
DATA_BLOB cred_blob = { m_cert->cbCertEncoded, m_cert->pbCertEncoded };
DATA_BLOB entropy_blob = { sizeof(s_entropy) , (LPBYTE)s_entropy };
data_blob cred_enc; data_blob cred_enc;
if (!CryptProtectData(&cred_blob, NULL, &entropy_blob, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN, &cred_enc)) if (m_cert) {
throw win_runtime_error(__FUNCTION__ " CryptProtectData failed."); // Encrypt the certificate using user's key.
DATA_BLOB cred_blob = { m_cert->cbCertEncoded, m_cert->pbCertEncoded };
DATA_BLOB entropy_blob = { sizeof(s_entropy) , (LPBYTE)s_entropy };
if (!CryptProtectData(&cred_blob, NULL, &entropy_blob, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN, &cred_enc))
throw win_runtime_error(__FUNCTION__ " CryptProtectData failed.");
}
tstring target(target_name(pszTargetName)); tstring target(target_name(pszTargetName));
@@ -214,17 +216,20 @@ void eap::credentials_tls::retrieve(_In_z_ LPCTSTR pszTargetName)
if (!CredRead(target_name(pszTargetName).c_str(), CRED_TYPE_GENERIC, 0, (PCREDENTIAL*)&cred)) if (!CredRead(target_name(pszTargetName).c_str(), CRED_TYPE_GENERIC, 0, (PCREDENTIAL*)&cred))
throw win_runtime_error(__FUNCTION__ " CredRead failed."); throw win_runtime_error(__FUNCTION__ " CredRead failed.");
// Decrypt the certificate using user's key. if (cred->CredentialBlobSize) {
DATA_BLOB cred_enc = { cred->CredentialBlobSize, cred->CredentialBlob }; // Decrypt the certificate using user's key.
DATA_BLOB entropy_blob = { sizeof(s_entropy) , (LPBYTE)s_entropy }; DATA_BLOB cred_enc = { cred->CredentialBlobSize, cred->CredentialBlob };
data_blob cred_int; DATA_BLOB entropy_blob = { sizeof(s_entropy) , (LPBYTE)s_entropy };
if (!CryptUnprotectData(&cred_enc, NULL, &entropy_blob, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN | CRYPTPROTECT_VERIFY_PROTECTION, &cred_int)) data_blob cred_int;
throw win_runtime_error(__FUNCTION__ " CryptUnprotectData failed."); if (!CryptUnprotectData(&cred_enc, NULL, &entropy_blob, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN | CRYPTPROTECT_VERIFY_PROTECTION, &cred_int))
throw win_runtime_error(__FUNCTION__ " CryptUnprotectData failed.");
bool bResult = m_cert.create(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, cred_int.pbData, cred_int.cbData); bool bResult = m_cert.create(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, cred_int.pbData, cred_int.cbData);
SecureZeroMemory(cred_int.pbData, cred_int.cbData); SecureZeroMemory(cred_int.pbData, cred_int.cbData);
if (!bResult) if (!bResult)
throw win_runtime_error(__FUNCTION__ " Error loading certificate."); throw win_runtime_error(__FUNCTION__ " Error loading certificate.");
} else
m_cert.free();
if (cred->UserName) if (cred->UserName)
m_identity = cred->UserName; m_identity = cred->UserName;
@@ -248,22 +253,56 @@ 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;
return L""; 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"";
} }
eap::credentials::source_t eap::credentials_tls::combine( eap::credentials::source_t eap::credentials_tls::combine(
_In_ const credentials_tls *cred_cached, _In_ const credentials *cred_cached,
_In_ const config_method_tls &cfg, _In_ const config_method_with_cred &cfg,
_In_opt_z_ LPCTSTR pszTargetName) _In_opt_z_ LPCTSTR pszTargetName)
{ {
if (cred_cached) { if (cred_cached) {
// Using EAP service cached credentials. // Using EAP service cached credentials.
*this = *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_CACHED1, event_data((unsigned int)eap_type_tls), event_data(credentials_tls::get_name()), event_data::blank);
return source_cache; return source_cache;
} }

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());
@@ -311,30 +290,30 @@ void eap::method_tls::begin_session(
// Prepare client credentials for Schannel. // Prepare client credentials for Schannel.
PCCERT_CONTEXT certs[] = { m_cred.m_cert ? m_cred.m_cert : NULL }; PCCERT_CONTEXT certs[] = { m_cred.m_cert ? m_cred.m_cert : NULL };
SCHANNEL_CRED cred = { SCHANNEL_CRED cred = {
SCHANNEL_CRED_VERSION, // dwVersion SCHANNEL_CRED_VERSION, // dwVersion
m_cred.m_cert ? 1 : 0, // cCreds m_cred.m_cert ? 1 : 0, // cCreds
certs, // paCred certs, // paCred
NULL, // hRootStore: Not valid for client credentials NULL, // hRootStore: Not valid for client credentials
0, // cMappers 0, // cMappers
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 0, // grbitEnabledProtocols: Use default
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
#if EAP_TLS >= EAP_TLS_SCHANNEL_FULL #if EAP_TLS >= EAP_TLS_SCHANNEL_FULL
SCH_CRED_AUTO_CRED_VALIDATION | // dwFlags: Let Schannel verify server certificate SCH_CRED_AUTO_CRED_VALIDATION | // dwFlags: Let Schannel verify server certificate
#else #else
SCH_CRED_MANUAL_CRED_VALIDATION | // dwFlags: Prevent Schannel verify server certificate (we want to use custom root CA store and multiple name checking) SCH_CRED_MANUAL_CRED_VALIDATION | // dwFlags: Prevent Schannel verify server certificate (we want to use custom root CA store and multiple name checking)
#endif #endif
SCH_CRED_CACHE_ONLY_URL_RETRIEVAL_ON_CREATE | // dwFlags: Do not attempt online revocation check - we do not expect to have network connection yet SCH_CRED_CACHE_ONLY_URL_RETRIEVAL_ON_CREATE | // dwFlags: Do not attempt online revocation check - we do not expect to have network connection yet
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
}; };
SECURITY_STATUS stat = m_sc_cred.acquire(NULL, UNISP_NAME, SECPKG_CRED_OUTBOUND, NULL, &cred); SECURITY_STATUS stat = m_sc_cred.acquire(NULL, UNISP_NAME, SECPKG_CRED_OUTBOUND, NULL, &cred);
if (FAILED(stat)) if (FAILED(stat))
@@ -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

@@ -248,7 +248,7 @@ protected:
}; };
class wxTLSCredentialsPanel : public wxEAPCredentialsPanelBase<eap::credentials_tls, wxTLSCredentialsPanelBase> class wxTLSCredentialsPanel : public wxEAPCredentialsPanel<eap::credentials_tls, wxTLSCredentialsPanelBase>
{ {
public: public:
/// ///

View File

@@ -194,8 +194,14 @@ wxTLSCredentialsPanelBase::wxTLSCredentialsPanelBase( wxWindow* parent, wxWindow
this->SetSizer( sb_credentials ); this->SetSizer( sb_credentials );
this->Layout(); this->Layout();
// Connect Events
this->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( wxTLSCredentialsPanelBase::OnUpdateUI ) );
} }
wxTLSCredentialsPanelBase::~wxTLSCredentialsPanelBase() wxTLSCredentialsPanelBase::~wxTLSCredentialsPanelBase()
{ {
// Disconnect Events
this->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( wxTLSCredentialsPanelBase::OnUpdateUI ) );
} }

View File

@@ -1050,7 +1050,7 @@
<event name="OnRightUp"></event> <event name="OnRightUp"></event>
<event name="OnSetFocus"></event> <event name="OnSetFocus"></event>
<event name="OnSize"></event> <event name="OnSize"></event>
<event name="OnUpdateUI"></event> <event name="OnUpdateUI">OnUpdateUI</event>
<object class="wxStaticBoxSizer" expanded="1"> <object class="wxStaticBoxSizer" expanded="1">
<property name="id">wxID_ANY</property> <property name="id">wxID_ANY</property>
<property name="label">TLS Client Certificate</property> <property name="label">TLS Client Certificate</property>

View File

@@ -84,6 +84,10 @@ class wxTLSCredentialsPanelBase : public wxPanel
wxTextCtrl* m_identity; wxTextCtrl* m_identity;
wxStaticText* m_identity_note; wxStaticText* m_identity_note;
wxCheckBox* m_remember; wxCheckBox* m_remember;
// Virtual event handlers, overide them in your derived class
virtual void OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); }
public: public:

View File

@@ -25,3 +25,5 @@
#include "../../../include/Version.h" #include "../../../include/Version.h"
#include "../include/TLS_UI.h" #include "../include/TLS_UI.h"
#include <WindowsX.h>

View File

@@ -312,7 +312,7 @@ bool wxFQDNListValidator::Parse(const wxString &val_in, size_t i_start, size_t i
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
wxTLSCredentialsPanel::wxTLSCredentialsPanel(const eap::config_provider &prov, const eap::config_method_with_cred &cfg, eap::credentials_tls &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config) : wxTLSCredentialsPanel::wxTLSCredentialsPanel(const eap::config_provider &prov, const eap::config_method_with_cred &cfg, eap::credentials_tls &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config) :
wxEAPCredentialsPanelBase<eap::credentials_tls, wxTLSCredentialsPanelBase>(prov, cfg, cred, pszCredTarget, parent, is_config) wxEAPCredentialsPanel<eap::credentials_tls, wxTLSCredentialsPanelBase>(prov, cfg, cred, pszCredTarget, parent, is_config)
{ {
// Load and set icon. // Load and set icon.
winstd::library lib_shell32; winstd::library lib_shell32;
@@ -361,7 +361,7 @@ bool wxTLSCredentialsPanel::TransferDataToWindow()
m_identity->SetValue(m_cred.m_identity); m_identity->SetValue(m_cred.m_identity);
return wxEAPCredentialsPanelBase<eap::credentials_tls, wxTLSCredentialsPanelBase>::TransferDataToWindow(); return wxEAPCredentialsPanel<eap::credentials_tls, wxTLSCredentialsPanelBase>::TransferDataToWindow();
} }
@@ -381,11 +381,11 @@ bool wxTLSCredentialsPanel::TransferDataFromWindow()
// Inherited TransferDataFromWindow() calls m_cred.store(). // Inherited TransferDataFromWindow() calls m_cred.store().
// Therefore, call it only now, that m_cred is set. // Therefore, call it only now, that m_cred is set.
return wxEAPCredentialsPanelBase<eap::credentials_tls, wxTLSCredentialsPanelBase>::TransferDataFromWindow(); return wxEAPCredentialsPanel<eap::credentials_tls, wxTLSCredentialsPanelBase>::TransferDataFromWindow();
} }
void wxTLSCredentialsPanel::OnUpdateUI(wxUpdateUIEvent& event) void wxTLSCredentialsPanel::OnUpdateUI(wxUpdateUIEvent& /*event*/)
{ {
if (!m_is_config && m_cfg.m_use_preshared) { if (!m_is_config && m_cfg.m_use_preshared) {
// Credential prompt mode & Using pre-shared credentials // Credential prompt mode & Using pre-shared credentials
@@ -404,8 +404,6 @@ void wxTLSCredentialsPanel::OnUpdateUI(wxUpdateUIEvent& event)
m_cert_select_val->Enable(m_cert_select->GetValue()); m_cert_select_val->Enable(m_cert_select->GetValue());
m_identity->Enable(true); m_identity->Enable(true);
} }
wxEAPCredentialsPanelBase<eap::credentials_tls, wxTLSCredentialsPanelBase>::OnUpdateUI(event);
} }
@@ -465,10 +463,8 @@ bool wxTLSServerTrustPanel::TransferDataFromWindow()
} }
void wxTLSServerTrustPanel::OnUpdateUI(wxUpdateUIEvent& event) void wxTLSServerTrustPanel::OnUpdateUI(wxUpdateUIEvent& /*event*/)
{ {
UNREFERENCED_PARAMETER(event);
if (m_prov.m_read_only) { if (m_prov.m_read_only) {
// This is provider-locked configuration. Disable controls. // This is provider-locked configuration. Disable controls.
m_root_ca_add_store->Enable(false); m_root_ca_add_store->Enable(false);
@@ -479,9 +475,12 @@ void wxTLSServerTrustPanel::OnUpdateUI(wxUpdateUIEvent& event)
// This is not a provider-locked configuration. Selectively enable/disable controls. // This is not a provider-locked configuration. Selectively enable/disable controls.
m_root_ca_add_store->Enable(true); m_root_ca_add_store->Enable(true);
m_root_ca_add_file ->Enable(true); m_root_ca_add_file ->Enable(true);
wxArrayInt selections; m_root_ca_remove ->Enable(ListBox_GetSelCount(m_root_ca->GetHWND()) ? true : false); // *
m_root_ca_remove->Enable(m_root_ca->GetSelections(selections) ? true : false);
m_server_names ->Enable(true); m_server_names ->Enable(true);
// * ListBox_GetSelCount() is not cross-platform, but this is Windows EAP Supplicant,
// and this is the fastest way to find out if there is a selection in the list box,
// observing wxWidgets 3.0.2 has nothing faster to offer.
} }
} }
@@ -494,10 +493,8 @@ void wxTLSServerTrustPanel::OnRootCADClick(wxCommandEvent& event)
} }
void wxTLSServerTrustPanel::OnRootCAAddStore(wxCommandEvent& event) void wxTLSServerTrustPanel::OnRootCAAddStore(wxCommandEvent& /*event*/)
{ {
UNREFERENCED_PARAMETER(event);
winstd::cert_store store; winstd::cert_store store;
if (store.create(NULL, _T("ROOT"))) { if (store.create(NULL, _T("ROOT"))) {
winstd::cert_context cert; winstd::cert_context cert;
@@ -510,8 +507,6 @@ void wxTLSServerTrustPanel::OnRootCAAddStore(wxCommandEvent& event)
void wxTLSServerTrustPanel::OnRootCAAddFile(wxCommandEvent& event) void wxTLSServerTrustPanel::OnRootCAAddFile(wxCommandEvent& event)
{ {
UNREFERENCED_PARAMETER(event);
const wxString separator(wxT("|")); const wxString separator(wxT("|"));
wxFileDialog open_dialog(this, _("Add Certificate"), wxEmptyString, wxEmptyString, wxFileDialog open_dialog(this, _("Add Certificate"), wxEmptyString, wxEmptyString,
_("Certificate Files (*.cer;*.crt;*.der;*.p7b;*.pem)") + separator + wxT("*.cer;*.crt;*.der;*.p7b;*.pem") + separator + _("Certificate Files (*.cer;*.crt;*.der;*.p7b;*.pem)") + separator + wxT("*.cer;*.crt;*.der;*.p7b;*.pem") + separator +
@@ -538,10 +533,8 @@ void wxTLSServerTrustPanel::OnRootCAAddFile(wxCommandEvent& event)
} }
void wxTLSServerTrustPanel::OnRootCARemove(wxCommandEvent& event) void wxTLSServerTrustPanel::OnRootCARemove(wxCommandEvent& /*event*/)
{ {
UNREFERENCED_PARAMETER(event);
wxArrayInt selections; wxArrayInt selections;
for (int i = m_root_ca->GetSelections(selections); i--; ) for (int i = m_root_ca->GetSelections(selections); i--; )
m_root_ca->Delete(selections[i]); m_root_ca->Delete(selections[i]);

View File

@@ -33,7 +33,6 @@ namespace eap
#include "Credentials.h" #include "Credentials.h"
#include "../../TLS/include/Config.h" #include "../../TLS/include/Config.h"
#include "../../PAP/include/Config.h"
#include <Windows.h> #include <Windows.h>
#include <assert.h> #include <assert.h>
@@ -142,6 +141,30 @@ namespace eap {
/// ///
virtual winstd::eap_type_t get_method_id() const; virtual winstd::eap_type_t get_method_id() const;
///
/// Returns a string \c L"EAP-TTLS"
///
virtual const wchar_t* get_method_str() const;
///
/// Creates a blank set of credentials suitable for this method
///
virtual credentials* make_credentials() const;
///
/// Makes a new inner method config
///
/// \param[in] eap_type EAP type
///
config_method_with_cred* make_config_method(_In_ winstd::eap_type_t eap_type) const;
///
/// Makes a new inner method config
///
/// \param[in] eap_type EAP type
///
config_method_with_cred* make_config_method(_In_ const wchar_t *eap_type) const;
/// ///
/// Generates public identity using current configuration and given credentials /// Generates public identity using current configuration and given credentials
/// ///

View File

@@ -29,10 +29,8 @@ namespace eap
#pragma once #pragma once
#include "../../TLS/include/Credentials.h" #include "../../TLS/include/Credentials.h"
#include "../../PAP/include/Credentials.h"
#include <memory> #include <memory>
#include <utility>
namespace eap namespace eap
@@ -161,11 +159,6 @@ namespace eap
/// ///
virtual void retrieve(_In_z_ LPCTSTR pszTargetName); virtual void retrieve(_In_z_ LPCTSTR pszTargetName);
///
/// Return target suffix for Windows Credential Manager credential name
///
virtual LPCTSTR target_suffix() const;
/// ///
/// Returns credential identity. /// Returns credential identity.
/// ///
@@ -180,18 +173,19 @@ namespace eap
/// 2. Pre-configured credentials /// 2. Pre-configured credentials
/// 3. Stored credentials /// 3. Stored credentials
/// ///
/// \param[in] cred_cached Cached credentials (optional, can be \c NULL) /// \param[in] cred_cached Cached credentials (optional, can be \c NULL, must be credentials_ttls* type)
/// \param[in] cfg Method configuration /// \param[in] cfg Method configuration (must be config_method_ttls type)
/// \param[in] pszTargetName The name in Windows Credential Manager to retrieve credentials from (optional, can be \c NULL) /// \param[in] pszTargetName The name in Windows Credential Manager to retrieve credentials from (optional, can be \c NULL)
/// ///
/// \returns /// \returns
/// - \c true if credentials were set; /// - \c source_cache Credentials were obtained from EapHost cache
/// - \c false otherwise /// - \c source_preshared Credentials were set by method configuration
/// - \c source_storage Credentials were loaded from Windows Credential Manager
/// ///
std::pair<source_t, source_t> combine( virtual source_t combine(
_In_ const credentials_ttls *cred_cached, _In_ const credentials *cred_cached,
_In_ const config_method_ttls &cfg, _In_ const config_method_with_cred &cfg,
_In_opt_z_ LPCTSTR pszTargetName); _In_opt_z_ LPCTSTR pszTargetName);
public: public:
std::unique_ptr<credentials> m_inner; ///< Inner credentials std::unique_ptr<credentials> m_inner; ///< Inner credentials

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

@@ -214,16 +214,21 @@ namespace eap
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:
config_connection m_cfg; ///< Connection configuration module &m_module; ///< Module
credentials_ttls m_cred; ///< User credentials config_connection m_cfg; ///< Connection configuration
method_ttls m_method; ///< EAP-TTLS method credentials_ttls m_cred; ///< User credentials
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

@@ -105,15 +105,19 @@ void eap::config_method_ttls::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode
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"), bstrNamespace, &pXmlElInnerAuthenticationMethod)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <InnerAuthenticationMethod> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <InnerAuthenticationMethod> element.");
if (dynamic_cast<const config_method_pap*>(m_inner.get())) { eap_type_t eap_type = m_inner->get_method_id();
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(L"PAP")))) if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElInnerAuthenticationMethod, bstr(L"NonEAPAuthMethod"), bstrNamespace, 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 {
// <InnerAuthenticationMethod>/<EAPMethod>
if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElInnerAuthenticationMethod, bstr(L"EAPMethod"), bstrNamespace, (DWORD)m_inner->get_method_id())))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <EAPMethod> element.");
}
// <InnerAuthenticationMethod>/... // <InnerAuthenticationMethod>/...
m_inner->save(pDoc, pXmlElInnerAuthenticationMethod); m_inner->save(pDoc, pXmlElInnerAuthenticationMethod);
} else
throw win_runtime_error(ERROR_NOT_SUPPORTED, __FUNCTION__ " Unsupported inner authentication method.");
} }
@@ -144,63 +148,38 @@ void eap::config_method_ttls::load(_In_ IXMLDOMNode *pConfigRoot)
throw com_runtime_error(hr, __FUNCTION__ " Error selecting <InnerAuthenticationMethod> element."); throw com_runtime_error(hr, __FUNCTION__ " Error selecting <InnerAuthenticationMethod> element.");
// Determine inner authentication type (<EAPMethod> and <NonEAPAuthMethod>). // Determine inner authentication type (<EAPMethod> and <NonEAPAuthMethod>).
//DWORD dwMethodID; DWORD dwMethod;
bstr bstrMethod; bstr bstrMethod;
/*if (SUCCEEDED(eapxml::get_element_value(pXmlElInnerAuthenticationMethod, bstr(L"eap-metadata:EAPMethod"), &dwMethodID)) && if (SUCCEEDED(eapxml::get_element_value(pXmlElInnerAuthenticationMethod, bstr(L"eap-metadata:EAPMethod"), &dwMethod)) &&
dwMethodID == EAP_TYPE_MSCHAPV2) eap_type_start <= dwMethod && dwMethod < eap_type_end)
{ {
// MSCHAPv2 m_inner.reset(make_config_method((eap_type_t)dwMethod));
// TODO: Add MSCHAPv2 support. m_module.log_config((xpath + L"/EAPMethod").c_str(), m_inner->get_method_str());
throw win_runtime_error(ERROR_NOT_SUPPORTED, __FUNCTION__ " MSCHAPv2 not supported yet."); } else if (SUCCEEDED(eapxml::get_element_value(pXmlElInnerAuthenticationMethod, bstr(L"eap-metadata:NonEAPAuthMethod"), &bstrMethod))) {
} else*/ if (SUCCEEDED(eapxml::get_element_value(pXmlElInnerAuthenticationMethod, bstr(L"eap-metadata:NonEAPAuthMethod"), &bstrMethod)) && m_inner.reset(make_config_method(bstrMethod));
CompareStringEx(LOCALE_NAME_INVARIANT, NORM_IGNORECASE, bstrMethod, bstrMethod.length(), L"PAP", -1, NULL, NULL, 0) == CSTR_EQUAL) m_module.log_config((xpath + L"/NonEAPAuthMethod").c_str(), m_inner->get_method_str());
{
// PAP
m_module.log_config((xpath + L"/NonEAPAuthMethod").c_str(), L"PAP");
m_inner.reset(new config_method_pap(m_module));
m_inner->load(pXmlElInnerAuthenticationMethod);
} else } else
throw win_runtime_error(ERROR_NOT_SUPPORTED, __FUNCTION__ " Unsupported inner authentication method."); throw win_runtime_error(ERROR_NOT_SUPPORTED, __FUNCTION__ " Unsupported inner authentication method.");
m_inner->load(pXmlElInnerAuthenticationMethod);
} }
void eap::config_method_ttls::operator<<(_Inout_ cursor_out &cursor) const void eap::config_method_ttls::operator<<(_Inout_ cursor_out &cursor) const
{ {
config_method_tls::operator<<(cursor); config_method_tls::operator<<(cursor);
cursor << m_inner->get_method_id();
if (m_inner) { cursor << *m_inner;
if (dynamic_cast<config_method_pap*>(m_inner.get())) {
cursor << eap_type_pap;
cursor << *m_inner;
} else {
assert(0); // Unsupported inner authentication method type.
cursor << eap_type_undefined;
}
} else
cursor << eap_type_undefined;
cursor << m_anonymous_identity; cursor << m_anonymous_identity;
} }
size_t eap::config_method_ttls::get_pk_size() const size_t eap::config_method_ttls::get_pk_size() const
{ {
size_t size_inner;
if (m_inner) {
if (dynamic_cast<config_method_pap*>(m_inner.get())) {
size_inner =
pksizeof(eap_type_pap) +
pksizeof(*m_inner);
} else {
assert(0); // Unsupported inner authentication method type.
size_inner = pksizeof(eap_type_undefined);
}
} else
size_inner = pksizeof(eap_type_undefined);
return return
config_method_tls::get_pk_size() + config_method_tls::get_pk_size() +
size_inner + pksizeof(m_inner->get_method_id()) +
pksizeof(*m_inner) +
pksizeof(m_anonymous_identity); pksizeof(m_anonymous_identity);
} }
@@ -211,16 +190,8 @@ void eap::config_method_ttls::operator>>(_Inout_ cursor_in &cursor)
eap_type_t eap_type; eap_type_t eap_type;
cursor >> eap_type; cursor >> eap_type;
switch (eap_type) { m_inner.reset(make_config_method(eap_type));
case eap_type_pap: cursor >> *m_inner;
m_inner.reset(new config_method_pap(m_module));
cursor >> *m_inner;
break;
default:
assert(0); // Unsupported inner authentication method type.
m_inner.reset(nullptr);
}
cursor >> m_anonymous_identity; cursor >> m_anonymous_identity;
} }
@@ -231,6 +202,42 @@ eap_type_t eap::config_method_ttls::get_method_id() const
} }
const wchar_t* eap::config_method_ttls::get_method_str() const
{
return L"EAP-TTLS";
}
eap::credentials* eap::config_method_ttls::make_credentials() const
{
return new credentials_ttls(m_module);
}
eap::config_method_with_cred* eap::config_method_ttls::make_config_method(_In_ winstd::eap_type_t eap_type) const
{
switch (eap_type) {
case eap_type_tls : return new config_method_tls (m_module);
case eap_type_ttls: return new config_method_ttls(m_module);
case eap_type_pap : return new config_method_pap (m_module);
default : throw invalid_argument(__FUNCTION__ " Unsupported inner authentication method.");
}
}
eap::config_method_with_cred* eap::config_method_ttls::make_config_method(_In_ const wchar_t *eap_type) const
{
if (_wcsicmp(eap_type, L"EAP-TLS") == 0)
return new config_method_tls(m_module);
else if (_wcsicmp(eap_type, L"EAP-TTLS") == 0)
return new config_method_ttls(m_module);
else if (_wcsicmp(eap_type, L"PAP") == 0)
return new config_method_pap(m_module);
else
throw invalid_argument(__FUNCTION__ " Unsupported inner authentication method.");
}
wstring eap::config_method_ttls::get_public_identity(const credentials_ttls &cred) const wstring eap::config_method_ttls::get_public_identity(const credentials_ttls &cred) const
{ {
if (m_anonymous_identity.empty()) { if (m_anonymous_identity.empty()) {

View File

@@ -79,14 +79,13 @@ eap::config* eap::credentials_ttls::clone() const
void eap::credentials_ttls::clear() void eap::credentials_ttls::clear()
{ {
credentials_tls::clear(); credentials_tls::clear();
if (m_inner) m_inner->clear();
m_inner->clear();
} }
bool eap::credentials_ttls::empty() const bool eap::credentials_ttls::empty() const
{ {
return credentials_tls::empty() && (!m_inner || m_inner->empty()); return credentials_tls::empty() && m_inner->empty();
} }
@@ -100,17 +99,15 @@ void eap::credentials_ttls::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *p
const bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata"); const bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata");
HRESULT hr; HRESULT hr;
if (m_inner) { // <InnerAuthenticationMethod>
// <InnerAuthenticationMethod> winstd::com_obj<IXMLDOMElement> pXmlElInnerAuthenticationMethod;
winstd::com_obj<IXMLDOMElement> pXmlElInnerAuthenticationMethod; if (FAILED(hr = eapxml::create_element(pDoc, winstd::bstr(L"InnerAuthenticationMethod"), bstrNamespace, &pXmlElInnerAuthenticationMethod)))
if (FAILED(hr = eapxml::create_element(pDoc, winstd::bstr(L"InnerAuthenticationMethod"), bstrNamespace, &pXmlElInnerAuthenticationMethod))) throw com_runtime_error(hr, __FUNCTION__ " Error creating <InnerAuthenticationMethod> element.");
throw com_runtime_error(hr, __FUNCTION__ " Error creating <InnerAuthenticationMethod> element.");
m_inner->save(pDoc, pXmlElInnerAuthenticationMethod); m_inner->save(pDoc, pXmlElInnerAuthenticationMethod);
if (FAILED(hr = pConfigRoot->appendChild(pXmlElInnerAuthenticationMethod, NULL))) if (FAILED(hr = pConfigRoot->appendChild(pXmlElInnerAuthenticationMethod, NULL)))
throw com_runtime_error(hr, __FUNCTION__ " Error appending <InnerAuthenticationMethod> element."); throw com_runtime_error(hr, __FUNCTION__ " Error appending <InnerAuthenticationMethod> element.");
}
} }
@@ -121,69 +118,34 @@ void eap::credentials_ttls::load(_In_ IXMLDOMNode *pConfigRoot)
credentials_tls::load(pConfigRoot); credentials_tls::load(pConfigRoot);
// TODO: For the time being, there is no detection what type is inner method. Introduce one! // Load inner credentials.
if (m_inner) { com_obj<IXMLDOMNode> pXmlElInnerAuthenticationMethod;
com_obj<IXMLDOMNode> pXmlElInnerAuthenticationMethod; if (SUCCEEDED(hr = eapxml::select_node(pConfigRoot, bstr(L"eap-metadata:InnerAuthenticationMethod"), &pXmlElInnerAuthenticationMethod)))
if (FAILED(hr = eapxml::select_node(pConfigRoot, bstr(L"eap-metadata:InnerAuthenticationMethod"), &pXmlElInnerAuthenticationMethod)))
throw com_runtime_error(hr, __FUNCTION__ " Error selecting <InnerAuthenticationMethod> element.");
m_inner->load(pXmlElInnerAuthenticationMethod); m_inner->load(pXmlElInnerAuthenticationMethod);
} else
m_inner->clear();
} }
void eap::credentials_ttls::operator<<(_Inout_ cursor_out &cursor) const void eap::credentials_ttls::operator<<(_Inout_ cursor_out &cursor) const
{ {
credentials_tls::operator<<(cursor); credentials_tls::operator<<(cursor);
if (m_inner) { cursor << *m_inner;
if (dynamic_cast<credentials_pap*>(m_inner.get())) {
cursor << eap_type_pap;
cursor << *m_inner;
} else {
assert(0); // Unsupported inner authentication method type.
cursor << eap_type_undefined;
}
} else
cursor << eap_type_undefined;
} }
size_t eap::credentials_ttls::get_pk_size() const size_t eap::credentials_ttls::get_pk_size() const
{ {
size_t size_inner;
if (m_inner) {
if (dynamic_cast<credentials_pap*>(m_inner.get())) {
size_inner =
pksizeof(eap_type_pap) +
pksizeof(*m_inner);
} else {
assert(0); // Unsupported inner authentication method type.
size_inner = pksizeof(eap_type_undefined);
}
} else
size_inner = pksizeof(eap_type_undefined);
return return
credentials_tls::get_pk_size() + credentials_tls::get_pk_size() +
size_inner; pksizeof(*m_inner);
} }
void eap::credentials_ttls::operator>>(_Inout_ cursor_in &cursor) void eap::credentials_ttls::operator>>(_Inout_ cursor_in &cursor)
{ {
credentials_tls::operator>>(cursor); credentials_tls::operator>>(cursor);
cursor >> *m_inner;
eap_type_t eap_type;
cursor >> eap_type;
switch (eap_type) {
case eap_type_pap:
m_inner.reset(new credentials_pap(m_module));
cursor >> *m_inner;
break;
default:
assert(0); // Unsupported inner authentication method type.
m_inner.reset(nullptr);
}
} }
@@ -193,8 +155,7 @@ void eap::credentials_ttls::store(_In_z_ LPCTSTR pszTargetName) const
credentials_tls::store(pszTargetName); credentials_tls::store(pszTargetName);
if (m_inner) m_inner->store(pszTargetName);
m_inner->store(pszTargetName);
} }
@@ -204,38 +165,38 @@ void eap::credentials_ttls::retrieve(_In_z_ LPCTSTR pszTargetName)
credentials_tls::retrieve(pszTargetName); credentials_tls::retrieve(pszTargetName);
if (m_inner) m_inner->retrieve(pszTargetName);
m_inner->retrieve(pszTargetName);
} }
LPCTSTR eap::credentials_ttls::target_suffix() const wstring eap::credentials_ttls::get_identity() const
{
assert(0); // Not that we would ever store inner&outer credentials to Windows Credential Manager joined, but for completness sake... Here we go:
return _T("TTLS");
}
std::wstring eap::credentials_ttls::get_identity() const
{ {
// Outer identity has the right-of-way. // Outer identity has the right-of-way.
if (!credentials_tls::empty()) wstring identity(credentials_tls::get_identity());
return credentials_tls::get_identity(); if (!identity.empty())
return identity;
// Inner identity. // Inner identity.
if (m_inner) return m_inner->get_identity();
return m_inner->get_identity();
return L"";
} }
pair<eap::credentials::source_t, eap::credentials::source_t> eap::credentials_ttls::combine( eap::credentials::source_t eap::credentials_ttls::combine(
_In_ const credentials_ttls *cred_cached, _In_ const credentials *cred_cached,
_In_ const config_method_ttls &cfg, _In_ const config_method_with_cred &cfg,
_In_opt_z_ LPCTSTR pszTargetName) _In_opt_z_ LPCTSTR pszTargetName)
{ {
return pair<source_t, source_t>( // Combine outer credentials.
credentials_tls::combine(cred_cached, cfg, pszTargetName), source_t src_outer = credentials_tls::combine(
dynamic_cast<const credentials_pap*>(m_inner.get()) ? ((credentials_pap*)m_inner.get())->combine(cred_cached ? (credentials_pap*)cred_cached->m_inner.get() : NULL, (const config_method_pap&)*cfg.m_inner, pszTargetName) : source_unknown); cred_cached,
cfg,
pszTargetName);
// Combine inner credentials.
source_t src_inner = m_inner->combine(
cred_cached ? ((const credentials_ttls*)cred_cached)->m_inner.get() : NULL,
*((const config_method_ttls&)cfg).m_inner,
pszTargetName);
return std::min<source_t>(src_outer, src_inner);
} }

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,121 +192,97 @@ 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.
SecPkgContext_StreamSizes sizes; #if EAP_TLS < EAP_TLS_SCHANNEL
status = QueryContextAttributes(m_sc_ctx, SECPKG_ATTR_STREAM_SIZES, &sizes); m_packet_res.m_code = EapCodeResponse;
if (FAILED(status)) m_packet_res.m_id = m_packet_req.m_id;
throw sec_runtime_error(status, __FUNCTION__ " Error getting Schannel required encryption sizes."); m_packet_res.m_flags = 0;
// Make PAP message. DWORD size_data = m_size_inner_packet_max;
sanitizing_blob msg_pap(make_pap_client()); sanitizing_blob data(size_data, 0);
assert(msg_pap.size() < sizes.cbMaximumMessage); unsigned char *ptr_data = data.data();
unsigned long size_data = std::min<unsigned long>(sizes.cbMaximumMessage, (unsigned long)msg_pap.size()); // Truncate #else
SecPkgContext_StreamSizes sizes;
SECURITY_STATUS status = QueryContextAttributes(m_sc_ctx, SECPKG_ATTR_STREAM_SIZES, &sizes);
if (FAILED(status))
throw sec_runtime_error(status, __FUNCTION__ " Error getting Schannel required encryption sizes.");
sanitizing_blob data(sizes.cbHeader + size_data + sizes.cbTrailer, 0); sanitizing_blob data(sizes.cbHeader + m_size_inner_packet_max + sizes.cbTrailer, 0);
memcpy(data.data() + sizes.cbHeader, msg_pap.data(), size_data); DWORD size_data = m_size_inner_packet_max;
unsigned char *ptr_data = data.data() + sizes.cbHeader;
#endif
m_inner->get_response_packet((EapPacket*)ptr_data, &size_data);
// Prepare input/output buffer(s). if (eap_type_noneap_start <= eap_type && eap_type < eap_type_noneap_end) {
SecBuffer buf[] = { // Inner method is non-EAP. Strip EAP header, since server expect raw data.
{ sizes.cbHeader, SECBUFFER_STREAM_HEADER , data.data() }, memmove(ptr_data, ptr_data + 4, size_data -= 4);
{ size_data, SECBUFFER_DATA , data.data() + sizes.cbHeader }, }
{ sizes.cbTrailer, SECBUFFER_STREAM_TRAILER, data.data() + sizes.cbHeader + size_data },
{ 0, SECBUFFER_EMPTY , NULL },
};
SecBufferDesc buf_desc = {
SECBUFFER_VERSION,
_countof(buf),
buf
};
// Encrypt the message. #if EAP_TLS < EAP_TLS_SCHANNEL
status = EncryptMessage(m_sc_ctx, 0, &buf_desc, 0); data.resize(size_data);
if (FAILED(status)) sanitizing_blob msg_application(make_message(tls_message_type_application_data, std::move(data)));
throw sec_runtime_error(status, __FUNCTION__ " Error encrypting message."); m_packet_res.m_data.insert(m_packet_res.m_data.end(), msg_application.begin(), msg_application.end());
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); #else
} // Prepare input/output buffer(s).
SecBuffer buf[] = {
{ sizes.cbHeader, SECBUFFER_STREAM_HEADER , data.data() },
{ size_data, SECBUFFER_DATA , ptr_data },
{ sizes.cbTrailer, SECBUFFER_STREAM_TRAILER, ptr_data + size_data },
{ 0, SECBUFFER_EMPTY , NULL },
};
SecBufferDesc buf_desc = {
SECBUFFER_VERSION,
_countof(buf),
buf
};
// Encrypt the message.
status = EncryptMessage(m_sc_ctx, 0, &buf_desc, 0);
if (FAILED(status))
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);
#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

@@ -76,10 +76,10 @@ void eap::peer_ttls::get_identity(
// Unpack configuration. // Unpack configuration.
config_connection cfg(*this); config_connection cfg(*this);
unpack(cfg, pConnectionData, dwConnectionDataSize); unpack(cfg, pConnectionData, dwConnectionDataSize);
if (cfg.m_providers.empty() || cfg.m_providers.front().m_methods.empty())
throw invalid_argument(__FUNCTION__ " Configuration has no providers and/or methods.");
// Get method configuration. // 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_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()); const config_method_ttls *cfg_method = dynamic_cast<const config_method_ttls*>(cfg_prov.m_methods.front().get());
assert(cfg_method); assert(cfg_method);
@@ -87,41 +87,56 @@ void eap::peer_ttls::get_identity(
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE #ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
// Unpack cached credentials. // Unpack cached credentials.
credentials_ttls cred_in(*this); credentials_ttls cred_in(*this);
if (dwUserDataSize) if (dwUserDataSize) {
cred_in.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_ttls cred_out(*this);
cred_out.m_inner.reset(cfg_method->m_inner->make_credentials());
// Determine inner credential type. // Assume no UI will be necessary.
eap_type_t type_inner; *pfInvokeUI = FALSE;
if (dynamic_cast<const config_method_pap*>(cfg_method->m_inner.get())) {
cred_out.m_inner.reset(new credentials_pap(*this));
type_inner = eap_type_pap;
} else {
assert(0); // Unsupported inner authentication method type.
type_inner = eap_type_undefined;
}
{ {
// Combine credentials. // Combine credentials. We could use eap::credentials_ttls() to do all the work, but we would not know which credentials is missing then.
user_impersonator impersonating(hTokenImpersonateUser); user_impersonator impersonating(hTokenImpersonateUser);
pair<eap::credentials::source_t, eap::credentials::source_t> cred_source(cred_out.combine(
// Combine outer credentials.
LPCTSTR target_name = (dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? cfg_prov.m_id.c_str() : NULL;
eap::credentials::source_t src_outer = cred_out.credentials_tls::combine(
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE #ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
&cred_in, &cred_in,
#else #else
NULL, NULL,
#endif #endif
*cfg_method, *cfg_method,
(dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? cfg_prov.m_id.c_str() : NULL)); target_name);
if (src_outer == eap::credentials::source_unknown) {
log_event(&EAPMETHOD_TRACE_EVT_CRED_INVOKE_UI1, event_data((unsigned int)eap_type_tls), event_data::blank);
*pfInvokeUI = TRUE;
}
// If either of credentials is unknown, request UI. // Combine inner credentials.
*pfInvokeUI = cred_source.first == eap::credentials::source_unknown || cred_source.second == eap::credentials::source_unknown ? TRUE : FALSE; eap::credentials::source_t src_inner = cred_out.m_inner->combine(
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
cred_in.m_inner.get(),
#else
NULL,
#endif
*cfg_method->m_inner,
target_name);
if (src_inner == eap::credentials::source_unknown) {
log_event(&EAPMETHOD_TRACE_EVT_CRED_INVOKE_UI1, event_data((unsigned int)cfg_method->m_inner->get_method_id()), event_data::blank);
*pfInvokeUI = TRUE;
}
} }
// If either of credentials is unknown, request UI.
if (*pfInvokeUI) { if (*pfInvokeUI) {
if ((dwFlags & EAP_FLAG_MACHINE_AUTH) == 0) { if ((dwFlags & EAP_FLAG_MACHINE_AUTH) == 0) {
// Per-user authentication // Per-user authentication
@@ -135,18 +150,20 @@ void eap::peer_ttls::get_identity(
// If we got here, we have all credentials we need. But, wait! // If we got here, we have all credentials we need. But, wait!
if (cfg_method->m_auth_failed) { if ((dwFlags & EAP_FLAG_MACHINE_AUTH) == 0) {
// Outer TLS: Credentials failed on last connection attempt. if (cfg_method->m_auth_failed) {
log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM, event_data((unsigned int)eap_type_tls), event_data::blank); // Outer: Credentials failed on last connection attempt.
*pfInvokeUI = TRUE; log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM, event_data((unsigned int)eap_type_tls), event_data::blank);
return; *pfInvokeUI = TRUE;
} return;
}
if (cfg_method->m_inner->m_auth_failed) { if (cfg_method->m_inner->m_auth_failed) {
// Inner: Credentials failed on last connection attempt. // Inner: Credentials failed on last connection attempt.
log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM, event_data((unsigned int)type_inner), event_data::blank); log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM, event_data((unsigned int)cfg_method->m_inner->get_method_id()), event_data::blank);
*pfInvokeUI = TRUE; *pfInvokeUI = TRUE;
return; return;
}
} }
// Build our identity. ;) // Build our identity. ;)
@@ -251,11 +268,22 @@ EAP_SESSION_HANDLE eap::peer_ttls::begin_session(
// Unpack configuration. // Unpack configuration.
unpack(s->m_cfg, pConnectionData, dwConnectionDataSize); unpack(s->m_cfg, pConnectionData, dwConnectionDataSize);
// Get method configuration.
if (s->m_cfg.m_providers.empty() || s->m_cfg.m_providers.front().m_methods.empty())
throw invalid_argument(__FUNCTION__ " Configuration has no providers and/or methods.");
config_provider &cfg_prov(s->m_cfg.m_providers.front());
config_method_ttls *cfg_method = dynamic_cast<config_method_ttls*>(cfg_prov.m_methods.front().get());
assert(cfg_method);
// Unpack credentials. // Unpack credentials.
s->m_cred.m_inner.reset(cfg_method->m_inner->make_credentials());
unpack(s->m_cred, pUserData, dwUserDataSize); unpack(s->m_cred, pUserData, dwUserDataSize);
// We have configuration, we have credentials, create method.
s->m_method.reset(new method_ttls(*this, *cfg_method, s->m_cred));
// 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();
} }
@@ -279,7 +307,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);
} }
@@ -288,7 +316,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);
} }
@@ -297,7 +325,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
} }
@@ -351,3 +399,30 @@ 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.");
} }
//////////////////////////////////////////////////////////////////////
// eap::peer_ttls::session
//////////////////////////////////////////////////////////////////////
eap::peer_ttls::session::session(_In_ module &mod) :
m_module(mod),
m_cfg(mod),
m_cred(mod),
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

@@ -25,6 +25,10 @@
#include "../include/Method.h" #include "../include/Method.h"
#include "../include/Module.h" #include "../include/Module.h"
#include "../../PAP/include/Config.h"
#include "../../PAP/include/Credentials.h"
#include "../../PAP/include/Method.h"
#include "../../EAPBase/include/EAPXML.h" #include "../../EAPBase/include/EAPXML.h"
#include <WinStd/EAP.h> #include <WinStd/EAP.h>

View File

@@ -40,6 +40,7 @@ class wxTTLSCredentialsPanel;
#include "../../TLS_UI/include/TLS_UI.h" #include "../../TLS_UI/include/TLS_UI.h"
#include "../../TTLS/include/Config.h" #include "../../TTLS/include/Config.h"
#include "../../PAP/include/Config.h"
#include <WinStd/Win.h> #include <WinStd/Win.h>
@@ -75,14 +76,19 @@ class wxTTLSConfigWindow : public wxEAPConfigWindow
{ {
public: public:
/// ///
/// Constructs a configuration panel /// Constructs a configuration window
/// ///
/// \param[in] prov Provider configuration data /// \param[in] prov Provider configuration data
/// \param[inout] cfg Configuration data /// \param[inout] cfg Configuration data
/// \param[in] pszCredTarget Target name of credentials in Windows Credential Manager. Can be further decorated to create final target name. /// \param[in] pszCredTarget Target name of credentials in Windows Credential Manager. Can be further decorated to create final target name.
/// \param[in] parent Parent window /// \param[in] parent Parent window
/// ///
wxTTLSConfigWindow(const eap::config_provider &prov, eap::config_method &cfg, LPCTSTR pszCredTarget, wxWindow* parent); wxTTLSConfigWindow(eap::config_provider &prov, eap::config_method &cfg, LPCTSTR pszCredTarget, wxWindow* parent);
///
/// Destructs the configuration window
///
virtual ~wxTTLSConfigWindow();
protected: protected:
/// \cond internal /// \cond internal
@@ -131,12 +137,12 @@ protected:
/// \endcond /// \endcond
public: public:
wxTLSCredentialsPanel *m_outer_cred; ///< Outer credentials panel wxTLSCredentialsPanel *m_outer_cred; ///< Outer credentials panel
wxPanel *m_inner_cred; ///< Inner credentials panel wxEAPCredentialsPanelBase *m_inner_cred; ///< Inner credentials panel
protected: protected:
const eap::config_provider &m_prov; ///< EAP provider const eap::config_provider &m_prov; ///< EAP provider
const eap::config_method_ttls &m_cfg; ///< TTLS configuration const eap::config_method_ttls &m_cfg; ///< TTLS configuration
wxStaticText *m_outer_title; ///< Outer authentication title wxStaticText *m_outer_title; ///< Outer authentication title
wxStaticText *m_inner_title; ///< Inner authentication title wxStaticText *m_inner_title; ///< Inner authentication title
}; };

View File

@@ -24,6 +24,21 @@ using namespace std;
using namespace winstd; using namespace winstd;
//////////////////////////////////////////////////////////////////////
// wxInitializerPeer
//////////////////////////////////////////////////////////////////////
class wxInitializerPeer
{
public:
wxInitializerPeer(_In_ HINSTANCE instance);
virtual ~wxInitializerPeer();
protected:
wxLocale m_locale; ///< Locale
};
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// eap::peer_ttls_ui // eap::peer_ttls_ui
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
@@ -89,43 +104,47 @@ void eap::peer_ttls_ui::invoke_config_ui(
} else { } else {
// This is a blank network profile. Create default configuraton. // This is a blank network profile. Create default configuraton.
// Start with PAP inner configuration. // 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)); unique_ptr<config_method_ttls> cfg_method(new config_method_ttls(*this));
cfg_method->m_inner.reset(new config_method_pap(*this));
cfg_method->m_anonymous_identity = L"@"; cfg_method->m_anonymous_identity = L"@";
cfg_method->m_use_preshared = true; cfg_method->m_use_preshared = true;
cfg_method->m_preshared.reset(new credentials_tls(*this)); cfg_method->m_preshared.reset(new credentials_tls(*this));
cfg_method->m_inner.reset(cfg_method_inner);
// Start with one method. // One method
config_provider cfg_provider(*this); config_provider cfg_provider(*this);
cfg_provider.m_methods.push_back(std::move(cfg_method)); cfg_provider.m_methods.push_back(std::move(cfg_method));
// Start with one provider. // One provider
cfg.m_providers.push_back(std::move(cfg_provider)); cfg.m_providers.push_back(std::move(cfg_provider));
} }
// Initialize application.
new wxApp();
wxEntryStart(m_instance);
int result; int result;
{ {
// Create wxWidget-approved parent window. // Initialize application.
wxWindow parent; wxInitializerPeer init(m_instance);
parent.SetHWND((WXHWND)(hwndParent ? hwndParent : GetForegroundWindow()));
parent.AdoptAttributesFromHWND();
wxTopLevelWindows.Append(&parent);
// Create and launch configuration dialog. {
wxEAPConfigDialog<wxTTLSConfigWindow> dlg(cfg, &parent); // Create wxWidget-approved parent window.
result = dlg.ShowModal(); wxWindow parent;
parent.SetHWND((WXHWND)(hwndParent ? hwndParent : GetForegroundWindow()));
parent.AdoptAttributesFromHWND();
wxTopLevelWindows.Append(&parent);
wxTopLevelWindows.DeleteObject(&parent); // Create and launch configuration dialog.
parent.SetHWND((WXHWND)NULL); wxEAPConfigDialog<wxTTLSConfigWindow> dlg(cfg, &parent);
result = dlg.ShowModal();
wxTopLevelWindows.DeleteObject(&parent);
parent.SetHWND((WXHWND)NULL);
}
} }
// Clean-up and return.
wxEntryCleanup();
if (result != wxID_OK) if (result != wxID_OK)
throw win_runtime_error(ERROR_CANCELLED, __FUNCTION__ " Cancelled."); throw win_runtime_error(ERROR_CANCELLED, __FUNCTION__ " Cancelled.");
@@ -150,10 +169,10 @@ void eap::peer_ttls_ui::invoke_identity_ui(
// Unpack configuration. // Unpack configuration.
config_connection cfg(*this); config_connection cfg(*this);
unpack(cfg, pConnectionData, dwConnectionDataSize); unpack(cfg, pConnectionData, dwConnectionDataSize);
if (cfg.m_providers.empty() || cfg.m_providers.front().m_methods.empty())
throw invalid_argument(__FUNCTION__ " Configuration has no providers and/or methods.");
// Get method configuration. // 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_provider &cfg_prov(cfg.m_providers.front());
config_method_ttls *cfg_method = dynamic_cast<config_method_ttls*>(cfg_prov.m_methods.front().get()); config_method_ttls *cfg_method = dynamic_cast<config_method_ttls*>(cfg_prov.m_methods.front().get());
assert(cfg_method); assert(cfg_method);
@@ -161,34 +180,35 @@ void eap::peer_ttls_ui::invoke_identity_ui(
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE #ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
// Unpack cached credentials. // Unpack cached credentials.
credentials_ttls cred_in(*this); credentials_ttls cred_in(*this);
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_ttls cred_out(*this);
cred_out.m_inner.reset(cfg_method->m_inner->make_credentials());
// Determine inner credential type. // Combine credentials. Outer and inner separately to get the idea which one is missing.
eap_type_t type_inner; eap::credentials::source_t cred_source = cred_out.credentials_tls::combine(
if (dynamic_cast<const config_method_pap*>(cfg_method->m_inner.get())) {
cred_out.m_inner.reset(new credentials_pap(*this));
type_inner = eap_type_pap;
} else {
assert(0); // Unsupported inner authentication method type.
type_inner = eap_type_undefined;
}
// Combine credentials.
pair<eap::credentials::source_t, eap::credentials::source_t> cred_source(cred_out.combine(
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE #ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
&cred_in, &cred_in,
#else #else
NULL, NULL,
#endif #endif
*cfg_method, *cfg_method,
(dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? cfg_prov.m_id.c_str() : NULL)); (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) { if (dwFlags & EAP_FLAG_GUEST_ACCESS) {
// Disable credential saving for guests. // Disable credential saving for guests.
@@ -196,61 +216,58 @@ void eap::peer_ttls_ui::invoke_identity_ui(
cfg_method->m_inner->m_allow_save = false; cfg_method->m_inner->m_allow_save = false;
} }
// Initialize application.
new wxApp();
wxEntryStart(m_instance);
int result; int result;
{ {
// Create wxWidget-approved parent window. // Initialize application.
wxWindow parent; wxInitializerPeer init(m_instance);
parent.SetHWND((WXHWND)(hwndParent ? hwndParent : GetForegroundWindow()));
parent.AdoptAttributesFromHWND();
wxTopLevelWindows.Append(&parent);
// Create credentials dialog. {
wxEAPCredentialsDialog dlg(cfg_prov, &parent); // Create wxWidget-approved parent window.
wxTTLSCredentialsPanel *panel = new wxTTLSCredentialsPanel(cfg_prov, *cfg_method, cred_out, cfg_prov.m_id.c_str(), &dlg); wxWindow parent;
dlg.AddContent(panel); parent.SetHWND((WXHWND)(hwndParent ? hwndParent : GetForegroundWindow()));
parent.AdoptAttributesFromHWND();
wxTopLevelWindows.Append(&parent);
// Set "Remember" checkboxes according to credential source, // Create credentials dialog.
panel->m_outer_cred->SetRememberValue(cred_source.first == eap::credentials::source_storage); wxEAPCredentialsDialog dlg(cfg_prov, &parent);
wxPAPCredentialsPanel *panel_inner_cred_pap = dynamic_cast<wxPAPCredentialsPanel*>(panel->m_inner_cred); wxTTLSCredentialsPanel *panel = new wxTTLSCredentialsPanel(cfg_prov, *cfg_method, cred_out, cfg_prov.m_id.c_str(), &dlg);
if (panel_inner_cred_pap) dlg.AddContent(panel);
panel_inner_cred_pap->SetRememberValue(cred_source.second == eap::credentials::source_storage);
// Centre and display dialog. // Set "Remember" checkboxes according to credential source,
dlg.Centre(wxBOTH); panel->m_outer_cred->SetRemember(cred_source == eap::credentials::source_storage);
result = dlg.ShowModal(); panel->m_inner_cred->SetRemember(cred_source_inner == eap::credentials::source_storage);
if (result == wxID_OK) {
// Write credentials to credential manager. // Centre and display dialog.
if (panel->m_outer_cred->GetRememberValue()) { dlg.Centre(wxBOTH);
try { result = dlg.ShowModal();
cred_out.credentials_tls::store(cfg_prov.m_id.c_str()); if (result == wxID_OK) {
} catch (winstd::win_runtime_error &err) { // Write credentials to credential manager.
wxLogError(winstd::tstring_printf(_("Error writing credentials to Credential Manager: %hs (error %u)"), err.what(), err.number()).c_str()); if (panel->m_outer_cred->GetRemember()) {
} catch (...) { try {
wxLogError(_("Writing credentials failed.")); cred_out.credentials_tls::store(cfg_prov.m_id.c_str());
} catch (winstd::win_runtime_error &err) {
wxLogError(winstd::tstring_printf(_("Error writing credentials to Credential Manager: %hs (error %u)"), err.what(), err.number()).c_str());
} catch (...) {
wxLogError(_("Writing credentials failed."));
}
}
if (panel->m_inner_cred->GetRemember()) {
try {
cred_out.m_inner->store(cfg_prov.m_id.c_str());
} catch (winstd::win_runtime_error &err) {
wxLogError(winstd::tstring_printf(_("Error writing credentials to Credential Manager: %hs (error %u)"), err.what(), err.number()).c_str());
} catch (...) {
wxLogError(_("Writing credentials failed."));
}
} }
} }
if (panel_inner_cred_pap && panel_inner_cred_pap->GetRememberValue()) { wxTopLevelWindows.DeleteObject(&parent);
try { parent.SetHWND((WXHWND)NULL);
cred_out.m_inner->store(cfg_prov.m_id.c_str());
} catch (winstd::win_runtime_error &err) {
wxLogError(winstd::tstring_printf(_("Error writing credentials to Credential Manager: %hs (error %u)"), err.what(), err.number()).c_str());
} catch (...) {
wxLogError(_("Writing credentials failed."));
}
}
} }
wxTopLevelWindows.DeleteObject(&parent);
parent.SetHWND((WXHWND)NULL);
} }
// Clean-up and return.
wxEntryCleanup();
if (result != wxID_OK) if (result != wxID_OK)
throw win_runtime_error(ERROR_CANCELLED, __FUNCTION__ " Cancelled."); throw win_runtime_error(ERROR_CANCELLED, __FUNCTION__ " Cancelled.");
@@ -281,3 +298,28 @@ void eap::peer_ttls_ui::invoke_interactive_ui(
InitCommonControls(); InitCommonControls();
MessageBox(hwndParent, _T(PRODUCT_NAME_STR) _T(" interactive UI goes here!"), _T(PRODUCT_NAME_STR) _T(" Prompt"), MB_OK); MessageBox(hwndParent, _T(PRODUCT_NAME_STR) _T(" interactive UI goes here!"), _T(PRODUCT_NAME_STR) _T(" Prompt"), MB_OK);
} }
//////////////////////////////////////////////////////////////////////
// wxInitializerPeer
//////////////////////////////////////////////////////////////////////
wxInitializerPeer::wxInitializerPeer(_In_ HINSTANCE instance)
{
// Initialize application.
new wxApp();
wxEntryStart(instance);
// Do our wxWidgets configuration and localization initialization.
wxInitializeConfig();
if (wxInitializeLocale(m_locale)) {
//m_locale.AddCatalog(wxT("wxExtend") wxT(wxExtendVersion));
m_locale.AddCatalog(wxT("EAPTTLSUI"));
}
}
wxInitializerPeer::~wxInitializerPeer()
{
wxEntryCleanup();
}

View File

@@ -71,10 +71,8 @@ bool wxTTLSConfigPanel::TransferDataFromWindow()
} }
void wxTTLSConfigPanel::OnUpdateUI(wxUpdateUIEvent& event) void wxTTLSConfigPanel::OnUpdateUI(wxUpdateUIEvent& /*event*/)
{ {
UNREFERENCED_PARAMETER(event);
if (m_prov.m_read_only) { if (m_prov.m_read_only) {
// This is provider-locked configuration. Disable controls. // This is provider-locked configuration. Disable controls.
m_outer_identity_same ->Enable(false); m_outer_identity_same ->Enable(false);
@@ -95,7 +93,7 @@ void wxTTLSConfigPanel::OnUpdateUI(wxUpdateUIEvent& event)
// wxTTLSConfigWindow // wxTTLSConfigWindow
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
wxTTLSConfigWindow::wxTTLSConfigWindow(const eap::config_provider &prov, eap::config_method &cfg, LPCTSTR pszCredTarget, wxWindow* parent) : wxTTLSConfigWindow::wxTTLSConfigWindow(eap::config_provider &prov, eap::config_method &cfg, LPCTSTR pszCredTarget, wxWindow* parent) :
m_cfg((eap::config_method_ttls&)cfg), m_cfg((eap::config_method_ttls&)cfg),
m_cfg_pap(cfg.m_module), m_cfg_pap(cfg.m_module),
wxEAPConfigWindow(prov, cfg, parent) wxEAPConfigWindow(prov, cfg, parent)
@@ -143,6 +141,14 @@ wxTTLSConfigWindow::wxTTLSConfigWindow(const eap::config_provider &prov, eap::co
// m_inner_type->SetFocusFromKbd(); // This control steals mouse-wheel scrolling for itself // m_inner_type->SetFocusFromKbd(); // This control steals mouse-wheel scrolling for itself
panel_pap->SetFocusFromKbd(); panel_pap->SetFocusFromKbd();
this->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(wxTTLSConfigWindow::OnUpdateUI));
}
wxTTLSConfigWindow::~wxTTLSConfigWindow()
{
this->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(wxTTLSConfigWindow::OnUpdateUI));
} }
@@ -193,10 +199,8 @@ void wxTTLSConfigWindow::OnInitDialog(wxInitDialogEvent& event)
} }
void wxTTLSConfigWindow::OnUpdateUI(wxUpdateUIEvent& event) void wxTTLSConfigWindow::OnUpdateUI(wxUpdateUIEvent& /*event*/)
{ {
wxEAPConfigWindow::OnUpdateUI(event);
m_inner_type->GetChoiceCtrl()->Enable(!m_prov.m_read_only); m_inner_type->GetChoiceCtrl()->Enable(!m_prov.m_read_only);
} }

View File

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

View File

@@ -1 +1,3 @@
*/EAPTTLSUI.mo
*/EventMonitor.mo
*/wxExtend13.mo */wxExtend13.mo