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.
///
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

View File

@ -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.)
};

View File

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

View File

@ -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);
};
}

View File

@ -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);
}

View File

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

View File

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

View File

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

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)
{
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(
_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;
}

View File

@ -33,7 +33,6 @@ namespace eap
#include "Credentials.h"
#include "../../TLS/include/Config.h"
#include "../../PAP/include/Config.h"
#include <Windows.h>
#include <assert.h>
@ -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
///

View File

@ -29,10 +29,8 @@ namespace eap
#pragma once
#include "../../TLS/include/Credentials.h"
#include "../../PAP/include/Credentials.h"
#include <memory>
#include <utility>
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<source_t, source_t> 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<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)))
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>
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.");
} 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>/...
m_inner->save(pDoc, pXmlElInnerAuthenticationMethod);
} else
throw win_runtime_error(ERROR_NOT_SUPPORTED, __FUNCTION__ " Unsupported inner authentication method.");
// <InnerAuthenticationMethod>/...
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 <InnerAuthenticationMethod> element.");
// Determine inner authentication type (<EAPMethod> and <NonEAPAuthMethod>).
//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<config_method_pap*>(m_inner.get())) {
cursor << eap_type_pap;
cursor << *m_inner;
} else {
assert(0); // Unsupported inner authentication method type.
cursor << eap_type_undefined;
}
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<config_method_pap*>(m_inner.get())) {
size_inner =
pksizeof(eap_type_pap) +
pksizeof(*m_inner);
} else {
assert(0); // Unsupported inner authentication method type.
size_inner = pksizeof(eap_type_undefined);
}
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()) {

View File

@ -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<IXMLDOMNode> pXmlElInnerAuthenticationMethod;
if (FAILED(hr = eapxml::select_node(pConfigRoot, bstr(L"eap-metadata:InnerAuthenticationMethod"), &pXmlElInnerAuthenticationMethod)))
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
{
credentials_tls::operator<<(cursor);
if (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;
cursor << *m_inner;
}
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
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::source_t, eap::credentials::source_t> 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<source_t, source_t>(
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);
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);
}

View File

@ -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<const config_method_ttls*>(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<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;
}
// Assume no UI will be necessary.
*pfInvokeUI = FALSE;
{
// Combine credentials.
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
&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<const config_method_ttls*>(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.

View File

@ -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 <WinStd/EAP.h>

View File

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

View File

@ -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<config_method_ttls*>(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<eap::credentials::source_t, eap::credentials::source_t> 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<wxPAPCredentialsPanel*>(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);

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