Support for pre-shared credentials introduced

This commit is contained in:
Simon Rozman 2016-06-15 20:00:04 +02:00
parent ef9fa750a0
commit a9fdd1d71d
20 changed files with 1300 additions and 625 deletions

View File

@ -28,9 +28,9 @@ namespace eap
class config; class config;
/// ///
/// Base class for method configuration storage /// Base template for method configuration storage
/// ///
class config_method; template <class _Tcred> class config_method;
/// ///
/// Provider configuration /// Provider configuration
@ -41,11 +41,6 @@ namespace eap
/// Providers configuration /// Providers configuration
/// ///
template <class _Tprov> class config_providers; template <class _Tprov> class config_providers;
///
/// Password based method configuration
///
typedef config_method config_pass;
} }
namespace eapserial namespace eapserial
@ -56,7 +51,7 @@ namespace eapserial
/// \param[inout] cursor Memory cursor /// \param[inout] cursor Memory cursor
/// \param[in] val Configuration to pack /// \param[in] val Configuration to pack
/// ///
inline void pack(_Inout_ unsigned char *&cursor, _In_ const eap::config_method &val); template <class _Tcred> inline void pack(_Inout_ unsigned char *&cursor, _In_ const eap::config_method<_Tcred> &val);
/// ///
/// Returns packed size of a method configuration /// Returns packed size of a method configuration
@ -65,7 +60,7 @@ namespace eapserial
/// ///
/// \returns Size of data when packed (in bytes) /// \returns Size of data when packed (in bytes)
/// ///
inline size_t get_pk_size(const eap::config_method &val); template <class _Tcred> inline size_t get_pk_size(const eap::config_method<_Tcred> &val);
/// ///
/// Unpacks a method configuration /// Unpacks a method configuration
@ -73,7 +68,7 @@ namespace eapserial
/// \param[inout] cursor Memory cursor /// \param[inout] cursor Memory cursor
/// \param[out] val Configuration to unpack to /// \param[out] val Configuration to unpack to
/// ///
inline void unpack(_Inout_ const unsigned char *&cursor, _Out_ eap::config_method &val); template <class _Tcred> inline void unpack(_Inout_ const unsigned char *&cursor, _Out_ eap::config_method<_Tcred> &val);
/// ///
/// Packs a provider configuration /// Packs a provider configuration
@ -234,6 +229,7 @@ namespace eap
}; };
template <class _Tcred>
class config_method : public config class config_method : public config
{ {
public: public:
@ -242,21 +238,44 @@ namespace eap
/// ///
/// \param[in] mod Reference of the EAP module to use for global services /// \param[in] mod Reference of the EAP module to use for global services
/// ///
config_method(_In_ module &mod); config_method(_In_ module &mod) :
m_allow_save(true),
m_use_preshared(false),
m_preshared(mod),
config(mod)
{
}
/// ///
/// Copies configuration /// Copies configuration
/// ///
/// \param[in] other Configuration to copy from /// \param[in] other Configuration to copy from
/// ///
config_method(_In_ const config_method &other); config_method(_In_ const config_method<_Tcred> &other) :
m_allow_save(other.m_allow_save),
m_anonymous_identity(other.m_anonymous_identity),
m_use_preshared(other.m_use_preshared),
m_preshared(other.m_preshared),
config(other)
{
}
/// ///
/// Moves configuration /// Moves configuration
/// ///
/// \param[in] other Configuration to move from /// \param[in] other Configuration to move from
/// ///
config_method(_Inout_ config_method &&other); config_method(_Inout_ config_method<_Tcred> &&other) :
m_allow_save(std::move(other.m_allow_save)),
m_anonymous_identity(std::move(other.m_anonymous_identity)),
m_use_preshared(std::move(other.m_use_preshared)),
m_preshared(std::move(other.m_preshared)),
config(std::move(other))
{
}
/// ///
/// Copies configuration /// Copies configuration
@ -265,7 +284,19 @@ namespace eap
/// ///
/// \returns Reference to this object /// \returns Reference to this object
/// ///
config_method& operator=(_In_ const config_method &other); config_method& operator=(_In_ const config_method<_Tcred> &other)
{
if (this != &other) {
(config&)*this = other;
m_allow_save = other.m_allow_save;
m_anonymous_identity = other.m_anonymous_identity;
m_use_preshared = other.m_use_preshared;
m_preshared = other.m_preshared;
}
return *this;
}
/// ///
/// Moves configuration /// Moves configuration
@ -274,7 +305,19 @@ namespace eap
/// ///
/// \returns Reference to this object /// \returns Reference to this object
/// ///
config_method& operator=(_Inout_ config_method &&other); config_method& operator=(_Inout_ config_method<_Tcred> &&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_use_preshared = std::move(other.m_use_preshared);
m_preshared = std::move(other.m_preshared);
}
return *this;
}
/// \name XML configuration management /// \name XML configuration management
/// @{ /// @{
@ -290,7 +333,38 @@ namespace eap
/// - \c ERROR_SUCCESS if succeeded /// - \c ERROR_SUCCESS if succeeded
/// - error code otherwise /// - error code otherwise
/// ///
virtual DWORD save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR **ppEapError) const; virtual DWORD save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR **ppEapError) const
{
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, 0, NULL, NULL, NULL, _T(__FUNCTION__) _T(" Error creating <ClientSideCredential> element."), NULL);
return dwResult;
}
// <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, 0, NULL, NULL, NULL, _T(__FUNCTION__) _T(" Error creating <allow-save> element."), NULL);
return dwResult;
}
// <ClientSideCredential>/<AnonymousIdentity>
if (!m_anonymous_identity.empty())
if ((dwResult = eapxml::put_element_value(pDoc, pXmlElClientSideCredential, winstd::bstr(L"AnonymousIdentity"), bstrNamespace, winstd::bstr(m_anonymous_identity))) != ERROR_SUCCESS) {
*ppEapError = m_module.make_error(dwResult, 0, NULL, NULL, NULL, _T(__FUNCTION__) _T(" Error creating <AnonymousIdentity> element."), NULL);
return dwResult;
}
if (m_use_preshared)
if ((dwResult = m_preshared.save(pDoc, pXmlElClientSideCredential, ppEapError)) != ERROR_SUCCESS)
return dwResult;
return ERROR_SUCCESS;
}
/// ///
/// Load configuration from XML document /// Load configuration from XML document
@ -302,7 +376,36 @@ namespace eap
/// - \c ERROR_SUCCESS if succeeded /// - \c ERROR_SUCCESS if succeeded
/// - error code otherwise /// - error code otherwise
/// ///
virtual DWORD load(_In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR **ppEapError); virtual DWORD load(_In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR **ppEapError)
{
DWORD dwResult;
m_allow_save = true;
m_use_preshared = false;
m_preshared.clear();
m_anonymous_identity.clear();
// <ClientSideCredential>
winstd::com_obj<IXMLDOMElement> pXmlElClientSideCredential;
if (eapxml::select_element(pConfigRoot, winstd::bstr(L"eap-metadata:ClientSideCredential"), &pXmlElClientSideCredential) == ERROR_SUCCESS) {
// <allow-save>
eapxml::get_element_value(pXmlElClientSideCredential, winstd::bstr(L"eap-metadata:allow-save"), &m_allow_save);
// <AnonymousIdentity>
eapxml::get_element_value(pXmlElClientSideCredential, winstd::bstr(L"eap-metadata:AnonymousIdentity"), m_anonymous_identity);
if ((dwResult = m_preshared.load(pXmlElClientSideCredential, ppEapError)) != ERROR_SUCCESS) {
// This is not really an error - merely an indication pre-shared credentials are unavailable.
if (*ppEapError) {
m_module.free_error_memory(*ppEapError);
*ppEapError = NULL;
}
} else
m_use_preshared = true;
}
return ERROR_SUCCESS;
}
/// @} /// @}
@ -314,8 +417,10 @@ namespace eap
virtual type_t get_method_id() const = 0; virtual type_t get_method_id() const = 0;
public: public:
bool m_allow_save; ///< Are credentials allowed to be saved to Windows Credential Manager? bool m_allow_save; ///< Are credentials allowed to be saved to Windows Credential Manager?
std::wstring m_anonymous_identity; ///< Anonymous identity std::wstring m_anonymous_identity; ///< Anonymous identity
bool m_use_preshared; ///< Does configuration use pre-shared credentials?
_Tcred m_preshared; ///< Pre-shared credentials
}; };
@ -757,25 +862,34 @@ namespace eap
namespace eapserial namespace eapserial
{ {
inline void pack(_Inout_ unsigned char *&cursor, _In_ const eap::config_method &val) template <class _Tcred>
inline void pack(_Inout_ unsigned char *&cursor, _In_ const eap::config_method<_Tcred> &val)
{ {
pack(cursor, val.m_allow_save ); pack(cursor, val.m_allow_save );
pack(cursor, val.m_anonymous_identity); pack(cursor, val.m_anonymous_identity);
pack(cursor, val.m_use_preshared );
pack(cursor, val.m_preshared );
} }
inline size_t get_pk_size(const eap::config_method &val) template <class _Tcred>
inline size_t get_pk_size(const eap::config_method<_Tcred> &val)
{ {
return return
get_pk_size(val.m_allow_save ) + get_pk_size(val.m_allow_save ) +
get_pk_size(val.m_anonymous_identity); get_pk_size(val.m_anonymous_identity) +
get_pk_size(val.m_use_preshared ) +
get_pk_size(val.m_preshared );
} }
inline void unpack(_Inout_ const unsigned char *&cursor, _Out_ eap::config_method &val) template <class _Tcred>
inline void unpack(_Inout_ const unsigned char *&cursor, _Out_ eap::config_method<_Tcred> &val)
{ {
unpack(cursor, val.m_allow_save ); unpack(cursor, val.m_allow_save );
unpack(cursor, val.m_anonymous_identity); unpack(cursor, val.m_anonymous_identity);
unpack(cursor, val.m_use_preshared );
unpack(cursor, val.m_preshared );
} }

View File

@ -158,6 +158,36 @@ namespace eap
/// ///
virtual bool empty() const; virtual bool empty() const;
/// \name XML configuration management
/// @{
///
/// Save credentials to XML document
///
/// \param[in] pDoc XML document
/// \param[in] pConfigRoot Suggested root element for saving credentials
/// \param[out] ppEapError Pointer to error descriptor in case of failure. Free using `module::free_error_memory()`.
///
/// \returns
/// - \c ERROR_SUCCESS if succeeded
/// - error code otherwise
///
virtual DWORD save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR **ppEapError) const;
///
/// Load credentials from XML document
///
/// \param[in] pConfigRoot Root element for loading credentials
/// \param[out] ppEapError Pointer to error descriptor in case of failure. Free using `module::free_error_memory()`.
///
/// \returns
/// - \c ERROR_SUCCESS if succeeded
/// - error code otherwise
///
virtual DWORD load(_In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR **ppEapError);
/// @}
/// \name Storage /// \name Storage
/// @{ /// @{
@ -335,23 +365,19 @@ namespace eapserial
{ {
inline void pack(_Inout_ unsigned char *&cursor, _In_ const eap::credentials &val) inline void pack(_Inout_ unsigned char *&cursor, _In_ const eap::credentials &val)
{ {
pack(cursor, (const eap::config&)val); pack(cursor, val.m_identity);
pack(cursor, val.m_identity );
} }
inline size_t get_pk_size(const eap::credentials &val) inline size_t get_pk_size(const eap::credentials &val)
{ {
return return get_pk_size(val.m_identity);
get_pk_size((const eap::config&)val) +
get_pk_size(val.m_identity );
} }
inline void unpack(_Inout_ const unsigned char *&cursor, _Out_ eap::credentials &val) inline void unpack(_Inout_ const unsigned char *&cursor, _Out_ eap::credentials &val)
{ {
unpack(cursor, (eap::config&)val); unpack(cursor, val.m_identity);
unpack(cursor, val.m_identity );
} }

View File

@ -23,6 +23,8 @@
#if !defined(RC_INVOKED) && !defined(MIDL_PASS) #if !defined(RC_INVOKED) && !defined(MIDL_PASS)
#include <sal.h>
namespace eap namespace eap
{ {
/// ///
@ -33,9 +35,39 @@ namespace eap
enum type_t; enum type_t;
} }
namespace eapserial
{
///
/// Packs an EAP method type
///
/// \param[inout] cursor Memory cursor
/// \param[in] val EAP method type to pack
///
inline void pack(_Inout_ unsigned char *&cursor, _In_ const eap::type_t &val);
///
/// Returns packed size of an EAP method type
///
/// \param[in] val EAP method type to pack
///
/// \returns Size of data when packed (in bytes)
///
inline size_t get_pk_size(const eap::type_t &val);
///
/// Unpacks an EAP method type
///
/// \param[inout] cursor Memory cursor
/// \param[out] val EAP method type to unpack to
///
inline void unpack(_Inout_ const unsigned char *&cursor, _Out_ eap::type_t &val);
}
#pragma once #pragma once
#include "EAPSerial.h"
namespace eap namespace eap
{ {
@ -49,4 +81,27 @@ namespace eap
}; };
} }
namespace eapserial
{
inline void pack(_Inout_ unsigned char *&cursor, _In_ const eap::type_t &val)
{
pack(cursor, (unsigned char)val);
}
inline size_t get_pk_size(_In_ const eap::type_t &val)
{
return get_pk_size((unsigned char)val);
}
inline void unpack(_Inout_ const unsigned char *&cursor, _Out_ eap::type_t &val)
{
unsigned char t;
unpack(cursor, t);
val = (eap::type_t)t;
}
}
#endif #endif

View File

@ -62,107 +62,6 @@ eap::config& eap::config::operator=(_In_ const config &other)
eap::config& eap::config::operator=(_Inout_ config &&other) eap::config& eap::config::operator=(_Inout_ config &&other)
{ {
UNREFERENCED_PARAMETER(other); UNREFERENCED_PARAMETER(other);
assert(&m_module == &other.m_module); // Copy configuration within same module only! assert(&m_module == &other.m_module); // Move configuration within same module only!
return *this; return *this;
} }
//////////////////////////////////////////////////////////////////////
// eap::config_method
//////////////////////////////////////////////////////////////////////
eap::config_method::config_method(_In_ module &mod) :
m_allow_save(true),
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),
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)),
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;
}
return *this;
}
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);
}
return *this;
}
DWORD eap::config_method::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR **ppEapError) const
{
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, 0, NULL, NULL, NULL, _T(__FUNCTION__) _T(" Error creating <ClientSideCredential> element."), NULL);
return dwResult;
}
// <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, 0, NULL, NULL, NULL, _T(__FUNCTION__) _T(" Error creating <allow-save> element."), NULL);
return dwResult;
}
// <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, 0, NULL, NULL, NULL, _T(__FUNCTION__) _T(" Error creating <AnonymousIdentity> element."), NULL);
return dwResult;
}
return ERROR_SUCCESS;
}
DWORD eap::config_method::load(_In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR **ppEapError)
{
UNREFERENCED_PARAMETER(ppEapError);
m_allow_save = true;
m_anonymous_identity.clear();
// <ClientSideCredential>
com_obj<IXMLDOMElement> pXmlElClientSideCredential;
if (eapxml::select_element(pConfigRoot, bstr(L"eap-metadata:ClientSideCredential"), &pXmlElClientSideCredential) == ERROR_SUCCESS) {
// <allow-save>
eapxml::get_element_value(pXmlElClientSideCredential, bstr(L"eap-metadata:allow-save"), &m_allow_save);
// <AnonymousIdentity>
eapxml::get_element_value(pXmlElClientSideCredential, bstr(L"eap-metadata:AnonymousIdentity"), m_anonymous_identity);
}
return ERROR_SUCCESS;
}

