2013-12-08 14:50:24 +00:00
/ *
2010-01-17 16:42:08 +00:00
* Copyright ( c ) Contributors , http : //opensimulator.org/
* See CONTRIBUTORS . TXT for a full list of copyright holders .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions are met :
* * Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* * Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ` ` AS IS ' ' AND ANY
* EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED . IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES
* ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ;
* LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* /
using System ;
2010-01-17 05:42:44 +00:00
using System.Collections.Generic ;
2010-01-19 00:34:23 +00:00
using System.Net ;
2010-01-17 05:42:44 +00:00
using System.Reflection ;
2011-04-27 14:02:37 +00:00
using System.Text.RegularExpressions ;
2010-01-17 05:42:44 +00:00
using OpenSim.Framework ;
using OpenSim.Services.Interfaces ;
using GridRegion = OpenSim . Services . Interfaces . GridRegion ;
using OpenSim.Server.Base ;
2010-01-29 03:19:42 +00:00
using OpenSim.Services.Connectors.Hypergrid ;
2010-01-17 05:42:44 +00:00
using OpenMetaverse ;
using Nini.Config ;
using log4net ;
namespace OpenSim.Services.HypergridService
{
public class GatekeeperService : IGatekeeperService
{
private static readonly ILog m_log =
LogManager . GetLogger (
MethodBase . GetCurrentMethod ( ) . DeclaringType ) ;
2010-08-03 23:02:52 +00:00
private static bool m_Initialized = false ;
2010-01-17 05:42:44 +00:00
2010-08-03 23:02:52 +00:00
private static IGridService m_GridService ;
private static IPresenceService m_PresenceService ;
private static IUserAccountService m_UserAccountService ;
private static IUserAgentService m_UserAgentService ;
private static ISimulationService m_SimulationService ;
2012-09-26 19:40:41 +00:00
private static IGridUserService m_GridUserService ;
2013-04-28 04:23:29 +00:00
private static IBansService m_BansService ;
2010-01-17 05:42:44 +00:00
2012-09-22 04:03:14 +00:00
private static string m_AllowedClients = string . Empty ;
private static string m_DeniedClients = string . Empty ;
2012-03-27 20:09:58 +00:00
private static bool m_ForeignAgentsAllowed = true ;
2012-09-22 04:03:14 +00:00
private static List < string > m_ForeignsAllowedExceptions = new List < string > ( ) ;
private static List < string > m_ForeignsDisallowedExceptions = new List < string > ( ) ;
2011-04-27 14:02:37 +00:00
2010-08-03 23:02:52 +00:00
private static UUID m_ScopeID ;
private static bool m_AllowTeleportsToAnyRegion ;
private static string m_ExternalName ;
2012-11-08 03:59:54 +00:00
private static Uri m_Uri ;
2010-08-03 23:02:52 +00:00
private static GridRegion m_DefaultGatewayRegion ;
2010-01-17 05:42:44 +00:00
public GatekeeperService ( IConfigSource config , ISimulationService simService )
{
2010-08-03 23:02:52 +00:00
if ( ! m_Initialized )
{
m_Initialized = true ;
IConfig serverConfig = config . Configs [ "GatekeeperService" ] ;
if ( serverConfig = = null )
throw new Exception ( String . Format ( "No section GatekeeperService in config file" ) ) ;
string accountService = serverConfig . GetString ( "UserAccountService" , String . Empty ) ;
2010-08-03 23:33:56 +00:00
string homeUsersService = serverConfig . GetString ( "UserAgentService" , string . Empty ) ;
2010-08-03 23:02:52 +00:00
string gridService = serverConfig . GetString ( "GridService" , String . Empty ) ;
string presenceService = serverConfig . GetString ( "PresenceService" , String . Empty ) ;
string simulationService = serverConfig . GetString ( "SimulationService" , String . Empty ) ;
2012-09-26 19:40:41 +00:00
string gridUserService = serverConfig . GetString ( "GridUserService" , String . Empty ) ;
2013-04-28 04:23:29 +00:00
string bansService = serverConfig . GetString ( "BansService" , String . Empty ) ;
2010-08-03 23:02:52 +00:00
2012-09-26 19:40:41 +00:00
// These are mandatory, the others aren't
2010-08-03 23:02:52 +00:00
if ( gridService = = string . Empty | | presenceService = = string . Empty )
throw new Exception ( "Incomplete specifications, Gatekeeper Service cannot function." ) ;
string scope = serverConfig . GetString ( "ScopeID" , UUID . Zero . ToString ( ) ) ;
UUID . TryParse ( scope , out m_ScopeID ) ;
//m_WelcomeMessage = serverConfig.GetString("WelcomeMessage", "Welcome to OpenSim!");
m_AllowTeleportsToAnyRegion = serverConfig . GetBoolean ( "AllowTeleportsToAnyRegion" , true ) ;
2013-02-28 04:59:16 +00:00
m_ExternalName = Util . GetConfigVarFromSections < string > ( config , "GatekeeperURI" ,
new string [ ] { "Startup" , "Hypergrid" , "GatekeeperService" } , String . Empty ) ;
2013-02-22 01:26:19 +00:00
m_ExternalName = serverConfig . GetString ( "ExternalName" , m_ExternalName ) ;
2010-12-06 03:43:24 +00:00
if ( m_ExternalName ! = string . Empty & & ! m_ExternalName . EndsWith ( "/" ) )
m_ExternalName = m_ExternalName + "/" ;
2010-08-03 23:02:52 +00:00
2012-11-08 03:59:54 +00:00
try
{
m_Uri = new Uri ( m_ExternalName ) ;
}
catch
{
m_log . WarnFormat ( "[GATEKEEPER SERVICE]: Malformed gatekeeper address {0}" , m_ExternalName ) ;
}
2010-08-03 23:02:52 +00:00
Object [ ] args = new Object [ ] { config } ;
m_GridService = ServerUtils . LoadPlugin < IGridService > ( gridService , args ) ;
m_PresenceService = ServerUtils . LoadPlugin < IPresenceService > ( presenceService , args ) ;
if ( accountService ! = string . Empty )
m_UserAccountService = ServerUtils . LoadPlugin < IUserAccountService > ( accountService , args ) ;
if ( homeUsersService ! = string . Empty )
m_UserAgentService = ServerUtils . LoadPlugin < IUserAgentService > ( homeUsersService , args ) ;
2012-09-26 19:40:41 +00:00
if ( gridUserService ! = string . Empty )
m_GridUserService = ServerUtils . LoadPlugin < IGridUserService > ( gridUserService , args ) ;
2013-04-28 04:23:29 +00:00
if ( bansService ! = string . Empty )
m_BansService = ServerUtils . LoadPlugin < IBansService > ( bansService , args ) ;
2010-08-03 23:02:52 +00:00
if ( simService ! = null )
m_SimulationService = simService ;
else if ( simulationService ! = string . Empty )
m_SimulationService = ServerUtils . LoadPlugin < ISimulationService > ( simulationService , args ) ;
2015-09-06 17:00:20 +00:00
string [ ] possibleAccessControlConfigSections = new string [ ] { "AccessControl" , "GatekeeperService" } ;
m_AllowedClients = Util . GetConfigVarFromSections < string > (
config , "AllowedClients" , possibleAccessControlConfigSections , string . Empty ) ;
m_DeniedClients = Util . GetConfigVarFromSections < string > (
config , "DeniedClients" , possibleAccessControlConfigSections , string . Empty ) ;
2012-03-27 20:09:58 +00:00
m_ForeignAgentsAllowed = serverConfig . GetBoolean ( "ForeignAgentsAllowed" , true ) ;
2011-04-27 14:02:37 +00:00
2012-09-22 04:03:14 +00:00
LoadDomainExceptionsFromConfig ( serverConfig , "AllowExcept" , m_ForeignsAllowedExceptions ) ;
LoadDomainExceptionsFromConfig ( serverConfig , "DisallowExcept" , m_ForeignsDisallowedExceptions ) ;
2010-08-03 23:02:52 +00:00
if ( m_GridService = = null | | m_PresenceService = = null | | m_SimulationService = = null )
throw new Exception ( "Unable to load a required plugin, Gatekeeper Service cannot function." ) ;
m_log . Debug ( "[GATEKEEPER SERVICE]: Starting..." ) ;
}
2010-01-17 05:42:44 +00:00
}
public GatekeeperService ( IConfigSource config )
: this ( config , null )
{
}
2012-09-22 04:03:14 +00:00
protected void LoadDomainExceptionsFromConfig ( IConfig config , string variable , List < string > exceptions )
{
string value = config . GetString ( variable , string . Empty ) ;
string [ ] parts = value . Split ( new char [ ] { ',' } , StringSplitOptions . RemoveEmptyEntries ) ;
foreach ( string s in parts )
exceptions . Add ( s . Trim ( ) ) ;
}
2016-11-20 03:51:38 +00:00
public bool LinkRegion ( string regionName , out UUID regionID , out ulong regionHandle , out string externalName , out string imageURL , out string reason , out int sizeX , out int sizeY )
2010-01-17 05:42:44 +00:00
{
2010-01-17 15:54:03 +00:00
regionID = UUID . Zero ;
regionHandle = 0 ;
2016-11-20 03:51:38 +00:00
sizeX = ( int ) Constants . RegionSize ;
sizeY = ( int ) Constants . RegionSize ;
2010-12-06 03:43:24 +00:00
externalName = m_ExternalName + ( ( regionName ! = string . Empty ) ? " " + regionName : "" ) ;
2010-01-17 05:42:44 +00:00
imageURL = string . Empty ;
reason = string . Empty ;
2010-12-13 20:19:33 +00:00
GridRegion region = null ;
2010-05-03 16:50:55 +00:00
m_log . DebugFormat ( "[GATEKEEPER SERVICE]: Request to link to {0}" , ( regionName = = string . Empty ) ? "default region" : regionName ) ;
2010-02-01 06:35:23 +00:00
if ( ! m_AllowTeleportsToAnyRegion | | regionName = = string . Empty )
2010-01-17 05:42:44 +00:00
{
2013-09-02 16:27:45 +00:00
List < GridRegion > defs = m_GridService . GetDefaultHypergridRegions ( m_ScopeID ) ;
2010-01-17 19:33:47 +00:00
if ( defs ! = null & & defs . Count > 0 )
2010-01-17 15:54:03 +00:00
{
2010-12-13 20:19:33 +00:00
region = defs [ 0 ] ;
m_DefaultGatewayRegion = region ;
2010-01-17 15:54:03 +00:00
}
2010-12-13 20:19:33 +00:00
else
2010-01-17 15:54:03 +00:00
{
2010-02-01 06:35:23 +00:00
reason = "Grid setup problem. Try specifying a particular region here." ;
2010-02-01 06:40:06 +00:00
m_log . DebugFormat ( "[GATEKEEPER SERVICE]: Unable to send information. Please specify a default region for this grid!" ) ;
2010-01-17 05:42:44 +00:00
return false ;
}
}
2010-12-13 20:19:33 +00:00
else
2010-01-17 05:42:44 +00:00
{
2010-12-13 20:19:33 +00:00
region = m_GridService . GetRegionByName ( m_ScopeID , regionName ) ;
if ( region = = null )
{
reason = "Region not found" ;
return false ;
}
2010-01-17 05:42:44 +00:00
}
regionID = region . RegionID ;
regionHandle = region . RegionHandle ;
2016-11-20 03:51:38 +00:00
sizeX = region . RegionSizeX ;
sizeY = region . RegionSizeY ;
2010-01-17 05:42:44 +00:00
2010-12-13 20:19:33 +00:00
string regionimage = "regionImage" + regionID . ToString ( ) ;
regionimage = regionimage . Replace ( "-" , "" ) ;
2010-10-02 23:17:02 +00:00
imageURL = region . ServerURI + "index.php?method=" + regionimage ;
2010-01-17 05:42:44 +00:00
return true ;
}
2014-04-06 13:18:40 +00:00
public GridRegion GetHyperlinkRegion ( UUID regionID , UUID agentID , string agentHomeURI , out string message )
2010-01-17 05:42:44 +00:00
{
2014-04-03 09:47:20 +00:00
message = null ;
2010-01-17 19:33:47 +00:00
2010-01-17 05:42:44 +00:00
if ( ! m_AllowTeleportsToAnyRegion )
2014-04-03 09:47:20 +00:00
{
2010-01-17 05:42:44 +00:00
// Don't even check the given regionID
2014-11-21 20:36:48 +00:00
m_log . DebugFormat (
"[GATEKEEPER SERVICE]: Returning gateway region {0} {1} @ {2} to user {3}{4} as teleporting to arbitrary regions is not allowed." ,
m_DefaultGatewayRegion . RegionName ,
m_DefaultGatewayRegion . RegionID ,
m_DefaultGatewayRegion . ServerURI ,
agentID ,
agentHomeURI = = null ? "" : " @ " + agentHomeURI ) ;
2014-04-03 09:47:20 +00:00
message = "Teleporting to the default region." ;
2010-01-17 05:42:44 +00:00
return m_DefaultGatewayRegion ;
2014-04-03 09:47:20 +00:00
}
2010-01-17 05:42:44 +00:00
GridRegion region = m_GridService . GetRegionByUUID ( m_ScopeID , regionID ) ;
2014-04-03 09:47:20 +00:00
if ( region = = null )
{
2014-11-21 20:36:48 +00:00
m_log . DebugFormat (
"[GATEKEEPER SERVICE]: Could not find region with ID {0} as requested by user {1}{2}. Returning null." ,
regionID , agentID , ( agentHomeURI = = null ) ? "" : " @ " + agentHomeURI ) ;
2014-04-03 09:47:20 +00:00
message = "The teleport destination could not be found." ;
return null ;
}
2014-11-21 20:36:48 +00:00
m_log . DebugFormat (
"[GATEKEEPER SERVICE]: Returning region {0} {1} @ {2} to user {3}{4}." ,
region . RegionName ,
region . RegionID ,
region . ServerURI ,
agentID ,
agentHomeURI = = null ? "" : " @ " + agentHomeURI ) ;
2010-01-17 05:42:44 +00:00
return region ;
}
2010-01-18 18:37:11 +00:00
#region Login Agent
2014-04-09 05:03:25 +00:00
public bool LoginAgent ( GridRegion source , AgentCircuitData aCircuit , GridRegion destination , out string reason )
2010-01-17 05:42:44 +00:00
{
2010-01-18 02:04:55 +00:00
reason = string . Empty ;
2010-01-17 19:33:47 +00:00
string authURL = string . Empty ;
if ( aCircuit . ServiceURLs . ContainsKey ( "HomeURI" ) )
authURL = aCircuit . ServiceURLs [ "HomeURI" ] . ToString ( ) ;
2014-04-09 05:03:25 +00:00
m_log . InfoFormat ( "[GATEKEEPER SERVICE]: Login request for {0} {1} @ {2} ({3}) at {4} using viewer {5}, channel {6}, IP {7}, Mac {8}, Id0 {9}, Teleport Flags: {10}. From region {11}" ,
aCircuit . firstname , aCircuit . lastname , authURL , aCircuit . AgentID , destination . RegionID ,
aCircuit . Viewer , aCircuit . Channel , aCircuit . IPAddress , aCircuit . Mac , aCircuit . Id0 , ( TeleportFlags ) aCircuit . teleportFlags ,
( source = = null ) ? "Unknown" : string . Format ( "{0} ({1}){2}" , source . RegionName , source . RegionID , ( source . RawServerURI = = null ) ? "" : " @ " + source . ServerURI ) ) ;
2013-04-28 04:23:29 +00:00
2013-12-08 14:50:24 +00:00
string curViewer = Util . GetViewerName ( aCircuit ) ;
2011-04-27 14:02:37 +00:00
/ /
// Check client
/ /
if ( m_AllowedClients ! = string . Empty )
{
Regex arx = new Regex ( m_AllowedClients ) ;
2013-12-08 14:50:24 +00:00
Match am = arx . Match ( curViewer ) ;
2011-04-27 14:02:37 +00:00
if ( ! am . Success )
{
2016-11-20 03:51:38 +00:00
reason = "Login failed: client " + curViewer + " is not allowed" ;
2013-12-08 14:50:24 +00:00
m_log . InfoFormat ( "[GATEKEEPER SERVICE]: Login failed, reason: client {0} is not allowed" , curViewer ) ;
2011-04-27 14:02:37 +00:00
return false ;
}
}
if ( m_DeniedClients ! = string . Empty )
{
Regex drx = new Regex ( m_DeniedClients ) ;
2013-12-08 14:50:24 +00:00
Match dm = drx . Match ( curViewer ) ;
2011-04-27 14:02:37 +00:00
if ( dm . Success )
{
2016-11-20 03:51:38 +00:00
reason = "Login failed: client " + curViewer + " is denied" ;
2013-12-08 14:50:24 +00:00
m_log . InfoFormat ( "[GATEKEEPER SERVICE]: Login failed, reason: client {0} is denied" , curViewer ) ;
2011-04-27 14:02:37 +00:00
return false ;
}
}
2010-01-17 19:33:47 +00:00
2010-01-19 01:00:06 +00:00
/ /
// Authenticate the user
/ /
2010-01-17 05:42:44 +00:00
if ( ! Authenticate ( aCircuit ) )
2010-01-17 19:33:47 +00:00
{
2010-01-18 02:04:55 +00:00
reason = "Unable to verify identity" ;
2010-01-17 19:33:47 +00:00
m_log . InfoFormat ( "[GATEKEEPER SERVICE]: Unable to verify identity of agent {0} {1}. Refusing service." , aCircuit . firstname , aCircuit . lastname ) ;
2010-01-17 05:42:44 +00:00
return false ;
2010-01-17 19:33:47 +00:00
}
2010-01-18 02:04:55 +00:00
m_log . DebugFormat ( "[GATEKEEPER SERVICE]: Identity verified for {0} {1} @ {2}" , aCircuit . firstname , aCircuit . lastname , authURL ) ;
2010-01-19 01:00:06 +00:00
/ /
// Check for impersonations
/ /
UserAccount account = null ;
if ( m_UserAccountService ! = null )
{
// Check to see if we have a local user with that UUID
account = m_UserAccountService . GetUserAccount ( m_ScopeID , aCircuit . AgentID ) ;
if ( account ! = null )
{
2010-01-29 03:19:42 +00:00
// Make sure this is the user coming home, and not a foreign user with same UUID as a local user
if ( m_UserAgentService ! = null )
2010-01-19 01:00:06 +00:00
{
2011-12-04 16:24:16 +00:00
if ( ! m_UserAgentService . IsAgentComingHome ( aCircuit . SessionID , m_ExternalName ) )
2010-01-19 01:00:06 +00:00
{
2010-01-29 03:19:42 +00:00
// Can't do, sorry
2010-01-19 01:00:06 +00:00
reason = "Unauthorized" ;
m_log . InfoFormat ( "[GATEKEEPER SERVICE]: Foreign agent {0} {1} has same ID as local user. Refusing service." ,
aCircuit . firstname , aCircuit . lastname ) ;
return false ;
}
}
}
}
2010-01-17 05:42:44 +00:00
2012-03-27 20:09:58 +00:00
/ /
2012-09-22 04:03:14 +00:00
// Foreign agents allowed? Exceptions?
2012-03-27 20:09:58 +00:00
/ /
2013-04-28 04:23:29 +00:00
if ( account = = null )
2012-03-27 20:09:58 +00:00
{
2012-09-22 04:03:14 +00:00
bool allowed = m_ForeignAgentsAllowed ;
if ( m_ForeignAgentsAllowed & & IsException ( aCircuit , m_ForeignsAllowedExceptions ) )
2013-04-28 04:23:29 +00:00
allowed = false ;
2012-09-22 04:03:14 +00:00
if ( ! m_ForeignAgentsAllowed & & IsException ( aCircuit , m_ForeignsDisallowedExceptions ) )
allowed = true ;
if ( ! allowed )
{
reason = "Destination does not allow visitors from your world" ;
m_log . InfoFormat ( "[GATEKEEPER SERVICE]: Foreign agents are not permitted {0} {1} @ {2}. Refusing service." ,
aCircuit . firstname , aCircuit . lastname , aCircuit . ServiceURLs [ "HomeURI" ] ) ;
return false ;
}
2012-03-27 20:09:58 +00:00
}
2013-04-28 04:23:29 +00:00
/ /
// Is the user banned?
// This uses a Ban service that's more powerful than the configs
/ /
string uui = ( account ! = null ? aCircuit . AgentID . ToString ( ) : Util . ProduceUserUniversalIdentifier ( aCircuit ) ) ;
if ( m_BansService ! = null & & m_BansService . IsBanned ( uui , aCircuit . IPAddress , aCircuit . Id0 , authURL ) )
{
reason = "You are banned from this world" ;
m_log . InfoFormat ( "[GATEKEEPER SERVICE]: Login failed, reason: user {0} is banned" , uui ) ;
return false ;
}
2013-08-22 00:24:55 +00:00
m_log . DebugFormat ( "[GATEKEEPER SERVICE]: User {0} is ok" , aCircuit . Name ) ;
2013-04-28 04:23:29 +00:00
2010-08-20 02:54:40 +00:00
bool isFirstLogin = false ;
2010-01-19 01:00:06 +00:00
/ /
2010-08-20 02:54:40 +00:00
// Login the presence, if it's not there yet (by the login service)
2010-01-19 01:00:06 +00:00
/ /
2010-08-20 02:54:40 +00:00
PresenceInfo presence = m_PresenceService . GetAgent ( aCircuit . SessionID ) ;
if ( presence ! = null ) // it has been placed there by the login service
isFirstLogin = true ;
2012-09-26 19:40:41 +00:00
else
{
2010-08-20 02:54:40 +00:00
if ( ! m_PresenceService . LoginAgent ( aCircuit . AgentID . ToString ( ) , aCircuit . SessionID , aCircuit . SecureSessionID ) )
{
reason = "Unable to login presence" ;
m_log . InfoFormat ( "[GATEKEEPER SERVICE]: Presence login failed for foreign agent {0} {1}. Refusing service." ,
aCircuit . firstname , aCircuit . lastname ) ;
return false ;
}
2013-08-22 00:24:55 +00:00
m_log . DebugFormat ( "[GATEKEEPER SERVICE]: Login presence {0} is ok" , aCircuit . Name ) ;
2010-01-18 02:04:55 +00:00
2012-09-26 19:40:41 +00:00
// Also login foreigners with GridUser service
if ( m_GridUserService ! = null & & account = = null )
{
string userId = aCircuit . AgentID . ToString ( ) ;
string first = aCircuit . firstname , last = aCircuit . lastname ;
if ( last . StartsWith ( "@" ) )
{
string [ ] parts = aCircuit . firstname . Split ( '.' ) ;
if ( parts . Length > = 2 )
{
first = parts [ 0 ] ;
last = parts [ 1 ] ;
}
}
userId + = ";" + aCircuit . ServiceURLs [ "HomeURI" ] + ";" + first + " " + last ;
m_GridUserService . LoggedIn ( userId ) ;
}
}
2010-01-19 01:00:06 +00:00
/ /
2010-01-18 02:04:55 +00:00
// Get the region
2010-01-19 01:00:06 +00:00
/ /
2010-01-18 02:04:55 +00:00
destination = m_GridService . GetRegionByUUID ( m_ScopeID , destination . RegionID ) ;
if ( destination = = null )
{
2013-08-26 20:07:49 +00:00
reason = "Destination region not found" ;
return false ;
2010-01-18 02:04:55 +00:00
}
2013-08-22 00:24:55 +00:00
m_log . DebugFormat (
"[GATEKEEPER SERVICE]: Destination {0} is ok for {1}" , destination . RegionName , aCircuit . Name ) ;
2010-01-19 01:00:06 +00:00
/ /
// Adjust the visible name
/ /
if ( account ! = null )
{
aCircuit . firstname = account . FirstName ;
aCircuit . lastname = account . LastName ;
}
2012-03-08 23:55:43 +00:00
if ( account = = null )
2010-01-19 01:00:06 +00:00
{
2012-03-08 23:55:43 +00:00
if ( ! aCircuit . lastname . StartsWith ( "@" ) )
aCircuit . firstname = aCircuit . firstname + "." + aCircuit . lastname ;
2010-08-16 00:25:27 +00:00
try
{
Uri uri = new Uri ( aCircuit . ServiceURLs [ "HomeURI" ] . ToString ( ) ) ;
2015-08-03 13:25:45 +00:00
aCircuit . lastname = "@" + uri . Authority ;
2010-08-16 00:25:27 +00:00
}
catch
{
m_log . WarnFormat ( "[GATEKEEPER SERVICE]: Malformed HomeURI (this should never happen): {0}" , aCircuit . ServiceURLs [ "HomeURI" ] ) ;
aCircuit . lastname = "@" + aCircuit . ServiceURLs [ "HomeURI" ] . ToString ( ) ;
}
2010-01-19 01:00:06 +00:00
}
2010-01-17 05:42:44 +00:00
2010-01-19 01:00:06 +00:00
/ /
2010-01-17 05:42:44 +00:00
// Finally launch the agent at the destination
2010-01-19 01:00:06 +00:00
/ /
2010-08-20 02:54:40 +00:00
Constants . TeleportFlags loginFlag = isFirstLogin ? Constants . TeleportFlags . ViaLogin : Constants . TeleportFlags . ViaHGLogin ;
2012-02-18 05:32:09 +00:00
// Preserve our TeleportFlags we have gathered so-far
loginFlag | = ( Constants . TeleportFlags ) aCircuit . teleportFlags ;
2014-04-09 05:03:25 +00:00
m_log . DebugFormat ( "[GATEKEEPER SERVICE]: Launching {0}, Teleport Flags: {1}" , aCircuit . Name , loginFlag ) ;
2013-08-22 00:24:55 +00:00
2015-10-31 17:13:02 +00:00
EntityTransferContext ctx = new EntityTransferContext ( ) ;
2014-07-21 22:53:33 +00:00
if ( ! m_SimulationService . QueryAccess (
destination , aCircuit . AgentID , aCircuit . ServiceURLs [ "HomeURI" ] . ToString ( ) ,
2015-10-31 17:13:02 +00:00
true , aCircuit . startpos , new List < UUID > ( ) , ctx , out reason ) )
2014-07-21 22:53:33 +00:00
return false ;
2015-11-01 18:11:14 +00:00
return m_SimulationService . CreateAgent ( source , destination , aCircuit , ( uint ) loginFlag , ctx , out reason ) ;
2010-01-17 05:42:44 +00:00
}
2010-01-18 18:37:11 +00:00
protected bool Authenticate ( AgentCircuitData aCircuit )
2010-01-17 05:42:44 +00:00
{
2010-01-29 03:19:42 +00:00
if ( ! CheckAddress ( aCircuit . ServiceSessionID ) )
return false ;
2013-07-14 00:52:05 +00:00
if ( string . IsNullOrEmpty ( aCircuit . IPAddress ) )
{
m_log . DebugFormat ( "[GATEKEEPER SERVICE]: Agent did not provide a client IP address." ) ;
return false ;
}
2010-01-29 03:19:42 +00:00
string userURL = string . Empty ;
2010-01-17 19:33:47 +00:00
if ( aCircuit . ServiceURLs . ContainsKey ( "HomeURI" ) )
2010-01-29 03:19:42 +00:00
userURL = aCircuit . ServiceURLs [ "HomeURI" ] . ToString ( ) ;
2010-01-17 19:33:47 +00:00
2010-01-29 03:19:42 +00:00
if ( userURL = = string . Empty )
2010-01-17 19:33:47 +00:00
{
m_log . DebugFormat ( "[GATEKEEPER SERVICE]: Agent did not provide an authentication server URL" ) ;
2010-01-17 05:42:44 +00:00
return false ;
2010-01-17 19:33:47 +00:00
}
2010-01-17 05:42:44 +00:00
2010-08-03 23:27:11 +00:00
if ( userURL = = m_ExternalName )
2011-11-15 20:37:49 +00:00
{
2010-08-04 00:05:48 +00:00
return m_UserAgentService . VerifyAgent ( aCircuit . SessionID , aCircuit . ServiceSessionID ) ;
2011-11-15 20:37:49 +00:00
}
2010-08-03 23:27:11 +00:00
else
2010-01-18 02:04:55 +00:00
{
2010-08-03 23:27:11 +00:00
IUserAgentService userAgentService = new UserAgentServiceConnector ( userURL ) ;
2011-11-15 20:37:49 +00:00
try
2010-01-18 02:04:55 +00:00
{
2011-11-15 20:37:49 +00:00
return userAgentService . VerifyAgent ( aCircuit . SessionID , aCircuit . ServiceSessionID ) ;
}
catch
{
m_log . DebugFormat ( "[GATEKEEPER SERVICE]: Unable to contact authentication service at {0}" , userURL ) ;
return false ;
2010-01-18 02:04:55 +00:00
}
}
2010-01-17 05:42:44 +00:00
}
2010-01-18 18:37:11 +00:00
2010-01-29 03:19:42 +00:00
// Check that the service token was generated for *this* grid.
// If it wasn't then that's a fake agent.
protected bool CheckAddress ( string serviceToken )
2010-01-18 18:37:11 +00:00
{
2010-01-29 03:19:42 +00:00
string [ ] parts = serviceToken . Split ( new char [ ] { ';' } ) ;
if ( parts . Length < 2 )
return false ;
2010-01-18 18:37:11 +00:00
2010-12-29 12:40:47 +00:00
char [ ] trailing_slash = new char [ ] { '/' } ;
string addressee = parts [ 0 ] . TrimEnd ( trailing_slash ) ;
string externalname = m_ExternalName . TrimEnd ( trailing_slash ) ;
m_log . DebugFormat ( "[GATEKEEPER SERVICE]: Verifying {0} against {1}" , addressee , externalname ) ;
2010-11-27 08:18:39 +00:00
2012-11-08 03:59:54 +00:00
Uri uri ;
try
{
uri = new Uri ( addressee ) ;
}
catch
{
m_log . DebugFormat ( "[GATEKEEPER SERVICE]: Visitor provided malformed service address {0}" , addressee ) ;
return false ;
}
return string . Equals ( uri . GetLeftPart ( UriPartial . Authority ) , m_Uri . GetLeftPart ( UriPartial . Authority ) , StringComparison . OrdinalIgnoreCase ) ;
2010-01-29 03:19:42 +00:00
}
2010-01-18 18:37:11 +00:00
2010-01-29 03:19:42 +00:00
# endregion
2010-01-18 18:37:11 +00:00
#region Misc
2012-09-22 04:03:14 +00:00
private bool IsException ( AgentCircuitData aCircuit , List < string > exceptions )
{
bool exception = false ;
if ( exceptions . Count > 0 ) // we have exceptions
{
// Retrieve the visitor's origin
string userURL = aCircuit . ServiceURLs [ "HomeURI" ] . ToString ( ) ;
if ( ! userURL . EndsWith ( "/" ) )
userURL + = "/" ;
if ( exceptions . Find ( delegate ( string s )
{
if ( ! s . EndsWith ( "/" ) )
s + = "/" ;
return s = = userURL ;
} ) ! = null )
exception = true ;
}
return exception ;
}
2010-01-18 18:37:11 +00:00
# endregion
2010-01-17 05:42:44 +00:00
}
}