config_method split into config_method and config_method_with_cred<>

This commit is contained in:
Simon Rozman 2016-07-21 22:01:08 +02:00
parent ac88d55fe4
commit 6ae8029a47
20 changed files with 567 additions and 332 deletions

View File

@ -34,6 +34,11 @@ namespace eap
///
class config_method;
///
/// Base class for method with credentials
///
template <class _Tcred> class config_method_with_cred;
///
/// Base class for single provider configuration storage
///
@ -201,10 +206,6 @@ namespace eap
};
// Forward declaration, otherwise we would have to merge Credentials.h here.
class credentials;
class config_method : public config
{
public:
@ -247,6 +248,101 @@ namespace eap
///
config_method& operator=(_Inout_ config_method &&other);
///
/// Returns EAP method type of this configuration
///
/// \returns One of `eap::type_t` constants.
///
virtual type_t get_method_id() const = 0;
};
template <class _Tcred>
class config_method_with_cred : public config_method
{
public:
///
/// Constructs configuration
///
/// \param[in] mod Reference of the EAP module to use for global services
///
config_method_with_cred(_In_ module &mod) :
m_allow_save(true),
m_use_preshared(false),
m_preshared(mod),
config_method(mod)
{
}
///
/// Copies configuration
///
/// \param[in] other Configuration to copy from
///
config_method_with_cred(_In_ const config_method_with_cred<_Tcred> &other) :
m_allow_save(other.m_allow_save),
m_use_preshared(other.m_use_preshared),
m_preshared(other.m_preshared),
config_method(other)
{
}
///
/// Moves configuration
///
/// \param[in] other Configuration to move from
///
config_method_with_cred(_Inout_ config_method_with_cred<_Tcred> &&other) :
m_allow_save(std::move(other.m_allow_save)),
m_use_preshared(std::move(other.m_use_preshared)),
m_preshared(std::move(other.m_preshared)),
config_method(std::move(other))
{
}
///
/// Copies configuration
///
/// \param[in] other Configuration to copy from
///
/// \returns Reference to this object
///
config_method_with_cred& operator=(_In_ const config_method_with_cred<_Tcred> &other)
{
if (this != &other) {
(config_method&)*this = other;
m_allow_save = other.m_allow_save;
m_use_preshared = other.m_use_preshared;
m_preshared = other.m_preshared;
}
return *this;
}
///
/// Moves configuration
///
/// \param[in] other Configuration to move from
///
/// \returns Reference to this object
///
config_method_with_cred& operator=(_Inout_ config_method_with_cred<_Tcred> &&other)
{
if (this != &other) {
(config_method&)*this = std::move(other );
m_allow_save = std::move(other.m_allow_save );
m_use_preshared = std::move(other.m_use_preshared);
m_preshared = std::move(other.m_preshared );
}
return *this;
}
/// \name XML configuration management
/// @{
@ -261,7 +357,33 @@ namespace eap
/// - \c true if succeeded
/// - \c false otherwise. See \p ppEapError for details.
///
virtual bool save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR **ppEapError) const;
virtual bool save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR **ppEapError) const
{
assert(pDoc);
assert(pConfigRoot);
assert(ppEapError);
const winstd::bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata");
DWORD dwResult;
// <ClientSideCredential>
winstd::com_obj<IXMLDOMElement> pXmlElClientSideCredential;
if ((dwResult = eapxml::create_element(pDoc, pConfigRoot, winstd::bstr(L"eap-metadata:ClientSideCredential"), winstd::bstr(L"ClientSideCredential"), bstrNamespace, &pXmlElClientSideCredential)) != ERROR_SUCCESS) {
*ppEapError = m_module.make_error(dwResult, _T(__FUNCTION__) _T(" Error creating <ClientSideCredential> element."));
return false;
}
// <ClientSideCredential>/<allow-save>
if ((dwResult = eapxml::put_element_value(pDoc, pXmlElClientSideCredential, winstd::bstr(L"allow-save"), bstrNamespace, m_allow_save)) != ERROR_SUCCESS) {
*ppEapError = m_module.make_error(dwResult, _T(__FUNCTION__) _T(" Error creating <allow-save> element."));
return false;
}
if (m_use_preshared && !m_preshared.save(pDoc, pXmlElClientSideCredential, ppEapError))
return false;
return true;
}
///
/// Load configuration from XML document
@ -273,7 +395,39 @@ namespace eap
/// - \c true if succeeded
/// - \c false otherwise. See \p ppEapError for details.
///
virtual bool load(_In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR **ppEapError);
virtual bool load(_In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR **ppEapError)
{
assert(pConfigRoot);
assert(ppEapError);
m_allow_save = true;
m_use_preshared = false;
m_preshared.clear();
// <ClientSideCredential>
winstd::com_obj<IXMLDOMElement> pXmlElClientSideCredential;
if (eapxml::select_element(pConfigRoot, winstd::bstr(L"eap-metadata:ClientSideCredential"), &pXmlElClientSideCredential) == ERROR_SUCCESS) {
std::wstring xpath(eapxml::get_xpath(pXmlElClientSideCredential));
// <allow-save>
eapxml::get_element_value(pXmlElClientSideCredential, winstd::bstr(L"eap-metadata:allow-save"), &m_allow_save);
m_module.log_config((xpath + L"/allow-save").c_str(), m_allow_save);
_Tcred preshared(m_module);
if (preshared.load(pXmlElClientSideCredential, ppEapError)) {
m_use_preshared = true;
m_preshared = std::move(preshared);
} else {
// This is not really an error - merely an indication pre-shared credentials are unavailable.
if (*ppEapError) {
m_module.free_error_memory(*ppEapError);
*ppEapError = NULL;
}
}
}
return true;
}
/// @}
@ -285,40 +439,49 @@ namespace eap
///
/// \param[inout] cursor Memory cursor
///
virtual void operator<<(_Inout_ cursor_out &cursor) const;
virtual void operator<<(_Inout_ cursor_out &cursor) const
{
config_method::operator<<(cursor);
cursor << m_allow_save;
cursor << m_use_preshared;
cursor << m_preshared;
}
///
/// Returns packed size of a configuration
///
/// \returns Size of data when packed (in bytes)
///
virtual size_t get_pk_size() const;
virtual size_t get_pk_size() const
{
return
config_method::get_pk_size() +
pksizeof(m_allow_save ) +
pksizeof(m_use_preshared) +
pksizeof(m_preshared );
}
///
/// Unpacks a configuration
///
/// \param[inout] cursor Memory cursor
///
virtual void operator>>(_Inout_ cursor_in &cursor);
virtual void operator>>(_Inout_ cursor_in &cursor)
{
config_method::operator>>(cursor);
cursor >> m_allow_save;
cursor >> m_use_preshared;
cursor >> m_preshared;
}
/// @}
///
/// Makes a new set of credentials for the given method type
///
virtual credentials* make_credentials() const = 0;
///
/// Returns EAP method type of this configuration
///
/// \returns One of `eap::type_t` constants.
///
virtual type_t get_method_id() const = 0;
public:
bool m_allow_save; ///< Are credentials allowed to be saved to Windows Credential Manager?
std::wstring m_anonymous_identity; ///< Anonymous identity
std::unique_ptr<credentials> m_preshared; ///< Pre-shared credentials
bool m_allow_save; ///< Are credentials allowed to be saved to Windows Credential Manager?
bool m_use_preshared; ///< Use pre-shared credentials
_Tcred m_preshared; ///< Pre-shared credentials
};

View File