View File

@ -83,6 +83,35 @@ bool eap::credentials::empty() const
} }
DWORD eap::credentials::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR **ppEapError) const
{
const bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata");
DWORD dwResult;
// <UserName>
if ((dwResult = eapxml::put_element_value(pDoc, pConfigRoot, bstr(L"UserName"), bstrNamespace, bstr(m_identity))) != ERROR_SUCCESS) {
*ppEapError = m_module.make_error(dwResult, 0, NULL, NULL, NULL, _T(__FUNCTION__) _T(" Error creating <UserName> element."), NULL);
return dwResult;
}
return ERROR_SUCCESS;
}
DWORD eap::credentials::load(_In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR **ppEapError)
{
assert(pConfigRoot);
DWORD dwResult;
if ((dwResult = eapxml::get_element_value(pConfigRoot, bstr(L"eap-metadata:UserName"), m_identity)) != ERROR_SUCCESS) {
*ppEapError = m_module.make_error(dwResult, 0, NULL, NULL, NULL, _T(__FUNCTION__) _T(" Error reading <UserName> element."), NULL);
return dwResult;
}
return ERROR_SUCCESS;
}
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// eap::credentials_pass // eap::credentials_pass
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
@ -146,22 +175,16 @@ DWORD eap::credentials_pass::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *
const bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata"); const bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata");
DWORD dwResult; DWORD dwResult;
// <UserName> if ((dwResult = credentials::save(pDoc, pConfigRoot, ppEapError)) != ERROR_SUCCESS)
if (!m_identity.empty()) return dwResult;
if ((dwResult = eapxml::put_element_value(pDoc, pConfigRoot, bstr(L"UserName"), bstrNamespace, bstr(m_identity))) != ERROR_SUCCESS) {
*ppEapError = m_module.make_error(dwResult, 0, NULL, NULL, NULL, _T(__FUNCTION__) _T(" Error creating <UserName> element."), NULL);
return dwResult;
}
// <Password> // <Password>
if (!m_password.empty()) { bstr pass(m_password);
bstr pass(m_password); dwResult = eapxml::put_element_value(pDoc, pConfigRoot, bstr(L"Password"), bstrNamespace, pass);
dwResult = eapxml::put_element_value(pDoc, pConfigRoot, bstr(L"Password"), bstrNamespace, pass); SecureZeroMemory((BSTR)pass, sizeof(OLECHAR)*pass.length());
SecureZeroMemory((BSTR)pass, sizeof(OLECHAR)*pass.length()); if (dwResult != ERROR_SUCCESS) {
if (dwResult != ERROR_SUCCESS) { *ppEapError = m_module.make_error(dwResult, 0, NULL, NULL, NULL, _T(__FUNCTION__) _T(" Error creating <Password> element."), NULL);
*ppEapError = m_module.make_error(dwResult, 0, NULL, NULL, NULL, _T(__FUNCTION__) _T(" Error creating <Password> element."), NULL); return dwResult;
return dwResult;
}
} }
return ERROR_SUCCESS; return ERROR_SUCCESS;
@ -171,13 +194,17 @@ DWORD eap::credentials_pass::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *
DWORD eap::credentials_pass::load(_In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR **ppEapError) DWORD eap::credentials_pass::load(_In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR **ppEapError)
{ {
assert(pConfigRoot); assert(pConfigRoot);
UNREFERENCED_PARAMETER(ppEapError); DWORD dwResult;
eapxml::get_element_value(pConfigRoot, bstr(L"eap-metadata:UserName"), m_identity); if ((dwResult = credentials::load(pConfigRoot, ppEapError)) != ERROR_SUCCESS)
return dwResult;
bstr pass; bstr pass;
if ((eapxml::get_element_value(pConfigRoot, bstr(L"eap-metadata:Password"), &pass)) == ERROR_SUCCESS) if ((dwResult = eapxml::get_element_value(pConfigRoot, bstr(L"eap-metadata:Password"), &pass)) != ERROR_SUCCESS) {
m_password = pass; *ppEapError = m_module.make_error(dwResult, 0, NULL, NULL, NULL, _T(__FUNCTION__) _T(" Error reading <Password> element."), NULL);
return dwResult;
}
m_password = pass;
SecureZeroMemory((BSTR)pass, sizeof(OLECHAR)*pass.length()); SecureZeroMemory((BSTR)pass, sizeof(OLECHAR)*pass.length());
return ERROR_SUCCESS; return ERROR_SUCCESS;

View File

@ -206,26 +206,72 @@ public:
protected: protected:
/// \cond internal /// \cond internal
virtual bool TransferDataToWindow()
{
wxCHECK(wxEAPCredentialsConfigPanelBase::TransferDataToWindow(), false);
if (!m_cfg.m_use_preshared) {
m_own->SetValue(true);
} else {
m_preshared->SetValue(true);
m_cred = m_cfg.m_preshared;
}
return true;
}
virtual bool TransferDataFromWindow()
{
if (m_own->GetValue()) {
m_cfg.m_use_preshared = false;
} else {
m_cfg.m_use_preshared = true;
m_cfg.m_preshared = m_cred;
}
return wxEAPCredentialsConfigPanelBase::TransferDataFromWindow();
}
virtual void OnUpdateUI(wxUpdateUIEvent& event) virtual void OnUpdateUI(wxUpdateUIEvent& event)
{ {
UNREFERENCED_PARAMETER(event); UNREFERENCED_PARAMETER(event);
DWORD dwResult; DWORD dwResult;
bool has_own;
std::unique_ptr<CREDENTIAL, winstd::CredFree_delete<CREDENTIAL> > cred; 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_clear->Enable(true); m_identity_own->SetValue(cred->UserName && cred->UserName[0] != 0 ? cred->UserName : _("<blank>"));
m_identity->SetValue(cred->UserName && cred->UserName[0] != 0 ? cred->UserName : _("<blank>")); has_own = true;
} else if ((dwResult = GetLastError()) == ERROR_NOT_FOUND) { } else if ((dwResult = GetLastError()) == ERROR_NOT_FOUND) {
m_clear->Enable(false); m_identity_own->Clear();
m_identity->Clear(); has_own = false;
} else { } else {
m_clear->Enable(true); m_identity_own->SetValue(wxString::Format(_("<error %u>"), dwResult));
m_identity->SetValue(wxString::Format(_("<error %u>"), dwResult)); has_own = true;
}
if (m_own->GetValue()) {
m_identity_own ->Enable(true);
m_set_own ->Enable(true);
m_clear_own ->Enable(has_own);
m_identity_preshared->Enable(false);
m_identity_preshared->SetValue(wxEmptyString);
m_set_preshared ->Enable(false);
} else {
m_identity_own ->Enable(false);
m_set_own ->Enable(false);
m_clear_own ->Enable(false);
m_identity_preshared->Enable(true);
m_identity_preshared->SetValue(!m_cred.empty() ? m_cred.m_identity : _("<blank>"));
m_set_preshared ->Enable(true);
} }
} }
virtual void OnSet(wxCommandEvent& event) virtual void OnSetOwn(wxCommandEvent& event)
{ {
UNREFERENCED_PARAMETER(event); UNREFERENCED_PARAMETER(event);
@ -238,13 +284,27 @@ protected:
} }
virtual void OnClear(wxCommandEvent& event) virtual void OnClearOwn(wxCommandEvent& event)
{ {
UNREFERENCED_PARAMETER(event); 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()); wxLogError(_("Deleting credentials failed (error %u)."), GetLastError());
} }
virtual void OnSetPreshared(wxCommandEvent& event)
{
UNREFERENCED_PARAMETER(event);
wxEAPCredentialsDialog dlg(this);
_Tpanel *panel = new _Tpanel(m_cred, _T(""), &dlg, true);
dlg.AddContents((wxPanel**)&panel, 1);
dlg.ShowModal();
}
/// \endcond /// \endcond
protected: protected:
@ -275,8 +335,8 @@ public:
m_target(pszCredTarget), m_target(pszCredTarget),
_Tbase(parent) _Tbase(parent)
{ {
if (is_config) { if (m_target.empty() || is_config) {
// User is setting credentials via configuration UI. // No Credential Manager, or user is setting credentials via configuration UI.
// => Pointless if not stored to Credential Manager // => Pointless if not stored to Credential Manager
m_remember->SetValue(true); m_remember->SetValue(true);
m_remember->Enable(false); m_remember->Enable(false);
@ -290,17 +350,19 @@ protected:
{ {
wxCHECK(_Tbase::TransferDataToWindow(), false); wxCHECK(_Tbase::TransferDataToWindow(), false);
// Read credentials from Credential Manager if (!m_target.empty()) {
EAP_ERROR *pEapError; // Read credentials from Credential Manager
DWORD dwResult; EAP_ERROR *pEapError;
if ((dwResult = m_cred.retrieve(m_target.c_str(), &pEapError)) == ERROR_SUCCESS) { DWORD dwResult;
m_remember->SetValue(true); if ((dwResult = m_cred.retrieve(m_target.c_str(), &pEapError)) == ERROR_SUCCESS) {
} else if (dwResult != ERROR_NOT_FOUND) { m_remember->SetValue(true);
if (pEapError) { } else if (dwResult != ERROR_NOT_FOUND) {
wxLogError(winstd::tstring_printf(_("Error reading credentials from Credential Manager: %ls (error %u)"), pEapError->pRootCauseString, pEapError->dwWinError).c_str()); if (pEapError) {
m_cred.m_module.free_error_memory(pEapError); wxLogError(winstd::tstring_printf(_("Error reading credentials from Credential Manager: %ls (error %u)"), pEapError->pRootCauseString, pEapError->dwWinError).c_str());
} else m_cred.m_module.free_error_memory(pEapError);
wxLogError(_("Reading credentials failed (error %u)."), dwResult); } else
wxLogError(_("Reading credentials failed (error %u)."), dwResult);
}
} }
return true; return true;
@ -309,16 +371,18 @@ protected:
virtual bool TransferDataFromWindow() virtual bool TransferDataFromWindow()
{ {
// Write credentials to credential manager. if (!m_target.empty()) {
if (m_remember->GetValue()) { // Write credentials to credential manager.
EAP_ERROR *pEapError; if (m_remember->GetValue()) {
DWORD dwResult; EAP_ERROR *pEapError;
if ((dwResult = m_cred.store(m_target.c_str(), &pEapError)) != ERROR_SUCCESS) { DWORD dwResult;
if (pEapError) { if ((dwResult = m_cred.store(m_target.c_str(), &pEapError)) != ERROR_SUCCESS) {
wxLogError(winstd::tstring_printf(_("Error writing credentials to Credential Manager: %ls (error %u)"), pEapError->pRootCauseString, pEapError->dwWinError).c_str()); if (pEapError) {
m_cred.m_module.free_error_memory(pEapError); wxLogError(winstd::tstring_printf(_("Error writing credentials to Credential Manager: %ls (error %u)"), pEapError->pRootCauseString, pEapError->dwWinError).c_str());
} else m_cred.m_module.free_error_memory(pEapError);
wxLogError(_("Writing credentials failed (error %u)."), dwResult); } else
wxLogError(_("Writing credentials failed (error %u)."), dwResult);
}
} }
} }

View File

@ -23,6 +23,8 @@ wxEAPConfigDialogBase::wxEAPConfigDialogBase( wxWindow* parent, wxWindowID id, c
sb_content->Add( m_banner, 0, wxEXPAND|wxBOTTOM, 5 ); sb_content->Add( m_banner, 0, wxEXPAND|wxBOTTOM, 5 );
m_providers = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); m_providers = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_providers->SetExtraStyle( wxWS_EX_VALIDATE_RECURSIVELY );
sb_content->Add( m_providers, 1, wxEXPAND|wxALL, 10 ); sb_content->Add( m_providers, 1, wxEXPAND|wxALL, 10 );
@ -131,43 +133,86 @@ wxEAPCredentialsConfigPanelBase::wxEAPCredentialsConfigPanelBase( wxWindow* pare
wxBoxSizer* sb_credentials_vert; wxBoxSizer* sb_credentials_vert;
sb_credentials_vert = new wxBoxSizer( wxVERTICAL ); sb_credentials_vert = new wxBoxSizer( wxVERTICAL );
m_credentials_label = new wxStaticText( sb_credentials->GetStaticBox(), wxID_ANY, _("Manage your credentials stored in Windows Credential Manager."), wxDefaultPosition, wxDefaultSize, 0 ); m_credentials_label = new wxStaticText( sb_credentials->GetStaticBox(), wxID_ANY, _("Manage credentials used to connect."), wxDefaultPosition, wxDefaultSize, 0 );
m_credentials_label->Wrap( 446 ); m_credentials_label->Wrap( 446 );
sb_credentials_vert->Add( m_credentials_label, 0, wxALL|wxEXPAND, 5 ); sb_credentials_vert->Add( m_credentials_label, 0, wxALL|wxEXPAND, 5 );
wxFlexGridSizer* sb_credentials_tbl; wxBoxSizer* sb_cred_radio;
sb_credentials_tbl = new wxFlexGridSizer( 0, 2, 5, 5 ); sb_cred_radio = new wxBoxSizer( wxVERTICAL );
sb_credentials_tbl->AddGrowableCol( 1 );
sb_credentials_tbl->SetFlexibleDirection( wxBOTH );
sb_credentials_tbl->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_identity_label = new wxStaticText( sb_credentials->GetStaticBox(), wxID_ANY, _("Identity:"), wxDefaultPosition, wxDefaultSize, 0 ); wxBoxSizer* sz_own;
m_identity_label->Wrap( -1 ); sz_own = new wxBoxSizer( wxVERTICAL );
sb_credentials_tbl->Add( m_identity_label, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 );
m_identity = new wxTextCtrl( sb_credentials->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY ); wxBoxSizer* sz_own_inner;
m_identity->SetToolTip( _("Enter your user name here (user@domain.org, DOMAINUser, etc.)") ); sz_own_inner = new wxBoxSizer( wxHORIZONTAL );
sb_credentials_tbl->Add( m_identity, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); m_own = new wxRadioButton( sb_credentials->GetStaticBox(), wxID_ANY, _("Use &own credentials:"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
m_own->SetToolTip( _("Select this option if you have your unique credentials to connect") );
sz_own_inner->Add( m_own, 2, wxEXPAND, 5 );
m_identity_own = new wxTextCtrl( sb_credentials->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
m_identity_own->SetToolTip( _("Enter your user name here (user@domain.org, DOMAINUser, etc.)") );
sz_own_inner->Add( m_identity_own, 3, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 );
sb_credentials_vert->Add( sb_credentials_tbl, 0, wxEXPAND|wxALL, 5 ); sz_own->Add( sz_own_inner, 1, wxEXPAND|wxBOTTOM, 5 );
wxBoxSizer* sb_buttons; wxBoxSizer* sb_buttons_own;
sb_buttons = new wxBoxSizer( wxHORIZONTAL ); sb_buttons_own = new wxBoxSizer( wxHORIZONTAL );
m_set = new wxButton( sb_credentials->GetStaticBox(), wxID_ANY, _("&Set Credentials..."), wxDefaultPosition, wxDefaultSize, 0 ); m_clear_own = new wxButton( sb_credentials->GetStaticBox(), wxID_ANY, _("&Clear Credentials"), wxDefaultPosition, wxDefaultSize, 0 );
m_set->SetToolTip( _("Click here to set or modify your credentials") ); m_clear_own->SetToolTip( _("Click to clear your credentials from Credential Manager.\nNote: You will be prompted to enter credentials when connecting.") );
sb_buttons->Add( m_set, 0, wxRIGHT, 5 ); sb_buttons_own->Add( m_clear_own, 0, wxRIGHT, 5 );
m_clear = new wxButton( sb_credentials->GetStaticBox(), wxID_ANY, _("&Clear Credentials"), wxDefaultPosition, wxDefaultSize, 0 ); m_set_own = new wxButton( sb_credentials->GetStaticBox(), wxID_ANY, _("&Set Credentials..."), wxDefaultPosition, wxDefaultSize, 0 );
m_clear->SetToolTip( _("Click to clear your credentials from Credential Manager.\nNote: You will be prompted to enter credentials when connecting.") ); m_set_own->SetToolTip( _("Click here to set or modify your credentials") );
sb_buttons->Add( m_clear, 0, wxLEFT, 5 ); sb_buttons_own->Add( m_set_own, 0, wxLEFT, 5 );
sb_credentials_vert->Add( sb_buttons, 0, wxALIGN_RIGHT|wxALL, 5 ); sz_own->Add( sb_buttons_own, 0, wxALIGN_RIGHT, 5 );
sb_cred_radio->Add( sz_own, 0, wxEXPAND|wxBOTTOM, 5 );
wxBoxSizer* sz_preshared;
sz_preshared = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* sz_preshared_inner;
sz_preshared_inner = new wxBoxSizer( wxHORIZONTAL );
m_preshared = new wxRadioButton( sb_credentials->GetStaticBox(), wxID_ANY, _("Use &pre-shared credentials:"), wxDefaultPosition, wxDefaultSize, 0 );
m_preshared->SetToolTip( _("Select this options if all clients connect using the same credentials") );
sz_preshared_inner->Add( m_preshared, 2, wxEXPAND, 5 );
m_identity_preshared = new wxTextCtrl( sb_credentials->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
m_identity_preshared->SetToolTip( _("Enter your user name here (user@domain.org, DOMAINUser, etc.)") );
sz_preshared_inner->Add( m_identity_preshared, 3, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 );
sz_preshared->Add( sz_preshared_inner, 1, wxEXPAND|wxBOTTOM, 5 );
wxBoxSizer* sb_buttons_preshared;
sb_buttons_preshared = new wxBoxSizer( wxHORIZONTAL );
m_set_preshared = new wxButton( sb_credentials->GetStaticBox(), wxID_ANY, _("&Set Credentials..."), wxDefaultPosition, wxDefaultSize, 0 );
m_set_preshared->SetToolTip( _("Click here to set or modify your credentials") );
sb_buttons_preshared->Add( m_set_preshared, 0, 0, 5 );
sz_preshared->Add( sb_buttons_preshared, 0, wxALIGN_RIGHT, 5 );
sb_cred_radio->Add( sz_preshared, 0, wxEXPAND|wxTOP, 5 );
sb_credentials_vert->Add( sb_cred_radio, 0, wxEXPAND|wxALL, 5 );
sb_credentials_horiz->Add( sb_credentials_vert, 1, wxEXPAND, 5 ); sb_credentials_horiz->Add( sb_credentials_vert, 1, wxEXPAND, 5 );
@ -181,16 +226,18 @@ wxEAPCredentialsConfigPanelBase::wxEAPCredentialsConfigPanelBase( wxWindow* pare
// Connect Events // Connect Events
this->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( wxEAPCredentialsConfigPanelBase::OnUpdateUI ) ); this->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( wxEAPCredentialsConfigPanelBase::OnUpdateUI ) );
m_set->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPCredentialsConfigPanelBase::OnSet ), NULL, this ); m_clear_own->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPCredentialsConfigPanelBase::OnClearOwn ), NULL, this );
m_clear->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPCredentialsConfigPanelBase::OnClear ), NULL, this ); m_set_own->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPCredentialsConfigPanelBase::OnSetOwn ), NULL, this );
m_set_preshared->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPCredentialsConfigPanelBase::OnSetPreshared ), NULL, this );
} }
wxEAPCredentialsConfigPanelBase::~wxEAPCredentialsConfigPanelBase() wxEAPCredentialsConfigPanelBase::~wxEAPCredentialsConfigPanelBase()
{ {
// Disconnect Events // Disconnect Events
this->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( wxEAPCredentialsConfigPanelBase::OnUpdateUI ) ); this->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( wxEAPCredentialsConfigPanelBase::OnUpdateUI ) );
m_set->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPCredentialsConfigPanelBase::OnSet ), NULL, this ); m_clear_own->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPCredentialsConfigPanelBase::OnClearOwn ), NULL, this );
m_clear->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPCredentialsConfigPanelBase::OnClear ), NULL, this ); m_set_own->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPCredentialsConfigPanelBase::OnSetOwn ), NULL, this );
m_set_preshared->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxEAPCredentialsConfigPanelBase::OnSetPreshared ), NULL, this );
} }

