Inner configuration/credential management virtualized to reduce cluttering code

This commit is contained in:
Simon Rozman 2016-08-28 17:20:24 +02:00
parent d20aafb3ff
commit fc5e54db05
19 changed files with 270 additions and 155 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -257,13 +257,13 @@ std::wstring eap::credentials_tls::get_identity() const
eap::credentials::source_t eap::credentials_tls::combine( eap::credentials::source_t eap::credentials_tls::combine(
_In_ const credentials_tls *cred_cached, _In_ const credentials *cred_cached,
_In_ const config_method_tls &cfg, _In_ const config_method_with_cred &cfg,
_In_opt_z_ LPCTSTR pszTargetName) _In_opt_z_ LPCTSTR pszTargetName)
{ {
if (cred_cached) { if (cred_cached) {
// Using EAP service cached credentials. // Using EAP service cached credentials.
*this = *cred_cached; *this = *(credentials_tls*)cred_cached;
m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_CACHED1, event_data((unsigned int)eap_type_tls), event_data(credentials_tls::get_name()), event_data::blank); m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_CACHED1, event_data((unsigned int)eap_type_tls), event_data(credentials_tls::get_name()), event_data::blank);
return source_cache; return source_cache;
} }

View File

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

View File

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

View File

@ -105,15 +105,19 @@ void eap::config_method_ttls::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode
if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:InnerAuthenticationMethod"), bstr(L"InnerAuthenticationMethod"), bstrNamespace, &pXmlElInnerAuthenticationMethod))) if (FAILED(hr = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:InnerAuthenticationMethod"), bstr(L"InnerAuthenticationMethod"), bstrNamespace, &pXmlElInnerAuthenticationMethod)))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <InnerAuthenticationMethod> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <InnerAuthenticationMethod> element.");
if (dynamic_cast<const config_method_pap*>(m_inner.get())) { eap_type_t eap_type = m_inner->get_method_id();
if (eap_type_noneap_start <= eap_type && eap_type < eap_type_noneap_end) {
// <InnerAuthenticationMethod>/<NonEAPAuthMethod> // <InnerAuthenticationMethod>/<NonEAPAuthMethod>
if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElInnerAuthenticationMethod, bstr(L"NonEAPAuthMethod"), bstrNamespace, bstr(L"PAP")))) if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElInnerAuthenticationMethod, bstr(L"NonEAPAuthMethod"), bstrNamespace, bstr(m_inner->get_method_str()))))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <NonEAPAuthMethod> element."); throw com_runtime_error(hr, __FUNCTION__ " Error creating <NonEAPAuthMethod> element.");
} else {
// <InnerAuthenticationMethod>/<EAPMethod>
if (FAILED(hr = eapxml::put_element_value(pDoc, pXmlElInnerAuthenticationMethod, bstr(L"EAPMethod"), bstrNamespace, (DWORD)m_inner->get_method_id())))
throw com_runtime_error(hr, __FUNCTION__ " Error creating <EAPMethod> element.");
}
// <InnerAuthenticationMethod>/... // <InnerAuthenticationMethod>/...
m_inner->save(pDoc, pXmlElInnerAuthenticationMethod); m_inner->save(pDoc, pXmlElInnerAuthenticationMethod);
} else
throw win_runtime_error(ERROR_NOT_SUPPORTED, __FUNCTION__ " Unsupported inner authentication method.");
} }
@ -144,23 +148,20 @@ void eap::config_method_ttls::load(_In_ IXMLDOMNode *pConfigRoot)
throw com_runtime_error(hr, __FUNCTION__ " Error selecting <InnerAuthenticationMethod> element."); throw com_runtime_error(hr, __FUNCTION__ " Error selecting <InnerAuthenticationMethod> element.");
// Determine inner authentication type (<EAPMethod> and <NonEAPAuthMethod>). // Determine inner authentication type (<EAPMethod> and <NonEAPAuthMethod>).
//DWORD dwMethodID; DWORD dwMethod;
bstr bstrMethod; bstr bstrMethod;
/*if (SUCCEEDED(eapxml::get_element_value(pXmlElInnerAuthenticationMethod, bstr(L"eap-metadata:EAPMethod"), &dwMethodID)) && if (SUCCEEDED(eapxml::get_element_value(pXmlElInnerAuthenticationMethod, bstr(L"eap-metadata:EAPMethod"), &dwMethod)) &&
dwMethodID == EAP_TYPE_MSCHAPV2) eap_type_start <= dwMethod && dwMethod < eap_type_end)
{ {
// MSCHAPv2 m_inner.reset(make_config_method((eap_type_t)dwMethod));
// TODO: Add MSCHAPv2 support. m_module.log_config((xpath + L"/EAPMethod").c_str(), m_inner->get_method_str());
throw win_runtime_error(ERROR_NOT_SUPPORTED, __FUNCTION__ " MSCHAPv2 not supported yet."); } else if (SUCCEEDED(eapxml::get_element_value(pXmlElInnerAuthenticationMethod, bstr(L"eap-metadata:NonEAPAuthMethod"), &bstrMethod))) {
} else*/ if (SUCCEEDED(eapxml::get_element_value(pXmlElInnerAuthenticationMethod, bstr(L"eap-metadata:NonEAPAuthMethod"), &bstrMethod)) && m_inner.reset(make_config_method(bstrMethod));
CompareStringEx(LOCALE_NAME_INVARIANT, NORM_IGNORECASE, bstrMethod, bstrMethod.length(), L"PAP", -1, NULL, NULL, 0) == CSTR_EQUAL) m_module.log_config((xpath + L"/NonEAPAuthMethod").c_str(), m_inner->get_method_str());
{
// PAP
m_module.log_config((xpath + L"/NonEAPAuthMethod").c_str(), L"PAP");
m_inner.reset(new config_method_pap(m_module));
m_inner->load(pXmlElInnerAuthenticationMethod);
} else } else
throw win_runtime_error(ERROR_NOT_SUPPORTED, __FUNCTION__ " Unsupported inner authentication method."); throw win_runtime_error(ERROR_NOT_SUPPORTED, __FUNCTION__ " Unsupported inner authentication method.");
m_inner->load(pXmlElInnerAuthenticationMethod);
} }
@ -169,13 +170,8 @@ void eap::config_method_ttls::operator<<(_Inout_ cursor_out &cursor) const
config_method_tls::operator<<(cursor); config_method_tls::operator<<(cursor);
if (m_inner) { if (m_inner) {
if (dynamic_cast<config_method_pap*>(m_inner.get())) { cursor << m_inner->get_method_id();
cursor << eap_type_pap; cursor << *m_inner;
cursor << *m_inner;
} else {
assert(0); // Unsupported inner authentication method type.
cursor << eap_type_undefined;
}
} else } else
cursor << eap_type_undefined; cursor << eap_type_undefined;
@ -187,14 +183,9 @@ size_t eap::config_method_ttls::get_pk_size() const
{ {
size_t size_inner; size_t size_inner;
if (m_inner) { if (m_inner) {
if (dynamic_cast<config_method_pap*>(m_inner.get())) { size_inner =
size_inner = pksizeof(m_inner->get_method_id()) +
pksizeof(eap_type_pap) + pksizeof(*m_inner);
pksizeof(*m_inner);
} else {
assert(0); // Unsupported inner authentication method type.
size_inner = pksizeof(eap_type_undefined);
}
} else } else
size_inner = pksizeof(eap_type_undefined); 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; eap_type_t eap_type;
cursor >> eap_type; cursor >> eap_type;
switch (eap_type) { if (eap_type != eap_type_undefined) {
case eap_type_pap: m_inner.reset(make_config_method(eap_type));
m_inner.reset(new config_method_pap(m_module)); cursor >> *m_inner;
cursor >> *m_inner;
break;
default:
assert(0); // Unsupported inner authentication method type.
m_inner.reset(nullptr);
} }
cursor >> m_anonymous_identity; cursor >> m_anonymous_identity;
} }
@ -231,6 +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 wstring eap::config_method_ttls::get_public_identity(const credentials_ttls &cred) const
{ {
if (m_anonymous_identity.empty()) { if (m_anonymous_identity.empty()) {

View File

@ -121,8 +121,8 @@ void eap::credentials_ttls::load(_In_ IXMLDOMNode *pConfigRoot)
credentials_tls::load(pConfigRoot); credentials_tls::load(pConfigRoot);
// TODO: For the time being, there is no detection what type is inner method. Introduce one!
if (m_inner) { if (m_inner) {
// Load inner credentials.
com_obj<IXMLDOMNode> pXmlElInnerAuthenticationMethod; com_obj<IXMLDOMNode> pXmlElInnerAuthenticationMethod;
if (FAILED(hr = eapxml::select_node(pConfigRoot, bstr(L"eap-metadata:InnerAuthenticationMethod"), &pXmlElInnerAuthenticationMethod))) if (FAILED(hr = eapxml::select_node(pConfigRoot, bstr(L"eap-metadata:InnerAuthenticationMethod"), &pXmlElInnerAuthenticationMethod)))
throw com_runtime_error(hr, __FUNCTION__ " Error selecting <InnerAuthenticationMethod> element."); throw com_runtime_error(hr, __FUNCTION__ " Error selecting <InnerAuthenticationMethod> element.");
@ -135,55 +135,22 @@ void eap::credentials_ttls::load(_In_ IXMLDOMNode *pConfigRoot)
void eap::credentials_ttls::operator<<(_Inout_ cursor_out &cursor) const void eap::credentials_ttls::operator<<(_Inout_ cursor_out &cursor) const
{ {
credentials_tls::operator<<(cursor); credentials_tls::operator<<(cursor);
if (m_inner) { cursor << *m_inner;
if (dynamic_cast<credentials_pap*>(m_inner.get())) {
cursor << eap_type_pap;
cursor << *m_inner;
} else {
assert(0); // Unsupported inner authentication method type.
cursor << eap_type_undefined;
}
} else
cursor << eap_type_undefined;
} }
size_t eap::credentials_ttls::get_pk_size() const size_t eap::credentials_ttls::get_pk_size() const
{ {
size_t size_inner;
if (m_inner) {
if (dynamic_cast<credentials_pap*>(m_inner.get())) {
size_inner =
pksizeof(eap_type_pap) +
pksizeof(*m_inner);
} else {
assert(0); // Unsupported inner authentication method type.
size_inner = pksizeof(eap_type_undefined);
}
} else
size_inner = pksizeof(eap_type_undefined);
return return
credentials_tls::get_pk_size() + credentials_tls::get_pk_size() +
size_inner; pksizeof(*m_inner);
} }
void eap::credentials_ttls::operator>>(_Inout_ cursor_in &cursor) void eap::credentials_ttls::operator>>(_Inout_ cursor_in &cursor)
{ {
credentials_tls::operator>>(cursor); credentials_tls::operator>>(cursor);
cursor >> *m_inner;
eap_type_t eap_type;
cursor >> eap_type;
switch (eap_type) {
case eap_type_pap:
m_inner.reset(new credentials_pap(m_module));
cursor >> *m_inner;
break;
default:
assert(0); // Unsupported inner authentication method type.
m_inner.reset(nullptr);
}
} }
@ -193,8 +160,7 @@ void eap::credentials_ttls::store(_In_z_ LPCTSTR pszTargetName) const
credentials_tls::store(pszTargetName); credentials_tls::store(pszTargetName);
if (m_inner) m_inner->store(pszTargetName);
m_inner->store(pszTargetName);
} }
@ -204,8 +170,7 @@ void eap::credentials_ttls::retrieve(_In_z_ LPCTSTR pszTargetName)
credentials_tls::retrieve(pszTargetName); credentials_tls::retrieve(pszTargetName);
if (m_inner) m_inner->retrieve(pszTargetName);
m_inner->retrieve(pszTargetName);
} }
@ -224,19 +189,30 @@ wstring eap::credentials_ttls::get_identity() const
return identity; return identity;
// Inner identity. // Inner identity.
if (m_inner) return m_inner->get_identity();
return m_inner->get_identity();
return L"";
} }
pair<eap::credentials::source_t, eap::credentials::source_t> eap::credentials_ttls::combine( eap::credentials::source_t eap::credentials_ttls::combine(
_In_ const credentials_ttls *cred_cached, _In_ const credentials *cred_cached,
_In_ const config_method_ttls &cfg, _In_ const config_method_with_cred &cfg,
_In_opt_z_ LPCTSTR pszTargetName) _In_opt_z_ LPCTSTR pszTargetName)
{ {
return pair<source_t, source_t>( source_t src;
credentials_tls::combine(cred_cached, cfg, pszTargetName),
dynamic_cast<const credentials_pap*>(m_inner.get()) ? ((credentials_pap*)m_inner.get())->combine(cred_cached ? (credentials_pap*)cred_cached->m_inner.get() : NULL, (const config_method_pap&)*cfg.m_inner, pszTargetName) : source_unknown); // 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);
} }

