eap::credentials no longer pure virtual to allow identity-only credentials (i.e. EAP-GTC).

This commit is contained in:
Simon Rozman 2017-01-31 10:33:15 +01:00
parent 4b4578fd59
commit 25934dd8c7
2 changed files with 109 additions and 4 deletions

View File

@ -111,6 +111,8 @@ namespace eap
///
credentials& operator=(_Inout_ credentials &&other);
virtual config* clone() const;
///
/// Resets credentials
///
@ -147,7 +149,7 @@ namespace eap
/// \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...)
///
virtual void store(_In_z_ LPCTSTR pszTargetName, _In_ unsigned int level) const = 0;
virtual void store(_In_z_ LPCTSTR pszTargetName, _In_ unsigned int level) const;
///
/// Retrieve credentials from Windows Credential Manager
@ -155,7 +157,7 @@ namespace eap
/// \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...)
///
virtual void retrieve(_In_z_ LPCTSTR pszTargetName, _In_ unsigned int level) = 0;
virtual void retrieve(_In_z_ LPCTSTR pszTargetName, _In_ unsigned int level);
///
/// Returns target name for Windows Credential Manager credential name
@ -187,7 +189,7 @@ namespace eap
///
/// Return target suffix for Windows Credential Manager credential name
///
virtual LPCTSTR target_suffix() const = 0;
virtual LPCTSTR target_suffix() const;
/// @}
@ -224,7 +226,7 @@ namespace eap
_In_ HANDLE hTokenImpersonateUser,
_In_opt_ const credentials *cred_cached,
_In_ const config_method &cfg,
_In_opt_z_ LPCTSTR pszTargetName) = 0;
_In_opt_z_ LPCTSTR pszTargetName);
public:
std::wstring m_identity; ///< Identity (username\@domain, certificate name etc.)

View File

@ -82,6 +82,12 @@ eap::credentials& eap::credentials::operator=(_Inout_ credentials &&other)
}
eap::config* eap::credentials::clone() const
{
return new credentials(*this);
}
void eap::credentials::clear()
{
m_identity.clear();
@ -148,6 +154,58 @@ void eap::credentials::operator>>(_Inout_ cursor_in &cursor)
}
void eap::credentials::store(_In_z_ LPCTSTR pszTargetName, _In_ unsigned int level) const
{
assert(pszTargetName);
tstring target(target_name(pszTargetName, level));
// Write credentials.
assert(m_identity.length() < CRED_MAX_USERNAME_LENGTH );
CREDENTIAL cred = {
0, // Flags
CRED_TYPE_GENERIC, // Type
const_cast<LPTSTR>(target.c_str()), // TargetName
_T(""), // Comment
{ 0, 0 }, // LastWritten
0, // CredentialBlobSize
NULL, // CredentialBlob
CRED_PERSIST_ENTERPRISE, // Persist
0, // AttributeCount
NULL, // Attributes
NULL, // TargetAlias
const_cast<LPTSTR>(m_identity.c_str()) // UserName
};
if (!CredWrite(&cred, 0))
throw win_runtime_error(__FUNCTION__ " CredWrite failed.");
}
void eap::credentials::retrieve(_In_z_ LPCTSTR pszTargetName, _In_ unsigned int level)
{
assert(pszTargetName);
// Read credentials.
unique_ptr<CREDENTIAL, CredFree_delete<CREDENTIAL> > cred;
if (!CredRead(target_name(pszTargetName, level).c_str(), CRED_TYPE_GENERIC, 0, (PCREDENTIAL*)&cred))
throw win_runtime_error(__FUNCTION__ " CredRead failed.");
if (cred->UserName)
m_identity = cred->UserName;
else
m_identity.clear();
wstring xpath(pszTargetName);
m_module.log_config((xpath + L"/Identity").c_str(), m_identity.c_str());
}
LPCTSTR eap::credentials::target_suffix() const
{
return _T("id");
}
wstring eap::credentials::get_identity() const
{
return m_identity;
@ -163,6 +221,51 @@ tstring eap::credentials::get_name() const
}
eap::credentials::source_t eap::credentials::combine(
_In_ DWORD dwFlags,
_In_ HANDLE hTokenImpersonateUser,
_In_opt_ const credentials *cred_cached,
_In_ const config_method &cfg,
_In_opt_z_ LPCTSTR pszTargetName)
{
UNREFERENCED_PARAMETER(dwFlags);
if (cred_cached) {
// Using EAP service cached credentials.
*this = *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);
return source_cache;
}
auto cfg_with_cred = dynamic_cast<const config_method_with_cred*>(&cfg);
if (cfg_with_cred && cfg_with_cred->m_use_cred) {
// Using configured credentials.
*this = *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);
return source_config;
}
if (pszTargetName) {
// Switch user context.
user_impersonator impersonating(hTokenImpersonateUser);
try {
credentials cred_loaded(m_module);
cred_loaded.retrieve(pszTargetName, cfg.m_level);
// Using stored credentials.
*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);
return source_storage;
} catch (...) {
// Not actually an error.
}
}
return source_unknown;
}
//////////////////////////////////////////////////////////////////////
// eap::credentials_pass
//////////////////////////////////////////////////////////////////////