File diff suppressed because it is too large Load Diff

View File

@ -27,6 +27,7 @@ class wxEAPBannerPanel;
#include <wx/image.h> #include <wx/image.h>
#include <wx/icon.h> #include <wx/icon.h>
#include <wx/statbmp.h> #include <wx/statbmp.h>
#include <wx/radiobut.h>
#include <wx/textctrl.h> #include <wx/textctrl.h>
#include <wx/statbox.h> #include <wx/statbox.h>
#include <wx/checkbox.h> #include <wx/checkbox.h>
@ -110,15 +111,19 @@ class wxEAPCredentialsConfigPanelBase : public wxPanel
protected: protected:
wxStaticBitmap* m_credentials_icon; wxStaticBitmap* m_credentials_icon;
wxStaticText* m_credentials_label; wxStaticText* m_credentials_label;
wxStaticText* m_identity_label; wxRadioButton* m_own;
wxTextCtrl* m_identity; wxTextCtrl* m_identity_own;
wxButton* m_set; wxButton* m_clear_own;
wxButton* m_clear; wxButton* m_set_own;
wxRadioButton* m_preshared;
wxTextCtrl* m_identity_preshared;
wxButton* m_set_preshared;
// Virtual event handlers, overide them in your derived class // Virtual event handlers, overide them in your derived class
virtual void OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); } virtual void OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void OnSet( wxCommandEvent& event ) { event.Skip(); } virtual void OnClearOwn( wxCommandEvent& event ) { event.Skip(); }
virtual void OnClear( wxCommandEvent& event ) { event.Skip(); } virtual void OnSetOwn( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSetPreshared( wxCommandEvent& event ) { event.Skip(); }
public: public:

View File

@ -58,6 +58,7 @@ namespace eapserial
#pragma once #pragma once
#include "Credentials.h"
#include "../../EAPBase/include/Config.h" #include "../../EAPBase/include/Config.h"
#include <Windows.h> #include <Windows.h>
@ -67,7 +68,7 @@ namespace eapserial
namespace eap namespace eap
{ {
class config_pap : public config_pass class config_pap : public config_method<credentials_pap>
{ {
public: public:
/// ///
@ -130,18 +131,18 @@ namespace eapserial
{ {
inline void pack(_Inout_ unsigned char *&cursor, _In_ const eap::config_pap &val) inline void pack(_Inout_ unsigned char *&cursor, _In_ const eap::config_pap &val)
{ {
pack(cursor, (const eap::config_pass&)val); pack(cursor, (const eap::config_method<eap::credentials_pap>&)val);
} }
inline size_t get_pk_size(const eap::config_pap &val) inline size_t get_pk_size(const eap::config_pap &val)
{ {
return get_pk_size((const eap::config_pass&)val); return get_pk_size((const eap::config_method<eap::credentials_pap>&)val);
} }
inline void unpack(_Inout_ const unsigned char *&cursor, _Out_ eap::config_pap &val) inline void unpack(_Inout_ const unsigned char *&cursor, _Out_ eap::config_pap &val)
{ {
unpack(cursor, (eap::config_pass&)val); unpack(cursor, (eap::config_method<eap::credentials_pap>&)val);
} }
} }

View File

@ -29,6 +29,34 @@ namespace eap
class credentials_pap; class credentials_pap;
} }
namespace eapserial
{
///
/// Packs a PAP method credentials
///
/// \param[inout] cursor Memory cursor
/// \param[in] val Credentials to pack
///
inline void pack(_Inout_ unsigned char *&cursor, _In_ const eap::credentials_pap &val);
///
/// Returns packed size of a PAP method credentials
///
/// \param[in] val Credentials to pack
///
/// \returns Size of data when packed (in bytes)
///
inline size_t get_pk_size(const eap::credentials_pap &val);
///
/// Unpacks a PAP method credentials
///
/// \param[inout] cursor Memory cursor
/// \param[out] val Credentials to unpack to
///
inline void unpack(_Inout_ const unsigned char *&cursor, _Out_ eap::credentials_pap &val);
}
#pragma once #pragma once
#include "../../EAPBase/include/Credentials.h" #include "../../EAPBase/include/Credentials.h"
@ -100,3 +128,24 @@ namespace eap
/// @} /// @}
}; };
} }
namespace eapserial
{
inline void pack(_Inout_ unsigned char *&cursor, _In_ const eap::credentials_pap &val)
{
pack(cursor, (const eap::credentials_pass&)val);
}
inline size_t get_pk_size(const eap::credentials_pap &val)
{
return get_pk_size((const eap::credentials_pass&)val);
}
inline void unpack(_Inout_ const unsigned char *&cursor, _Out_ eap::credentials_pap &val)
{
unpack(cursor, (eap::credentials_pass&)val);
}
}

