From 12ef3059e94ee16c1b00598460260744bb642757 Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Mon, 22 Nov 2021 14:40:28 +0100 Subject: [PATCH] Backport EAPSup code changes This introduces some PEAP/EAP-TTLS split code, but helps maintain shared code base. Signed-off-by: Simon Rozman --- lib/TTLS_UI/include/Module.h | 49 +++++++++-- lib/TTLS_UI/include/TTLS_UI.h | 55 +++++++++--- lib/TTLS_UI/src/Module.cpp | 117 ++++++++++++++++++------ lib/TTLS_UI/src/TTLS_UI.cpp | 161 ++++++++++++++++++++-------------- 4 files changed, 271 insertions(+), 111 deletions(-) diff --git a/lib/TTLS_UI/include/Module.h b/lib/TTLS_UI/include/Module.h index 3fc7c05..7f99bcc 100644 --- a/lib/TTLS_UI/include/Module.h +++ b/lib/TTLS_UI/include/Module.h @@ -37,22 +37,26 @@ namespace eap /// @{ /// - /// TTLS UI peer + /// PEAP UI peer /// - class peer_ttls_ui : public peer_ui + class peer_peap_ui : public peer_ui { public: /// - /// Constructs a EAP-TTLS UI peer module + /// Constructs a PEAP UI peer module /// - peer_ttls_ui(); + peer_peap_ui(); + protected: /// - /// @copydoc eap::method::make_config() - /// \returns This implementation always returns `eap::config_method_ttls` type of configuration + /// Constructs a peer module /// - virtual config_method* make_config(); + /// \param[in] eap_method EAP method type ID + /// \param[in] domain Localization catalog domain name. Usually EAP method name followed by "_UI". + /// + peer_peap_ui(_In_ winstd::eap_type_t eap_method, _In_opt_ LPCTSTR domain); + public: virtual void invoke_config_ui( _In_ HWND hwndParent, _In_count_(dwConnectionDataInSize) const BYTE *pConnectionDataIn, @@ -77,6 +81,37 @@ namespace eap _In_ DWORD dwUIContextDataSize, _Inout_ BYTE **ppDataFromInteractiveUI, _Inout_ DWORD *pdwDataFromInteractiveUISize); + + protected: + virtual wxEAPCredentialsPanelBase* make_inner_credential_panel(const config_provider &prov, const config_method_with_cred &cfg, credentials *cred, wxWindow *parent) const; + }; + + /// + /// EAP-TTLS UI peer + /// + class peer_ttls_ui : public peer_peap_ui + { + public: + /// + /// Constructs a EAP-TTLS UI peer module + /// + peer_ttls_ui(); + + /// + /// @copydoc eap::method::make_config() + /// \returns This implementation always returns `eap::config_method_ttls` type of configuration + /// + virtual config_method* make_config(); + + virtual void invoke_config_ui( + _In_ HWND hwndParent, + _In_count_(dwConnectionDataInSize) const BYTE *pConnectionDataIn, + _In_ DWORD dwConnectionDataInSize, + _Out_ BYTE **ppConnectionDataOut, + _Out_ DWORD *pdwConnectionDataOutSize); + + protected: + virtual wxEAPCredentialsPanelBase* make_inner_credential_panel(const config_provider &prov, const config_method_with_cred &cfg, credentials *cred, wxWindow *parent) const; }; /// @} diff --git a/lib/TTLS_UI/include/TTLS_UI.h b/lib/TTLS_UI/include/TTLS_UI.h index 9e7d131..a466ff9 100644 --- a/lib/TTLS_UI/include/TTLS_UI.h +++ b/lib/TTLS_UI/include/TTLS_UI.h @@ -19,6 +19,7 @@ */ class wxTLSTunnelConfigWindow; +class wxPEAPConfigWindow; class wxTTLSConfigWindow; #pragma once @@ -26,6 +27,12 @@ class wxTTLSConfigWindow; #include "../../TLS_UI/include/TLS_UI.h" #include "../../TTLS/include/Config.h" + +#include "../../EapHost_UI/include/EapHost_UI.h" +#include "../../PAP_UI/include/PAP_UI.h" +#include "../../MSCHAPv2_UI/include/MSCHAPv2_UI.h" +#include "../../GTC_UI/include/GTC_UI.h" + #include "../../EapHost/include/Config.h" #include "../../PAP/include/Config.h" #include "../../MSCHAPv2/include/Config.h" @@ -80,9 +87,41 @@ protected: /// -/// TTLS configuration scrollable window +/// PEAP configuration scrollable window /// -class wxTTLSConfigWindow : public wxTLSTunnelConfigWindow +class wxPEAPConfigWindow : public wxTLSTunnelConfigWindow +{ +public: + /// + /// Constructs a configuration window + /// + /// \param[in] prov Provider configuration data + /// \param[inout] cfg Method configuration data + /// \param[in] parent Parent window + /// + wxPEAPConfigWindow(eap::config_provider &prov, eap::config_method &cfg, wxWindow* parent); + +protected: + /// \cond internal + virtual bool TransferDataToWindow(); + virtual bool TransferDataFromWindow(); + /// \endcond + +protected: + eap::config_method_eapmschapv2 m_cfg_eapmschapv2; ///< EAP-MSCHAPv2 configuration to hold data until applied + wxMSCHAPv2ConfigPanel *m_panel_eapmschapv2; ///< EAP-MSCHAPv2 config panel + eap::config_method_eapgtc m_cfg_eapgtc; ///< EAP-GTC configuration to hold data until applied + wxGTCConfigPanel *m_panel_eapgtc; ///< EAP-GTC config panel +#if EAP_INNER_EAPHOST + eap::config_method_eaphost m_cfg_eaphost; ///< Inner EAP configuration to hold data until applied + wxEapHostConfigPanel *m_panel_eaphost; ///< Inner EAP config panel +#endif +}; + +/// +/// EAP-TTLS configuration scrollable window +/// +class wxTTLSConfigWindow : public wxPEAPConfigWindow { public: /// @@ -101,14 +140,10 @@ protected: /// \endcond protected: - // Temporary inner method configurations to hold data until applied - eap::config_method_pap m_cfg_pap; ///< PAP configuration - eap::config_method_mschapv2 m_cfg_mschapv2; ///< MSCHAPv2 configuration - eap::config_method_eapmschapv2 m_cfg_eapmschapv2; ///< EAP-MSCHAPv2 configuration - eap::config_method_eapgtc m_cfg_eapgtc; ///< EAP-GTC configuration -#if EAP_INNER_EAPHOST - eap::config_method_eaphost m_cfg_eaphost; ///< Inner EAP configuration -#endif + eap::config_method_pap m_cfg_pap; ///< PAP configuration to hold data until applied + wxPAPConfigPanel *m_panel_pap; ///< PAP config panel + eap::config_method_mschapv2 m_cfg_mschapv2; ///< MSCHAPv2 configuration to hold data until applied + wxMSCHAPv2ConfigPanel *m_panel_mschapv2; ///< MSCHAPv2 config panel }; /// @} diff --git a/lib/TTLS_UI/src/Module.cpp b/lib/TTLS_UI/src/Module.cpp index 8ee8dc8..c71af50 100644 --- a/lib/TTLS_UI/src/Module.cpp +++ b/lib/TTLS_UI/src/Module.cpp @@ -25,21 +25,20 @@ using namespace winstd; ////////////////////////////////////////////////////////////////////// -// eap::peer_ttls_ui +// eap::peer_peap_ui ////////////////////////////////////////////////////////////////////// -eap::peer_ttls_ui::peer_ttls_ui() : peer_ui(eap_type_t::ttls, _T("EAP-TTLS_UI")) +eap::peer_peap_ui::peer_peap_ui() : peer_ui(eap_type_t::peap, _T("PEAP_UI")) { } -eap::config_method* eap::peer_ttls_ui::make_config() +eap::peer_peap_ui::peer_peap_ui(_In_ eap_type_t eap_method, _In_opt_ LPCTSTR domain) : peer_ui(eap_method, domain) { - return new config_method_ttls(*this, 0); } -void eap::peer_ttls_ui::invoke_config_ui( +void eap::peer_peap_ui::invoke_config_ui( _In_ HWND hwndParent, _In_count_(dwConnectionDataInSize) const BYTE *pConnectionDataIn, _In_ DWORD dwConnectionDataInSize, @@ -59,7 +58,7 @@ void eap::peer_ttls_ui::invoke_config_ui( wxInitializerPeer init(m_instance, m_domain, hwndParent); // Create and launch configuration dialog. - wxEAPConfigDialog dlg(cfg, init.m_parent); + wxEAPConfigDialog dlg(cfg, init.m_parent); if (!init.m_parent) { FLASHWINFO fwi = { sizeof(FLASHWINFO), dlg.GetHWND(), FLASHW_ALL | FLASHW_TIMERNOFG }; ::FlashWindowEx(&fwi); @@ -72,7 +71,7 @@ void eap::peer_ttls_ui::invoke_config_ui( } -void eap::peer_ttls_ui::invoke_identity_ui( +void eap::peer_peap_ui::invoke_identity_ui( _In_ HWND hwndParent, _In_ DWORD dwFlags, _In_count_(dwConnectionDataSize) const BYTE *pConnectionData, @@ -260,27 +259,7 @@ void eap::peer_ttls_ui::invoke_identity_ui( wxUICanceller lock(hWndCurrent, dlg.GetHWND()); if (eap::config_method::status_t::cred_begin <= cfg_method->m_inner->m_last_status && cfg_method->m_inner->m_last_status < eap::config_method::status_t::cred_end) dlg.AddContent(new wxEAPCredentialWarningPanel(*cfg_prov, cfg_method->m_inner->m_last_status, &dlg)); - wxEAPCredentialsPanelBase *panel = NULL; - switch (cfg_method->m_inner->get_method_id()) { - case eap_type_t::legacy_pap : panel = new wxPAPCredentialsPanel (*cfg_prov, *dynamic_cast(cfg_method->m_inner.get()), *dynamic_cast(cred->m_inner.get()), &dlg, false); break; - case eap_type_t::legacy_mschapv2: panel = new wxMSCHAPv2CredentialsPanel(*cfg_prov, *dynamic_cast(cfg_method->m_inner.get()), *dynamic_cast(cred->m_inner.get()), &dlg, false); break; - case eap_type_t::mschapv2 : panel = new wxMSCHAPv2CredentialsPanel(*cfg_prov, *dynamic_cast(cfg_method->m_inner.get()), *dynamic_cast(cred->m_inner.get()), &dlg, false); break; - case eap_type_t::gtc : { - // EAP-GTC credential prompt differes for "Challenge/Response" and "Password" authentication modes. - eap::credentials_identity *cred_resp; - eap::credentials_pass *cred_pass; - if ((cred_resp = dynamic_cast(cred->m_inner.get())) != NULL) - panel = new wxGTCResponseCredentialsPanel(*cfg_prov, *dynamic_cast(cfg_method->m_inner.get()), *cred_resp, &dlg, false); - else if ((cred_pass = dynamic_cast(cred->m_inner.get())) != NULL) - panel = new wxGTCPasswordCredentialsPanel(*cfg_prov, *dynamic_cast(cfg_method->m_inner.get()), *cred_pass, &dlg, false); - else - wxLogError("Unsupported authentication mode."); - break; - } - default: wxLogError("Unsupported inner authentication method."); - } - if (!panel) - throw invalid_argument("Invalid authentication mode"); + wxEAPCredentialsPanelBase *panel = make_inner_credential_panel(*cfg_prov, *dynamic_cast(cfg_method->m_inner.get()), cred->m_inner.get(), &dlg); panel->SetRemember(src_inner == eap::credentials::source_t::storage); dlg.AddContent(panel); @@ -322,7 +301,7 @@ void eap::peer_ttls_ui::invoke_identity_ui( } -void eap::peer_ttls_ui::invoke_interactive_ui( +void eap::peer_peap_ui::invoke_interactive_ui( _In_ HWND hwndParent, _In_count_(dwUIContextDataSize) const BYTE *pUIContextData, _In_ DWORD dwUIContextDataSize, @@ -416,3 +395,83 @@ void eap::peer_ttls_ui::invoke_interactive_ui( // Pack output data. pack(ctx.m_data, ppDataFromInteractiveUI, pdwDataFromInteractiveUISize); } + + +wxEAPCredentialsPanelBase* eap::peer_peap_ui::make_inner_credential_panel(const config_provider &prov, const config_method_with_cred &cfg, credentials *cred, wxWindow *parent) const +{ + switch (cfg.get_method_id()) { + case eap_type_t::mschapv2: return new wxMSCHAPv2CredentialsPanel(prov, dynamic_cast(cfg), *dynamic_cast(cred), parent, false); break; + case eap_type_t::gtc : { + // EAP-GTC credential prompt differes for "Challenge/Response" and "Password" authentication modes. + eap::credentials_identity *cred_resp; + eap::credentials_pass *cred_pass; + if ((cred_resp = dynamic_cast(cred)) != NULL) + return new wxGTCResponseCredentialsPanel(prov, dynamic_cast(cfg), *cred_resp, parent, false); + else if ((cred_pass = dynamic_cast(cred)) != NULL) + return new wxGTCPasswordCredentialsPanel(prov, dynamic_cast(cfg), *cred_pass, parent, false); + else + wxLogError("Unsupported authentication mode."); + break; + } + default: wxLogError("Unsupported inner authentication method."); + } + throw invalid_argument("Invalid authentication mode"); +} + + +////////////////////////////////////////////////////////////////////// +// eap::peer_ttls_ui +////////////////////////////////////////////////////////////////////// + +eap::peer_ttls_ui::peer_ttls_ui() : peer_peap_ui(eap_type_t::ttls, _T("EAP-TTLS_UI")) +{ +} + + +eap::config_method* eap::peer_ttls_ui::make_config() +{ + return new config_method_ttls(*this, 0); +} + + +void eap::peer_ttls_ui::invoke_config_ui( + _In_ HWND hwndParent, + _In_count_(dwConnectionDataInSize) const BYTE *pConnectionDataIn, + _In_ DWORD dwConnectionDataInSize, + _Out_ BYTE **ppConnectionDataOut, + _Out_ DWORD *pdwConnectionDataOutSize) +{ + // Unpack configuration. + config_connection cfg(*this); + if (dwConnectionDataInSize) { + // Load existing configuration. + unpack(cfg, pConnectionDataIn, dwConnectionDataInSize); + } else { + // This is a blank network profile. `cfg` is already set to defaults. + } + + // Initialize application. + wxInitializerPeer init(m_instance, m_domain, hwndParent); + + // Create and launch configuration dialog. + wxEAPConfigDialog dlg(cfg, init.m_parent); + if (!init.m_parent) { + FLASHWINFO fwi = { sizeof(FLASHWINFO), dlg.GetHWND(), FLASHW_ALL | FLASHW_TIMERNOFG }; + ::FlashWindowEx(&fwi); + } + if (dlg.ShowModal() != wxID_OK) + throw win_runtime_error(ERROR_CANCELLED, __FUNCTION__ " Cancelled."); + + // Pack new configuration. + pack(cfg, ppConnectionDataOut, pdwConnectionDataOutSize); +} + + +wxEAPCredentialsPanelBase* eap::peer_ttls_ui::make_inner_credential_panel(const config_provider &prov, const config_method_with_cred &cfg, credentials *cred, wxWindow *parent) const +{ + switch (cfg.get_method_id()) { + case eap_type_t::legacy_pap : return new wxPAPCredentialsPanel (prov, dynamic_cast(cfg), *dynamic_cast(cred), parent, false); break; + case eap_type_t::legacy_mschapv2: return new wxMSCHAPv2CredentialsPanel(prov, dynamic_cast(cfg), *dynamic_cast(cred), parent, false); break; + } + return peer_peap_ui::make_inner_credential_panel(prov, cfg, cred, parent); +} diff --git a/lib/TTLS_UI/src/TTLS_UI.cpp b/lib/TTLS_UI/src/TTLS_UI.cpp index caf8020..3f612ad 100644 --- a/lib/TTLS_UI/src/TTLS_UI.cpp +++ b/lib/TTLS_UI/src/TTLS_UI.cpp @@ -112,12 +112,10 @@ void wxTLSTunnelConfigWindow::OnUpdateUI(wxUpdateUIEvent& event) ////////////////////////////////////////////////////////////////////// -// wxTTLSConfigWindow +// wxPEAPConfigWindow ////////////////////////////////////////////////////////////////////// -wxTTLSConfigWindow::wxTTLSConfigWindow(eap::config_provider &prov, eap::config_method &cfg, wxWindow* parent) : - m_cfg_pap (cfg.m_module, cfg.m_level + 1), - m_cfg_mschapv2 (cfg.m_module, cfg.m_level + 1), +wxPEAPConfigWindow::wxPEAPConfigWindow(eap::config_provider &prov, eap::config_method &cfg, wxWindow* parent) : m_cfg_eapmschapv2(cfg.m_module, cfg.m_level + 1), m_cfg_eapgtc (cfg.m_module, cfg.m_level + 1), #if EAP_INNER_EAPHOST @@ -125,97 +123,130 @@ wxTTLSConfigWindow::wxTTLSConfigWindow(eap::config_provider &prov, eap::config_m #endif wxTLSTunnelConfigWindow(prov, cfg, parent) { - wxPAPConfigPanel *panel_pap = new wxPAPConfigPanel(m_prov, m_cfg_pap, m_inner_type); - m_inner_type->AddPage(panel_pap, _("PAP")); - wxMSCHAPv2ConfigPanel *panel_mschapv2 = new wxMSCHAPv2ConfigPanel(m_prov, m_cfg_mschapv2, m_inner_type); - m_inner_type->AddPage(panel_mschapv2, _("MSCHAPv2")); - wxMSCHAPv2ConfigPanel *panel_eapmschapv2 = new wxMSCHAPv2ConfigPanel(m_prov, m_cfg_eapmschapv2, m_inner_type); - m_inner_type->AddPage(panel_eapmschapv2, _("EAP-MSCHAPv2")); - wxGTCConfigPanel *panel_eapgtc = new wxGTCConfigPanel(m_prov, m_cfg_eapgtc, m_inner_type); - m_inner_type->AddPage(panel_eapgtc, _("EAP-GTC")); + m_panel_eapmschapv2 = new wxMSCHAPv2ConfigPanel(m_prov, m_cfg_eapmschapv2, m_inner_type); + m_inner_type->AddPage(m_panel_eapmschapv2, _("EAP-MSCHAPv2")); + m_panel_eapgtc = new wxGTCConfigPanel(m_prov, m_cfg_eapgtc, m_inner_type); + m_inner_type->AddPage(m_panel_eapgtc, _("EAP-GTC")); #if EAP_INNER_EAPHOST - wxEapHostConfigPanel *panel_eaphost = new wxEapHostConfigPanel(m_prov, m_cfg_eaphost, m_inner_type); - m_inner_type->AddPage(panel_eaphost, _("Other EAP methods...")); + m_panel_eaphost = new wxEapHostConfigPanel(m_prov, m_cfg_eaphost, m_inner_type); + m_inner_type->AddPage(m_panel_eaphost, _("Other EAP methods...")); #endif } /// \cond internal -bool wxTTLSConfigWindow::TransferDataToWindow() +bool wxPEAPConfigWindow::TransferDataToWindow() { - auto &cfg_ttls = dynamic_cast(m_cfg); - - // Native inner methods - switch (cfg_ttls.m_inner->get_method_id()) { - case winstd::eap_type_t::legacy_pap: - m_cfg_pap = dynamic_cast(*cfg_ttls.m_inner); - m_inner_type->SetSelection(0); // 0=PAP - break; - - case winstd::eap_type_t::legacy_mschapv2: - m_cfg_mschapv2 = dynamic_cast(*cfg_ttls.m_inner); - m_inner_type->SetSelection(1); // 1=MSCHAPv2 - break; + auto &cfg = dynamic_cast(m_cfg); + switch (cfg.m_inner->get_method_id()) { case winstd::eap_type_t::mschapv2: - m_cfg_eapmschapv2 = dynamic_cast(*cfg_ttls.m_inner); - m_inner_type->SetSelection(2); // 2=EAP-MSCHAPv2 + m_cfg_eapmschapv2 = dynamic_cast(*cfg.m_inner); + m_inner_type->SetSelection(m_inner_type->FindPage(m_panel_eapmschapv2)); break; case winstd::eap_type_t::gtc: - m_cfg_eapgtc = dynamic_cast(*cfg_ttls.m_inner); - m_inner_type->SetSelection(3); // 3=EAP-GTC + m_cfg_eapgtc = dynamic_cast(*cfg.m_inner); + m_inner_type->SetSelection(m_inner_type->FindPage(m_panel_eapgtc)); break; +#if EAP_INNER_EAPHOST case winstd::eap_type_t::undefined: - m_cfg_eaphost = dynamic_cast(*cfg_ttls.m_inner); - m_inner_type->SetSelection(4); // 4=EapHost + m_cfg_eaphost = dynamic_cast(*cfg.m_inner); + m_inner_type->SetSelection(m_inner_type->FindPage(m_panel_eaphost)); break; - - default: - wxFAIL_MSG(wxT("Unsupported inner authentication method type.")); +#endif } - // Do not invoke inherited TransferDataToWindow(), as it will call others TransferDataToWindow(). - // This will handle wxTTLSConfigWindow::OnInitDialog() via wxEVT_INIT_DIALOG forwarding. - return true /*wxScrolledWindow::TransferDataToWindow()*/; + return wxTLSTunnelConfigWindow::TransferDataToWindow(); } -bool wxTTLSConfigWindow::TransferDataFromWindow() +bool wxPEAPConfigWindow::TransferDataFromWindow() { wxCHECK(wxTLSTunnelConfigWindow::TransferDataFromWindow(), false); - auto &cfg_ttls = dynamic_cast(m_cfg); + auto &cfg = dynamic_cast(m_cfg); if (!m_prov.m_read_only) { // This is not a provider-locked configuration. Save the data. - switch (m_inner_type->GetSelection()) { - case 0: // 0=PAP - cfg_ttls.m_inner.reset(new eap::config_method_pap(m_cfg_pap)); - break; - - case 1: // 1=MSCHAPv2 - cfg_ttls.m_inner.reset(new eap::config_method_mschapv2(m_cfg_mschapv2)); - break; - - case 2: // 2=EAP-MSCHAPv2 - cfg_ttls.m_inner.reset(new eap::config_method_eapmschapv2(m_cfg_eapmschapv2)); - break; - - case 3: // 3=EAP-GTC - cfg_ttls.m_inner.reset(new eap::config_method_eapgtc(m_cfg_eapgtc)); - break; - + int idx = m_inner_type->GetSelection(); + if (idx != wxNOT_FOUND) { + wxWindow *page = m_inner_type->GetPage(idx); + if (page == m_panel_eapmschapv2) + cfg.m_inner.reset(new eap::config_method_eapmschapv2(m_cfg_eapmschapv2)); + else if (page == m_panel_eapgtc) + cfg.m_inner.reset(new eap::config_method_eapgtc(m_cfg_eapgtc)); #if EAP_INNER_EAPHOST - case 4: // 4=EapHost - cfg_ttls.m_inner.reset(new eap::config_method_eaphost(m_cfg_eaphost)); - break; + else if (page == m_panel_eaphost) + cfg.m_inner.reset(new eap::config_method_eaphost(m_cfg_eaphost)); #endif - - default: - wxFAIL_MSG(wxT("Unsupported inner authentication method type.")); + } + } + + return true; +} + +/// \endcond + + +////////////////////////////////////////////////////////////////////// +// wxTTLSConfigWindow +////////////////////////////////////////////////////////////////////// + +wxTTLSConfigWindow::wxTTLSConfigWindow(eap::config_provider &prov, eap::config_method &cfg, wxWindow* parent) : + m_cfg_pap (cfg.m_module, cfg.m_level + 1), + m_cfg_mschapv2(cfg.m_module, cfg.m_level + 1), + wxPEAPConfigWindow(prov, cfg, parent) +{ + m_panel_pap = new wxPAPConfigPanel(m_prov, m_cfg_pap, m_inner_type); + m_inner_type->InsertPage(0, m_panel_pap, _("PAP")); + m_panel_mschapv2 = new wxMSCHAPv2ConfigPanel(m_prov, m_cfg_mschapv2, m_inner_type); + m_inner_type->InsertPage(1, m_panel_mschapv2, _("MSCHAPv2")); + + m_panel_pap->SetFocusFromKbd(); +} + + +/// \cond internal + +bool wxTTLSConfigWindow::TransferDataToWindow() +{ + auto &cfg = dynamic_cast(m_cfg); + + // Native inner methods + switch (cfg.m_inner->get_method_id()) { + case winstd::eap_type_t::legacy_pap: + m_cfg_pap = dynamic_cast(*cfg.m_inner); + m_inner_type->SetSelection(m_inner_type->FindPage(m_panel_pap)); + break; + + case winstd::eap_type_t::legacy_mschapv2: + m_cfg_mschapv2 = dynamic_cast(*cfg.m_inner); + m_inner_type->SetSelection(m_inner_type->FindPage(m_panel_mschapv2)); + break; + } + + return wxPEAPConfigWindow::TransferDataToWindow(); +} + + +bool wxTTLSConfigWindow::TransferDataFromWindow() +{ + wxCHECK(wxPEAPConfigWindow::TransferDataFromWindow(), false); + + auto &cfg = dynamic_cast(m_cfg); + + if (!m_prov.m_read_only) { + // This is not a provider-locked configuration. Save the data. + int idx = m_inner_type->GetSelection(); + if (idx != wxNOT_FOUND) { + wxWindow *page = m_inner_type->GetPage(idx); + if (page == m_panel_pap) + cfg.m_inner.reset(new eap::config_method_pap(m_cfg_pap)); + else if (page == m_panel_mschapv2) + cfg.m_inner.reset(new eap::config_method_mschapv2(m_cfg_mschapv2)); } }