/** * @file llviewernetwork.cpp * @author James Cook, Richard Nelson * @brief Networking constants and globals for viewer. * * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * 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. * * 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 "llviewernetwork.h" #include "llviewercontrol.h" #include "llsdserialize.h" #include "llsecapi.h" #include "lltrans.h" #include "llweb.h" #pragma optimize("", off) /// key used to store the grid, and the name attribute in the grid data const std::string GRID_VALUE = "keyname"; /// the value displayed in the grid selector menu, and other human-oriented text const std::string GRID_LABEL_VALUE = "label"; /// the value used on the --grid command line argument const std::string GRID_ID_VALUE = "grid_login_id"; /// the url for the login cgi script const std::string GRID_LOGIN_URI_VALUE = "login_uri"; /// url base for update queries const std::string GRID_UPDATE_SERVICE_URL = "update_query_url_base"; /// const std::string GRID_HELPER_URI_VALUE = "helper_uri"; /// the splash page url const std::string GRID_LOGIN_PAGE_VALUE = "login_page"; /// url for the web profile site const std::string GRID_WEB_PROFILE_VALUE = "web_profile_url"; /// internal data on system grids const std::string GRID_IS_SYSTEM_GRID_VALUE = "system_grid"; /// whether this is single or double names const std::string GRID_LOGIN_IDENTIFIER_TYPES = "login_identifier_types"; // defines slurl formats associated with various grids. // we need to continue to support existing forms, as slurls // are shared between viewers that may not understand newer // forms. const std::string GRID_SLURL_BASE = "slurl_base"; const std::string GRID_APP_SLURL_BASE = "app_slurl_base"; const std::string DEFAULT_LOGIN_PAGE = "http://viewer-login.agni.lindenlab.com/"; const std::string MAIN_GRID_LOGIN_URI = "https://login.agni.lindenlab.com/cgi-bin/login.cgi"; const std::string SL_UPDATE_QUERY_URL = "https://update.secondlife.com/update"; const std::string MAIN_GRID_SLURL_BASE = "http://maps.secondlife.com/secondlife/"; const std::string SYSTEM_GRID_APP_SLURL_BASE = "secondlife:///app"; const std::string MAIN_GRID_WEB_PROFILE_URL = "https://my.secondlife.com/"; const char* SYSTEM_GRID_SLURL_BASE = "secondlife://%s/secondlife/"; const char* DEFAULT_SLURL_BASE = "https://%s/region/"; const char* DEFAULT_APP_SLURL_BASE = "x-grid-location-info://%s/app"; LLGridManager::LLGridManager() : mIsInProductionGrid(false) { // by default, we use the 'grids.xml' file in the user settings directory // this file is an LLSD file containing multiple grid definitions. // This file does not contain definitions for secondlife.com grids, // as that would be a security issue when they are overwritten by // an attacker. Don't want someone snagging a password. std::string grid_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "grids.xml"); // fall back to app_settings/grids.xml if it's provided if (!LLFile::isfile(grid_file)) { grid_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "grids.xml"); } LL_DEBUGS("GridManager")<getExpandedFilename(LL_PATH_APP_SETTINGS, "default_grids.xml"); out_llsd_xml.open(default_grid_file.c_str()); LLSDSerialize::toPrettyXML(mGridList, out_llsd_xml); out_llsd_xml.close(); LLSD other_grids; llifstream llsd_xml; if (!grid_file.empty()) { LL_INFOS("GridManager")<<"Grid configuration file '"<first; LLSD grid = grid_itr->second; std::string existingGrid = getGrid(grid); if (mGridList.has(key_name) || !existingGrid.empty()) { LL_WARNS("GridManager") << "Cannot override existing grid '" << key_name << "'; ignoring definition from '"<getSignal()->connect(boost::bind(&LLGridManager::updateIsInProductionGrid, this)); } // since above only triggers on changes, trigger the callback manually to initialize state updateIsInProductionGrid(); setGridChoice(mGrid); } LLGridManager::~LLGridManager() { } // // LLGridManager::addGrid - add a grid to the grid list, populating the needed values // if they're not populated yet. // bool LLGridManager::addGrid(LLSD& grid_data) { bool added = false; if (grid_data.isMap() && grid_data.has(GRID_VALUE)) { std::string grid = utf8str_tolower(grid_data[GRID_VALUE].asString()); if ( getGrid(grid_data[GRID_VALUE]).empty() && getGrid(grid).empty() ) { std::string grid_id = grid_data.has(GRID_ID_VALUE) ? grid_data[GRID_ID_VALUE].asString() : ""; if ( getGrid(grid_id).empty() ) { // populate the other values if they don't exist if (!grid_data.has(GRID_LABEL_VALUE)) { grid_data[GRID_LABEL_VALUE] = grid; } if (!grid_data.has(GRID_ID_VALUE)) { grid_data[GRID_ID_VALUE] = grid; } // if the grid data doesn't include any of the URIs, then // generate them from the grid, which should be a dns address if (!grid_data.has(GRID_LOGIN_URI_VALUE)) { grid_data[GRID_LOGIN_URI_VALUE] = LLSD::emptyArray(); grid_data[GRID_LOGIN_URI_VALUE].append(std::string("https://") + grid + "/cgi-bin/login.cgi"); } // Populate to the default values if (!grid_data.has(GRID_LOGIN_PAGE_VALUE)) { grid_data[GRID_LOGIN_PAGE_VALUE] = std::string("http://") + grid + "/app/login/"; } if (!grid_data.has(GRID_HELPER_URI_VALUE)) { grid_data[GRID_HELPER_URI_VALUE] = std::string("https://") + grid + "/helpers/"; } if (!grid_data.has(GRID_WEB_PROFILE_VALUE)) { grid_data[GRID_WEB_PROFILE_VALUE] = std::string("https://") + grid + "/"; } if (!grid_data.has(GRID_LOGIN_IDENTIFIER_TYPES)) { // non system grids and grids that haven't already been configured with values // get both types of credentials. grid_data[GRID_LOGIN_IDENTIFIER_TYPES] = LLSD::emptyArray(); grid_data[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_TYPE_AGENT); grid_data[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_TYPE_ACCOUNT); } LL_DEBUGS("GridManager") <asString()<<"\n"; } LL_CONT << LL_ENDL; mGridList[grid] = grid_data; added = true; } else { LL_WARNS("GridManager")<<"duplicate grid id'"< grid label mappings for UI purposes std::map LLGridManager::getKnownGrids() { std::map result; for(LLSD::map_iterator grid_iter = mGridList.beginMap(); grid_iter != mGridList.endMap(); grid_iter++) { result[grid_iter->first] = grid_iter->second[GRID_LABEL_VALUE].asString(); } return result; } void LLGridManager::setGridChoice(const std::string& grid) { // Set the grid choice based on a string. LL_DEBUGS("GridManager")<<"requested "<second.has(GRID_ID_VALUE)) { if (0 == (LLStringUtil::compareInsensitive(grid, grid_iter->second[GRID_ID_VALUE].asString()))) { // found a matching label, return this name grid_name = grid_iter->first; } } } } return grid_name; } std::string LLGridManager::getGridLabel(const std::string& grid) { std::string grid_label; std::string grid_name = getGrid(grid); if (!grid.empty()) { grid_label = mGridList[grid_name][GRID_LABEL_VALUE].asString(); } else { LL_WARNS("GridManager")<<"invalid grid '"<& uris) { uris.clear(); std::string grid_name = getGrid(grid); if (!grid_name.empty()) { if (mGridList[grid_name][GRID_LOGIN_URI_VALUE].isArray()) { for (LLSD::array_iterator llsd_uri = mGridList[grid_name][GRID_LOGIN_URI_VALUE].beginArray(); llsd_uri != mGridList[grid_name][GRID_LOGIN_URI_VALUE].endArray(); llsd_uri++) { uris.push_back(llsd_uri->asString()); } } else { uris.push_back(mGridList[grid_name][GRID_LOGIN_URI_VALUE].asString()); } } else { LL_WARNS("GridManager")<<"invalid grid '"<& uris) { getLoginURIs(mGrid, uris); } std::string LLGridManager::getHelperURI(const std::string& grid) { std::string helper_uri; std::string grid_name = getGrid(grid); if (!grid_name.empty()) { helper_uri = mGridList[grid_name][GRID_HELPER_URI_VALUE].asString(); } else { LL_WARNS("GridManager")<<"invalid grid '"< uris; getLoginURIs(uris); if (uris.empty()) { mIsInProductionGrid = true; } else { for ( std::vector::iterator uri_it = uris.begin(); ! mIsInProductionGrid && uri_it != uris.end(); uri_it++ ) { if( MAIN_GRID_LOGIN_URI == *uri_it ) { mIsInProductionGrid = true; } } } } bool LLGridManager::isInProductionGrid() { return mIsInProductionGrid; } bool LLGridManager::isSystemGrid(const std::string& grid) { std::string grid_name = getGrid(grid); return ( !grid_name.empty() && mGridList.has(grid) && mGridList[grid].has(GRID_IS_SYSTEM_GRID_VALUE) && mGridList[grid][GRID_IS_SYSTEM_GRID_VALUE].asBoolean() ); } // build a slurl for the given region within the selected grid std::string LLGridManager::getSLURLBase(const std::string& grid) { std::string grid_base = ""; std::string grid_name = getGrid(grid); if( ! grid_name.empty() && mGridList.has(grid_name) ) { if (mGridList[grid_name].has(GRID_SLURL_BASE)) { grid_base = mGridList[grid_name][GRID_SLURL_BASE].asString(); } else { grid_base = llformat(DEFAULT_SLURL_BASE, grid_name.c_str()); } } LL_DEBUGS("GridManager")<<"returning '"<