summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/app_settings/settings_per_account.xml11
-rw-r--r--indra/newview/lllogininstance.cpp50
-rw-r--r--indra/newview/llstartup.cpp16
-rw-r--r--indra/newview/skins/default/xui/en/floater_mfa.xml49
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml21
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml4
-rw-r--r--indra/newview/tests/lllogininstance_test.cpp10
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){}