Compare commits

..

14 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
29 changed files with 1039 additions and 505 deletions

View File

@@ -107,6 +107,9 @@
<ProjectReference Include="..\lib\PAP\build\PAP.vcxproj"> <ProjectReference Include="..\lib\PAP\build\PAP.vcxproj">
<Project>{36b0cf8a-7794-46c3-8099-825ba962b4c7}</Project> <Project>{36b0cf8a-7794-46c3-8099-825ba962b4c7}</Project>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\lib\TLS\build\TLS.vcxproj">
<Project>{4d40cb8a-812e-4f12-b23a-31af743878e8}</Project>
</ProjectReference>
<ProjectReference Include="..\lib\WinStd\build\WinStd.vcxproj"> <ProjectReference Include="..\lib\WinStd\build\WinStd.vcxproj">
<Project>{47399d91-7eb9-41de-b521-514ba5db0c43}</Project> <Project>{47399d91-7eb9-41de-b521-514ba5db0c43}</Project>
</ProjectReference> </ProjectReference>

View File

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

View File

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

Binary file not shown.

View File

@@ -2,7 +2,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: EAPMethods\n" "Project-Id-Version: EAPMethods\n"
"POT-Creation-Date: 2016-08-25 10:43+0200\n" "POT-Creation-Date: 2016-08-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 ""

View File

