diff options
| -rw-r--r-- | indra/cmake/Boost.cmake | 16 | ||||
| -rw-r--r-- | indra/newview/app_settings/settings_per_account.xml | 11 | ||||
| -rw-r--r-- | indra/newview/lllogininstance.cpp | 42 | ||||
| -rw-r--r-- | indra/newview/llstartup.cpp | 14 | ||||
| -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 | 
8 files changed, 154 insertions, 13 deletions
| diff --git a/indra/cmake/Boost.cmake b/indra/cmake/Boost.cmake index 06a7ab6d75..26604d4913 100644 --- a/indra/cmake/Boost.cmake +++ b/indra/cmake/Boost.cmake @@ -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) 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..06dbf97e51 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -225,10 +225,21 @@ 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 +    if(mfa_hash.empty()) +    { +        LLPointer<LLSecAPIHandler> basic_secure_store = getSecHandler(BASIC_SECHANDLER); +        std::string grid(LLGridManager::getInstance()->getGridId()); +        mfa_hash = basic_secure_store->getProtectedData("mfa_hash", grid).asString(); +    } + +    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 +418,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..d625ef2539 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,13 @@ bool process_login_success_response()  		LLViewerMedia::getInstance()->openIDSetup(openid_url, openid_token);  	} +	if(response.has("mfa_hash") && gSavedSettings.getBOOL("RememberUser")) +	{ +		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){} | 
