From a1fb89ebb6e6cc89ed301b10305c145da3be295f Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Tue, 23 Nov 2021 17:44:06 -0800 Subject: SL-16365 Viewer adds empty mfa token to login params --- indra/newview/lllogininstance.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/newview/lllogininstance.cpp') diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index e81d2cc082..25182593ce 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -225,6 +225,7 @@ void LLLoginInstance::constructAuthParams(LLPointer user_credentia request_params["id0"] = mSerialNumber; request_params["host_id"] = gSavedSettings.getString("HostID"); request_params["extended_errors"] = true; // request message_id and message_args + request_params["token"] = ""; // log request_params _before_ adding the credentials LL_DEBUGS("LLLogin") << "Login parameters: " << LLSDOStreamer(request_params) << LL_ENDL; -- cgit v1.2.3 From d307843dd431de86e6d4c4f3e6fe8eaf946354d4 Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Tue, 23 Nov 2021 17:39:37 -0800 Subject: SL-16388 Viewer MFA Implementation We now present MFA errors to the user during login and prompt them for an authentication token. --- indra/newview/lllogininstance.cpp | 40 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'indra/newview/lllogininstance.cpp') diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 25182593ce..e380e5a3f4 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -75,6 +75,8 @@ public: static const char * const TOS_REPLY_PUMP = "lllogininstance_tos_callback"; static const char * const TOS_LISTENER_NAME = "lllogininstance_tos"; +static const char * const MFA_REPLY_PUMP = "lllogininstance_mfa_callback"; +static const char * const MFA_LISTENER_NAME = "lllogininstance_mfa"; std::string construct_start_string(); @@ -408,6 +410,23 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event) boost::bind(&LLLoginInstance::syncWithUpdater, this, resp, _1, _2)); } } + else if(reason_response == "mfa_challenge") + { + LL_DEBUGS("LLLogin") << " MFA challenge" << LL_ENDL; + + LLSD data(LLSD::emptyMap()); + data["message"] = message_response; + data["reply_pump"] = MFA_REPLY_PUMP; + if (gViewerWindow) + { + gViewerWindow->setShowProgress(FALSE); + } + LLFloaterReg::showInstance("message_mfa", data); + LLEventPumps::instance().obtain(MFA_REPLY_PUMP) + .listen(MFA_LISTENER_NAME, [=](const LLSD& token) { + return this->handleMFAResponse(token, "token"); + }); + } else if( reason_response == "key" || reason_response == "presence" || reason_response == "connect" @@ -502,6 +521,27 @@ bool LLLoginInstance::handleTOSResponse(bool accepted, const std::string& key) return true; } +bool LLLoginInstance::handleMFAResponse(const std::string& token, const std::string& key) +{ + if(!token.empty()) + { + LL_INFOS("LLLogin") << "LLLoginInstance::handleMFAResponse: token submitted" << LL_ENDL; + + // Set the request data to true and retry login. + mRequestData["params"][key] = token; + reconnect(); + } + else + { + LL_INFOS("LLLogin") << "LLLoginInstance::handleMFAResponse: no token, attemptComplete" << LL_ENDL; + + attemptComplete(); + } + + LLEventPumps::instance().obtain(MFA_REPLY_PUMP).stopListening(MFA_LISTENER_NAME); + return true; +} + std::string construct_start_string() { std::string start; -- cgit v1.2.3 From 30cd108c7e4a524c9f17060d5b2f7b4ff193b4b8 Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Mon, 6 Dec 2021 16:17:55 -0800 Subject: SL-16388 Viewer MFA Implementation Improvements token input is now handled and message formatting is improved. Added beginnings of support for saving slmfa_hash value client side. --- indra/newview/lllogininstance.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/newview/lllogininstance.cpp') diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index e380e5a3f4..553a8c91ff 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -228,6 +228,7 @@ void LLLoginInstance::constructAuthParams(LLPointer user_credentia request_params["host_id"] = gSavedSettings.getString("HostID"); request_params["extended_errors"] = true; // request message_id and message_args request_params["token"] = ""; + request_params["slmfa_hash"] = ""; // log request_params _before_ adding the credentials LL_DEBUGS("LLLogin") << "Login parameters: " << LLSDOStreamer(request_params) << LL_ENDL; -- cgit v1.2.3 From 6d177898a9a5883ad7939be162e51d9a61d0e0b1 Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Mon, 13 Dec 2021 14:58:38 -0800 Subject: SL-16501 SLMFAHash is now saved client side --- indra/newview/lllogininstance.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/lllogininstance.cpp') diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 553a8c91ff..f19569d429 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -228,7 +228,7 @@ void LLLoginInstance::constructAuthParams(LLPointer user_credentia request_params["host_id"] = gSavedSettings.getString("HostID"); request_params["extended_errors"] = true; // request message_id and message_args request_params["token"] = ""; - request_params["slmfa_hash"] = ""; + request_params["slmfa_hash"] = gSavedPerAccountSettings.getString("SLMFAHash"); // log request_params _before_ adding the credentials LL_DEBUGS("LLLogin") << "Login parameters: " << LLSDOStreamer(request_params) << LL_ENDL; -- cgit v1.2.3 From b74dc0e27a09fef55d12e5ea0e22a13ec9ca24e8 Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Tue, 14 Dec 2021 09:07:09 -0800 Subject: SL-16388 Viewer MFA fix Duplicate Listener crash when first token challenge failed also cleaned up some xui warnings --- indra/newview/lllogininstance.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/newview/lllogininstance.cpp') diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index f19569d429..902510c294 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -524,6 +524,8 @@ bool LLLoginInstance::handleTOSResponse(bool accepted, const std::string& key) bool LLLoginInstance::handleMFAResponse(const std::string& token, const std::string& key) { + LLEventPumps::instance().obtain(MFA_REPLY_PUMP).stopListening(MFA_LISTENER_NAME); + if(!token.empty()) { LL_INFOS("LLLogin") << "LLLoginInstance::handleMFAResponse: token submitted" << LL_ENDL; @@ -539,7 +541,6 @@ bool LLLoginInstance::handleMFAResponse(const std::string& token, const std::str attemptComplete(); } - LLEventPumps::instance().obtain(MFA_REPLY_PUMP).stopListening(MFA_LISTENER_NAME); return true; } -- cgit v1.2.3 From 96a6d21086353639d48befa20d86c97d2fd2dddb Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Fri, 14 Jan 2022 22:24:52 -0800 Subject: SL-16514 store mfa hash in protected data using LLSecAPIBasicHandler --- indra/newview/lllogininstance.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'indra/newview/lllogininstance.cpp') diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 902510c294..a4c001ad8b 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -228,11 +228,20 @@ void LLLoginInstance::constructAuthParams(LLPointer user_credentia request_params["host_id"] = gSavedSettings.getString("HostID"); request_params["extended_errors"] = true; // request message_id and message_args request_params["token"] = ""; - request_params["slmfa_hash"] = gSavedPerAccountSettings.getString("SLMFAHash"); - // log request_params _before_ adding the credentials + // log request_params _before_ adding the credentials or sensitive MFA hash data LL_DEBUGS("LLLogin") << "Login parameters: " << LLSDOStreamer(request_params) << LL_ENDL; + std::string slmfa_hash = gSavedPerAccountSettings.getString("SLMFAHash"); //non-persistent to enable testing + if(slmfa_hash.empty()) + { + LLPointer basic_secure_store = getSecHandler(BASIC_SECHANDLER); + std::string grid(LLGridManager::getInstance()->getGridId()); + slmfa_hash = basic_secure_store->getProtectedData("slmfa_hash", grid).asString(); + } + + request_params["slmfa_hash"] = slmfa_hash; + // Copy the credentials into the request after logging the rest LLSD credentials(user_credential->getLoginParams()); for (LLSD::map_const_iterator it = credentials.beginMap(); @@ -417,7 +426,7 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event) LLSD data(LLSD::emptyMap()); data["message"] = message_response; - data["reply_pump"] = MFA_REPLY_PUMP; + data["reply_pump"] = MFA_REPLY_PUMP if (gViewerWindow) { gViewerWindow->setShowProgress(FALSE); -- cgit v1.2.3 From 990bee7ee227c947cc5e133ff0818c347b404e9d Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Fri, 14 Jan 2022 22:38:45 -0800 Subject: SL-16654 simplify MFA token prompt UI to use notifications instead of new custom floater. --- indra/newview/lllogininstance.cpp | 52 +++++++++++++++------------------------ 1 file changed, 20 insertions(+), 32 deletions(-) (limited to 'indra/newview/lllogininstance.cpp') diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index a4c001ad8b..2b1dbc869a 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -75,8 +75,6 @@ public: static const char * const TOS_REPLY_PUMP = "lllogininstance_tos_callback"; static const char * const TOS_LISTENER_NAME = "lllogininstance_tos"; -static const char * const MFA_REPLY_PUMP = "lllogininstance_mfa_callback"; -static const char * const MFA_LISTENER_NAME = "lllogininstance_mfa"; std::string construct_start_string(); @@ -424,18 +422,30 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event) { LL_DEBUGS("LLLogin") << " MFA challenge" << LL_ENDL; - LLSD data(LLSD::emptyMap()); - data["message"] = message_response; - data["reply_pump"] = MFA_REPLY_PUMP if (gViewerWindow) { gViewerWindow->setShowProgress(FALSE); } - LLFloaterReg::showInstance("message_mfa", data); - LLEventPumps::instance().obtain(MFA_REPLY_PUMP) - .listen(MFA_LISTENER_NAME, [=](const LLSD& token) { - return this->handleMFAResponse(token, "token"); - }); + + LLSD args(llsd::map( "MESSAGE", LLTrans::getString(response["message_id"]) )); + LLSD payload; + LLNotificationsUtil::add("PromptMFAToken", args, payload, [=](LLSD const & notif, LLSD const & response) { + bool continue_clicked = response["continue"].asBoolean(); + LLSD token = response["token"]; + LL_DEBUGS("LLLogin") << "PromptMFAToken: response: " << response << " continue_clicked" << continue_clicked << LL_ENDL; + + if (continue_clicked && !token.asString().empty()) + { + LL_INFOS("LLLogin") << "PromptMFAToken: token submitted" << LL_ENDL; + + // Set the request data to true and retry login. + mRequestData["params"]["token"] = token; + reconnect(); + } else { + LL_INFOS("LLLogin") << "PromptMFAToken: no token, attemptComplete" << LL_ENDL; + attemptComplete(); + } + }); } else if( reason_response == "key" || reason_response == "presence" @@ -531,28 +541,6 @@ bool LLLoginInstance::handleTOSResponse(bool accepted, const std::string& key) return true; } -bool LLLoginInstance::handleMFAResponse(const std::string& token, const std::string& key) -{ - LLEventPumps::instance().obtain(MFA_REPLY_PUMP).stopListening(MFA_LISTENER_NAME); - - if(!token.empty()) - { - LL_INFOS("LLLogin") << "LLLoginInstance::handleMFAResponse: token submitted" << LL_ENDL; - - // Set the request data to true and retry login. - mRequestData["params"][key] = token; - reconnect(); - } - else - { - LL_INFOS("LLLogin") << "LLLoginInstance::handleMFAResponse: no token, attemptComplete" << LL_ENDL; - - attemptComplete(); - } - - return true; -} - std::string construct_start_string() { std::string start; -- cgit v1.2.3 From 8422183958a54e49c230bf85743336e0dd4dff71 Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Fri, 4 Feb 2022 14:03:05 -0800 Subject: Related to fix for SL-16792, standardize on naming the filed simply mfa_hash end-to-end to avoid confusion --- indra/newview/lllogininstance.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'indra/newview/lllogininstance.cpp') diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 2b1dbc869a..06dbf97e51 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -230,15 +230,15 @@ void LLLoginInstance::constructAuthParams(LLPointer user_credentia // log request_params _before_ adding the credentials or sensitive MFA hash data LL_DEBUGS("LLLogin") << "Login parameters: " << LLSDOStreamer(request_params) << LL_ENDL; - std::string slmfa_hash = gSavedPerAccountSettings.getString("SLMFAHash"); //non-persistent to enable testing - if(slmfa_hash.empty()) + std::string mfa_hash = gSavedPerAccountSettings.getString("MFAHash"); //non-persistent to enable testing + if(mfa_hash.empty()) { LLPointer basic_secure_store = getSecHandler(BASIC_SECHANDLER); std::string grid(LLGridManager::getInstance()->getGridId()); - slmfa_hash = basic_secure_store->getProtectedData("slmfa_hash", grid).asString(); + mfa_hash = basic_secure_store->getProtectedData("mfa_hash", grid).asString(); } - request_params["slmfa_hash"] = slmfa_hash; + request_params["mfa_hash"] = mfa_hash; // Copy the credentials into the request after logging the rest LLSD credentials(user_credential->getLoginParams()); -- cgit v1.2.3 From 9d1891aff1a350847b2242f341addf04b802929b Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Tue, 8 Mar 2022 17:48:49 -0800 Subject: SL-16888 debug setting MFAHash value now gets saved to mfa_hash secure storage as well. --- indra/newview/lllogininstance.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'indra/newview/lllogininstance.cpp') diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 06dbf97e51..fd186fcddc 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -231,11 +231,19 @@ void LLLoginInstance::constructAuthParams(LLPointer user_credentia LL_DEBUGS("LLLogin") << "Login parameters: " << LLSDOStreamer(request_params) << LL_ENDL; std::string mfa_hash = gSavedPerAccountSettings.getString("MFAHash"); //non-persistent to enable testing - if(mfa_hash.empty()) + LLPointer basic_secure_store = getSecHandler(BASIC_SECHANDLER); + std::string grid(LLGridManager::getInstance()->getGridId()); + if (basic_secure_store) { - LLPointer basic_secure_store = getSecHandler(BASIC_SECHANDLER); - std::string grid(LLGridManager::getInstance()->getGridId()); - mfa_hash = basic_secure_store->getProtectedData("mfa_hash", grid).asString(); + if (mfa_hash.empty()) + { + mfa_hash = basic_secure_store->getProtectedData("mfa_hash", grid).asString(); + } + else + { + // SL-16888 the mfa_hash is being overridden for testing so save it for consistency for future login requests + basic_secure_store->setProtectedData("mfa_hash", grid, mfa_hash); + } } request_params["mfa_hash"] = mfa_hash; -- cgit v1.2.3 From 6bdd744d78f2040767abe57afcb06f8a55a9dd83 Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Wed, 9 Mar 2022 14:13:02 -0800 Subject: SL-17019 mfa_hash should get saved per-username --- indra/newview/lllogininstance.cpp | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) (limited to 'indra/newview/lllogininstance.cpp') diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index fd186fcddc..2335674501 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -230,34 +230,43 @@ void LLLoginInstance::constructAuthParams(LLPointer user_credentia // log request_params _before_ adding the credentials or sensitive MFA hash data LL_DEBUGS("LLLogin") << "Login parameters: " << LLSDOStreamer(request_params) << LL_ENDL; - std::string mfa_hash = gSavedPerAccountSettings.getString("MFAHash"); //non-persistent to enable testing - LLPointer basic_secure_store = getSecHandler(BASIC_SECHANDLER); + // Copy the credentials into the request after logging the rest + LLSD credentials(user_credential->getLoginParams()); + for (LLSD::map_const_iterator it = credentials.beginMap(); + it != credentials.endMap(); + it++ + ) + { + request_params[it->first] = it->second; + } + + std::string mfa_hash = gSavedSettings.getString("MFAHash"); //non-persistent to enable testing std::string grid(LLGridManager::getInstance()->getGridId()); - if (basic_secure_store) + std::string user_id = user_credential->userID(); + if (gSecAPIHandler) { if (mfa_hash.empty()) { - mfa_hash = basic_secure_store->getProtectedData("mfa_hash", grid).asString(); + // normal execution, mfa_hash was not set from debug setting so load from protected store + LLSD data_map = gSecAPIHandler->getProtectedData("mfa_hash", grid); + if (data_map.isMap() && data_map.has(user_id)) + { + mfa_hash = data_map[user_id].asString(); + } } else { // SL-16888 the mfa_hash is being overridden for testing so save it for consistency for future login requests - basic_secure_store->setProtectedData("mfa_hash", grid, mfa_hash); + gSecAPIHandler->addToProtectedMap("mfa_hash", grid, user_id, mfa_hash); } } - - request_params["mfa_hash"] = mfa_hash; - - // Copy the credentials into the request after logging the rest - LLSD credentials(user_credential->getLoginParams()); - for (LLSD::map_const_iterator it = credentials.beginMap(); - it != credentials.endMap(); - it++ - ) + else { - request_params[it->first] = it->second; + LL_WARNS() << "unable to access protected store for mfa_hash" << LL_ENDL; } + request_params["mfa_hash"] = mfa_hash; + // Specify desired timeout/retry options LLSD http_params; F32 srv_timeout = llclamp(gSavedSettings.getF32("LoginSRVTimeout"), LOGIN_SRV_TIMEOUT_MIN, LOGIN_SRV_TIMEOUT_MAX); -- cgit v1.2.3 From 22a22d17b4c10606cb36a35c92ed627ba2d8aa69 Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Fri, 18 Mar 2022 15:22:29 -0700 Subject: Fix SL-17034/BUG-231938 whitespace in token causes authentication failure --- indra/newview/lllogininstance.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'indra/newview/lllogininstance.cpp') diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 2335674501..523d39da58 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -61,6 +61,7 @@ #include "lltrans.h" #include +#include #include const S32 LOGIN_MAX_RETRIES = 0; // Viewer should not autmatically retry login @@ -448,10 +449,13 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event) LLSD payload; LLNotificationsUtil::add("PromptMFAToken", args, payload, [=](LLSD const & notif, LLSD const & response) { bool continue_clicked = response["continue"].asBoolean(); - LLSD token = response["token"]; + std::string token = response["token"].asString(); LL_DEBUGS("LLLogin") << "PromptMFAToken: response: " << response << " continue_clicked" << continue_clicked << LL_ENDL; - if (continue_clicked && !token.asString().empty()) + // strip out whitespace - SL-17034/BUG-231938 + token = boost::regex_replace(token, boost::regex("\\s"), ""); + + if (continue_clicked && !token.empty()) { LL_INFOS("LLLogin") << "PromptMFAToken: token submitted" << LL_ENDL; -- cgit v1.2.3 From 3feb92046ff226c6d65a90ae948a0390e768ed48 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 24 Mar 2022 18:47:08 +0200 Subject: SL-16831 Viewer stalls for 10 seconds before displaying a login failure # Conflicts: # indra/newview/llstartup.cpp --- indra/newview/lllogininstance.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indra/newview/lllogininstance.cpp') diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 523d39da58..267f1d03ea 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -280,6 +280,11 @@ void LLLoginInstance::constructAuthParams(LLPointer user_credentia mRequestData["params"] = request_params; mRequestData["options"] = requested_options; mRequestData["http_params"] = http_params; +#if LL_RELEASE_FOR_DOWNLOAD + mRequestData["wait_for_updater"] = !gSavedSettings.getBOOL("CmdLineSkipUpdater") && !LLAppViewer::instance()->isUpdaterMissing(); +#else + mRequestData["wait_for_updater"] = false; +#endif } bool LLLoginInstance::handleLoginEvent(const LLSD& event) -- cgit v1.2.3