diff options
Diffstat (limited to 'indra/viewer_components/login')
| -rwxr-xr-x[-rw-r--r--] | indra/viewer_components/login/CMakeLists.txt | 33 | ||||
| -rwxr-xr-x[-rw-r--r--] | indra/viewer_components/login/lllogin.cpp | 139 | ||||
| -rwxr-xr-x[-rw-r--r--] | indra/viewer_components/login/lllogin.h | 36 | ||||
| -rwxr-xr-x[-rw-r--r--] | indra/viewer_components/login/tests/lllogin_test.cpp | 47 |
4 files changed, 157 insertions, 98 deletions
diff --git a/indra/viewer_components/login/CMakeLists.txt b/indra/viewer_components/login/CMakeLists.txt index fb65779eb7..c152f7c0a6 100644..100755 --- a/indra/viewer_components/login/CMakeLists.txt +++ b/indra/viewer_components/login/CMakeLists.txt @@ -3,17 +3,22 @@ project(login) include(00-Common) -include(LLAddBuildTest) +if(LL_TESTS) + include(LLAddBuildTest) +endif(LL_TESTS) include(LLCommon) include(LLMath) include(LLXML) -include(Pth) +include(Boost) include_directories( ${LLCOMMON_INCLUDE_DIRS} ${LLMATH_INCLUDE_DIRS} ${LLXML_INCLUDE_DIRS} - ${PTH_INCLUDE_DIRS} + ) +include_directories(SYSTEM + ${LLCOMMON_SYSTEM_INCLUDE_DIRS} + ${LLXML_SYSTEM_INCLUDE_DIRS} ) set(login_SOURCE_FILES @@ -40,17 +45,21 @@ target_link_libraries(lllogin ${LLCOMMON_LIBRARIES} ${LLMATH_LIBRARIES} ${LLXML_LIBRARIES} - ${PTH_LIBRARIES} + ${BOOST_CONTEXT_LIBRARY} + ${BOOST_THREAD_LIBRARY} + ${BOOST_COROUTINE_LIBRARY} + ${BOOST_SYSTEM_LIBRARY} ) -SET(lllogin_TEST_SOURCE_FILES +if(LL_TESTS) + SET(lllogin_TEST_SOURCE_FILES + lllogin.cpp + ) + set_source_files_properties( lllogin.cpp + PROPERTIES + LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_COROUTINE_LIBRARY};${BOOST_CONTEXT_LIBRARY};${BOOST_THREAD_LIBRARY};${BOOST_SYSTEM_LIBRARY}" ) -set_source_files_properties( - lllogin.cpp - PROPERTIES - LL_TEST_ADDITIONAL_LIBRARIES "${PTH_LIBRARIES}" - ) - -LL_ADD_PROJECT_UNIT_TESTS(lllogin "${lllogin_TEST_SOURCE_FILES}") + LL_ADD_PROJECT_UNIT_TESTS(lllogin "${lllogin_TEST_SOURCE_FILES}") +endif(LL_TESTS) diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp index 364088ab31..b8408a6fb4 100644..100755 --- a/indra/viewer_components/login/lllogin.cpp +++ b/indra/viewer_components/login/lllogin.cpp @@ -1,35 +1,28 @@ /** * @file lllogin.cpp * - * $LicenseInfo:firstyear=2009&license=viewergpl$ - * - * Copyright (c) 2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * 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 <boost/coroutine/coroutine.hpp> #include "linden_common.h" #include "llsd.h" #include "llsdutil.h" @@ -122,62 +115,77 @@ private: LLSD mAuthResponse, mValidAuthResponse; }; -void LLLogin::Impl::connect(const std::string& uri, const LLSD& credentials) +void LLLogin::Impl::connect(const std::string& uri, const LLSD& login_params) { + LL_DEBUGS("LLLogin") << " connect with uri '" << uri << "', login_params " << login_params << LL_ENDL; + // Launch a coroutine with our login_() method. Run the coroutine until // its first wait; at that point, return here. std::string coroname = LLCoros::instance().launch("LLLogin::Impl::login_", - boost::bind(&Impl::login_, this, _1, uri, credentials)); + boost::bind(&Impl::login_, this, _1, uri, login_params)); + LL_DEBUGS("LLLogin") << " connected with uri '" << uri << "', login_params " << login_params << LL_ENDL; } -void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD credentials) +void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD login_params) { - LLSD printable_credentials = credentials; - if(printable_credentials.has("params") - && printable_credentials["params"].has("passwd")) + try { - printable_credentials["params"]["passwd"] = "*******"; - } - LL_DEBUGS("LLLogin") << "Entering coroutine " << LLCoros::instance().getName(self) - << " with uri '" << uri << "', credentials " << printable_credentials << LL_ENDL; + LLSD printable_params = login_params; + //if(printable_params.has("params") + // && printable_params["params"].has("passwd")) + //{ + // printable_params["params"]["passwd"] = "*******"; + //} + LL_DEBUGS("LLLogin") << "Entering coroutine " << LLCoros::instance().getName(self) + << " with uri '" << uri << "', parameters " << printable_params << LL_ENDL; // Arriving in SRVRequest state - LLEventStream replyPump("reply", true); + LLEventStream replyPump("SRVreply", true); // Should be an array of one or more uri strings. + LLSD rewrittenURIs; { - LLEventTimeout filter(replyPump); - sendProgressEvent("offline", "srvrequest"); + LLEventTimeout filter(replyPump); + sendProgressEvent("offline", "srvrequest"); - // Request SRV record. - LL_DEBUGS("LLLogin") << "Requesting SRV record from " << uri << LL_ENDL; + // Request SRV record. + LL_DEBUGS("LLLogin") << "Requesting SRV record from " << uri << LL_ENDL; - // *NOTE:Mani - Completely arbitrary default timeout value for SRV request. + // *NOTE:Mani - Completely arbitrary default timeout value for SRV request. F32 seconds_to_timeout = 5.0f; - if(credentials.has("cfg_srv_timeout")) + if(login_params.has("cfg_srv_timeout")) { - seconds_to_timeout = credentials["cfg_srv_timeout"].asReal(); + seconds_to_timeout = login_params["cfg_srv_timeout"].asReal(); } - filter.eventAfter(seconds_to_timeout, - getProgressEventLLSD("offline", "fail.login")); + // If the SRV request times out (e.g. EXT-3934), simulate response: an + // array containing our original URI. + LLSD fakeResponse(LLSD::emptyArray()); + fakeResponse.append(uri); + filter.eventAfter(seconds_to_timeout, fakeResponse); std::string srv_pump_name = "LLAres"; - if(credentials.has("cfg_srv_pump")) + if(login_params.has("cfg_srv_pump")) { - srv_pump_name = credentials["cfg_srv_pump"].asString(); + srv_pump_name = login_params["cfg_srv_pump"].asString(); } // Make request - LLSD request; - request["op"] = "rewriteURI"; - request["uri"] = uri; - request["reply"] = replyPump.getName(); - rewrittenURIs = postAndWait(self, request, srv_pump_name, filter); + LLSD request; + request["op"] = "rewriteURI"; + request["uri"] = uri; + request["reply"] = replyPump.getName(); + rewrittenURIs = postAndWait(self, request, srv_pump_name, filter); + // EXP-772: If rewrittenURIs fail, try original URI as a fallback. + rewrittenURIs.append(uri); } // we no longer need the filter LLEventPump& xmlrpcPump(LLEventPumps::instance().obtain("LLXMLRPCTransaction")); + // EXT-4193: use a DIFFERENT reply pump than for the SRV request. We used + // to share them -- but the EXT-3934 fix made it possible for an abandoned + // SRV response to arrive just as we were expecting the XMLRPC response. + LLEventStream loginReplyPump("loginreply", true); // Loop through the rewrittenURIs, counting attempts along the way. // Because of possible redirect responses, we may make more than one @@ -187,8 +195,8 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD credential urend(rewrittenURIs.endArray()); urit != urend; ++urit) { - LLSD request(credentials); - request["reply"] = replyPump.getName(); + LLSD request(login_params); + request["reply"] = loginReplyPump.getName(); request["uri"] = *urit; std::string status; @@ -213,16 +221,16 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD credential // possible for the reply to arrive before the post() call // returns. Subsequent responses, of course, must be awaited // without posting again. - for (mAuthResponse = validateResponse(replyPump.getName(), - postAndWait(self, request, xmlrpcPump, replyPump, "reply")); + for (mAuthResponse = validateResponse(loginReplyPump.getName(), + postAndWait(self, request, xmlrpcPump, loginReplyPump, "reply")); mAuthResponse["status"].asString() == "Downloading"; - mAuthResponse = validateResponse(replyPump.getName(), - waitForEventOn(self, replyPump))) + mAuthResponse = validateResponse(loginReplyPump.getName(), + waitForEventOn(self, loginReplyPump))) { // Still Downloading -- send progress update. sendProgressEvent("offline", "downloading"); } - + LL_DEBUGS("LLLogin") << "Auth Response: " << mAuthResponse << LL_ENDL; status = mAuthResponse["status"].asString(); @@ -262,6 +270,16 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD credential } return; // Done! } + + /* Sometimes we end with "Started" here. Slightly slow server? + * Seems to be ok to just skip it. Otherwise we'd error out and crash in the if below. + */ + if( status == "Started") + { + LL_DEBUGS("LLLogin") << mAuthResponse << LL_ENDL; + continue; + } + // If we don't recognize status at all, trouble if (! (status == "CURLError" || status == "XMLRPCError" @@ -284,8 +302,17 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD credential // to success, add a data/message and data/reason fields. LLSD error_response; error_response["reason"] = mAuthResponse["status"]; + error_response["errorcode"] = mAuthResponse["errorcode"]; error_response["message"] = mAuthResponse["error"]; + if(mAuthResponse.has("certificate")) + { + error_response["certificate"] = mAuthResponse["certificate"]; + } sendProgressEvent("offline", "fail.login", error_response); + } + catch (...) { + LL_ERRS() << "login exception caught" << LL_ENDL; + } } void LLLogin::Impl::disconnect() diff --git a/indra/viewer_components/login/lllogin.h b/indra/viewer_components/login/lllogin.h index 0598b4e457..051641ff59 100644..100755 --- a/indra/viewer_components/login/lllogin.h +++ b/indra/viewer_components/login/lllogin.h @@ -1,31 +1,25 @@ /** * @file lllogin.h * - * $LicenseInfo:firstyear=2009&license=viewergpl$ - * - * Copyright (c) 2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, 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. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * 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. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * 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 * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ diff --git a/indra/viewer_components/login/tests/lllogin_test.cpp b/indra/viewer_components/login/tests/lllogin_test.cpp index 7159959a4f..58bf371a04 100644..100755 --- a/indra/viewer_components/login/tests/lllogin_test.cpp +++ b/indra/viewer_components/login/tests/lllogin_test.cpp @@ -4,8 +4,25 @@ * @date 2009-02-26 * @brief Tests of lllogin.cpp. * - * $LicenseInfo:firstyear=2009&license=internal$ - * Copyright (c) 2009, Linden Research, Inc. + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2009-2010, 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$ */ @@ -209,20 +226,20 @@ namespace tut typedef test_group<llviewerlogin_data> llviewerlogin_group; typedef llviewerlogin_group::object llviewerlogin_object; - llviewerlogin_group llviewerlogingrp("llviewerlogin"); + llviewerlogin_group llviewerlogingrp("LLViewerLogin"); template<> template<> void llviewerlogin_object::test<1>() { DEBUG; - // Testing login with immediate repsonses from Ares and XMLPRC + // Testing login with immediate responses from Ares and XMLPRC // The response from both requests will come before the post request exits. // This tests an edge case of the login state handling. LLEventStream llaresPump("LLAres"); // Dummy LLAres pump. LLEventStream xmlrpcPump("LLXMLRPCTransaction"); // Dummy XMLRPC pump bool respond_immediately = true; - // Have 'dummy ares' repsond immediately. + // Have 'dummy ares' respond immediately. LLAresListener dummyLLAres("dummy_llares", respond_immediately); dummyLLAres.listenTo(llaresPump); @@ -251,7 +268,7 @@ namespace tut DEBUG; // Tests a successful login in with delayed responses. // Also includes 'failure' that cause the login module - // To re-attempt connection, once from a basic failure + // to re-attempt connection, once from a basic failure // and once from the 'indeterminate' response. set_test_name("LLLogin multiple srv uris w/ success"); @@ -441,8 +458,8 @@ namespace tut // Testing normal login procedure. LLEventStream llaresPump("LLAres"); // Dummy LLAres pump. - // LLAresListener dummyLLAres("dummy_llares"); - // dummyLLAres.listenTo(llaresPump); + LLAresListener dummyLLAres("dummy_llares"); + dummyLLAres.listenTo(llaresPump); LLLogin login; LoginListener listener("test_ear"); @@ -464,6 +481,18 @@ namespace tut LLSD frame_event; mainloop.post(frame_event); - ensure_equals("SRV Failure", listener.lastEvent()["change"].asString(), "fail.login"); + // In this state we have NOT sent a reply from LLAresListener -- in + // fact there's no such object. Nonetheless, we expect the timeout to + // have stepped the login module forward to try to authenticate with + // the original URI. + ensure_equals("Auth state", listener.lastEvent()["change"].asString(), "authenticating"); + ensure_equals("Attempt", listener.lastEvent()["data"]["attempt"].asInteger(), 1); + ensure_equals("URI", listener.lastEvent()["data"]["request"]["uri"].asString(), "login.bar.com"); + + // EXT-4193: if the SRV reply isn't lost but merely late, and if it + // arrives just at the moment we're expecting the XMLRPC reply, the + // original code got confused and crashed. Drive that case here. We + // observe that without the fix, this call DOES repro. + dummyLLAres.sendReply(); } } |
