Merge branch 'master' into DRTVWR-544-maint
# Conflicts: # indra/viewer_components/login/lllogin.cppmeow-7.2.2
commit
59d5443905
|
|
@ -103,28 +103,28 @@ else (USESYSTEMLIBS)
|
|||
elseif (DARWIN)
|
||||
set(BOOST_CONTEXT_LIBRARY
|
||||
optimized boost_context-mt${addrsfx}
|
||||
debug boost_context-mt${addrsfx}-d)
|
||||
debug boost_context-mt${addrsfx})
|
||||
set(BOOST_FIBER_LIBRARY
|
||||
optimized boost_fiber-mt${addrsfx}
|
||||
debug boost_fiber-mt${addrsfx}-d)
|
||||
debug boost_fiber-mt${addrsfx})
|
||||
set(BOOST_FILESYSTEM_LIBRARY
|
||||
optimized boost_filesystem-mt${addrsfx}
|
||||
debug boost_filesystem-mt${addrsfx}-d)
|
||||
debug boost_filesystem-mt${addrsfx})
|
||||
set(BOOST_PROGRAM_OPTIONS_LIBRARY
|
||||
optimized boost_program_options-mt${addrsfx}
|
||||
debug boost_program_options-mt${addrsfx}-d)
|
||||
debug boost_program_options-mt${addrsfx})
|
||||
set(BOOST_REGEX_LIBRARY
|
||||
optimized boost_regex-mt${addrsfx}
|
||||
debug boost_regex-mt${addrsfx}-d)
|
||||
debug boost_regex-mt${addrsfx})
|
||||
set(BOOST_SIGNALS_LIBRARY
|
||||
optimized boost_signals-mt${addrsfx}
|
||||
debug boost_signals-mt${addrsfx}-d)
|
||||
debug boost_signals-mt${addrsfx})
|
||||
set(BOOST_SYSTEM_LIBRARY
|
||||
optimized boost_system-mt${addrsfx}
|
||||
debug boost_system-mt${addrsfx}-d)
|
||||
debug boost_system-mt${addrsfx})
|
||||
set(BOOST_THREAD_LIBRARY
|
||||
optimized boost_thread-mt${addrsfx}
|
||||
debug boost_thread-mt${addrsfx}-d)
|
||||
debug boost_thread-mt${addrsfx})
|
||||
endif (WINDOWS)
|
||||
endif (USESYSTEMLIBS)
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
6.5.5
|
||||
6.5.6
|
||||
|
|
|
|||
|
|
@ -16826,5 +16826,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>
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@
|
|||
#include "lltrans.h"
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
#include <sstream>
|
||||
|
||||
const S32 LOGIN_MAX_RETRIES = 0; // Viewer should not autmatically retry login
|
||||
|
|
@ -224,8 +225,9 @@ 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;
|
||||
|
||||
// Copy the credentials into the request after logging the rest
|
||||
|
|
@ -238,6 +240,33 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
|
|||
request_params[it->first] = it->second;
|
||||
}
|
||||
|
||||
std::string mfa_hash = gSavedSettings.getString("MFAHash"); //non-persistent to enable testing
|
||||
std::string grid(LLGridManager::getInstance()->getGridId());
|
||||
std::string user_id = user_credential->userID();
|
||||
if (gSecAPIHandler)
|
||||
{
|
||||
if (mfa_hash.empty())
|
||||
{
|
||||
// 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
|
||||
gSecAPIHandler->addToProtectedMap("mfa_hash", grid, user_id, mfa_hash);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
|
|
@ -411,6 +440,38 @@ 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();
|
||||
std::string token = response["token"].asString();
|
||||
LL_DEBUGS("LLLogin") << "PromptMFAToken: response: " << response << " continue_clicked" << continue_clicked << LL_ENDL;
|
||||
|
||||
// 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;
|
||||
|
||||
// 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"
|
||||
|
|
|
|||
|
|
@ -485,6 +485,9 @@ public:
|
|||
const std::string& data_id,
|
||||
const std::string& map_elem)=0;
|
||||
|
||||
// ensure protected store's map is written to storage
|
||||
virtual void syncProtectedMap() = 0;
|
||||
|
||||
public:
|
||||
virtual LLPointer<LLCredential> createCredential(const std::string& grid,
|
||||
const LLSD& identifier,
|
||||
|
|
|
|||
|
|
@ -1608,6 +1608,11 @@ void LLSecAPIBasicHandler::removeFromProtectedMap(const std::string& data_type,
|
|||
}
|
||||
}
|
||||
|
||||
void LLSecAPIBasicHandler::syncProtectedMap()
|
||||
{
|
||||
// TODO - consider unifing these functions
|
||||
_writeProtectedData();
|
||||
}
|
||||
//
|
||||
// Create a credential object from an identifier and authenticator. credentials are
|
||||
// per grid.
|
||||
|
|
|
|||
|
|
@ -278,6 +278,9 @@ public:
|
|||
const std::string& data_id,
|
||||
const std::string& map_elem);
|
||||
|
||||
// ensure protected store's map is written to storage
|
||||
virtual void syncProtectedMap();
|
||||
|
||||
// credential management routines
|
||||
|
||||
virtual LLPointer<LLCredential> createCredential(const std::string& grid,
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
@ -1116,10 +1117,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"))
|
||||
{
|
||||
|
|
@ -3686,6 +3687,17 @@ 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"))
|
||||
{
|
||||
std::string grid(LLGridManager::getInstance()->getGridId());
|
||||
std::string user_id(gUserCredential->userID());
|
||||
gSecAPIHandler->addToProtectedMap("mfa_hash", grid, user_id, response["mfa_hash"]);
|
||||
// TODO(brad) - related to SL-17223 consider building a better interface that sync's automatically
|
||||
gSecAPIHandler->syncProtectedMap();
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
// JC: gesture loading done below, when we have an asset system
|
||||
// in place. Don't delete/clear gUserCredentials until then.
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -11817,4 +11817,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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -186,6 +186,15 @@ 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"
|
||||
|
|
@ -227,6 +236,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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ LLPointer<LLCertificateStore> LLSecAPIBasicHandler::getCertificateStore(const st
|
|||
void LLSecAPIBasicHandler::setProtectedData(const std::string& data_type, const std::string& data_id, const LLSD& data) {}
|
||||
void LLSecAPIBasicHandler::addToProtectedMap(const std::string& data_type, const std::string& data_id, const std::string& map_elem, const LLSD& data) {}
|
||||
void LLSecAPIBasicHandler::removeFromProtectedMap(const std::string& data_type, const std::string& data_id, const std::string& map_elem) {}
|
||||
void LLSecAPIBasicHandler::syncProtectedMap() {}
|
||||
LLSD LLSecAPIBasicHandler::getProtectedData(const std::string& data_type, const std::string& data_id) { return LLSD(); }
|
||||
void LLSecAPIBasicHandler::deleteProtectedData(const std::string& data_type, const std::string& data_id) {}
|
||||
LLPointer<LLCredential> LLSecAPIBasicHandler::createCredential(const std::string& grid, const LLSD& identifier, const LLSD& authenticator) { return NULL; }
|
||||
|
|
|
|||
Loading…
Reference in New Issue