29 using System.Collections.Generic;
31 using System.Reflection;
32 using System.Text.RegularExpressions;
34 using OpenSim.Framework;
35 using OpenSim.Services.Interfaces;
37 using OpenSim.Server.Base;
38 using OpenSim.Services.Connectors.Hypergrid;
45 namespace OpenSim.Services.HypergridService
49 private static readonly ILog m_log =
51 MethodBase.GetCurrentMethod().DeclaringType);
53 private static bool m_Initialized =
false;
63 private static string m_AllowedClients = string.Empty;
64 private static string m_DeniedClients = string.Empty;
65 private static bool m_ForeignAgentsAllowed =
true;
66 private static List<string> m_ForeignsAllowedExceptions =
new List<string>();
67 private static List<string> m_ForeignsDisallowedExceptions =
new List<string>();
69 private static UUID m_ScopeID;
70 private static bool m_AllowTeleportsToAnyRegion;
71 private static string m_ExternalName;
72 private static Uri m_Uri;
73 private static GridRegion m_DefaultGatewayRegion;
81 IConfig serverConfig = config.Configs[
"GatekeeperService"];
82 if (serverConfig == null)
83 throw new Exception(String.Format(
"No section GatekeeperService in config file"));
85 string accountService = serverConfig.GetString(
"UserAccountService", String.Empty);
86 string homeUsersService = serverConfig.GetString(
"UserAgentService", string.Empty);
87 string gridService = serverConfig.GetString(
"GridService", String.Empty);
88 string presenceService = serverConfig.GetString(
"PresenceService", String.Empty);
89 string simulationService = serverConfig.GetString(
"SimulationService", String.Empty);
90 string gridUserService = serverConfig.GetString(
"GridUserService", String.Empty);
91 string bansService = serverConfig.GetString(
"BansService", String.Empty);
94 if (gridService ==
string.Empty || presenceService ==
string.Empty)
95 throw new Exception(
"Incomplete specifications, Gatekeeper Service cannot function.");
97 string scope = serverConfig.GetString(
"ScopeID", UUID.Zero.ToString());
98 UUID.TryParse(scope, out m_ScopeID);
100 m_AllowTeleportsToAnyRegion = serverConfig.GetBoolean(
"AllowTeleportsToAnyRegion",
true);
101 m_ExternalName = Util.GetConfigVarFromSections<
string>(config,
"GatekeeperURI",
102 new string[] {
"Startup",
"Hypergrid",
"GatekeeperService" }, String.Empty);
103 m_ExternalName = serverConfig.GetString(
"ExternalName", m_ExternalName);
104 if (m_ExternalName !=
string.Empty && !m_ExternalName.EndsWith(
"/"))
105 m_ExternalName = m_ExternalName +
"/";
109 m_Uri =
new Uri(m_ExternalName);
113 m_log.WarnFormat(
"[GATEKEEPER SERVICE]: Malformed gatekeeper address {0}", m_ExternalName);
116 Object[] args =
new Object[] { config };
117 m_GridService = ServerUtils.LoadPlugin<
IGridService>(gridService, args);
118 m_PresenceService = ServerUtils.LoadPlugin<
IPresenceService>(presenceService, args);
120 if (accountService !=
string.Empty)
122 if (homeUsersService !=
string.Empty)
123 m_UserAgentService = ServerUtils.LoadPlugin<
IUserAgentService>(homeUsersService, args);
124 if (gridUserService !=
string.Empty)
125 m_GridUserService = ServerUtils.LoadPlugin<
IGridUserService>(gridUserService, args);
126 if (bansService !=
string.Empty)
127 m_BansService = ServerUtils.LoadPlugin<
IBansService>(bansService, args);
129 if (simService != null)
130 m_SimulationService = simService;
131 else if (simulationService !=
string.Empty)
132 m_SimulationService = ServerUtils.LoadPlugin<
ISimulationService>(simulationService, args);
134 string[] possibleAccessControlConfigSections =
new string[] {
"AccessControl",
"GatekeeperService" };
135 m_AllowedClients = Util.GetConfigVarFromSections<
string>(
136 config,
"AllowedClients", possibleAccessControlConfigSections, string.Empty);
137 m_DeniedClients = Util.GetConfigVarFromSections<
string>(
138 config,
"DeniedClients", possibleAccessControlConfigSections, string.Empty);
139 m_ForeignAgentsAllowed = serverConfig.GetBoolean(
"ForeignAgentsAllowed",
true);
141 LoadDomainExceptionsFromConfig(serverConfig,
"AllowExcept", m_ForeignsAllowedExceptions);
142 LoadDomainExceptionsFromConfig(serverConfig,
"DisallowExcept", m_ForeignsDisallowedExceptions);
144 if (m_GridService == null || m_PresenceService == null || m_SimulationService == null)
145 throw new Exception(
"Unable to load a required plugin, Gatekeeper Service cannot function.");
147 m_log.Debug(
"[GATEKEEPER SERVICE]: Starting...");
158 string value = config.GetString(variable, string.Empty);
159 string[] parts = value.Split(
new char[] {
',' }, StringSplitOptions.RemoveEmptyEntries);
161 foreach (
string s
in parts)
162 exceptions.Add(s.Trim());
165 public bool LinkRegion(
string regionName, out UUID regionID, out ulong regionHandle, out
string externalName, out
string imageURL, out
string reason)
167 regionID = UUID.Zero;
169 externalName = m_ExternalName + ((regionName != string.Empty) ?
" " + regionName :
"");
170 imageURL = string.Empty;
171 reason = string.Empty;
174 m_log.DebugFormat(
"[GATEKEEPER SERVICE]: Request to link to {0}", (regionName == string.Empty)?
"default region" : regionName);
175 if (!m_AllowTeleportsToAnyRegion || regionName ==
string.Empty)
177 List<GridRegion> defs = m_GridService.GetDefaultHypergridRegions(m_ScopeID);
178 if (defs != null && defs.Count > 0)
181 m_DefaultGatewayRegion = region;
185 reason =
"Grid setup problem. Try specifying a particular region here.";
186 m_log.DebugFormat(
"[GATEKEEPER SERVICE]: Unable to send information. Please specify a default region for this grid!");
192 region = m_GridService.GetRegionByName(m_ScopeID, regionName);
195 reason =
"Region not found";
200 regionID = region.RegionID;
201 regionHandle = region.RegionHandle;
203 string regionimage =
"regionImage" + regionID.ToString();
204 regionimage = regionimage.Replace(
"-",
"");
205 imageURL = region.ServerURI +
"index.php?method=" + regionimage;
214 if (!m_AllowTeleportsToAnyRegion)
218 "[GATEKEEPER SERVICE]: Returning gateway region {0} {1} @ {2} to user {3}{4} as teleporting to arbitrary regions is not allowed.",
219 m_DefaultGatewayRegion.RegionName,
220 m_DefaultGatewayRegion.RegionID,
221 m_DefaultGatewayRegion.ServerURI,
223 agentHomeURI == null ?
"" :
" @ " + agentHomeURI);
225 message =
"Teleporting to the default region.";
226 return m_DefaultGatewayRegion;
229 GridRegion region = m_GridService.GetRegionByUUID(m_ScopeID, regionID);
234 "[GATEKEEPER SERVICE]: Could not find region with ID {0} as requested by user {1}{2}. Returning null.",
235 regionID, agentID, (agentHomeURI == null) ?
"" :
" @ " + agentHomeURI);
237 message =
"The teleport destination could not be found.";
242 "[GATEKEEPER SERVICE]: Returning region {0} {1} @ {2} to user {3}{4}.",
247 agentHomeURI == null ?
"" :
" @ " + agentHomeURI);
255 reason = string.Empty;
257 string authURL = string.Empty;
259 authURL = aCircuit.
ServiceURLs[
"HomeURI"].ToString();
261 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}",
262 aCircuit.firstname, aCircuit.lastname, authURL, aCircuit.AgentID, destination.RegionID,
264 (source == null) ?
"Unknown" : string.Format(
"{0} ({1}){2}", source.RegionName, source.RegionID, (source.RawServerURI == null) ?
"" :
" @ " + source.
ServerURI));
266 string curViewer = Util.GetViewerName(aCircuit);
271 if (m_AllowedClients !=
string.Empty)
273 Regex arx =
new Regex(m_AllowedClients);
274 Match am = arx.Match(curViewer);
278 m_log.InfoFormat(
"[GATEKEEPER SERVICE]: Login failed, reason: client {0} is not allowed", curViewer);
283 if (m_DeniedClients !=
string.Empty)
285 Regex drx =
new Regex(m_DeniedClients);
286 Match dm = drx.Match(curViewer);
290 m_log.InfoFormat(
"[GATEKEEPER SERVICE]: Login failed, reason: client {0} is denied", curViewer);
300 reason =
"Unable to verify identity";
301 m_log.InfoFormat(
"[GATEKEEPER SERVICE]: Unable to verify identity of agent {0} {1}. Refusing service.", aCircuit.firstname, aCircuit.lastname);
304 m_log.DebugFormat(
"[GATEKEEPER SERVICE]: Identity verified for {0} {1} @ {2}", aCircuit.firstname, aCircuit.lastname, authURL);
310 if (m_UserAccountService != null)
313 account = m_UserAccountService.GetUserAccount(m_ScopeID, aCircuit.AgentID);
317 if (m_UserAgentService != null)
319 if (!m_UserAgentService.IsAgentComingHome(aCircuit.
SessionID, m_ExternalName))
322 reason =
"Unauthorized";
323 m_log.InfoFormat(
"[GATEKEEPER SERVICE]: Foreign agent {0} {1} has same ID as local user. Refusing service.",
324 aCircuit.firstname, aCircuit.lastname);
337 bool allowed = m_ForeignAgentsAllowed;
339 if (m_ForeignAgentsAllowed && IsException(aCircuit, m_ForeignsAllowedExceptions))
342 if (!m_ForeignAgentsAllowed && IsException(aCircuit, m_ForeignsDisallowedExceptions))
347 reason =
"Destination does not allow visitors from your world";
348 m_log.InfoFormat(
"[GATEKEEPER SERVICE]: Foreign agents are not permitted {0} {1} @ {2}. Refusing service.",
349 aCircuit.firstname, aCircuit.lastname, aCircuit.ServiceURLs[
"HomeURI"]);
358 string uui = (account != null ? aCircuit.AgentID.ToString() : Util.ProduceUserUniversalIdentifier(aCircuit));
359 if (m_BansService != null && m_BansService.IsBanned(uui, aCircuit.
IPAddress, aCircuit.
Id0, authURL))
361 reason =
"You are banned from this world";
362 m_log.InfoFormat(
"[GATEKEEPER SERVICE]: Login failed, reason: user {0} is banned", uui);
366 m_log.DebugFormat(
"[GATEKEEPER SERVICE]: User {0} is ok", aCircuit.Name);
368 bool isFirstLogin =
false;
372 PresenceInfo presence = m_PresenceService.GetAgent(aCircuit.SessionID);
373 if (presence != null)
378 if (!m_PresenceService.LoginAgent(aCircuit.
AgentID.ToString(), aCircuit.SessionID, aCircuit.SecureSessionID))
380 reason =
"Unable to login presence";
381 m_log.InfoFormat(
"[GATEKEEPER SERVICE]: Presence login failed for foreign agent {0} {1}. Refusing service.",
382 aCircuit.firstname, aCircuit.lastname);
386 m_log.DebugFormat(
"[GATEKEEPER SERVICE]: Login presence {0} is ok", aCircuit.Name);
389 if (m_GridUserService != null && account == null)
391 string userId = aCircuit.AgentID.ToString();
392 string first = aCircuit.firstname, last = aCircuit.lastname;
393 if (last.StartsWith(
"@"))
395 string[] parts = aCircuit.firstname.Split(
'.');
396 if (parts.Length >= 2)
403 userId +=
";" + aCircuit.ServiceURLs[
"HomeURI"] +
";" + first +
" " + last;
404 m_GridUserService.LoggedIn(userId);
411 destination = m_GridService.GetRegionByUUID(m_ScopeID, destination.RegionID);
412 if (destination == null)
414 reason =
"Destination region not found";
419 "[GATEKEEPER SERVICE]: Destination {0} is ok for {1}", destination.RegionName, aCircuit.Name);
426 aCircuit.firstname = account.FirstName;
427 aCircuit.lastname = account.LastName;
431 if (!aCircuit.
lastname.StartsWith(
"@"))
435 Uri uri =
new Uri(aCircuit.
ServiceURLs[
"HomeURI"].ToString());
436 aCircuit.lastname =
"@" + uri.Authority;
440 m_log.WarnFormat(
"[GATEKEEPER SERVICE]: Malformed HomeURI (this should never happen): {0}", aCircuit.ServiceURLs[
"HomeURI"]);
441 aCircuit.lastname =
"@" + aCircuit.ServiceURLs[
"HomeURI"].ToString();
448 Constants.TeleportFlags loginFlag = isFirstLogin ? Constants.TeleportFlags.ViaLogin : Constants.TeleportFlags.ViaHGLogin;
453 m_log.DebugFormat(
"[GATEKEEPER SERVICE]: Launching {0}, Teleport Flags: {1}", aCircuit.Name, loginFlag);
457 if (!m_SimulationService.QueryAccess(
458 destination, aCircuit.AgentID, aCircuit.ServiceURLs[
"HomeURI"].ToString(),
459 true, aCircuit.startpos,
new List<UUID>(), ctx, out reason))
462 return m_SimulationService.CreateAgent(source, destination, aCircuit, (uint)loginFlag, ctx, out reason);
470 if (
string.IsNullOrEmpty(aCircuit.
IPAddress))
472 m_log.DebugFormat(
"[GATEKEEPER SERVICE]: Agent did not provide a client IP address.");
476 string userURL = string.Empty;
478 userURL = aCircuit.
ServiceURLs[
"HomeURI"].ToString();
480 if (userURL ==
string.Empty)
482 m_log.DebugFormat(
"[GATEKEEPER SERVICE]: Agent did not provide an authentication server URL");
486 if (userURL == m_ExternalName)
488 return m_UserAgentService.VerifyAgent(aCircuit.SessionID, aCircuit.ServiceSessionID);
496 return userAgentService.VerifyAgent(aCircuit.SessionID, aCircuit.ServiceSessionID);
500 m_log.DebugFormat(
"[GATEKEEPER SERVICE]: Unable to contact authentication service at {0}", userURL);
510 string[] parts = serviceToken.Split(
new char[] {
';' });
511 if (parts.Length < 2)
514 char[] trailing_slash =
new char[] {
'/' };
515 string addressee = parts[0].TrimEnd(trailing_slash);
516 string externalname = m_ExternalName.TrimEnd(trailing_slash);
517 m_log.DebugFormat(
"[GATEKEEPER SERVICE]: Verifying {0} against {1}", addressee, externalname);
522 uri =
new Uri(addressee);
526 m_log.DebugFormat(
"[GATEKEEPER SERVICE]: Visitor provided malformed service address {0}", addressee);
530 return string.Equals(uri.GetLeftPart(UriPartial.Authority), m_Uri.GetLeftPart(UriPartial.Authority), StringComparison.OrdinalIgnoreCase) ;
538 private bool IsException(
AgentCircuitData aCircuit, List<string> exceptions)
540 bool exception =
false;
541 if (exceptions.Count > 0)
544 string userURL = aCircuit.ServiceURLs[
"HomeURI"].ToString();
545 if (!userURL.EndsWith(
"/"))
548 if (exceptions.Find(delegate(
string s)
550 if (!s.EndsWith(
"/"))
string ServiceSessionID
Hypergrid service token; generated by the user domain, consumed by the receiving grid. There is one such unique token for each grid visited.
string lastname
Agent's account last name
OpenSim.Framework.Constants.TeleportFlags TeleportFlags
GatekeeperService(IConfigSource config)
string Id0
The id0 as reported by the viewer at login
bool LoginAgent(GridRegion source, AgentCircuitData aCircuit, GridRegion destination, out string reason)
Dictionary< string, object > ServiceURLs
GatekeeperService(IConfigSource config, ISimulationService simService)
string IPAddress
The client's IP address, as captured by the login service
UUID SessionID
Non secure Session ID
string firstname
Agent's account first name
bool CheckAddress(string serviceToken)
void LoadDomainExceptionsFromConfig(IConfig config, string variable, List< string > exceptions)
bool Authenticate(AgentCircuitData aCircuit)
Circuit data for an agent. Connection information shared between regions that accept UDP connections ...
bool LinkRegion(string regionName, out UUID regionID, out ulong regionHandle, out string externalName, out string imageURL, out string reason)
string ServerURI
A well-formed URI for the host region server (namely "http://" + ExternalHostName) ...
Interactive OpenSim region server
GridRegion GetHyperlinkRegion(UUID regionID, UUID agentID, string agentHomeURI, out string message)
Returns the region a Hypergrid visitor should enter.
UUID AgentID
Avatar Unique Agent Identifier
OpenSim.Services.Interfaces.GridRegion GridRegion
uint teleportFlags
How this agent got here