@@ -3,7 +3,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: EAPMethods\n" "Project-Id-Version: EAPMethods\n"
"POT-Creation-Date: 2016-08-25 10:43+0200\n" "POT-Creation-Date: 2016-08-28 23:08+0200\n"
"PO-Revision-Date: 2016-06-02 12:27+0200\n" "PO-Revision-Date: 2016-06-02 12:27+0200\n"
"Last-Translator: Simon Rozman <simon@rozman.si>, 2016\n" "Last-Translator: Simon Rozman <simon@rozman.si>, 2016\n"
"Language-Team: Slovenian (Slovenia) (https://www.transifex.com/eduroam_devel/teams/11799/sl_SI/)\n" "Language-Team: Slovenian (Slovenia) (https://www.transifex.com/eduroam_devel/teams/11799/sl_SI/)\n"
@@ -30,7 +30,7 @@ msgstr "Napredno ..."
msgid "Opens dialog with provider settings" msgid "Opens dialog with provider settings"
msgstr "Odpre dialog z nastavitvami ponudnika" msgstr "Odpre dialog z nastavitvami ponudnika"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:174 lib/EAPBase_UI/res/wxEAP_UI.cpp:296 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:174 lib/EAPBase_UI/res/wxEAP_UI.cpp:299
msgid "Client Credentials" msgid "Client Credentials"
msgstr "Odjemalčeve poverilnice" msgstr "Odjemalčeve poverilnice"
@@ -84,39 +84,39 @@ msgstr ""
msgid "Common (pre-shared) credentials" msgid "Common (pre-shared) credentials"
msgstr "Skupne (deljene) poverilnice" msgstr "Skupne (deljene) poverilnice"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:307 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:310
msgid "Please provide your user ID and password." msgid "Please provide your user ID and password."
msgstr "Vnesite svoj uporabniški ID in geslo." msgstr "Vnesite svoj uporabniški ID in geslo."
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:317 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:320
msgid "User ID:" msgid "User ID:"
msgstr "Uporabniški ID:" msgstr "Uporabniški ID:"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:322 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:325
msgid "Enter your user name here (user@domain.org, DOMAIN\\User, etc.)" msgid "Enter your user name here (user@domain.org, DOMAIN\\User, etc.)"
msgstr "Tukaj vnesite svoje up. ime (up. ime@domena.si, DOMENA\\Uporabnik ipd.)" msgstr "Tukaj vnesite svoje up. ime (up. ime@domena.si, DOMENA\\Uporabnik ipd.)"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:326 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:329
msgid "Password:" msgid "Password:"
msgstr "Geslo:" msgstr "Geslo:"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:331 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:334
msgid "Enter your password here" msgid "Enter your password here"
msgstr "Tukaj vnesite svoje geslo" msgstr "Tukaj vnesite svoje geslo"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:338 lib/TLS_UI/res/wxTLS_UI.cpp:183 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:341 lib/TLS_UI/res/wxTLS_UI.cpp:183
msgid "&Remember" msgid "&Remember"
msgstr "Za&pomni si" msgstr "Za&pomni si"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:339 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:342
msgid "Check if you would like to save username and password" msgid "Check if you would like to save username and password"
msgstr "Odkljukajte, če želite shraniti up. ime in geslo" msgstr "Odkljukajte, če želite shraniti up. ime in geslo"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:361 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:364
msgid "Your Organization" msgid "Your Organization"
msgstr "Vaša organizacija" msgstr "Vaša organizacija"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:372 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:375
msgid "" msgid ""
"Describe your organization to customize user prompts. When organization is " "Describe your organization to customize user prompts. When organization is "
"introduced, end-users find program messages easier to understand and act." "introduced, end-users find program messages easier to understand and act."
@@ -125,54 +125,54 @@ msgstr ""
"predstavi, uporabniki lažje razumejo sporočila programa in ustrezneje " "predstavi, uporabniki lažje razumejo sporočila programa in ustrezneje "
"reagirajo." "reagirajo."
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:379 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:382
msgid "Your organization &name:" msgid "Your organization &name:"
msgstr "Ime vaše orga&nizacije:" msgstr "Ime vaše orga&nizacije:"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:384 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:387
msgid "" msgid ""
"Your organization name as it will appear on helpdesk contact notifications" "Your organization name as it will appear on helpdesk contact notifications"
msgstr "" msgstr ""
"Ime vaše organizacije, kot bo nastopalo na obvestilih s stikom na center za " "Ime vaše organizacije, kot bo nastopalo na obvestilih s stikom na center za "
"pomoč" "pomoč"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:388 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:391
msgid "(Keep it short, please)" msgid "(Keep it short, please)"
msgstr "(Naj bo kratko, prosim)" msgstr "(Naj bo kratko, prosim)"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:398 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:401
msgid "Helpdesk contact &information:" msgid "Helpdesk contact &information:"
msgstr "Podatk&i centra za pomoč:" msgstr "Podatk&i centra za pomoč:"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:408 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:411
msgid "¶" msgid "¶"
msgstr "¶" msgstr "¶"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:415 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:418
msgid "Your helpdesk website address" msgid "Your helpdesk website address"
msgstr "Naslov spletne strani vašega centra za pomoč" msgstr "Naslov spletne strani vašega centra za pomoč"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:419 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:422
msgid "*" msgid "*"
msgstr "*" msgstr "*"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:426 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:429
msgid "Your helpdesk e-mail address" msgid "Your helpdesk e-mail address"
msgstr "E-poštni naslov vašega centra za pomoč" msgstr "E-poštni naslov vašega centra za pomoč"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:430 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:433
msgid ")" msgid ")"
msgstr ")" msgstr ")"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:437 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:440
msgid "Your helpdesk phone number" msgid "Your helpdesk phone number"
msgstr "Telefonska številka vašega centra za pomoč" msgstr "Telefonska številka vašega centra za pomoč"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:471 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:468
msgid "Configuration Lock" msgid "Configuration Lock"
msgstr "Zaklep konfiguracije" msgstr "Zaklep konfiguracije"
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:482 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:479
msgid "" msgid ""
"Your configuration can be locked to prevent accidental modification by end-" "Your configuration can be locked to prevent accidental modification by end-"
"users. Users will only be allowed to enter credentials." "users. Users will only be allowed to enter credentials."
@@ -180,7 +180,7 @@ msgstr ""
"Svojo konfiguracijo lahko zaklenete in preprečite končnim uporabnikom " "Svojo konfiguracijo lahko zaklenete in preprečite končnim uporabnikom "
"nenamerno spreminjanje. Uporabniki bodo lahko vnašali samo poverilnice." "nenamerno spreminjanje. Uporabniki bodo lahko vnašali samo poverilnice."
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:489 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:486
msgid "" msgid ""
"&Lock this configuration and prevent any further modification via user " "&Lock this configuration and prevent any further modification via user "
"interface." "interface."
@@ -188,42 +188,42 @@ msgstr ""
"Zak&leni to konfiguracijo in prepreči vse nadaljnje spremembe preko up. " "Zak&leni to konfiguracijo in prepreči vse nadaljnje spremembe preko up. "
"vmesnika." "vmesnika."
#: lib/EAPBase_UI/res/wxEAP_UI.cpp:492 #: lib/EAPBase_UI/res/wxEAP_UI.cpp:489
msgid "(Warning: Once locked, you can not revert using this dialog!)" msgid "(Warning: Once locked, you can not revert using this dialog!)"
msgstr "(Pozor: Ko zaklenete, vrnitev ne bo več možna preko tega dialoga!)" msgstr "(Pozor: Ko zaklenete, vrnitev ne bo več možna preko tega dialoga!)"
#: lib/EAPBase_UI/src/EAP_UI.cpp:88 #: lib/EAPBase_UI/src/EAP_UI.cpp:98
#, c-format #, c-format
msgid "%s Credentials" msgid "%s Credentials"
msgstr "Poverilnice za %s" msgstr "Poverilnice za %s"
#: lib/EAPBase_UI/src/EAP_UI.cpp:118 #: lib/EAPBase_UI/src/EAP_UI.cpp:128
#, c-format #, c-format
msgid "For additional help and instructions, please contact %s at:" msgid "For additional help and instructions, please contact %s at:"
msgstr "Za dodtano pomoč ali navodila se obrnite na %s na:" msgstr "Za dodtano pomoč ali navodila se obrnite na %s na:"
#: lib/EAPBase_UI/src/EAP_UI.cpp:120 #: lib/EAPBase_UI/src/EAP_UI.cpp:130
#, c-format #, c-format
msgid "your %ls provider" msgid "your %ls provider"
msgstr "vaš ponudnik %ls" msgstr "vaš ponudnik %ls"
#: lib/EAPBase_UI/src/EAP_UI.cpp:120 #: lib/EAPBase_UI/src/EAP_UI.cpp:130
msgid "your provider" msgid "your provider"
msgstr "vaš ponudnik" msgstr "vaš ponudnik"
#: lib/EAPBase_UI/src/EAP_UI.cpp:139 #: lib/EAPBase_UI/src/EAP_UI.cpp:149
msgid "Open the default web browser" msgid "Open the default web browser"
msgstr "Odpre privzeto nastavljen spletni brskalnik" msgstr "Odpre privzeto nastavljen spletni brskalnik"
#: lib/EAPBase_UI/src/EAP_UI.cpp:150 #: lib/EAPBase_UI/src/EAP_UI.cpp:160
msgid "Open your e-mail program" msgid "Open your e-mail program"
msgstr "Odpre vaš program za e-pošto" msgstr "Odpre vaš program za e-pošto"
#: lib/EAPBase_UI/src/EAP_UI.cpp:161 #: lib/EAPBase_UI/src/EAP_UI.cpp:171
msgid "Dial the phone number" msgid "Dial the phone number"
msgstr "Pokliče telefonsko številko" msgstr "Pokliče telefonsko številko"
#: lib/EAPBase_UI/src/EAP_UI.cpp:180 #: lib/EAPBase_UI/src/EAP_UI.cpp:191
#, c-format #, c-format
msgid "" msgid ""
"%s has pre-set parts of this configuration. Those parts are locked to " "%s has pre-set parts of this configuration. Those parts are locked to "
@@ -232,16 +232,16 @@ msgstr ""
"%s je prednastavil dele te konfiguracije. Ti deli so zaklenjeni zaradi " "%s je prednastavil dele te konfiguracije. Ti deli so zaklenjeni zaradi "
"preprečevanja nenamernih sprememb." "preprečevanja nenamernih sprememb."
#: lib/EAPBase_UI/src/EAP_UI.cpp:182 #: lib/EAPBase_UI/src/EAP_UI.cpp:193
#, c-format #, c-format
msgid "Your %ls provider" msgid "Your %ls provider"
msgstr "Vaš ponudnik %ls" msgstr "Vaš ponudnik %ls"
#: lib/EAPBase_UI/src/EAP_UI.cpp:182 #: lib/EAPBase_UI/src/EAP_UI.cpp:193
msgid "Your provider" msgid "Your provider"
msgstr "Vaš ponudnik" msgstr "Vaš ponudnik"
#: lib/EAPBase_UI/src/EAP_UI.cpp:201 #: lib/EAPBase_UI/src/EAP_UI.cpp:213
msgid "" msgid ""
"Previous attempt to connect failed. Please, make sure your credentials are " "Previous attempt to connect failed. Please, make sure your credentials are "
"correct, or try again later." "correct, or try again later."
@@ -371,32 +371,32 @@ msgstr "Napačen znak v imenu gostitelja: %c"
msgid "Validation conflict" msgid "Validation conflict"
msgstr "Nesoglasje pri preverjanju" msgstr "Nesoglasje pri preverjanju"
#: lib/TLS_UI/src/TLS_UI.cpp:514 #: lib/TLS_UI/src/TLS_UI.cpp:511
msgid "Add Certificate" msgid "Add Certificate"
msgstr "Dodaj potrdilo" msgstr "Dodaj potrdilo"
#: lib/TLS_UI/src/TLS_UI.cpp:515 #: lib/TLS_UI/src/TLS_UI.cpp:512
msgid "Certificate Files (*.cer;*.crt;*.der;*.p7b;*.pem)" msgid "Certificate Files (*.cer;*.crt;*.der;*.p7b;*.pem)"
msgstr "Datoteke s potrdili (*.cer;*.crt;*.der;*.p7b;*.pem)" msgstr "Datoteke s potrdili (*.cer;*.crt;*.der;*.p7b;*.pem)"
#: lib/TLS_UI/src/TLS_UI.cpp:516 #: lib/TLS_UI/src/TLS_UI.cpp:513
msgid "X.509 Certificate Files (*.cer;*.crt;*.der;*.pem)" msgid "X.509 Certificate Files (*.cer;*.crt;*.der;*.pem)"
msgstr "Datoteke s potrdili X.509 (*.cer;*.crt;*.der;*.pem)" msgstr "Datoteke s potrdili X.509 (*.cer;*.crt;*.der;*.pem)"
#: lib/TLS_UI/src/TLS_UI.cpp:517 #: lib/TLS_UI/src/TLS_UI.cpp:514
msgid "PKCS #7 Certificate Files (*.p7b)" msgid "PKCS #7 Certificate Files (*.p7b)"
msgstr "Datoteke s potrdili PKCS #7 (*.p7b)" msgstr "Datoteke s potrdili PKCS #7 (*.p7b)"
#: lib/TLS_UI/src/TLS_UI.cpp:518 #: lib/TLS_UI/src/TLS_UI.cpp:515
msgid "All Files (*.*)" msgid "All Files (*.*)"
msgstr "Vse datoteke (*.*)" msgstr "Vse datoteke (*.*)"
#: lib/TLS_UI/src/TLS_UI.cpp:534 #: lib/TLS_UI/src/TLS_UI.cpp:531
#, c-format #, c-format
msgid "Invalid or unsupported certificate file %s" msgid "Invalid or unsupported certificate file %s"
msgstr "Napačna ali nepodprta datoteka s potrdilom %s" msgstr "Napačna ali nepodprta datoteka s potrdilom %s"
#: lib/TLS_UI/src/TLS_UI.cpp:534 #: lib/TLS_UI/src/TLS_UI.cpp:531
msgid "Error" msgid "Error"
msgstr "Napaka" msgstr "Napaka"
@@ -438,71 +438,69 @@ msgstr "Navedite zunanjo identiteto po meri"
msgid "Custom outer identity to use" msgid "Custom outer identity to use"
msgstr "Zunanja identiteta po meri za uporabo" msgstr "Zunanja identiteta po meri za uporabo"
#: lib/TTLS_UI/src/Module.cpp:231 lib/TTLS_UI/src/Module.cpp:241 #: lib/TTLS_UI/src/Module.cpp:249 lib/TTLS_UI/src/Module.cpp:259
#: lib/EAPBase_UI/include/EAP_UI.h:582 #: lib/EAPBase_UI/include/EAP_UI.h:584
#, c-format #, c-format
msgid "Error writing credentials to Credential Manager: %hs (error %u)" msgid "Error writing credentials to Credential Manager: %hs (error %u)"
msgstr "" msgstr ""
"Napaka pri zapisovanju poverilnic v upravitelja poverilnic: %hs (napaka %u)" "Napaka pri zapisovanju poverilnic v upravitelja poverilnic: %hs (napaka %u)"
#: lib/TTLS_UI/src/Module.cpp:233 lib/TTLS_UI/src/Module.cpp:243 #: lib/TTLS_UI/src/Module.cpp:251 lib/TTLS_UI/src/Module.cpp:261
#: lib/EAPBase_UI/include/EAP_UI.h:584 #: lib/EAPBase_UI/include/EAP_UI.h:587
msgid "Writing credentials failed." msgid "Writing credentials failed."
msgstr "Zapisovanje poverilnic ni uspelo." msgstr "Zapisovanje poverilnic ni uspelo."
#: lib/TTLS_UI/src/TTLS_UI.cpp:108 lib/TTLS_UI/src/TTLS_UI.cpp:215 #: lib/TTLS_UI/src/TTLS_UI.cpp:107 lib/TTLS_UI/src/TTLS_UI.cpp:220
msgid "Inner Authentication" msgid "Inner Authentication"
msgstr "Notranje overovljanje" msgstr "Notranje overovljanje"
#: lib/TTLS_UI/src/TTLS_UI.cpp:114 #: lib/TTLS_UI/src/TTLS_UI.cpp:113
msgid "Select inner authentication method from the list" msgid "Select inner authentication method from the list"
msgstr "Izberite postopek notranjega overovljanja s seznama" msgstr "Izberite postopek notranjega overovljanja s seznama"
#: lib/TTLS_UI/src/TTLS_UI.cpp:116 #: lib/TTLS_UI/src/TTLS_UI.cpp:115
msgid "PAP" msgid "PAP"
msgstr "PAP" msgstr "PAP"
#: lib/TTLS_UI/src/TTLS_UI.cpp:121 lib/TTLS_UI/src/TTLS_UI.cpp:236 #: lib/TTLS_UI/src/TTLS_UI.cpp:120 lib/TTLS_UI/src/TTLS_UI.cpp:241
msgid "Outer Authentication" msgid "Outer Authentication"
msgstr "Zunanje overovljanje" msgstr "Zunanje overovljanje"
#: lib/EAPBase_UI/include/EAP_UI.h:253 #: lib/EAPBase_UI/include/EAP_UI.h:283
msgid "EAP Credentials" msgid "EAP Credentials"
msgstr "Poverilnice EAP" msgstr "Poverilnice EAP"
#: lib/EAPBase_UI/include/EAP_UI.h:422 #: lib/EAPBase_UI/include/EAP_UI.h:443
msgid "Provider Settings" msgid "Provider Settings"
msgstr "Nastavitve ponudnika" msgstr "Nastavitve ponudnika"
#: lib/EAPBase_UI/include/EAP_UI.h:502 lib/EAPBase_UI/include/EAP_UI.h:529 #: lib/EAPBase_UI/include/EAP_UI.h:600
msgid "<blank>"
msgstr "<prazno>"
#: lib/EAPBase_UI/include/EAP_UI.h:508
#, c-format
msgid "<error %u>"
msgstr "<napaka %u>"
#: lib/EAPBase_UI/include/EAP_UI.h:568
#, c-format
msgid "Error reading credentials from Credential Manager: %hs (error %u)"
msgstr ""
"Napaka pri branju poverilnic iz upravitelja poverilnic: %hs (napaka %u)"
#: lib/EAPBase_UI/include/EAP_UI.h:570
msgid "Reading credentials failed."
msgstr "Branje poverilnic ni uspelo."
#: lib/EAPBase_UI/include/EAP_UI.h:595
#, c-format #, c-format
msgid "Deleting credentials failed (error %u)." msgid "Deleting credentials failed (error %u)."
msgstr "Izbris poverilnic ni uspel (napaka %u)." msgstr "Izbris poverilnic ni uspel (napaka %u)."
#: lib/EAPBase_UI/include/EAP_UI.h:817 #: lib/EAPBase_UI/include/EAP_UI.h:633
#, c-format
msgid "<error %u>"
msgstr "<napaka %u>"
#: lib/EAPBase_UI/include/EAP_UI.h:637
msgid "<error>"
msgstr "<napaka>"
#: lib/EAPBase_UI/include/EAP_UI.h:646 lib/EAPBase_UI/include/EAP_UI.h:657
msgid "<empty credentials>"
msgstr "<prazne poverilnice>"
#: lib/EAPBase_UI/include/EAP_UI.h:649 lib/EAPBase_UI/include/EAP_UI.h:660
msgid "<blank identity>"
msgstr "<prazna identiteta>"
#: lib/EAPBase_UI/include/EAP_UI.h:866
msgid "<Your Organization>" msgid "<Your Organization>"
msgstr "<vaša organizacija>" msgstr "<vaša organizacija>"
#: lib/EAPBase_UI/res/wxEAP_UI.h:60 #: lib/EAPBase_UI/res/wxEAP_UI.h:64
msgid "EAP Method Configuration" msgid "EAP Method Configuration"
msgstr "Konfiguracija postopka EAP" msgstr "Konfiguracija postopka EAP"

