Peer correctly returns providers configuration instead of method configuration in method_tls::get_result()

This commit is contained in:
2016-08-15 14:13:14 +02:00
parent 217c3dd090
commit 3d6849a523
10 changed files with 98 additions and 72 deletions

View File

@@ -148,7 +148,7 @@ namespace eap {
std::wstring get_public_identity(const credentials_ttls &cred) const;
public:
std::unique_ptr<config> m_inner; ///< Inner authentication configuration
std::wstring m_anonymous_identity; ///< Anonymous identity
std::unique_ptr<config_method_with_cred> m_inner; ///< Inner authentication configuration
std::wstring m_anonymous_identity; ///< Anonymous identity
};
}

View File

@@ -57,9 +57,10 @@ namespace eap
/// Constructs an EAP method
///
/// \param[in] mod EAP module to use for global services
/// \param[in] cfg Method configuration
/// \param[in] cfg Providers configuration
/// \param[in] cred User credentials
///
method_ttls(_In_ module &module, _In_ config_method_ttls &cfg, _In_ credentials_ttls &cred);
method_ttls(_In_ module &module, _In_ config_provider_list &cfg, _In_ credentials_ttls &cred);
///
/// Copies an EAP method
@@ -115,6 +116,15 @@ namespace eap
_Inout_bytecap_(*dwSendPacketSize) EapPacket *pSendPacket,
_Inout_ DWORD *pdwSendPacketSize);
///
/// Obtains the result of an authentication session from the EAP method.
///
/// \sa [EapPeerGetResult function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363611.aspx)
///
virtual void get_result(
_In_ EapPeerMethodResultReason reason,
_Inout_ EapPeerMethodResult *ppResult);
/// @}
///

View File

@@ -221,7 +221,7 @@ namespace eap
{}
public:
config_method_ttls m_cfg; ///< Method configuration
config_provider_list m_cfg; ///< Providers configuration
credentials_ttls m_cred; ///< User credentials
method_ttls m_method; ///< EAP-TTLS method
};

View File