View File

@ -76,10 +76,10 @@ void eap::peer_ttls::get_identity(
// Unpack configuration. // Unpack configuration.
config_connection cfg(*this); config_connection cfg(*this);
unpack(cfg, pConnectionData, dwConnectionDataSize); unpack(cfg, pConnectionData, dwConnectionDataSize);
if (cfg.m_providers.empty() || cfg.m_providers.front().m_methods.empty())
throw invalid_argument(__FUNCTION__ " Configuration has no providers and/or methods.");
// Get method configuration. // Get method configuration.
if (cfg.m_providers.empty() || cfg.m_providers.front().m_methods.empty())
throw invalid_argument(__FUNCTION__ " Configuration has no providers and/or methods.");
const config_provider &cfg_prov(cfg.m_providers.front()); const config_provider &cfg_prov(cfg.m_providers.front());
const config_method_ttls *cfg_method = dynamic_cast<const config_method_ttls*>(cfg_prov.m_methods.front().get()); const config_method_ttls *cfg_method = dynamic_cast<const config_method_ttls*>(cfg_prov.m_methods.front().get());
assert(cfg_method); assert(cfg_method);
@ -87,39 +87,36 @@ void eap::peer_ttls::get_identity(
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE #ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
// Unpack cached credentials. // Unpack cached credentials.
credentials_ttls cred_in(*this); credentials_ttls cred_in(*this);
if (dwUserDataSize) if (dwUserDataSize) {
cred_in.m_inner.reset(cfg_method->m_inner->make_credentials());
unpack(cred_in, pUserData, dwUserDataSize); unpack(cred_in, pUserData, dwUserDataSize);
}
#else #else
UNREFERENCED_PARAMETER(pUserData); UNREFERENCED_PARAMETER(pUserData);
UNREFERENCED_PARAMETER(dwUserDataSize); UNREFERENCED_PARAMETER(dwUserDataSize);
#endif #endif
credentials_ttls cred_out(*this); credentials_ttls cred_out(*this);
cred_out.m_inner.reset(cfg_method->m_inner->make_credentials());
// Determine inner credential type. // Assume no UI will be necessary.
eap_type_t type_inner; *pfInvokeUI = FALSE;
if (dynamic_cast<const config_method_pap*>(cfg_method->m_inner.get())) {
cred_out.m_inner.reset(new credentials_pap(*this));
type_inner = eap_type_pap;
} else {
assert(0); // Unsupported inner authentication method type.
type_inner = eap_type_undefined;
}
{ {
// Combine credentials. // Combine credentials.
user_impersonator impersonating(hTokenImpersonateUser); user_impersonator impersonating(hTokenImpersonateUser);
pair<eap::credentials::source_t, eap::credentials::source_t> cred_source(cred_out.combine( eap::credentials::source_t cred_source = cred_out.combine(
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE #ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
&cred_in, &cred_in,
#else #else
NULL, NULL,
#endif #endif
*cfg_method, *cfg_method,
(dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? cfg_prov.m_id.c_str() : NULL)); (dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? cfg_prov.m_id.c_str() : NULL);
// If either of credentials is unknown, request UI. // 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) { if (*pfInvokeUI) {
@ -144,7 +141,7 @@ void eap::peer_ttls::get_identity(
if (cfg_method->m_inner->m_auth_failed) { if (cfg_method->m_inner->m_auth_failed) {
// Inner: Credentials failed on last connection attempt. // Inner: Credentials failed on last connection attempt.
log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM, event_data((unsigned int)type_inner), event_data::blank); log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM, event_data((unsigned int)cfg_method->m_inner->get_method_id()), event_data::blank);
*pfInvokeUI = TRUE; *pfInvokeUI = TRUE;
return; return;
} }
@ -251,7 +248,15 @@ EAP_SESSION_HANDLE eap::peer_ttls::begin_session(
// Unpack configuration. // Unpack configuration.
unpack(s->m_cfg, pConnectionData, dwConnectionDataSize); unpack(s->m_cfg, pConnectionData, dwConnectionDataSize);
// Get method configuration.
if (s->m_cfg.m_providers.empty() || s->m_cfg.m_providers.front().m_methods.empty())
throw invalid_argument(__FUNCTION__ " Configuration has no providers and/or methods.");
const config_provider &cfg_prov(s->m_cfg.m_providers.front());
const config_method_ttls *cfg_method = dynamic_cast<const config_method_ttls*>(cfg_prov.m_methods.front().get());
assert(cfg_method);
// Unpack credentials. // Unpack credentials.
s->m_cred.m_inner.reset(cfg_method->m_inner->make_credentials());
unpack(s->m_cred, pUserData, dwUserDataSize); unpack(s->m_cred, pUserData, dwUserDataSize);
// Initialize method. // Initialize method.

View File

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

View File

@ -40,6 +40,7 @@ class wxTTLSCredentialsPanel;
#include "../../TLS_UI/include/TLS_UI.h" #include "../../TLS_UI/include/TLS_UI.h"
#include "../../TTLS/include/Config.h" #include "../../TTLS/include/Config.h"
#include "../../PAP/include/Config.h"
#include <WinStd/Win.h> #include <WinStd/Win.h>

View File

@ -164,10 +164,10 @@ void eap::peer_ttls_ui::invoke_identity_ui(
// Unpack configuration. // Unpack configuration.
config_connection cfg(*this); config_connection cfg(*this);
unpack(cfg, pConnectionData, dwConnectionDataSize); unpack(cfg, pConnectionData, dwConnectionDataSize);
if (cfg.m_providers.empty() || cfg.m_providers.front().m_methods.empty())
throw invalid_argument(__FUNCTION__ " Configuration has no providers and/or methods.");
// Get method configuration. // Get method configuration.
if (cfg.m_providers.empty() || cfg.m_providers.front().m_methods.empty())
throw invalid_argument(__FUNCTION__ " Configuration has no providers and/or methods.");
const config_provider &cfg_prov(cfg.m_providers.front()); const config_provider &cfg_prov(cfg.m_providers.front());
config_method_ttls *cfg_method = dynamic_cast<config_method_ttls*>(cfg_prov.m_methods.front().get()); config_method_ttls *cfg_method = dynamic_cast<config_method_ttls*>(cfg_prov.m_methods.front().get());
assert(cfg_method); assert(cfg_method);
@ -175,8 +175,10 @@ void eap::peer_ttls_ui::invoke_identity_ui(
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE #ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
// Unpack cached credentials. // Unpack cached credentials.
credentials_ttls cred_in(*this); credentials_ttls cred_in(*this);
if (dwUserDataSize) if (dwUserDataSize) {
s->m_cred.m_inner.reset(cfg_method->m_inner->make_credentials());
unpack(cred_in, pUserData, dwUserDataSize); unpack(cred_in, pUserData, dwUserDataSize);
}
#else #else
UNREFERENCED_PARAMETER(pUserData); UNREFERENCED_PARAMETER(pUserData);
UNREFERENCED_PARAMETER(dwUserDataSize); UNREFERENCED_PARAMETER(dwUserDataSize);
@ -194,15 +196,23 @@ void eap::peer_ttls_ui::invoke_identity_ui(
type_inner = eap_type_undefined; type_inner = eap_type_undefined;
} }
// Combine credentials. // Combine credentials. Outer and inner separately to get the idea which one is missing.
pair<eap::credentials::source_t, eap::credentials::source_t> cred_source(cred_out.combine( eap::credentials::source_t cred_source = 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)); (dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? cfg_prov.m_id.c_str() : NULL);
eap::credentials::source_t cred_source_inner = cred_out.m_inner->combine(
#ifdef EAP_USE_NATIVE_CREDENTIAL_CACHE
cred_in.m_inner.get(),
#else
NULL,
#endif
*cfg_method->m_inner,
(dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 ? cfg_prov.m_id.c_str() : NULL);
if (dwFlags & EAP_FLAG_GUEST_ACCESS) { if (dwFlags & EAP_FLAG_GUEST_ACCESS) {
// Disable credential saving for guests. // Disable credential saving for guests.
@ -228,10 +238,10 @@ void eap::peer_ttls_ui::invoke_identity_ui(
dlg.AddContent(panel); dlg.AddContent(panel);
// Set "Remember" checkboxes according to credential source, // 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<wxPAPCredentialsPanel*>(panel->m_inner_cred); wxPAPCredentialsPanel *panel_inner_cred_pap = dynamic_cast<wxPAPCredentialsPanel*>(panel->m_inner_cred);
if (panel_inner_cred_pap) 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. // Centre and display dialog.
dlg.Centre(wxBOTH); dlg.Centre(wxBOTH);

@ -1 +1 @@
Subproject commit 88a8b7d093f357390065283dd08dac6459685726 Subproject commit 167e95f01accd3ec4a9e2d65d5af5ed29316faab