@ -562,13 +562,13 @@ namespace eap
return false;
cursor_in cursor = { data.data(), data.data() + data.size() };
cursor >> record;
#else
UNREFERENCED_PARAMETER(ppEapError);
cursor_in cursor = { pDataIn, pDataIn + dwDataInSize };
cursor >> record;
#endif
cursor >> record;
assert(cursor.ptr == cursor.ptr_end);
return true;
}
@ -593,6 +593,9 @@ namespace eap
_Out_ DWORD *pdwDataOutSize,
_Out_ EAP_ERROR **ppEapError)
{
assert(ppDataOut);
assert(pdwDataOutSize);
#if EAP_ENCRYPT_BLOBS
// Allocate BLOB.
std::vector<unsigned char, winstd::sanitizing_allocator<unsigned char> > data;
@ -601,7 +604,7 @@ namespace eap
// Pack to BLOB.
cursor_out cursor = { data.data(), data.data() + data.size() };
cursor << record;
data.resize(cursor.ptr - &data.front());
assert(cursor.ptr == cursor.ptr_end);
// Prepare cryptographics provider.
winstd::crypt_prov cp;
@ -616,8 +619,6 @@ namespace eap
return false;
// Copy encrypted BLOB to output.
assert(ppDataOut);
assert(pdwDataOutSize);
*pdwDataOutSize = (DWORD)data_enc.size();
*ppDataOut = alloc_memory(*pdwDataOutSize);
if (!*ppDataOut) {
@ -627,8 +628,6 @@ namespace eap
memcpy(*ppDataOut, data_enc.data(), *pdwDataOutSize);
#else
// Allocate BLOB.
assert(ppDataOut);
assert(pdwDataOutSize);
*pdwDataOutSize = (DWORD)pksizeof(record);
*ppDataOut = alloc_memory(*pdwDataOutSize);
if (!*ppDataOut) {
@ -639,6 +638,7 @@ namespace eap
// Pack to BLOB.
cursor_out cursor = { *ppDataOut, *ppDataOut + *pdwDataOutSize };
cursor << record;
assert(cursor.ptr == cursor.ptr_end);
*pdwDataOutSize = cursor.ptr - *ppDataOut;
#endif

View File

@ -103,39 +103,25 @@ void eap::config::operator>>(_Inout_ cursor_in &cursor)
// eap::config_method
//////////////////////////////////////////////////////////////////////
eap::config_method::config_method(_In_ module &mod) :
m_allow_save(true),
config(mod)
eap::config_method::config_method(_In_ module &mod) : config(mod)
{
}
eap::config_method::config_method(_In_ const config_method &other) :
m_allow_save(other.m_allow_save),
m_anonymous_identity(other.m_anonymous_identity),
m_preshared(other.m_preshared ? (credentials*)other.m_preshared->clone() : nullptr),
config(other)
eap::config_method::config_method(_In_ const config_method &other) : config(other)
{
}
eap::config_method::config_method(_Inout_ config_method &&other) :
m_allow_save(std::move(other.m_allow_save)),
m_anonymous_identity(std::move(other.m_anonymous_identity)),
m_preshared(std::move(other.m_preshared)),
config(std::move(other))
eap::config_method::config_method(_Inout_ config_method &&other) : config(std::move(other))
{
}
eap::config_method& eap::config_method::operator=(_In_ const config_method &other)
{
if (this != &other) {
(config&)*this = other;
m_allow_save = other.m_allow_save;
m_anonymous_identity = other.m_anonymous_identity;
m_preshared.reset(other.m_preshared ? (credentials*)other.m_preshared->clone() : nullptr);
}
if (this != &other)
(config&)*this = other;
return *this;
}
@ -143,142 +129,13 @@ eap::config_method& eap::config_method::operator=(_In_ const config_method &othe
eap::config_method& eap::config_method::operator=(_Inout_ config_method &&other)
{
if (this != &other) {
(config&&)*this = std::move(other);
m_allow_save = std::move(other.m_allow_save);
m_anonymous_identity = std::move(other.m_anonymous_identity);
m_preshared = std::move(other.m_preshared);
}
if (this != &other)
(config&&)*this = std::move(other);
return *this;
}
bool eap::config_method::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR **ppEapError) const
{
assert(pDoc);
assert(pConfigRoot);
assert(ppEapError);
if (!config::save(pDoc, pConfigRoot, ppEapError))
return false;
const bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata");
DWORD dwResult;
// <ClientSideCredential>
com_obj<IXMLDOMElement> pXmlElClientSideCredential;
if ((dwResult = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:ClientSideCredential"), bstr(L"ClientSideCredential"), bstrNamespace, &pXmlElClientSideCredential)) != ERROR_SUCCESS) {
*ppEapError = m_module.make_error(dwResult, _T(__FUNCTION__) _T(" Error creating <ClientSideCredential> element."));
return false;
}
// <ClientSideCredential>/<allow-save>
if ((dwResult = eapxml::put_element_value(pDoc, pXmlElClientSideCredential, bstr(L"allow-save"), bstrNamespace, m_allow_save)) != ERROR_SUCCESS) {
*ppEapError = m_module.make_error(dwResult, _T(__FUNCTION__) _T(" Error creating <allow-save> element."));
return false;
}
// <ClientSideCredential>/<AnonymousIdentity>
if (!m_anonymous_identity.empty())
if ((dwResult = eapxml::put_element_value(pDoc, pXmlElClientSideCredential, bstr(L"AnonymousIdentity"), bstrNamespace, bstr(m_anonymous_identity))) != ERROR_SUCCESS) {
*ppEapError = m_module.make_error(dwResult, _T(__FUNCTION__) _T(" Error creating <AnonymousIdentity> element."));
return false;
}
if (m_preshared)
if (!m_preshared->save(pDoc, pXmlElClientSideCredential, ppEapError))
return false;
return true;
}
bool eap::config_method::load(_In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR **ppEapError)
{
assert(pConfigRoot);
assert(ppEapError);
if (!config::load(pConfigRoot, ppEapError))
return false;
m_allow_save = true;
m_preshared.reset(nullptr);
m_anonymous_identity.clear();
// <ClientSideCredential>
com_obj<IXMLDOMElement> pXmlElClientSideCredential;
if (eapxml::select_element(pConfigRoot, bstr(L"eap-metadata:ClientSideCredential"), &pXmlElClientSideCredential) == ERROR_SUCCESS) {
wstring xpath(eapxml::get_xpath(pXmlElClientSideCredential));
// <allow-save>
eapxml::get_element_value(pXmlElClientSideCredential, bstr(L"eap-metadata:allow-save"), &m_allow_save);
m_module.log_config((xpath + L"/allow-save").c_str(), m_allow_save);
// <AnonymousIdentity>
eapxml::get_element_value(pXmlElClientSideCredential, bstr(L"eap-metadata:AnonymousIdentity"), m_anonymous_identity);
m_module.log_config((xpath + L"/AnonymousIdentity").c_str(), m_anonymous_identity.c_str());
unique_ptr<credentials> preshared(make_credentials());
assert(preshared);
if (preshared->load(pXmlElClientSideCredential, ppEapError)) {
m_preshared = std::move(preshared);
} else {
// This is not really an error - merely an indication pre-shared credentials are unavailable.
if (*ppEapError) {
m_module.free_error_memory(*ppEapError);
*ppEapError = NULL;
}
}
}
return true;
}
void eap::config_method::operator<<(_Inout_ cursor_out &cursor) const
{
config::operator<<(cursor);
cursor << m_allow_save ;
cursor << m_anonymous_identity;
if (m_preshared) {
cursor << true;
cursor << *m_preshared;
} else
cursor << false;
}
size_t eap::config_method::get_pk_size() const
{
return
config::get_pk_size() +
pksizeof(m_allow_save ) +
pksizeof(m_anonymous_identity) +
(m_preshared ?
pksizeof(true ) +
pksizeof(*m_preshared) :
pksizeof(false ));
}
void eap::config_method::operator>>(_Inout_ cursor_in &cursor)
{
config::operator>>(cursor);
cursor >> m_allow_save ;
cursor >> m_anonymous_identity;
bool use_preshared;
cursor >> use_preshared;
if (use_preshared) {
m_preshared.reset(make_credentials());
assert(m_preshared);
cursor >> *m_preshared;
} else
m_preshared.reset(nullptr);
}
//////////////////////////////////////////////////////////////////////
// eap::config_provider
//////////////////////////////////////////////////////////////////////

View File

@ -47,7 +47,7 @@ class wxEAPProviderLockedPanel;
///
/// Base template for credential configuration panel
///
template <class _wxT> class wxEAPCredentialsConfigPanel;
template <class _Tcred, class _wxT> class wxEAPCredentialsConfigPanel;
///
/// Base template for all credential entry panels
@ -216,23 +216,23 @@ protected:
};
template <class _wxT>
template <class _Tcred, class _wxT>
class wxEAPCredentialsConfigPanel : public wxEAPCredentialsConfigPanelBase
{
public:
///
/// Constructs a credential configuration panel
///
/// \param[inout] prov Provider configuration data
/// \param[in] prov Provider configuration data
/// \param[inout] cfg Configuration data
/// \param[in] pszCredTarget Target name of credentials in Windows Credential Manager. Can be further decorated to create final target name.
/// \param[in] parent Parent window
///
wxEAPCredentialsConfigPanel(const eap::config_provider &prov, eap::config_method &cfg, LPCTSTR pszCredTarget, wxWindow *parent) :
wxEAPCredentialsConfigPanel(const eap::config_provider &prov, eap::config_method_with_cred<_Tcred> &cfg, LPCTSTR pszCredTarget, wxWindow *parent) :
m_prov(prov),
m_cfg(cfg),
m_target(pszCredTarget),
m_cred(cfg.make_credentials()),
m_cred(cfg.m_module),
wxEAPCredentialsConfigPanelBase(parent)
{
// Load and set icon.
@ -253,12 +253,12 @@ protected:
m_preshared_set ->Enable(false);
}
if (!m_cfg.m_preshared) {
if (!m_cfg.m_use_preshared)
m_own->SetValue(true);
} else {
else
m_preshared->SetValue(true);
m_cred.reset((eap::credentials*)m_cfg.m_preshared->clone());
}
m_cred = m_cfg.m_preshared;
return wxEAPCredentialsConfigPanelBase::TransferDataToWindow();
}
@ -270,7 +270,8 @@ protected:
if (!m_prov.m_read_only) {
// This is not a provider-locked configuration. Save the data.
m_cfg.m_preshared.reset(m_own->GetValue() ? nullptr : (eap::credentials*)m_cred->clone());
m_cfg.m_use_preshared = !m_own->GetValue();
m_cfg.m_preshared = m_cred;
}
return true;
@ -285,7 +286,7 @@ protected:
if (m_cfg.m_allow_save) {
bool has_own;
std::unique_ptr<CREDENTIAL, winstd::CredFree_delete<CREDENTIAL> > cred;
if (CredRead(m_cred->target_name(m_target.c_str()).c_str(), CRED_TYPE_GENERIC, 0, (PCREDENTIAL*)&cred)) {
if (CredRead(m_cred.target_name(m_target.c_str()).c_str(), CRED_TYPE_GENERIC, 0, (PCREDENTIAL*)&cred)) {
m_own_identity->SetValue(cred->UserName && cred->UserName[0] != 0 ? cred->UserName : _("<blank>"));
has_own = true;
} else if ((dwResult = GetLastError()) == ERROR_NOT_FOUND) {
@ -313,7 +314,7 @@ protected:
m_own_clear ->Enable(false);
}
m_preshared_identity->SetValue(!m_cred->empty() ? m_cred->get_name() : _("<blank>"));
m_preshared_identity->SetValue(!m_cred.empty() ? m_cred.get_name() : _("<blank>"));
if (!m_prov.m_read_only) {
// This is not a provider-locked configuration. Selectively enable/disable controls.
@ -334,7 +335,8 @@ protected:
wxEAPCredentialsDialog dlg(m_prov, this);
_wxT *panel = new _wxT(m_prov, *m_cred, m_target.c_str(), &dlg, true);
_Tcred cred(m_cfg.m_module);
_wxT *panel = new _wxT(m_prov, m_cfg, cred, m_target.c_str(), &dlg, true);
dlg.AddContents((wxPanel**)&panel, 1);
dlg.ShowModal();
@ -345,7 +347,7 @@ protected:
{
UNREFERENCED_PARAMETER(event);
if (!CredDelete(m_cred->target_name(m_target.c_str()).c_str(), CRED_TYPE_GENERIC, 0))
if (!CredDelete(m_cred.target_name(m_target.c_str()).c_str(), CRED_TYPE_GENERIC, 0))
wxLogError(_("Deleting credentials failed (error %u)."), GetLastError());
}
@ -356,7 +358,7 @@ protected:
wxEAPCredentialsDialog dlg(m_prov, this);
_wxT *panel = new _wxT(m_prov, *m_cred, _T(""), &dlg, true);
_wxT *panel = new _wxT(m_prov, m_cfg, m_cred, _T(""), &dlg, true);
dlg.AddContents((wxPanel**)&panel, 1);
dlg.ShowModal();
@ -365,14 +367,14 @@ protected:
/// \endcond
protected:
const eap::config_provider &m_prov; ///< EAP provider
eap::config_method &m_cfg; ///< EAP method configuration
winstd::library m_shell32; ///< shell32.dll resource library reference
wxIcon m_icon; ///< Panel icon
winstd::tstring m_target; ///< Credential Manager target
const eap::config_provider &m_prov; ///< EAP provider
eap::config_method_with_cred<_Tcred> &m_cfg; ///< EAP method configuration
winstd::library m_shell32; ///< shell32.dll resource library reference
wxIcon m_icon; ///< Panel icon
winstd::tstring m_target; ///< Credential Manager target
private:
std::unique_ptr<eap::credentials> m_cred; ///< Temporary credential data
_Tcred m_cred; ///< Temporary credential data
};
@ -383,12 +385,16 @@ public:
///
/// Constructs a credentials panel
///
/// \param[in] prov Provider configuration data
/// \param[in] cfg Configuration data
/// \param[inout] cred Credentials data
/// \param[in] pszCredTarget Target name of credentials in Windows Credential Manager. Can be further decorated to create final target name.
/// \param[in] parent Parent window
/// \param[in] is_config Is this panel used to pre-enter credentials? When \c true, the "Remember" checkbox is always selected and disabled.
///
wxEAPCredentialsPanelBase(eap::credentials &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config = false) :
wxEAPCredentialsPanelBase(const eap::config_provider &prov, const eap::config_method &cfg, eap::credentials &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config = false) :
m_prov(prov),
m_cfg(cfg),
m_cred(cred),
m_target(pszCredTarget),
_Tbase(parent)
@ -447,8 +453,10 @@ protected:
/// \endcond
protected:
eap::credentials &m_cred; ///< Generic credentials
winstd::tstring m_target; ///< Credential Manager target
const eap::config_provider &m_prov; ///< Provider configuration
const eap::config_method &m_cfg; ///< Method configuration
eap::credentials &m_cred; ///< Generic credentials
winstd::tstring m_target; ///< Credential Manager target
};
@ -458,13 +466,14 @@ public:
///
/// Constructs a password credentials panel
///
/// \param[inout] prov EAP provider
/// \param[in] prov Provider configuration data
/// \param[in] cfg Configuration data
/// \param[inout] cred Credentials data
/// \param[in] pszCredTarget Target name of credentials in Windows Credential Manager. Can be further decorated to create final target name.
/// \param[in] parent Parent window
/// \param[in] is_config Is this panel used to pre-enter credentials? When \c true, the "Remember" checkbox is always selected and disabled.
///
wxPasswordCredentialsPanel(const eap::config_provider &prov, eap::credentials &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config = false);
wxPasswordCredentialsPanel(const eap::config_provider &prov, const eap::config_method &cfg, eap::credentials &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config = false);
protected:
/// \cond internal

View File

@ -155,28 +155,28 @@ bool wxEAPProviderLockedPanel::AcceptsFocusFromKeyboard() const
// wxPasswordCredentialsPanel
//////////////////////////////////////////////////////////////////////
wxPasswordCredentialsPanel::wxPasswordCredentialsPanel(const eap::config_provider &prov, eap::credentials &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config) :
wxPasswordCredentialsPanel::wxPasswordCredentialsPanel(const eap::config_provider &prov, const eap::config_method &cfg, eap::credentials &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config) :
m_cred((eap::credentials_pass&)cred),
wxEAPCredentialsPanelBase<wxEAPCredentialsPanelPassBase>(cred, pszCredTarget, parent, is_config)
wxEAPCredentialsPanelBase<wxEAPCredentialsPanelPassBase>(prov, cfg, cred, pszCredTarget, parent, is_config)
{
// Load and set icon.
if (m_shell32.load(_T("shell32.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE))
wxSetIconFromResource(m_credentials_icon, m_icon, m_shell32, MAKEINTRESOURCE(269));
bool layout = false;
if (!prov.m_lbl_alt_credential.empty()) {
m_credentials_label->SetLabel(prov.m_lbl_alt_credential);
if (!m_prov.m_lbl_alt_credential.empty()) {
m_credentials_label->SetLabel(m_prov.m_lbl_alt_credential);
m_credentials_label->Wrap( 446 );
layout = true;
}
if (!prov.m_lbl_alt_identity.empty()) {
m_identity_label->SetLabel(prov.m_lbl_alt_identity);
if (!m_prov.m_lbl_alt_identity.empty()) {
m_identity_label->SetLabel(m_prov.m_lbl_alt_identity);
layout = true;
}
if (!prov.m_lbl_alt_password.empty()) {
m_password_label->SetLabel(prov.m_lbl_alt_password);
if (!m_prov.m_lbl_alt_password.empty()) {
m_password_label->SetLabel(m_prov.m_lbl_alt_password);
layout = true;
}

View File

@ -40,7 +40,7 @@ namespace eap
namespace eap
{
class config_method_pap : public config_method
class config_method_pap : public config_method_with_cred<credentials_pap>
{
public:
///
@ -89,11 +89,6 @@ namespace eap
///
virtual config* clone() const;
///
/// Makes new set of credentials for the given method type
///
virtual credentials* make_credentials() const;
///
/// Returns EAP method type of this configuration
///

View File

@ -25,19 +25,19 @@
// eap::config_method_pap
//////////////////////////////////////////////////////////////////////
eap::config_method_pap::config_method_pap(_In_ module &mod) : config_method(mod)
eap::config_method_pap::config_method_pap(_In_ module &mod) : config_method_with_cred<credentials_pap>(mod)
{
}
eap::config_method_pap::config_method_pap(_In_ const config_method_pap &other) :
config_method(other)
config_method_with_cred<credentials_pap>(other)
{
}
eap::config_method_pap::config_method_pap(_Inout_ config_method_pap &&other) :
config_method(std::move(other))
config_method_with_cred<credentials_pap>(std::move(other))
{
}
@ -45,7 +45,7 @@ eap::config_method_pap::config_method_pap(_Inout_ config_method_pap &&other) :
eap::config_method_pap& eap::config_method_pap::operator=(_In_ const config_method_pap &other)
{
if (this != &other)
(config_method&)*this = other;
(config_method_with_cred<credentials_pap>&)*this = other;
return *this;
}
@ -54,7 +54,7 @@ eap::config_method_pap& eap::config_method_pap::operator=(_In_ const config_meth
eap::config_method_pap& eap::config_method_pap::operator=(_Inout_ config_method_pap &&other)
{
if (this != &other)
(config_method&&)*this = std::move(other);
(config_method_with_cred<credentials_pap>&&)*this = std::move(other);
return *this;
}
@ -66,12 +66,6 @@ eap::config* eap::config_method_pap::clone() const
}
eap::credentials* eap::config_method_pap::make_credentials() const
{
return new credentials_pap(m_module);
}
eap::type_t eap::config_method_pap::get_method_id() const
{
return eap::type_pap;

View File

@ -25,13 +25,18 @@
///
/// PAP credential configuration panel
///
typedef wxEAPCredentialsConfigPanel<wxPasswordCredentialsPanel> wxPAPCredentialsConfigPanel;
typedef wxEAPCredentialsConfigPanel<eap::credentials_pap, wxPasswordCredentialsPanel> wxPAPCredentialsConfigPanel;
///
/// PAP configuration panel
///
class wxPAPConfigPanel;
///
/// PAP credential entry panel
///
typedef wxPasswordCredentialsPanel wxPAPCredentialsPanel;
#pragma once
#include <wx/panel.h>

View File

@ -54,7 +54,7 @@ namespace eap
namespace eap
{
class config_method_tls : public config_method
class config_method_tls : public config_method_with_cred<credentials_tls>
{
public:
///
@ -159,11 +159,6 @@ namespace eap
/// @}
///
/// Makes new set of credentials for the given method type
///
virtual credentials* make_credentials() const;
///
/// Returns EAP method type of this configuration
///

View File

@ -66,7 +66,7 @@ tstring eap::get_cert_title(PCCERT_CONTEXT cert)
// eap::config_method_tls
//////////////////////////////////////////////////////////////////////
eap::config_method_tls::config_method_tls(_In_ module &mod) : config_method(mod)
eap::config_method_tls::config_method_tls(_In_ module &mod) : config_method_with_cred<credentials_tls>(mod)
{
}
@ -74,7 +74,7 @@ eap::config_method_tls::config_method_tls(_In_ module &mod) : config_method(mod)
eap::config_method_tls::config_method_tls(_In_ const config_method_tls &other) :
m_trusted_root_ca(other.m_trusted_root_ca),
m_server_names(other.m_server_names),
config_method(other)
config_method_with_cred<credentials_tls>(other)
{
}
@ -82,7 +82,7 @@ eap::config_method_tls::config_method_tls(_In_ const config_method_tls &other) :
eap::config_method_tls::config_method_tls(_Inout_ config_method_tls &&other) :
m_trusted_root_ca(std::move(other.m_trusted_root_ca)),
m_server_names(std::move(other.m_server_names)),
config_method(std::move(other))
config_method_with_cred<credentials_tls>(std::move(other))
{
}
@ -90,7 +90,7 @@ eap::config_method_tls::config_method_tls(_Inout_ config_method_tls &&other) :
eap::config_method_tls& eap::config_method_tls::operator=(_In_ const config_method_tls &other)
{
if (this != &other) {
(config_method&)*this = other;
(config_method_with_cred<credentials_tls>&)*this = other;
m_trusted_root_ca = other.m_trusted_root_ca;
m_server_names = other.m_server_names;
}
@ -102,7 +102,7 @@ eap::config_method_tls& eap::config_method_tls::operator=(_In_ const config_meth
eap::config_method_tls& eap::config_method_tls::operator=(_Inout_ config_method_tls &&other)
{
if (this != &other) {
(config_method&&)*this = std::move(other);
(config_method_with_cred<credentials_tls>&&)*this = std::move(other);
m_trusted_root_ca = std::move(other.m_trusted_root_ca);
m_server_names = std::move(other.m_server_names);
}
@ -123,7 +123,7 @@ bool eap::config_method_tls::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *
assert(pConfigRoot);
assert(ppEapError);
if (!config_method::save(pDoc, pConfigRoot, ppEapError))
if (!config_method_with_cred<credentials_tls>::save(pDoc, pConfigRoot, ppEapError))
return false;
const bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata");
@ -182,7 +182,7 @@ bool eap::config_method_tls::load(_In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR
{
assert(pConfigRoot);
if (!config_method::load(pConfigRoot, ppEapError))
if (!config_method_with_cred<credentials_tls>::load(pConfigRoot, ppEapError))
return false;
std::wstring xpath(eapxml::get_xpath(pConfigRoot));
@ -258,7 +258,7 @@ bool eap::config_method_tls::load(_In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR
void eap::config_method_tls::operator<<(_Inout_ cursor_out &cursor) const
{
config_method::operator<<(cursor);
config_method_with_cred<credentials_tls>::operator<<(cursor);
cursor << m_trusted_root_ca;
cursor << m_server_names ;
}
@ -267,7 +267,7 @@ void eap::config_method_tls::operator<<(_Inout_ cursor_out &cursor) const
size_t eap::config_method_tls::get_pk_size() const
{
return
config_method::get_pk_size() +
config_method_with_cred<credentials_tls>::get_pk_size() +
pksizeof(m_trusted_root_ca) +
pksizeof(m_server_names );
}
@ -275,18 +275,12 @@ size_t eap::config_method_tls::get_pk_size() const
void eap::config_method_tls::operator>>(_Inout_ cursor_in &cursor)
{
config_method::operator>>(cursor);
config_method_with_cred<credentials_tls>::operator>>(cursor);
cursor >> m_trusted_root_ca;
cursor >> m_server_names ;
}
eap::credentials* eap::config_method_tls::make_credentials() const
{
return new credentials_tls(m_module);
}
eap::type_t eap::config_method_tls::get_method_id() const
{
return type_tls;

View File

@ -68,7 +68,7 @@ class wxTLSServerTrustPanel;
///
/// TLS credentials configuration panel
///
typedef wxEAPCredentialsConfigPanel<wxTLSCredentialsPanel> wxTLSCredentialsConfigPanel;
typedef wxEAPCredentialsConfigPanel<eap::credentials_tls, wxTLSCredentialsPanel> wxTLSCredentialsConfigPanel;
///
/// TLS configuration panel
@ -254,7 +254,14 @@ public:
///
/// Constructs a configuration panel
///
wxTLSCredentialsPanel(const eap::config_provider &prov, eap::credentials &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config = false);
/// \param[in] prov Provider configuration data
/// \param[in] cfg Configuration data
/// \param[inout] cred Credentials data
/// \param[in] pszCredTarget Target name of credentials in Windows Credential Manager. Can be further decorated to create final target name.
/// \param[in] parent Parent window
/// \param[in] is_config Is this panel used to pre-enter credentials? When \c true, the "Remember" checkbox is always selected and disabled.
///
wxTLSCredentialsPanel(const eap::config_provider &prov, const eap::config_method &cfg, eap::credentials &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config = false);
protected:
/// \cond internal

View File

@ -311,12 +311,10 @@ bool wxFQDNListValidator::Parse(const wxString &val_in, size_t i_start, size_t i
// wxTLSCredentialsPanel
//////////////////////////////////////////////////////////////////////
wxTLSCredentialsPanel::wxTLSCredentialsPanel(const eap::config_provider &prov, eap::credentials &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config) :
wxTLSCredentialsPanel::wxTLSCredentialsPanel(const eap::config_provider &prov, const eap::config_method &cfg, eap::credentials &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config) :
m_cred((eap::credentials_tls&)cred),
wxEAPCredentialsPanelBase<wxTLSCredentialsPanelBase>(cred, pszCredTarget, parent, is_config)
wxEAPCredentialsPanelBase<wxTLSCredentialsPanelBase>(prov, cfg, cred, pszCredTarget, parent, is_config)
{
UNREFERENCED_PARAMETER(prov);
// Load and set icon.
if (m_shell32.load(_T("shell32.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE))
wxSetIconFromResource(m_credentials_icon, m_icon, m_shell32, MAKEINTRESOURCE(269));

View File

@ -40,7 +40,7 @@ namespace eap
namespace eap {
class config_method_ttls : public config_method_tls
class config_method_ttls : public config_method
{
public:
///
@ -150,7 +150,14 @@ namespace eap {
///
virtual eap::type_t get_method_id() const;
///
/// Generates public identity using current configuration and given credentials
///
std::wstring get_public_identity(const credentials &cred) const;
public:
config_method_tls m_outer; ///< Outer authentication configuration
std::unique_ptr<config> m_inner; ///< Inner authentication configuration
std::wstring m_anonymous_identity; ///< Anonymous identity
};
}

View File

@ -36,7 +36,7 @@ namespace eap
namespace eap
{
class credentials_ttls : public credentials_tls
class credentials_ttls : public credentials
{
public:
///
@ -189,6 +189,7 @@ namespace eap
/// @}
public:
credentials_tls m_outer; ///< Outer credentials
std::unique_ptr<credentials> m_inner; ///< Inner credentials
};
}

View File

@ -29,21 +29,26 @@ using namespace winstd;
//////////////////////////////////////////////////////////////////////
eap::config_method_ttls::config_method_ttls(_In_ module &mod) :
config_method_tls(mod)
m_outer(mod),
config_method(mod)
{
}
eap::config_method_ttls::config_method_ttls(const _In_ config_method_ttls &other) :
m_outer(other.m_outer),
m_inner(other.m_inner ? (config_method*)other.m_inner->clone() : nullptr),
config_method_tls(other)
m_anonymous_identity(other.m_anonymous_identity),
config_method(other)
{
}
eap::config_method_ttls::config_method_ttls(_Inout_ config_method_ttls &&other) :
m_outer(std::move(other.m_outer)),
m_inner(std::move(other.m_inner)),
config_method_tls(std::move(other))
m_anonymous_identity(std::move(other.m_anonymous_identity)),
config_method(std::move(other))
{
}
@ -51,8 +56,10 @@ eap::config_method_ttls::config_method_ttls(_Inout_ config_method_ttls &&other)
eap::config_method_ttls& eap::config_method_ttls::operator=(const _In_ config_method_ttls &other)
{
if (this != &other) {
(config_method_tls&)*this = other;
(config_method&)*this = other;
m_outer = other.m_outer;
m_inner.reset(other.m_inner ? (config_method*)other.m_inner->clone() : nullptr);
m_anonymous_identity = other.m_anonymous_identity;
}
return *this;
@ -62,8 +69,10 @@ eap::config_method_ttls& eap::config_method_ttls::operator=(const _In_ config_me
eap::config_method_ttls& eap::config_method_ttls::operator=(_Inout_ config_method_ttls &&other)
{
if (this != &other) {
(config_method_tls&&)*this = std::move(other);
m_inner = std::move(other.m_inner);
(config_method&&)*this = std::move(other);
m_outer = std::move(other.m_outer);
m_inner = std::move(other.m_inner);
m_anonymous_identity = std::move(other.m_anonymous_identity);
}
return *this;
@ -82,12 +91,29 @@ bool eap::config_method_ttls::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode
assert(pConfigRoot);
assert(ppEapError);
if (!config_method_tls::save(pDoc, pConfigRoot, ppEapError))
if (!config_method::save(pDoc, pConfigRoot, ppEapError))
return false;
const bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata");
DWORD dwResult;
// <ClientSideCredential>
com_obj<IXMLDOMElement> pXmlElClientSideCredential;
if ((dwResult = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:ClientSideCredential"), bstr(L"ClientSideCredential"), bstrNamespace, &pXmlElClientSideCredential)) != ERROR_SUCCESS) {
*ppEapError = m_module.make_error(dwResult, _T(__FUNCTION__) _T(" Error creating <ClientSideCredential> element."));
return false;
}
// <ClientSideCredential>/<AnonymousIdentity>
if (!m_anonymous_identity.empty())
if ((dwResult = eapxml::put_element_value(pDoc, pXmlElClientSideCredential, bstr(L"AnonymousIdentity"), bstrNamespace, bstr(m_anonymous_identity))) != ERROR_SUCCESS) {
*ppEapError = m_module.make_error(dwResult, _T(__FUNCTION__) _T(" Error creating <AnonymousIdentity> element."));
return false;
}
if (!m_outer.save(pDoc, pConfigRoot, ppEapError))
return false;
// <InnerAuthenticationMethod>
com_obj<IXMLDOMElement> pXmlElInnerAuthenticationMethod;
if ((dwResult = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:InnerAuthenticationMethod"), bstr(L"InnerAuthenticationMethod"), bstrNamespace, &pXmlElInnerAuthenticationMethod)) != ERROR_SUCCESS) {
@ -120,12 +146,27 @@ bool eap::config_method_ttls::load(_In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERRO
assert(ppEapError);
DWORD dwResult;
if (!config_method_tls::load(pConfigRoot, ppEapError))
if (!config_method::load(pConfigRoot, ppEapError))
return false;
std::wstring xpath(eapxml::get_xpath(pConfigRoot));
// Load inner authentication configuration (<InnerAuthenticationMethod>).
m_anonymous_identity.clear();
// <ClientSideCredential>
com_obj<IXMLDOMElement> pXmlElClientSideCredential;
if (eapxml::select_element(pConfigRoot, bstr(L"eap-metadata:ClientSideCredential"), &pXmlElClientSideCredential) == ERROR_SUCCESS) {
wstring xpathClientSideCredential(xpath + L"/ClientSideCredential");
// <AnonymousIdentity>
eapxml::get_element_value(pXmlElClientSideCredential, bstr(L"eap-metadata:AnonymousIdentity"), m_anonymous_identity);
m_module.log_config((xpathClientSideCredential + L"/AnonymousIdentity").c_str(), m_anonymous_identity.c_str());
}
if (!m_outer.load(pConfigRoot, ppEapError))
return false;
// <InnerAuthenticationMethod>
com_obj<IXMLDOMElement> pXmlElInnerAuthenticationMethod;
if ((dwResult = eapxml::select_element(pConfigRoot, bstr(L"eap-metadata:InnerAuthenticationMethod"), &pXmlElInnerAuthenticationMethod)) != ERROR_SUCCESS) {
*ppEapError = m_module.make_error(dwResult, _T(__FUNCTION__) _T(" Error selecting <InnerAuthenticationMethod> element."), _T("Please make sure profile XML is a valid ") _T(PRODUCT_NAME_STR) _T(" profile XML document."));
@ -160,7 +201,9 @@ bool eap::config_method_ttls::load(_In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERRO
void eap::config_method_ttls::operator<<(_Inout_ cursor_out &cursor) const
{
config_method_tls::operator<<(cursor);
config_method::operator<<(cursor);
cursor << m_outer;
if (m_inner) {
if (dynamic_cast<config_method_pap*>(m_inner.get())) {
cursor << type_pap;
@ -171,6 +214,8 @@ void eap::config_method_ttls::operator<<(_Inout_ cursor_out &cursor) const
}
} else
cursor << type_undefined;
cursor << m_anonymous_identity;
}
@ -190,14 +235,17 @@ size_t eap::config_method_ttls::get_pk_size() const
size_inner = pksizeof(type_undefined);
return
config_method_tls::get_pk_size() +
size_inner;
config_method::get_pk_size() +
pksizeof(m_outer) +
size_inner +
pksizeof(m_anonymous_identity);
}
void eap::config_method_ttls::operator>>(_Inout_ cursor_in &cursor)
{
config_method_tls::operator>>(cursor);
config_method::operator>>(cursor);
cursor >> m_outer;
type_t eap_type;
cursor >> eap_type;
@ -210,6 +258,8 @@ void eap::config_method_ttls::operator>>(_Inout_ cursor_in &cursor)
assert(0); // Unsupported inner authentication method type.
m_inner.reset(nullptr);
}
cursor >> m_anonymous_identity;
}
@ -217,3 +267,21 @@ eap::type_t eap::config_method_ttls::get_method_id() const
{
return type_ttls;
}
wstring eap::config_method_ttls::get_public_identity(const credentials &cred) const
{
if (m_anonymous_identity.empty()) {
// Use the true identity. Outer has the right-of-way.
return cred.get_identity();
} else if (m_anonymous_identity.compare(L"@") == 0) {
// Strip username part from identity (RFC 4822).
wstring identity(std::move(cred.get_identity()));
wstring::size_type offset = identity.find(L'@');
if (offset != wstring::npos) identity.erase(0, offset);
return identity;
} else {
// Use configured identity.
return m_anonymous_identity;
}
}

View File

@ -29,21 +29,24 @@ using namespace winstd;
//////////////////////////////////////////////////////////////////////
eap::credentials_ttls::credentials_ttls(_In_ module &mod) :
credentials_tls(mod)
m_outer(mod),
credentials(mod)
{
}
eap::credentials_ttls::credentials_ttls(_In_ const credentials_ttls &other) :
m_outer(other.m_outer),
m_inner(other.m_inner ? (credentials*)other.m_inner->clone() : nullptr),
credentials_tls(other)
credentials(other)
{
}
eap::credentials_ttls::credentials_ttls(_Inout_ credentials_ttls &&other) :
m_outer(std::move(other.m_outer)),
m_inner(std::move(other.m_inner)),
credentials_tls(std::move(other))
credentials(std::move(other))
{
}
@ -51,7 +54,8 @@ eap::credentials_ttls::credentials_ttls(_Inout_ credentials_ttls &&other) :
eap::credentials_ttls& eap::credentials_ttls::operator=(_In_ const credentials_ttls &other)
{
if (this != &other) {
(credentials_tls&)*this = other;
(credentials&)*this = other;
m_outer = other.m_outer;
m_inner.reset(other.m_inner ? (credentials*)other.m_inner->clone() : nullptr);
}
@ -62,8 +66,9 @@ eap::credentials_ttls& eap::credentials_ttls::operator=(_In_ const credentials_t
eap::credentials_ttls& eap::credentials_ttls::operator=(_Inout_ credentials_ttls &&other)
{
if (this != &other) {
(credentials_tls&)*this = std::move(other);
m_inner = std::move(other.m_inner);
(credentials&)*this = std::move(other);
m_outer = std::move(other.m_outer);
m_inner = std::move(other.m_inner);
}
return *this;
@ -78,7 +83,8 @@ eap::config* eap::credentials_ttls::clone() const
void eap::credentials_ttls::clear()
{
credentials_tls::clear();
credentials::clear();
m_outer.clear();
if (m_inner)
m_inner->clear();
}
@ -86,7 +92,7 @@ void eap::credentials_ttls::clear()
bool eap::credentials_ttls::empty() const
{
return credentials_tls::empty() && (!m_inner || m_inner->empty());
return credentials::empty() && m_outer.empty() && (!m_inner || m_inner->empty());
}
@ -96,7 +102,10 @@ bool eap::credentials_ttls::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *p
assert(pConfigRoot);
assert(ppEapError);
if (!credentials_tls::save(pDoc, pConfigRoot, ppEapError))
if (!credentials::save(pDoc, pConfigRoot, ppEapError))
return false;
if (!m_outer.save(pDoc, pConfigRoot, ppEapError))
return false;
const bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata");
@ -130,7 +139,10 @@ bool eap::credentials_ttls::load(_In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR
assert(ppEapError);
DWORD dwResult;
if (!credentials_tls::load(pConfigRoot, ppEapError))
if (!credentials::load(pConfigRoot, ppEapError))
return false;
if (!m_outer.load(pConfigRoot, ppEapError))
return false;
// TODO: For the time being, there is no detection what type is inner method. Introduce one!
@ -151,7 +163,8 @@ bool eap::credentials_ttls::load(_In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR
void eap::credentials_ttls::operator<<(_Inout_ cursor_out &cursor) const
{
credentials_tls::operator<<(cursor);
credentials::operator<<(cursor);
cursor << m_outer;
if (m_inner) {
if (dynamic_cast<credentials_pap*>(m_inner.get())) {
cursor << type_pap;
@ -181,14 +194,16 @@ size_t eap::credentials_ttls::get_pk_size() const
size_inner = pksizeof(type_undefined);
return
credentials_tls::get_pk_size() +
credentials::get_pk_size() +
pksizeof(m_outer) +
size_inner;
}
void eap::credentials_ttls::operator>>(_Inout_ cursor_in &cursor)
{
credentials_tls::operator>>(cursor);
credentials::operator>>(cursor);
cursor >> m_outer;
type_t eap_type;
cursor >> eap_type;
@ -206,7 +221,7 @@ void eap::credentials_ttls::operator>>(_Inout_ cursor_in &cursor)
bool eap::credentials_ttls::store(_In_ LPCTSTR pszTargetName, _Out_ EAP_ERROR **ppEapError) const
{
if (!credentials_tls::store(pszTargetName, ppEapError))
if (!m_outer.store(pszTargetName, ppEapError))
return false;
if (m_inner) {
@ -220,7 +235,7 @@ bool eap::credentials_ttls::store(_In_ LPCTSTR pszTargetName, _Out_ EAP_ERROR **
bool eap::credentials_ttls::retrieve(_In_ LPCTSTR pszTargetName, _Out_ EAP_ERROR **ppEapError)
{
if (!credentials_tls::retrieve(pszTargetName, ppEapError))
if (!m_outer.retrieve(pszTargetName, ppEapError))
return false;
if (m_inner) {
@ -242,8 +257,8 @@ LPCTSTR eap::credentials_ttls::target_suffix() const
std::wstring eap::credentials_ttls::get_identity() const
{
// Outer identity has the right-of-way.
if (!credentials_tls::empty())
return credentials_tls::get_identity();
if (!m_outer.empty())
return m_outer.get_identity();
// Inner identity.
if (m_inner)

View File

@ -79,15 +79,15 @@ bool 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());
wstring target_outer(std::move(cred_out.credentials_tls::target_suffix()));
assert(cfg_method);
wstring target_outer(std::move(cred_out.m_outer.target_suffix()));
wstring target_inner;
bool is_outer_set = false;
assert(cfg_method);
if (cfg_method->m_preshared) {
if (cfg_method->m_outer.m_use_preshared) {
// Outer TLS: Preshared credentials.
(credentials_tls&)cred_out = (credentials_tls&)*cfg_method->m_preshared;
log_event(&EAPMETHOD_TRACE_EVT_CRED_PRESHARED, event_data(target_outer), event_data(cred_out.credentials_tls::get_name()), event_data::blank);
cred_out.m_outer = (credentials_tls&)cfg_method->m_outer.m_preshared;
log_event(&EAPMETHOD_TRACE_EVT_CRED_PRESHARED, event_data(target_outer), event_data(cred_out.m_outer.get_name()), event_data::blank);
is_outer_set = true;
}
@ -95,9 +95,9 @@ bool eap::peer_ttls::get_identity(
const config_method_pap *cfg_inner_pap = dynamic_cast<const config_method_pap*>(cfg_method->m_inner.get());
if (cfg_inner_pap) {
target_inner = L"PAP";
if (cfg_inner_pap->m_preshared) {
if (cfg_inner_pap->m_use_preshared) {
// Inner PAP: Preshared credentials.
cred_out.m_inner.reset((credentials*)cfg_inner_pap->m_preshared->clone());
cred_out.m_inner.reset((credentials*)cfg_inner_pap->m_preshared.clone());
log_event(&EAPMETHOD_TRACE_EVT_CRED_PRESHARED, event_data(target_inner), event_data(cred_out.m_inner->get_name()), event_data::blank);
is_inner_set = true;
}
@ -114,8 +114,8 @@ bool eap::peer_ttls::get_identity(
credentials_tls cred_loaded(*this);
if (cred_loaded.retrieve(cfg_prov.m_id.c_str(), ppEapError)) {
// Outer TLS: Stored credentials.
(credentials_tls&&)cred_out = std::move(cred_loaded);
log_event(&EAPMETHOD_TRACE_EVT_CRED_STORED, event_data(target_outer), event_data(cred_out.credentials_tls::get_name()), event_data::blank);
cred_out.m_outer = std::move(cred_loaded);
log_event(&EAPMETHOD_TRACE_EVT_CRED_STORED, event_data(target_outer), event_data(cred_out.m_outer.get_name()), event_data::blank);
is_outer_set = true;
} else {
// Not actually an error.
@ -147,8 +147,8 @@ bool eap::peer_ttls::get_identity(
if (!is_outer_set) {
// Outer TLS: EAP service cached credentials.
(credentials_tls&)cred_out = (const credentials_tls&)cred_in;
log_event(&EAPMETHOD_TRACE_EVT_CRED_CACHED, event_data(target_outer), event_data(cred_out.credentials_tls::get_name()), event_data::blank);
cred_out.m_outer = cred_in->m_outer;
log_event(&EAPMETHOD_TRACE_EVT_CRED_CACHED, event_data(target_outer), event_data(cred_out.m_outer.get_name()), event_data::blank);
is_outer_set = true;
}
@ -185,23 +185,8 @@ bool eap::peer_ttls::get_identity(
// If we got here, we have all credentials we need.
// Build our identity. ;)
wstring identity;
if (cfg_method->m_anonymous_identity.empty()) {
// Use the true identity. Outer has the right-of-way.
identity = std::move(cred_out.get_identity());
} else if (cfg_method->m_anonymous_identity.compare(L"@") == 0) {
// Strip username part from identity (RFC 4822).
identity = std::move(cred_out.get_identity());
wstring::size_type offset = identity.find(L'@');
if (offset != wstring::npos) identity.erase(0, offset);
} else {
// Use configured identity.
identity = cfg_method->m_anonymous_identity;
}
wstring identity(std::move(cfg_method->get_public_identity(cred_out)));
log_event(&EAPMETHOD_TRACE_EVT_CRED_OUTER_ID, event_data(L"TTLS"), event_data(identity), event_data::blank);
// Save the identity for EAPHost.
size_t size = sizeof(WCHAR)*(identity.length() + 1);
*ppwszIdentity = (WCHAR*)alloc_memory(size);
memcpy(*ppwszIdentity, identity.c_str(), size);

View File

@ -28,6 +28,11 @@ class wxTTLSConfigPanel;
///
class wxTTLSConfigWindow;
///
/// TTLS credential panel
///
class wxTTLSCredentialsPanel;
#pragma once
#include "../res/wxTTLS_UI.h"
@ -102,6 +107,41 @@ protected:
wxStaticText *m_inner_title; ///< Inner authentication title
wxChoicebook *m_inner_type; ///< Inner authentication type
// Temprary inner method configurations to hold data until applied
// Temporary inner method configurations to hold data until applied
eap::config_method_pap m_cfg_pap; ///< PAP configuration
};
class wxTTLSCredentialsPanel : public wxPanel
{
public:
///
/// Constructs a configuration panel
///
/// \param[in] prov Provider configuration data
/// \param[in] cfg Configuration data
/// \param[inout] cred Credentials data
/// \param[in] pszCredTarget Target name of credentials in Windows Credential Manager. Can be further decorated to create final target name.
/// \param[in] parent Parent window
/// \param[in] is_config Is this panel used to pre-enter credentials? When \c true, the "Remember" checkbox is always selected and disabled.
///
wxTTLSCredentialsPanel(const eap::config_provider &prov, const eap::config_method &cfg, eap::credentials &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config = false);
///
/// Destructs the configuration panel
///
virtual ~wxTTLSCredentialsPanel();
protected:
/// \cond internal
virtual void OnInitDialog(wxInitDialogEvent& event);
/// \endcond
protected:
const eap::config_provider &m_prov; ///< EAP provider
const eap::config_method_ttls &m_cfg; ///< TTLS configuration
wxStaticText *m_outer_title; ///< Outer authentication title
wxTLSCredentialsPanel *m_outer_cred; ///< Outer credentials panel
wxStaticText *m_inner_title; ///< Inner authentication title
wxPanel *m_inner_cred; ///< Inner credentials panel
};

View File

@ -77,13 +77,51 @@ bool eap::peer_ttls_ui::invoke_identity_ui(
_Out_ EAP_ERROR **ppEapError)
{
UNREFERENCED_PARAMETER(dwFlags);
UNREFERENCED_PARAMETER(cfg);
UNREFERENCED_PARAMETER(cred);
UNREFERENCED_PARAMETER(ppwszIdentity);
UNREFERENCED_PARAMETER(ppEapError);
InitCommonControls();
MessageBox(hwndParent, _T(PRODUCT_NAME_STR) _T(" credential prompt goes here!"), _T(PRODUCT_NAME_STR) _T(" Credentials"), MB_OK);
if (cfg.m_providers.empty() || cfg.m_providers.front().m_methods.empty()) {
*ppEapError = make_error(ERROR_INVALID_PARAMETER, _T(__FUNCTION__) _T(" Configuration has no providers and/or methods."));
return false;
}
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);
// Initialize application.
new wxApp();
wxEntryStart(m_instance);
int result;
{
// Create wxWidget-approved parent window.
wxWindow parent;
parent.SetHWND((WXHWND)hwndParent);
parent.AdoptAttributesFromHWND();
wxTopLevelWindows.Append(&parent);
// Create and launch credentials dialog.
wxEAPCredentialsDialog dlg(cfg_prov, &parent);
wxTTLSCredentialsPanel *panel = new wxTTLSCredentialsPanel(cfg_prov, *cfg_method, cred, cfg_prov.m_id.c_str(), &dlg, true);
dlg.AddContents((wxPanel**)&panel, 1);
result = dlg.ShowModal();
wxTopLevelWindows.DeleteObject(&parent);
parent.SetHWND((WXHWND)NULL);
}
// Clean-up and return.
wxEntryCleanup();
if (result != wxID_OK) {
*ppEapError = make_error(ERROR_CANCELLED, _T(__FUNCTION__) _T(" Cancelled."));
return false;
}
// Build our identity. ;)
std::wstring identity(std::move(cfg_method->get_public_identity(cred)));
log_event(&EAPMETHOD_TRACE_EVT_CRED_OUTER_ID, winstd::event_data(L"TTLS"), winstd::event_data(identity), winstd::event_data::blank);
size_t size = sizeof(WCHAR)*(identity.length() + 1);
*ppwszIdentity = (WCHAR*)alloc_memory(size);
memcpy(*ppwszIdentity, identity.c_str(), size);
return true;
}

View File

@ -102,8 +102,8 @@ wxTTLSConfigWindow::wxTTLSConfigWindow(const eap::config_provider &prov, eap::co
wxBoxSizer* sb_content;
sb_content = new wxBoxSizer( wxVERTICAL );
if (prov.m_read_only)
sb_content->Add(new wxEAPProviderLockedPanel(prov, this), 0, wxALL|wxEXPAND, 5);
if (m_prov.m_read_only)
sb_content->Add(new wxEAPProviderLockedPanel(m_prov, this), 0, wxALL|wxEXPAND, 5);
m_inner_title = new wxStaticText(this, wxID_ANY, _("Inner Authentication"), wxDefaultPosition, wxDefaultSize, 0);
m_inner_title->SetFont(wxFont(18, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString));
@ -112,7 +112,7 @@ wxTTLSConfigWindow::wxTTLSConfigWindow(const eap::config_provider &prov, eap::co
m_inner_type = new wxChoicebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxCHB_DEFAULT);
m_inner_type->SetToolTip( _("Select inner authentication method from the list") );
m_inner_type->AddPage(new wxPAPConfigPanel(prov, m_cfg_pap, pszCredTarget, m_inner_type), _("PAP"));
m_inner_type->AddPage(new wxPAPConfigPanel(m_prov, m_cfg_pap, pszCredTarget, m_inner_type), _("PAP"));
sb_content->Add(m_inner_type, 0, wxALL|wxEXPAND, 5);
sb_content->Add(20, 20, 1, wxALL|wxEXPAND, 5);
@ -122,10 +122,10 @@ wxTTLSConfigWindow::wxTTLSConfigWindow(const eap::config_provider &prov, eap::co
m_outer_title->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_INACTIVECAPTION ) );
sb_content->Add(m_outer_title, 0, wxALL|wxALIGN_RIGHT, 5);
m_outer_identity = new wxTTLSConfigPanel(prov, m_cfg, this);
m_outer_identity = new wxTTLSConfigPanel(m_prov, m_cfg, this);
sb_content->Add(m_outer_identity, 0, wxALL|wxEXPAND, 5);
m_tls = new wxTLSConfigPanel(prov, m_cfg, pszCredTarget, this);
m_tls = new wxTLSConfigPanel(m_prov, m_cfg.m_outer, pszCredTarget, this);
sb_content->Add(m_tls, 0, wxALL|wxEXPAND, 5);
wxSize size = sb_content->CalcMin();
@ -205,3 +205,67 @@ void wxTTLSConfigWindow::OnInitDialog(wxInitDialogEvent& event)
for (wxWindowList::compatibility_iterator inner = m_inner_type->GetChildren().GetFirst(); inner; inner = inner->GetNext())
inner->GetData()->GetEventHandler()->ProcessEvent(event);
}
//////////////////////////////////////////////////////////////////////
// wxTTLSCredentialsPanel
//////////////////////////////////////////////////////////////////////
wxTTLSCredentialsPanel::wxTTLSCredentialsPanel(const eap::config_provider &prov, const eap::config_method &cfg, eap::credentials &cred, LPCTSTR pszCredTarget, wxWindow* parent, bool is_config) :
m_prov(prov),
m_cfg((eap::config_method_ttls&)cfg),
wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize)
{
wxBoxSizer* sb_content;
sb_content = new wxBoxSizer( wxVERTICAL );
if (m_prov.m_read_only)
sb_content->Add(new wxEAPProviderLockedPanel(m_prov, this), 0, wxALL|wxEXPAND, 5);
m_inner_title = new wxStaticText(this, wxID_ANY, _("Inner Authentication"), wxDefaultPosition, wxDefaultSize, 0);
m_inner_title->SetFont(wxFont(18, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString));
m_inner_title->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_INACTIVECAPTION ) );
sb_content->Add(m_inner_title, 0, wxALL|wxALIGN_RIGHT, 5);
assert(m_cfg.m_inner);
const eap::config_method_pap *cfg_inner_pap = dynamic_cast<const eap::config_method_pap*>(m_cfg.m_inner.get());
if (cfg_inner_pap) {
if (!((eap::credentials_ttls&)cred).m_inner) ((eap::credentials_ttls&)cred).m_inner.reset(new eap::credentials_pap(cred.m_module));
m_inner_cred = new wxPAPCredentialsPanel(m_prov, *cfg_inner_pap, *((eap::credentials_ttls&)cred).m_inner.get(), pszCredTarget, this, is_config);
sb_content->Add(m_inner_cred, 0, wxALL|wxEXPAND, 5);
} else
assert(0); // Unsupported inner authentication method type.
sb_content->Add(20, 20, 1, wxALL|wxEXPAND, 5);
m_outer_title = new wxStaticText(this, wxID_ANY, _("Outer Authentication"), wxDefaultPosition, wxDefaultSize, 0);
m_outer_title->SetFont(wxFont(18, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString));
m_outer_title->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_INACTIVECAPTION ) );
sb_content->Add(m_outer_title, 0, wxALL|wxALIGN_RIGHT, 5);
m_outer_cred = new wxTLSCredentialsPanel(m_prov, (const eap::config_method_tls&)m_cfg, (eap::credentials_tls&)cred, pszCredTarget, this, is_config);
sb_content->Add(m_outer_cred, 0, wxALL|wxEXPAND, 5);
this->SetSizer(sb_content);
this->Layout();
m_inner_cred->SetFocusFromKbd();
// Connect Events
this->Connect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(wxTTLSCredentialsPanel::OnInitDialog));
}
wxTTLSCredentialsPanel::~wxTTLSCredentialsPanel()
{
// Disconnect Events
this->Disconnect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(wxTTLSCredentialsPanel::OnInitDialog));
}
void wxTTLSCredentialsPanel::OnInitDialog(wxInitDialogEvent& event)
{
// Forward the event to child panels.
m_outer_cred->GetEventHandler()->ProcessEvent(event);
m_inner_cred->GetEventHandler()->ProcessEvent(event);
}