View File

@ -25,19 +25,19 @@
// eap::config_pap // eap::config_pap
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
eap::config_pap::config_pap(_In_ module &mod) : config_pass(mod) eap::config_pap::config_pap(_In_ module &mod) : config_method<credentials_pap>(mod)
{ {
} }
eap::config_pap::config_pap(_In_ const config_pap &other) : eap::config_pap::config_pap(_In_ const config_pap &other) :
config_pass(other) config_method<credentials_pap>(other)
{ {
} }
eap::config_pap::config_pap(_Inout_ config_pap &&other) : eap::config_pap::config_pap(_Inout_ config_pap &&other) :
config_pass(std::move(other)) config_method<credentials_pap>(std::move(other))
{ {
} }
@ -45,7 +45,7 @@ eap::config_pap::config_pap(_Inout_ config_pap &&other) :
eap::config_pap& eap::config_pap::operator=(_In_ const config_pap &other) eap::config_pap& eap::config_pap::operator=(_In_ const config_pap &other)
{ {
if (this != &other) if (this != &other)
(config_pass&)*this = other; (config_method<credentials_pap>&)*this = other;
return *this; return *this;
} }
@ -54,7 +54,7 @@ eap::config_pap& eap::config_pap::operator=(_In_ const config_pap &other)
eap::config_pap& eap::config_pap::operator=(_Inout_ config_pap &&other) eap::config_pap& eap::config_pap::operator=(_Inout_ config_pap &&other)
{ {
if (this != &other) if (this != &other)
(config_pass&&)*this = std::move(other); (config_method<credentials_pap>&&)*this = std::move(other);
return *this; return *this;
} }

