// // LLGridManager::initialze - initialize the list of known grids based // on the fixed list of linden grids (fixed for security reasons) // and the grids.xml file void LLGridManager::initialize(const std::string& grid_file) { // default grid list. // Don't move to a modifiable file for security reasons, mGrid.clear() ; // set to undefined mGridList = LLSD(); mGridFile = grid_file; // as we don't want an attacker to override our grid list // to point the default grid to an invalid grid addSystemGrid(SECOND_LIFE_MAIN_LABEL, MAINGRID, MAIN_GRID_LOGIN_URI, "https://secondlife.com/helpers/", DEFAULT_LOGIN_PAGE, "Agni"); addSystemGrid(SECOND_LIFE_BETA_LABEL, "util.aditi.lindenlab.com", "https://login.aditi.lindenlab.com/cgi-bin/login.cgi", "http://aditi-secondlife.webdev.lindenlab.com/helpers/", DEFAULT_LOGIN_PAGE, "Aditi"); #if 0 //<FS:AW disabled for meeting havok sublicense requirements/> LLSD other_grids; llifstream llsd_xml; if (!grid_file.empty()) { LL_INFOS("GridManager")<<"Grid configuration file '"<<grid_file<<"'"<<LL_ENDL; llsd_xml.open( grid_file.c_str(), std::ios::in | std::ios::binary ); // parse through the gridfile, inserting grids into the list unless // they overwrite an existing grid. if( llsd_xml.is_open()) { LLSDSerialize::fromXMLDocument( other_grids, llsd_xml ); if(other_grids.isMap()) { for(LLSD::map_iterator grid_itr = other_grids.beginMap(); grid_itr != other_grids.endMap(); ++grid_itr) { LLSD::String key_name = grid_itr->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 '"<<grid_file<<"'" << LL_ENDL; } else if ( addGrid(grid) ) { LL_INFOS("GridManager") << "added grid '"<<key_name<<"'"<<LL_ENDL; } else { LL_WARNS("GridManager") << "failed to add invalid grid '"<<key_name<<"'"<<LL_ENDL; } } llsd_xml.close(); } else { LL_WARNS("GridManager")<<"Failed to parse grid configuration '"<<grid_file<<"'"<<LL_ENDL; } } else { LL_WARNS("GridManager")<<"Failed to open grid configuration '"<<grid_file<<"'"<<LL_ENDL; } } else { LL_DEBUGS("GridManager")<<"no grid file specified"<<LL_ENDL; } #endif //<FS:AW disabled for meeting havok sublicense requirements/> // load a grid from the command line. // if the actual grid name is specified from the command line, // set it as the 'selected' grid. std::string cmd_line_grid = gSavedSettings.getString("CmdLineGridChoice"); if(!cmd_line_grid.empty()) { // try to find the grid assuming the command line parameter is // the case-insensitive 'label' of the grid. ie 'Agni' mGrid = getGrid(cmd_line_grid); if(mGrid.empty()) { LL_WARNS("GridManager")<<"Unknown grid '"<<cmd_line_grid<<"'"<<LL_ENDL; } else { LL_INFOS("GridManager")<<"Command line specified '"<<cmd_line_grid<<"': "<<mGrid<<LL_ENDL; } } else { // if a grid was not passed in via the command line, grab it from the CurrentGrid setting. // if there's no current grid, that's ok as it'll be either set by the value passed // in via the login uri if that's specified, or will default to maingrid std::string last_grid = gSavedSettings.getString("CurrentGrid"); if ( ! getGrid(last_grid).empty() ) { LL_INFOS("GridManager")<<"Using last grid: "<<last_grid<<LL_ENDL; // <FS:AW last grid might be unknown switching between SL/OpenSim flavour> // mGrid = last_grid; mGrid = getGrid(last_grid); // </FS:AW last grid might be unknown switching between SL/OpenSim flavour> } else { LL_INFOS("GridManager")<<"Last grid '"<<last_grid<<"' not configured"<<LL_ENDL; } } if(mGrid.empty()) { // no grid was specified so default to maingrid LL_INFOS("GridManager") << "Default grid to "<<MAINGRID<< LL_ENDL; mGrid = MAINGRID; } LLControlVariablePtr grid_control = gSavedSettings.getControl("CurrentGrid"); if (grid_control.notNull()) { grid_control->getSignal()->connect(boost::bind(&LLGridManager::updateIsInProductionGrid, this)); } // since above only triggers on changes, trigger the callback manually to initialize state updateIsInProductionGrid(); setGridChoice(mGrid); }
// // LLGridManager::initialze - initialize the list of known grids based // on the fixed list of linden grids (fixed for security reasons) // the grids.xml file // and the command line. void LLGridManager::initialize(const std::string& grid_file) { // default grid list. // Don't move to a modifiable file for security reasons, mGrid.clear() ; // set to undefined mGridList = LLSD(); // as we don't want an attacker to override our grid list // to point the default grid to an invalid grid addSystemGrid("None", "", "", "", DEFAULT_LOGIN_PAGE); addSystemGrid("Second Life", MAINGRID, "https://login.agni.lindenlab.com/cgi-bin/login.cgi", "https://secondlife.com/helpers/", DEFAULT_LOGIN_PAGE); addSystemGrid("Second Life Beta", "util.aditi.lindenlab.com", "https://login.aditi.lindenlab.com/cgi-bin/login.cgi", "http://aditi-secondlife.webdev.lindenlab.com/helpers/", DEFAULT_LOGIN_PAGE); LLSD other_grids; llifstream llsd_xml; // load the systemwide grids file from std::string globalGridFile = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "grids.xml"); LL_INFOS("Grid Manager") << globalGridFile << LL_ENDL; if (!globalGridFile.empty()) { llsd_xml.open( globalGridFile.c_str(), std::ios::in | std::ios::binary ); // parse through the gridfile, inserting grids into the list unless // they overwrite a linden grid. if( llsd_xml.is_open()) { LLSDSerialize::fromXMLDocument( other_grids, llsd_xml ); if(other_grids.isMap()) { for(LLSD::map_iterator grid_itr = other_grids.beginMap(); grid_itr != other_grids.endMap(); ++grid_itr) { LLSD::String key_name = grid_itr->first; LLSD grid = grid_itr->second; // TODO: Make sure gridfile specified label is not // a system grid label LL_DEBUGS("GridManager") << "reading: " << key_name << LL_ENDL; if (mGridList.has(key_name) && mGridList[key_name].has(GRID_IS_SYSTEM_GRID_VALUE)) { LL_DEBUGS("GridManager") << "Cannot override grid " << key_name << " as it's a system grid" << LL_ENDL; // If the system grid does exist in the grids file, and it's marked as a favorite, set it as a favorite. if(grid_itr->second.has(GRID_IS_FAVORITE_VALUE) && grid_itr->second[GRID_IS_FAVORITE_VALUE].asBoolean() ) { mGridList[key_name][GRID_IS_FAVORITE_VALUE] = TRUE; } } else { try { addGrid(grid); LL_DEBUGS("GridManager") << "Added grid: " << key_name << LL_ENDL; } catch (...) { } } } llsd_xml.close(); } } } // load the user grid file mGridFile = grid_file; LL_INFOS("Grid Manager") << mGridFile << LL_ENDL; if (!grid_file.empty()) { llsd_xml.open( grid_file.c_str(), std::ios::in | std::ios::binary ); // parse through the gridfile, inserting grids into the list unless // they overwrite a linden grid. if( llsd_xml.is_open()) { LLSDSerialize::fromXMLDocument( other_grids, llsd_xml ); if(other_grids.isMap()) { for(LLSD::map_iterator grid_itr = other_grids.beginMap(); grid_itr != other_grids.endMap(); ++grid_itr) { LLSD::String key_name = grid_itr->first; LLSD grid = grid_itr->second; // TODO: Make sure gridfile specified label is not // a system grid label LL_DEBUGS("GridManager") << "reading: " << key_name << LL_ENDL; if (mGridList.has(key_name) && mGridList[key_name].has(GRID_IS_SYSTEM_GRID_VALUE)) { LL_DEBUGS("GridManager") << "Cannot override grid " << key_name << " as it's a system grid" << LL_ENDL; // If the system grid does exist in the grids file, and it's marked as a favorite, set it as a favorite. if(grid_itr->second.has(GRID_IS_FAVORITE_VALUE) && grid_itr->second[GRID_IS_FAVORITE_VALUE].asBoolean() ) { mGridList[key_name][GRID_IS_FAVORITE_VALUE] = TRUE; } } else { try { addGrid(grid); LL_DEBUGS("GridManager") << "Added grid: " << key_name << LL_ENDL; } catch (...) { } } } llsd_xml.close(); } } } // load a grid from the command line. // if the actual grid name is specified from the command line, // set it as the 'selected' grid. std::string cmd_line_grid = gSavedSettings.getString("CmdLineGridChoice"); if(!cmd_line_grid.empty()) { // try to find the grid assuming the command line parameter is // the case-insensitive 'label' of the grid. ie 'Agni' mGrid = getGridByLabel(cmd_line_grid); if(mGrid.empty()) { // if we couldn't find it, assume the // requested grid is the actual grid 'name' or index, // which would be the dns name of the grid (for non // linden hosted grids) // If the grid isn't there, that's ok, as it will be // automatically added later. mGrid = cmd_line_grid; } } else { // if a grid was not passed in via the command line, grab it from the CurrentGrid setting. // if there's no current grid, that's ok as it'll be either set by the value passed // in via the login uri if that's specified, or will default to maingrid mGrid = gSavedSettings.getString("CurrentGrid"); } if(mGrid.empty()) { // no grid was specified so default to maingrid LL_DEBUGS("GridManager") << "Setting grid to MAINGRID as no grid has been specified " << LL_ENDL; mGrid = MAINGRID; } // generate a 'grid list' entry for any command line parameter overrides // or setting overides that we'll add to the grid list or override // any grid list entries with. LLSD grid = LLSD::emptyMap(); if(mGridList.has(mGrid)) { grid = mGridList[mGrid]; } else { grid[GRID_VALUE] = mGrid; // add the grid with the additional values, or update the // existing grid if it exists with the given values addGrid(grid); } LLControlVariablePtr grid_control = gSavedSettings.getControl("CurrentGrid"); if (grid_control.notNull()) { grid_control->getSignal()->connect(boost::bind(&LLGridManager::updateIsInProductionGrid, this)); } // since above only triggers on changes, trigger the callback manually to initialize state updateIsInProductionGrid(); LL_DEBUGS("GridManager") << "Selected grid is " << mGrid << LL_ENDL; setGridChoice(mGrid); if(mGridList[mGrid][GRID_LOGIN_URI_VALUE].isArray()) { llinfos << "is array" << llendl; } }
// // LLGridManager::addGrid - add a grid to the grid list, populating the needed values // if they're not populated yet. // void LLGridManager::addGrid(GridEntry* grid_entry, AddState state) { if(!grid_entry) { llwarns << "addGrid called with NULL grid_entry. Please send a bug report." << llendl; state = FAIL; } if(!grid_entry->grid.has(GRID_VALUE)) { state = FAIL; } else if(grid_entry->grid[GRID_VALUE].asString().empty()) { state = FAIL; } else if(!grid_entry->grid.isMap()) { state = FAIL; } if ((FETCH == state) ||(FETCHTEMP == state) || (SYSTEM == state)) { std::string grid = utf8str_tolower(grid_entry->grid[GRID_VALUE]); // grid should be in the form of a dns address // but also support localhost:9000 or localhost:9000/login if ( !grid.empty() && grid.find_first_not_of("abcdefghijklmnopqrstuvwxyz1234567890-_.:/@% ") != std::string::npos) { printf("grid name: %s", grid.c_str()); if (grid_entry) { state = FAIL; delete grid_entry; grid_entry = NULL; } throw LLInvalidGridName(grid); } size_t find_last_slash = grid.find_last_of("/"); if ( (grid.length()-1) == find_last_slash ) { grid.erase(find_last_slash); grid_entry->grid[GRID_VALUE] = grid; } if (FETCHTEMP == state) { grid_entry->grid["FLAG_TEMPORARY"] = "TRUE"; state = FETCH; } } if ((FETCH == state) || (RETRY == state)) { std::string grid = utf8str_tolower(grid_entry->grid[GRID_VALUE]); std::string match = "://"; size_t find_scheme = grid.find(match); if ( std::string::npos != find_scheme) { // We only support http so just remove anything the user might have chosen grid.erase(0,find_scheme+match.length()); grid_entry->grid[GRID_VALUE] = grid; } std::string uri = "http://"+grid; if (std::string::npos != uri.find("lindenlab.com")) { state = SYSTEM; } else { if ( std::string::npos == uri.find(".") || std::string::npos != uri.find("127.0.0.1") || std::string::npos != uri.find("localhost") ) { state = LOCAL; } grid_entry->grid[GRID_LOGIN_URI_VALUE] = LLSD::emptyArray(); grid_entry->grid[GRID_LOGIN_URI_VALUE].append(uri); size_t find_last_slash = uri.find_last_of("/"); if ( (uri.length()-1) != find_last_slash ) { uri.append("/"); } uri.append("get_grid_info"); LL_DEBUGS("GridManager") << "get_grid_info uri: " << uri << LL_ENDL; time_t last_modified = 0; if(grid_entry->grid.has("LastModified")) { LLDate saved_value = grid_entry->grid["LastModified"]; last_modified = (time_t)saved_value.secondsSinceEpoch(); } LLHTTPClient::getIfModified(uri, new GridInfoRequestResponder(this, grid_entry, state), last_modified); return; } } if(TRYLEGACY == state) { std::string grid = utf8str_tolower(grid_entry->grid[GRID_VALUE]); std::string uri = "https://" + grid + "/cgi-bin/login.cgi"; llwarns << "No gridinfo found. Trying if legacy login page exists: " << uri << llendl; LLHTTPClient::get(uri, new GridInfoRequestResponder(this, grid_entry, state)); return; } if(FAIL != state) { std::string grid = utf8str_tolower(grid_entry->grid[GRID_VALUE]); // populate the other values if they don't exist if (!grid_entry->grid.has(GRID_LABEL_VALUE)) { grid_entry->grid[GRID_LABEL_VALUE] = grid; llwarns << "No \"gridname\" found in grid info, setting to " << grid_entry->grid[GRID_LABEL_VALUE].asString() << llendl; } if (!grid_entry->grid.has(GRID_NICK_VALUE)) { grid_entry->grid[GRID_NICK_VALUE] = grid; llwarns << "No \"gridnick\" found in grid info, setting to " << grid_entry->grid[GRID_NICK_VALUE].asString() << llendl; } } if (SYSTEM == state) { std::string grid = utf8str_tolower(grid_entry->grid[GRID_VALUE]); // if the grid data doesn't include any of the URIs, then // generate them from the grid if (!grid_entry->grid.has(GRID_LOGIN_URI_VALUE)) { grid_entry->grid[GRID_LOGIN_URI_VALUE] = LLSD::emptyArray(); grid_entry->grid[GRID_LOGIN_URI_VALUE].append(std::string("https://") + grid + "/cgi-bin/login.cgi"); llwarns << "Adding Legacy Login Service at:" << grid_entry->grid[GRID_LOGIN_URI_VALUE].asString() << llendl; } // Populate to the default values if (!grid_entry->grid.has(GRID_LOGIN_PAGE_VALUE)) { grid_entry->grid[GRID_LOGIN_PAGE_VALUE] = std::string("http://") + grid + "/app/login/"; llwarns << "Adding Legacy Login Screen at:" << grid_entry->grid[GRID_LOGIN_PAGE_VALUE].asString() << llendl; } if (!grid_entry->grid.has(GRID_HELPER_URI_VALUE)) { llwarns << "Adding Legacy Economy at:" << grid_entry->grid[GRID_HELPER_URI_VALUE].asString() << llendl; grid_entry->grid[GRID_HELPER_URI_VALUE] = std::string("https://") + grid + "/helpers/"; } } if(FAIL != state) { std::string grid = utf8str_tolower(grid_entry->grid[GRID_VALUE]); if (!grid_entry->grid.has(GRID_LOGIN_IDENTIFIER_TYPES)) { // non system grids and grids that haven't already been configured with values // get both types of credentials. grid_entry->grid[GRID_LOGIN_IDENTIFIER_TYPES] = LLSD::emptyArray(); grid_entry->grid[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_TYPE_AGENT); grid_entry->grid[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_TYPE_ACCOUNT); } bool is_current = grid_entry->set_current; grid_entry->set_current = false; if(!grid.empty())// { if (!mGridList.has(grid)) //new grid { //finally add the grid \o/ mGridList[grid] = grid_entry->grid; ++mGridEntries; LL_DEBUGS("GridManager") << "Adding new entry: " << grid << LL_ENDL; } else { LLSD existing_grid = mGridList[grid]; if (!existing_grid.has("LastModified")) { //lack of "LastModified" means existing_grid is from fallback list, // assume its anyway older and override with the new entry mGridList[grid] = grid_entry->grid; //number of mGridEntries doesn't change LL_DEBUGS("GridManager") << "Using custom entry: " << grid << LL_ENDL; } else if (grid_entry->grid.has("LastModified")) { // (time_t)saved_value.secondsSinceEpoch(); LLDate testing_newer = grid_entry->grid["LastModified"]; LLDate existing = existing_grid["LastModified"]; LL_DEBUGS("GridManager") << "testing_newer " << testing_newer << " existing " << existing << LL_ENDL; if(testing_newer.secondsSinceEpoch() > existing.secondsSinceEpoch()) { //existing_grid is older, override. mGridList[grid] = grid_entry->grid; //number of mGridEntries doesn't change LL_DEBUGS("GridManager") << "Updating entry: " << grid << LL_ENDL; } } else { LL_DEBUGS("GridManager") << "Same or newer entry already present: " << grid << LL_ENDL; } } if(is_current) { mGrid = grid; LL_DEBUGS("GridManager") << "Selected grid is " << mGrid << LL_ENDL; setGridChoice(mGrid); } } } // This is only of use if we want to fetch infos of entire gridlists at startup /* if(grid_entry && FINISH == state || FAIL == state) { if((FINISH == state && !mCommandLineDone && 0 == mResponderCount) ||(FAIL == state && grid_entry->set_current) ) { LL_DEBUGS("GridManager") << "init CmdLineGrids" << LL_ENDL; initCmdLineGrids(); } } */ if (grid_entry) { if(!grid_entry->mOnDoneCallback.empty()) { grid_entry->mOnDoneCallback(); } delete grid_entry; grid_entry = NULL; } }
void LLGridManager::deleteGrid(const std::string& grid) { if(MAINGRID == grid) return; mGridList.erase(grid); if(mGrid == grid) setGridChoice(MAINGRID); }
void LLGridManager::initCmdLineGrids() { mCommandLineDone = true; // load a grid from the command line. // if the actual grid name is specified from the command line, // set it as the 'selected' grid. LLSD cmd_line_login_uri = gSavedSettings.getLLSD("CmdLineLoginURI"); if (cmd_line_login_uri.isString() && !cmd_line_login_uri.asString().empty()) { mGrid = cmd_line_login_uri.asString(); gSavedSettings.setLLSD("CmdLineLoginURI", LLSD::emptyArray()); //in case setGridChoice tries to addGrid //and addGrid recurses here. setGridChoice(mGrid); return; } std::string cmd_line_grid = gSavedSettings.getString("CmdLineGridChoice"); if(!cmd_line_grid.empty()) { // try to find the grid assuming the command line parameter is // the case-insensitive 'label' of the grid. ie 'Agni' mGrid = getGridByGridNick(cmd_line_grid); gSavedSettings.setString("CmdLineGridChoice",std::string()); if(mGrid.empty()) { mGrid = getGridByLabel(cmd_line_grid); } if(mGrid.empty()) { // if we couldn't find it, assume the // requested grid is the actual grid 'name' or index, // which would be the dns name of the grid (for non // linden hosted grids) // If the grid isn't there, that's ok, as it will be // automatically added later. mGrid = cmd_line_grid; } } else { // if a grid was not passed in via the command line, grab it from the CurrentGrid setting. // if there's no current grid, that's ok as it'll be either set by the value passed // in via the login uri if that's specified, or will default to maingrid mGrid = gSavedSettings.getString("CurrentGrid"); } if(mGrid.empty()) { // no grid was specified so default to maingrid LL_DEBUGS("GridManager") << "Setting grid to MAINGRID as no grid has been specified " << LL_ENDL; mGrid = MAINGRID; } // generate a 'grid list' entry for any command line parameter overrides // or setting overides that we'll add to the grid list or override // any grid list entries with. if(mGridList.has(mGrid)) { // grid_entry->grid = mGridList[mGrid]; LL_DEBUGS("GridManager") << "Setting commandline grid " << mGrid << LL_ENDL; setGridChoice(mGrid); } else { LL_DEBUGS("GridManager") << "Trying to fetch commandline grid " << mGrid << LL_ENDL; GridEntry* grid_entry = new GridEntry; grid_entry->set_current = true; grid_entry->grid = LLSD::emptyMap(); grid_entry->grid[GRID_VALUE] = mGrid; // add the grid with the additional values, or update the // existing grid if it exists with the given values addGrid(grid_entry, FETCH); } }