Merge remote-tracking branch 'origin/DRTVWR-543-maint_cmake' into DRTVWR-543-maint_cmake

master
Nicky 2022-05-07 18:10:29 +02:00
commit 62053e1e88
20 changed files with 264 additions and 31 deletions

View File

@ -335,7 +335,7 @@ public:
// "init_history" message
void initializeUrlHistory(const LLSD& url_history);
boost::shared_ptr<LLPluginClassMedia> getSharedPrt() { return boost::dynamic_pointer_cast<LLPluginClassMedia>(shared_from_this()); } // due to enable_shared_from_this
boost::shared_ptr<LLPluginClassMedia> getSharedPtr() { return boost::dynamic_pointer_cast<LLPluginClassMedia>(shared_from_this()); } // due to enable_shared_from_this
protected:

View File

@ -1 +1 @@
6.5.5
6.5.6

View File

@ -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>

View File

@ -3095,6 +3095,11 @@ bool LLAppViewer::initWindow()
return true;
}
bool LLAppViewer::isUpdaterMissing()
{
return mUpdaterNotFound;
}
void LLAppViewer::writeDebugInfo(bool isStatic)
{
#if LL_WINDOWS && LL_BUGSPLAT

View File

@ -98,7 +98,7 @@ public:
bool quitRequested() { return mQuitRequested; }
bool logoutRequestSent() { return mLogoutRequestSent; }
bool isSecondInstance() { return mSecondInstance; }
bool isUpdaterMissing() { return mUpdaterNotFound; }
bool isUpdaterMissing(); // In use by tests
void writeDebugInfo(bool isStatic=true);

View File

@ -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);
@ -250,6 +279,11 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> 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)
@ -406,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"

View File