View File

@ -58,6 +58,8 @@ namespace eapserial
#pragma once #pragma once
#include "Credentials.h"
#include "../../EAPBase/include/Config.h" #include "../../EAPBase/include/Config.h"
#include <WinStd/Crypt.h> #include <WinStd/Crypt.h>
@ -70,7 +72,7 @@ namespace eapserial
namespace eap namespace eap
{ {
class config_tls : public config_method class config_tls : public config_method<credentials_tls>
{ {
public: public:
/// ///
@ -174,24 +176,24 @@ namespace eapserial
{ {
inline void pack(_Inout_ unsigned char *&cursor, _In_ const eap::config_tls &val) inline void pack(_Inout_ unsigned char *&cursor, _In_ const eap::config_tls &val)
{ {
pack(cursor, (const eap::config_method&)val); pack(cursor, (const eap::config_method<eap::credentials_tls>&)val);
pack(cursor, val.m_trusted_root_ca ); pack(cursor, val.m_trusted_root_ca);
pack(cursor, val.m_server_names ); pack(cursor, val.m_server_names );
} }
inline size_t get_pk_size(const eap::config_tls &val) inline size_t get_pk_size(const eap::config_tls &val)
{ {
return return
get_pk_size((const eap::config_method&)val) + get_pk_size((const eap::config_method<eap::credentials_tls>&)val) +
get_pk_size(val.m_trusted_root_ca ) + get_pk_size(val.m_trusted_root_ca) +
get_pk_size(val.m_server_names ); get_pk_size(val.m_server_names );
} }
inline void unpack(_Inout_ const unsigned char *&cursor, _Out_ eap::config_tls &val) inline void unpack(_Inout_ const unsigned char *&cursor, _Out_ eap::config_tls &val)
{ {
unpack(cursor, (eap::config_method&)val ); unpack(cursor, (eap::config_method<eap::credentials_tls>&)val);
unpack(cursor, val.m_trusted_root_ca); unpack(cursor, val.m_trusted_root_ca);
unpack(cursor, val.m_server_names ); unpack(cursor, val.m_server_names );
} }

View File

@ -28,7 +28,7 @@ using namespace winstd;
// eap::config_tls // eap::config_tls
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
eap::config_tls::config_tls(_In_ module &mod) : config_method(mod) eap::config_tls::config_tls(_In_ module &mod) : config_method<credentials_tls>(mod)
{ {
} }
@ -36,7 +36,7 @@ eap::config_tls::config_tls(_In_ module &mod) : config_method(mod)
eap::config_tls::config_tls(_In_ const config_tls &other) : eap::config_tls::config_tls(_In_ const config_tls &other) :
m_trusted_root_ca(other.m_trusted_root_ca), m_trusted_root_ca(other.m_trusted_root_ca),
m_server_names(other.m_server_names), m_server_names(other.m_server_names),
config_method(other) config_method<credentials_tls>(other)
{ {
} }
@ -44,7 +44,7 @@ eap::config_tls::config_tls(_In_ const config_tls &other) :
eap::config_tls::config_tls(_Inout_ config_tls &&other) : eap::config_tls::config_tls(_Inout_ config_tls &&other) :
m_trusted_root_ca(std::move(other.m_trusted_root_ca)), m_trusted_root_ca(std::move(other.m_trusted_root_ca)),
m_server_names(std::move(other.m_server_names)), m_server_names(std::move(other.m_server_names)),
config_method(std::move(other)) config_method<credentials_tls>(std::move(other))
{ {
} }
@ -52,9 +52,9 @@ eap::config_tls::config_tls(_Inout_ config_tls &&other) :
eap::config_tls& eap::config_tls::operator=(_In_ const eap::config_tls &other) eap::config_tls& eap::config_tls::operator=(_In_ const eap::config_tls &other)
{ {
if (this != &other) { if (this != &other) {
(config_method&)*this = other; (config_method<credentials_tls>&)*this = other;
m_trusted_root_ca = other.m_trusted_root_ca; m_trusted_root_ca = other.m_trusted_root_ca;
m_server_names = other.m_server_names; m_server_names = other.m_server_names;
} }
return *this; return *this;
@ -64,9 +64,9 @@ eap::config_tls& eap::config_tls::operator=(_In_ const eap::config_tls &other)
eap::config_tls& eap::config_tls::operator=(_Inout_ eap::config_tls &&other) eap::config_tls& eap::config_tls::operator=(_Inout_ eap::config_tls &&other)
{ {
if (this != &other) { if (this != &other) {
(config_method&&)*this = std::move(other); (config_method<credentials_tls>&&)*this = std::move(other);
m_trusted_root_ca = std::move(other.m_trusted_root_ca); m_trusted_root_ca = std::move(other.m_trusted_root_ca);
m_server_names = std::move(other.m_server_names); m_server_names = std::move(other.m_server_names);
} }
return *this; return *this;
@ -129,7 +129,7 @@ DWORD eap::config_tls::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pConfi
} }
} }
return config_method::save(pDoc, pConfigRoot, ppEapError); return config_method<credentials_tls>::save(pDoc, pConfigRoot, ppEapError);
} }
@ -180,7 +180,7 @@ DWORD eap::config_tls::load(_In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR **ppE
} }
} }
return config_method::load(pConfigRoot, ppEapError); return config_method<credentials_tls>::load(pConfigRoot, ppEapError);
} }

