From 6bdd744d78f2040767abe57afcb06f8a55a9dd83 Mon Sep 17 00:00:00 2001
From: Brad Kittenbrink <brad@lindenlab.com>
Date: Wed, 9 Mar 2022 14:13:02 -0800
Subject: [PATCH] SL-17019 mfa_hash should get saved per-username

---
 indra/newview/app_settings/settings.xml       | 11 ++++++
 .../app_settings/settings_per_account.xml     | 11 ------
 indra/newview/lllogininstance.cpp             | 39 ++++++++++++-------
 indra/newview/llstartup.cpp                   |  4 +-
 indra/newview/tests/lllogininstance_test.cpp  | 11 +++---
 5 files changed, 43 insertions(+), 33 deletions(-)

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 6c36fa6f090..7d39a54c1dc 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -16815,5 +16815,16 @@
   <key>Value</key>
   <integer>1</integer>
   </map>
+  <key>MFAHash</key>
+  <map>
+    <key>Comment</key>
+    <string>Override MFA state hash for authentication</string>
+    <key>Persist</key>
+    <integer>0</integer>
+    <key>Type</key>
+    <string>String</string>
+    <key>Value</key>
+    <string></string>
+  </map>
 </map>
 </llsd>
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index c45e841b943..537744b44c0 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -436,16 +436,5 @@
         <key>Value</key>
         <integer>2</integer>
       </map>
-      <key>MFAHash</key>
-      <map>
-        <key>Comment</key>
-        <string>MFA state hash for authentication</string>
-        <key>Persist</key>
-        <integer>0</integer>
-        <key>Type</key>
-        <string>String</string>
-        <key>Value</key>
-        <string></string>
-      </map>
     </map>
 </llsd>
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index fd186fcddcb..2335674501e 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -230,34 +230,43 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
     // log request_params _before_ adding the credentials or sensitive MFA hash data
     LL_DEBUGS("LLLogin") << "Login parameters: " << LLSDOStreamer<LLSDNotationFormatter>(request_params) << LL_ENDL;
 
-    std::string mfa_hash = gSavedPerAccountSettings.getString("MFAHash"); //non-persistent to enable testing
-    LLPointer<LLSecAPIHandler> 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);
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 64e60420473..e7a16223326 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -3621,9 +3621,9 @@ bool process_login_success_response()
 	// Only save mfa_hash for future logins if the user wants their info remembered.
 	if(response.has("mfa_hash") && gSavedSettings.getBOOL("RememberUser") && gSavedSettings.getBOOL("RememberPassword"))
 	{
-		LLPointer<LLSecAPIHandler> basic_secure_store = getSecHandler(BASIC_SECHANDLER);
 		std::string grid(LLGridManager::getInstance()->getGridId());
-		basic_secure_store->setProtectedData("mfa_hash", grid, response["mfa_hash"]);
+		std::string user_id(gUserCredential->userID());
+		gSecAPIHandler->addToProtectedMap("mfa_hash", grid, user_id, response["mfa_hash"]);
 	}
 
 	bool success = false;
diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp
index 9253516411d..a8f57f975a8 100644
--- a/indra/newview/tests/lllogininstance_test.cpp
+++ b/indra/newview/tests/lllogininstance_test.cpp
@@ -191,15 +191,14 @@ std::string LLGridManager::getGridId(const std::string& grid)
     return std::string();
 }
 
-LLPointer<LLSecAPIHandler> getSecHandler(const std::string& handler_type)
-{
-    return nullptr;
-}
+//LLPointer<LLSecAPIHandler> getSecHandler(const std::string& handler_type)
+//{
+//    return nullptr;
+//}
 
 //-----------------------------------------------------------------------------
 #include "../llviewercontrol.h"
 LLControlGroup gSavedSettings("Global");
-LLControlGroup gSavedPerAccountSettings("PerAccount");
 
 LLControlGroup::LLControlGroup(const std::string& name) :
 	LLInstanceTracker<LLControlGroup, std::string>(name){}
@@ -236,6 +235,8 @@ LLAppViewer * LLAppViewer::sInstance = 0;
 static std::string gTOSType;
 static LLEventPump * gTOSReplyPump = NULL;
 
+LLPointer<LLSecAPIHandler> gSecAPIHandler;
+
 //static
 LLFloater* LLFloaterReg::showInstance(const std::string& name, const LLSD& key, BOOL focus)
 {
-- 
GitLab