@ -61,7 +61,8 @@
#define CAP_SERVICE_NAVMESH_STATUS "NavMeshGenerationStatus"
#define CAP_SERVICE_OBJECT_LINKSETS "RegionObjects"
#define CAP_SERVICE_GET_OBJECT_LINKSETS "RegionObjects"
#define CAP_SERVICE_SET_OBJECT_LINKSETS "ObjectNavMeshProperties"
#define CAP_SERVICE_TERRAIN_LINKSETS "TerrainNavMeshProperties"
#define CAP_SERVICE_CHARACTERS "CharacterProperties"
@ -244,7 +245,7 @@ void LLPathfindingManager::requestGetLinksets(request_id_t pRequestId, object_re
}
else
{
std::string objectLinksetsURL = getObjectLinksetsURLForCurrentRegion();
std::string objectLinksetsURL = getRetrieveObjectLinksetsURLForCurrentRegion();
std::string terrainLinksetsURL = getTerrainLinksetsURLForCurrentRegion();
if (objectLinksetsURL.empty() || terrainLinksetsURL.empty())
{
@ -273,7 +274,7 @@ void LLPathfindingManager::requestSetLinksets(request_id_t pRequestId, const LLP
{
LLPathfindingObjectListPtr emptyLinksetListPtr;
std::string objectLinksetsURL = getObjectLinksetsURLForCurrentRegion();
std::string objectLinksetsURL = getChangeObjectLinksetsURLForCurrentRegion();
std::string terrainLinksetsURL = getTerrainLinksetsURLForCurrentRegion();
if (objectLinksetsURL.empty() || terrainLinksetsURL.empty())
{
@ -755,9 +756,14 @@ std::string LLPathfindingManager::getRetrieveNavMeshURLForRegion(LLViewerRegion
return getCapabilityURLForRegion(pRegion, CAP_SERVICE_RETRIEVE_NAVMESH);
}
std::string LLPathfindingManager::getObjectLinksetsURLForCurrentRegion() const
std::string LLPathfindingManager::getRetrieveObjectLinksetsURLForCurrentRegion() const
{
return getCapabilityURLForCurrentRegion(CAP_SERVICE_OBJECT_LINKSETS);
return getCapabilityURLForCurrentRegion(CAP_SERVICE_GET_OBJECT_LINKSETS);
}
std::string LLPathfindingManager::getChangeObjectLinksetsURLForCurrentRegion() const
{
return getCapabilityURLForCurrentRegion(CAP_SERVICE_SET_OBJECT_LINKSETS);
}
std::string LLPathfindingManager::getTerrainLinksetsURLForCurrentRegion() const

View File

@ -122,7 +122,8 @@ private:
std::string getNavMeshStatusURLForCurrentRegion() const;
std::string getNavMeshStatusURLForRegion(LLViewerRegion *pRegion) const;
std::string getRetrieveNavMeshURLForRegion(LLViewerRegion *pRegion) const;
std::string getObjectLinksetsURLForCurrentRegion() const;
std::string getRetrieveObjectLinksetsURLForCurrentRegion() const;
std::string getChangeObjectLinksetsURLForCurrentRegion() const;
std::string getTerrainLinksetsURLForCurrentRegion() const;
std::string getCharactersURLForCurrentRegion() const;
std::string getAgentStateURLForRegion(LLViewerRegion *pRegion) const;

View File

@ -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,

View File

@ -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.

View File

@ -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,

View File

@ -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"
@ -1135,10 +1136,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"))
{
@ -2375,8 +2376,31 @@ void show_release_notes_if_required()
&& gSavedSettings.getBOOL("UpdaterShowReleaseNotes")
&& !gSavedSettings.getBOOL("FirstLoginThisInstall"))
{
LLSD info(LLAppViewer::instance()->getViewerInfo());
LLWeb::loadURLInternal(info["VIEWER_RELEASE_NOTES_URL"]);
#if LL_RELEASE_FOR_DOWNLOAD
if (!gSavedSettings.getBOOL("CmdLineSkipUpdater")
&& !LLAppViewer::instance()->isUpdaterMissing())
{
// Instantiate a "relnotes" listener which assumes any arriving event
// is the release notes URL string. Since "relnotes" is an
// LLEventMailDrop, this listener will be invoked whether or not the
// URL has already been posted. If so, it will fire immediately;
// otherwise it will fire whenever the URL is (later) posted. Either
// way, it will display the release notes as soon as the URL becomes
// available.
LLEventPumps::instance().obtain("relnotes").listen(
"showrelnotes",
[](const LLSD& url) {
LLWeb::loadURLInternal(url.asString());
return false;
});
}
else
#endif // LL_RELEASE_FOR_DOWNLOAD
{
LLSD info(LLAppViewer::instance()->getViewerInfo());
LLWeb::loadURLInternal(info["VIEWER_RELEASE_NOTES_URL"]);
}
release_notes_shown = true;
}
}
@ -3666,6 +3690,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.

View File

@ -255,13 +255,13 @@ void LLFilePickerReplyThread::notify(const std::vector<std::string>& filenames)
LLMediaFilePicker::LLMediaFilePicker(LLPluginClassMedia* plugin, LLFilePicker::ELoadFilter filter, bool get_multiple)
: LLFilePickerThread(filter, get_multiple),
mPlugin(plugin->getSharedPrt())
mPlugin(plugin->getSharedPtr())
{
}
LLMediaFilePicker::LLMediaFilePicker(LLPluginClassMedia* plugin, LLFilePicker::ESaveFilter filter, const std::string &proposed_name)
: LLFilePickerThread(filter, proposed_name),
mPlugin(plugin->getSharedPrt())
mPlugin(plugin->getSharedPtr())
{
}

View File

@ -3008,6 +3008,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("ObjectAnimation");
capabilityNames.append("ObjectMedia");
capabilityNames.append("ObjectMediaNavigate");
capabilityNames.append("ObjectNavMeshProperties");
capabilityNames.append("ParcelPropertiesUpdate");
capabilityNames.append("ParcelVoiceInfoRequest");
capabilityNames.append("ProductInfoRequest");

View File

@ -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>

View File

@ -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>

View File

@ -136,6 +136,7 @@ If you feel this is an error, please contact support@secondlife.com.</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
@ -198,7 +199,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>

View File

@ -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"
@ -218,6 +227,7 @@ bool llHashedUniqueID(unsigned char* id)
//-----------------------------------------------------------------------------
#include "../llappviewer.h"
void LLAppViewer::forceQuit(void) {}
bool LLAppViewer::isUpdaterMissing() { return true; }
LLAppViewer * LLAppViewer::sInstance = 0;
//-----------------------------------------------------------------------------
@ -226,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)
{
@ -343,6 +355,7 @@ namespace tut
gSavedSettings.declareString("ClientSettingsFile", "test_settings.xml", "", LLControlVariable::PERSIST_NO);
gSavedSettings.declareString("NextLoginLocation", "", "", LLControlVariable::PERSIST_NO);
gSavedSettings.declareBOOL("LoginLastLocation", FALSE, "", LLControlVariable::PERSIST_NO);
gSavedSettings.declareBOOL("CmdLineSkipUpdater", TRUE, "", LLControlVariable::PERSIST_NO);
LLSD authenticator = LLSD::emptyMap();
LLSD identifier = LLSD::emptyMap();

View File

@ -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; }

View File

@ -251,20 +251,31 @@ void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params)
// Since sSyncPoint is an LLEventMailDrop, we DEFINITELY want to
// consume the posted event.
LLCoros::OverrideConsuming oc(true);
// Timeout should produce the isUndefined() object passed here.
LL_DEBUGS("LLLogin") << "Login failure, waiting for sync from updater" << LL_ENDL;
LLSD updater = llcoro::suspendUntilEventOnWithTimeout(sSyncPoint, 10, LLSD());
if (updater.isUndefined())
{
LL_WARNS("LLLogin") << "Failed to hear from updater, proceeding with fail.login"
<< LL_ENDL;
}
else
{
LL_DEBUGS("LLLogin") << "Got responses from updater and login.cgi" << LL_ENDL;
}
// Let the fail.login handler deal with empty updater response.
LLSD responses(mAuthResponse["responses"]);
LLSD updater;
if (printable_params["wait_for_updater"].asBoolean())
{
std::string reason_response = responses["data"]["reason"].asString();
if (reason_response == "update") // No point waiting if not an update
{
// Timeout should produce the isUndefined() object passed here.
LL_INFOS("LLLogin") << "Login failure, waiting for sync from updater" << LL_ENDL;
updater = llcoro::suspendUntilEventOnWithTimeout(sSyncPoint, 10, LLSD());
if (updater.isUndefined())
{
LL_WARNS("LLLogin") << "Failed to hear from updater, proceeding with fail.login"
<< LL_ENDL;
}
else
{
LL_DEBUGS("LLLogin") << "Got responses from updater and login.cgi" << LL_ENDL;
}
}
}
// Let the fail.login handler deal with empty updater response.
responses["updater"] = updater;
sendProgressEvent("offline", "fail.login", responses);
}