View File

@ -41,7 +41,7 @@ eap::credentials_tls::credentials_tls(_In_ const credentials_tls &other) :
eap::credentials_tls::credentials_tls(_Inout_ credentials_tls &&other) : eap::credentials_tls::credentials_tls(_Inout_ credentials_tls &&other) :
m_cert_hash(std::move(m_cert_hash)), m_cert_hash(std::move(other.m_cert_hash)),
credentials(std::move(other)) credentials(std::move(other))
{ {
} }
@ -93,12 +93,14 @@ DWORD eap::credentials_tls::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *p
const bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata"); const bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata");
DWORD dwResult; DWORD dwResult;
if ((dwResult = credentials::save(pDoc, pConfigRoot, ppEapError)) != ERROR_SUCCESS)
return dwResult;
// <CertHash> // <CertHash>
if (!m_cert_hash.empty()) if ((dwResult = eapxml::put_element_hex(pDoc, pConfigRoot, bstr(L"CertHash"), bstrNamespace, m_cert_hash.data(), m_cert_hash.size())) != ERROR_SUCCESS) {
if ((dwResult = eapxml::put_element_hex(pDoc, pConfigRoot, bstr(L"CertHash"), bstrNamespace, m_cert_hash.data(), m_cert_hash.size())) != ERROR_SUCCESS) { *ppEapError = m_module.make_error(dwResult, 0, NULL, NULL, NULL, _T(__FUNCTION__) _T(" Error creating <CertHash> element."), NULL);
*ppEapError = m_module.make_error(dwResult, 0, NULL, NULL, NULL, _T(__FUNCTION__) _T(" Error creating <CertHash> element."), NULL); return dwResult;
return dwResult; }
}
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
@ -107,9 +109,16 @@ DWORD eap::credentials_tls::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *p
DWORD eap::credentials_tls::load(_In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR **ppEapError) DWORD eap::credentials_tls::load(_In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR **ppEapError)
{ {
assert(pConfigRoot); assert(pConfigRoot);
UNREFERENCED_PARAMETER(ppEapError); DWORD dwResult;
eapxml::get_element_hex(pConfigRoot, bstr(L"CertHash"), m_cert_hash); if ((dwResult = credentials::load(pConfigRoot, ppEapError)) != ERROR_SUCCESS)
return dwResult;
// <CertHash>
if ((dwResult = eapxml::get_element_hex(pConfigRoot, bstr(L"eap-metadata:CertHash"), m_cert_hash)) != ERROR_SUCCESS) {
*ppEapError = m_module.make_error(dwResult, 0, NULL, NULL, NULL, _T(__FUNCTION__) _T(" Error reading <CertHash> element."), NULL);
return dwResult;
}
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }

View File

@ -158,7 +158,7 @@ namespace eap {
virtual eap::type_t get_method_id() const; virtual eap::type_t get_method_id() const;
public: public:
config_method *m_inner; ///< Inner authentication configuration config *m_inner; ///< Inner authentication configuration
}; };
} }
@ -170,26 +170,31 @@ namespace eapserial
pack(cursor, (const eap::config_tls&)val); pack(cursor, (const eap::config_tls&)val);
if (val.m_inner) { if (val.m_inner) {
if (dynamic_cast<eap::config_pap*>(val.m_inner)) { if (dynamic_cast<eap::config_pap*>(val.m_inner)) {
pack(cursor, (unsigned char)eap::type_pap); pack(cursor, eap::type_pap);
pack(cursor, (const eap::config_pap&)*val.m_inner); pack(cursor, (const eap::config_pap&)*val.m_inner);
} else { } else {
assert(0); // Unsupported inner authentication method type. assert(0); // Unsupported inner authentication method type.
pack(cursor, (unsigned char)0); pack(cursor, eap::type_undefined);
} }
} else } else
pack(cursor, (unsigned char)0); pack(cursor, eap::type_undefined);
} }
inline size_t get_pk_size(const eap::config_ttls &val) inline size_t get_pk_size(const eap::config_ttls &val)
{ {
size_t size_inner = sizeof(unsigned char); size_t size_inner;
if (val.m_inner) { if (val.m_inner) {
if (dynamic_cast<eap::config_pap*>(val.m_inner)) if (dynamic_cast<eap::config_pap*>(val.m_inner)) {
size_inner += get_pk_size((const eap::config_pap&)*val.m_inner); size_inner =
else get_pk_size(eap::type_pap) +
get_pk_size((const eap::config_pap&)*val.m_inner);
} else {
size_inner = get_pk_size(eap::type_undefined);
assert(0); // Unsupported inner authentication method type. assert(0); // Unsupported inner authentication method type.
} }
} else
size_inner = get_pk_size(eap::type_undefined);
return return
get_pk_size((const eap::config_tls&)val) + get_pk_size((const eap::config_tls&)val) +
@ -201,16 +206,19 @@ namespace eapserial
{ {
unpack(cursor, (eap::config_tls&)val); unpack(cursor, (eap::config_tls&)val);
assert(!val.m_inner); if (val.m_inner)
unsigned char eap_type; delete val.m_inner;
eap::type_t eap_type;
unpack(cursor, eap_type); unpack(cursor, eap_type);
switch (eap_type) { switch (eap_type) {
case eap::type_pap: case eap::type_pap:
val.m_inner = new eap::config_pap(val.m_module); val.m_inner = new eap::config_pap(val.m_module);
unpack(cursor, (eap::config_pap&)*val.m_inner); unpack(cursor, (eap::config_pap&)*val.m_inner);
break; break;
case 0 : break; default:
default : assert(0); // Unsupported inner authentication method type. val.m_inner = NULL;
assert(0); // Unsupported inner authentication method type.
} }
} }
} }

