aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services/LLLoginService/LLLoginService.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Services/LLLoginService/LLLoginService.cs383
1 files changed, 383 insertions, 0 deletions
diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs
new file mode 100644
index 0000000..2ae552f
--- /dev/null
+++ b/OpenSim/Services/LLLoginService/LLLoginService.cs
@@ -0,0 +1,383 @@
1using System;
2using System.Collections.Generic;
3using System.Net;
4using System.Reflection;
5using System.Text.RegularExpressions;
6
7using log4net;
8using Nini.Config;
9using OpenMetaverse;
10
11using OpenSim.Framework;
12using OpenSim.Framework.Capabilities;
13using OpenSim.Server.Base;
14using OpenSim.Services.Interfaces;
15using GridRegion = OpenSim.Services.Interfaces.GridRegion;
16
17namespace OpenSim.Services.LLLoginService
18{
19 public class LLLoginService : ILoginService
20 {
21 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
22
23 private IUserAccountService m_UserAccountService;
24 private IAuthenticationService m_AuthenticationService;
25 private IInventoryService m_InventoryService;
26 private IGridService m_GridService;
27 private IPresenceService m_PresenceService;
28 private ISimulationService m_LocalSimulationService;
29 private ISimulationService m_RemoteSimulationService;
30 private ILibraryService m_LibraryService;
31 private IAvatarService m_AvatarService;
32
33 private string m_DefaultRegionName;
34 private string m_WelcomeMessage;
35 private bool m_RequireInventory;
36
37 public LLLoginService(IConfigSource config, ISimulationService simService, ILibraryService libraryService)
38 {
39 IConfig serverConfig = config.Configs["LoginService"];
40 if (serverConfig == null)
41 throw new Exception(String.Format("No section LoginService in config file"));
42
43 string accountService = serverConfig.GetString("UserAccountService", String.Empty);
44 string authService = serverConfig.GetString("AuthenticationService", String.Empty);
45 string invService = serverConfig.GetString("InventoryService", String.Empty);
46 string gridService = serverConfig.GetString("GridService", String.Empty);
47 string presenceService = serverConfig.GetString("PresenceService", String.Empty);
48 string libService = serverConfig.GetString("LibraryService", String.Empty);
49 string avatarService = serverConfig.GetString("AvatarService", String.Empty);
50 string simulationService = serverConfig.GetString("SimulationService", String.Empty);
51
52 m_DefaultRegionName = serverConfig.GetString("DefaultRegion", String.Empty);
53 m_WelcomeMessage = serverConfig.GetString("WelcomeMessage", "Welcome to OpenSim!");
54 m_RequireInventory = serverConfig.GetBoolean("RequireInventory", true);
55
56 // These are required; the others aren't
57 if (accountService == string.Empty || authService == string.Empty)
58 throw new Exception("LoginService is missing service specifications");
59
60 Object[] args = new Object[] { config };
61 m_UserAccountService = ServerUtils.LoadPlugin<IUserAccountService>(accountService, args);
62 m_AuthenticationService = ServerUtils.LoadPlugin<IAuthenticationService>(authService, args);
63 m_InventoryService = ServerUtils.LoadPlugin<IInventoryService>(invService, args);
64 if (gridService != string.Empty)
65 m_GridService = ServerUtils.LoadPlugin<IGridService>(gridService, args);
66 if (presenceService != string.Empty)
67 m_PresenceService = ServerUtils.LoadPlugin<IPresenceService>(presenceService, args);
68 if (avatarService != string.Empty)
69 m_AvatarService = ServerUtils.LoadPlugin<IAvatarService>(avatarService, args);
70 if (simulationService != string.Empty)
71 m_RemoteSimulationService = ServerUtils.LoadPlugin<ISimulationService>(simulationService, args);
72 //
73 // deal with the services given as argument
74 //
75 m_LocalSimulationService = simService;
76 if (libraryService != null)
77 {
78 m_log.DebugFormat("[LLOGIN SERVICE]: Using LibraryService given as argument");
79 m_LibraryService = libraryService;
80 }
81 else if (libService != string.Empty)
82 {
83 m_log.DebugFormat("[LLOGIN SERVICE]: Using instantiated LibraryService");
84 m_LibraryService = ServerUtils.LoadPlugin<ILibraryService>(libService, args);
85 }
86
87 m_log.DebugFormat("[LLOGIN SERVICE]: Starting...");
88
89 }
90
91 public LLLoginService(IConfigSource config) : this(config, null, null)
92 {
93 }
94
95 public LoginResponse Login(string firstName, string lastName, string passwd, string startLocation, IPEndPoint clientIP)
96 {
97 bool success = false;
98 UUID session = UUID.Random();
99
100 try
101 {
102 // Get the account and check that it exists
103 UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero, firstName, lastName);
104 if (account == null)
105 {
106 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: user not found");
107 return LLFailedLoginResponse.UserProblem;
108 }
109
110 // Authenticate this user
111 if (!passwd.StartsWith("$1$"))
112 passwd = "$1$" + Util.Md5Hash(passwd);
113 passwd = passwd.Remove(0, 3); //remove $1$
114 string token = m_AuthenticationService.Authenticate(account.PrincipalID, passwd, 30);
115 UUID secureSession = UUID.Zero;
116 if ((token == string.Empty) || (token != string.Empty && !UUID.TryParse(token, out secureSession)))
117 {
118 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: authentication failed");
119 return LLFailedLoginResponse.UserProblem;
120 }
121
122 // Get the user's inventory
123 if (m_RequireInventory && m_InventoryService == null)
124 {
125 m_log.WarnFormat("[LLOGIN SERVICE]: Login failed, reason: inventory service not set up");
126 return LLFailedLoginResponse.InventoryProblem;
127 }
128 List<InventoryFolderBase> inventorySkel = m_InventoryService.GetInventorySkeleton(account.PrincipalID);
129 if (m_RequireInventory && ((inventorySkel == null) || (inventorySkel != null && inventorySkel.Count == 0)))
130 {
131 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: unable to retrieve user inventory");
132 return LLFailedLoginResponse.InventoryProblem;
133 }
134
135 // Login the presence
136 // We may want to check for user already logged in, to
137 // stay compatible with what people expect...
138 PresenceInfo presence = null;
139 GridRegion home = null;
140 if (m_PresenceService != null)
141 {
142 success = m_PresenceService.LoginAgent(account.PrincipalID.ToString(), session, secureSession);
143 if (!success)
144 {
145 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: could not login presence");
146 return LLFailedLoginResponse.GridProblem;
147 }
148
149 // Get the updated presence info
150 presence = m_PresenceService.GetAgent(session);
151
152 // Get the home region
153 if ((presence.HomeRegionID != UUID.Zero) && m_GridService != null)
154 {
155 home = m_GridService.GetRegionByUUID(account.ScopeID, presence.HomeRegionID);
156 }
157 }
158
159 // Find the destination region/grid
160 string where = string.Empty;
161 Vector3 position = Vector3.Zero;
162 Vector3 lookAt = Vector3.Zero;
163 GridRegion destination = FindDestination(account, presence, session, startLocation, out where, out position, out lookAt);
164 if (destination == null)
165 {
166 m_PresenceService.LogoutAgent(session);
167 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: destination not found");
168 return LLFailedLoginResponse.GridProblem;
169 }
170
171 // Get the avatar
172 AvatarData avatar = null;
173 if (m_AvatarService != null)
174 {
175 avatar = m_AvatarService.GetAvatar(account.PrincipalID);
176 }
177
178 // Instantiate/get the simulation interface and launch an agent at the destination
179 ISimulationService simConnector = null;
180 string reason = string.Empty;
181 uint circuitCode = 0;
182 AgentCircuitData aCircuit = null;
183 Object[] args = new Object[] { destination };
184 // HG standalones have both a localSimulatonDll and a remoteSimulationDll
185 // non-HG standalones have just a localSimulationDll
186 // independent login servers have just a remoteSimulationDll
187 if (!startLocation.Contains("@") && (m_LocalSimulationService != null))
188 simConnector = m_LocalSimulationService;
189 else if (m_RemoteSimulationService != null)
190 simConnector = m_RemoteSimulationService;
191 if (simConnector != null)
192 {
193 circuitCode = (uint)Util.RandomClass.Next(); ;
194 aCircuit = LaunchAgent(simConnector, destination, account, avatar, session, secureSession, circuitCode, position, out reason);
195 }
196 if (aCircuit == null)
197 {
198 m_PresenceService.LogoutAgent(session);
199 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: {0}", reason);
200 return LLFailedLoginResponse.AuthorizationProblem;
201 }
202
203 // TODO: Get Friends list...
204
205 // Finally, fill out the response and return it
206 LLLoginResponse response = new LLLoginResponse(account, aCircuit, presence, destination, inventorySkel, m_LibraryService,
207 where, startLocation, position, lookAt, m_WelcomeMessage, home, clientIP);
208
209 return response;
210 }
211 catch (Exception e)
212 {
213 m_log.WarnFormat("[LLOGIN SERVICE]: Exception processing login for {0} {1}: {2}", firstName, lastName, e.StackTrace);
214 if (m_PresenceService != null)
215 m_PresenceService.LogoutAgent(session);
216 return LLFailedLoginResponse.InternalError;
217 }
218 }
219
220 private GridRegion FindDestination(UserAccount account, PresenceInfo pinfo, UUID sessionID, string startLocation, out string where, out Vector3 position, out Vector3 lookAt)
221 {
222 m_log.DebugFormat("[LLOGIN SERVICE]: FindDestination for start location {0}", startLocation);
223
224 where = "home";
225 position = new Vector3(128, 128, 0);
226 lookAt = new Vector3(0, 1, 0);
227 if (startLocation.Equals("home"))
228 {
229 // logging into home region
230 if (m_PresenceService == null || m_GridService == null)
231 return null;
232
233 if (pinfo == null)
234 return null;
235
236 GridRegion region = null;
237
238 if (pinfo.HomeRegionID.Equals(UUID.Zero))
239 {
240 if (m_DefaultRegionName != string.Empty)
241 {
242 region = m_GridService.GetRegionByName(account.ScopeID, m_DefaultRegionName);
243 where = "safe";
244 }
245 else
246 m_log.WarnFormat("[LLOGIN SERVICE]: User {0} {1} does not have a home set and this grid does not have a default location." +
247 "Please specify DefaultRegion in [LoginService]", account.FirstName, account.LastName);
248 }
249 else
250 region = m_GridService.GetRegionByUUID(account.ScopeID, pinfo.HomeRegionID);
251
252 return region;
253 }
254 else if (startLocation.Equals("last"))
255 {
256 // logging into last visited region
257 where = "last";
258 if (m_PresenceService == null || m_GridService == null)
259 return null;
260
261 if (pinfo == null)
262 return null;
263
264 GridRegion region = null;
265
266 if (pinfo.RegionID.Equals(UUID.Zero))
267 {
268 region = m_GridService.GetRegionByName(account.ScopeID, m_DefaultRegionName);
269 where = "safe";
270 }
271 else
272 {
273 region = m_GridService.GetRegionByUUID(account.ScopeID, pinfo.RegionID);
274 position = pinfo.Position;
275 lookAt = pinfo.LookAt;
276 }
277 return region;
278
279 }
280 else
281 {
282 // free uri form
283 // e.g. New Moon&135&46 New Moon@osgrid.org:8002&153&34
284 where = "url";
285 Regex reURI = new Regex(@"^uri:(?<region>[^&]+)&(?<x>\d+)&(?<y>\d+)&(?<z>\d+)$");
286 Match uriMatch = reURI.Match(startLocation);
287 if (uriMatch == null)
288 {
289 m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, but can't process it", startLocation);
290 return null;
291 }
292 else
293 {
294 position = new Vector3(float.Parse(uriMatch.Groups["x"].Value),
295 float.Parse(uriMatch.Groups["y"].Value),
296 float.Parse(uriMatch.Groups["z"].Value));
297
298 string regionName = uriMatch.Groups["region"].ToString();
299 if (regionName != null)
300 {
301 if (!regionName.Contains("@"))
302 {
303 if (m_GridService == null)
304 return null;
305
306 List<GridRegion> regions = m_GridService.GetRegionsByName(account.ScopeID, regionName, 1);
307 if ((regions == null) || (regions != null && regions.Count == 0))
308 {
309 m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, can't locate region {1}", startLocation, regionName);
310 return null;
311 }
312 return regions[0];
313 }
314 else
315 {
316 string[] parts = regionName.Split(new char[] { '@' });
317 if (parts.Length < 2)
318 {
319 m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, can't locate region {1}", startLocation, regionName);
320 return null;
321 }
322 // Valid specification of a remote grid
323 regionName = parts[0];
324 string domainLocator = parts[1];
325 parts = domainLocator.Split(new char[] {':'});
326 string domainName = parts[0];
327 uint port = 0;
328 if (parts.Length > 1)
329 UInt32.TryParse(parts[1], out port);
330 GridRegion region = new GridRegion();
331 region.ExternalHostName = domainName;
332 region.HttpPort = port;
333 region.RegionName = regionName;
334 return region;
335 }
336
337 }
338 else
339 {
340 if (m_PresenceService == null || m_GridService == null)
341 return null;
342
343 return m_GridService.GetRegionByName(account.ScopeID, m_DefaultRegionName);
344
345 }
346 }
347 //response.LookAt = "[r0,r1,r0]";
348 //// can be: last, home, safe, url
349 //response.StartLocation = "url";
350
351 }
352
353 }
354
355 private AgentCircuitData LaunchAgent(ISimulationService simConnector, GridRegion region, UserAccount account,
356 AvatarData avatar, UUID session, UUID secureSession, uint circuit, Vector3 position, out string reason)
357 {
358 reason = string.Empty;
359 AgentCircuitData aCircuit = new AgentCircuitData();
360
361 aCircuit.AgentID = account.PrincipalID;
362 if (avatar != null)
363 aCircuit.Appearance = avatar.ToAvatarAppearance();
364 //aCircuit.BaseFolder = irrelevant
365 aCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
366 aCircuit.child = false; // the first login agent is root
367 aCircuit.ChildrenCapSeeds = new Dictionary<ulong, string>();
368 aCircuit.circuitcode = circuit;
369 aCircuit.firstname = account.FirstName;
370 //aCircuit.InventoryFolder = irrelevant
371 aCircuit.lastname = account.LastName;
372 aCircuit.SecureSessionID = secureSession;
373 aCircuit.SessionID = session;
374 aCircuit.startpos = position;
375
376 if (simConnector.CreateAgent(region, aCircuit, 0, out reason))
377 return aCircuit;
378
379 return null;
380
381 }
382 }
383}