From c9be6f4f7ba4e56dc67f1da1938e6df1deeb04ae Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Wed, 31 Aug 2016 14:39:27 +0200 Subject: [PATCH] Support for multiple identity providers of draft-winter-opsawg-eap-metadata XML configuration added --- EAPMethods/locale/EAPMethods.pot | 133 +++++++-------- MSI/Base/locale/GEANTLink.pot | 23 +-- lib/EAPBase/include/Credentials.h | 109 ++++++++++++ lib/EAPBase/src/Credentials.cpp | 152 ++++++++++++++++- lib/EAPBase_UI/include/EAP_UI.h | 30 +++- lib/EAPBase_UI/res/wxEAP_UI.cpp | 44 ++++- lib/EAPBase_UI/res/wxEAP_UI.fbp | 268 +++++++++++++++++++++++++++++- lib/EAPBase_UI/res/wxEAP_UI.h | 27 ++- lib/EAPBase_UI/src/EAP_UI.cpp | 38 +++++ lib/Events/res/EventsETW.man | Bin 92756 -> 97394 bytes lib/TLS/src/Credentials.cpp | 6 +- lib/TTLS/include/Module.h | 14 +- lib/TTLS/src/Config.cpp | 16 +- lib/TTLS/src/Credentials.cpp | 1 + lib/TTLS/src/Module.cpp | 209 +++++++++++++---------- lib/TTLS_UI/src/Module.cpp | 165 +++++++++++------- 16 files changed, 978 insertions(+), 257 deletions(-) diff --git a/EAPMethods/locale/EAPMethods.pot b/EAPMethods/locale/EAPMethods.pot index 4f0cde3..e56b7e1 100644 --- a/EAPMethods/locale/EAPMethods.pot +++ b/EAPMethods/locale/EAPMethods.pot @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: EAPMethods\n" -"POT-Creation-Date: 2016-08-31 00:43+0200\n" +"POT-Creation-Date: 2016-08-31 14:32+0200\n" "PO-Revision-Date: 2016-06-02 12:27+0200\n" "Last-Translator: Simon Rozman \n" "Language-Team: Amebis, d. o. o., Kamnik \n" @@ -43,145 +43,145 @@ msgstr "" msgid "Opens dialog with provider settings" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:188 lib/EAPBase_UI/res/wxEAP_UI.cpp:313 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:230 lib/EAPBase_UI/res/wxEAP_UI.cpp:355 msgid "Client Credentials" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:199 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:241 msgid "Manage credentials used to connect." msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:212 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:254 msgid "Use &own credentials:" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:213 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:255 msgid "Select this option if you have your unique credentials to connect" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:218 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:260 msgid "Your credentials loaded from Windows Credential Manager" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:228 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:270 msgid "&Clear Credentials" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:229 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:271 msgid "" "Click to clear your credentials from Credential Manager.\n" "Note: You will be prompted to enter credentials when connecting." msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:233 lib/EAPBase_UI/res/wxEAP_UI.cpp:266 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:275 lib/EAPBase_UI/res/wxEAP_UI.cpp:308 msgid "&Set Credentials..." msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:234 lib/EAPBase_UI/res/wxEAP_UI.cpp:267 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:276 lib/EAPBase_UI/res/wxEAP_UI.cpp:309 msgid "Click here to set or modify your credentials" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:250 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:292 msgid "Use &pre-shared credentials:" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:251 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:293 msgid "Select this options if all clients connect using the same credentials" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:256 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:298 msgid "Common (pre-shared) credentials" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:324 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:366 msgid "Please provide your user ID and password." msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:334 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:376 msgid "User ID:" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:339 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:381 msgid "Enter your user name here (user@domain.org, DOMAIN\\User, etc.)" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:343 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:385 msgid "Password:" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:348 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:390 msgid "Enter your password here" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:355 lib/TLS_UI/res/wxTLS_UI.cpp:183 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:397 lib/TLS_UI/res/wxTLS_UI.cpp:183 msgid "&Remember" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:356 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:398 msgid "Check if you would like to save username and password" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:378 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:420 msgid "Your Organization" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:389 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:431 msgid "Describe your organization to customize user prompts. When organization is introduced, end-users find program messages easier to understand and act." msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:396 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:438 msgid "Your organization &name:" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:401 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:443 msgid "Your organization name as it will appear on helpdesk contact notifications" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:405 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:447 msgid "(Keep it short, please)" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:415 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:457 msgid "Helpdesk contact &information:" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:425 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:467 msgid "¶" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:432 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:474 msgid "Your helpdesk website address" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:436 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:478 msgid "*" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:443 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:485 msgid "Your helpdesk e-mail address" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:447 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:489 msgid ")" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:454 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:496 msgid "Your helpdesk phone number" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:482 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:524 msgid "Configuration Lock" msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:493 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:535 msgid "Your configuration can be locked to prevent accidental modification by end-users. Users will only be allowed to enter credentials." msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:500 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:542 msgid "&Lock this configuration and prevent any further modification via user interface." msgstr "" -#: lib/EAPBase_UI/res/wxEAP_UI.cpp:503 +#: lib/EAPBase_UI/res/wxEAP_UI.cpp:545 msgid "(Warning: Once locked, you can not revert using this dialog!)" msgstr "" @@ -190,47 +190,52 @@ msgstr "" msgid "%s Credentials" msgstr "" -#: lib/EAPBase_UI/src/EAP_UI.cpp:128 +#: lib/EAPBase_UI/src/EAP_UI.cpp:123 lib/EAPBase_UI/include/EAP_UI.h:346 +#: lib/EAPBase_UI/include/EAP_UI.h:356 lib/EAPBase_UI/res/wxEAP_UI.h:118 +msgid "EAP Credentials" +msgstr "" + +#: lib/EAPBase_UI/src/EAP_UI.cpp:166 #, c-format msgid "For additional help and instructions, please contact %s at:" msgstr "" -#: lib/EAPBase_UI/src/EAP_UI.cpp:130 +#: lib/EAPBase_UI/src/EAP_UI.cpp:168 #, c-format msgid "your %ls provider" msgstr "" -#: lib/EAPBase_UI/src/EAP_UI.cpp:130 +#: lib/EAPBase_UI/src/EAP_UI.cpp:168 msgid "your provider" msgstr "" -#: lib/EAPBase_UI/src/EAP_UI.cpp:149 +#: lib/EAPBase_UI/src/EAP_UI.cpp:187 msgid "Open the default web browser" msgstr "" -#: lib/EAPBase_UI/src/EAP_UI.cpp:160 +#: lib/EAPBase_UI/src/EAP_UI.cpp:198 msgid "Open your e-mail program" msgstr "" -#: lib/EAPBase_UI/src/EAP_UI.cpp:171 +#: lib/EAPBase_UI/src/EAP_UI.cpp:209 msgid "Dial the phone number" msgstr "" -#: lib/EAPBase_UI/src/EAP_UI.cpp:191 +#: lib/EAPBase_UI/src/EAP_UI.cpp:229 #, c-format msgid "%s has pre-set parts of this configuration. Those parts are locked to prevent accidental modification." msgstr "" -#: lib/EAPBase_UI/src/EAP_UI.cpp:193 +#: lib/EAPBase_UI/src/EAP_UI.cpp:231 #, c-format msgid "Your %ls provider" msgstr "" -#: lib/EAPBase_UI/src/EAP_UI.cpp:193 +#: lib/EAPBase_UI/src/EAP_UI.cpp:231 msgid "Your provider" msgstr "" -#: lib/EAPBase_UI/src/EAP_UI.cpp:213 +#: lib/EAPBase_UI/src/EAP_UI.cpp:251 msgid "Previous attempt to connect failed. Please, make sure your credentials are correct, or try again later." msgstr "" @@ -404,14 +409,14 @@ msgstr "" msgid "Custom outer identity to use" msgstr "" -#: lib/TTLS_UI/src/Module.cpp:230 lib/TTLS_UI/src/Module.cpp:240 -#: lib/EAPBase_UI/include/EAP_UI.h:642 +#: lib/TTLS_UI/src/Module.cpp:269 lib/TTLS_UI/src/Module.cpp:279 +#: lib/EAPBase_UI/include/EAP_UI.h:662 #, c-format msgid "Error writing credentials to Credential Manager: %hs (error %u)" msgstr "" -#: lib/TTLS_UI/src/Module.cpp:232 lib/TTLS_UI/src/Module.cpp:242 -#: lib/EAPBase_UI/include/EAP_UI.h:645 +#: lib/TTLS_UI/src/Module.cpp:271 lib/TTLS_UI/src/Module.cpp:281 +#: lib/EAPBase_UI/include/EAP_UI.h:665 msgid "Writing credentials failed." msgstr "" @@ -431,51 +436,47 @@ msgstr "" msgid "Outer Authentication" msgstr "" -#: lib/EAPBase_UI/include/EAP_UI.h:278 +#: lib/EAPBase_UI/include/EAP_UI.h:283 #, c-format msgid "Are you sure you want to permanently remove %ls provider from configuration?" msgstr "" -#: lib/EAPBase_UI/include/EAP_UI.h:278 +#: lib/EAPBase_UI/include/EAP_UI.h:283 msgid "Warning" msgstr "" -#: lib/EAPBase_UI/include/EAP_UI.h:341 -msgid "EAP Credentials" -msgstr "" - -#: lib/EAPBase_UI/include/EAP_UI.h:501 +#: lib/EAPBase_UI/include/EAP_UI.h:521 msgid "Provider Settings" msgstr "" -#: lib/EAPBase_UI/include/EAP_UI.h:658 +#: lib/EAPBase_UI/include/EAP_UI.h:678 #, c-format msgid "Deleting credentials failed (error %u)." msgstr "" -#: lib/EAPBase_UI/include/EAP_UI.h:691 +#: lib/EAPBase_UI/include/EAP_UI.h:711 #, c-format msgid "" msgstr "" -#: lib/EAPBase_UI/include/EAP_UI.h:695 +#: lib/EAPBase_UI/include/EAP_UI.h:715 msgid "" msgstr "" -#: lib/EAPBase_UI/include/EAP_UI.h:704 lib/EAPBase_UI/include/EAP_UI.h:715 -msgid "" +#: lib/EAPBase_UI/include/EAP_UI.h:724 lib/EAPBase_UI/include/EAP_UI.h:735 +msgid "" msgstr "" -#: lib/EAPBase_UI/include/EAP_UI.h:707 lib/EAPBase_UI/include/EAP_UI.h:718 -msgid "" +#: lib/EAPBase_UI/include/EAP_UI.h:727 lib/EAPBase_UI/include/EAP_UI.h:738 +msgid "" msgstr "" -#: lib/EAPBase_UI/include/EAP_UI.h:924 +#: lib/EAPBase_UI/include/EAP_UI.h:944 msgid "" msgstr "" #: lib/EAPBase_UI/res/wxEAP_UI.h:68 -msgid "EAP Method Configuration" +msgid "EAP Connection Configuration" msgstr "" #: EAPMethods/MSIBuild/En.Win32.Release.Feature-2.idtx:3 diff --git a/MSI/Base/locale/GEANTLink.pot b/MSI/Base/locale/GEANTLink.pot index 2d70541..c458793 100644 --- a/MSI/Base/locale/GEANTLink.pot +++ b/MSI/Base/locale/GEANTLink.pot @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: GÉANTLink MSI\n" -"POT-Creation-Date: 2016-07-15 10:51+0200\n" +"POT-Creation-Date: 2016-08-31 14:33+0200\n" "PO-Revision-Date: 2016-06-02 12:27+0200\n" "Last-Translator: Simon Rozman \n" "Language-Team: Amebis, d. o. o., Kamnik \n" @@ -17,25 +17,20 @@ msgstr "" "X-Poedit-KeywordsList: _\n" "X-Poedit-SearchPath-0: .\n" -#: En.Win32.Release.Property-2.idtx:6 En.x64.Release.Property-2.idtx:6 -msgid "+386 1 8311 035" +#: En.Win32.Release.LaunchCondition-2.idtx:4 +#: En.x64.Release.LaunchCondition-2.idtx:4 +msgid "[ProductName] requires Windows Vista or later version of Windows." msgstr "" #: En.Win32.Release.Property-2.idtx:3 En.x64.Release.Property-2.idtx:3 -#, fuzzy msgid "1252" -msgstr "1250" - -#: En.Win32.Release.Property-2.idtx:5 En.x64.Release.Property-2.idtx:5 -msgid "Amebis, p. p. 69, SI-1241 Kamnik, Slovenia, E.U." msgstr "" -#: En.Win32.Release.Property-2.idtx:4 En.x64.Release.Property-2.idtx:4 -msgid "Amebis, Slovenia, E.U." +#: En.Win32.Release.Property-2.idtx:4 En.Win32.Release.Property-2.idtx:5 +#: En.x64.Release.Property-2.idtx:4 En.x64.Release.Property-2.idtx:5 +msgid "http://www.geant.org/" msgstr "" -#: En.Win32.Release.Property-2.idtx:7 En.Win32.Release.Property-2.idtx:8 -#: En.Win32.Release.Property-2.idtx:9 En.x64.Release.Property-2.idtx:7 -#: En.x64.Release.Property-2.idtx:8 En.x64.Release.Property-2.idtx:9 -msgid "http://www.amebis.si/" +#: En.Win32.Release.Property-2.idtx:6 En.x64.Release.Property-2.idtx:6 +msgid "https://github.com/Amebis/GEANTLink/releases" msgstr "" diff --git a/lib/EAPBase/include/Credentials.h b/lib/EAPBase/include/Credentials.h index 5e89b56..288878e 100644 --- a/lib/EAPBase/include/Credentials.h +++ b/lib/EAPBase/include/Credentials.h @@ -31,6 +31,11 @@ namespace eap /// Password based method credentials /// class credentials_pass; + + /// + /// Connection credentials + /// + class credentials_connection; } #pragma once @@ -47,6 +52,7 @@ namespace eap #include #include +#include #include @@ -372,4 +378,107 @@ namespace eap static const unsigned char s_entropy[1024]; /// \endcond }; + + + class credentials_connection : public config + { + public: + /// + /// Constructs credentials + /// + /// \param[in] mod EAP module to use for global services + /// \param[in] cfg Connection configuration + /// + credentials_connection(_In_ module &mod, _In_ const config_connection &cfg); + + /// + /// Copies credentials + /// + /// \param[in] other Credentials to copy from + /// + credentials_connection(_In_ const credentials_connection &other); + + /// + /// Moves credentials + /// + /// \param[in] other Credentials to move from + /// + credentials_connection(_Inout_ credentials_connection &&other); + + /// + /// Copies credentials + /// + /// \param[in] other Credentials to copy from + /// + /// \returns Reference to this object + /// + credentials_connection& operator=(_In_ const credentials_connection &other); + + /// + /// Moves credentials + /// + /// \param[in] other Credentials to move from + /// + /// \returns Reference to this object + /// + credentials_connection& operator=(_Inout_ credentials_connection &&other); + + /// + /// Clones configuration + /// + /// \returns Pointer to cloned configuration + /// + virtual config* clone() const; + + /// \name XML configuration management + /// @{ + + /// + /// Save to XML document + /// + /// \param[in] pDoc XML document + /// \param[in] pConfigRoot Suggested root element for saving + /// + virtual void save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pConfigRoot) const; + + /// + /// Load from XML document + /// + /// \param[in] pConfigRoot Root element for loading + /// + virtual void load(_In_ IXMLDOMNode *pConfigRoot); + + /// @} + + /// \name BLOB management + /// @{ + + /// + /// Packs a configuration + /// + /// \param[inout] cursor Memory cursor + /// + virtual void operator<<(_Inout_ cursor_out &cursor) const; + + /// + /// Returns packed size of a configuration + /// + /// \returns Size of data when packed (in bytes) + /// + virtual size_t get_pk_size() const; + + /// + /// Unpacks a configuration + /// + /// \param[inout] cursor Memory cursor + /// + virtual void operator>>(_Inout_ cursor_in &cursor); + + /// @} + + public: + const config_connection& m_cfg; ///< Connection configuration + std::wstring m_id; ///< Provider ID + std::unique_ptr m_cred; ///< Credentials + }; } diff --git a/lib/EAPBase/src/Credentials.cpp b/lib/EAPBase/src/Credentials.cpp index 0fd554e..390037c 100644 --- a/lib/EAPBase/src/Credentials.cpp +++ b/lib/EAPBase/src/Credentials.cpp @@ -144,9 +144,9 @@ wstring eap::credentials::get_identity() const tstring eap::credentials::get_name() const { - if (empty()) return _T(""); + if (empty()) return _T(""); tstring identity(std::move(get_identity())); - return !identity.empty() ? identity : _T(""); + return !identity.empty() ? identity : _T(""); } @@ -415,3 +415,151 @@ const unsigned char eap::credentials_pass::s_entropy[1024] = { 0x30, 0x29, 0x39, 0x9a, 0xd6, 0xab, 0x2e, 0xc6, 0x42, 0x47, 0x5e, 0x54, 0xbb, 0x90, 0xe6, 0x98, 0xe6, 0x52, 0x58, 0x58, 0x1e, 0xd0, 0x00, 0x9c, 0x8f, 0x4a, 0x17, 0x7e, 0x8a, 0x5a, 0xef, 0x3e, }; + + +////////////////////////////////////////////////////////////////////// +// eap::credentials_connection +////////////////////////////////////////////////////////////////////// + +eap::credentials_connection::credentials_connection(_In_ module &mod, _In_ const config_connection &cfg) : + m_cfg(cfg), + config(mod) +{ +} + + +eap::credentials_connection::credentials_connection(_In_ const credentials_connection &other) : + m_cfg (other.m_cfg ), + m_id (other.m_id ), + m_cred(other.m_cred ? (credentials*)other.m_cred->clone() : nullptr), + config(other ) +{ +} + + +eap::credentials_connection::credentials_connection(_Inout_ credentials_connection &&other) : + m_cfg ( other.m_cfg ), + m_id (std::move(other.m_id )), + m_cred(std::move(other.m_cred)), + config(std::move(other )) +{ +} + + +eap::credentials_connection& eap::credentials_connection::operator=(_In_ const credentials_connection &other) +{ + if (this != &other) { + (config&)*this = other; + m_id = other.m_id; + m_cred.reset(other.m_cred ? (credentials*)other.m_cred->clone() : nullptr); + } + + return *this; +} + + +eap::credentials_connection& eap::credentials_connection::operator=(_Inout_ credentials_connection &&other) +{ + if (this != &other) { + (config&)*this = std::move(other ); + m_id = std::move(other.m_id ); + m_cred = std::move(other.m_cred); + } + + return *this; +} + + +eap::config* eap::credentials_connection::clone() const +{ + return new credentials_connection(*this); +} + + +void eap::credentials_connection::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pConfigRoot) const +{ + assert(pDoc); + assert(pConfigRoot); + + config::save(pDoc, pConfigRoot); + + HRESULT hr; + + // + if (FAILED(hr = eapxml::put_element_value(pDoc, pConfigRoot, bstr(L"IdentityProviderID"), namespace_eapmetadata, bstr(m_id)))) + throw com_runtime_error(hr, __FUNCTION__ " Error creating element."); + + m_cred->save(pDoc, pConfigRoot); +} + + +void eap::credentials_connection::load(_In_ IXMLDOMNode *pConfigRoot) +{ + assert(pConfigRoot); + HRESULT hr; + + config::load(pConfigRoot); + + std::wstring xpath(eapxml::get_xpath(pConfigRoot)); + + if (FAILED(hr = eapxml::get_element_value(pConfigRoot, bstr(L"eap-metadata:IdentityProviderID"), m_id))) + m_id.clear(); + + m_module.log_config((xpath + L"/IdentityProviderID").c_str(), m_id.c_str()); + + // Look-up the provider. + for (config_connection::provider_list::const_iterator cfg_prov = m_cfg.m_providers.cbegin(), cfg_prov_end = m_cfg.m_providers.cend(); ; ++cfg_prov) { + if (cfg_prov != cfg_prov_end) { + if (_wcsicmp(cfg_prov->m_id.c_str(), m_id.c_str()) == 0) { + // Matching provider found. Create matching blank credential set, then load. + if (cfg_prov->m_methods.empty()) + throw invalid_argument(string_printf(__FUNCTION__ " %ls provider has no methods.", cfg_prov->m_id.c_str()).c_str()); + const config_method_with_cred *cfg_method = dynamic_cast(cfg_prov->m_methods.front().get()); + m_cred.reset(cfg_method->make_credentials()); + m_cred->load(pConfigRoot); + break; + } + } else + throw invalid_argument(string_printf(__FUNCTION__ " Credentials do not match to any provider ID within this connection configuration (provider ID: %ls).", m_id.c_str()).c_str()); + } +} + + +void eap::credentials_connection::operator<<(_Inout_ cursor_out &cursor) const +{ + config::operator<<(cursor); + cursor << m_id ; + cursor << *m_cred; +} + + +size_t eap::credentials_connection::get_pk_size() const +{ + return + config::get_pk_size() + + pksizeof( m_id ) + + pksizeof(*m_cred); +} + + +void eap::credentials_connection::operator>>(_Inout_ cursor_in &cursor) +{ + config::operator>>(cursor); + cursor >> m_id; + + // Look-up the provider. + for (config_connection::provider_list::const_iterator cfg_prov = m_cfg.m_providers.cbegin(), cfg_prov_end = m_cfg.m_providers.cend(); ; ++cfg_prov) { + if (cfg_prov != cfg_prov_end) { + if (_wcsicmp(cfg_prov->m_id.c_str(), m_id.c_str()) == 0) { + // Matching provider found. Create matching blank credential set, then read. + if (cfg_prov->m_methods.empty()) + throw invalid_argument(string_printf(__FUNCTION__ " %ls provider has no methods.", cfg_prov->m_id.c_str()).c_str()); + const config_method_with_cred *cfg_method = dynamic_cast(cfg_prov->m_methods.front().get()); + m_cred.reset(cfg_method->make_credentials()); + cursor >> *m_cred; + break; + } + } else + throw invalid_argument(string_printf(__FUNCTION__ " Credentials do not match to any provider ID within this connection configuration (provider ID: %ls).", m_id.c_str()).c_str()); + } +} diff --git a/lib/EAPBase_UI/include/EAP_UI.h b/lib/EAPBase_UI/include/EAP_UI.h index f6916b6..d578ddc 100644 --- a/lib/EAPBase_UI/include/EAP_UI.h +++ b/lib/EAPBase_UI/include/EAP_UI.h @@ -43,10 +43,15 @@ template class wxEAPConfigDialog; class wxEAPGeneralDialog; /// -/// EAP top-most credential dialog +/// EAP method credential dialog /// class wxEAPCredentialsDialog; +/// +/// EAP connection credential dialog +/// +class wxEAPCredentialsConnectionDialog; + /// /// EAP general note /// @@ -342,6 +347,21 @@ public: }; +class wxEAPCredentialsConnectionDialog : public wxEAPCredentialsConnectionDialogBase +{ +public: + /// + /// Constructs a credential dialog + /// + wxEAPCredentialsConnectionDialog(wxWindow *parent, wxWindowID id = wxID_ANY, const wxString &title = _("EAP Credentials"), const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE); + +protected: + /// \cond internal + virtual void OnInitDialog(wxInitDialogEvent& event); + /// \endcond +}; + + class wxEAPNotePanel : public wxEAPNotePanelBase { public: @@ -701,10 +721,10 @@ protected: inline void UpdateOwnIdentity() { if (m_cred_own.empty()) - m_own_identity->SetValue(_("")); + m_own_identity->SetValue(_("")); else { wxString identity(m_cred_own.get_name()); - m_own_identity->SetValue(!identity.empty() ? identity : _("")); + m_own_identity->SetValue(!identity.empty() ? identity : _("")); } } @@ -712,10 +732,10 @@ protected: inline void UpdatePresharedIdentity() { if (m_cred_preshared.empty()) - m_preshared_identity->SetValue(_("")); + m_preshared_identity->SetValue(_("")); else { wxString identity(m_cred_preshared.get_name()); - m_preshared_identity->SetValue(!identity.empty() ? identity : _("")); + m_preshared_identity->SetValue(!identity.empty() ? identity : _("")); } } diff --git a/lib/EAPBase_UI/res/wxEAP_UI.cpp b/lib/EAPBase_UI/res/wxEAP_UI.cpp index 500eb5f..eaf9f0f 100644 --- a/lib/EAPBase_UI/res/wxEAP_UI.cpp +++ b/lib/EAPBase_UI/res/wxEAP_UI.cpp @@ -26,7 +26,7 @@ wxEAPConfigDialogBase::wxEAPConfigDialogBase( wxWindow* parent, wxWindowID id, c m_providers->SetExtraStyle( wxWS_EX_VALIDATE_RECURSIVELY ); - sb_content->Add( m_providers, 0, wxEXPAND|wxALL, 10 ); + sb_content->Add( m_providers, 1, wxEXPAND|wxALL, 10 ); wxBoxSizer* sb_bottom_horiz; sb_bottom_horiz = new wxBoxSizer( wxHORIZONTAL ); @@ -129,6 +129,48 @@ wxEAPGeneralDialogBase::~wxEAPGeneralDialogBase() } +wxEAPCredentialsConnectionDialogBase::wxEAPCredentialsConnectionDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* sb_content; + sb_content = new wxBoxSizer( wxVERTICAL ); + + m_banner = new wxEAPBannerPanel( this ); + + sb_content->Add( m_banner, 0, wxEXPAND|wxBOTTOM, 5 ); + + m_providers = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); + m_providers->SetExtraStyle( wxWS_EX_VALIDATE_RECURSIVELY ); + + + sb_content->Add( m_providers, 1, wxEXPAND | wxALL, 5 ); + + m_buttons = new wxStdDialogButtonSizer(); + m_buttonsOK = new wxButton( this, wxID_OK ); + m_buttons->AddButton( m_buttonsOK ); + m_buttonsCancel = new wxButton( this, wxID_CANCEL ); + m_buttons->AddButton( m_buttonsCancel ); + m_buttons->Realize(); + + sb_content->Add( m_buttons, 0, wxEXPAND|wxALL, 5 ); + + + this->SetSizer( sb_content ); + this->Layout(); + sb_content->Fit( this ); + + // Connect Events + this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( wxEAPCredentialsConnectionDialogBase::OnInitDialog ) ); +} + +wxEAPCredentialsConnectionDialogBase::~wxEAPCredentialsConnectionDialogBase() +{ + // Disconnect Events + this->Disconnect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( wxEAPCredentialsConnectionDialogBase::OnInitDialog ) ); + +} + wxEAPBannerPanelBase::wxEAPBannerPanelBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style ) { this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) ); diff --git a/lib/EAPBase_UI/res/wxEAP_UI.fbp b/lib/EAPBase_UI/res/wxEAP_UI.fbp index f9e9bde..c3215e6 100644 --- a/lib/EAPBase_UI/res/wxEAP_UI.fbp +++ b/lib/EAPBase_UI/res/wxEAP_UI.fbp @@ -47,7 +47,7 @@ wxDEFAULT_DIALOG_STYLE ; - EAP Method Configuration + EAP Connection Configuration @@ -181,7 +181,7 @@ 10 wxEXPAND|wxALL - 0 + 1 1 1 @@ -767,6 +767,270 @@ + + 0 + wxAUI_MGR_DEFAULT + + + + 1 + 1 + impl_virtual + + + + 0 + wxID_ANY + + + wxEAPCredentialsConnectionDialogBase + + + wxDEFAULT_DIALOG_STYLE + ; + EAP Credentials + + + + + + + + + + + + + + + + + + + + OnInitDialog + + + + + + + + + + + + + + + + + + + + + + + sb_content + wxVERTICAL + none + + 5 + wxEXPAND|wxBOTTOM + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + wxEAPBannerPanel + 1 + m_banner = new wxEAPBannerPanel( this ); + + 1 + wxEAPBannerPanel *m_banner; + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + class wxEAPBannerPanel; + + 0 + + + 0 + + 1 + m_banner + 1 + + + protected + 1 + + Resizable + + 1 + -1,-1 + ; ../include/EAP_UI.h + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND | wxALL + 1 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_providers + 1 + + + public + 1 + + Resizable + 1 + + + + 0 + + wxWS_EX_VALIDATE_RECURSIVELY + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 0 + + 0 + 1 + 0 + 0 + 0 + 1 + 0 + 0 + + m_buttons + protected + + + + + + + + + + + + 0 wxAUI_MGR_DEFAULT diff --git a/lib/EAPBase_UI/res/wxEAP_UI.h b/lib/EAPBase_UI/res/wxEAP_UI.h index f2e0162..d98143a 100644 --- a/lib/EAPBase_UI/res/wxEAP_UI.h +++ b/lib/EAPBase_UI/res/wxEAP_UI.h @@ -65,7 +65,7 @@ class wxEAPConfigDialogBase : public wxDialog public: - wxEAPConfigDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("EAP Method Configuration"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); + wxEAPConfigDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("EAP Connection Configuration"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); ~wxEAPConfigDialogBase(); }; @@ -95,6 +95,31 @@ class wxEAPGeneralDialogBase : public wxDialog }; +/////////////////////////////////////////////////////////////////////////////// +/// Class wxEAPCredentialsConnectionDialogBase +/////////////////////////////////////////////////////////////////////////////// +class wxEAPCredentialsConnectionDialogBase : public wxDialog +{ + private: + + protected: + wxEAPBannerPanel *m_banner; + wxStdDialogButtonSizer* m_buttons; + wxButton* m_buttonsOK; + wxButton* m_buttonsCancel; + + // Virtual event handlers, overide them in your derived class + virtual void OnInitDialog( wxInitDialogEvent& event ) { event.Skip(); } + + + public: + wxNotebook* m_providers; + + wxEAPCredentialsConnectionDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("EAP Credentials"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); + ~wxEAPCredentialsConnectionDialogBase(); + +}; + /////////////////////////////////////////////////////////////////////////////// /// Class wxEAPBannerPanelBase /////////////////////////////////////////////////////////////////////////////// diff --git a/lib/EAPBase_UI/src/EAP_UI.cpp b/lib/EAPBase_UI/src/EAP_UI.cpp index 9176937..ed1ffba 100644 --- a/lib/EAPBase_UI/src/EAP_UI.cpp +++ b/lib/EAPBase_UI/src/EAP_UI.cpp @@ -99,6 +99,44 @@ wxEAPCredentialsDialog::wxEAPCredentialsDialog(const eap::config_provider &prov, } +////////////////////////////////////////////////////////////////////// +// wxEAPCredentialsConnectionDialog +////////////////////////////////////////////////////////////////////// + +wxEAPCredentialsConnectionDialog::wxEAPCredentialsConnectionDialog(wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &pos, const wxSize &size, long style) : + wxEAPCredentialsConnectionDialogBase(parent, id, title, pos, size, style) +{ + // Set extra style here, as wxFormBuilder overrides all default flags. + this->SetExtraStyle(this->GetExtraStyle() | wxWS_EX_VALIDATE_RECURSIVELY); + + // Load window icons. +#ifdef __WINDOWS__ + wxIconBundle icons; + icons.AddIcon(wxIcon(wxT("product.ico"), wxBITMAP_TYPE_ICO_RESOURCE, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON))); + icons.AddIcon(wxIcon(wxT("product.ico"), wxBITMAP_TYPE_ICO_RESOURCE, ::GetSystemMetrics(SM_CXICON ), ::GetSystemMetrics(SM_CYICON ))); + this->SetIcons(icons); +#else + this->SetIcon(wxIcon(wxICON(product.ico))); +#endif + + // Set banner title. + m_banner->m_title->SetLabel(_("EAP Credentials")); + + m_buttonsOK->SetDefault(); +} + + +void wxEAPCredentialsConnectionDialog::OnInitDialog(wxInitDialogEvent& event) +{ + // Forward the event to child panels. + for (wxWindowList::compatibility_iterator provider = m_providers->GetChildren().GetFirst(); provider; provider = provider->GetNext()) { + wxWindow *prov = wxDynamicCast(provider->GetData(), wxWindow); + if (prov) + prov->GetEventHandler()->ProcessEvent(event); + } +} + + ////////////////////////////////////////////////////////////////////// // wxEAPNotePanel ////////////////////////////////////////////////////////////////////// diff --git a/lib/Events/res/EventsETW.man b/lib/Events/res/EventsETW.man index bb6628db46fb6c7c2e7de5f9058f77485771962d..bc2469f45da61e58935fcf887f72c81b71af2f48 100644 GIT binary patch delta 1202 zcmbVLUr1A76hFslE&pum>ZaL(t7J$n(b+?VU=9`Cb~j7=15qh%sf2S*O%Vx$9)zNV z1AV<^Q)`XL4kT`g+_2wWyna? zl9twANHqE0rvE2V2+*m=-W(UFu7DQ?pbL7bHr%a011@mzaKkyCtEhIijM5&MsV!*D zN?;)T&`lL#E#rM~l}9fO@mxhqk30FYr#apRPR>Q4qIn|)pBGZ|yek!hxUZm&0$ByL z5^0WVgJunBgA!Wl=bc=#1PiEb?gaT4^GKd%Z`7>GJSEXuRv}eT9ZiNaqX%cwH90MO zZ8rO|QbnxthE8IDqFv#a#?jRX@w#va@ z{ZP(3O?<9K1Q_Y#b-DTobYjg;_hY)oWZe?5iib|j7qSD>#i$c?H7aquo*gWxO2^4% z?gceDAMXwGT85o;+w!r}VWp~?FWxFxx<4LU0+q>eVpTy0TE*Q9Xgsd|GXJluHUJjW z>PD{kZbwN(n$VB&=vO+N}ealZ3kU*^V3@6&RxlaYk$)tIj1fqoVZ4S4%?!aB5KtYq3c4FS& m5{`?LPR{z%hJiveCNbi~N%66bQRNDbiFE@?uND-%XZ{0D3|%__ delta 239 zcmezLgZ0W4)(u<*n|+G5F;6a-$Tqp4O=xn%A+F7Q6>55u71juCUbc#hd9%}c7Us!* zTX{C$*!+iSvfpl@&3QX2Y}gGM^gwVj<3Z8QOkd|EPF`?;Wx8DyBj0qE5JsWt2~mt1 z(@PQi-7bbv3`tR03>HO`6Ltzr wpX3fSxh{@TV!A^DP|bx{#(9%ZtmOj m_method; ///< EAP-TTLS method // The following members are required to avoid memory leakage in get_result() diff --git a/lib/TTLS/src/Config.cpp b/lib/TTLS/src/Config.cpp index 2692c19..40690c1 100644 --- a/lib/TTLS/src/Config.cpp +++ b/lib/TTLS/src/Config.cpp @@ -212,7 +212,9 @@ const wchar_t* eap::config_method_ttls::get_method_str() const eap::credentials* eap::config_method_ttls::make_credentials() const { - return new credentials_ttls(m_module); + credentials_ttls *cred = new credentials_ttls(m_module); + cred->m_inner.reset(m_inner->make_credentials()); + return cred; } @@ -229,14 +231,10 @@ eap::config_method_with_cred* eap::config_method_ttls::make_config_method(_In_ w eap::config_method_with_cred* eap::config_method_ttls::make_config_method(_In_ const wchar_t *eap_type) const { - if (_wcsicmp(eap_type, L"EAP-TLS") == 0) - return new config_method_tls(m_module); - else if (_wcsicmp(eap_type, L"EAP-TTLS") == 0) - return new config_method_ttls(m_module); - else if (_wcsicmp(eap_type, L"PAP") == 0) - return new config_method_pap(m_module); - else - throw invalid_argument(__FUNCTION__ " Unsupported inner authentication method."); + if (_wcsicmp(eap_type, L"EAP-TLS" ) == 0) return new config_method_tls (m_module); + else if (_wcsicmp(eap_type, L"EAP-TTLS") == 0) return new config_method_ttls(m_module); + else if (_wcsicmp(eap_type, L"PAP" ) == 0) return new config_method_pap (m_module); + else throw invalid_argument(__FUNCTION__ " Unsupported inner authentication method."); } diff --git a/lib/TTLS/src/Credentials.cpp b/lib/TTLS/src/Credentials.cpp index d4771d4..90a8de6 100644 --- a/lib/TTLS/src/Credentials.cpp +++ b/lib/TTLS/src/Credentials.cpp @@ -103,6 +103,7 @@ void eap::credentials_ttls::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *p if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:InnerAuthenticationMethod"), bstr(L"InnerAuthenticationMethod"), namespace_eapmetadata, &pXmlElInnerAuthenticationMethod))) throw com_runtime_error(hr, __FUNCTION__ " Error creating element."); + // /... m_inner->save(pDoc, pXmlElInnerAuthenticationMethod); } diff --git a/lib/TTLS/src/Module.cpp b/lib/TTLS/src/Module.cpp index 43d023b..db35368 100644 --- a/lib/TTLS/src/Module.cpp +++ b/lib/TTLS/src/Module.cpp @@ -77,97 +77,28 @@ void eap::peer_ttls::get_identity( config_connection cfg(*this); unpack(cfg, pConnectionData, dwConnectionDataSize); - // Get method configuration. - if (cfg.m_providers.empty() || cfg.m_providers.front().m_methods.empty()) - throw invalid_argument(__FUNCTION__ " Configuration has no providers and/or methods."); - const config_provider &cfg_prov(cfg.m_providers.front()); - const config_method_ttls *cfg_method = dynamic_cast(cfg_prov.m_methods.front().get()); - assert(cfg_method); + // Combine credentials. + credentials_connection cred_out(*this, cfg); + const config_method_ttls *cfg_method = combine_credentials(dwFlags, cfg, pUserData, dwUserDataSize, cred_out, hTokenImpersonateUser); -#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE - // Unpack cached credentials. - credentials_ttls cred_in(*this); - if (dwUserDataSize) { - cred_in.m_inner.reset(cfg_method->m_inner->make_credentials()); - unpack(cred_in, pUserData, dwUserDataSize); - } -#else - UNREFERENCED_PARAMETER(pUserData); - UNREFERENCED_PARAMETER(dwUserDataSize); -#endif - - credentials_ttls cred_out(*this); - cred_out.m_inner.reset(cfg_method->m_inner->make_credentials()); - - // Assume no UI will be necessary. - *pfInvokeUI = FALSE; - - { - // Combine credentials. We could use eap::credentials_ttls() to do all the work, but we would not know which credentials is missing then. - user_impersonator impersonating(hTokenImpersonateUser); - - // Combine outer credentials. - LPCTSTR target_name = (dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? cfg_prov.m_id.c_str() : NULL; - eap::credentials::source_t src_outer = cred_out.credentials_tls::combine( -#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE - &cred_in, -#else - NULL, -#endif - *cfg_method, - target_name); - if (src_outer == eap::credentials::source_unknown) { - log_event(&EAPMETHOD_TRACE_EVT_CRED_INVOKE_UI1, event_data((unsigned int)eap_type_tls), event_data::blank); - *pfInvokeUI = TRUE; - } - - // Combine inner credentials. - eap::credentials::source_t src_inner = cred_out.m_inner->combine( -#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE - cred_in.m_inner.get(), -#else - NULL, -#endif - *cfg_method->m_inner, - target_name); - if (src_inner == eap::credentials::source_unknown) { - log_event(&EAPMETHOD_TRACE_EVT_CRED_INVOKE_UI1, event_data((unsigned int)cfg_method->m_inner->get_method_id()), event_data::blank); - *pfInvokeUI = TRUE; - } - } - - // If either of credentials is unknown, request UI. - if (*pfInvokeUI) { + if (cfg_method) { + // No UI will be necessary. + *pfInvokeUI = FALSE; + } else { + // Credentials missing or incomplete. if ((dwFlags & EAP_FLAG_MACHINE_AUTH) == 0) { - // Per-user authentication + // Per-user authentication, request UI. log_event(&EAPMETHOD_TRACE_EVT_CRED_INVOKE_UI2, event_data::blank); + *pfInvokeUI = TRUE; return; } else { - // Per-machine authentication + // Per-machine authentication, cannot use UI. throw win_runtime_error(ERROR_NO_SUCH_USER, __FUNCTION__ " Credentials for per-machine authentication not available."); } } - // If we got here, we have all credentials we need. But, wait! - - if ((dwFlags & EAP_FLAG_MACHINE_AUTH) == 0) { - if (cfg_method->m_auth_failed) { - // Outer: Credentials failed on last connection attempt. - log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM, event_data((unsigned int)eap_type_tls), event_data::blank); - *pfInvokeUI = TRUE; - return; - } - - if (cfg_method->m_inner->m_auth_failed) { - // Inner: Credentials failed on last connection attempt. - log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM, event_data((unsigned int)cfg_method->m_inner->get_method_id()), event_data::blank); - *pfInvokeUI = TRUE; - return; - } - } - // Build our identity. ;) - wstring identity(std::move(cfg_method->get_public_identity(cred_out))); + wstring identity(std::move(cfg_method->get_public_identity((const credentials_ttls&)*cred_out.m_cred))); log_event(&EAPMETHOD_TRACE_EVT_CRED_OUTER_ID1, event_data((unsigned int)eap_type_ttls), event_data(identity), event_data::blank); size_t size = sizeof(WCHAR)*(identity.length() + 1); *ppwszIdentity = (WCHAR*)alloc_memory(size); @@ -268,19 +199,26 @@ EAP_SESSION_HANDLE eap::peer_ttls::begin_session( // Unpack configuration. unpack(s->m_cfg, pConnectionData, dwConnectionDataSize); - // Get method configuration. - if (s->m_cfg.m_providers.empty() || s->m_cfg.m_providers.front().m_methods.empty()) - throw invalid_argument(__FUNCTION__ " Configuration has no providers and/or methods."); - config_provider &cfg_prov(s->m_cfg.m_providers.front()); - config_method_ttls *cfg_method = dynamic_cast(cfg_prov.m_methods.front().get()); - assert(cfg_method); - // Unpack credentials. - s->m_cred.m_inner.reset(cfg_method->m_inner->make_credentials()); unpack(s->m_cred, pUserData, dwUserDataSize); + config_method_ttls *cfg_method; + + for (config_connection::provider_list::iterator cfg_prov = s->m_cfg.m_providers.begin(), cfg_prov_end = s->m_cfg.m_providers.end();; ++cfg_prov) { + if (cfg_prov != cfg_prov_end) { + if (_wcsicmp(cfg_prov->m_id.c_str(), s->m_cred.m_id.c_str()) == 0) { + // Matching provider found. + if (cfg_prov->m_methods.empty()) + throw invalid_argument(string_printf(__FUNCTION__ " %ls provider has no methods.", cfg_prov->m_id.c_str()).c_str()); + cfg_method = dynamic_cast(cfg_prov->m_methods.front().get()); + break; + } + } else + throw invalid_argument(string_printf(__FUNCTION__ " Credentials do not match to any provider ID within this connection configuration (provider ID: %ls).", s->m_cred.m_id.c_str()).c_str()); + } + // We have configuration, we have credentials, create method. - s->m_method.reset(new method_ttls(*this, *cfg_method, s->m_cred)); + s->m_method.reset(new method_ttls(*this, *cfg_method, *(credentials_ttls*)s->m_cred.m_cred.get())); // Initialize method. s->m_method->begin_session(dwFlags, pAttributeArray, hTokenImpersonateUser, dwMaxSendPacketSize); @@ -401,6 +339,95 @@ void eap::peer_ttls::set_response_attributes( } +const eap::config_method_ttls* eap::peer_ttls::combine_credentials( + _In_ DWORD dwFlags, + _In_ const config_connection &cfg, + _In_count_(dwUserDataSize) const BYTE *pUserData, + _In_ DWORD dwUserDataSize, + _Out_ credentials_connection& cred_out, + _In_ HANDLE hTokenImpersonateUser) +{ +#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE + // Unpack cached credentials. + credentials_connection cred_in(*this, cfg); + if (dwUserDataSize) + unpack(cred_in, pUserData, dwUserDataSize); +#else + UNREFERENCED_PARAMETER(pUserData); + UNREFERENCED_PARAMETER(dwUserDataSize); +#endif + + user_impersonator impersonating(hTokenImpersonateUser); + + for (config_connection::provider_list::const_iterator cfg_prov = cfg.m_providers.cbegin(), cfg_prov_end = cfg.m_providers.cend(); cfg_prov != cfg_prov_end; ++cfg_prov) { + // Get method configuration. + if (cfg_prov->m_methods.empty()) { + log_event(&EAPMETHOD_TRACE_EVT_CRED_NO_METHOD, event_data(cfg_prov->m_id), event_data::blank); + continue; + } + const config_method_ttls *cfg_method = dynamic_cast(cfg_prov->m_methods.front().get()); + assert(cfg_method); + + // Combine credentials. We could use eap::credentials_ttls() to do all the work, but we would not know which credentials is missing then. + credentials_ttls *cred = (credentials_ttls*)cfg_method->make_credentials(); + cred_out.m_cred.reset(cred); +#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE + bool is_own = cred_in.m_cred && _wcsicmp(cred_in.m_id.c_str(), cfg_prov->m_id.c_str()) == 0; +#endif + + // Combine outer credentials. + LPCTSTR target_name = (dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? cfg_prov->m_id.c_str() : NULL; + eap::credentials::source_t src_outer = cred->credentials_tls::combine( +#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE + is_own ? cred_in.m_cred.get() : NULL, +#else + NULL, +#endif + *cfg_method, + target_name); + if (src_outer == eap::credentials::source_unknown) { + log_event(&EAPMETHOD_TRACE_EVT_CRED_UNKNOWN3, event_data(cfg_prov->m_id), event_data((unsigned int)eap_type_tls), event_data::blank); + continue; + } + + // Combine inner credentials. + eap::credentials::source_t src_inner = cred->m_inner->combine( +#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE + is_own ? ((credentials_ttls*)cred_in.m_cred.get())->m_inner.get() : NULL, +#else + NULL, +#endif + *cfg_method->m_inner, + target_name); + if (src_inner == eap::credentials::source_unknown) { + log_event(&EAPMETHOD_TRACE_EVT_CRED_UNKNOWN3, event_data(cfg_prov->m_id), event_data((unsigned int)cfg_method->m_inner->get_method_id()), event_data::blank); + continue; + } + + // If we got here, we have all credentials we need. But, wait! + + if ((dwFlags & EAP_FLAG_MACHINE_AUTH) == 0) { + if (cfg_method->m_auth_failed) { + // Outer: Credentials failed on last connection attempt. + log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM1, event_data(cfg_prov->m_id), event_data((unsigned int)eap_type_tls), event_data::blank); + continue; + } + + if (cfg_method->m_inner->m_auth_failed) { + // Inner: Credentials failed on last connection attempt. + log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM1, event_data(cfg_prov->m_id), event_data((unsigned int)cfg_method->m_inner->get_method_id()), event_data::blank); + continue; + } + } + + cred_out.m_id = cfg_prov->m_id; + return cfg_method; + } + + return NULL; +} + + ////////////////////////////////////////////////////////////////////// // eap::peer_ttls::session ////////////////////////////////////////////////////////////////////// @@ -408,7 +435,7 @@ void eap::peer_ttls::set_response_attributes( eap::peer_ttls::session::session(_In_ module &mod) : m_module(mod), m_cfg(mod), - m_cred(mod), + m_cred(mod, m_cfg), m_blob_cfg(NULL) #ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE , m_blob_cred(NULL) diff --git a/lib/TTLS_UI/src/Module.cpp b/lib/TTLS_UI/src/Module.cpp index 8e4d616..a8e5c32 100644 --- a/lib/TTLS_UI/src/Module.cpp +++ b/lib/TTLS_UI/src/Module.cpp @@ -151,51 +151,21 @@ void eap::peer_ttls_ui::invoke_identity_ui( config_connection cfg(*this); unpack(cfg, pConnectionData, dwConnectionDataSize); - // Get method configuration. - if (cfg.m_providers.empty() || cfg.m_providers.front().m_methods.empty()) - throw invalid_argument(__FUNCTION__ " Configuration has no providers and/or methods."); - const config_provider &cfg_prov(cfg.m_providers.front()); - config_method_ttls *cfg_method = dynamic_cast(cfg_prov.m_methods.front().get()); - assert(cfg_method); - #ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE // Unpack cached credentials. - credentials_ttls cred_in(*this); - if (dwUserDataSize) { - s->m_cred.m_inner.reset(cfg_method->m_inner->make_credentials()); + credentials_connection cred_in(*this, cfg); + if (dwUserDataSize) unpack(cred_in, pUserData, dwUserDataSize); - } #else UNREFERENCED_PARAMETER(pUserData); UNREFERENCED_PARAMETER(dwUserDataSize); #endif - credentials_ttls cred_out(*this); - cred_out.m_inner.reset(cfg_method->m_inner->make_credentials()); + credentials_connection cred_out(*this, cfg); + config_method_ttls *cfg_method = NULL; - // Combine credentials. Outer and inner separately to get the idea which one is missing. - eap::credentials::source_t cred_source = cred_out.credentials_tls::combine( -#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE - &cred_in, -#else - NULL, -#endif - *cfg_method, - (dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? cfg_prov.m_id.c_str() : NULL); - eap::credentials::source_t cred_source_inner = cred_out.m_inner->combine( -#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE - cred_in.m_inner.get(), -#else - NULL, -#endif - *cfg_method->m_inner, - (dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? cfg_prov.m_id.c_str() : NULL); - - if (dwFlags & EAP_FLAG_GUEST_ACCESS) { - // Disable credential saving for guests. - cfg_method->m_allow_save = false; - cfg_method->m_inner->m_allow_save = false; - } + vector > cred_method_store; + cred_method_store.reserve(cfg.m_providers.size()); int result; { @@ -209,39 +179,110 @@ void eap::peer_ttls_ui::invoke_identity_ui( parent.AdoptAttributesFromHWND(); wxTopLevelWindows.Append(&parent); - // Create credentials dialog. - wxEAPCredentialsDialog dlg(cfg_prov, &parent); - wxTTLSCredentialsPanel *panel = new wxTTLSCredentialsPanel(cfg_prov, *cfg_method, cred_out, cfg_prov.m_id.c_str(), &dlg); - dlg.AddContent(panel); + // Create credentials dialog and populate it with providers. + bool combined = false; + wxEAPCredentialsConnectionDialog dlg(&parent); + for (config_connection::provider_list::iterator cfg_prov = cfg.m_providers.begin(), cfg_prov_end = cfg.m_providers.end(); cfg_prov != cfg_prov_end; ++cfg_prov) { + // Get method configuration. + if (cfg_prov->m_methods.empty()) { + log_event(&EAPMETHOD_TRACE_EVT_CRED_NO_METHOD, event_data(cfg_prov->m_id), event_data::blank); + continue; + } + config_method_ttls *cfg_method = dynamic_cast(cfg_prov->m_methods.front().get()); + assert(cfg_method); - // Set "Remember" checkboxes according to credential source, - panel->m_outer_cred->SetRemember(cred_source == eap::credentials::source_storage); - panel->m_inner_cred->SetRemember(cred_source_inner == eap::credentials::source_storage); + // Prepare new set of credentials for given provider. + credentials_connection cred_method(*this, cfg); + cred_method.m_id = cfg_prov->m_id; + credentials_ttls *_cred_method = (credentials_ttls*)cfg_method->make_credentials(); + cred_method.m_cred.reset(_cred_method); +#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE + bool is_own = cred_in.m_cred && _wcsicmp(cred_in.m_id.c_str(), cfg_prov->m_id.c_str()) == 0; +#endif + + // Combine outer credentials. + LPCTSTR target_name = (dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? cfg_prov->m_id.c_str() : NULL; + eap::credentials::source_t src_outer = _cred_method->credentials_tls::combine( +#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE + is_own ? cred_in.m_cred.get() : NULL, +#else + NULL, +#endif + *cfg_method, + target_name); + + // Combine inner credentials. + eap::credentials::source_t src_inner = _cred_method->m_inner->combine( +#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE + is_own ? ((credentials_ttls*)cred_in.m_cred.get())->m_inner.get() : NULL, +#else + NULL, +#endif + *cfg_method->m_inner, + target_name); + + if (dwFlags & EAP_FLAG_GUEST_ACCESS) { + // Disable credential saving for guests. + cfg_method->m_allow_save = false; + cfg_method->m_inner->m_allow_save = false; + } + + // Create method credentials panel. + wxTTLSCredentialsPanel *panel = new wxTTLSCredentialsPanel(*cfg_prov, *cfg_method, *_cred_method, cfg_prov->m_id.c_str(), dlg.m_providers); + + // Set "Remember" checkboxes according to credential source, + panel->m_outer_cred->SetRemember(src_outer == eap::credentials::source_storage); + panel->m_inner_cred->SetRemember(src_inner == eap::credentials::source_storage); + + // Add panel to choice-book. Select the first one to have known sources. + if (!combined && src_outer != eap::credentials::source_unknown && src_inner != eap::credentials::source_unknown) { + if (dlg.m_providers->AddPage(panel, wxEAPGetProviderName(cfg_prov->m_name), true)) { + cred_method_store.push_back(pair(cfg_method, std::move(cred_method))); + combined = true; + } + } else + if (dlg.m_providers->AddPage(panel, wxEAPGetProviderName(cfg_prov->m_name), false)) + cred_method_store.push_back(pair(cfg_method, std::move(cred_method))); + } + + // Update dialog layout. + dlg.Layout(); + dlg.GetSizer()->Fit(&dlg); // Centre and display dialog. dlg.Centre(wxBOTH); result = dlg.ShowModal(); if (result == wxID_OK) { - // Write credentials to credential manager. - if (panel->m_outer_cred->GetRemember()) { - try { - cred_out.credentials_tls::store(cfg_prov.m_id.c_str()); - } catch (winstd::win_runtime_error &err) { - wxLogError(winstd::tstring_printf(_("Error writing credentials to Credential Manager: %hs (error %u)"), err.what(), err.number()).c_str()); - } catch (...) { - wxLogError(_("Writing credentials failed.")); - } - } + int idx_prov = dlg.m_providers->GetSelection(); + if (idx_prov != wxNOT_FOUND) { + wxTTLSCredentialsPanel *panel = dynamic_cast(dlg.m_providers->GetPage(idx_prov)); + pair &res = cred_method_store[idx_prov]; + cfg_method = res.first; + cred_out = res.second; + credentials_ttls *_cred_out = dynamic_cast(cred_out.m_cred.get()); - if (panel->m_inner_cred->GetRemember()) { - try { - cred_out.m_inner->store(cfg_prov.m_id.c_str()); - } catch (winstd::win_runtime_error &err) { - wxLogError(winstd::tstring_printf(_("Error writing credentials to Credential Manager: %hs (error %u)"), err.what(), err.number()).c_str()); - } catch (...) { - wxLogError(_("Writing credentials failed.")); + // Write credentials to credential manager. + if (panel->m_outer_cred->GetRemember()) { + try { + _cred_out->credentials_tls::store(cred_out.m_id.c_str()); + } catch (winstd::win_runtime_error &err) { + wxLogError(winstd::tstring_printf(_("Error writing credentials to Credential Manager: %hs (error %u)"), err.what(), err.number()).c_str()); + } catch (...) { + wxLogError(_("Writing credentials failed.")); + } } - } + + if (panel->m_inner_cred->GetRemember()) { + try { + _cred_out->m_inner->store(cred_out.m_id.c_str()); + } catch (winstd::win_runtime_error &err) { + wxLogError(winstd::tstring_printf(_("Error writing credentials to Credential Manager: %hs (error %u)"), err.what(), err.number()).c_str()); + } catch (...) { + wxLogError(_("Writing credentials failed.")); + } + } + } else + result = wxID_CANCEL; } wxTopLevelWindows.DeleteObject(&parent); @@ -253,7 +294,7 @@ void eap::peer_ttls_ui::invoke_identity_ui( throw win_runtime_error(ERROR_CANCELLED, __FUNCTION__ " Cancelled."); // Build our identity. ;) - wstring identity(move(cfg_method->get_public_identity(cred_out))); + wstring identity(std::move(cfg_method->get_public_identity((const credentials_ttls&)*cred_out.m_cred))); log_event(&EAPMETHOD_TRACE_EVT_CRED_OUTER_ID1, event_data((unsigned int)eap_type_ttls), event_data(identity), event_data::blank); size_t size = sizeof(WCHAR)*(identity.length() + 1); *ppwszIdentity = (WCHAR*)alloc_memory(size);