View File

@ -124,6 +124,19 @@ namespace eap
/// \name XML credentials management /// \name XML credentials management
/// @{ /// @{
///
/// Save credentials to XML document
///
/// \param[in] pDoc XML document
/// \param[in] pConfigRoot Suggested root element for saving credentials
/// \param[out] ppEapError Pointer to error descriptor in case of failure. Free using `module::free_error_memory()`.
///
/// \returns
/// - \c ERROR_SUCCESS if succeeded
/// - error code otherwise
///
virtual DWORD save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR **ppEapError) const;
/// ///
/// Load credentials from XML document /// Load credentials from XML document
/// ///

View File

@ -93,6 +93,9 @@ DWORD eap::config_ttls::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pConf
const bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata"); const bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata");
DWORD dwResult; DWORD dwResult;
if ((dwResult = config_tls::save(pDoc, pConfigRoot, ppEapError)) != ERROR_SUCCESS)
return dwResult;
// <InnerAuthenticationMethod> // <InnerAuthenticationMethod>
com_obj<IXMLDOMElement> pXmlElInnerAuthenticationMethod; com_obj<IXMLDOMElement> pXmlElInnerAuthenticationMethod;
if ((dwResult = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:InnerAuthenticationMethod"), bstr(L"InnerAuthenticationMethod"), bstrNamespace, &pXmlElInnerAuthenticationMethod)) != ERROR_SUCCESS) { if ((dwResult = eapxml::create_element(pDoc, pConfigRoot, bstr(L"eap-metadata:InnerAuthenticationMethod"), bstr(L"InnerAuthenticationMethod"), bstrNamespace, &pXmlElInnerAuthenticationMethod)) != ERROR_SUCCESS) {
@ -113,7 +116,7 @@ DWORD eap::config_ttls::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pConf
} else } else
return dwResult = ERROR_NOT_SUPPORTED; return dwResult = ERROR_NOT_SUPPORTED;
return config_tls::save(pDoc, pConfigRoot, ppEapError); return ERROR_SUCCESS;
} }
@ -122,6 +125,9 @@ DWORD eap::config_ttls::load(_In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR **pp
assert(ppEapError); assert(ppEapError);
DWORD dwResult; DWORD dwResult;
if ((dwResult = config_tls::load(pConfigRoot, ppEapError)) != ERROR_SUCCESS)
return dwResult;
// Load inner authentication configuration (<InnerAuthenticationMethod>). // Load inner authentication configuration (<InnerAuthenticationMethod>).
com_obj<IXMLDOMElement> pXmlElInnerAuthenticationMethod; com_obj<IXMLDOMElement> pXmlElInnerAuthenticationMethod;
if ((dwResult = eapxml::select_element(pConfigRoot, bstr(L"eap-metadata:InnerAuthenticationMethod"), &pXmlElInnerAuthenticationMethod)) != ERROR_SUCCESS) { if ((dwResult = eapxml::select_element(pConfigRoot, bstr(L"eap-metadata:InnerAuthenticationMethod"), &pXmlElInnerAuthenticationMethod)) != ERROR_SUCCESS) {
@ -151,7 +157,7 @@ DWORD eap::config_ttls::load(_In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR **pp
return dwResult; return dwResult;
} }
return config_tls::load(pConfigRoot, ppEapError); return ERROR_SUCCESS;
} }

