aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services/LLLoginService
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Services/LLLoginService')
-rw-r--r--OpenSim/Services/LLLoginService/LLLoginResponse.cs977
-rw-r--r--OpenSim/Services/LLLoginService/LLLoginService.cs744
2 files changed, 1721 insertions, 0 deletions
diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs
new file mode 100644
index 0000000..0cd8f5b
--- /dev/null
+++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs
@@ -0,0 +1,977 @@
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;
30using System.Collections.Generic;
31using System.Net;
32using System.Reflection;
33
34using OpenSim.Framework;
35using OpenSim.Framework.Capabilities;
36using OpenSim.Services.Interfaces;
37using GridRegion = OpenSim.Services.Interfaces.GridRegion;
38using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
39
40using log4net;
41using OpenMetaverse;
42using OpenMetaverse.StructuredData;
43using OSDArray = OpenMetaverse.StructuredData.OSDArray;
44using OSDMap = OpenMetaverse.StructuredData.OSDMap;
45
46namespace OpenSim.Services.LLLoginService
47{
48 public class LLFailedLoginResponse : OpenSim.Services.Interfaces.FailedLoginResponse
49 {
50 protected string m_key;
51 protected string m_value;
52 protected string m_login;
53
54 public static LLFailedLoginResponse UserProblem;
55 public static LLFailedLoginResponse AuthorizationProblem;
56 public static LLFailedLoginResponse GridProblem;
57 public static LLFailedLoginResponse InventoryProblem;
58 public static LLFailedLoginResponse DeadRegionProblem;
59 public static LLFailedLoginResponse LoginBlockedProblem;
60 public static LLFailedLoginResponse UnverifiedAccountProblem;
61 public static LLFailedLoginResponse AlreadyLoggedInProblem;
62 public static LLFailedLoginResponse InternalError;
63
64 static LLFailedLoginResponse()
65 {
66 UserProblem = new LLFailedLoginResponse("key",
67 "Could not authenticate your avatar. Please check your username and password, and check the grid if problems persist.",
68 "false");
69 AuthorizationProblem = new LLFailedLoginResponse("key",
70 "Error connecting to grid. Unable to authorize your session into the region.",
71 "false");
72 GridProblem = new LLFailedLoginResponse("key",
73 "Error connecting to the desired location. Try connecting to another region.",
74 "false");
75 InventoryProblem = new LLFailedLoginResponse("key",
76 "The inventory service is not responding. Please notify your login region operator.",
77 "false");
78 DeadRegionProblem = new LLFailedLoginResponse("key",
79 "The region you are attempting to log into is not responding. Please select another region and try again.",
80 "false");
81 LoginBlockedProblem = new LLFailedLoginResponse("presence",
82 "Logins are currently restricted. Please try again later.",
83 "false");
84 UnverifiedAccountProblem = new LLFailedLoginResponse("presence",
85 "Your account has not yet been verified. Please check " +
86 "your email and click the provided link.",
87 "false");
88 AlreadyLoggedInProblem = new LLFailedLoginResponse("presence",
89 "You appear to be already logged in. " +
90 "If this is not the case please wait for your session to timeout. " +
91 "If this takes longer than a few minutes please contact the grid owner. " +
92 "Please wait 5 minutes if you are going to connect to a region nearby to the region you were at previously.",
93 "false");
94 InternalError = new LLFailedLoginResponse("Internal Error", "Error generating Login Response", "false");
95 }
96
97 public LLFailedLoginResponse(string key, string value, string login)
98 {
99 m_key = key;
100 m_value = value;
101 m_login = login;
102 }
103
104 public override Hashtable ToHashtable()
105 {
106 Hashtable loginError = new Hashtable();
107 loginError["reason"] = m_key;
108 loginError["message"] = m_value;
109 loginError["login"] = m_login;
110 return loginError;
111 }
112
113 public override OSD ToOSDMap()
114 {
115 OSDMap map = new OSDMap();
116
117 map["reason"] = OSD.FromString(m_key);
118 map["message"] = OSD.FromString(m_value);
119 map["login"] = OSD.FromString(m_login);
120
121 return map;
122 }
123 }
124
125 /// <summary>
126 /// A class to handle LL login response.
127 /// </summary>
128 public class LLLoginResponse : OpenSim.Services.Interfaces.LoginResponse
129 {
130 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
131 private static Hashtable globalTexturesHash;
132 // Global Textures
133 private static string sunTexture = "cce0f112-878f-4586-a2e2-a8f104bba271";
134 private static string cloudTexture = "dc4b9f0b-d008-45c6-96a4-01dd947ac621";
135 private static string moonTexture = "ec4b9f0b-d008-45c6-96a4-01dd947ac621";
136
137 private Hashtable loginFlagsHash;
138 private Hashtable uiConfigHash;
139
140 private ArrayList loginFlags;
141 private ArrayList globalTextures;
142 private ArrayList eventCategories;
143 private ArrayList uiConfig;
144 private ArrayList classifiedCategories;
145 private ArrayList inventoryRoot;
146 private ArrayList initialOutfit;
147 private ArrayList agentInventory;
148 private ArrayList inventoryLibraryOwner;
149 private ArrayList inventoryLibRoot;
150 private ArrayList inventoryLibrary;
151 private ArrayList activeGestures;
152
153 private UserInfo userProfile;
154
155 private UUID agentID;
156 private UUID sessionID;
157 private UUID secureSessionID;
158
159 // Login Flags
160 private string dst;
161 private string stipendSinceLogin;
162 private string gendered;
163 private string everLoggedIn;
164 private string login;
165 private uint simPort;
166 private uint simHttpPort;
167 private string simAddress;
168 private string agentAccess;
169 private string agentAccessMax;
170 private Int32 circuitCode;
171 private uint regionX;
172 private uint regionY;
173
174 // Login
175 private string firstname;
176 private string lastname;
177
178 // Error Flags
179 private string errorReason;
180 private string errorMessage;
181
182 private string welcomeMessage;
183 private string startLocation;
184 private string allowFirstLife;
185 private string home;
186 private string seedCapability;
187 private string lookAt;
188
189 private BuddyList m_buddyList = null;
190
191 static LLLoginResponse()
192 {
193 // This is being set, but it's not used
194 // not sure why.
195 globalTexturesHash = new Hashtable();
196 globalTexturesHash["sun_texture_id"] = sunTexture;
197 globalTexturesHash["cloud_texture_id"] = cloudTexture;
198 globalTexturesHash["moon_texture_id"] = moonTexture;
199 }
200
201 public LLLoginResponse()
202 {
203 loginFlags = new ArrayList();
204 globalTextures = new ArrayList();
205 eventCategories = new ArrayList();
206 uiConfig = new ArrayList();
207 classifiedCategories = new ArrayList();
208
209 uiConfigHash = new Hashtable();
210
211 // defaultXmlRpcResponse = new XmlRpcResponse();
212 userProfile = new UserInfo();
213 inventoryRoot = new ArrayList();
214 initialOutfit = new ArrayList();
215 agentInventory = new ArrayList();
216 inventoryLibrary = new ArrayList();
217 inventoryLibraryOwner = new ArrayList();
218 activeGestures = new ArrayList();
219
220 SetDefaultValues();
221 }
222
223 public LLLoginResponse(UserAccount account, AgentCircuitData aCircuit, PresenceInfo pinfo,
224 GridRegion destination, List<InventoryFolderBase> invSkel, FriendInfo[] friendsList, ILibraryService libService,
225 string where, string startlocation, Vector3 position, Vector3 lookAt, string message,
226 GridRegion home, IPEndPoint clientIP)
227 : this()
228 {
229 FillOutInventoryData(invSkel, libService);
230
231 CircuitCode = (int)aCircuit.circuitcode;
232 Lastname = account.LastName;
233 Firstname = account.FirstName;
234 AgentID = account.PrincipalID;
235 SessionID = aCircuit.SessionID;
236 SecureSessionID = aCircuit.SecureSessionID;
237 Message = message;
238 BuddList = ConvertFriendListItem(friendsList);
239 StartLocation = where;
240
241 FillOutHomeData(pinfo, home);
242 LookAt = String.Format("[r{0},r{1},r{2}]", lookAt.X, lookAt.Y, lookAt.Z);
243
244 FillOutRegionData(destination);
245
246 FillOutSeedCap(aCircuit, destination, clientIP);
247
248 }
249
250 private void FillOutInventoryData(List<InventoryFolderBase> invSkel, ILibraryService libService)
251 {
252 InventoryData inventData = null;
253
254 try
255 {
256 inventData = GetInventorySkeleton(invSkel);
257 }
258 catch (Exception e)
259 {
260 m_log.WarnFormat(
261 "[LLLOGIN SERVICE]: Error processing inventory skeleton of agent {0} - {1}",
262 agentID, e);
263
264 // ignore and continue
265 }
266
267 if (inventData != null)
268 {
269 ArrayList AgentInventoryArray = inventData.InventoryArray;
270
271 Hashtable InventoryRootHash = new Hashtable();
272 InventoryRootHash["folder_id"] = inventData.RootFolderID.ToString();
273 InventoryRoot = new ArrayList();
274 InventoryRoot.Add(InventoryRootHash);
275 InventorySkeleton = AgentInventoryArray;
276 }
277
278 // Inventory Library Section
279 if (libService != null && libService.LibraryRootFolder != null)
280 {
281 Hashtable InventoryLibRootHash = new Hashtable();
282 InventoryLibRootHash["folder_id"] = "00000112-000f-0000-0000-000100bba000";
283 InventoryLibRoot = new ArrayList();
284 InventoryLibRoot.Add(InventoryLibRootHash);
285
286 InventoryLibraryOwner = GetLibraryOwner(libService.LibraryRootFolder);
287 InventoryLibrary = GetInventoryLibrary(libService);
288 }
289 }
290
291 private void FillOutHomeData(PresenceInfo pinfo, GridRegion home)
292 {
293 int x = 1000 * (int)Constants.RegionSize, y = 1000 * (int)Constants.RegionSize;
294 if (home != null)
295 {
296 x = home.RegionLocX;
297 y = home.RegionLocY;
298 }
299
300 Home = string.Format(
301 "{{'region_handle':[r{0},r{1}], 'position':[r{2},r{3},r{4}], 'look_at':[r{5},r{6},r{7}]}}",
302 x,
303 y,
304 pinfo.HomePosition.X, pinfo.HomePosition.Y, pinfo.HomePosition.Z,
305 pinfo.HomeLookAt.X, pinfo.HomeLookAt.Y, pinfo.HomeLookAt.Z);
306
307 }
308
309 private void FillOutRegionData(GridRegion destination)
310 {
311 IPEndPoint endPoint = destination.ExternalEndPoint;
312 SimAddress = endPoint.Address.ToString();
313 SimPort = (uint)endPoint.Port;
314 RegionX = (uint)destination.RegionLocX;
315 RegionY = (uint)destination.RegionLocY;
316 }
317
318 private void FillOutSeedCap(AgentCircuitData aCircuit, GridRegion destination, IPEndPoint ipepClient)
319 {
320 string capsSeedPath = String.Empty;
321
322 // Don't use the following! It Fails for logging into any region not on the same port as the http server!
323 // Kept here so it doesn't happen again!
324 // response.SeedCapability = regionInfo.ServerURI + capsSeedPath;
325
326 #region IP Translation for NAT
327 if (ipepClient != null)
328 {
329 capsSeedPath
330 = "http://"
331 + NetworkUtil.GetHostFor(ipepClient.Address, destination.ExternalHostName)
332 + ":"
333 + destination.HttpPort
334 + CapsUtil.GetCapsSeedPath(aCircuit.CapsPath);
335 }
336 else
337 {
338 capsSeedPath
339 = "http://"
340 + destination.ExternalHostName
341 + ":"
342 + destination.HttpPort
343 + CapsUtil.GetCapsSeedPath(aCircuit.CapsPath);
344 }
345 #endregion
346
347 SeedCapability = capsSeedPath;
348 }
349
350 private void SetDefaultValues()
351 {
352 DST = TimeZone.CurrentTimeZone.IsDaylightSavingTime(DateTime.Now) ? "Y" : "N";
353 StipendSinceLogin = "N";
354 Gendered = "Y";
355 EverLoggedIn = "Y";
356 login = "false";
357 firstname = "Test";
358 lastname = "User";
359 agentAccess = "M";
360 agentAccessMax = "A";
361 startLocation = "last";
362 allowFirstLife = "Y";
363
364 ErrorMessage = "You have entered an invalid name/password combination. Check Caps/lock.";
365 ErrorReason = "key";
366 welcomeMessage = "Welcome to OpenSim!";
367 seedCapability = String.Empty;
368 home = "{'region_handle':[r" + (1000*Constants.RegionSize).ToString() + ",r" + (1000*Constants.RegionSize).ToString() + "], 'position':[r" +
369 userProfile.homepos.X.ToString() + ",r" + userProfile.homepos.Y.ToString() + ",r" +
370 userProfile.homepos.Z.ToString() + "], 'look_at':[r" + userProfile.homelookat.X.ToString() + ",r" +
371 userProfile.homelookat.Y.ToString() + ",r" + userProfile.homelookat.Z.ToString() + "]}";
372 lookAt = "[r0.99949799999999999756,r0.03166859999999999814,r0]";
373 RegionX = (uint) 255232;
374 RegionY = (uint) 254976;
375
376 // Classifieds;
377 AddClassifiedCategory((Int32) 1, "Shopping");
378 AddClassifiedCategory((Int32) 2, "Land Rental");
379 AddClassifiedCategory((Int32) 3, "Property Rental");
380 AddClassifiedCategory((Int32) 4, "Special Attraction");
381 AddClassifiedCategory((Int32) 5, "New Products");
382 AddClassifiedCategory((Int32) 6, "Employment");
383 AddClassifiedCategory((Int32) 7, "Wanted");
384 AddClassifiedCategory((Int32) 8, "Service");
385 AddClassifiedCategory((Int32) 9, "Personal");
386
387 SessionID = UUID.Random();
388 SecureSessionID = UUID.Random();
389 AgentID = UUID.Random();
390
391 Hashtable InitialOutfitHash = new Hashtable();
392 InitialOutfitHash["folder_name"] = "Nightclub Female";
393 InitialOutfitHash["gender"] = "female";
394 initialOutfit.Add(InitialOutfitHash);
395 }
396
397
398 public override Hashtable ToHashtable()
399 {
400 try
401 {
402 Hashtable responseData = new Hashtable();
403
404 loginFlagsHash = new Hashtable();
405 loginFlagsHash["daylight_savings"] = DST;
406 loginFlagsHash["stipend_since_login"] = StipendSinceLogin;
407 loginFlagsHash["gendered"] = Gendered;
408 loginFlagsHash["ever_logged_in"] = EverLoggedIn;
409 loginFlags.Add(loginFlagsHash);
410
411 responseData["first_name"] = Firstname;
412 responseData["last_name"] = Lastname;
413 responseData["agent_access"] = agentAccess;
414 responseData["agent_access_max"] = agentAccessMax;
415
416 globalTextures.Add(globalTexturesHash);
417 // this.eventCategories.Add(this.eventCategoriesHash);
418
419 AddToUIConfig("allow_first_life", allowFirstLife);
420 uiConfig.Add(uiConfigHash);
421
422 responseData["sim_port"] = (Int32) SimPort;
423 responseData["sim_ip"] = SimAddress;
424 responseData["http_port"] = (Int32)SimHttpPort;
425
426 responseData["agent_id"] = AgentID.ToString();
427 responseData["session_id"] = SessionID.ToString();
428 responseData["secure_session_id"] = SecureSessionID.ToString();
429 responseData["circuit_code"] = CircuitCode;
430 responseData["seconds_since_epoch"] = (Int32) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
431 responseData["login-flags"] = loginFlags;
432 responseData["global-textures"] = globalTextures;
433 responseData["seed_capability"] = seedCapability;
434
435 responseData["event_categories"] = eventCategories;
436 responseData["event_notifications"] = new ArrayList(); // todo
437 responseData["classified_categories"] = classifiedCategories;
438 responseData["ui-config"] = uiConfig;
439
440 if (agentInventory != null)
441 {
442 responseData["inventory-skeleton"] = agentInventory;
443 responseData["inventory-root"] = inventoryRoot;
444 }
445 responseData["inventory-skel-lib"] = inventoryLibrary;
446 responseData["inventory-lib-root"] = inventoryLibRoot;
447 responseData["gestures"] = activeGestures;
448 responseData["inventory-lib-owner"] = inventoryLibraryOwner;
449 responseData["initial-outfit"] = initialOutfit;
450 responseData["start_location"] = startLocation;
451 responseData["seed_capability"] = seedCapability;
452 responseData["home"] = home;
453 responseData["look_at"] = lookAt;
454 responseData["message"] = welcomeMessage;
455 responseData["region_x"] = (Int32)(RegionX);
456 responseData["region_y"] = (Int32)(RegionY);
457
458 if (m_buddyList != null)
459 {
460 responseData["buddy-list"] = m_buddyList.ToArray();
461 }
462
463 responseData["login"] = "true";
464
465 return responseData;
466 }
467 catch (Exception e)
468 {
469 m_log.Warn("[CLIENT]: LoginResponse: Error creating Hashtable Response: " + e.Message);
470
471 return LLFailedLoginResponse.InternalError.ToHashtable();
472 }
473 }
474
475 public override OSD ToOSDMap()
476 {
477 try
478 {
479 OSDMap map = new OSDMap();
480
481 map["first_name"] = OSD.FromString(Firstname);
482 map["last_name"] = OSD.FromString(Lastname);
483 map["agent_access"] = OSD.FromString(agentAccess);
484 map["agent_access_max"] = OSD.FromString(agentAccessMax);
485
486 map["sim_port"] = OSD.FromInteger(SimPort);
487 map["sim_ip"] = OSD.FromString(SimAddress);
488
489 map["agent_id"] = OSD.FromUUID(AgentID);
490 map["session_id"] = OSD.FromUUID(SessionID);
491 map["secure_session_id"] = OSD.FromUUID(SecureSessionID);
492 map["circuit_code"] = OSD.FromInteger(CircuitCode);
493 map["seconds_since_epoch"] = OSD.FromInteger((int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds);
494
495 #region Login Flags
496
497 OSDMap loginFlagsLLSD = new OSDMap();
498 loginFlagsLLSD["daylight_savings"] = OSD.FromString(DST);
499 loginFlagsLLSD["stipend_since_login"] = OSD.FromString(StipendSinceLogin);
500 loginFlagsLLSD["gendered"] = OSD.FromString(Gendered);
501 loginFlagsLLSD["ever_logged_in"] = OSD.FromString(EverLoggedIn);
502 map["login-flags"] = WrapOSDMap(loginFlagsLLSD);
503
504 #endregion Login Flags
505
506 #region Global Textures
507
508 OSDMap globalTexturesLLSD = new OSDMap();
509 globalTexturesLLSD["sun_texture_id"] = OSD.FromString(SunTexture);
510 globalTexturesLLSD["cloud_texture_id"] = OSD.FromString(CloudTexture);
511 globalTexturesLLSD["moon_texture_id"] = OSD.FromString(MoonTexture);
512
513 map["global-textures"] = WrapOSDMap(globalTexturesLLSD);
514
515 #endregion Global Textures
516
517 map["seed_capability"] = OSD.FromString(seedCapability);
518
519 map["event_categories"] = ArrayListToOSDArray(eventCategories);
520 //map["event_notifications"] = new OSDArray(); // todo
521 map["classified_categories"] = ArrayListToOSDArray(classifiedCategories);
522
523 #region UI Config
524
525 OSDMap uiConfigLLSD = new OSDMap();
526 uiConfigLLSD["allow_first_life"] = OSD.FromString(allowFirstLife);
527 map["ui-config"] = WrapOSDMap(uiConfigLLSD);
528
529 #endregion UI Config
530
531 #region Inventory
532
533 map["inventory-skeleton"] = ArrayListToOSDArray(agentInventory);
534
535 map["inventory-skel-lib"] = ArrayListToOSDArray(inventoryLibrary);
536 map["inventory-root"] = ArrayListToOSDArray(inventoryRoot); ;
537 map["inventory-lib-root"] = ArrayListToOSDArray(inventoryLibRoot);
538 map["inventory-lib-owner"] = ArrayListToOSDArray(inventoryLibraryOwner);
539
540 #endregion Inventory
541
542 map["gestures"] = ArrayListToOSDArray(activeGestures);
543
544 map["initial-outfit"] = ArrayListToOSDArray(initialOutfit);
545 map["start_location"] = OSD.FromString(startLocation);
546
547 map["seed_capability"] = OSD.FromString(seedCapability);
548 map["home"] = OSD.FromString(home);
549 map["look_at"] = OSD.FromString(lookAt);
550 map["message"] = OSD.FromString(welcomeMessage);
551 map["region_x"] = OSD.FromInteger(RegionX);
552 map["region_y"] = OSD.FromInteger(RegionY);
553
554 if (m_buddyList != null)
555 {
556 map["buddy-list"] = ArrayListToOSDArray(m_buddyList.ToArray());
557 }
558
559 map["login"] = OSD.FromString("true");
560
561 return map;
562 }
563 catch (Exception e)
564 {
565 m_log.Warn("[CLIENT]: LoginResponse: Error creating LLSD Response: " + e.Message);
566
567 return LLFailedLoginResponse.InternalError.ToOSDMap();
568 }
569 }
570
571 public OSDArray ArrayListToOSDArray(ArrayList arrlst)
572 {
573 OSDArray llsdBack = new OSDArray();
574 foreach (Hashtable ht in arrlst)
575 {
576 OSDMap mp = new OSDMap();
577 foreach (DictionaryEntry deHt in ht)
578 {
579 mp.Add((string)deHt.Key, OSDString.FromObject(deHt.Value));
580 }
581 llsdBack.Add(mp);
582 }
583 return llsdBack;
584 }
585
586 private static OSDArray WrapOSDMap(OSDMap wrapMe)
587 {
588 OSDArray array = new OSDArray();
589 array.Add(wrapMe);
590 return array;
591 }
592
593 public void SetEventCategories(string category, string value)
594 {
595 // this.eventCategoriesHash[category] = value;
596 //TODO
597 }
598
599 public void AddToUIConfig(string itemName, string item)
600 {
601 uiConfigHash[itemName] = item;
602 }
603
604 public void AddClassifiedCategory(Int32 ID, string categoryName)
605 {
606 Hashtable hash = new Hashtable();
607 hash["category_name"] = categoryName;
608 hash["category_id"] = ID;
609 classifiedCategories.Add(hash);
610 // this.classifiedCategoriesHash.Clear();
611 }
612
613
614 private static LLLoginResponse.BuddyList ConvertFriendListItem(FriendInfo[] friendsList)
615 {
616 LLLoginResponse.BuddyList buddylistreturn = new LLLoginResponse.BuddyList();
617 foreach (FriendInfo finfo in friendsList)
618 {
619 if (finfo.TheirFlags == -1)
620 continue;
621 LLLoginResponse.BuddyList.BuddyInfo buddyitem = new LLLoginResponse.BuddyList.BuddyInfo(finfo.Friend);
622 buddyitem.BuddyID = finfo.Friend;
623 buddyitem.BuddyRightsHave = (int)finfo.TheirFlags;
624 buddyitem.BuddyRightsGiven = (int)finfo.MyFlags;
625 buddylistreturn.AddNewBuddy(buddyitem);
626 }
627 return buddylistreturn;
628 }
629
630 private InventoryData GetInventorySkeleton(List<InventoryFolderBase> folders)
631 {
632 UUID rootID = UUID.Zero;
633 ArrayList AgentInventoryArray = new ArrayList();
634 Hashtable TempHash;
635 foreach (InventoryFolderBase InvFolder in folders)
636 {
637 if (InvFolder.ParentID == UUID.Zero)
638 {
639 rootID = InvFolder.ID;
640 }
641 TempHash = new Hashtable();
642 TempHash["name"] = InvFolder.Name;
643 TempHash["parent_id"] = InvFolder.ParentID.ToString();
644 TempHash["version"] = (Int32)InvFolder.Version;
645 TempHash["type_default"] = (Int32)InvFolder.Type;
646 TempHash["folder_id"] = InvFolder.ID.ToString();
647 AgentInventoryArray.Add(TempHash);
648 }
649
650 return new InventoryData(AgentInventoryArray, rootID);
651
652 }
653
654 /// <summary>
655 /// Converts the inventory library skeleton into the form required by the rpc request.
656 /// </summary>
657 /// <returns></returns>
658 protected virtual ArrayList GetInventoryLibrary(ILibraryService library)
659 {
660 Dictionary<UUID, InventoryFolderImpl> rootFolders = library.GetAllFolders();
661 m_log.DebugFormat("[LLOGIN]: Library has {0} folders", rootFolders.Count);
662 //Dictionary<UUID, InventoryFolderImpl> rootFolders = new Dictionary<UUID,InventoryFolderImpl>();
663 ArrayList folderHashes = new ArrayList();
664
665 foreach (InventoryFolderBase folder in rootFolders.Values)
666 {
667 Hashtable TempHash = new Hashtable();
668 TempHash["name"] = folder.Name;
669 TempHash["parent_id"] = folder.ParentID.ToString();
670 TempHash["version"] = (Int32)folder.Version;
671 TempHash["type_default"] = (Int32)folder.Type;
672 TempHash["folder_id"] = folder.ID.ToString();
673 folderHashes.Add(TempHash);
674 }
675
676 return folderHashes;
677 }
678
679 /// <summary>
680 ///
681 /// </summary>
682 /// <returns></returns>
683 protected virtual ArrayList GetLibraryOwner(InventoryFolderImpl libFolder)
684 {
685 //for now create random inventory library owner
686 Hashtable TempHash = new Hashtable();
687 TempHash["agent_id"] = "11111111-1111-0000-0000-000100bba000"; // libFolder.Owner
688 ArrayList inventoryLibOwner = new ArrayList();
689 inventoryLibOwner.Add(TempHash);
690 return inventoryLibOwner;
691 }
692
693 public class InventoryData
694 {
695 public ArrayList InventoryArray = null;
696 public UUID RootFolderID = UUID.Zero;
697
698 public InventoryData(ArrayList invList, UUID rootID)
699 {
700 InventoryArray = invList;
701 RootFolderID = rootID;
702 }
703 }
704
705 #region Properties
706
707 public string Login
708 {
709 get { return login; }
710 set { login = value; }
711 }
712
713 public string DST
714 {
715 get { return dst; }
716 set { dst = value; }
717 }
718
719 public string StipendSinceLogin
720 {
721 get { return stipendSinceLogin; }
722 set { stipendSinceLogin = value; }
723 }
724
725 public string Gendered
726 {
727 get { return gendered; }
728 set { gendered = value; }
729 }
730
731 public string EverLoggedIn
732 {
733 get { return everLoggedIn; }
734 set { everLoggedIn = value; }
735 }
736
737 public uint SimPort
738 {
739 get { return simPort; }
740 set { simPort = value; }
741 }
742
743 public uint SimHttpPort
744 {
745 get { return simHttpPort; }
746 set { simHttpPort = value; }
747 }
748
749 public string SimAddress
750 {
751 get { return simAddress; }
752 set { simAddress = value; }
753 }
754
755 public UUID AgentID
756 {
757 get { return agentID; }
758 set { agentID = value; }
759 }
760
761 public UUID SessionID
762 {
763 get { return sessionID; }
764 set { sessionID = value; }
765 }
766
767 public UUID SecureSessionID
768 {
769 get { return secureSessionID; }
770 set { secureSessionID = value; }
771 }
772
773 public Int32 CircuitCode
774 {
775 get { return circuitCode; }
776 set { circuitCode = value; }
777 }
778
779 public uint RegionX
780 {
781 get { return regionX; }
782 set { regionX = value; }
783 }
784
785 public uint RegionY
786 {
787 get { return regionY; }
788 set { regionY = value; }
789 }
790
791 public string SunTexture
792 {
793 get { return sunTexture; }
794 set { sunTexture = value; }
795 }
796
797 public string CloudTexture
798 {
799 get { return cloudTexture; }
800 set { cloudTexture = value; }
801 }
802
803 public string MoonTexture
804 {
805 get { return moonTexture; }
806 set { moonTexture = value; }
807 }
808
809 public string Firstname
810 {
811 get { return firstname; }
812 set { firstname = value; }
813 }
814
815 public string Lastname
816 {
817 get { return lastname; }
818 set { lastname = value; }
819 }
820
821 public string AgentAccess
822 {
823 get { return agentAccess; }
824 set { agentAccess = value; }
825 }
826
827 public string AgentAccessMax
828 {
829 get { return agentAccessMax; }
830 set { agentAccessMax = value; }
831 }
832
833 public string StartLocation
834 {
835 get { return startLocation; }
836 set { startLocation = value; }
837 }
838
839 public string LookAt
840 {
841 get { return lookAt; }
842 set { lookAt = value; }
843 }
844
845 public string SeedCapability
846 {
847 get { return seedCapability; }
848 set { seedCapability = value; }
849 }
850
851 public string ErrorReason
852 {
853 get { return errorReason; }
854 set { errorReason = value; }
855 }
856
857 public string ErrorMessage
858 {
859 get { return errorMessage; }
860 set { errorMessage = value; }
861 }
862
863 public ArrayList InventoryRoot
864 {
865 get { return inventoryRoot; }
866 set { inventoryRoot = value; }
867 }
868
869 public ArrayList InventorySkeleton
870 {
871 get { return agentInventory; }
872 set { agentInventory = value; }
873 }
874
875 public ArrayList InventoryLibrary
876 {
877 get { return inventoryLibrary; }
878 set { inventoryLibrary = value; }
879 }
880
881 public ArrayList InventoryLibraryOwner
882 {
883 get { return inventoryLibraryOwner; }
884 set { inventoryLibraryOwner = value; }
885 }
886
887 public ArrayList InventoryLibRoot
888 {
889 get { return inventoryLibRoot; }
890 set { inventoryLibRoot = value; }
891 }
892
893 public ArrayList ActiveGestures
894 {
895 get { return activeGestures; }
896 set { activeGestures = value; }
897 }
898
899 public string Home
900 {
901 get { return home; }
902 set { home = value; }
903 }
904
905 public string Message
906 {
907 get { return welcomeMessage; }
908 set { welcomeMessage = value; }
909 }
910
911 public BuddyList BuddList
912 {
913 get { return m_buddyList; }
914 set { m_buddyList = value; }
915 }
916
917 #endregion
918
919 public class UserInfo
920 {
921 public string firstname;
922 public string lastname;
923 public ulong homeregionhandle;
924 public Vector3 homepos;
925 public Vector3 homelookat;
926 }
927
928 public class BuddyList
929 {
930 public List<BuddyInfo> Buddies = new List<BuddyInfo>();
931
932 public void AddNewBuddy(BuddyInfo buddy)
933 {
934 if (!Buddies.Contains(buddy))
935 {
936 Buddies.Add(buddy);
937 }
938 }
939
940 public ArrayList ToArray()
941 {
942 ArrayList buddyArray = new ArrayList();
943 foreach (BuddyInfo buddy in Buddies)
944 {
945 buddyArray.Add(buddy.ToHashTable());
946 }
947 return buddyArray;
948 }
949
950 public class BuddyInfo
951 {
952 public int BuddyRightsHave = 1;
953 public int BuddyRightsGiven = 1;
954 public string BuddyID;
955
956 public BuddyInfo(string buddyID)
957 {
958 BuddyID = buddyID;
959 }
960
961 public BuddyInfo(UUID buddyID)
962 {
963 BuddyID = buddyID.ToString();
964 }
965
966 public Hashtable ToHashTable()
967 {
968 Hashtable hTable = new Hashtable();
969 hTable["buddy_rights_has"] = BuddyRightsHave;
970 hTable["buddy_rights_given"] = BuddyRightsGiven;
971 hTable["buddy_id"] = BuddyID;
972 return hTable;
973 }
974 }
975 }
976 }
977}
diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs
new file mode 100644
index 0000000..5301140
--- /dev/null
+++ b/OpenSim/Services/LLLoginService/LLLoginService.cs
@@ -0,0 +1,744 @@
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;
32using System.Text.RegularExpressions;
33
34using log4net;
35using Nini.Config;
36using OpenMetaverse;
37
38using OpenSim.Framework;
39using OpenSim.Framework.Capabilities;
40using OpenSim.Framework.Console;
41using OpenSim.Server.Base;
42using OpenSim.Services.Interfaces;
43using GridRegion = OpenSim.Services.Interfaces.GridRegion;
44using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
45using OpenSim.Services.Connectors.Hypergrid;
46
47namespace OpenSim.Services.LLLoginService
48{
49 public class LLLoginService : ILoginService
50 {
51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52 private static bool Initialized = false;
53
54 protected IUserAccountService m_UserAccountService;
55 protected IAuthenticationService m_AuthenticationService;
56 protected IInventoryService m_InventoryService;
57 protected IGridService m_GridService;
58 protected IPresenceService m_PresenceService;
59 private ISimulationService m_LocalSimulationService;
60 private ISimulationService m_RemoteSimulationService;
61 protected ILibraryService m_LibraryService;
62 protected IFriendsService m_FriendsService;
63 protected IAvatarService m_AvatarService;
64 private IUserAgentService m_UserAgentService;
65
66 private GatekeeperServiceConnector m_GatekeeperConnector;
67
68 private string m_DefaultRegionName;
69 protected string m_WelcomeMessage;
70 private bool m_RequireInventory;
71 protected int m_MinLoginLevel;
72 private string m_GatekeeperURL;
73
74 IConfig m_LoginServerConfig;
75
76 public LLLoginService(IConfigSource config, ISimulationService simService, ILibraryService libraryService)
77 {
78 m_LoginServerConfig = config.Configs["LoginService"];
79 if (m_LoginServerConfig == null)
80 throw new Exception(String.Format("No section LoginService in config file"));
81
82 string accountService = m_LoginServerConfig.GetString("UserAccountService", String.Empty);
83 string agentService = m_LoginServerConfig.GetString("UserAgentService", String.Empty);
84 string authService = m_LoginServerConfig.GetString("AuthenticationService", String.Empty);
85 string invService = m_LoginServerConfig.GetString("InventoryService", String.Empty);
86 string gridService = m_LoginServerConfig.GetString("GridService", String.Empty);
87 string presenceService = m_LoginServerConfig.GetString("PresenceService", String.Empty);
88 string libService = m_LoginServerConfig.GetString("LibraryService", String.Empty);
89 string friendsService = m_LoginServerConfig.GetString("FriendsService", String.Empty);
90 string avatarService = m_LoginServerConfig.GetString("AvatarService", String.Empty);
91 string simulationService = m_LoginServerConfig.GetString("SimulationService", String.Empty);
92
93 m_DefaultRegionName = m_LoginServerConfig.GetString("DefaultRegion", String.Empty);
94 m_WelcomeMessage = m_LoginServerConfig.GetString("WelcomeMessage", "Welcome to OpenSim!");
95 m_RequireInventory = m_LoginServerConfig.GetBoolean("RequireInventory", true);
96 m_GatekeeperURL = m_LoginServerConfig.GetString("GatekeeperURI", string.Empty);
97
98 // These are required; the others aren't
99 if (accountService == string.Empty || authService == string.Empty)
100 throw new Exception("LoginService is missing service specifications");
101
102 Object[] args = new Object[] { config };
103 m_UserAccountService = ServerUtils.LoadPlugin<IUserAccountService>(accountService, args);
104 m_AuthenticationService = ServerUtils.LoadPlugin<IAuthenticationService>(authService, args);
105 m_InventoryService = ServerUtils.LoadPlugin<IInventoryService>(invService, args);
106 if (gridService != string.Empty)
107 m_GridService = ServerUtils.LoadPlugin<IGridService>(gridService, args);
108 if (presenceService != string.Empty)
109 m_PresenceService = ServerUtils.LoadPlugin<IPresenceService>(presenceService, args);
110 if (avatarService != string.Empty)
111 m_AvatarService = ServerUtils.LoadPlugin<IAvatarService>(avatarService, args);
112 if (friendsService != string.Empty)
113 m_FriendsService = ServerUtils.LoadPlugin<IFriendsService>(friendsService, args);
114 if (simulationService != string.Empty)
115 m_RemoteSimulationService = ServerUtils.LoadPlugin<ISimulationService>(simulationService, args);
116 if (agentService != string.Empty)
117 m_UserAgentService = ServerUtils.LoadPlugin<IUserAgentService>(agentService, args);
118
119 //
120 // deal with the services given as argument
121 //
122 m_LocalSimulationService = simService;
123 if (libraryService != null)
124 {
125 m_log.DebugFormat("[LLOGIN SERVICE]: Using LibraryService given as argument");
126 m_LibraryService = libraryService;
127 }
128 else if (libService != string.Empty)
129 {
130 m_log.DebugFormat("[LLOGIN SERVICE]: Using instantiated LibraryService");
131 m_LibraryService = ServerUtils.LoadPlugin<ILibraryService>(libService, args);
132 }
133
134 m_GatekeeperConnector = new GatekeeperServiceConnector();
135
136 if (!Initialized)
137 {
138 Initialized = true;
139 RegisterCommands();
140 }
141
142 m_log.DebugFormat("[LLOGIN SERVICE]: Starting...");
143
144 }
145
146 public LLLoginService(IConfigSource config) : this(config, null, null)
147 {
148 }
149
150 public LoginResponse Login(string firstName, string lastName, string passwd, string startLocation, UUID scopeID, IPEndPoint clientIP)
151 {
152 bool success = false;
153 UUID session = UUID.Random();
154
155 try
156 {
157 //
158 // Get the account and check that it exists
159 //
160 UserAccount account = m_UserAccountService.GetUserAccount(scopeID, firstName, lastName);
161 if (account == null)
162 {
163 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: user not found");
164 return LLFailedLoginResponse.UserProblem;
165 }
166
167 if (account.UserLevel < 0)
168 {
169 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: Unverified account");
170 return LLFailedLoginResponse.UnverifiedAccountProblem;
171 }
172
173 if (account.UserLevel < m_MinLoginLevel)
174 {
175 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: login is blocked for user level {0}", account.UserLevel);
176 return LLFailedLoginResponse.LoginBlockedProblem;
177 }
178
179 // If a scope id is requested, check that the account is in
180 // that scope, or unscoped.
181 //
182 if (scopeID != UUID.Zero)
183 {
184 if (account.ScopeID != scopeID && account.ScopeID != UUID.Zero)
185 {
186 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: user not found");
187 return LLFailedLoginResponse.UserProblem;
188 }
189 }
190 else
191 {
192 scopeID = account.ScopeID;
193 }
194
195 //
196 // Authenticate this user
197 //
198 if (!passwd.StartsWith("$1$"))
199 passwd = "$1$" + Util.Md5Hash(passwd);
200 passwd = passwd.Remove(0, 3); //remove $1$
201 string token = m_AuthenticationService.Authenticate(account.PrincipalID, passwd, 30);
202 UUID secureSession = UUID.Zero;
203 if ((token == string.Empty) || (token != string.Empty && !UUID.TryParse(token, out secureSession)))
204 {
205 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: authentication failed");
206 return LLFailedLoginResponse.UserProblem;
207 }
208
209 //
210 // Get the user's inventory
211 //
212 if (m_RequireInventory && m_InventoryService == null)
213 {
214 m_log.WarnFormat("[LLOGIN SERVICE]: Login failed, reason: inventory service not set up");
215 return LLFailedLoginResponse.InventoryProblem;
216 }
217 List<InventoryFolderBase> inventorySkel = m_InventoryService.GetInventorySkeleton(account.PrincipalID);
218 if (m_RequireInventory && ((inventorySkel == null) || (inventorySkel != null && inventorySkel.Count == 0)))
219 {
220 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: unable to retrieve user inventory");
221 return LLFailedLoginResponse.InventoryProblem;
222 }
223
224 //
225 // Login the presence
226 //
227 PresenceInfo presence = null;
228 GridRegion home = null;
229 if (m_PresenceService != null)
230 {
231 success = m_PresenceService.LoginAgent(account.PrincipalID.ToString(), session, secureSession);
232 if (!success)
233 {
234 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: could not login presence");
235 return LLFailedLoginResponse.GridProblem;
236 }
237
238 // Get the updated presence info
239 presence = m_PresenceService.GetAgent(session);
240
241 // Get the home region
242 if ((presence.HomeRegionID != UUID.Zero) && m_GridService != null)
243 {
244 home = m_GridService.GetRegionByUUID(scopeID, presence.HomeRegionID);
245 }
246 }
247
248 //
249 // Find the destination region/grid
250 //
251 string where = string.Empty;
252 Vector3 position = Vector3.Zero;
253 Vector3 lookAt = Vector3.Zero;
254 GridRegion gatekeeper = null;
255 GridRegion destination = FindDestination(account, scopeID, presence, session, startLocation, out gatekeeper, out where, out position, out lookAt);
256 if (destination == null)
257 {
258 m_PresenceService.LogoutAgent(session, presence.Position, presence.LookAt);
259 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: destination not found");
260 return LLFailedLoginResponse.GridProblem;
261 }
262
263 //
264 // Get the avatar
265 //
266 AvatarData avatar = null;
267 if (m_AvatarService != null)
268 {
269 avatar = m_AvatarService.GetAvatar(account.PrincipalID);
270 }
271
272 //
273 // Instantiate/get the simulation interface and launch an agent at the destination
274 //
275 string reason = string.Empty;
276 AgentCircuitData aCircuit = LaunchAgentAtGrid(gatekeeper, destination, account, avatar, session, secureSession, position, where, out where, out reason);
277
278 if (aCircuit == null)
279 {
280 m_PresenceService.LogoutAgent(session, presence.Position, presence.LookAt);
281 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: {0}", reason);
282 return LLFailedLoginResponse.AuthorizationProblem;
283
284 }
285 // Get Friends list
286 FriendInfo[] friendsList = new FriendInfo[0];
287 if (m_FriendsService != null)
288 {
289 friendsList = m_FriendsService.GetFriends(account.PrincipalID);
290 m_log.DebugFormat("[LLOGIN SERVICE]: Retrieved {0} friends", friendsList.Length);
291 }
292
293 //
294 // Finally, fill out the response and return it
295 //
296 LLLoginResponse response = new LLLoginResponse(account, aCircuit, presence, destination, inventorySkel, friendsList, m_LibraryService,
297 where, startLocation, position, lookAt, m_WelcomeMessage, home, clientIP);
298
299 m_log.DebugFormat("[LLOGIN SERVICE]: All clear. Sending login response to client.");
300 return response;
301 }
302 catch (Exception e)
303 {
304 m_log.WarnFormat("[LLOGIN SERVICE]: Exception processing login for {0} {1}: {2} {3}", firstName, lastName, e.ToString(), e.StackTrace);
305 if (m_PresenceService != null)
306 m_PresenceService.LogoutAgent(session, new Vector3(128, 128, 0), new Vector3(0, 1, 0));
307 return LLFailedLoginResponse.InternalError;
308 }
309 }
310
311 protected GridRegion FindDestination(UserAccount account, UUID scopeID, PresenceInfo pinfo, UUID sessionID, string startLocation, out GridRegion gatekeeper, out string where, out Vector3 position, out Vector3 lookAt)
312 {
313 m_log.DebugFormat("[LLOGIN SERVICE]: FindDestination for start location {0}", startLocation);
314
315 gatekeeper = null;
316 where = "home";
317 position = new Vector3(128, 128, 0);
318 lookAt = new Vector3(0, 1, 0);
319
320 if (m_GridService == null)
321 return null;
322
323 if (startLocation.Equals("home"))
324 {
325 // logging into home region
326 if (pinfo == null)
327 return null;
328
329 GridRegion region = null;
330
331 bool tryDefaults = false;
332
333 if (pinfo.HomeRegionID.Equals(UUID.Zero))
334 {
335 m_log.WarnFormat(
336 "[LLOGIN SERVICE]: User {0} {1} tried to login to a 'home' start location but they have none set",
337 account.FirstName, account.LastName);
338
339 tryDefaults = true;
340 }
341 else
342 {
343 region = m_GridService.GetRegionByUUID(scopeID, pinfo.HomeRegionID);
344
345 if (null == region)
346 {
347 m_log.WarnFormat(
348 "[LLOGIN SERVICE]: User {0} {1} has a recorded home region of {2} but this cannot be found by the grid service",
349 account.FirstName, account.LastName, pinfo.HomeRegionID);
350
351 tryDefaults = true;
352 }
353 }
354
355 if (tryDefaults)
356 {
357 List<GridRegion> defaults = m_GridService.GetDefaultRegions(scopeID);
358 if (defaults != null && defaults.Count > 0)
359 {
360 region = defaults[0];
361 where = "safe";
362 }
363 else
364 {
365 m_log.WarnFormat("[LLOGIN SERVICE]: User {0} {1} does not have a valid home and this grid does not have default locations. Attempting to find random region",
366 account.FirstName, account.LastName);
367 defaults = m_GridService.GetRegionsByName(scopeID, "", 1);
368 if (defaults != null && defaults.Count > 0)
369 {
370 region = defaults[0];
371 where = "safe";
372 }
373 }
374 }
375
376 return region;
377 }
378 else if (startLocation.Equals("last"))
379 {
380 // logging into last visited region
381 where = "last";
382
383 if (pinfo == null)
384 return null;
385
386 GridRegion region = null;
387
388 if (pinfo.RegionID.Equals(UUID.Zero) || (region = m_GridService.GetRegionByUUID(scopeID, pinfo.RegionID)) == null)
389 {
390 List<GridRegion> defaults = m_GridService.GetDefaultRegions(scopeID);
391 if (defaults != null && defaults.Count > 0)
392 {
393 region = defaults[0];
394 where = "safe";
395 }
396 else
397 {
398 m_log.Info("[LLOGIN SERVICE]: Last Region Not Found Attempting to find random region");
399 defaults = m_GridService.GetRegionsByName(scopeID, "", 1);
400 if (defaults != null && defaults.Count > 0)
401 {
402 region = defaults[0];
403 where = "safe";
404 }
405 }
406
407 }
408 else
409 {
410 position = pinfo.Position;
411 lookAt = pinfo.LookAt;
412 }
413
414 return region;
415 }
416 else
417 {
418 // free uri form
419 // e.g. New Moon&135&46 New Moon@osgrid.org:8002&153&34
420 where = "url";
421 Regex reURI = new Regex(@"^uri:(?<region>[^&]+)&(?<x>\d+)&(?<y>\d+)&(?<z>\d+)$");
422 Match uriMatch = reURI.Match(startLocation);
423 if (uriMatch == null)
424 {
425 m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, but can't process it", startLocation);
426 return null;
427 }
428 else
429 {
430 position = new Vector3(float.Parse(uriMatch.Groups["x"].Value, Culture.NumberFormatInfo),
431 float.Parse(uriMatch.Groups["y"].Value, Culture.NumberFormatInfo),
432 float.Parse(uriMatch.Groups["z"].Value, Culture.NumberFormatInfo));
433
434 string regionName = uriMatch.Groups["region"].ToString();
435 if (regionName != null)
436 {
437 if (!regionName.Contains("@"))
438 {
439 List<GridRegion> regions = m_GridService.GetRegionsByName(scopeID, regionName, 1);
440 if ((regions == null) || (regions != null && regions.Count == 0))
441 {
442 m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, can't locate region {1}. Trying defaults.", startLocation, regionName);
443 regions = m_GridService.GetDefaultRegions(scopeID);
444 if (regions != null && regions.Count > 0)
445 {
446 where = "safe";
447 return regions[0];
448 }
449 else
450 {
451 m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, Grid does not provide default regions.", startLocation);
452 return null;
453 }
454 }
455 return regions[0];
456 }
457 else
458 {
459 if (m_UserAgentService == null)
460 {
461 m_log.WarnFormat("[LLLOGIN SERVICE]: This llogin service is not running a user agent service, as such it can't lauch agents at foreign grids");
462 return null;
463 }
464 string[] parts = regionName.Split(new char[] { '@' });
465 if (parts.Length < 2)
466 {
467 m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, can't locate region {1}", startLocation, regionName);
468 return null;
469 }
470 // Valid specification of a remote grid
471
472 regionName = parts[0];
473 string domainLocator = parts[1];
474 parts = domainLocator.Split(new char[] {':'});
475 string domainName = parts[0];
476 uint port = 0;
477 if (parts.Length > 1)
478 UInt32.TryParse(parts[1], out port);
479
480 GridRegion region = FindForeignRegion(domainName, port, regionName, out gatekeeper);
481 return region;
482 }
483 }
484 else
485 {
486 List<GridRegion> defaults = m_GridService.GetDefaultRegions(scopeID);
487 if (defaults != null && defaults.Count > 0)
488 {
489 where = "safe";
490 return defaults[0];
491 }
492 else
493 return null;
494 }
495 }
496 //response.LookAt = "[r0,r1,r0]";
497 //// can be: last, home, safe, url
498 //response.StartLocation = "url";
499
500 }
501
502 }
503
504 private GridRegion FindForeignRegion(string domainName, uint port, string regionName, out GridRegion gatekeeper)
505 {
506 gatekeeper = new GridRegion();
507 gatekeeper.ExternalHostName = domainName;
508 gatekeeper.HttpPort = port;
509 gatekeeper.RegionName = regionName;
510 gatekeeper.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0);
511
512 UUID regionID;
513 ulong handle;
514 string imageURL = string.Empty, reason = string.Empty;
515 if (m_GatekeeperConnector.LinkRegion(gatekeeper, out regionID, out handle, out domainName, out imageURL, out reason))
516 {
517 GridRegion destination = m_GatekeeperConnector.GetHyperlinkRegion(gatekeeper, regionID);
518 return destination;
519 }
520
521 return null;
522 }
523
524 private string hostName = string.Empty;
525 private int port = 0;
526
527 private void SetHostAndPort(string url)
528 {
529 try
530 {
531 Uri uri = new Uri(url);
532 hostName = uri.Host;
533 port = uri.Port;
534 }
535 catch
536 {
537 m_log.WarnFormat("[LLLogin SERVICE]: Unable to parse GatekeeperURL {0}", url);
538 }
539 }
540
541 protected AgentCircuitData LaunchAgentAtGrid(GridRegion gatekeeper, GridRegion destination, UserAccount account, AvatarData avatar,
542 UUID session, UUID secureSession, Vector3 position, string currentWhere, out string where, out string reason)
543 {
544 where = currentWhere;
545 ISimulationService simConnector = null;
546 reason = string.Empty;
547 uint circuitCode = 0;
548 AgentCircuitData aCircuit = null;
549
550 if (m_UserAgentService == null)
551 {
552 // HG standalones have both a localSimulatonDll and a remoteSimulationDll
553 // non-HG standalones have just a localSimulationDll
554 // independent login servers have just a remoteSimulationDll
555 if (m_LocalSimulationService != null)
556 simConnector = m_LocalSimulationService;
557 else if (m_RemoteSimulationService != null)
558 simConnector = m_RemoteSimulationService;
559 }
560 else // User Agent Service is on
561 {
562 if (gatekeeper == null) // login to local grid
563 {
564 if (hostName == string.Empty)
565 SetHostAndPort(m_GatekeeperURL);
566
567 gatekeeper = new GridRegion(destination);
568 gatekeeper.ExternalHostName = hostName;
569 gatekeeper.HttpPort = (uint)port;
570
571 }
572 else // login to foreign grid
573 {
574 }
575 }
576
577 bool success = false;
578
579 if (m_UserAgentService == null && simConnector != null)
580 {
581 circuitCode = (uint)Util.RandomClass.Next(); ;
582 aCircuit = MakeAgent(destination, account, avatar, session, secureSession, circuitCode, position);
583 success = LaunchAgentDirectly(simConnector, destination, aCircuit, out reason);
584 if (!success && m_GridService != null)
585 {
586 // Try the fallback regions
587 List<GridRegion> fallbacks = m_GridService.GetFallbackRegions(account.ScopeID, destination.RegionLocX, destination.RegionLocY);
588 if (fallbacks != null)
589 {
590 foreach (GridRegion r in fallbacks)
591 {
592 success = LaunchAgentDirectly(simConnector, r, aCircuit, out reason);
593 if (success)
594 {
595 where = "safe";
596 destination = r;
597 break;
598 }
599 }
600 }
601 }
602 }
603
604 if (m_UserAgentService != null)
605 {
606 circuitCode = (uint)Util.RandomClass.Next(); ;
607 aCircuit = MakeAgent(destination, account, avatar, session, secureSession, circuitCode, position);
608 success = LaunchAgentIndirectly(gatekeeper, destination, aCircuit, out reason);
609 if (!success && m_GridService != null)
610 {
611 // Try the fallback regions
612 List<GridRegion> fallbacks = m_GridService.GetFallbackRegions(account.ScopeID, destination.RegionLocX, destination.RegionLocY);
613 if (fallbacks != null)
614 {
615 foreach (GridRegion r in fallbacks)
616 {
617 success = LaunchAgentIndirectly(gatekeeper, r, aCircuit, out reason);
618 if (success)
619 {
620 where = "safe";
621 destination = r;
622 break;
623 }
624 }
625 }
626 }
627 }
628
629 if (success)
630 return aCircuit;
631 else
632 return null;
633 }
634
635 private AgentCircuitData MakeAgent(GridRegion region, UserAccount account,
636 AvatarData avatar, UUID session, UUID secureSession, uint circuit, Vector3 position)
637 {
638 AgentCircuitData aCircuit = new AgentCircuitData();
639
640 aCircuit.AgentID = account.PrincipalID;
641 if (avatar != null)
642 aCircuit.Appearance = avatar.ToAvatarAppearance(account.PrincipalID);
643 else
644 aCircuit.Appearance = new AvatarAppearance(account.PrincipalID);
645
646 //aCircuit.BaseFolder = irrelevant
647 aCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
648 aCircuit.child = false; // the first login agent is root
649 aCircuit.ChildrenCapSeeds = new Dictionary<ulong, string>();
650 aCircuit.circuitcode = circuit;
651 aCircuit.firstname = account.FirstName;
652 //aCircuit.InventoryFolder = irrelevant
653 aCircuit.lastname = account.LastName;
654 aCircuit.SecureSessionID = secureSession;
655 aCircuit.SessionID = session;
656 aCircuit.startpos = position;
657 SetServiceURLs(aCircuit, account);
658
659 return aCircuit;
660
661 //m_UserAgentService.LoginAgentToGrid(aCircuit, GatekeeperServiceConnector, region, out reason);
662 //if (simConnector.CreateAgent(region, aCircuit, 0, out reason))
663 // return aCircuit;
664
665 //return null;
666
667 }
668
669 private void SetServiceURLs(AgentCircuitData aCircuit, UserAccount account)
670 {
671 aCircuit.ServiceURLs = new Dictionary<string, object>();
672 if (account.ServiceURLs == null)
673 return;
674
675 foreach (KeyValuePair<string, object> kvp in account.ServiceURLs)
676 {
677 if (kvp.Value == null || (kvp.Value != null && kvp.Value.ToString() == string.Empty))
678 {
679 aCircuit.ServiceURLs[kvp.Key] = m_LoginServerConfig.GetString(kvp.Key, string.Empty);
680 }
681 else
682 {
683 aCircuit.ServiceURLs[kvp.Key] = kvp.Value;
684 }
685 }
686 }
687
688 private bool LaunchAgentDirectly(ISimulationService simConnector, GridRegion region, AgentCircuitData aCircuit, out string reason)
689 {
690 return simConnector.CreateAgent(region, aCircuit, (int)Constants.TeleportFlags.ViaLogin, out reason);
691 }
692
693 private bool LaunchAgentIndirectly(GridRegion gatekeeper, GridRegion destination, AgentCircuitData aCircuit, out string reason)
694 {
695 m_log.Debug("[LLOGIN SERVICE] Launching agent at " + destination.RegionName);
696 return m_UserAgentService.LoginAgentToGrid(aCircuit, gatekeeper, destination, out reason);
697 }
698
699 #region Console Commands
700 private void RegisterCommands()
701 {
702 //MainConsole.Instance.Commands.AddCommand
703 MainConsole.Instance.Commands.AddCommand("loginservice", false, "login level",
704 "login level <level>",
705 "Set the minimum user level to log in", HandleLoginCommand);
706
707 MainConsole.Instance.Commands.AddCommand("loginservice", false, "login reset",
708 "login reset",
709 "Reset the login level to allow all users",
710 HandleLoginCommand);
711
712 MainConsole.Instance.Commands.AddCommand("loginservice", false, "login text",
713 "login text <text>",
714 "Set the text users will see on login", HandleLoginCommand);
715
716 }
717
718 private void HandleLoginCommand(string module, string[] cmd)
719 {
720 string subcommand = cmd[1];
721
722 switch (subcommand)
723 {
724 case "level":
725 // Set the minimum level to allow login
726 // Useful to allow grid update without worrying about users.
727 // or fixing critical issues
728 //
729 if (cmd.Length > 2)
730 Int32.TryParse(cmd[2], out m_MinLoginLevel);
731 break;
732 case "reset":
733 m_MinLoginLevel = 0;
734 break;
735 case "text":
736 if (cmd.Length > 2)
737 m_WelcomeMessage = cmd[2];
738 break;
739 }
740 }
741 }
742
743 #endregion
744}