aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services/HypergridService/GatekeeperService.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Services/HypergridService/GatekeeperService.cs')
-rw-r--r--OpenSim/Services/HypergridService/GatekeeperService.cs322
1 files changed, 322 insertions, 0 deletions
diff --git a/OpenSim/Services/HypergridService/GatekeeperService.cs b/OpenSim/Services/HypergridService/GatekeeperService.cs
new file mode 100644
index 0000000..c5cfe75
--- /dev/null
+++ b/OpenSim/Services/HypergridService/GatekeeperService.cs
@@ -0,0 +1,322 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Net;
31using System.Reflection;
32
33using OpenSim.Framework;
34using OpenSim.Services.Interfaces;
35using GridRegion = OpenSim.Services.Interfaces.GridRegion;
36using OpenSim.Server.Base;
37using OpenSim.Services.Connectors.Hypergrid;
38
39using OpenMetaverse;
40
41using Nini.Config;
42using log4net;
43
44namespace OpenSim.Services.HypergridService
45{
46 public class GatekeeperService : IGatekeeperService
47 {
48 private static readonly ILog m_log =
49 LogManager.GetLogger(
50 MethodBase.GetCurrentMethod().DeclaringType);
51
52 IGridService m_GridService;
53 IPresenceService m_PresenceService;
54 IUserAccountService m_UserAccountService;
55 IUserAgentService m_UserAgentService;
56 ISimulationService m_SimulationService;
57
58 string m_AuthDll;
59
60 UUID m_ScopeID;
61 bool m_AllowTeleportsToAnyRegion;
62 string m_ExternalName;
63 GridRegion m_DefaultGatewayRegion;
64
65 public GatekeeperService(IConfigSource config, ISimulationService simService)
66 {
67 IConfig serverConfig = config.Configs["GatekeeperService"];
68 if (serverConfig == null)
69 throw new Exception(String.Format("No section GatekeeperService in config file"));
70
71 string accountService = serverConfig.GetString("UserAccountService", String.Empty);
72 string homeUsersService = serverConfig.GetString("HomeUsersSecurityService", string.Empty);
73 string gridService = serverConfig.GetString("GridService", String.Empty);
74 string presenceService = serverConfig.GetString("PresenceService", String.Empty);
75 string simulationService = serverConfig.GetString("SimulationService", String.Empty);
76
77 //m_AuthDll = serverConfig.GetString("AuthenticationService", String.Empty);
78
79 // These 3 are mandatory, the others aren't
80 if (gridService == string.Empty || presenceService == string.Empty || m_AuthDll == string.Empty)
81 throw new Exception("Incomplete specifications, Gatekeeper Service cannot function.");
82
83 string scope = serverConfig.GetString("ScopeID", UUID.Zero.ToString());
84 UUID.TryParse(scope, out m_ScopeID);
85 //m_WelcomeMessage = serverConfig.GetString("WelcomeMessage", "Welcome to OpenSim!");
86 m_AllowTeleportsToAnyRegion = serverConfig.GetBoolean("AllowTeleportsToAnyRegion", true);
87 m_ExternalName = serverConfig.GetString("ExternalName", string.Empty);
88
89 Object[] args = new Object[] { config };
90 m_GridService = ServerUtils.LoadPlugin<IGridService>(gridService, args);
91 m_PresenceService = ServerUtils.LoadPlugin<IPresenceService>(presenceService, args);
92
93 if (accountService != string.Empty)
94 m_UserAccountService = ServerUtils.LoadPlugin<IUserAccountService>(accountService, args);
95 if (homeUsersService != string.Empty)
96 m_UserAgentService = ServerUtils.LoadPlugin<IUserAgentService>(homeUsersService, args);
97
98 if (simService != null)
99 m_SimulationService = simService;
100 else if (simulationService != string.Empty)
101 m_SimulationService = ServerUtils.LoadPlugin<ISimulationService>(simulationService, args);
102
103 if (m_GridService == null || m_PresenceService == null || m_SimulationService == null)
104 throw new Exception("Unable to load a required plugin, Gatekeeper Service cannot function.");
105
106 m_log.Debug("[GATEKEEPER SERVICE]: Starting...");
107 }
108
109 public GatekeeperService(IConfigSource config)
110 : this(config, null)
111 {
112 }
113
114 public bool LinkRegion(string regionName, out UUID regionID, out ulong regionHandle, out string externalName, out string imageURL, out string reason)
115 {
116 regionID = UUID.Zero;
117 regionHandle = 0;
118 externalName = m_ExternalName;
119 imageURL = string.Empty;
120 reason = string.Empty;
121
122
123 m_log.DebugFormat("[GATEKEEPER SERVICE]: Request to link to {0}", (regionName == string.Empty)? "default region" : regionName);
124 if (!m_AllowTeleportsToAnyRegion || regionName == string.Empty)
125 {
126 List<GridRegion> defs = m_GridService.GetDefaultRegions(m_ScopeID);
127 if (defs != null && defs.Count > 0)
128 m_DefaultGatewayRegion = defs[0];
129
130 try
131 {
132 regionID = m_DefaultGatewayRegion.RegionID;
133 regionHandle = m_DefaultGatewayRegion.RegionHandle;
134 }
135 catch
136 {
137 reason = "Grid setup problem. Try specifying a particular region here.";
138 m_log.DebugFormat("[GATEKEEPER SERVICE]: Unable to send information. Please specify a default region for this grid!");
139 return false;
140 }
141
142 return true;
143 }
144
145 GridRegion region = m_GridService.GetRegionByName(m_ScopeID, regionName);
146 if (region == null)
147 {
148 reason = "Region not found";
149 return false;
150 }
151
152 regionID = region.RegionID;
153 regionHandle = region.RegionHandle;
154 string regionimage = "regionImage" + region.RegionID.ToString();
155 regionimage = regionimage.Replace("-", "");
156
157 imageURL = "http://" + region.ExternalHostName + ":" + region.HttpPort + "/index.php?method=" + regionimage;
158
159 return true;
160 }
161
162 public GridRegion GetHyperlinkRegion(UUID regionID)
163 {
164 m_log.DebugFormat("[GATEKEEPER SERVICE]: Request to get hyperlink region {0}", regionID);
165
166 if (!m_AllowTeleportsToAnyRegion)
167 // Don't even check the given regionID
168 return m_DefaultGatewayRegion;
169
170 GridRegion region = m_GridService.GetRegionByUUID(m_ScopeID, regionID);
171 return region;
172 }
173
174 #region Login Agent
175 public bool LoginAgent(AgentCircuitData aCircuit, GridRegion destination, out string reason)
176 {
177 reason = string.Empty;
178
179 string authURL = string.Empty;
180 if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
181 authURL = aCircuit.ServiceURLs["HomeURI"].ToString();
182 m_log.DebugFormat("[GATEKEEPER SERVICE]: Request to login foreign agent {0} {1} @ {2} ({3}) at destination {4}",
183 aCircuit.firstname, aCircuit.lastname, authURL, aCircuit.AgentID, destination.RegionName);
184
185 //
186 // Authenticate the user
187 //
188 if (!Authenticate(aCircuit))
189 {
190 reason = "Unable to verify identity";
191 m_log.InfoFormat("[GATEKEEPER SERVICE]: Unable to verify identity of agent {0} {1}. Refusing service.", aCircuit.firstname, aCircuit.lastname);
192 return false;
193 }
194 m_log.DebugFormat("[GATEKEEPER SERVICE]: Identity verified for {0} {1} @ {2}", aCircuit.firstname, aCircuit.lastname, authURL);
195
196 //
197 // Check for impersonations
198 //
199 UserAccount account = null;
200 if (m_UserAccountService != null)
201 {
202 // Check to see if we have a local user with that UUID
203 account = m_UserAccountService.GetUserAccount(m_ScopeID, aCircuit.AgentID);
204 if (account != null)
205 {
206 // Make sure this is the user coming home, and not a foreign user with same UUID as a local user
207 if (m_UserAgentService != null)
208 {
209 if (!m_UserAgentService.AgentIsComingHome(aCircuit.SessionID, m_ExternalName))
210 {
211 // Can't do, sorry
212 reason = "Unauthorized";
213 m_log.InfoFormat("[GATEKEEPER SERVICE]: Foreign agent {0} {1} has same ID as local user. Refusing service.",
214 aCircuit.firstname, aCircuit.lastname);
215 return false;
216
217 }
218 }
219 }
220 }
221 m_log.DebugFormat("[GATEKEEPER SERVICE]: User is ok");
222
223 // May want to authorize
224
225 //
226 // Login the presence
227 //
228 if (!m_PresenceService.LoginAgent(aCircuit.AgentID.ToString(), aCircuit.SessionID, aCircuit.SecureSessionID))
229 {
230 reason = "Unable to login presence";
231 m_log.InfoFormat("[GATEKEEPER SERVICE]: Presence login failed for foreign agent {0} {1}. Refusing service.",
232 aCircuit.firstname, aCircuit.lastname);
233 return false;
234 }
235 m_log.DebugFormat("[GATEKEEPER SERVICE]: Login presence ok");
236
237 //
238 // Get the region
239 //
240 destination = m_GridService.GetRegionByUUID(m_ScopeID, destination.RegionID);
241 if (destination == null)
242 {
243 reason = "Destination region not found";
244 return false;
245 }
246 m_log.DebugFormat("[GATEKEEPER SERVICE]: destination ok: {0}", destination.RegionName);
247
248 //
249 // Adjust the visible name
250 //
251 if (account != null)
252 {
253 aCircuit.firstname = account.FirstName;
254 aCircuit.lastname = account.LastName;
255 }
256 if (account == null && !aCircuit.lastname.StartsWith("@"))
257 {
258 aCircuit.firstname = aCircuit.firstname + "." + aCircuit.lastname;
259 aCircuit.lastname = "@" + aCircuit.ServiceURLs["HomeURI"].ToString();
260 }
261
262 //
263 // Finally launch the agent at the destination
264 //
265 return m_SimulationService.CreateAgent(destination, aCircuit, (uint)Constants.TeleportFlags.ViaLogin, out reason);
266 }
267
268 protected bool Authenticate(AgentCircuitData aCircuit)
269 {
270 if (!CheckAddress(aCircuit.ServiceSessionID))
271 return false;
272
273 string userURL = string.Empty;
274 if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
275 userURL = aCircuit.ServiceURLs["HomeURI"].ToString();
276
277 if (userURL == string.Empty)
278 {
279 m_log.DebugFormat("[GATEKEEPER SERVICE]: Agent did not provide an authentication server URL");
280 return false;
281 }
282
283 Object[] args = new Object[] { userURL };
284 IUserAgentService userAgentService = new UserAgentServiceConnector(userURL); //ServerUtils.LoadPlugin<IUserAgentService>(m_AuthDll, args);
285 if (userAgentService != null)
286 {
287 try
288 {
289 return userAgentService.VerifyAgent(aCircuit.SessionID, aCircuit.ServiceSessionID);
290 }
291 catch
292 {
293 m_log.DebugFormat("[GATEKEEPER SERVICE]: Unable to contact authentication service at {0}", userURL);
294 return false;
295 }
296 }
297
298 return false;
299 }
300
301 // Check that the service token was generated for *this* grid.
302 // If it wasn't then that's a fake agent.
303 protected bool CheckAddress(string serviceToken)
304 {
305 string[] parts = serviceToken.Split(new char[] { ';' });
306 if (parts.Length < 2)
307 return false;
308
309 string addressee = parts[0];
310 m_log.DebugFormat("[GATEKEEPER SERVICE]: Verifying {0} against {1}", addressee, m_ExternalName);
311 return (addressee == m_ExternalName);
312 }
313
314 #endregion
315
316
317 #region Misc
318
319
320 #endregion
321 }
322}