From c765954c0f910fde05a0573873a08dd662de0917 Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Tue, 6 Sep 2016 14:10:02 +0200 Subject: [PATCH] "Last Authentication Failed" flag extended to support finer feedback, why last authentication failed --- EAPMethods/locale/EAPMethods.pot | 34 ++++++++++++++++++------- lib/EAPBase/include/Config.h | 41 ++++++++++++++++++++++++++++--- lib/EAPBase/include/Method.h | 2 +- lib/EAPBase/src/Config.cpp | 34 ++++++++++++++++--------- lib/EAPBase/src/Method.cpp | 33 +++++++++++++++++++++++++ lib/EAPBase_UI/include/EAP_UI.h | 2 +- lib/EAPBase_UI/src/EAP_UI.cpp | 9 +++++-- lib/Events/res/EventsETW.man | Bin 97810 -> 103146 bytes lib/PAP/include/Method.h | 19 ++++---------- lib/PAP/src/Method.cpp | 38 +--------------------------- lib/TLS/include/Method.h | 2 +- lib/TLS/src/Method.cpp | 40 +++++------------------------- lib/TTLS/src/Method.cpp | 8 +++--- lib/TTLS/src/Module.cpp | 4 +-- lib/TTLS_UI/src/TTLS_UI.cpp | 8 +++--- 15 files changed, 149 insertions(+), 125 deletions(-) diff --git a/EAPMethods/locale/EAPMethods.pot b/EAPMethods/locale/EAPMethods.pot index 140c916..a82cc6c 100644 --- a/EAPMethods/locale/EAPMethods.pot +++ b/EAPMethods/locale/EAPMethods.pot @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: EAPMethods\n" -"POT-Creation-Date: 2016-09-02 19:08+0200\n" +"POT-Creation-Date: 2016-09-06 14:06+0200\n" "PO-Revision-Date: 2016-06-02 12:27+0200\n" "Last-Translator: Simon Rozman \n" "Language-Team: Amebis, d. o. o., Kamnik \n" @@ -253,8 +253,24 @@ msgstr "" msgid "Your provider" msgstr "" -#: lib/EAPBase_UI/src/EAP_UI.cpp:249 -msgid "Previous attempt to connect failed. Please, make sure your credentials are correct, or try again later." +#: lib/EAPBase_UI/src/EAP_UI.cpp:250 +msgid "Previous attempt to connect reported invalid credentials." +msgstr "" + +#: lib/EAPBase_UI/src/EAP_UI.cpp:251 +msgid "Previous attempt to connect reported your credentials expired." +msgstr "" + +#: lib/EAPBase_UI/src/EAP_UI.cpp:252 +msgid "Previous attempt to connect reported your credentials are being changed." +msgstr "" + +#: lib/EAPBase_UI/src/EAP_UI.cpp:253 +msgid "Previous attempt to connect failed." +msgstr "" + +#: lib/EAPBase_UI/src/EAP_UI.cpp:254 +msgid "Please, make sure your credentials are correct, or try again later." msgstr "" #: lib/TLS_UI/res/wxTLS_UI.cpp:17 @@ -454,7 +470,7 @@ msgstr "" msgid "MSCHAPv2" msgstr "" -#: lib/TTLS_UI/src/TTLS_UI.cpp:123 lib/TTLS_UI/src/TTLS_UI.cpp:256 +#: lib/TTLS_UI/src/TTLS_UI.cpp:123 lib/TTLS_UI/src/TTLS_UI.cpp:262 msgid "Outer Authentication" msgstr "" @@ -476,24 +492,24 @@ msgstr "" msgid "Deleting credentials failed (error %u)." msgstr "" -#: lib/EAPBase_UI/include/EAP_UI.h:738 +#: lib/EAPBase_UI/include/EAP_UI.h:739 #, c-format msgid "" msgstr "" -#: lib/EAPBase_UI/include/EAP_UI.h:742 +#: lib/EAPBase_UI/include/EAP_UI.h:743 msgid "" msgstr "" -#: lib/EAPBase_UI/include/EAP_UI.h:753 lib/EAPBase_UI/include/EAP_UI.h:762 +#: lib/EAPBase_UI/include/EAP_UI.h:754 lib/EAPBase_UI/include/EAP_UI.h:764 msgid "" msgstr "" -#: lib/EAPBase_UI/include/EAP_UI.h:753 lib/EAPBase_UI/include/EAP_UI.h:762 +#: lib/EAPBase_UI/include/EAP_UI.h:754 lib/EAPBase_UI/include/EAP_UI.h:764 msgid "" msgstr "" -#: lib/EAPBase_UI/include/EAP_UI.h:962 +#: lib/EAPBase_UI/include/EAP_UI.h:964 msgid "" msgstr "" diff --git a/lib/EAPBase/include/Config.h b/lib/EAPBase/include/Config.h index 7028598..78ac7c7 100644 --- a/lib/EAPBase/include/Config.h +++ b/lib/EAPBase/include/Config.h @@ -352,10 +352,25 @@ namespace eap virtual credentials* make_credentials() const = 0; public: - bool m_allow_save; ///< Are credentials allowed to be saved to Windows Credential Manager? - bool m_use_preshared; ///< Use pre-shared credentials - std::unique_ptr m_preshared; ///< Pre-shared credentials - bool m_auth_failed; ///< Did credential fail last time? + bool m_allow_save; ///< Are credentials allowed to be saved to Windows Credential Manager? + bool m_use_preshared; ///< Use pre-shared credentials + std::unique_ptr m_preshared; ///< Pre-shared credentials + + enum status { + status_success = 0, ///< Authentication succeeded + status_auth_failed, ///< Authentication failed + status_cred_invalid, ///< Invalid credentials + status_cred_expired, ///< Credentials expired + status_cred_changing, ///< Credentials are being changed + status_account_disabled, ///< Account is disabled + status_account_logon_hours, ///< Restricted account logon hours + status_account_denied, ///< Account access is denied + + // Meta statuses + status_cred_begin = status_cred_invalid, ///< First credential related problem + status_cred_end = status_cred_changing + 1, ///< First problem, that is not credential related any more + } m_last_status; ///< Status of authentication the last time + std::wstring m_last_msg; ///< Server message at the last authentication }; @@ -604,3 +619,21 @@ inline void operator>>(_Inout_ eap::cursor_in &cursor, _Out_ eap::config &val) { val.operator>>(cursor); } + + +inline void operator<<(_Inout_ eap::cursor_out &cursor, _In_ const eap::config_method_with_cred::status &val) +{ + cursor << (unsigned char)val; +} + + +inline size_t pksizeof(_In_ const eap::config_method_with_cred::status &val) +{ + return pksizeof((unsigned char)val); +} + + +inline void operator>>(_Inout_ eap::cursor_in &cursor, _Out_ eap::config_method_with_cred::status &val) +{ + cursor >> (unsigned char&)val; +} diff --git a/lib/EAPBase/include/Method.h b/lib/EAPBase/include/Method.h index 6867a6a..2fdb62a 100644 --- a/lib/EAPBase/include/Method.h +++ b/lib/EAPBase/include/Method.h @@ -124,7 +124,7 @@ namespace eap /// virtual void get_result( _In_ EapPeerMethodResultReason reason, - _Inout_ EapPeerMethodResult *ppResult) = 0; + _Inout_ EapPeerMethodResult *ppResult); /// @} diff --git a/lib/EAPBase/src/Config.cpp b/lib/EAPBase/src/Config.cpp index d6779bd..ceb4df9 100644 --- a/lib/EAPBase/src/Config.cpp +++ b/lib/EAPBase/src/Config.cpp @@ -142,18 +142,19 @@ eap::config_method& eap::config_method::operator=(_Inout_ config_method &&other) eap::config_method_with_cred::config_method_with_cred(_In_ module &mod) : m_allow_save(true), m_use_preshared(false), - m_auth_failed(false), + m_last_status(status_success), config_method(mod) { } eap::config_method_with_cred::config_method_with_cred(_In_ const config_method_with_cred &other) : - m_allow_save(other.m_allow_save), - m_use_preshared(other.m_use_preshared), - m_preshared(other.m_preshared ? (credentials*)other.m_preshared->clone() : nullptr), - m_auth_failed(other.m_auth_failed), - config_method(other) + m_allow_save (other.m_allow_save ), + m_use_preshared(other.m_use_preshared ), + m_preshared (other.m_preshared ? (credentials*)other.m_preshared->clone() : nullptr), + m_last_status (other.m_last_status ), + m_last_msg (other.m_last_msg ), + config_method (other ) { } @@ -162,7 +163,8 @@ eap::config_method_with_cred::config_method_with_cred(_Inout_ config_method_with 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 )), - m_auth_failed (std::move(other.m_auth_failed )), + m_last_status (std::move(other.m_last_status )), + m_last_msg (std::move(other.m_last_msg )), config_method (std::move(other )) { } @@ -175,7 +177,8 @@ eap::config_method_with_cred& eap::config_method_with_cred::operator=(_In_ const m_allow_save = other.m_allow_save; m_use_preshared = other.m_use_preshared; m_preshared.reset(other.m_preshared ? (credentials*)other.m_preshared->clone() : nullptr); - m_auth_failed = other.m_auth_failed; + m_last_status = other.m_last_status; + m_last_msg = other.m_last_msg; } return *this; @@ -189,7 +192,8 @@ eap::config_method_with_cred& eap::config_method_with_cred::operator=(_Inout_ co 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 ); - m_auth_failed = std::move(other.m_auth_failed ); + m_last_status = std::move(other.m_last_status ); + m_last_msg = std::move(other.m_last_msg ); } return *this; @@ -241,6 +245,9 @@ void eap::config_method_with_cred::load(_In_ IXMLDOMNode *pConfigRoot) // This is not really an error - merely an indication pre-shared credentials are unavailable. } } + + m_last_status = status_success; + m_last_msg.clear(); } @@ -250,7 +257,8 @@ void eap::config_method_with_cred::operator<<(_Inout_ cursor_out &cursor) const cursor << m_allow_save; cursor << m_use_preshared; cursor << *m_preshared; - cursor << m_auth_failed; + cursor << m_last_status; + cursor << m_last_msg; } @@ -261,7 +269,8 @@ size_t eap::config_method_with_cred::get_pk_size() const pksizeof(m_allow_save ) + pksizeof(m_use_preshared) + pksizeof(*m_preshared ) + - pksizeof(m_auth_failed ); + pksizeof(m_last_status ) + + pksizeof(m_last_msg ); } @@ -271,7 +280,8 @@ void eap::config_method_with_cred::operator>>(_Inout_ cursor_in &cursor) cursor >> m_allow_save; cursor >> m_use_preshared; cursor >> *m_preshared; - cursor >> m_auth_failed; + cursor >> m_last_status; + cursor >> m_last_msg; } diff --git a/lib/EAPBase/src/Method.cpp b/lib/EAPBase/src/Method.cpp index 0659c7a..3604fc4 100644 --- a/lib/EAPBase/src/Method.cpp +++ b/lib/EAPBase/src/Method.cpp @@ -68,6 +68,11 @@ void eap::method::begin_session( UNREFERENCED_PARAMETER(pAttributeArray); UNREFERENCED_PARAMETER(hTokenImpersonateUser); UNREFERENCED_PARAMETER(dwMaxSendPacketSize); + + // Presume authentication will fail with generic protocol failure. (Pesimist!!!) + // We will reset once we get get_result(Success) call. + m_cfg.m_last_status = config_method_with_cred::status_auth_failed; + m_cfg.m_last_msg.clear(); } @@ -76,6 +81,34 @@ void eap::method::end_session() } +void eap::method::get_result( + _In_ EapPeerMethodResultReason reason, + _Inout_ EapPeerMethodResult *ppResult) +{ + assert(ppResult); + + switch (reason) { + case EapPeerMethodResultSuccess: { + m_module.log_event(&EAPMETHOD_METHOD_SUCCESS, event_data((unsigned int)m_cfg.get_method_id()), event_data::blank); + m_cfg.m_last_status = config_method_with_cred::status_success; + break; + } + + case EapPeerMethodResultFailure: + m_module.log_event(&EAPMETHOD_METHOD_FAILURE_ERROR2, event_data((unsigned int)m_cfg.get_method_id()), event_data((unsigned int)m_cfg.m_last_status), event_data::blank); + break; + + default: + throw win_runtime_error(ERROR_NOT_SUPPORTED, __FUNCTION__ " Not supported."); + } + + // Always ask EAP host to save the connection data. And it will save it *only* when we report "success". + // Don't worry. EapHost is well aware of failed authentication condition. + ppResult->fSaveConnectionData = TRUE; + ppResult->fIsSuccess = TRUE; +} + + ////////////////////////////////////////////////////////////////////// // eap::method_noneap ////////////////////////////////////////////////////////////////////// diff --git a/lib/EAPBase_UI/include/EAP_UI.h b/lib/EAPBase_UI/include/EAP_UI.h index 67d4c96..6f32392 100644 --- a/lib/EAPBase_UI/include/EAP_UI.h +++ b/lib/EAPBase_UI/include/EAP_UI.h @@ -433,7 +433,7 @@ public: /// /// Constructs a notice pannel and set the title text /// - wxEAPCredentialWarningPanel(const eap::config_provider &prov, wxWindow* parent); + wxEAPCredentialWarningPanel(const eap::config_provider &prov, eap::config_method_with_cred::status status, wxWindow* parent); }; diff --git a/lib/EAPBase_UI/src/EAP_UI.cpp b/lib/EAPBase_UI/src/EAP_UI.cpp index b023791..385ea68 100644 --- a/lib/EAPBase_UI/src/EAP_UI.cpp +++ b/lib/EAPBase_UI/src/EAP_UI.cpp @@ -239,14 +239,19 @@ wxEAPProviderLockedPanel::wxEAPProviderLockedPanel(const eap::config_provider &p // wxEAPCredentialWarningPanel ////////////////////////////////////////////////////////////////////// -wxEAPCredentialWarningPanel::wxEAPCredentialWarningPanel(const eap::config_provider &prov, wxWindow* parent) : wxEAPNotePanel(parent) +wxEAPCredentialWarningPanel::wxEAPCredentialWarningPanel(const eap::config_provider &prov, eap::config_method_with_cred::status status, wxWindow* parent) : wxEAPNotePanel(parent) { // Load and set icon. winstd::library lib_shell32; if (lib_shell32.load(_T("shell32.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE)) m_note_icon->SetIcon(wxLoadIconFromResource(lib_shell32, MAKEINTRESOURCE(161))); - m_note_label->SetLabel(_("Previous attempt to connect failed. Please, make sure your credentials are correct, or try again later.")); + m_note_label->SetLabel(( + status == eap::config_method_with_cred::status_cred_invalid ? _("Previous attempt to connect reported invalid credentials.") : + status == eap::config_method_with_cred::status_cred_expired ? _("Previous attempt to connect reported your credentials expired.") : + status == eap::config_method_with_cred::status_cred_changing ? _("Previous attempt to connect reported your credentials are being changed.") : + _("Previous attempt to connect failed.")) + " " + + _("Please, make sure your credentials are correct, or try again later.")); m_note_label->Wrap(449); CreateContactFields(prov); diff --git a/lib/Events/res/EventsETW.man b/lib/Events/res/EventsETW.man index 3cc4aa4ed22879d946061e00dcb5d7bd7dd3bea8..b7b61decc1032e9c1e20a8c5b3a8f6e4c682ad75 100644 GIT binary patch delta 1435 zcmZ`(Nla5w6n)o(GPD#aLK!Um6^sT8NP##;tqj3X6{~S&gx`TmgimP;>c%KBhJ|tX zS9u9>0Hf}Vm@e2EjKfM3S(+|X!bW3EiHUJRjQ4*!{4(UFzsY;&opbMd=RA2S>&H{w z^tc`+U5&CBn|Jc0%>B zetcBgjIXRZ6pVJO7T3Z;%+Gx62$R?dVf$GhPL(#I>~IvVfy4R|C%&~gY$t%MEJE>EJu`8|$Wt!gIPMf(EulURq! z5Tf1{mC-tfZT(%X)SpCMz4&a2cIoY>@otYPw~g8k5lILKJiD-C%#K~XZoJ{YDEnPF z(PJn`0oYNhFhFNttATCDxZI9iqFo^?N@G)1;83_eg{ON&`IdmUFO+ATY2sd^Hu2JB z48AjBFlNNj2Lgr`n(%$BNmJ#=i7I)vRgM|>&mb7Fu1vt4v19sf*2dg4jx#sfeiuU% z4lR^n@cCwC`>Gxa$GiD22}(7*LmxVm${A#fGYK;JzRFd+Mvrv*s~P#!c`)Pjn*%sD zZ-`ER=_tu=WOd5GhP>kFrax|-*1Nn@f@W~yV%)-?NU)zz?uNWVtzA?b-xI;YKMAlg z0qq(D1Apd)8WnF%OZGp7nYVCL~NU|*@2VBp`gpn^a2fQeW3Kq;@$ z!68fPddU(=rIhV)@ozES{AX107E#TWK+g6r=Ya|2`$R(clo#q%;ce;CGrg`!hLTTy zq7TfrOo*U{N1*VgLX;-nu^#bSA^P^RXrG&8!W796v3coVc@zYSrZ%nuJrBtU3e=1e zV+tXkD}ZM6I)eOa4wP}D4~$hS%U>o}WWyw-G$HWUIdm_xr=Xh0H-ItPzjSSwe+@!8 zug;}gs2qgDY4`Gc5e}-W`m{Y8IQYQEuS-zL$tD}=RrFJlBkEUR18SSfn-gIEH3=Lm P2)Idvy)*G4*kbq(A%%qw delta 91 zcmaF0lx@-<)(z9RH=77N3*9^+ORjFR#0Rm>UT;0b*o_$UKyb1lm+1C&%#1;7(-%lH vvQ6F~z_ML{pRu8IdQCf{(Byk>d8Ys2X5^XvK$=l(`hyBauI)nYj5oLe7GNN1 diff --git a/lib/PAP/include/Method.h b/lib/PAP/include/Method.h index 51bada8..f86c120 100644 --- a/lib/PAP/include/Method.h +++ b/lib/PAP/include/Method.h @@ -89,24 +89,15 @@ namespace eap _In_ DWORD dwReceivedPacketSize, _Inout_ EapPeerMethodOutput *pEapOutput); - /// - /// Obtains the result of an authentication session from the EAP method. - /// - /// \sa [EapPeerGetResult function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363611.aspx) - /// - virtual void get_result( - _In_ EapPeerMethodResultReason reason, - _Inout_ EapPeerMethodResult *ppResult); - /// @} protected: - credentials_pap &m_cred; ///< EAP-TLS user credentials + credentials_pap &m_cred; ///< EAP-TLS user credentials enum { - phase_unknown = -1, ///< Unknown phase - phase_init = 0, ///< Handshake initialize - phase_finished, ///< Connection shut down - } m_phase, m_phase_prev; ///< What phase is our communication at? + phase_unknown = -1, ///< Unknown phase + phase_init = 0, ///< Handshake initialize + phase_finished, ///< Connection shut down + } m_phase; ///< What phase is our communication at? }; } diff --git a/lib/PAP/src/Method.cpp b/lib/PAP/src/Method.cpp index 7d3e044..b0ff75a 100644 --- a/lib/PAP/src/Method.cpp +++ b/lib/PAP/src/Method.cpp @@ -31,7 +31,6 @@ using namespace winstd; eap::method_pap::method_pap(_In_ module &module, _In_ config_method_pap &cfg, _In_ credentials_pap &cred) : m_cred(cred), m_phase(phase_unknown), - m_phase_prev(phase_unknown), method_noneap(module, cfg, cred) { } @@ -40,7 +39,6 @@ eap::method_pap::method_pap(_In_ module &module, _In_ config_method_pap &cfg, _I eap::method_pap::method_pap(_Inout_ method_pap &&other) : m_cred ( other.m_cred ), m_phase (std::move(other.m_phase )), - m_phase_prev (std::move(other.m_phase_prev)), method_noneap(std::move(other )) { } @@ -52,7 +50,6 @@ eap::method_pap& eap::method_pap::operator=(_Inout_ method_pap &&other) assert(std::addressof(m_cred) == std::addressof(other.m_cred)); // Move method with same credentials only! (method_noneap&)*this = std::move(other ); m_phase = std::move(other.m_phase ); - m_phase_prev = std::move(other.m_phase_prev); } return *this; @@ -82,7 +79,6 @@ void eap::method_pap::process_request_packet( m_module.log_event(&EAPMETHOD_PACKET_RECV, event_data((unsigned int)eap_type_legacy_pap), event_data((unsigned int)dwReceivedPacketSize), event_data::blank); - m_phase_prev = m_phase; switch (m_phase) { case phase_init: { // Convert username and password to UTF-8. @@ -101,6 +97,7 @@ void eap::method_pap::process_request_packet( append_avp(2, diameter_avp_flag_mandatory, password_utf8.data(), (unsigned int)password_utf8.size()); m_phase = phase_finished; + m_cfg.m_last_status = config_method_with_cred::status_cred_invalid; // Blame credentials if we fail beyond this point. break; } @@ -111,36 +108,3 @@ void eap::method_pap::process_request_packet( pEapOutput->fAllowNotifications = TRUE; pEapOutput->action = EapPeerMethodResponseActionSend; } - - -void eap::method_pap::get_result( - _In_ EapPeerMethodResultReason reason, - _Inout_ EapPeerMethodResult *ppResult) -{ - assert(ppResult); - - switch (reason) { - case EapPeerMethodResultSuccess: { - m_module.log_event(&EAPMETHOD_METHOD_SUCCESS, event_data((unsigned int)eap_type_legacy_pap), event_data::blank); - m_cfg.m_auth_failed = false; - break; - } - - case EapPeerMethodResultFailure: - m_module.log_event( - m_phase_prev < phase_finished ? &EAPMETHOD_METHOD_FAILURE_INIT : &EAPMETHOD_METHOD_FAILURE, - event_data((unsigned int)eap_type_legacy_pap), event_data::blank); - - // Mark credentials as failed, so GUI can re-prompt user. - // But be careful: do so only after credentials were actually tried. - m_cfg.m_auth_failed = m_phase_prev < phase_finished && m_phase >= phase_finished; - - break; - - default: - throw win_runtime_error(ERROR_NOT_SUPPORTED, __FUNCTION__ " Not supported."); - } - - // Always ask EAP host to save the connection data. - ppResult->fSaveConnectionData = TRUE; -} diff --git a/lib/TLS/include/Method.h b/lib/TLS/include/Method.h index a93b537..642f394 100644 --- a/lib/TLS/include/Method.h +++ b/lib/TLS/include/Method.h @@ -483,7 +483,7 @@ namespace eap phase_handshake_cont, ///< Handshake continue phase_application_data, ///< Exchange application data phase_shutdown, ///< Connection shut down - } m_phase, m_phase_prev; ///< What phase is our communication at? + } m_phase; ///< What phase is our communication at? #endif }; } diff --git a/lib/TLS/src/Method.cpp b/lib/TLS/src/Method.cpp index c0436c7..c1f55c5 100644 --- a/lib/TLS/src/Method.cpp +++ b/lib/TLS/src/Method.cpp @@ -71,7 +71,6 @@ eap::method_tls::method_tls(_In_ module &module, _In_ config_method_tls &cfg, _I m_seq_num_server(0), #else m_phase(phase_unknown), - m_phase_prev(phase_unknown), #endif method(module, cfg, cred) { @@ -121,7 +120,6 @@ eap::method_tls::method_tls(_Inout_ method_tls &&other) : m_sc_queue (std::move(other.m_sc_queue )), m_sc_ctx (std::move(other.m_sc_ctx )), m_phase (std::move(other.m_phase )), - m_phase_prev (std::move(other.m_phase_prev )), #endif method (std::move(other )) { @@ -178,7 +176,6 @@ eap::method_tls& eap::method_tls::operator=(_Inout_ method_tls &&other) m_sc_queue = std::move(other.m_sc_queue ); m_sc_ctx = std::move(other.m_sc_ctx ); m_phase = std::move(other.m_phase ); - m_phase_prev = std::move(other.m_phase_prev ); #endif } @@ -446,6 +443,7 @@ void eap::method_tls::process_request_packet( } else { m_session_resumed = false; m_phase = phase_change_cipher_spec; + m_cfg.m_last_status = config_method_with_cred::status_cred_invalid; // Blame credentials if we fail beyond this point. } break; } @@ -473,7 +471,6 @@ void eap::method_tls::process_request_packet( } else m_sc_queue.insert(m_sc_queue.end(), m_packet_req.m_data.begin(), m_packet_req.m_data.end()); - m_phase_prev = m_phase; switch (m_phase) { case phase_handshake_init: case phase_handshake_cont: @@ -511,10 +508,10 @@ void eap::method_tls::get_result( { assert(ppResult); + method::get_result(reason, ppResult); + switch (reason) { case EapPeerMethodResultSuccess: { - m_module.log_event(&EAPMETHOD_METHOD_SUCCESS, event_data((unsigned int)eap_type_tls), event_data::blank); - // Derive MSK/EMSK for line encryption. derive_msk(); @@ -527,9 +524,6 @@ void eap::method_tls::get_result( m_eap_attr.push_back(std::move(a)); m_eap_attr.push_back(eap_attr::blank); - // Clear credentials as failed. - m_cfg.m_auth_failed = false; - #if EAP_TLS < EAP_TLS_SCHANNEL // Update configuration with session resumption data. m_cfg.m_session_id = m_session_id; @@ -567,39 +561,15 @@ void eap::method_tls::get_result( case EapPeerMethodResultFailure: #if EAP_TLS < EAP_TLS_SCHANNEL - m_module.log_event( - m_phase < phase_change_cipher_spec ? &EAPMETHOD_METHOD_FAILURE_INIT : - m_phase < phase_application_data ? &EAPMETHOD_METHOD_FAILURE_HANDSHAKE : &EAPMETHOD_METHOD_FAILURE, - event_data((unsigned int)eap_type_tls), event_data::blank); - - // Mark credentials as failed, so GUI can re-prompt user. - // But be careful: do so only if this happened after transition from handshake to application data phase. - m_cfg.m_auth_failed = m_phase_prev < phase_application_data && m_phase >= phase_application_data; - // Clear session resumption data. m_cfg.m_session_id.clear(); m_cfg.m_master_secret.clear(); #else - m_module.log_event( - m_phase_prev < phase_handshake_cont ? &EAPMETHOD_METHOD_FAILURE_INIT : - m_phase_prev < phase_application_data ? &EAPMETHOD_METHOD_FAILURE_HANDSHAKE : &EAPMETHOD_METHOD_FAILURE, - event_data((unsigned int)eap_type_tls), event_data::blank); - - // Mark credentials as failed, so GUI can re-prompt user. - // But be careful: do so only if this happened after transition from handshake to application data phase. - m_cfg.m_auth_failed = m_phase_prev < phase_application_data && m_phase >= phase_application_data; - // TODO: Research how a Schannel session context can be cleared not to resume. #endif break; - - default: - throw win_runtime_error(ERROR_NOT_SUPPORTED, __FUNCTION__ " Not supported."); } - - // Always ask EAP host to save the connection data. - ppResult->fSaveConnectionData = TRUE; } @@ -1236,8 +1206,10 @@ void eap::method_tls::process_handshake() m_phase = phase_application_data; process_application_data(m_sc_queue.data(), m_sc_queue.size()); - } else + } else { m_phase = phase_handshake_cont; + m_cfg.m_last_status = config_method_with_cred::status_cred_invalid; // Blame credentials if we fail beyond this point. + } } else if (status == SEC_E_INCOMPLETE_MESSAGE) { // Schannel neeeds more data. Send ACK packet to server to send more. } else if (FAILED(status)) { diff --git a/lib/TTLS/src/Method.cpp b/lib/TTLS/src/Method.cpp index 4f7f6b9..fcb43b5 100644 --- a/lib/TTLS/src/Method.cpp +++ b/lib/TTLS/src/Method.cpp @@ -130,10 +130,10 @@ void eap::method_ttls::get_result( if (result.fSaveConnectionData) ppResult->fSaveConnectionData = TRUE; - if (m_inner->m_cfg.m_auth_failed) { - // Inner method admitted its credentials failed, so autentication must have proceeded to inner authentication already. - // Therefore, outer credentials must have been OK. - m_cfg.m_auth_failed = false; + if (m_inner->m_cfg.m_last_status != config_method_with_cred::status_success) { + // Inner method admitted problems, so autentication must have proceeded to inner authentication already. + // Therefore, outer authentication must have been OK. + m_cfg.m_last_status = config_method_with_cred::status_success; } } } diff --git a/lib/TTLS/src/Module.cpp b/lib/TTLS/src/Module.cpp index 8862130..0fdf929 100644 --- a/lib/TTLS/src/Module.cpp +++ b/lib/TTLS/src/Module.cpp @@ -416,13 +416,13 @@ const eap::config_method_ttls* eap::peer_ttls::combine_credentials( // If we got here, we have all credentials we need. But, wait! if ((dwFlags & EAP_FLAG_MACHINE_AUTH) == 0) { - if (cfg_method->m_auth_failed) { + if (config_method_with_cred::status_cred_begin <= cfg_method->m_last_status && cfg_method->m_last_status < config_method_with_cred::status_cred_end) { // Outer: Credentials failed on last connection attempt. log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM1, event_data(target_name), event_data((unsigned int)eap_type_tls), event_data::blank); continue; } - if (cfg_method->m_inner->m_auth_failed) { + if (config_method_with_cred::status_cred_begin <= cfg_method->m_inner->m_last_status && cfg_method->m_inner->m_last_status < config_method_with_cred::status_cred_end) { // Inner: Credentials failed on last connection attempt. log_event(&EAPMETHOD_TRACE_EVT_CRED_PROBLEM1, event_data(target_name), event_data((unsigned int)cfg_method->m_inner->get_method_id()), event_data::blank); continue; diff --git a/lib/TTLS_UI/src/TTLS_UI.cpp b/lib/TTLS_UI/src/TTLS_UI.cpp index 682cf6c..9205733 100644 --- a/lib/TTLS_UI/src/TTLS_UI.cpp +++ b/lib/TTLS_UI/src/TTLS_UI.cpp @@ -239,8 +239,8 @@ wxTTLSCredentialsPanel::wxTTLSCredentialsPanel(const eap::config_provider &prov, assert(m_cfg.m_inner); - if (m_cfg.m_inner->m_auth_failed) - sb_content->Add(new wxEAPCredentialWarningPanel(m_prov, this), 0, wxALL|wxEXPAND, 5); + if (eap::config_method_with_cred::status_cred_begin <= m_cfg.m_inner->m_last_status && m_cfg.m_inner->m_last_status < eap::config_method_with_cred::status_cred_end) + sb_content->Add(new wxEAPCredentialWarningPanel(m_prov, m_cfg.m_inner->m_last_status, this), 0, wxALL|wxEXPAND, 5); const eap::config_method_pap *cfg_inner_pap = dynamic_cast(m_cfg.m_inner.get()); if (cfg_inner_pap) { @@ -258,8 +258,8 @@ wxTTLSCredentialsPanel::wxTTLSCredentialsPanel(const eap::config_provider &prov, m_outer_title->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_INACTIVECAPTION ) ); sb_content->Add(m_outer_title, 0, wxALL|wxALIGN_RIGHT, 5); - if (m_cfg.m_auth_failed) - sb_content->Add(new wxEAPCredentialWarningPanel(m_prov, this), 0, wxALL|wxEXPAND, 5); + if (eap::config_method_with_cred::status_cred_begin <= m_cfg.m_last_status && m_cfg.m_last_status < eap::config_method_with_cred::status_cred_end) + sb_content->Add(new wxEAPCredentialWarningPanel(m_prov, m_cfg.m_last_status, this), 0, wxALL|wxEXPAND, 5); m_outer_cred = new wxTLSCredentialsPanel(m_prov, (const eap::config_method_tls&)m_cfg, (eap::credentials_tls&)cred, this, is_config); sb_content->Add(m_outer_cred, 0, wxALL|wxEXPAND, 5);