@@ -35,7 +35,7 @@ eap::config_method_ttls::config_method_ttls(_In_ module &mod) :
eap::config_method_ttls::config_method_ttls(const _In_ config_method_ttls &other) :
m_inner(other.m_inner ? (config_method*)other.m_inner->clone() : nullptr),
m_inner(other.m_inner ? (config_method_with_cred*)other.m_inner->clone() : nullptr),
m_anonymous_identity(other.m_anonymous_identity),
config_method_tls(other)
{
@@ -54,7 +54,7 @@ eap::config_method_ttls& eap::config_method_ttls::operator=(const _In_ config_me
{
if (this != &other) {
(config_method_tls&)*this = other;
m_inner.reset(other.m_inner ? (config_method*)other.m_inner->clone() : nullptr);
m_inner.reset(other.m_inner ? (config_method_with_cred*)other.m_inner->clone() : nullptr);
m_anonymous_identity = other.m_anonymous_identity;
}

View File

@@ -28,7 +28,7 @@ using namespace winstd;
// eap::method_ttls
//////////////////////////////////////////////////////////////////////
eap::method_ttls::method_ttls(_In_ module &module, _In_ config_method_ttls &cfg, _In_ credentials_ttls &cred) :
eap::method_ttls::method_ttls(_In_ module &module, _In_ config_provider_list &cfg, _In_ credentials_ttls &cred) :
m_cred(cred),
m_version(version_0),
method_tls(module, cfg, cred)
@@ -127,6 +127,25 @@ void eap::method_ttls::get_response_packet(
}
void eap::method_ttls::get_result(
_In_ EapPeerMethodResultReason reason,
_Inout_ EapPeerMethodResult *ppResult)
{
if (!m_server_finished) {
// Do the TLS.
method_tls::get_result(reason, ppResult);
} else {
// The TLS was OK.
method_tls::get_result(EapPeerMethodResultSuccess, ppResult);
if (reason == EapPeerMethodResultFailure) {
ppResult->fIsSuccess = FALSE;
ppResult->dwFailureReasonCode = EAP_E_AUTHENTICATION_FAILED;
}
}
}
void eap::method_ttls::derive_msk()
{
static const unsigned char s_label[] = "ttls keying material";

View File

@@ -83,7 +83,6 @@ void eap::peer_ttls::get_identity(
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);
const config_method_pap *cfg_inner_pap = dynamic_cast<const config_method_pap*>(cfg_method->m_inner.get());
// Unpack cached credentials.
credentials_ttls cred_in(*this);
@@ -92,11 +91,11 @@ void eap::peer_ttls::get_identity(
credentials_ttls cred_out(*this);
// Determine credential storage target(s). Also used as user-friendly method name for logging.
// Determine credential storage target(s).
eap_type_t type_inner;
if (cfg_inner_pap) {
if (dynamic_cast<const config_method_pap*>(cfg_method->m_inner.get()))
type_inner = eap_type_pap;
} else {
else {
assert(0); // Unsupported inner authentication method type.
type_inner = eap_type_undefined;
}
@@ -116,7 +115,7 @@ void eap::peer_ttls::get_identity(
}
if (!is_inner_set && cred_in.m_inner) {
// Inner PAP: Using EAP service cached credentials.
// Inner: Using EAP service cached credentials.
cred_out.m_inner.reset((credentials*)cred_in.m_inner->clone());
log_event(&EAPMETHOD_TRACE_EVT_CRED_CACHED1, event_data((unsigned int)type_inner), event_data(cred_out.m_inner->get_name()), event_data::blank);
is_inner_set = true;
@@ -131,15 +130,12 @@ void eap::peer_ttls::get_identity(
}
if (!is_inner_set) {
if (cfg_inner_pap) {
if (cfg_inner_pap->m_use_preshared) {
// Inner PAP: Using preshared credentials.
cred_out.m_inner.reset((credentials*)cfg_inner_pap->m_preshared->clone());
log_event(&EAPMETHOD_TRACE_EVT_CRED_PRESHARED1, event_data((unsigned int)type_inner), event_data(cred_out.m_inner->get_name()), event_data::blank);
is_inner_set = true;
}
} else
assert(0); // Unsupported inner authentication method type.
if (cfg_method->m_inner->m_use_preshared) {
// Inner: Using preshared credentials.
cred_out.m_inner.reset((credentials*)cfg_method->m_inner->m_preshared->clone());
log_event(&EAPMETHOD_TRACE_EVT_CRED_PRESHARED1, event_data((unsigned int)type_inner), event_data(cred_out.m_inner->get_name()), event_data::blank);
is_inner_set = true;
}
}
if ((dwFlags & EAP_FLAG_GUEST_ACCESS) == 0 && (!is_outer_set || !is_inner_set)) {
@@ -164,12 +160,14 @@ void eap::peer_ttls::get_identity(
if (!is_inner_set) {
unique_ptr<credentials> cred_loaded;
if (cfg_inner_pap) cred_loaded.reset(new credentials_pap(*this));
else assert(0); // Unsupported inner authentication method type.
switch (type_inner) {
case eap_type_pap: cred_loaded.reset(new credentials_pap(*this)); break;
default : assert(0); // Unsupported inner authentication method type.
}
try {
cred_loaded->retrieve(cfg_prov.m_id.c_str());
// Inner PAP: Using stored credentials.
// Inner: Using stored credentials.
cred_out.m_inner = std::move(cred_loaded);
log_event(&EAPMETHOD_TRACE_EVT_CRED_STORED1, event_data((unsigned int)type_inner), event_data(cred_out.m_inner->get_name()), event_data::blank);
is_inner_set = true;
@@ -304,14 +302,7 @@ EAP_SESSION_HANDLE eap::peer_ttls::begin_session(
unique_ptr<session> s(new session(*this));
// Unpack configuration.
config_provider_list 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.");
// Copy method configuration.
const config_provider &cfg_prov(cfg.m_providers.front());
s->m_cfg = *dynamic_cast<const config_method_ttls*>(cfg_prov.m_methods.front().get());
unpack(s->m_cfg, pConnectionData, dwConnectionDataSize);
// Unpack credentials.
unpack(s->m_cred, pUserData, dwUserDataSize);