View File

@ -95,6 +95,36 @@ bool eap::credentials_ttls::empty() const
} }
DWORD eap::credentials_ttls::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR **ppEapError) const
{
const bstr bstrNamespace(L"urn:ietf:params:xml:ns:yang:ietf-eap-metadata");
DWORD dwResult;
HRESULT hr;
if ((dwResult = credentials_tls::save(pDoc, pConfigRoot, ppEapError)) != ERROR_SUCCESS)
return dwResult;
if (m_inner) {
// <InnerAuthenticationMethod>
winstd::com_obj<IXMLDOMElement> pXmlElInnerAuthenticationMethod;
if ((dwResult = eapxml::create_element(pDoc, winstd::bstr(L"InnerAuthenticationMethod"), bstrNamespace, &pXmlElInnerAuthenticationMethod))) {
*ppEapError = m_module.make_error(dwResult, 0, NULL, NULL, NULL, _T(__FUNCTION__) _T(" Error creating <InnerAuthenticationMethod> element."), NULL);
return dwResult;
}
if ((dwResult = m_inner->save(pDoc, pXmlElInnerAuthenticationMethod, ppEapError)) != ERROR_SUCCESS)
return dwResult;
if (FAILED(hr = pConfigRoot->appendChild(pXmlElInnerAuthenticationMethod, NULL))) {
*ppEapError = m_module.make_error(dwResult = HRESULT_CODE(hr), 0, NULL, NULL, NULL, _T(__FUNCTION__) _T(" Error appending <InnerAuthenticationMethod> element."), NULL);
return dwResult;
}
}
return ERROR_SUCCESS;
}
DWORD eap::credentials_ttls::load(_In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR **ppEapError) DWORD eap::credentials_ttls::load(_In_ IXMLDOMNode *pConfigRoot, _Out_ EAP_ERROR **ppEapError)
{ {
assert(pConfigRoot); assert(pConfigRoot);

@ -1 +1 @@
Subproject commit 385986f704e96025cc7111b74094579ceb0b7380 Subproject commit 7510410b5660ba9027feb432f8f18940e000f376