diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/newview/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | indra/newview/app_settings/settings_per_account.xml | 11 | ||||
| -rw-r--r-- | indra/newview/llfloatermfa.cpp | 101 | ||||
| -rw-r--r-- | indra/newview/llfloatermfa.h | 50 | ||||
| -rw-r--r-- | indra/newview/lllogininstance.cpp | 43 | ||||
| -rw-r--r-- | indra/newview/lllogininstance.h | 1 | ||||
| -rw-r--r-- | indra/newview/llstartup.cpp | 11 | ||||
| -rw-r--r-- | indra/newview/llviewerfloaterreg.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_mfa.xml | 49 | ||||
| -rw-r--r-- | indra/newview/tests/lllogininstance_test.cpp | 1 | 
10 files changed, 268 insertions, 3 deletions
| diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 5a06106de3..6c976e3f2d 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -275,6 +275,7 @@ set(viewer_SOURCE_FILES      llfloatermap.cpp      llfloatermediasettings.cpp      llfloatermemleak.cpp +    llfloatermfa.cpp      llfloatermodelpreview.cpp      llfloatermodeluploadbase.cpp      llfloatermyscripts.cpp @@ -918,6 +919,7 @@ set(viewer_HEADER_FILES      llfloatermarketplacelistings.h      llfloatermediasettings.h      llfloatermemleak.h +    llfloatermfa.h      llfloatermodelpreview.h      llfloatermodeluploadbase.h      llfloatermyscripts.h diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index 537744b44c..d7d008689c 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>SLMFAHash</key> +      <map> +        <key>Comment</key> +        <string>MFA state hash for authentication</string> +        <key>Persist</key> +        <integer>1</integer> +        <key>Type</key> +        <string>String</string> +        <key>Value</key> +        <string></string> +      </map>      </map>  </llsd> diff --git a/indra/newview/llfloatermfa.cpp b/indra/newview/llfloatermfa.cpp new file mode 100644 index 0000000000..7710817c23 --- /dev/null +++ b/indra/newview/llfloatermfa.cpp @@ -0,0 +1,101 @@ +/** + * @file llfloatermfa.cpp + * @brief Multi-Factor Auth token submission dialog + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2021, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloatermfa.h" + +// viewer includes +#include "llevents.h" + + +LLFloaterMFA::LLFloaterMFA(const LLSD& data) +:   LLModalDialog("mfa_challenge"), +    mMessage(data["message"].asStringRef()), +    mReplyPumpName(data["reply_pump"].asStringRef()) +{ + +} + +LLFloaterMFA::~LLFloaterMFA() +{ +} + +BOOL LLFloaterMFA::postBuild() +{ +    centerOnScreen(); + +    childSetAction("continue_btn", onContinue, this); +    childSetAction("cancel_btn", onCancel, this); +    childSetCommitCallback("token_edit", [](LLUICtrl*, void* userdata) { onContinue(userdata);}, this); + +    // this displays the prompt message +    LLUICtrl *token_prompt = getChild<LLUICtrl>("token_prompt_text"); +    token_prompt->setEnabled( FALSE ); +    token_prompt->setValue(LLSD(mMessage)); + +    LLUICtrl *token_edit = getChild<LLUICtrl>("token_edit"); +    token_edit->setFocus(TRUE); + +    return TRUE; +} + +// static +void LLFloaterMFA::onContinue(void* userdata ) +{ +    LLFloaterMFA* self = static_cast<LLFloaterMFA*>(userdata); + +    LLUICtrl *token_ctrl = self->getChild<LLUICtrl>("token_edit"); + +    std::string token(token_ctrl->getValue().asStringRef()); + +    if (!token.empty()) +    { +        LL_INFOS("MFA") << "User submits MFA token for challenge." << LL_ENDL; +        if(self->mReplyPumpName != "") +        { +            LLEventPumps::instance().obtain(self->mReplyPumpName).post(LLSD(token)); +        } + +        self->closeFloater(); // destroys this object +    } +} + +// static +void LLFloaterMFA::onCancel(void* userdata) +{ +    LLFloaterMFA* self = static_cast<LLFloaterMFA*>(userdata); +    LL_INFOS("MFA") << "User cancels MFA challenge attempt." << LL_ENDL; + +    if(self->mReplyPumpName != "") +    { +        LL_DEBUGS("MFA") << self->mReplyPumpName << LL_ENDL; +        LLEventPumps::instance().obtain(self->mReplyPumpName).post(LLSD()); +    } + +    // destroys this object +    self->closeFloater(); +} diff --git a/indra/newview/llfloatermfa.h b/indra/newview/llfloatermfa.h new file mode 100644 index 0000000000..9332b35877 --- /dev/null +++ b/indra/newview/llfloatermfa.h @@ -0,0 +1,50 @@ +/** + * @file llfloatermfa.h + * @brief Multi-Factor Auth token submission dialog + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2021, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATERMFA_H +#define LL_LLFLOATERMFA_H + +#include "llmodaldialog.h" + + +class LLFloaterMFA : +    public LLModalDialog +{ +public: +    LLFloaterMFA(const LLSD& data); +    virtual ~LLFloaterMFA(); + +    BOOL postBuild(); + +    static void onContinue(void* userdata); +    static void onCancel(void* userdata); + +private: +    std::string mMessage; +    std::string mReplyPumpName; +}; + +#endif // LL_FLOATERMFA_H diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index e81d2cc082..902510c294 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -75,6 +75,8 @@ public:  static const char * const TOS_REPLY_PUMP = "lllogininstance_tos_callback";  static const char * const TOS_LISTENER_NAME = "lllogininstance_tos"; +static const char * const MFA_REPLY_PUMP = "lllogininstance_mfa_callback"; +static const char * const MFA_LISTENER_NAME = "lllogininstance_mfa";  std::string construct_start_string(); @@ -225,6 +227,8 @@ 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"] = ""; +	request_params["slmfa_hash"] = gSavedPerAccountSettings.getString("SLMFAHash");      // log request_params _before_ adding the credentials         LL_DEBUGS("LLLogin") << "Login parameters: " << LLSDOStreamer<LLSDNotationFormatter>(request_params) << LL_ENDL; @@ -407,6 +411,23 @@ 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; + +        LLSD data(LLSD::emptyMap()); +        data["message"] = message_response; +        data["reply_pump"] = MFA_REPLY_PUMP; +        if (gViewerWindow) +        { +            gViewerWindow->setShowProgress(FALSE); +        } +        LLFloaterReg::showInstance("message_mfa", data); +        LLEventPumps::instance().obtain(MFA_REPLY_PUMP) +            .listen(MFA_LISTENER_NAME, [=](const LLSD& token) { +                return this->handleMFAResponse(token, "token"); +            }); +    }      else if(   reason_response == "key"              || reason_response == "presence"              || reason_response == "connect" @@ -501,6 +522,28 @@ bool LLLoginInstance::handleTOSResponse(bool accepted, const std::string& key)  	return true;  } +bool LLLoginInstance::handleMFAResponse(const std::string& token, const std::string& key) +{ +    LLEventPumps::instance().obtain(MFA_REPLY_PUMP).stopListening(MFA_LISTENER_NAME); + +    if(!token.empty()) +    { +        LL_INFOS("LLLogin") << "LLLoginInstance::handleMFAResponse: token submitted" << LL_ENDL; + +        // Set the request data to true and retry login. +        mRequestData["params"][key] = token; +        reconnect(); +    } +    else +    { +        LL_INFOS("LLLogin") << "LLLoginInstance::handleMFAResponse: no token, attemptComplete" << LL_ENDL; + +        attemptComplete(); +    } + +    return true; +} +  std::string construct_start_string()  {  	std::string start; diff --git a/indra/newview/lllogininstance.h b/indra/newview/lllogininstance.h index b759b43474..ce64e9e3be 100644 --- a/indra/newview/lllogininstance.h +++ b/indra/newview/lllogininstance.h @@ -84,6 +84,7 @@ private:  	void syncWithUpdater(ResponsePtr resp, const LLSD& notification, const LLSD& response);  	bool handleTOSResponse(bool v, const std::string& key); +	bool handleMFAResponse(const std::string& v, const std::string& key);  	void attemptComplete() { mAttemptComplete = true; } // In the future an event? diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 54f3e6305c..8e81843153 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1109,10 +1109,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"))  					{ @@ -3597,6 +3597,11 @@ bool process_login_success_response()  		LLViewerMedia::getInstance()->openIDSetup(openid_url, openid_token);  	} +	if(response.has("slmfa_hash")) +	{ +		gSavedPerAccountSettings.setString("SLMFAHash", response["slmfa_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/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 62d73063aa..677b55e49f 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -92,6 +92,7 @@  #include "llfloatermarketplacelistings.h"  #include "llfloatermediasettings.h"  #include "llfloatermemleak.h" +#include "llfloatermfa.h"  #include "llfloatermodelpreview.h"  #include "llfloatermyscripts.h"  #include "llfloatermyenvironment.h" @@ -288,6 +289,7 @@ void LLViewerFloaterReg::registerFloaters()  	LLFloaterReg::add("marketplace_validation", "floater_marketplace_validation.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMarketplaceValidation>);  	LLFloaterReg::add("message_critical", "floater_critical.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>);  	LLFloaterReg::add("message_tos", "floater_tos.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>); +	LLFloaterReg::add("message_mfa", "floater_mfa.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMFA>);  	LLFloaterReg::add("moveview", "floater_moveview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMove>);  	LLFloaterReg::add("mute_object_by_name", "floater_mute_object.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGetBlockedObjectName>);  	LLFloaterReg::add("mini_map", "floater_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMap>); 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/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp index 8d1956957c..43f0e89222 100644 --- a/indra/newview/tests/lllogininstance_test.cpp +++ b/indra/newview/tests/lllogininstance_test.cpp @@ -190,6 +190,7 @@ std::string LLGridManager::getAppSLURLBase(const std::string& grid_name)  //-----------------------------------------------------------------------------  #include "../llviewercontrol.h"  LLControlGroup gSavedSettings("Global"); +LLControlGroup gSavedPerAccountSettings("PerAccount");  LLControlGroup::LLControlGroup(const std::string& name) :  	LLInstanceTracker<LLControlGroup, std::string>(name){} | 