BIN
Makefile

Binary file not shown.

Binary file not shown.

View File

@@ -29,7 +29,7 @@
// Product version as a single DWORD // Product version as a single DWORD
// Note: Used for version comparison within C/C++ code. // Note: Used for version comparison within C/C++ code.
// //
#define PRODUCT_VERSION 0x00ff0e00 #define PRODUCT_VERSION 0x00ff0f00
// //
// Product version by components // Product version by components
@@ -39,20 +39,20 @@
// //
#define PRODUCT_VERSION_MAJ 0 #define PRODUCT_VERSION_MAJ 0
#define PRODUCT_VERSION_MIN 255 #define PRODUCT_VERSION_MIN 255
#define PRODUCT_VERSION_REV 14 #define PRODUCT_VERSION_REV 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-alpha14" #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.14" #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

View File

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

View File

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

@@ -643,7 +643,7 @@ protected:
inline void UpdateOwnIdentity() inline void UpdateOwnIdentity()
{ {
if (m_cred_own.empty()) if (m_cred_own.empty())
m_own_identity->SetValue(_T("<empty credentials>")); m_own_identity->SetValue(_("<empty credentials>"));
else { else {
wxString identity(m_cred_own.get_name()); wxString identity(m_cred_own.get_name());
m_own_identity->SetValue(!identity.empty() ? identity : _("<blank identity>")); m_own_identity->SetValue(!identity.empty() ? identity : _("<blank identity>"));
@@ -654,7 +654,7 @@ protected:
inline void UpdatePresharedIdentity() inline void UpdatePresharedIdentity()
{ {
if (m_cred_preshared.empty()) if (m_cred_preshared.empty())
m_preshared_identity->SetValue(_T("<empty credentials>")); m_preshared_identity->SetValue(_("<empty credentials>"));
else { else {
wxString identity(m_cred_preshared.get_name()); wxString identity(m_cred_preshared.get_name());
m_preshared_identity->SetValue(!identity.empty() ? identity : _("<blank identity>")); m_preshared_identity->SetValue(!identity.empty() ? identity : _("<blank identity>"));

View File

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

Binary file not shown.

View File

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

View File

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

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

@@ -0,0 +1,167 @@
/*
Copyright 2015-2016 Amebis
Copyright 2016 G<>ANT
This file is part of G<>ANTLink.
G<>ANTLink is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
G<>ANTLink is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with G<>ANTLink. If not, see <http://www.gnu.org/licenses/>.
*/
namespace eap
{
///
/// PAP method
///
class method_pap;
}
#pragma once
#include "Config.h"
#include "Credentials.h"
#include "../../EAPBase/include/Method.h"
namespace eap
{
class method_pap : public method
{
public:
///
/// EAP-PAP packet (data)
///
class packet
{
public:
///
/// Constructs an empty packet
///
packet();
///
/// Copies a packet
///
/// \param[in] other Packet to copy from
///
packet(_In_ const packet &other);
///
/// Moves a packet
///
/// \param[in] other Packet to move from
///
packet(_Inout_ packet &&other);
///
/// Copies a packet
///
/// \param[in] other Packet to copy from
///
/// \returns Reference to this object
///
packet& operator=(_In_ const packet &other);
///
/// Moves a packet
///
/// \param[in] other Packet to move from
///
/// \returns Reference to this object
///
packet& operator=(_Inout_ packet &&other);
///
/// Empty the packet
///
void clear();
public:
EapCode m_code; ///< Packet code
unsigned char m_id; ///< Packet ID
sanitizing_blob m_data; ///< Packet data
};
public:
///
/// Constructs an EAP method
///
/// \param[in] mod EAP module to use for global services
/// \param[in] cfg Method configuration
/// \param[in] cred User credentials
///
method_pap(_In_ module &module, _In_ config_method_pap &cfg, _In_ credentials_pap &cred);
///
/// Moves an EAP method
///
/// \param[in] other EAP method to move from
///
method_pap(_Inout_ method_pap &&other);
///
/// Moves an EAP method
///
/// \param[in] other EAP method to move from
///
/// \returns Reference to this object
///
method_pap& operator=(_Inout_ method_pap &&other);
/// \name Packet processing
/// @{
///
/// Processes a packet received by EapHost from a supplicant.
///
/// \sa [EapPeerProcessRequestPacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363621.aspx)
///
virtual void process_request_packet(
_In_bytecount_(dwReceivedPacketSize) const EapPacket *pReceivedPacket,
_In_ DWORD dwReceivedPacketSize,
_Inout_ EapPeerMethodOutput *pEapOutput);
///
/// Obtains a response packet from the EAP method.
///
/// \sa [EapPeerGetResponsePacket function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363610.aspx)
///
virtual void get_response_packet(
_Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket,
_Inout_ DWORD *pdwSendPacketSize);
///
/// Obtains the result of an authentication session from the EAP method.
///
/// \sa [EapPeerGetResult function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363611.aspx)
///
virtual void get_result(
_In_ EapPeerMethodResultReason reason,
_Inout_ EapPeerMethodResult *ppResult);
/// @}
protected:
credentials_pap &m_cred; ///< EAP-TLS user credentials
packet m_packet_res; ///< Response packet
enum {
phase_unknown = -1, ///< Unknown phase
phase_init = 0, ///< Handshake initialize
phase_finished, ///< Connection shut down
} m_phase, m_phase_prev; ///< What phase is our communication at?
};
}

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

@@ -0,0 +1,283 @@
/*
Copyright 2015-2016 Amebis
Copyright 2016 G<>ANT
This file is part of G<>ANTLink.
G<>ANTLink is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
G<>ANTLink is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with G<>ANTLink. If not, see <http://www.gnu.org/licenses/>.
*/
#include "StdAfx.h"
using namespace std;
using namespace winstd;
//////////////////////////////////////////////////////////////////////
// eap::method_pap::packet
//////////////////////////////////////////////////////////////////////
eap::method_pap::packet::packet() :
m_code((EapCode)0),
m_id(0)
{
}
eap::method_pap::packet::packet(_In_ const packet &other) :
m_code(other.m_code),
m_id (other.m_id ),
m_data(other.m_data)
{
}
eap::method_pap::packet::packet(_Inout_ packet &&other) :
m_code(std::move(other.m_code)),
m_id (std::move(other.m_id )),
m_data(std::move(other.m_data))
{
}
eap::method_pap::packet& eap::method_pap::packet::operator=(_In_ const packet &other)
{
if (this != std::addressof(other)) {
m_code = other.m_code;
m_id = other.m_id ;
m_data = other.m_data;
}
return *this;
}
eap::method_pap::packet& eap::method_pap::packet::operator=(_Inout_ packet &&other)
{
if (this != std::addressof(other)) {
m_code = std::move(other.m_code);
m_id = std::move(other.m_id );
m_data = std::move(other.m_data);
}
return *this;
}
void eap::method_pap::packet::clear()
{
m_code = (EapCode)0;
m_id = 0;
m_data.clear();
}
//////////////////////////////////////////////////////////////////////
// eap::method_pap
//////////////////////////////////////////////////////////////////////
eap::method_pap::method_pap(_In_ module &module, _In_ config_method_pap &cfg, _In_ credentials_pap &cred) :
m_cred(cred),
m_phase(phase_unknown),
m_phase_prev(phase_unknown),
method(module, cfg, cred)
{
}
eap::method_pap::method_pap(_Inout_ method_pap &&other) :
m_cred ( other.m_cred ),
m_packet_res(std::move(other.m_packet_res)),
m_phase (std::move(other.m_phase )),
m_phase_prev(std::move(other.m_phase_prev)),
method (std::move(other ))
{
}
eap::method_pap& eap::method_pap::operator=(_Inout_ method_pap &&other)
{
if (this != std::addressof(other)) {
assert(std::addressof(m_cred) == std::addressof(other.m_cred)); // Move method with same credentials only!
(method&)*this = std::move(other );
m_packet_res = std::move(other.m_packet_res);
m_phase = std::move(other.m_phase );
m_phase_prev = std::move(other.m_phase_prev);
}
return *this;
}
void eap::method_pap::process_request_packet(
_In_bytecount_(dwReceivedPacketSize) const EapPacket *pReceivedPacket,
_In_ DWORD dwReceivedPacketSize,
_Inout_ EapPeerMethodOutput *pEapOutput)
{
assert(pReceivedPacket && dwReceivedPacketSize >= 4);
assert(pEapOutput);
m_module.log_event(&EAPMETHOD_PACKET_RECV, event_data((unsigned int)eap_type_pap), event_data((unsigned int)dwReceivedPacketSize - 4), event_data::blank);
if (pReceivedPacket->Id == 0) {
m_module.log_event(&EAPMETHOD_METHOD_HANDSHAKE_START2, event_data((unsigned int)eap_type_pap), event_data::blank);
m_phase = phase_init;
}
m_phase_prev = m_phase;
switch (m_phase) {
case phase_init: {
// Convert username and password to UTF-8.
sanitizing_string identity_utf8, password_utf8;
WideCharToMultiByte(CP_UTF8, 0, m_cred.m_identity.c_str(), (int)m_cred.m_identity.length(), identity_utf8, NULL, NULL);
WideCharToMultiByte(CP_UTF8, 0, m_cred.m_password.c_str(), (int)m_cred.m_password.length(), password_utf8, NULL, NULL);
// PAP passwords must be padded to 16B boundary according to RFC 5281. Will not add random extra padding here, as length obfuscation should be done by outer transport layers.
size_t padding_password_ex = (16 - password_utf8.length()) % 16;
password_utf8.append(padding_password_ex, 0);
size_t
size_identity = identity_utf8.length(),
size_password = password_utf8.length(),
padding_identity = (4 - size_identity ) % 4,
padding_password = (4 - password_utf8.length()) % 4,
size_identity_outer,
size_password_outer;
m_packet_res.m_code = EapCodeResponse;
m_packet_res.m_id = pReceivedPacket->Id;
m_packet_res.m_data.clear();
m_packet_res.m_data.reserve(
(size_identity_outer =
4 + // Diameter AVP Code
4 + // Diameter AVP Flags & Length
size_identity) + // Identity
padding_identity + // Identity padding
(size_password_outer =
4 + // Diameter AVP Code
4 + // Diameter AVP Flags & Length
size_password) + // Password
padding_password); // Password padding
// Diameter AVP Code User-Name (0x00000001)
m_packet_res.m_data.push_back(0x00);
m_packet_res.m_data.push_back(0x00);
m_packet_res.m_data.push_back(0x00);
m_packet_res.m_data.push_back(0x01);
// Diameter AVP Flags & Length
unsigned int identity_hdr = htonl((diameter_avp_flag_mandatory << 24) | (unsigned int)size_identity_outer);
m_packet_res.m_data.insert(m_packet_res.m_data.end(), (unsigned char*)&identity_hdr, (unsigned char*)(&identity_hdr + 1));
// Identity
m_packet_res.m_data.insert(m_packet_res.m_data.end(), identity_utf8.begin(), identity_utf8.end());
m_packet_res.m_data.insert(m_packet_res.m_data.end(), padding_identity, 0);
// Diameter AVP Code User-Password (0x00000002)
m_packet_res.m_data.push_back(0x00);
m_packet_res.m_data.push_back(0x00);
m_packet_res.m_data.push_back(0x00);
m_packet_res.m_data.push_back(0x02);
// Diameter AVP Flags & Length
unsigned int password_hdr = htonl((diameter_avp_flag_mandatory << 24) | (unsigned int)size_password_outer);
m_packet_res.m_data.insert(m_packet_res.m_data.end(), (unsigned char*)&password_hdr, (unsigned char*)(&password_hdr + 1));
// Password
m_packet_res.m_data.insert(m_packet_res.m_data.end(), password_utf8.begin(), password_utf8.end());
m_packet_res.m_data.insert(m_packet_res.m_data.end(), padding_password, 0);
m_phase = phase_finished;
break;
}
case phase_finished:
break;
}
pEapOutput->fAllowNotifications = TRUE;
pEapOutput->action = EapPeerMethodResponseActionSend;
}
void eap::method_pap::get_response_packet(
_Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket,
_Inout_ DWORD *pdwSendPacketSize)
{
assert(pdwSendPacketSize);
assert(pSendPacket);
unsigned int
size_data = (unsigned int)m_packet_res.m_data.size(),
size_packet = size_data + 4;
unsigned short size_packet_limit = (unsigned short)std::min<unsigned int>(*pdwSendPacketSize, USHRT_MAX);
// Not fragmented.
if (size_packet <= size_packet_limit) {
// No need to fragment the packet.
m_module.log_event(&EAPMETHOD_PACKET_SEND, event_data((unsigned int)eap_type_pap), event_data((unsigned int)size_data), event_data::blank);
} else {
// But it should be fragmented.
throw com_runtime_error(TYPE_E_SIZETOOBIG, __FUNCTION__ " PAP message exceeds 64kB.");
}
pSendPacket->Code = (BYTE)m_packet_res.m_code;
pSendPacket->Id = m_packet_res.m_id;
*(unsigned short*)pSendPacket->Length = htons((unsigned short)size_packet);
memcpy(pSendPacket->Data, m_packet_res.m_data.data(), size_data);
m_packet_res.m_data.erase(m_packet_res.m_data.begin(), m_packet_res.m_data.begin() + size_data);
*pdwSendPacketSize = size_packet;
}
void eap::method_pap::get_result(
_In_ EapPeerMethodResultReason reason,
_Inout_ EapPeerMethodResult *ppResult)
{
assert(ppResult);
switch (reason) {
case EapPeerMethodResultSuccess: {
m_module.log_event(&EAPMETHOD_METHOD_SUCCESS, event_data((unsigned int)eap_type_pap), event_data::blank);
m_cfg.m_auth_failed = false;
ppResult->fIsSuccess = TRUE;
ppResult->dwFailureReasonCode = ERROR_SUCCESS;
break;
}
case EapPeerMethodResultFailure:
m_module.log_event(
m_phase_prev < phase_finished ? &EAPMETHOD_METHOD_FAILURE_INIT : &EAPMETHOD_METHOD_FAILURE,
event_data((unsigned int)eap_type_pap), event_data::blank);
// Mark credentials as failed, so GUI can re-prompt user.
// But be careful: do so only after credentials were actually tried.
m_cfg.m_auth_failed = m_phase == phase_finished;
// Do not report failure to EapHost, as it will not save updated configuration then. But we need it to save it, to alert user on next connection attempt.
// EapHost is well aware of the failed condition.
//ppResult->fIsSuccess = FALSE;
//ppResult->dwFailureReasonCode = EAP_E_AUTHENTICATION_FAILED;
break;
default:
throw win_runtime_error(ERROR_NOT_SUPPORTED, __FUNCTION__ " Not supported.");
}
// Always ask EAP host to save the connection data.
ppResult->fSaveConnectionData = TRUE;
}

View File

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

View File

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

View File

@@ -253,10 +253,44 @@ std::wstring eap::credentials_tls::get_identity() const
if (!m_identity.empty()) { if (!m_identity.empty()) {
return m_identity; return m_identity;
} else if (m_cert) { } else if (m_cert) {
wstring identity; for (DWORD idx_ext = 0; idx_ext < m_cert->pCertInfo->cExtension; idx_ext++) {
CertGetNameString(m_cert, CERT_NAME_EMAIL_TYPE, 0, NULL, identity); unique_ptr<CERT_ALT_NAME_INFO, LocalFree_delete<CERT_ALT_NAME_INFO> > san_info;
return identity; if (strcmp(m_cert->pCertInfo->rgExtension[idx_ext].pszObjId, szOID_SUBJECT_ALT_NAME2) == 0) {
} else unsigned char *output = NULL;
DWORD size_output;
if (!CryptDecodeObjectEx(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
szOID_SUBJECT_ALT_NAME2,
m_cert->pCertInfo->rgExtension[idx_ext].Value.pbData, m_cert->pCertInfo->rgExtension[idx_ext].Value.cbData,
CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_ENABLE_PUNYCODE_FLAG,
NULL,
&output, &size_output))
throw win_runtime_error(__FUNCTION__ " Error decoding subjectAltName2 certificate extension.");
san_info.reset((CERT_ALT_NAME_INFO*)output);
} else if (strcmp(m_cert->pCertInfo->rgExtension[idx_ext].pszObjId, szOID_SUBJECT_ALT_NAME) == 0) {
unsigned char *output = NULL;
DWORD size_output;
if (!CryptDecodeObjectEx(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
szOID_SUBJECT_ALT_NAME,
m_cert->pCertInfo->rgExtension[idx_ext].Value.pbData, m_cert->pCertInfo->rgExtension[idx_ext].Value.cbData,
CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_ENABLE_PUNYCODE_FLAG,
NULL,
&output, &size_output))
throw win_runtime_error(__FUNCTION__ " Error decoding subjectAltName certificate extension.");
san_info.reset((CERT_ALT_NAME_INFO*)output);
} else {
// Skip this extension.
continue;
}
for (DWORD idx_entry = 0; idx_entry < san_info->cAltEntry; idx_entry++) {
if (san_info->rgAltEntry[idx_entry].dwAltNameChoice == CERT_ALT_NAME_RFC822_NAME)
return san_info->rgAltEntry[idx_entry].pwszRfc822Name;
}
}
}
return L""; return L"";
} }

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());
@@ -332,7 +311,7 @@ void eap::method_tls::begin_session(
SCH_CRED_IGNORE_NO_REVOCATION_CHECK | // dwFlags: Ignore no-revocation-check errors (TODO: Test if this flag is required.) SCH_CRED_IGNORE_NO_REVOCATION_CHECK | // dwFlags: Ignore no-revocation-check errors (TODO: Test if this flag is required.)
SCH_CRED_IGNORE_REVOCATION_OFFLINE | // dwFlags: Ignore offline-revocation errors - we do not expect to have network connection yet SCH_CRED_IGNORE_REVOCATION_OFFLINE | // dwFlags: Ignore offline-revocation errors - we do not expect to have network connection yet
SCH_CRED_NO_DEFAULT_CREDS | // dwFlags: If client certificate we provided is not acceptable, do not try to select one on your own SCH_CRED_NO_DEFAULT_CREDS | // dwFlags: If client certificate we provided is not acceptable, do not try to select one on your own
(cfg_method->m_server_names.empty() ? SCH_CRED_NO_SERVERNAME_CHECK : 0) | // dwFlags: When no expected server name is given, do not do the server name check. (m_cfg.m_server_names.empty() ? SCH_CRED_NO_SERVERNAME_CHECK : 0) | // dwFlags: When no expected server name is given, do not do the server name check.
0x00400000 /*SCH_USE_STRONG_CRYPTO*/, // dwFlags: Do not use broken ciphers 0x00400000 /*SCH_USE_STRONG_CRYPTO*/, // dwFlags: Do not use broken ciphers
0 // dwCredFormat 0 // dwCredFormat
}; };
@@ -378,14 +357,14 @@ void eap::method_tls::process_request_packet(
// Preallocate data according to the Length field. // Preallocate data according to the Length field.
size_t size_tot = ntohl(*(unsigned int*)(pReceivedPacket->Data + 2)); size_t size_tot = ntohl(*(unsigned int*)(pReceivedPacket->Data + 2));
m_packet_req.m_data.reserve(size_tot); m_packet_req.m_data.reserve(size_tot);
m_module.log_event(&EAPMETHOD_TLS_PACKET_RECV_FRAG_FIRST, event_data((unsigned int)eap_type_tls), event_data((unsigned int)packet_data_size), event_data((unsigned int)size_tot), event_data::blank); m_module.log_event(&EAPMETHOD_PACKET_RECV_FRAG_FIRST, event_data((unsigned int)eap_type_tls), event_data((unsigned int)packet_data_size), event_data((unsigned int)size_tot), event_data::blank);
} else { } else {
// The Length field was not included. Odd. Nevermind, no pre-allocation then. // The Length field was not included. Odd. Nevermind, no pre-allocation then.
m_module.log_event(&EAPMETHOD_TLS_PACKET_RECV_FRAG_FIRST1, event_data((unsigned int)eap_type_tls), event_data((unsigned int)packet_data_size), event_data::blank); m_module.log_event(&EAPMETHOD_PACKET_RECV_FRAG_FIRST1, event_data((unsigned int)eap_type_tls), event_data((unsigned int)packet_data_size), event_data::blank);
} }
} else { } else {
// Mid fragment received. // Mid fragment received.
m_module.log_event(&EAPMETHOD_TLS_PACKET_RECV_FRAG_MID, event_data((unsigned int)eap_type_tls), event_data((unsigned int)packet_data_size), event_data((unsigned int)m_packet_req.m_data.size()), event_data::blank); m_module.log_event(&EAPMETHOD_PACKET_RECV_FRAG_MID, event_data((unsigned int)eap_type_tls), event_data((unsigned int)packet_data_size), event_data((unsigned int)m_packet_req.m_data.size()), event_data::blank);
} }
m_packet_req.m_data.insert(m_packet_req.m_data.end(), packet_data_ptr, packet_data_ptr + packet_data_size); m_packet_req.m_data.insert(m_packet_req.m_data.end(), packet_data_ptr, packet_data_ptr + packet_data_size);
@@ -400,11 +379,11 @@ void eap::method_tls::process_request_packet(
} else if (!m_packet_req.m_data.empty()) { } else if (!m_packet_req.m_data.empty()) {
// Last fragment received. Append data. // Last fragment received. Append data.
m_packet_req.m_data.insert(m_packet_req.m_data.end(), packet_data_ptr, packet_data_ptr + packet_data_size); m_packet_req.m_data.insert(m_packet_req.m_data.end(), packet_data_ptr, packet_data_ptr + packet_data_size);
m_module.log_event(&EAPMETHOD_TLS_PACKET_RECV_FRAG_LAST, event_data((unsigned int)eap_type_tls), event_data((unsigned int)packet_data_size), event_data((unsigned int)m_packet_req.m_data.size()), event_data::blank); m_module.log_event(&EAPMETHOD_PACKET_RECV_FRAG_LAST, event_data((unsigned int)eap_type_tls), event_data((unsigned int)packet_data_size), event_data((unsigned int)m_packet_req.m_data.size()), event_data::blank);
} else { } else {
// This is a complete non-fragmented packet. // This is a complete non-fragmented packet.
m_packet_req.m_data.assign(packet_data_ptr, packet_data_ptr + packet_data_size); m_packet_req.m_data.assign(packet_data_ptr, packet_data_ptr + packet_data_size);
m_module.log_event(&EAPMETHOD_TLS_PACKET_RECV, event_data((unsigned int)eap_type_tls), event_data((unsigned int)packet_data_size), event_data::blank); m_module.log_event(&EAPMETHOD_PACKET_RECV, event_data((unsigned int)eap_type_tls), event_data((unsigned int)packet_data_size), event_data::blank);
} }
m_packet_req.m_code = (EapCode)pReceivedPacket->Code; m_packet_req.m_code = (EapCode)pReceivedPacket->Code;
@@ -436,7 +415,7 @@ void eap::method_tls::process_request_packet(
#if EAP_TLS < EAP_TLS_SCHANNEL #if EAP_TLS < EAP_TLS_SCHANNEL
if (pReceivedPacket->Code == EapCodeRequest && (m_packet_req.m_flags & flags_req_start)) { if (pReceivedPacket->Code == EapCodeRequest && (m_packet_req.m_flags & flags_req_start)) {
// This is the EAP-TLS start message: (re)initialize method. // This is the EAP-TLS start message: (re)initialize method.
m_module.log_event(&EAPMETHOD_TLS_HANDSHAKE_START2, event_data((unsigned int)eap_type_tls), event_data::blank); m_module.log_event(&EAPMETHOD_METHOD_HANDSHAKE_START2, event_data((unsigned int)eap_type_tls), event_data::blank);
m_phase = phase_client_hello; m_phase = phase_client_hello;
} else { } else {
// Process the packet. // Process the packet.
@@ -565,14 +544,22 @@ void eap::method_tls::process_request_packet(
sanitizing_blob msg_finished(make_message(tls_message_type_handshake, make_finished())); sanitizing_blob msg_finished(make_message(tls_message_type_handshake, make_finished()));
m_packet_res.m_data.insert(m_packet_res.m_data.end(), msg_finished.begin(), msg_finished.end()); m_packet_res.m_data.insert(m_packet_res.m_data.end(), msg_finished.begin(), msg_finished.end());
m_phase = m_handshake[tls_handshake_type_finished] ? phase_application_data : phase_change_cipher_spec; if (m_handshake[tls_handshake_type_finished]) {
// Go to application data phase. And allow piggybacking of the first data message.
m_phase = phase_application_data;
process_application_data(NULL, 0);
} else {
m_phase = phase_change_cipher_spec;
}
break; break;
} }
case phase_change_cipher_spec: case phase_change_cipher_spec:
// Wait in this phase until server sends change cipher spec and finish. // Wait in this phase until server sends change cipher spec and finish.
if (m_state_server.m_alg_encrypt && m_handshake[tls_handshake_type_finished]) if (m_state_server.m_alg_encrypt && m_handshake[tls_handshake_type_finished]) {
m_phase = phase_application_data; m_phase = phase_application_data;
process_application_data(NULL, 0);
}
break; break;
case phase_application_data: case phase_application_data:
@@ -582,7 +569,7 @@ void eap::method_tls::process_request_packet(
#else #else
if (pReceivedPacket->Code == EapCodeRequest && (m_packet_req.m_flags & flags_req_start)) { if (pReceivedPacket->Code == EapCodeRequest && (m_packet_req.m_flags & flags_req_start)) {
// This is the EAP-TLS start message: (re)initialize method. // This is the EAP-TLS start message: (re)initialize method.
m_module.log_event(&EAPMETHOD_TLS_HANDSHAKE_START2, event_data((unsigned int)eap_type_tls), event_data::blank); m_module.log_event(&EAPMETHOD_METHOD_HANDSHAKE_START2, event_data((unsigned int)eap_type_tls), event_data::blank);
m_phase = phase_handshake_init; m_phase = phase_handshake_init;
m_sc_queue.assign(m_packet_req.m_data.begin(), m_packet_req.m_data.end()); m_sc_queue.assign(m_packet_req.m_data.begin(), m_packet_req.m_data.end());
} else } else
@@ -628,7 +615,7 @@ void eap::method_tls::get_response_packet(
// No need to fragment the packet. // No need to fragment the packet.
m_packet_res.m_flags &= ~flags_res_length_incl; // No need to explicitly include the Length field either. m_packet_res.m_flags &= ~flags_res_length_incl; // No need to explicitly include the Length field either.
data_dst = pSendPacket->Data + 2; data_dst = pSendPacket->Data + 2;
m_module.log_event(&EAPMETHOD_TLS_PACKET_SEND, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_data), event_data::blank); m_module.log_event(&EAPMETHOD_PACKET_SEND, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_data), event_data::blank);
} else { } else {
// But it should be fragmented. // But it should be fragmented.
m_packet_res.m_flags |= flags_res_length_incl | flags_res_more_frag; m_packet_res.m_flags |= flags_res_length_incl | flags_res_more_frag;
@@ -636,7 +623,7 @@ void eap::method_tls::get_response_packet(
data_dst = pSendPacket->Data + 6; data_dst = pSendPacket->Data + 6;
size_data = size_packet_limit - 10; size_data = size_packet_limit - 10;
size_packet = size_packet_limit; size_packet = size_packet_limit;
m_module.log_event(&EAPMETHOD_TLS_PACKET_SEND_FRAG_FIRST, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_data), event_data((unsigned int)(m_packet_res.m_data.size() - size_data)), event_data::blank); m_module.log_event(&EAPMETHOD_PACKET_SEND_FRAG_FIRST, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_data), event_data((unsigned int)(m_packet_res.m_data.size() - size_data)), event_data::blank);
} }
} else { } else {
// Continuing the fragmented packet... // Continuing the fragmented packet...
@@ -645,11 +632,11 @@ void eap::method_tls::get_response_packet(
m_packet_res.m_flags &= ~flags_res_length_incl; m_packet_res.m_flags &= ~flags_res_length_incl;
size_data = size_packet_limit - 6; size_data = size_packet_limit - 6;
size_packet = size_packet_limit; size_packet = size_packet_limit;
m_module.log_event(&EAPMETHOD_TLS_PACKET_SEND_FRAG_MID, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_data), event_data((unsigned int)(m_packet_res.m_data.size() - size_data)), event_data::blank); m_module.log_event(&EAPMETHOD_PACKET_SEND_FRAG_MID, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_data), event_data((unsigned int)(m_packet_res.m_data.size() - size_data)), event_data::blank);
} else { } else {
// This is the last fragment. // This is the last fragment.
m_packet_res.m_flags &= ~(flags_res_length_incl | flags_res_more_frag); m_packet_res.m_flags &= ~(flags_res_length_incl | flags_res_more_frag);
m_module.log_event(&EAPMETHOD_TLS_PACKET_SEND_FRAG_LAST, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_data), event_data((unsigned int)(m_packet_res.m_data.size() - size_data)), event_data::blank); m_module.log_event(&EAPMETHOD_PACKET_SEND_FRAG_LAST, event_data((unsigned int)eap_type_tls), event_data((unsigned int)size_data), event_data((unsigned int)(m_packet_res.m_data.size() - size_data)), event_data::blank);
} }
data_dst = pSendPacket->Data + 2; data_dst = pSendPacket->Data + 2;
} }
@@ -671,13 +658,9 @@ void eap::method_tls::get_result(
{ {
assert(ppResult); assert(ppResult);
config_provider &cfg_prov(m_cfg.m_providers.front());
config_method_tls *cfg_method = dynamic_cast<config_method_tls*>(cfg_prov.m_methods.front().get());
assert(cfg_method);
switch (reason) { switch (reason) {
case EapPeerMethodResultSuccess: { case EapPeerMethodResultSuccess: {
m_module.log_event(&EAPMETHOD_TLS_SUCCESS, event_data((unsigned int)eap_type_tls), event_data::blank); m_module.log_event(&EAPMETHOD_METHOD_SUCCESS, event_data((unsigned int)eap_type_tls), event_data::blank);
#if EAP_TLS < EAP_TLS_SCHANNEL #if EAP_TLS < EAP_TLS_SCHANNEL
// Derive MSK/EMSK for line encryption. // Derive MSK/EMSK for line encryption.
@@ -685,8 +668,7 @@ void eap::method_tls::get_result(
// Fill array with RADIUS attributes. // Fill array with RADIUS attributes.
eap_attr a; eap_attr a;
m_eap_attr.clear(); m_eap_attr.reserve(m_eap_attr.size() + 3);
m_eap_attr.reserve(3);
a.create_ms_mppe_key(16, (LPCBYTE)&m_key_mppe_client, sizeof(tls_random)); a.create_ms_mppe_key(16, (LPCBYTE)&m_key_mppe_client, sizeof(tls_random));
m_eap_attr.push_back(std::move(a)); m_eap_attr.push_back(std::move(a));
a.create_ms_mppe_key(17, (LPCBYTE)&m_key_mppe_server, sizeof(tls_random)); a.create_ms_mppe_key(17, (LPCBYTE)&m_key_mppe_server, sizeof(tls_random));
@@ -702,8 +684,7 @@ void eap::method_tls::get_result(
// Fill array with RADIUS attributes. // Fill array with RADIUS attributes.
eap_attr a; eap_attr a;
m_eap_attr.clear(); m_eap_attr.reserve(m_eap_attr.size() + 3);
m_eap_attr.reserve(3);
a.create_ms_mppe_key(16, _key_block, sizeof(tls_random)); a.create_ms_mppe_key(16, _key_block, sizeof(tls_random));
m_eap_attr.push_back(std::move(a)); m_eap_attr.push_back(std::move(a));
_key_block += sizeof(tls_random); _key_block += sizeof(tls_random);
@@ -713,40 +694,45 @@ void eap::method_tls::get_result(
m_eap_attr.push_back(eap_attr::blank); m_eap_attr.push_back(eap_attr::blank);
#endif #endif
m_eap_attr_desc.dwNumberOfAttributes = (DWORD)m_eap_attr.size();
m_eap_attr_desc.pAttribs = m_eap_attr.data();
ppResult->pAttribArray = &m_eap_attr_desc;
// Clear credentials as failed. // Clear credentials as failed.
cfg_method->m_auth_failed = false; m_cfg.m_auth_failed = false;
ppResult->fIsSuccess = TRUE; ppResult->fIsSuccess = TRUE;
ppResult->dwFailureReasonCode = ERROR_SUCCESS; ppResult->dwFailureReasonCode = ERROR_SUCCESS;
#if EAP_TLS < EAP_TLS_SCHANNEL #if EAP_TLS < EAP_TLS_SCHANNEL
// Update configuration with session resumption data and prepare BLOB. // Update configuration with session resumption data and prepare BLOB.
cfg_method->m_session_id = m_session_id; m_cfg.m_session_id = m_session_id;
cfg_method->m_master_secret = m_master_secret; m_cfg.m_master_secret = m_master_secret;
#endif #endif
break; break;
} }
case EapPeerMethodResultFailure: case EapPeerMethodResultFailure:
m_module.log_event(
m_phase_prev < phase_handshake_cont ? &EAPMETHOD_TLS_FAILURE_INIT :
m_phase_prev < phase_application_data ? &EAPMETHOD_TLS_FAILURE_HANDSHAKE : &EAPMETHOD_TLS_FAILURE,
event_data((unsigned int)eap_type_tls), event_data::blank);
#if EAP_TLS < EAP_TLS_SCHANNEL #if EAP_TLS < EAP_TLS_SCHANNEL
// Clear session resumption data. m_module.log_event(
cfg_method->m_session_id.clear(); m_phase < phase_change_cipher_spec ? &EAPMETHOD_METHOD_FAILURE_INIT :
cfg_method->m_master_secret.clear(); m_phase < phase_application_data ? &EAPMETHOD_METHOD_FAILURE_HANDSHAKE : &EAPMETHOD_METHOD_FAILURE,
#endif event_data((unsigned int)eap_type_tls), event_data::blank);
// Mark credentials as failed, so GUI can re-prompt user. // Mark credentials as failed, so GUI can re-prompt user.
// But be careful: do so only if this happened after transition from handshake to application data phase. // But be careful: do so only if this happened after transition from handshake to application data phase.
cfg_method->m_auth_failed = m_phase_prev < phase_application_data && m_phase >= phase_application_data; m_cfg.m_auth_failed = m_phase >= phase_application_data;
// Clear session resumption data.
m_cfg.m_session_id.clear();
m_cfg.m_master_secret.clear();
#else
m_module.log_event(
m_phase_prev < phase_handshake_cont ? &EAPMETHOD_METHOD_FAILURE_INIT :
m_phase_prev < phase_application_data ? &EAPMETHOD_METHOD_FAILURE_HANDSHAKE : &EAPMETHOD_METHOD_FAILURE,
event_data((unsigned int)eap_type_tls), event_data::blank);
// Mark credentials as failed, so GUI can re-prompt user.
// But be careful: do so only if this happened after transition from handshake to application data phase.
m_cfg.m_auth_failed = m_phase_prev < phase_application_data && m_phase >= phase_application_data;
#endif
// Do not report failure to EapHost, as it will not save updated configuration then. But we need it to save it, to alert user on next connection attempt. // Do not report failure to EapHost, as it will not save updated configuration then. But we need it to save it, to alert user on next connection attempt.
// EapHost is well aware of the failed condition. // EapHost is well aware of the failed condition.
@@ -761,18 +747,6 @@ void eap::method_tls::get_result(
// Always ask EAP host to save the connection data. // Always ask EAP host to save the connection data.
ppResult->fSaveConnectionData = TRUE; ppResult->fSaveConnectionData = TRUE;
m_module.pack(m_cfg, &ppResult->pConnectionData, &ppResult->dwSizeofConnectionData);
if (m_blob_cfg)
m_module.free_memory(m_blob_cfg);
m_blob_cfg = ppResult->pConnectionData;
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
ppResult->fSaveUserData = TRUE;
m_module.pack(m_cred, &ppResult->pUserData, &ppResult->dwSizeofUserData);
if (m_blob_cred)
m_module.free_memory(m_blob_cred);
m_blob_cred = ppResult->pUserData;
#endif
} }
@@ -1483,38 +1457,34 @@ void eap::method_tls::verify_server_trust() const
throw sec_runtime_error(status, __FUNCTION__ " Error retrieving server certificate from Schannel."); throw sec_runtime_error(status, __FUNCTION__ " Error retrieving server certificate from Schannel.");
#endif #endif
const config_provider &cfg_prov(m_cfg.m_providers.front());
const config_method_tls *cfg_method = dynamic_cast<const config_method_tls*>(cfg_prov.m_methods.front().get());
assert(cfg_method);
// Check server name. // Check server name.
if (!cfg_method->m_server_names.empty()) { if (!m_cfg.m_server_names.empty()) {
bool bool
has_san = false, has_san = false,
found = false; found = false;
// Search subjectAltName2 and subjectAltName. // Search subjectAltName2 and subjectAltName.
for (DWORD i = 0; !found && i < cert->pCertInfo->cExtension; i++) { for (DWORD idx_ext = 0; !found && idx_ext < cert->pCertInfo->cExtension; idx_ext++) {
unique_ptr<CERT_ALT_NAME_INFO, LocalFree_delete<CERT_ALT_NAME_INFO> > san_info; unique_ptr<CERT_ALT_NAME_INFO, LocalFree_delete<CERT_ALT_NAME_INFO> > san_info;
if (strcmp(cert->pCertInfo->rgExtension[i].pszObjId, szOID_SUBJECT_ALT_NAME2) == 0) { if (strcmp(cert->pCertInfo->rgExtension[idx_ext].pszObjId, szOID_SUBJECT_ALT_NAME2) == 0) {
unsigned char *output = NULL; unsigned char *output = NULL;
DWORD size_output; DWORD size_output;
if (!CryptDecodeObjectEx( if (!CryptDecodeObjectEx(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
szOID_SUBJECT_ALT_NAME2, szOID_SUBJECT_ALT_NAME2,
cert->pCertInfo->rgExtension[i].Value.pbData, cert->pCertInfo->rgExtension[i].Value.cbData, cert->pCertInfo->rgExtension[idx_ext].Value.pbData, cert->pCertInfo->rgExtension[idx_ext].Value.cbData,
CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_ENABLE_PUNYCODE_FLAG, CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_ENABLE_PUNYCODE_FLAG,
NULL, NULL,
&output, &size_output)) &output, &size_output))
throw win_runtime_error(__FUNCTION__ " Error decoding subjectAltName2 certificate extension."); throw win_runtime_error(__FUNCTION__ " Error decoding subjectAltName2 certificate extension.");
san_info.reset((CERT_ALT_NAME_INFO*)output); san_info.reset((CERT_ALT_NAME_INFO*)output);
} else if (strcmp(cert->pCertInfo->rgExtension[i].pszObjId, szOID_SUBJECT_ALT_NAME) == 0) { } else if (strcmp(cert->pCertInfo->rgExtension[idx_ext].pszObjId, szOID_SUBJECT_ALT_NAME) == 0) {
unsigned char *output = NULL; unsigned char *output = NULL;
DWORD size_output; DWORD size_output;
if (!CryptDecodeObjectEx( if (!CryptDecodeObjectEx(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
szOID_SUBJECT_ALT_NAME, szOID_SUBJECT_ALT_NAME,
cert->pCertInfo->rgExtension[i].Value.pbData, cert->pCertInfo->rgExtension[i].Value.cbData, cert->pCertInfo->rgExtension[idx_ext].Value.pbData, cert->pCertInfo->rgExtension[idx_ext].Value.cbData,
CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_ENABLE_PUNYCODE_FLAG, CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_ENABLE_PUNYCODE_FLAG,
NULL, NULL,
&output, &size_output)) &output, &size_output))
@@ -1526,12 +1496,12 @@ void eap::method_tls::verify_server_trust() const
} }
has_san = true; has_san = true;
for (list<wstring>::const_iterator s = cfg_method->m_server_names.cbegin(), s_end = cfg_method->m_server_names.cend(); !found && s != s_end; ++s) { for (list<wstring>::const_iterator s = m_cfg.m_server_names.cbegin(), s_end = m_cfg.m_server_names.cend(); !found && s != s_end; ++s) {
for (DWORD i = 0; !found && i < san_info->cAltEntry; i++) { for (DWORD idx_entry = 0; !found && idx_entry < san_info->cAltEntry; idx_entry++) {
if (san_info->rgAltEntry[i].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME && if (san_info->rgAltEntry[idx_entry].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME &&
_wcsicmp(s->c_str(), san_info->rgAltEntry[i].pwszDNSName) == 0) _wcsicmp(s->c_str(), san_info->rgAltEntry[idx_entry].pwszDNSName) == 0)
{ {
m_module.log_event(&EAPMETHOD_TLS_SERVER_NAME_TRUSTED1, event_data(san_info->rgAltEntry[i].pwszDNSName), event_data::blank); m_module.log_event(&EAPMETHOD_TLS_SERVER_NAME_TRUSTED1, event_data(san_info->rgAltEntry[idx_entry].pwszDNSName), event_data::blank);
found = true; found = true;
} }
} }
@@ -1544,7 +1514,7 @@ void eap::method_tls::verify_server_trust() const
if (!CertGetNameStringW(cert, CERT_NAME_DNS_TYPE, CERT_NAME_STR_ENABLE_PUNYCODE_FLAG, NULL, subj)) if (!CertGetNameStringW(cert, CERT_NAME_DNS_TYPE, CERT_NAME_STR_ENABLE_PUNYCODE_FLAG, NULL, subj))
throw win_runtime_error(__FUNCTION__ " Error retrieving server's certificate subject name."); throw win_runtime_error(__FUNCTION__ " Error retrieving server's certificate subject name.");
for (list<wstring>::const_iterator s = cfg_method->m_server_names.cbegin(), s_end = cfg_method->m_server_names.cend(); !found && s != s_end; ++s) { for (list<wstring>::const_iterator s = m_cfg.m_server_names.cbegin(), s_end = m_cfg.m_server_names.cend(); !found && s != s_end; ++s) {
if (_wcsicmp(s->c_str(), subj.c_str()) == 0) { if (_wcsicmp(s->c_str(), subj.c_str()) == 0) {
m_module.log_event(&EAPMETHOD_TLS_SERVER_NAME_TRUSTED1, event_data(subj), event_data::blank); m_module.log_event(&EAPMETHOD_TLS_SERVER_NAME_TRUSTED1, event_data(subj), event_data::blank);
found = true; found = true;
@@ -1564,7 +1534,7 @@ void eap::method_tls::verify_server_trust() const
cert_store store; cert_store store;
if (!store.create(CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, NULL, 0, NULL)) if (!store.create(CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, NULL, 0, NULL))
throw win_runtime_error(__FUNCTION__ " Error creating temporary certificate store."); throw win_runtime_error(__FUNCTION__ " Error creating temporary certificate store.");
for (list<cert_context>::const_iterator c = cfg_method->m_trusted_root_ca.cbegin(), c_end = cfg_method->m_trusted_root_ca.cend(); c != c_end; ++c) for (list<cert_context>::const_iterator c = m_cfg.m_trusted_root_ca.cbegin(), c_end = m_cfg.m_trusted_root_ca.cend(); c != c_end; ++c)
CertAddCertificateContextToStore(store, *c, CERT_STORE_ADD_REPLACE_EXISTING, NULL); CertAddCertificateContextToStore(store, *c, CERT_STORE_ADD_REPLACE_EXISTING, NULL);
// Add all intermediate certificates from the server's certificate chain. // Add all intermediate certificates from the server's certificate chain.
@@ -1636,7 +1606,7 @@ void eap::method_tls::verify_server_trust() const
throw sec_runtime_error(SEC_E_CERT_UNKNOWN, __FUNCTION__ " Can not verify empty certificate chain."); throw sec_runtime_error(SEC_E_CERT_UNKNOWN, __FUNCTION__ " Can not verify empty certificate chain.");
PCCERT_CONTEXT cert_root = context->rgpChain[0]->rgpElement[context->rgpChain[0]->cElement-1]->pCertContext; PCCERT_CONTEXT cert_root = context->rgpChain[0]->rgpElement[context->rgpChain[0]->cElement-1]->pCertContext;
for (list<cert_context>::const_iterator c = cfg_method->m_trusted_root_ca.cbegin(), c_end = cfg_method->m_trusted_root_ca.cend();; ++c) { for (list<cert_context>::const_iterator c = m_cfg.m_trusted_root_ca.cbegin(), c_end = m_cfg.m_trusted_root_ca.cend();; ++c) {
if (c != c_end) { if (c != c_end) {
if (cert_root->cbCertEncoded == (*c)->cbCertEncoded && if (cert_root->cbCertEncoded == (*c)->cbCertEncoded &&
memcmp(cert_root->pbCertEncoded, (*c)->pbCertEncoded, cert_root->cbCertEncoded) == 0) memcmp(cert_root->pbCertEncoded, (*c)->pbCertEncoded, cert_root->cbCertEncoded) == 0)

View File

@@ -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:
module &m_module; ///< Module
config_connection m_cfg; ///< Connection configuration config_connection m_cfg; ///< Connection configuration
credentials_ttls m_cred; ///< User credentials credentials_ttls m_cred; ///< User credentials
method_ttls m_method; ///< EAP-TTLS method std::unique_ptr<method_ttls> m_method; ///< EAP-TTLS method
// The following members are required to avoid memory leakage in get_result()
EAP_ATTRIBUTES m_eap_attr_desc; ///< EAP attributes descriptor
BYTE *m_blob_cfg; ///< Configuration BLOB
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
BYTE *m_blob_cred; ///< Credentials BLOB
#endif
}; };
}; };
} }

View File

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

View File

@@ -103,22 +103,40 @@ void eap::peer_ttls::get_identity(
*pfInvokeUI = FALSE; *pfInvokeUI = FALSE;
{ {
// 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);
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) {
// If either of credentials is unknown, request UI. log_event(&EAPMETHOD_TRACE_EVT_CRED_INVOKE_UI1, event_data((unsigned int)eap_type_tls), event_data::blank);
if (cred_source == eap::credentials::source_unknown)
*pfInvokeUI = TRUE; *pfInvokeUI = TRUE;
} }
// Combine inner credentials.
eap::credentials::source_t src_inner = cred_out.m_inner->combine(
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
cred_in.m_inner.get(),
#else
NULL,
#endif
*cfg_method->m_inner,
target_name);
if (src_inner == eap::credentials::source_unknown) {
log_event(&EAPMETHOD_TRACE_EVT_CRED_INVOKE_UI1, event_data((unsigned int)cfg_method->m_inner->get_method_id()), event_data::blank);
*pfInvokeUI = TRUE;
}
}
// If either of credentials is unknown, request UI.
if (*pfInvokeUI) { if (*pfInvokeUI) {
if ((dwFlags & EAP_FLAG_MACHINE_AUTH) == 0) { if ((dwFlags & EAP_FLAG_MACHINE_AUTH) == 0) {
// Per-user authentication // Per-user authentication
@@ -132,8 +150,9 @@ 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 ((dwFlags & EAP_FLAG_MACHINE_AUTH) == 0) {
if (cfg_method->m_auth_failed) { if (cfg_method->m_auth_failed) {
// Outer TLS: Credentials failed on last connection attempt. // Outer: Credentials failed on last connection attempt.
log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM, event_data((unsigned int)eap_type_tls), event_data::blank); log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM, event_data((unsigned int)eap_type_tls), event_data::blank);
*pfInvokeUI = TRUE; *pfInvokeUI = TRUE;
return; return;
@@ -145,6 +164,7 @@ void eap::peer_ttls::get_identity(
*pfInvokeUI = TRUE; *pfInvokeUI = TRUE;
return; return;
} }
}
// Build our identity. ;) // Build our identity. ;)
wstring identity(std::move(cfg_method->get_public_identity(cred_out))); wstring identity(std::move(cfg_method->get_public_identity(cred_out)));
@@ -251,16 +271,19 @@ EAP_SESSION_HANDLE eap::peer_ttls::begin_session(
// Get method configuration. // Get method configuration.
if (s->m_cfg.m_providers.empty() || s->m_cfg.m_providers.front().m_methods.empty()) 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."); throw invalid_argument(__FUNCTION__ " Configuration has no providers and/or methods.");
const config_provider &cfg_prov(s->m_cfg.m_providers.front()); config_provider &cfg_prov(s->m_cfg.m_providers.front());
const config_method_ttls *cfg_method = dynamic_cast<const config_method_ttls*>(cfg_prov.m_methods.front().get()); config_method_ttls *cfg_method = dynamic_cast<config_method_ttls*>(cfg_prov.m_methods.front().get());
assert(cfg_method); assert(cfg_method);
// Unpack credentials. // Unpack credentials.
s->m_cred.m_inner.reset(cfg_method->m_inner->make_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();
} }
@@ -284,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);
} }
@@ -293,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);
} }
@@ -302,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
} }
@@ -356,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

@@ -27,6 +27,7 @@
#include "../../PAP/include/Config.h" #include "../../PAP/include/Config.h"
#include "../../PAP/include/Credentials.h" #include "../../PAP/include/Credentials.h"
#include "../../PAP/include/Method.h"
#include "../../EAPBase/include/EAPXML.h" #include "../../EAPBase/include/EAPXML.h"

View File

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