//
// 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;
	}
}
예제 #3
0
//
// 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;
	}
}
예제 #4
0
void LLGridManager::deleteGrid(const std::string& grid)
{
	if(MAINGRID == grid) return;
	mGridList.erase(grid);
	if(mGrid == grid) setGridChoice(MAINGRID);
}
예제 #5
0
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);
	}
}