OpenSimulator Internals/Code Map/ROBUST/GatekeeperService
OpenSimulator Internals/Code Map/ROBUST/GatekeeperService
[edit]Overview
[edit]GatekeeperService is the HyperGrid entry point for a grid. It handles inbound teleport requests from foreign grids and local-grid login requests that go through the HG path. It authenticates the visiting agent, checks access policy, and launches the agent at the destination region.
Source file:
OpenSim/Services/HypergridService/GatekeeperService.cs
Constructor and Config Loading
[edit]GatekeeperService(IConfigSource config, ISimulationService simService)
[GatekeeperService] section is required -- throws if absent.
All static fields are initialized once (m_Initialized flag). Subsequent instantiations are no-ops.
Services loaded from [GatekeeperService]:
| Key | Interface | Required |
|---|---|---|
| GridService | IGridService | Yes -- throws if empty |
| PresenceService | IPresenceService | Yes -- throws if empty |
| SimulationService | ISimulationService | Yes -- throws if null after loading |
| UserAccountService | IUserAccountService | No |
| UserAgentService | IUserAgentService | No |
| GridUserService | IGridUserService | No |
| BansService | IBansService | No |
simService argument takes precedence over SimulationService config key if non-null.
Additional config:
| Section | Key | Default | Notes |
|---|---|---|---|
| [GatekeeperService] | ScopeID | UUID.Zero | Grid scope filter |
| [GatekeeperService] | AllowTeleportsToAnyRegion | true | If false, all inbound TPs go to the default HG region |
| [Const]/[Startup]/[Hypergrid]/[GatekeeperService] | GatekeeperURI | (none) | External URL of this gatekeeper; also tries ExternalName |
| [Const]/[Startup]/[Hypergrid]/[GatekeeperService] | GatekeeperURIAlias | (none) | Comma-separated list of alternate hostnames accepted as this grid |
| [GatekeeperService] | ForeignAgentsAllowed | true | Whether visitors from other grids are permitted |
| [GatekeeperService] | AllowExcept | (none) | Comma-separated HomeURIs excluded from ForeignAgentsAllowed=true |
| [GatekeeperService] | DisallowExcept | (none) | Comma-separated HomeURIs excluded from ForeignAgentsAllowed=false |
| [AccessControl]/[GatekeeperService] | AllowedClients | (none) | Regex matched against viewer string |
| [AccessControl]/[GatekeeperService] | DeniedClients | (none) | Regex matched against viewer string |
| [AccessControl]/[GatekeeperService] | DeniedMacs | (none) | Case-insensitive substring match against MAC |
| [AccessControl]/[GatekeeperService] | DeniedID0s | (none) | Case-insensitive substring match against id0 |
| [PresenceService] | AllowDuplicatePresences | false | If false, kick existing session on duplicate login |
| [Messaging] | MessageKey | (none) | Auth key for InstantMessage service |
GatekeeperURI is resolved at startup via OSHHTPHost. Throws if the hostname cannot be resolved or is invalid.
GatekeeperURIAlias entries are parsed but not resolved (IsValidHost only, not IsResolvedHost) -- allows aliases that may not be locally resolvable.
AllowedClients and DeniedClients regex compilation failures are caught and logged; the regex is set to null (check skipped).
LinkLocalRegion()
[edit]public bool LinkLocalRegion(string regionName, out UUID regionID, out ulong regionHandle,
out string externalName, out string imageURL, out string reason, out int sizeX, out int sizeY)
Called by a foreign grid that wants to link to a region on this grid.
If AllowTeleportsToAnyRegion = false or regionName is empty:
- Returns the first result from GridService.GetDefaultHypergridRegions()
- Caches it as m_DefaultGatewayRegion
- Returns false with an error reason if no default HG regions exist
Otherwise:
- Calls GridService.GetLocalRegionByName() -- returns false if not found
On success: populates regionID, regionHandle, sizeX, sizeY, externalName (gatekeeperURL + region name), imageURL (region ServerURI + index.php?method=regionImage{uuid}).
GetHyperlinkRegion()
[edit]public GridRegion GetHyperlinkRegion(UUID regionID, UUID agentID, string agentHomeURI, out string message)
Returns the GridRegion descriptor for a given regionID. Called by foreign grids after LinkLocalRegion to get the full region record.
If AllowTeleportsToAnyRegion = false: returns m_DefaultGatewayRegion regardless of regionID.
Otherwise: calls GridService.GetRegionByUUID(). Returns null with message if not found.
LoginAgent()
[edit]public bool LoginAgent(GridRegion source, AgentCircuitData aCircuit, GridRegion destination, out string reason)
Main inbound HG agent entry point. Returns false with a reason string on any failure.
Sequence:
- Client checks (same pattern as LLLoginService):
- AllowedClientsRegex -- viewer string must match if set
- DeniedClientsRegex -- viewer string must not match if set
- DeniedMacs -- MAC must not appear as case-insensitive substring
- DeniedID0s -- id0 must not appear as case-insensitive substring
- Authentication via Authenticate():
- Verifies ServiceSessionID was issued for this grid (CheckAddress)
- Verifies agent IP address is present
- Calls UserAgentService.VerifyAgent() -- uses local service if HomeURI matches this grid, else instantiates a remote UserAgentServiceConnector
- Returns false ("Unable to verify identity") on failure
- Impersonation check (if UserAccountService configured):
- Looks up aCircuit.AgentID in local UserAccounts
- If found AND UserAgentService configured: calls IsAgentComingHome() -- if false, agent UUID collides with a local account but is not actually that user; refuses with "Unauthorized"
- Foreign agent policy (if account is null, i.e. visitor):
- Starts with m_ForeignAgentsAllowed
- If allowed AND HomeURI is in AllowExcept list: set allowed = false
- If not allowed AND HomeURI is in DisallowExcept list: set allowed = true
- Returns false ("Destination does not allow visitors from your world") if not allowed
- Ban check via BansService.IsBanned(uui, IPAddress, Id0, authURL) if configured
- God account check: aCircuit.AgentID == Constants.servicesGodAgentID -- refuses with "Invalid account ID"
- Duplicate presence check (if GridUserService configured and AllowDuplicatePresences = false):
- Gets GridUserInfo for the UUI
- If online with known last region: calls SendAgentGodKillToRegion(), returns false
- Presence handling:
- Calls PresenceService.GetAgent(sessionID)
- If found: isFirstLogin = true (presence was placed by LLLoginService -- this is a local user logging into HG)
- If not found: calls PresenceService.LoginAgent() -- fails if this also fails
- Destination verification: GridService.GetRegionByUUID() -- returns false if not found
- Name adjustment:
- Local user: name taken from UserAccount record
- Foreign user without "@" suffix: firstname becomes "firstname.lastname", lastname becomes "@authority-of-HomeURI"
- Agent launch:
- SimulationService.QueryAccess() -- returns false on rejection
- SimulationService.CreateAgent() with ViaLogin (first login) or ViaHGLogin (HG transfer) flag, OR'd with existing teleport flags
- On success: if not first login and GridUserService configured and account is null (foreign visitor), calls GridUserService.LoggedIn() with a composite UUI string: agentID + ";" + HomeURI + ";" + firstname + " " + lastname
Authenticate()
[edit]protected bool Authenticate(AgentCircuitData aCircuit)
Two-step check:
CheckAddress(ServiceSessionID):
- Splits ServiceSessionID on ";"
- Parses first part as a grid URL
- Checks it against m_gatekeeperHost and m_gateKeeperAlias
- Returns false if it doesn't match -- this grid did not issue the token
VerifyAgent:
- If HomeURI resolves to this grid: uses local m_UserAgentService.VerifyAgent()
- Otherwise: instantiates a UserAgentServiceConnector for the foreign HomeURI and calls VerifyAgent() remotely
- Connection failures are caught and return false
SendAgentGodKillToRegion()
[edit]Same pattern as LLLoginService. Sends a god-kick InstantMessage (dialog = 250) from Constants.servicesGodAgentID to the agent's last known region. Calls GridUserService.LoggedOut() after sending. Returns false if the region cannot be found or has no ServerURI.
Notes
[edit]- All service references are static -- shared across all instances. The m_Initialized flag means only the first construction does any work.
- Foreign visitors get a composite UUI (agentID;HomeURI;name) logged to GridUser, not just a plain UUID.
- Direct HG login via URI with "@" in region name is not handled here -- that path was removed from LLLoginService and is not present in GatekeeperService.
- The AllowExcept/DisallowExcept lists provide per-grid overrides of the ForeignAgentsAllowed policy. Matching is exact string comparison on the HomeURI (trailing slash normalized).
- isFirstLogin logic is inverted from the variable name: the variable is set to true when the presence already exists (placed by the login service), meaning this is a local-grid user going HG outbound for the first time, not a returning foreign visitor.