diff options
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/app_settings/settings_per_account.xml | 11 | ||||
-rw-r--r-- | indra/newview/lllogininstance.cpp | 50 | ||||
-rw-r--r-- | indra/newview/llstartup.cpp | 16 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/floater_mfa.xml | 49 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/notifications.xml | 21 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/strings.xml | 4 | ||||
-rw-r--r-- | indra/newview/tests/lllogininstance_test.cpp | 10 |
7 files changed, 156 insertions, 5 deletions
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index 537744b44c..c45e841b94 100644 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -436,5 +436,16 @@ <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 e81d2cc082..fd186fcddc 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -225,10 +225,29 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> 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 + // 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); + std::string grid(LLGridManager::getInstance()->getGridId()); + if (basic_secure_store) + { + 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; + // Copy the credentials into the request after logging the rest LLSD credentials(user_credential->getLoginParams()); for (LLSD::map_const_iterator it = credentials.beginMap(); @@ -407,6 +426,35 @@ 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; + + if (gViewerWindow) + { + gViewerWindow->setShowProgress(FALSE); + } + + 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" || reason_response == "connect" diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 79ef0c075e..64e6042047 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -133,6 +133,7 @@ #include "llproxy.h" #include "llproductinforequest.h" #include "llqueryflags.h" +#include "llsecapi.h" #include "llselectmgr.h" #include "llsky.h" #include "llstatview.h" @@ -1109,10 +1110,10 @@ bool idle_startup() } else { - if (reason_response != "tos") + if (reason_response != "tos" && reason_response != "mfa_challenge") { - // Don't pop up a notification in the TOS case because - // LLFloaterTOS::onCancel() already scolded the user. + // Don't pop up a notification in the TOS or MFA cases because + // the specialized floater has already scolded the user. std::string error_code; if(response.has("errorcode")) { @@ -3616,6 +3617,15 @@ bool process_login_success_response() LLViewerMedia::getInstance()->openIDSetup(openid_url, openid_token); } + + // 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"]); + } + bool success = false; // JC: gesture loading done below, when we have an asset system // in place. Don't delete/clear gUserCredentials until then. diff --git a/indra/newview/skins/default/xui/en/floater_mfa.xml b/indra/newview/skins/default/xui/en/floater_mfa.xml new file mode 100644 index 0000000000..a649cc6d47 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_mfa.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + title="MFA Token Requred" + legacy_header_height="18" + can_minimize="false" + can_close="false" + height="110" + layout="topleft" + name="mfa_challenge" + help_topic="mfa_challenge" + width="550"> + <text + type="string" + word_wrap="true" + length="1" + follows="top|left" + height="15" + layout="topleft" + left="10" + name="token_prompt_text" + top="20"> + token prompt + </text> + <line_editor + follows="left|top|right" + height="19" + layout="topleft" + bottom_delta="40" + name="token_edit" + width="100" /> + <button + follows="top|left" + height="20" + label="Continue" + layout="topleft" + left="10" + name="continue_btn" + bottom_delta="30" + width="64" /> + <button + follows="top|left" + height="20" + label="Cancel" + layout="topleft" + left_pad="5" + name="cancel_btn" + bottom_delta="0" + width="64" /> +</floater> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 2007abefd7..175698ca41 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -11816,4 +11816,25 @@ Unpacking: [UNPACK_TIME]s [USIZE]KB <tag>fail</tag> </notification> + <notification + icon="alertmodal.tga" + label="Prompt for MFA Token" + name="PromptMFAToken" + type="alertmodal"> + [MESSAGE] + <tag>confirm</tag> + <form name="form"> + <input name="token" type="text" width="400" /> + <button + default="true" + index="0" + name="continue" + text="Continue"/> + <button + index="1" + name="cancel" + text="Cancel"/> + </form> + </notification> + </notifications> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index f26ee06e6b..866196a760 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -133,6 +133,7 @@ http://secondlife.com/viewer-access-faq</string> Please check to make sure you entered the right * Username (like bobsmith12 or steller.sunshine) * Password + * Second Factor Token (if enabled) Also, please make sure your Caps Lock key is off.</string> <string name="LoginFailedPasswordChanged">As a security precaution your password has been changed. Please go to your account page at http://secondlife.com/password @@ -192,7 +193,8 @@ Please try logging in again in a minute.</string> Please try logging in again in a minute.</string> <string name="LoginFailedLoggingOutSession">The system has begun logging out your last session. Please try logging in again in a minute.</string> - + <string name="LoginFailedAuthenticationMFARequired">To continue logging in, enter a new token from your multifactor authentication app. +If you feel this is an error, please contact support@secondlife.com</string> <!-- Disconnection --> <string name="AgentLostConnection">This region may be experiencing trouble. Please check your connection to the Internet.</string> diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp index 8d1956957c..9253516411 100644 --- a/indra/newview/tests/lllogininstance_test.cpp +++ b/indra/newview/tests/lllogininstance_test.cpp @@ -186,10 +186,20 @@ std::string LLGridManager::getAppSLURLBase(const std::string& grid_name) { return "myappslurl"; } +std::string LLGridManager::getGridId(const std::string& grid) +{ + return std::string(); +} + +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){} |