eap::credentials reverted back to abstract class (25934dd8c70ca399ff4c58fd9a06319de81611f3 undone), and eap::credentials_identity introduced, since identity-only credentials must fail when <UserName> absent
This commit is contained in:
parent
0b358acba7
commit
f9083dc300
@ -111,8 +111,6 @@ namespace eap
|
|||||||
///
|
///
|
||||||
credentials& operator=(_Inout_ credentials &&other);
|
credentials& operator=(_Inout_ credentials &&other);
|
||||||
|
|
||||||
virtual config* clone() const;
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Resets credentials
|
/// Resets credentials
|
||||||
///
|
///
|
||||||
@ -149,7 +147,7 @@ namespace eap
|
|||||||
/// \param[in] pszTargetName The name in Windows Credential Manager to store credentials as
|
/// \param[in] pszTargetName The name in Windows Credential Manager to store credentials as
|
||||||
/// \param[in] level Credential level (0=outer, 1=inner, 2=inner-inner...)
|
/// \param[in] level Credential level (0=outer, 1=inner, 2=inner-inner...)
|
||||||
///
|
///
|
||||||
virtual void store(_In_z_ LPCTSTR pszTargetName, _In_ unsigned int level) const;
|
virtual void store(_In_z_ LPCTSTR pszTargetName, _In_ unsigned int level) const = 0;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Retrieve credentials from Windows Credential Manager
|
/// Retrieve credentials from Windows Credential Manager
|
||||||
@ -157,7 +155,7 @@ namespace eap
|
|||||||
/// \param[in] pszTargetName The name in Windows Credential Manager to retrieve credentials from
|
/// \param[in] pszTargetName The name in Windows Credential Manager to retrieve credentials from
|
||||||
/// \param[in] level Credential level (0=outer, 1=inner, 2=inner-inner...)
|
/// \param[in] level Credential level (0=outer, 1=inner, 2=inner-inner...)
|
||||||
///
|
///
|
||||||
virtual void retrieve(_In_z_ LPCTSTR pszTargetName, _In_ unsigned int level);
|
virtual void retrieve(_In_z_ LPCTSTR pszTargetName, _In_ unsigned int level) = 0;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns target name for Windows Credential Manager credential name
|
/// Returns target name for Windows Credential Manager credential name
|
||||||
@ -189,7 +187,7 @@ namespace eap
|
|||||||
///
|
///
|
||||||
/// Return target suffix for Windows Credential Manager credential name
|
/// Return target suffix for Windows Credential Manager credential name
|
||||||
///
|
///
|
||||||
virtual LPCTSTR target_suffix() const;
|
virtual LPCTSTR target_suffix() const = 0;
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
@ -226,13 +224,105 @@ namespace eap
|
|||||||
_In_ HANDLE hTokenImpersonateUser,
|
_In_ HANDLE hTokenImpersonateUser,
|
||||||
_In_opt_ const credentials *cred_cached,
|
_In_opt_ const credentials *cred_cached,
|
||||||
_In_ const config_method &cfg,
|
_In_ const config_method &cfg,
|
||||||
_In_opt_z_ LPCTSTR pszTargetName);
|
_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.)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Identity-only based method credentials
|
||||||
|
///
|
||||||
|
class credentials_identity : public credentials
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
///
|
||||||
|
/// Constructs credentials
|
||||||
|
///
|
||||||
|
/// \param[in] mod EAP module to use for global services
|
||||||
|
///
|
||||||
|
credentials_identity(_In_ module &mod);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Copies credentials
|
||||||
|
///
|
||||||
|
/// \param[in] other Credentials to copy from
|
||||||
|
///
|
||||||
|
credentials_identity(_In_ const credentials_identity &other);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Moves credentials
|
||||||
|
///
|
||||||
|
/// \param[in] other Credentials to move from
|
||||||
|
///
|
||||||
|
credentials_identity(_Inout_ credentials_identity &&other);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Copies credentials
|
||||||
|
///
|
||||||
|
/// \param[in] other Credentials to copy from
|
||||||
|
///
|
||||||
|
/// \returns Reference to this object
|
||||||
|
///
|
||||||
|
credentials_identity& operator=(_In_ const credentials_identity &other);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Moves credentials
|
||||||
|
///
|
||||||
|
/// \param[in] other Credentials to move from
|
||||||
|
///
|
||||||
|
/// \returns Reference to this object
|
||||||
|
///
|
||||||
|
credentials_identity& operator=(_Inout_ credentials_identity &&other);
|
||||||
|
|
||||||
|
virtual config* clone() const;
|
||||||
|
|
||||||
|
/// \name XML management
|
||||||
|
/// @{
|
||||||
|
virtual void save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pConfigRoot) const;
|
||||||
|
virtual void load(_In_ IXMLDOMNode *pConfigRoot);
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// \name Storage
|
||||||
|
/// @{
|
||||||
|
virtual void store(_In_z_ LPCTSTR pszTargetName, _In_ unsigned int level) const;
|
||||||
|
virtual void retrieve(_In_z_ LPCTSTR pszTargetName, _In_ unsigned int level);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @copydoc eap::credentials::target_suffix()
|
||||||
|
/// \returns This implementation always returns `_T("pass")`
|
||||||
|
///
|
||||||
|
virtual LPCTSTR target_suffix() const;
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Combine credentials in the following order:
|
||||||
|
///
|
||||||
|
/// 1. Cached credentials
|
||||||
|
/// 2. Configured credentials (if \p cfg is derived from `config_method_with_cred`)
|
||||||
|
/// 3. Stored credentials
|
||||||
|
///
|
||||||
|
/// \param[in] dwFlags A combination of [EAP flags](https://msdn.microsoft.com/en-us/library/windows/desktop/bb891975.aspx) that describe the EAP authentication session behavior
|
||||||
|
/// \param[in] hTokenImpersonateUser Impersonation token for a logged-on user to collect user-related information
|
||||||
|
/// \param[in] cred_cached Cached credentials (optional, can be \c NULL)
|
||||||
|
/// \param[in] cfg Method configuration (when derived from `config_method_with_cred`, metod attempt to load credentials from \p cfg)
|
||||||
|
/// \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_config Credentials were set by method configuration
|
||||||
|
/// - \c source_storage Credentials were loaded from Windows Credential Manager
|
||||||
|
///
|
||||||
|
virtual source_t combine(
|
||||||
|
_In_ DWORD dwFlags,
|
||||||
|
_In_ HANDLE hTokenImpersonateUser,
|
||||||
|
_In_opt_ const credentials *cred_cached,
|
||||||
|
_In_ const config_method &cfg,
|
||||||
|
_In_opt_z_ LPCTSTR pszTargetName);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Password based method credentials
|
/// Password based method credentials
|
||||||
///
|
///
|
||||||
|
@ -82,12 +82,6 @@ eap::credentials& eap::credentials::operator=(_Inout_ credentials &&other)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
eap::config* eap::credentials::clone() const
|
|
||||||
{
|
|
||||||
return new credentials(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void eap::credentials::clear()
|
void eap::credentials::clear()
|
||||||
{
|
{
|
||||||
m_identity.clear();
|
m_identity.clear();
|
||||||
@ -154,14 +148,109 @@ void eap::credentials::operator>>(_Inout_ cursor_in &cursor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void eap::credentials::store(_In_z_ LPCTSTR pszTargetName, _In_ unsigned int level) const
|
wstring eap::credentials::get_identity() const
|
||||||
|
{
|
||||||
|
return m_identity;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tstring eap::credentials::get_name() const
|
||||||
|
{
|
||||||
|
tstring identity(std::move(get_identity()));
|
||||||
|
return
|
||||||
|
!identity.empty() ? identity :
|
||||||
|
empty() ? _T("<empty>") : _T("<blank ID>");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// eap::credentials_identity
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
eap::credentials_identity::credentials_identity(_In_ module &mod) : credentials(mod)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
eap::credentials_identity::credentials_identity(_In_ const credentials_identity &other) : credentials(other)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
eap::credentials_identity::credentials_identity(_Inout_ credentials_identity &&other) : credentials(std::move(other))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
eap::credentials_identity& eap::credentials_identity::operator=(_In_ const credentials_identity &other)
|
||||||
|
{
|
||||||
|
if (this != &other)
|
||||||
|
(credentials&)*this = other;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
eap::credentials_identity& eap::credentials_identity::operator=(_Inout_ credentials_identity &&other)
|
||||||
|
{
|
||||||
|
if (this != &other)
|
||||||
|
(credentials&)*this = std::move(other);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
eap::config* eap::credentials_identity::clone() const
|
||||||
|
{
|
||||||
|
return new credentials_identity(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void eap::credentials_identity::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pConfigRoot) const
|
||||||
|
{
|
||||||
|
assert(pDoc);
|
||||||
|
assert(pConfigRoot);
|
||||||
|
|
||||||
|
// We could have used credentials::save() to save identity,
|
||||||
|
// but that method tolerates absence of <UserName> element,
|
||||||
|
// whereas for this class the absence of <UserName> is fatal.
|
||||||
|
config::save(pDoc, pConfigRoot);
|
||||||
|
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
// <UserName>
|
||||||
|
if (FAILED(hr = eapxml::put_element_value(pDoc, pConfigRoot, bstr(L"UserName"), namespace_eapmetadata, bstr(m_identity))))
|
||||||
|
throw com_runtime_error(hr, __FUNCTION__ " Error creating <UserName> element.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void eap::credentials_identity::load(_In_ IXMLDOMNode *pConfigRoot)
|
||||||
|
{
|
||||||
|
assert(pConfigRoot);
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
// We could have used credentials::load() to load identity,
|
||||||
|
// but that method tolerates absence of <UserName> element,
|
||||||
|
// whereas for this class the absence of <UserName> is fatal.
|
||||||
|
config::load(pConfigRoot);
|
||||||
|
|
||||||
|
wstring xpath(eapxml::get_xpath(pConfigRoot));
|
||||||
|
|
||||||
|
if (FAILED(hr = eapxml::get_element_value(pConfigRoot, bstr(L"eap-metadata:UserName"), m_identity)))
|
||||||
|
throw com_runtime_error(hr, __FUNCTION__ " Error reading <UserName> element.");
|
||||||
|
|
||||||
|
m_module.log_config((xpath + L"/UserName").c_str(), m_identity.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void eap::credentials_identity::store(_In_z_ LPCTSTR pszTargetName, _In_ unsigned int level) const
|
||||||
{
|
{
|
||||||
assert(pszTargetName);
|
assert(pszTargetName);
|
||||||
|
|
||||||
tstring target(target_name(pszTargetName, level));
|
tstring target(target_name(pszTargetName, level));
|
||||||
|
|
||||||
// Write credentials.
|
// Write credentials.
|
||||||
assert(m_identity.length() < CRED_MAX_USERNAME_LENGTH );
|
assert(m_identity.length() < CRED_MAX_USERNAME_LENGTH);
|
||||||
CREDENTIAL cred = {
|
CREDENTIAL cred = {
|
||||||
0, // Flags
|
0, // Flags
|
||||||
CRED_TYPE_GENERIC, // Type
|
CRED_TYPE_GENERIC, // Type
|
||||||
@ -181,7 +270,7 @@ void eap::credentials::store(_In_z_ LPCTSTR pszTargetName, _In_ unsigned int lev
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void eap::credentials::retrieve(_In_z_ LPCTSTR pszTargetName, _In_ unsigned int level)
|
void eap::credentials_identity::retrieve(_In_z_ LPCTSTR pszTargetName, _In_ unsigned int level)
|
||||||
{
|
{
|
||||||
assert(pszTargetName);
|
assert(pszTargetName);
|
||||||
|
|
||||||
@ -200,28 +289,13 @@ void eap::credentials::retrieve(_In_z_ LPCTSTR pszTargetName, _In_ unsigned int
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LPCTSTR eap::credentials::target_suffix() const
|
LPCTSTR eap::credentials_identity::target_suffix() const
|
||||||
{
|
{
|
||||||
return _T("id");
|
return _T("id");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
wstring eap::credentials::get_identity() const
|
eap::credentials::source_t eap::credentials_identity::combine(
|
||||||
{
|
|
||||||
return m_identity;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
tstring eap::credentials::get_name() const
|
|
||||||
{
|
|
||||||
tstring identity(std::move(get_identity()));
|
|
||||||
return
|
|
||||||
!identity.empty() ? identity :
|
|
||||||
empty() ? _T("<empty>") : _T("<blank ID>");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
eap::credentials::source_t eap::credentials::combine(
|
|
||||||
_In_ DWORD dwFlags,
|
_In_ DWORD dwFlags,
|
||||||
_In_ HANDLE hTokenImpersonateUser,
|
_In_ HANDLE hTokenImpersonateUser,
|
||||||
_In_opt_ const credentials *cred_cached,
|
_In_opt_ const credentials *cred_cached,
|
||||||
@ -232,16 +306,16 @@ eap::credentials::source_t eap::credentials::combine(
|
|||||||
|
|
||||||
if (cred_cached) {
|
if (cred_cached) {
|
||||||
// Using EAP service cached credentials.
|
// Using EAP service cached credentials.
|
||||||
*this = *cred_cached;
|
*this = *dynamic_cast<const credentials_identity*>(cred_cached);
|
||||||
m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_CACHED2, event_data((unsigned int)cfg.get_method_id()), event_data(credentials::get_name()), event_data(pszTargetName), event_data::blank);
|
m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_CACHED2, event_data((unsigned int)cfg.get_method_id()), event_data(credentials_identity::get_name()), event_data(pszTargetName), event_data::blank);
|
||||||
return source_cache;
|
return source_cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cfg_with_cred = dynamic_cast<const config_method_with_cred*>(&cfg);
|
auto cfg_with_cred = dynamic_cast<const config_method_with_cred*>(&cfg);
|
||||||
if (cfg_with_cred && cfg_with_cred->m_use_cred) {
|
if (cfg_with_cred && cfg_with_cred->m_use_cred) {
|
||||||
// Using configured credentials.
|
// Using configured credentials.
|
||||||
*this = *cfg_with_cred->m_cred.get();
|
*this = *dynamic_cast<const credentials_identity*>(cfg_with_cred->m_cred.get());
|
||||||
m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_CONFIG2, event_data((unsigned int)cfg.get_method_id()), event_data(credentials::get_name()), event_data(pszTargetName), event_data::blank);
|
m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_CONFIG2, event_data((unsigned int)cfg.get_method_id()), event_data(credentials_identity::get_name()), event_data(pszTargetName), event_data::blank);
|
||||||
return source_config;
|
return source_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,12 +324,12 @@ eap::credentials::source_t eap::credentials::combine(
|
|||||||
user_impersonator impersonating(hTokenImpersonateUser);
|
user_impersonator impersonating(hTokenImpersonateUser);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
credentials cred_loaded(m_module);
|
credentials_identity cred_loaded(m_module);
|
||||||
cred_loaded.retrieve(pszTargetName, cfg.m_level);
|
cred_loaded.retrieve(pszTargetName, cfg.m_level);
|
||||||
|
|
||||||
// Using stored credentials.
|
// Using stored credentials.
|
||||||
*this = std::move(cred_loaded);
|
*this = std::move(cred_loaded);
|
||||||
m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_STORED2, event_data((unsigned int)cfg.get_method_id()), event_data(credentials::get_name()), event_data(pszTargetName), event_data::blank);
|
m_module.log_event(&EAPMETHOD_TRACE_EVT_CRED_STORED2, event_data((unsigned int)cfg.get_method_id()), event_data(credentials_identity::get_name()), event_data(pszTargetName), event_data::blank);
|
||||||
return source_storage;
|
return source_storage;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
// Not actually an error.
|
// Not actually an error.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user