From fc5e54db05b529453ef1073fb48b4dad5d709274 Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Sun, 28 Aug 2016 17:20:24 +0200 Subject: [PATCH] Inner configuration/credential management virtualized to reduce cluttering code --- lib/EAPBase/include/Config.h | 10 +++ lib/EAPBase/include/Credentials.h | 21 ++++++ lib/PAP/include/Config.h | 10 +++ lib/PAP/include/Credentials.h | 17 ++--- lib/PAP/src/Config.cpp | 12 ++++ lib/PAP/src/Credentials.cpp | 8 +-- lib/TLS/include/Config.h | 10 +++ lib/TLS/include/Credentials.h | 17 ++--- lib/TLS/src/Config.cpp | 12 ++++ lib/TLS/src/Credentials.cpp | 8 +-- lib/TTLS/include/Config.h | 25 ++++++- lib/TTLS/include/Credentials.h | 19 +++--- lib/TTLS/src/Config.cpp | 107 ++++++++++++++++++------------ lib/TTLS/src/Credentials.cpp | 80 ++++++++-------------- lib/TTLS/src/Module.cpp | 37 ++++++----- lib/TTLS/src/StdAfx.h | 3 + lib/TTLS_UI/include/TTLS_UI.h | 1 + lib/TTLS_UI/src/Module.cpp | 26 +++++--- lib/WinStd | 2 +- 19 files changed, 270 insertions(+), 155 deletions(-) diff --git a/lib/EAPBase/include/Config.h b/lib/EAPBase/include/Config.h index 417396c..00c1d23 100644 --- a/lib/EAPBase/include/Config.h +++ b/lib/EAPBase/include/Config.h @@ -243,6 +243,11 @@ namespace eap /// \returns One of `winstd::eap_type_t` constants. /// virtual winstd::eap_type_t get_method_id() const = 0; + + /// + /// Returns a string identifier of the EAP method type of this configuration + /// + virtual const wchar_t* get_method_str() const = 0; }; @@ -337,6 +342,11 @@ namespace eap /// @} + /// + /// Creates a blank set of credentials suitable for this method + /// + virtual credentials* make_credentials() const = 0; + public: bool m_allow_save; ///< Are credentials allowed to be saved to Windows Credential Manager? bool m_use_preshared; ///< Use pre-shared credentials diff --git a/lib/EAPBase/include/Credentials.h b/lib/EAPBase/include/Credentials.h index 25f5679..cc3f50e 100644 --- a/lib/EAPBase/include/Credentials.h +++ b/lib/EAPBase/include/Credentials.h @@ -217,6 +217,27 @@ namespace eap /// virtual winstd::tstring get_name() const; + /// + /// Combine credentials in the following order: + /// + /// 1. Cached credentials + /// 2. Pre-configured credentials + /// 3. Stored credentials + /// + /// \param[in] cred_cached Cached credentials (optional, can be \c NULL, must be the same type of credentials as `this`) + /// \param[in] cfg Method configuration (must be the same type of configuration as `this` credentials belong to) + /// \param[in] pszTargetName The name in Windows Credential Manager to retrieve credentials from (optional, can be \c NULL) + /// + /// \returns + /// - \c source_cache Credentials were obtained from EapHost cache + /// - \c source_preshared Credentials were set by method configuration + /// - \c source_storage Credentials were loaded from Windows Credential Manager + /// + virtual source_t combine( + _In_ const credentials *cred_cached, + _In_ const config_method_with_cred &cfg, + _In_opt_z_ LPCTSTR pszTargetName) = 0; + public: std::wstring m_identity; ///< Identity (username\@domain, certificate name etc.) }; diff --git a/lib/PAP/include/Config.h b/lib/PAP/include/Config.h index dd1c144..348f141 100644 --- a/lib/PAP/include/Config.h +++ b/lib/PAP/include/Config.h @@ -95,5 +95,15 @@ namespace eap /// \returns `eap::type_pap` /// virtual winstd::eap_type_t get_method_id() const; + + /// + /// Returns a string \c L"PAP" + /// + virtual const wchar_t* get_method_str() const; + + /// + /// Creates a blank set of credentials suitable for this method + /// + virtual credentials* make_credentials() const; }; } diff --git a/lib/PAP/include/Credentials.h b/lib/PAP/include/Credentials.h index 1c73db3..f0f4cd8 100644 --- a/lib/PAP/include/Credentials.h +++ b/lib/PAP/include/Credentials.h @@ -105,17 +105,18 @@ namespace eap /// 2. Pre-configured credentials /// 3. Stored credentials /// - /// \param[in] cred_cached Cached credentials (optional, can be \c NULL) - /// \param[in] cfg Method configuration + /// \param[in] cred_cached Cached credentials (optional, can be \c NULL, must be credentials_pap* type) + /// \param[in] cfg Method configuration (must be config_method_pap type) /// \param[in] pszTargetName The name in Windows Credential Manager to retrieve credentials from (optional, can be \c NULL) /// /// \returns - /// - \c true if credentials were set; - /// - \c false otherwise + /// - \c source_cache Credentials were obtained from EapHost cache + /// - \c source_preshared Credentials were set by method configuration + /// - \c source_storage Credentials were loaded from Windows Credential Manager /// - source_t combine( - _In_ const credentials_pap *cred_cached, - _In_ const config_method_pap &cfg, - _In_opt_z_ LPCTSTR pszTargetName); + virtual source_t combine( + _In_ const credentials *cred_cached, + _In_ const config_method_with_cred &cfg, + _In_opt_z_ LPCTSTR pszTargetName); }; } diff --git a/lib/PAP/src/Config.cpp b/lib/PAP/src/Config.cpp index ec326c5..2e3fdca 100644 --- a/lib/PAP/src/Config.cpp +++ b/lib/PAP/src/Config.cpp @@ -74,3 +74,15 @@ eap_type_t eap::config_method_pap::get_method_id() const { return eap_type_pap; } + + +const wchar_t* eap::config_method_pap::get_method_str() const +{ + return L"PAP"; +} + + +eap::credentials* eap::config_method_pap::make_credentials() const +{ + return new credentials_pap(m_module); +} diff --git a/lib/PAP/src/Credentials.cpp b/lib/PAP/src/Credentials.cpp index 9c6382f..1df5a5b 100644 --- a/lib/PAP/src/Credentials.cpp +++ b/lib/PAP/src/Credentials.cpp @@ -76,13 +76,13 @@ LPCTSTR eap::credentials_pap::target_suffix() const eap::credentials::source_t eap::credentials_pap::combine( - _In_ const credentials_pap *cred_cached, - _In_ const config_method_pap &cfg, - _In_opt_z_ LPCTSTR pszTargetName) + _In_ const credentials *cred_cached, + _In_ const config_method_with_cred &cfg, + _In_opt_z_ LPCTSTR pszTargetName) { if (cred_cached) { // Using EAP service cached credentials. - *this = *cred_cached; + *this = *(credentials_pap*)cred_cached; m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_CACHED1, event_data((unsigned int)eap_type_pap), event_data(credentials_pap::get_name()), event_data::blank); return source_cache; } diff --git a/lib/TLS/include/Config.h b/lib/TLS/include/Config.h index 78a42db..5154d02 100644 --- a/lib/TLS/include/Config.h +++ b/lib/TLS/include/Config.h @@ -162,6 +162,16 @@ namespace eap /// virtual winstd::eap_type_t get_method_id() const; + /// + /// Returns a string \c L"EAP-TLS" + /// + virtual const wchar_t* get_method_str() const; + + /// + /// Creates a blank set of credentials suitable for this method + /// + virtual credentials* make_credentials() const; + /// /// Adds CA to the list of trusted root CA's /// diff --git a/lib/TLS/include/Credentials.h b/lib/TLS/include/Credentials.h index 64e70a8..4554698 100644 --- a/lib/TLS/include/Credentials.h +++ b/lib/TLS/include/Credentials.h @@ -187,18 +187,19 @@ namespace eap /// 2. Pre-configured credentials /// 3. Stored credentials /// - /// \param[in] cred_cached Cached credentials (optional, can be \c NULL) - /// \param[in] cfg Method configuration + /// \param[in] cred_cached Cached credentials (optional, can be \c NULL, must be credentials_tls* type) + /// \param[in] cfg Method configuration (must be config_method_tls type) /// \param[in] pszTargetName The name in Windows Credential Manager to retrieve credentials from (optional, can be \c NULL) /// /// \returns - /// - \c true if credentials were set; - /// - \c false otherwise + /// - \c source_cache Credentials were obtained from EapHost cache + /// - \c source_preshared Credentials were set by method configuration + /// - \c source_storage Credentials were loaded from Windows Credential Manager /// - source_t combine( - _In_ const credentials_tls *cred_cached, - _In_ const config_method_tls &cfg, - _In_opt_z_ LPCTSTR pszTargetName); + virtual source_t combine( + _In_ const credentials *cred_cached, + _In_ const config_method_with_cred &cfg, + _In_opt_z_ LPCTSTR pszTargetName); public: winstd::cert_context m_cert; ///< Client certificate diff --git a/lib/TLS/src/Config.cpp b/lib/TLS/src/Config.cpp index a07ed20..50d13bc 100644 --- a/lib/TLS/src/Config.cpp +++ b/lib/TLS/src/Config.cpp @@ -292,6 +292,18 @@ eap_type_t eap::config_method_tls::get_method_id() const } +const wchar_t* eap::config_method_tls::get_method_str() const +{ + return L"EAP-TLS"; +} + + +eap::credentials* eap::config_method_tls::make_credentials() const +{ + return new credentials_tls(m_module); +} + + bool eap::config_method_tls::add_trusted_ca(_In_ DWORD dwCertEncodingType, _In_ const BYTE *pbCertEncoded, _In_ DWORD cbCertEncoded) { cert_context cert; diff --git a/lib/TLS/src/Credentials.cpp b/lib/TLS/src/Credentials.cpp index bdfeac2..9a2df46 100644 --- a/lib/TLS/src/Credentials.cpp +++ b/lib/TLS/src/Credentials.cpp @@ -257,13 +257,13 @@ std::wstring eap::credentials_tls::get_identity() const eap::credentials::source_t eap::credentials_tls::combine( - _In_ const credentials_tls *cred_cached, - _In_ const config_method_tls &cfg, - _In_opt_z_ LPCTSTR pszTargetName) + _In_ const credentials *cred_cached, + _In_ const config_method_with_cred &cfg, + _In_opt_z_ LPCTSTR pszTargetName) { if (cred_cached) { // Using EAP service cached credentials. - *this = *cred_cached; + *this = *(credentials_tls*)cred_cached; m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_CACHED1, event_data((unsigned int)eap_type_tls), event_data(credentials_tls::get_name()), event_data::blank); return source_cache; } diff --git a/lib/TTLS/include/Config.h b/lib/TTLS/include/Config.h index 2140d84..6641b2a 100644 --- a/lib/TTLS/include/Config.h +++ b/lib/TTLS/include/Config.h @@ -33,7 +33,6 @@ namespace eap #include "Credentials.h" #include "../../TLS/include/Config.h" -#include "../../PAP/include/Config.h" #include #include @@ -142,6 +141,30 @@ namespace eap { /// virtual winstd::eap_type_t get_method_id() const; + /// + /// Returns a string \c L"EAP-TTLS" + /// + virtual const wchar_t* get_method_str() const; + + /// + /// Creates a blank set of credentials suitable for this method + /// + virtual credentials* make_credentials() const; + + /// + /// Makes a new inner method config + /// + /// \param[in] eap_type EAP type + /// + config_method_with_cred* make_config_method(_In_ winstd::eap_type_t eap_type) const; + + /// + /// Makes a new inner method config + /// + /// \param[in] eap_type EAP type + /// + config_method_with_cred* make_config_method(_In_ const wchar_t *eap_type) const; + /// /// Generates public identity using current configuration and given credentials /// diff --git a/lib/TTLS/include/Credentials.h b/lib/TTLS/include/Credentials.h index b3e11dc..370def2 100644 --- a/lib/TTLS/include/Credentials.h +++ b/lib/TTLS/include/Credentials.h @@ -29,10 +29,8 @@ namespace eap #pragma once #include "../../TLS/include/Credentials.h" -#include "../../PAP/include/Credentials.h" #include -#include namespace eap @@ -180,18 +178,19 @@ namespace eap /// 2. Pre-configured credentials /// 3. Stored credentials /// - /// \param[in] cred_cached Cached credentials (optional, can be \c NULL) - /// \param[in] cfg Method configuration + /// \param[in] cred_cached Cached credentials (optional, can be \c NULL, must be credentials_ttls* type) + /// \param[in] cfg Method configuration (must be config_method_ttls type) /// \param[in] pszTargetName The name in Windows Credential Manager to retrieve credentials from (optional, can be \c NULL) /// /// \returns - /// - \c true if credentials were set; - /// - \c false otherwise + /// - \c source_cache Credentials were obtained from EapHost cache + /// - \c source_preshared Credentials were set by method configuration + /// - \c source_storage Credentials were loaded from Windows Credential Manager /// - std::pair combine( - _In_ const credentials_ttls *cred_cached, - _In_ const config_method_ttls &cfg, - _In_opt_z_ LPCTSTR pszTargetName); + virtual source_t combine( + _In_ const credentials *cred_cached, + _In_ const config_method_with_cred &cfg, + _In_opt_z_ LPCTSTR pszTargetName); public: std::unique_ptr m_inner; ///< Inner credentials diff --git a/lib/TTLS/src/Config.cpp b/lib/TTLS/src/Config.cpp index b9f9ed7..7f7608b 100644 --- a/lib/TTLS/src/Config.cpp +++ b/lib/TTLS/src/Config.cpp @@ -105,15 +105,19 @@ void eap::config_method_ttls::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:InnerAuthenticationMethod"), bstr(L"InnerAuthenticationMethod"), bstrNamespace, &pXmlElInnerAuthenticationMethod))) throw com_runtime_error(hr, __FUNCTION__ " Error creating element."); - if (dynamic_cast(m_inner.get())) { + eap_type_t eap_type = m_inner->get_method_id(); + if (eap_type_noneap_start <= eap_type && eap_type < eap_type_noneap_end) { // / - if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElInnerAuthenticationMethod, bstr(L"NonEAPAuthMethod"), bstrNamespace, bstr(L"PAP")))) + if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElInnerAuthenticationMethod, bstr(L"NonEAPAuthMethod"), bstrNamespace, bstr(m_inner->get_method_str())))) throw com_runtime_error(hr, __FUNCTION__ " Error creating element."); + } else { + // / + if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElInnerAuthenticationMethod, bstr(L"EAPMethod"), bstrNamespace, (DWORD)m_inner->get_method_id()))) + throw com_runtime_error(hr, __FUNCTION__ " Error creating element."); + } - // /... - m_inner->save(pDoc, pXmlElInnerAuthenticationMethod); - } else - throw win_runtime_error(ERROR_NOT_SUPPORTED, __FUNCTION__ " Unsupported inner authentication method."); + // /... + m_inner->save(pDoc, pXmlElInnerAuthenticationMethod); } @@ -144,23 +148,20 @@ void eap::config_method_ttls::load(_In_ IXMLDOMNode *pConfigRoot) throw com_runtime_error(hr, __FUNCTION__ " Error selecting element."); // Determine inner authentication type ( and ). - //DWORD dwMethodID; + DWORD dwMethod; bstr bstrMethod; - /*if (SUCCEEDED(eapxml::get_element_value(pXmlElInnerAuthenticationMethod, bstr(L"eap-metadata:EAPMethod"), &dwMethodID)) && - dwMethodID == EAP_TYPE_MSCHAPV2) + if (SUCCEEDED(eapxml::get_element_value(pXmlElInnerAuthenticationMethod, bstr(L"eap-metadata:EAPMethod"), &dwMethod)) && + eap_type_start <= dwMethod && dwMethod < eap_type_end) { - // MSCHAPv2 - // TODO: Add MSCHAPv2 support. - throw win_runtime_error(ERROR_NOT_SUPPORTED, __FUNCTION__ " MSCHAPv2 not supported yet."); - } else*/ if (SUCCEEDED(eapxml::get_element_value(pXmlElInnerAuthenticationMethod, bstr(L"eap-metadata:NonEAPAuthMethod"), &bstrMethod)) && - CompareStringEx(LOCALE_NAME_INVARIANT, NORM_IGNORECASE, bstrMethod, bstrMethod.length(), L"PAP", -1, NULL, NULL, 0) == CSTR_EQUAL) - { - // PAP - m_module.log_config((xpath + L"/NonEAPAuthMethod").c_str(), L"PAP"); - m_inner.reset(new config_method_pap(m_module)); - m_inner->load(pXmlElInnerAuthenticationMethod); + m_inner.reset(make_config_method((eap_type_t)dwMethod)); + m_module.log_config((xpath + L"/EAPMethod").c_str(), m_inner->get_method_str()); + } else if (SUCCEEDED(eapxml::get_element_value(pXmlElInnerAuthenticationMethod, bstr(L"eap-metadata:NonEAPAuthMethod"), &bstrMethod))) { + m_inner.reset(make_config_method(bstrMethod)); + m_module.log_config((xpath + L"/NonEAPAuthMethod").c_str(), m_inner->get_method_str()); } else throw win_runtime_error(ERROR_NOT_SUPPORTED, __FUNCTION__ " Unsupported inner authentication method."); + + m_inner->load(pXmlElInnerAuthenticationMethod); } @@ -169,13 +170,8 @@ void eap::config_method_ttls::operator<<(_Inout_ cursor_out &cursor) const config_method_tls::operator<<(cursor); if (m_inner) { - if (dynamic_cast(m_inner.get())) { - cursor << eap_type_pap; - cursor << *m_inner; - } else { - assert(0); // Unsupported inner authentication method type. - cursor << eap_type_undefined; - } + cursor << m_inner->get_method_id(); + cursor << *m_inner; } else cursor << eap_type_undefined; @@ -187,14 +183,9 @@ size_t eap::config_method_ttls::get_pk_size() const { size_t size_inner; if (m_inner) { - if (dynamic_cast(m_inner.get())) { - size_inner = - pksizeof(eap_type_pap) + - pksizeof(*m_inner); - } else { - assert(0); // Unsupported inner authentication method type. - size_inner = pksizeof(eap_type_undefined); - } + size_inner = + pksizeof(m_inner->get_method_id()) + + pksizeof(*m_inner); } else size_inner = pksizeof(eap_type_undefined); @@ -211,16 +202,10 @@ void eap::config_method_ttls::operator>>(_Inout_ cursor_in &cursor) eap_type_t eap_type; cursor >> eap_type; - switch (eap_type) { - case eap_type_pap: - m_inner.reset(new config_method_pap(m_module)); - cursor >> *m_inner; - break; - default: - assert(0); // Unsupported inner authentication method type. - m_inner.reset(nullptr); + if (eap_type != eap_type_undefined) { + m_inner.reset(make_config_method(eap_type)); + cursor >> *m_inner; } - cursor >> m_anonymous_identity; } @@ -231,6 +216,42 @@ eap_type_t eap::config_method_ttls::get_method_id() const } +const wchar_t* eap::config_method_ttls::get_method_str() const +{ + return L"EAP-TTLS"; +} + + +eap::credentials* eap::config_method_ttls::make_credentials() const +{ + return new credentials_ttls(m_module); +} + + +eap::config_method_with_cred* eap::config_method_ttls::make_config_method(_In_ winstd::eap_type_t eap_type) const +{ + switch (eap_type) { + case eap_type_tls : return new config_method_tls (m_module); + case eap_type_ttls: return new config_method_ttls(m_module); + case eap_type_pap : return new config_method_pap (m_module); + default : throw invalid_argument(__FUNCTION__ " Unsupported inner authentication method."); + } +} + + +eap::config_method_with_cred* eap::config_method_ttls::make_config_method(_In_ const wchar_t *eap_type) const +{ + if (_wcsicmp(eap_type, L"EAP-TLS") == 0) + return new config_method_tls(m_module); + else if (_wcsicmp(eap_type, L"EAP-TTLS") == 0) + return new config_method_ttls(m_module); + else if (_wcsicmp(eap_type, L"PAP") == 0) + return new config_method_pap(m_module); + else + throw invalid_argument(__FUNCTION__ " Unsupported inner authentication method."); +} + + wstring eap::config_method_ttls::get_public_identity(const credentials_ttls &cred) const { if (m_anonymous_identity.empty()) { diff --git a/lib/TTLS/src/Credentials.cpp b/lib/TTLS/src/Credentials.cpp index e5f9aff..dec87e8 100644 --- a/lib/TTLS/src/Credentials.cpp +++ b/lib/TTLS/src/Credentials.cpp @@ -121,8 +121,8 @@ void eap::credentials_ttls::load(_In_ IXMLDOMNode *pConfigRoot) credentials_tls::load(pConfigRoot); - // TODO: For the time being, there is no detection what type is inner method. Introduce one! if (m_inner) { + // Load inner credentials. com_obj pXmlElInnerAuthenticationMethod; if (FAILED(hr = eapxml::select_node(pConfigRoot, bstr(L"eap-metadata:InnerAuthenticationMethod"), &pXmlElInnerAuthenticationMethod))) throw com_runtime_error(hr, __FUNCTION__ " Error selecting element."); @@ -135,55 +135,22 @@ void eap::credentials_ttls::load(_In_ IXMLDOMNode *pConfigRoot) void eap::credentials_ttls::operator<<(_Inout_ cursor_out &cursor) const { credentials_tls::operator<<(cursor); - if (m_inner) { - if (dynamic_cast(m_inner.get())) { - cursor << eap_type_pap; - cursor << *m_inner; - } else { - assert(0); // Unsupported inner authentication method type. - cursor << eap_type_undefined; - } - } else - cursor << eap_type_undefined; + cursor << *m_inner; } size_t eap::credentials_ttls::get_pk_size() const { - size_t size_inner; - if (m_inner) { - if (dynamic_cast(m_inner.get())) { - size_inner = - pksizeof(eap_type_pap) + - pksizeof(*m_inner); - } else { - assert(0); // Unsupported inner authentication method type. - size_inner = pksizeof(eap_type_undefined); - } - } else - size_inner = pksizeof(eap_type_undefined); - return credentials_tls::get_pk_size() + - size_inner; + pksizeof(*m_inner); } void eap::credentials_ttls::operator>>(_Inout_ cursor_in &cursor) { credentials_tls::operator>>(cursor); - - eap_type_t eap_type; - cursor >> eap_type; - switch (eap_type) { - case eap_type_pap: - m_inner.reset(new credentials_pap(m_module)); - cursor >> *m_inner; - break; - default: - assert(0); // Unsupported inner authentication method type. - m_inner.reset(nullptr); - } + cursor >> *m_inner; } @@ -193,8 +160,7 @@ void eap::credentials_ttls::store(_In_z_ LPCTSTR pszTargetName) const credentials_tls::store(pszTargetName); - if (m_inner) - m_inner->store(pszTargetName); + m_inner->store(pszTargetName); } @@ -204,8 +170,7 @@ void eap::credentials_ttls::retrieve(_In_z_ LPCTSTR pszTargetName) credentials_tls::retrieve(pszTargetName); - if (m_inner) - m_inner->retrieve(pszTargetName); + m_inner->retrieve(pszTargetName); } @@ -224,19 +189,30 @@ wstring eap::credentials_ttls::get_identity() const return identity; // Inner identity. - if (m_inner) - return m_inner->get_identity(); - - return L""; + return m_inner->get_identity(); } -pair eap::credentials_ttls::combine( - _In_ const credentials_ttls *cred_cached, - _In_ const config_method_ttls &cfg, - _In_opt_z_ LPCTSTR pszTargetName) +eap::credentials::source_t eap::credentials_ttls::combine( + _In_ const credentials *cred_cached, + _In_ const config_method_with_cred &cfg, + _In_opt_z_ LPCTSTR pszTargetName) { - return pair( - credentials_tls::combine(cred_cached, cfg, pszTargetName), - dynamic_cast(m_inner.get()) ? ((credentials_pap*)m_inner.get())->combine(cred_cached ? (credentials_pap*)cred_cached->m_inner.get() : NULL, (const config_method_pap&)*cfg.m_inner, pszTargetName) : source_unknown); + source_t src; + + // Combine outer credentials first. + src = credentials_tls::combine( + cred_cached, + cfg, + pszTargetName); + if (src == source_unknown) { + // Outer credentials are unknown. Enough unknowness. + return source_unknown; + } + + // Combine inner credentials. + return m_inner->combine( + cred_cached ? ((const credentials_ttls*)cred_cached)->m_inner.get() : NULL, + *((const config_method_ttls&)cfg).m_inner, + pszTargetName); } diff --git a/lib/TTLS/src/Module.cpp b/lib/TTLS/src/Module.cpp index 7240dcc..bf4a98d 100644 --- a/lib/TTLS/src/Module.cpp +++ b/lib/TTLS/src/Module.cpp @@ -76,10 +76,10 @@ void eap::peer_ttls::get_identity( // Unpack configuration. config_connection cfg(*this); unpack(cfg, pConnectionData, dwConnectionDataSize); - if (cfg.m_providers.empty() || cfg.m_providers.front().m_methods.empty()) - throw invalid_argument(__FUNCTION__ " Configuration has no providers and/or methods."); // Get method configuration. + 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); @@ -87,39 +87,36 @@ void eap::peer_ttls::get_identity( #ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE // Unpack cached credentials. credentials_ttls cred_in(*this); - if (dwUserDataSize) + if (dwUserDataSize) { + cred_in.m_inner.reset(cfg_method->m_inner->make_credentials()); unpack(cred_in, pUserData, dwUserDataSize); + } #else UNREFERENCED_PARAMETER(pUserData); UNREFERENCED_PARAMETER(dwUserDataSize); #endif credentials_ttls cred_out(*this); + cred_out.m_inner.reset(cfg_method->m_inner->make_credentials()); - // Determine inner credential type. - eap_type_t type_inner; - if (dynamic_cast(cfg_method->m_inner.get())) { - cred_out.m_inner.reset(new credentials_pap(*this)); - type_inner = eap_type_pap; - } else { - assert(0); // Unsupported inner authentication method type. - type_inner = eap_type_undefined; - } + // Assume no UI will be necessary. + *pfInvokeUI = FALSE; { // Combine credentials. user_impersonator impersonating(hTokenImpersonateUser); - pair cred_source(cred_out.combine( + eap::credentials::source_t cred_source = cred_out.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)); + (dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? cfg_prov.m_id.c_str() : NULL); // If either of credentials is unknown, request UI. - *pfInvokeUI = cred_source.first == eap::credentials::source_unknown || cred_source.second == eap::credentials::source_unknown ? TRUE : FALSE; + if (cred_source == eap::credentials::source_unknown) + *pfInvokeUI = TRUE; } if (*pfInvokeUI) { @@ -144,7 +141,7 @@ void eap::peer_ttls::get_identity( 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)type_inner), event_data::blank); + log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM, event_data((unsigned int)cfg_method->m_inner->get_method_id()), event_data::blank); *pfInvokeUI = TRUE; return; } @@ -251,7 +248,15 @@ 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."); + const config_provider &cfg_prov(s->m_cfg.m_providers.front()); + const 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); // Initialize method. diff --git a/lib/TTLS/src/StdAfx.h b/lib/TTLS/src/StdAfx.h index 8602e9a..daa33fe 100644 --- a/lib/TTLS/src/StdAfx.h +++ b/lib/TTLS/src/StdAfx.h @@ -25,6 +25,9 @@ #include "../include/Method.h" #include "../include/Module.h" +#include "../../PAP/include/Config.h" +#include "../../PAP/include/Credentials.h" + #include "../../EAPBase/include/EAPXML.h" #include diff --git a/lib/TTLS_UI/include/TTLS_UI.h b/lib/TTLS_UI/include/TTLS_UI.h index 0c78411..8840c06 100644 --- a/lib/TTLS_UI/include/TTLS_UI.h +++ b/lib/TTLS_UI/include/TTLS_UI.h @@ -40,6 +40,7 @@ class wxTTLSCredentialsPanel; #include "../../TLS_UI/include/TLS_UI.h" #include "../../TTLS/include/Config.h" +#include "../../PAP/include/Config.h" #include diff --git a/lib/TTLS_UI/src/Module.cpp b/lib/TTLS_UI/src/Module.cpp index 73dda05..0e215d4 100644 --- a/lib/TTLS_UI/src/Module.cpp +++ b/lib/TTLS_UI/src/Module.cpp @@ -164,10 +164,10 @@ void eap::peer_ttls_ui::invoke_identity_ui( // Unpack configuration. config_connection cfg(*this); unpack(cfg, pConnectionData, dwConnectionDataSize); - if (cfg.m_providers.empty() || cfg.m_providers.front().m_methods.empty()) - throw invalid_argument(__FUNCTION__ " Configuration has no providers and/or methods."); // Get method configuration. + 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); @@ -175,8 +175,10 @@ void eap::peer_ttls_ui::invoke_identity_ui( #ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE // Unpack cached credentials. credentials_ttls cred_in(*this); - if (dwUserDataSize) + if (dwUserDataSize) { + s->m_cred.m_inner.reset(cfg_method->m_inner->make_credentials()); unpack(cred_in, pUserData, dwUserDataSize); + } #else UNREFERENCED_PARAMETER(pUserData); UNREFERENCED_PARAMETER(dwUserDataSize); @@ -194,15 +196,23 @@ void eap::peer_ttls_ui::invoke_identity_ui( type_inner = eap_type_undefined; } - // Combine credentials. - pair cred_source(cred_out.combine( + // 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)); + (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. @@ -228,10 +238,10 @@ void eap::peer_ttls_ui::invoke_identity_ui( dlg.AddContent(panel); // Set "Remember" checkboxes according to credential source, - panel->m_outer_cred->SetRememberValue(cred_source.first == eap::credentials::source_storage); + panel->m_outer_cred->SetRememberValue(cred_source == eap::credentials::source_storage); wxPAPCredentialsPanel *panel_inner_cred_pap = dynamic_cast(panel->m_inner_cred); if (panel_inner_cred_pap) - panel_inner_cred_pap->SetRememberValue(cred_source.second == eap::credentials::source_storage); + panel_inner_cred_pap->SetRememberValue(cred_source_inner == eap::credentials::source_storage); // Centre and display dialog. dlg.Centre(wxBOTH); diff --git a/lib/WinStd b/lib/WinStd index 88a8b7d..167e95f 160000 --- a/lib/WinStd +++ b/lib/WinStd @@ -1 +1 @@ -Subproject commit 88a8b7d093f357390065283dd08dac6459685726 +Subproject commit 167e95f01accd3ec4a9e2d65d5af5ed29316faab