opensim-development – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 eva 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  
28 using System;
29 using System.Collections.Generic;
30 using System.Net;
31 using System.Reflection;
32  
33 using OpenSim.Data;
34 using OpenSim.Framework;
35 using OpenSim.Services.Connectors.Friends;
36 using OpenSim.Services.Connectors.Hypergrid;
37 using OpenSim.Services.Interfaces;
38 using GridRegion = OpenSim.Services.Interfaces.GridRegion;
39 using OpenSim.Server.Base;
40 using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
41  
42 using OpenMetaverse;
43 using log4net;
44 using Nini.Config;
45  
46 namespace OpenSim.Services.HypergridService
47 {
48 /// <summary>
49 /// This service is for HG1.5 only, to make up for the fact that clients don't
50 /// keep any private information in themselves, and that their 'home service'
51 /// needs to do it for them.
52 /// Once we have better clients, this shouldn't be needed.
53 /// </summary>
54 public class UserAgentService : UserAgentServiceBase, IUserAgentService
55 {
56 private static readonly ILog m_log =
57 LogManager.GetLogger(
58 MethodBase.GetCurrentMethod().DeclaringType);
59  
60 // This will need to go into a DB table
61 //static Dictionary<UUID, TravelingAgentInfo> m_Database = new Dictionary<UUID, TravelingAgentInfo>();
62  
63 static bool m_Initialized = false;
64  
65 protected static IGridUserService m_GridUserService;
66 protected static IGridService m_GridService;
67 protected static GatekeeperServiceConnector m_GatekeeperConnector;
68 protected static IGatekeeperService m_GatekeeperService;
69 protected static IFriendsService m_FriendsService;
70 protected static IPresenceService m_PresenceService;
71 protected static IUserAccountService m_UserAccountService;
72 protected static IFriendsSimConnector m_FriendsLocalSimConnector; // standalone, points to HGFriendsModule
73 protected static FriendsSimConnector m_FriendsSimConnector; // grid
74  
75 protected static string m_GridName;
76  
77 protected static int m_LevelOutsideContacts;
78  
79 protected static bool m_BypassClientVerification;
80  
81 private static Dictionary<int, bool> m_ForeignTripsAllowed = new Dictionary<int, bool>();
82 private static Dictionary<int, List<string>> m_TripsAllowedExceptions = new Dictionary<int, List<string>>();
83 private static Dictionary<int, List<string>> m_TripsDisallowedExceptions = new Dictionary<int, List<string>>();
84  
85 public UserAgentService(IConfigSource config) : this(config, null)
86 {
87 }
88  
89 public UserAgentService(IConfigSource config, IFriendsSimConnector friendsConnector)
90 : base(config)
91 {
92 // Let's set this always, because we don't know the sequence
93 // of instantiations
94 if (friendsConnector != null)
95 m_FriendsLocalSimConnector = friendsConnector;
96  
97 if (!m_Initialized)
98 {
99 m_Initialized = true;
100  
101 m_log.DebugFormat("[HOME USERS SECURITY]: Starting...");
102  
103 m_FriendsSimConnector = new FriendsSimConnector();
104  
105 IConfig serverConfig = config.Configs["UserAgentService"];
106 if (serverConfig == null)
107 throw new Exception(String.Format("No section UserAgentService in config file"));
108  
109 string gridService = serverConfig.GetString("GridService", String.Empty);
110 string gridUserService = serverConfig.GetString("GridUserService", String.Empty);
111 string gatekeeperService = serverConfig.GetString("GatekeeperService", String.Empty);
112 string friendsService = serverConfig.GetString("FriendsService", String.Empty);
113 string presenceService = serverConfig.GetString("PresenceService", String.Empty);
114 string userAccountService = serverConfig.GetString("UserAccountService", String.Empty);
115  
116 m_BypassClientVerification = serverConfig.GetBoolean("BypassClientVerification", false);
117  
118 if (gridService == string.Empty || gridUserService == string.Empty || gatekeeperService == string.Empty)
119 throw new Exception(String.Format("Incomplete specifications, UserAgent Service cannot function."));
120  
121 Object[] args = new Object[] { config };
122 m_GridService = ServerUtils.LoadPlugin<IGridService>(gridService, args);
123 m_GridUserService = ServerUtils.LoadPlugin<IGridUserService>(gridUserService, args);
124 m_GatekeeperConnector = new GatekeeperServiceConnector();
125 m_GatekeeperService = ServerUtils.LoadPlugin<IGatekeeperService>(gatekeeperService, args);
126 m_FriendsService = ServerUtils.LoadPlugin<IFriendsService>(friendsService, args);
127 m_PresenceService = ServerUtils.LoadPlugin<IPresenceService>(presenceService, args);
128 m_UserAccountService = ServerUtils.LoadPlugin<IUserAccountService>(userAccountService, args);
129  
130 m_LevelOutsideContacts = serverConfig.GetInt("LevelOutsideContacts", 0);
131  
132 LoadTripPermissionsFromConfig(serverConfig, "ForeignTripsAllowed");
133 LoadDomainExceptionsFromConfig(serverConfig, "AllowExcept", m_TripsAllowedExceptions);
134 LoadDomainExceptionsFromConfig(serverConfig, "DisallowExcept", m_TripsDisallowedExceptions);
135  
136 m_GridName = Util.GetConfigVarFromSections<string>(config, "GatekeeperURI",
137 new string[] { "Startup", "Hypergrid", "UserAgentService" }, String.Empty);
138 if (string.IsNullOrEmpty(m_GridName)) // Legacy. Remove soon.
139 {
140 m_GridName = serverConfig.GetString("ExternalName", string.Empty);
141 if (m_GridName == string.Empty)
142 {
143 serverConfig = config.Configs["GatekeeperService"];
144 m_GridName = serverConfig.GetString("ExternalName", string.Empty);
145 }
146 }
147  
148 if (!m_GridName.EndsWith("/"))
149 m_GridName = m_GridName + "/";
150  
151 // Finally some cleanup
152 m_Database.DeleteOld();
153  
154 }
155 }
156  
157 protected void LoadTripPermissionsFromConfig(IConfig config, string variable)
158 {
159 foreach (string keyName in config.GetKeys())
160 {
161 if (keyName.StartsWith(variable + "_Level_"))
162 {
163 int level = 0;
164 if (Int32.TryParse(keyName.Replace(variable + "_Level_", ""), out level))
165 m_ForeignTripsAllowed.Add(level, config.GetBoolean(keyName, true));
166 }
167 }
168 }
169  
170 protected void LoadDomainExceptionsFromConfig(IConfig config, string variable, Dictionary<int, List<string>> exceptions)
171 {
172 foreach (string keyName in config.GetKeys())
173 {
174 if (keyName.StartsWith(variable + "_Level_"))
175 {
176 int level = 0;
177 if (Int32.TryParse(keyName.Replace(variable + "_Level_", ""), out level) && !exceptions.ContainsKey(level))
178 {
179 exceptions.Add(level, new List<string>());
180 string value = config.GetString(keyName, string.Empty);
181 string[] parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
182  
183 foreach (string s in parts)
184 exceptions[level].Add(s.Trim());
185 }
186 }
187 }
188 }
189  
190  
191 public GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt)
192 {
193 position = new Vector3(128, 128, 0); lookAt = Vector3.UnitY;
194  
195 m_log.DebugFormat("[USER AGENT SERVICE]: Request to get home region of user {0}", userID);
196  
197 GridRegion home = null;
198 GridUserInfo uinfo = m_GridUserService.GetGridUserInfo(userID.ToString());
199 if (uinfo != null)
200 {
201 if (uinfo.HomeRegionID != UUID.Zero)
202 {
203 home = m_GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID);
204 position = uinfo.HomePosition;
205 lookAt = uinfo.HomeLookAt;
206 }
207 if (home == null)
208 {
209 List<GridRegion> defs = m_GridService.GetDefaultRegions(UUID.Zero);
210 if (defs != null && defs.Count > 0)
211 home = defs[0];
212 }
213 }
214  
215 return home;
216 }
217  
218 public bool LoginAgentToGrid(AgentCircuitData agentCircuit, GridRegion gatekeeper, GridRegion finalDestination, bool fromLogin, out string reason)
219 {
220 m_log.DebugFormat("[USER AGENT SERVICE]: Request to login user {0} {1} (@{2}) to grid {3}",
221 agentCircuit.firstname, agentCircuit.lastname, (fromLogin ? agentCircuit.IPAddress : "stored IP"), gatekeeper.ServerURI);
222  
223 string gridName = gatekeeper.ServerURI;
224  
225 UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero, agentCircuit.AgentID);
226 if (account == null)
227 {
228 m_log.WarnFormat("[USER AGENT SERVICE]: Someone attempted to lauch a foreign user from here {0} {1}", agentCircuit.firstname, agentCircuit.lastname);
229 reason = "Forbidden to launch your agents from here";
230 return false;
231 }
232  
233 // Is this user allowed to go there?
234 if (m_GridName != gridName)
235 {
236 if (m_ForeignTripsAllowed.ContainsKey(account.UserLevel))
237 {
238 bool allowed = m_ForeignTripsAllowed[account.UserLevel];
239  
240 if (m_ForeignTripsAllowed[account.UserLevel] && IsException(gridName, account.UserLevel, m_TripsAllowedExceptions))
241 allowed = false;
242  
243 if (!m_ForeignTripsAllowed[account.UserLevel] && IsException(gridName, account.UserLevel, m_TripsDisallowedExceptions))
244 allowed = true;
245  
246 if (!allowed)
247 {
248 reason = "Your world does not allow you to visit the destination";
249 m_log.InfoFormat("[USER AGENT SERVICE]: Agents not permitted to visit {0}. Refusing service.", gridName);
250 return false;
251 }
252 }
253 }
254  
255  
256 // Take the IP address + port of the gatekeeper (reg) plus the info of finalDestination
257 GridRegion region = new GridRegion(gatekeeper);
258 region.ServerURI = gatekeeper.ServerURI;
259 region.ExternalHostName = finalDestination.ExternalHostName;
260 region.InternalEndPoint = finalDestination.InternalEndPoint;
261 region.RegionName = finalDestination.RegionName;
262 region.RegionID = finalDestination.RegionID;
263 region.RegionLocX = finalDestination.RegionLocX;
264 region.RegionLocY = finalDestination.RegionLocY;
265  
266 // Generate a new service session
267 agentCircuit.ServiceSessionID = region.ServerURI + ";" + UUID.Random();
268 TravelingAgentInfo old = null;
269 TravelingAgentInfo travel = CreateTravelInfo(agentCircuit, region, fromLogin, out old);
270  
271 bool success = false;
272 string myExternalIP = string.Empty;
273  
274 m_log.DebugFormat("[USER AGENT SERVICE]: this grid: {0}, desired grid: {1}, desired region: {2}", m_GridName, gridName, region.RegionID);
275  
276 if (m_GridName == gridName)
277 success = m_GatekeeperService.LoginAgent(agentCircuit, finalDestination, out reason);
278 else
279 {
280 success = m_GatekeeperConnector.CreateAgent(region, agentCircuit, (uint)Constants.TeleportFlags.ViaLogin, out myExternalIP, out reason);
281 if (success)
282 // Report them as nowhere
283 m_PresenceService.ReportAgent(agentCircuit.SessionID, UUID.Zero);
284 }
285  
286 if (!success)
287 {
288 m_log.DebugFormat("[USER AGENT SERVICE]: Unable to login user {0} {1} to grid {2}, reason: {3}",
289 agentCircuit.firstname, agentCircuit.lastname, region.ServerURI, reason);
290  
291 if (old != null)
292 StoreTravelInfo(old);
293 else
294 m_Database.Delete(agentCircuit.SessionID);
295  
296 return false;
297 }
298  
299 // Everything is ok
300  
301 // Update the perceived IP Address of our grid
302 m_log.DebugFormat("[USER AGENT SERVICE]: Gatekeeper sees me as {0}", myExternalIP);
303 travel.MyIpAddress = myExternalIP;
304  
305 StoreTravelInfo(travel);
306  
307 return true;
308 }
309  
310 public bool LoginAgentToGrid(AgentCircuitData agentCircuit, GridRegion gatekeeper, GridRegion finalDestination, out string reason)
311 {
312 reason = string.Empty;
313 return LoginAgentToGrid(agentCircuit, gatekeeper, finalDestination, false, out reason);
314 }
315  
316 TravelingAgentInfo CreateTravelInfo(AgentCircuitData agentCircuit, GridRegion region, bool fromLogin, out TravelingAgentInfo existing)
317 {
318 HGTravelingData hgt = m_Database.Get(agentCircuit.SessionID);
319 existing = null;
320  
321 if (hgt != null)
322 {
323 // Very important! Override whatever this agent comes with.
324 // UserAgentService always sets the IP for every new agent
325 // with the original IP address.
326 existing = new TravelingAgentInfo(hgt);
327 agentCircuit.IPAddress = existing.ClientIPAddress;
328 }
329  
330 TravelingAgentInfo travel = new TravelingAgentInfo(existing);
331 travel.SessionID = agentCircuit.SessionID;
332 travel.UserID = agentCircuit.AgentID;
333 travel.GridExternalName = region.ServerURI;
334 travel.ServiceToken = agentCircuit.ServiceSessionID;
335  
336 if (fromLogin)
337 travel.ClientIPAddress = agentCircuit.IPAddress;
338  
339 StoreTravelInfo(travel);
340  
341 return travel;
342 }
343  
344 public void LogoutAgent(UUID userID, UUID sessionID)
345 {
346 m_log.DebugFormat("[USER AGENT SERVICE]: User {0} logged out", userID);
347  
348 m_Database.Delete(sessionID);
349  
350 GridUserInfo guinfo = m_GridUserService.GetGridUserInfo(userID.ToString());
351 if (guinfo != null)
352 m_GridUserService.LoggedOut(userID.ToString(), sessionID, guinfo.LastRegionID, guinfo.LastPosition, guinfo.LastLookAt);
353 }
354  
355 // We need to prevent foreign users with the same UUID as a local user
356 public bool IsAgentComingHome(UUID sessionID, string thisGridExternalName)
357 {
358 HGTravelingData hgt = m_Database.Get(sessionID);
359 if (hgt == null)
360 return false;
361  
362 TravelingAgentInfo travel = new TravelingAgentInfo(hgt);
363  
364 return travel.GridExternalName.ToLower() == thisGridExternalName.ToLower();
365 }
366  
367 public bool VerifyClient(UUID sessionID, string reportedIP)
368 {
369 if (m_BypassClientVerification)
370 return true;
371  
372 m_log.DebugFormat("[USER AGENT SERVICE]: Verifying Client session {0} with reported IP {1}.",
373 sessionID, reportedIP);
374  
375 HGTravelingData hgt = m_Database.Get(sessionID);
376 if (hgt == null)
377 return false;
378  
379 TravelingAgentInfo travel = new TravelingAgentInfo(hgt);
380  
381 bool result = travel.ClientIPAddress == reportedIP || travel.MyIpAddress == reportedIP; // NATed
382  
383 m_log.DebugFormat("[USER AGENT SERVICE]: Comparing {0} with login IP {1} and MyIP {1}; result is {3}",
384 reportedIP, travel.ClientIPAddress, travel.MyIpAddress, result);
385  
386 return result;
387 }
388  
389 public bool VerifyAgent(UUID sessionID, string token)
390 {
391 HGTravelingData hgt = m_Database.Get(sessionID);
392 if (hgt == null)
393 {
394 m_log.DebugFormat("[USER AGENT SERVICE]: Token verification for session {0}: no such session", sessionID);
395 return false;
396 }
397  
398 TravelingAgentInfo travel = new TravelingAgentInfo(hgt);
399 m_log.DebugFormat("[USER AGENT SERVICE]: Verifying agent token {0} against {1}", token, travel.ServiceToken);
400 return travel.ServiceToken == token;
401 }
402  
403 [Obsolete]
404 public List<UUID> StatusNotification(List<string> friends, UUID foreignUserID, bool online)
405 {
406 if (m_FriendsService == null || m_PresenceService == null)
407 {
408 m_log.WarnFormat("[USER AGENT SERVICE]: Unable to perform status notifications because friends or presence services are missing");
409 return new List<UUID>();
410 }
411  
412 List<UUID> localFriendsOnline = new List<UUID>();
413  
414 m_log.DebugFormat("[USER AGENT SERVICE]: Status notification: foreign user {0} wants to notify {1} local friends", foreignUserID, friends.Count);
415  
416 // First, let's double check that the reported friends are, indeed, friends of that user
417 // And let's check that the secret matches
418 List<string> usersToBeNotified = new List<string>();
419 foreach (string uui in friends)
420 {
421 UUID localUserID;
422 string secret = string.Empty, tmp = string.Empty;
423 if (Util.ParseUniversalUserIdentifier(uui, out localUserID, out tmp, out tmp, out tmp, out secret))
424 {
425 FriendInfo[] friendInfos = m_FriendsService.GetFriends(localUserID);
426 foreach (FriendInfo finfo in friendInfos)
427 {
428 if (finfo.Friend.StartsWith(foreignUserID.ToString()) && finfo.Friend.EndsWith(secret))
429 {
430 // great!
431 usersToBeNotified.Add(localUserID.ToString());
432 }
433 }
434 }
435 }
436  
437 // Now, let's send the notifications
438 m_log.DebugFormat("[USER AGENT SERVICE]: Status notification: user has {0} local friends", usersToBeNotified.Count);
439  
440 // First, let's send notifications to local users who are online in the home grid
441 PresenceInfo[] friendSessions = m_PresenceService.GetAgents(usersToBeNotified.ToArray());
442 if (friendSessions != null && friendSessions.Length > 0)
443 {
444 PresenceInfo friendSession = null;
445 foreach (PresenceInfo pinfo in friendSessions)
446 if (pinfo.RegionID != UUID.Zero) // let's guard against traveling agents
447 {
448 friendSession = pinfo;
449 break;
450 }
451  
452 if (friendSession != null)
453 {
454 ForwardStatusNotificationToSim(friendSession.RegionID, foreignUserID, friendSession.UserID, online);
455 usersToBeNotified.Remove(friendSession.UserID.ToString());
456 UUID id;
457 if (UUID.TryParse(friendSession.UserID, out id))
458 localFriendsOnline.Add(id);
459  
460 }
461 }
462  
463 //// Lastly, let's notify the rest who may be online somewhere else
464 //foreach (string user in usersToBeNotified)
465 //{
466 // UUID id = new UUID(user);
467 // if (m_Database.ContainsKey(id) && m_Database[id].GridExternalName != m_GridName)
468 // {
469 // string url = m_Database[id].GridExternalName;
470 // // forward
471 // m_log.WarnFormat("[USER AGENT SERVICE]: User {0} is visiting {1}. HG Status notifications still not implemented.", user, url);
472 // }
473 //}
474  
475 // and finally, let's send the online friends
476 if (online)
477 {
478 return localFriendsOnline;
479 }
480 else
481 return new List<UUID>();
482 }
483  
484 [Obsolete]
485 protected void ForwardStatusNotificationToSim(UUID regionID, UUID foreignUserID, string user, bool online)
486 {
487 UUID userID;
488 if (UUID.TryParse(user, out userID))
489 {
490 if (m_FriendsLocalSimConnector != null)
491 {
492 m_log.DebugFormat("[USER AGENT SERVICE]: Local Notify, user {0} is {1}", foreignUserID, (online ? "online" : "offline"));
493 m_FriendsLocalSimConnector.StatusNotify(foreignUserID, userID, online);
494 }
495 else
496 {
497 GridRegion region = m_GridService.GetRegionByUUID(UUID.Zero /* !!! */, regionID);
498 if (region != null)
499 {
500 m_log.DebugFormat("[USER AGENT SERVICE]: Remote Notify to region {0}, user {1} is {2}", region.RegionName, foreignUserID, (online ? "online" : "offline"));
501 m_FriendsSimConnector.StatusNotify(region, foreignUserID, userID.ToString(), online);
502 }
503 }
504 }
505 }
506  
507 public List<UUID> GetOnlineFriends(UUID foreignUserID, List<string> friends)
508 {
509 List<UUID> online = new List<UUID>();
510  
511 if (m_FriendsService == null || m_PresenceService == null)
512 {
513 m_log.WarnFormat("[USER AGENT SERVICE]: Unable to get online friends because friends or presence services are missing");
514 return online;
515 }
516  
517 m_log.DebugFormat("[USER AGENT SERVICE]: Foreign user {0} wants to know status of {1} local friends", foreignUserID, friends.Count);
518  
519 // First, let's double check that the reported friends are, indeed, friends of that user
520 // And let's check that the secret matches and the rights
521 List<string> usersToBeNotified = new List<string>();
522 foreach (string uui in friends)
523 {
524 UUID localUserID;
525 string secret = string.Empty, tmp = string.Empty;
526 if (Util.ParseUniversalUserIdentifier(uui, out localUserID, out tmp, out tmp, out tmp, out secret))
527 {
528 FriendInfo[] friendInfos = m_FriendsService.GetFriends(localUserID);
529 foreach (FriendInfo finfo in friendInfos)
530 {
531 if (finfo.Friend.StartsWith(foreignUserID.ToString()) && finfo.Friend.EndsWith(secret) &&
532 (finfo.TheirFlags & (int)FriendRights.CanSeeOnline) != 0 && (finfo.TheirFlags != -1))
533 {
534 // great!
535 usersToBeNotified.Add(localUserID.ToString());
536 }
537 }
538 }
539 }
540  
541 // Now, let's find out their status
542 m_log.DebugFormat("[USER AGENT SERVICE]: GetOnlineFriends: user has {0} local friends with status rights", usersToBeNotified.Count);
543  
544 // First, let's send notifications to local users who are online in the home grid
545 PresenceInfo[] friendSessions = m_PresenceService.GetAgents(usersToBeNotified.ToArray());
546 if (friendSessions != null && friendSessions.Length > 0)
547 {
548 foreach (PresenceInfo pi in friendSessions)
549 {
550 UUID presenceID;
551 if (UUID.TryParse(pi.UserID, out presenceID))
552 online.Add(presenceID);
553 }
554 }
555  
556 return online;
557 }
558  
559 public Dictionary<string, object> GetUserInfo(UUID userID)
560 {
561 Dictionary<string, object> info = new Dictionary<string, object>();
562  
563 if (m_UserAccountService == null)
564 {
565 m_log.WarnFormat("[USER AGENT SERVICE]: Unable to get user flags because user account service is missing");
566 info["result"] = "fail";
567 info["message"] = "UserAccountService is missing!";
568 return info;
569 }
570  
571 UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero /*!!!*/, userID);
572  
573 if (account != null)
574 {
575 info.Add("user_flags", (object)account.UserFlags);
576 info.Add("user_created", (object)account.Created);
577 info.Add("user_title", (object)account.UserTitle);
578 info.Add("result", "success");
579 }
580  
581 return info;
582 }
583  
584 public Dictionary<string, object> GetServerURLs(UUID userID)
585 {
586 if (m_UserAccountService == null)
587 {
588 m_log.WarnFormat("[USER AGENT SERVICE]: Unable to get server URLs because user account service is missing");
589 return new Dictionary<string, object>();
590 }
591 UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero /*!!!*/, userID);
592 if (account != null)
593 return account.ServiceURLs;
594  
595 return new Dictionary<string, object>();
596 }
597  
598 public string LocateUser(UUID userID)
599 {
600 HGTravelingData[] hgts = m_Database.GetSessions(userID);
601 if (hgts == null)
602 return string.Empty;
603  
604 foreach (HGTravelingData t in hgts)
605 if (t.Data.ContainsKey("GridExternalName") && !m_GridName.Equals(t.Data["GridExternalName"]))
606 return t.Data["GridExternalName"];
607  
608 return string.Empty;
609 }
610  
611 public string GetUUI(UUID userID, UUID targetUserID)
612 {
613 // Let's see if it's a local user
614 UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero, targetUserID);
615 if (account != null)
616 return targetUserID.ToString() + ";" + m_GridName + ";" + account.FirstName + " " + account.LastName ;
617  
618 // Let's try the list of friends
619 FriendInfo[] friends = m_FriendsService.GetFriends(userID);
620 if (friends != null && friends.Length > 0)
621 {
622 foreach (FriendInfo f in friends)
623 if (f.Friend.StartsWith(targetUserID.ToString()))
624 {
625 // Let's remove the secret
626 UUID id; string tmp = string.Empty, secret = string.Empty;
627 if (Util.ParseUniversalUserIdentifier(f.Friend, out id, out tmp, out tmp, out tmp, out secret))
628 return f.Friend.Replace(secret, "0");
629 }
630 }
631  
632 return string.Empty;
633 }
634  
635 public UUID GetUUID(String first, String last)
636 {
637 // Let's see if it's a local user
638 UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero, first, last);
639 if (account != null)
640 {
641 // check user level
642 if (account.UserLevel < m_LevelOutsideContacts)
643 return UUID.Zero;
644 else
645 return account.PrincipalID;
646 }
647 else
648 return UUID.Zero;
649 }
650  
651 #region Misc
652  
653 private bool IsException(string dest, int level, Dictionary<int, List<string>> exceptions)
654 {
655 if (!exceptions.ContainsKey(level))
656 return false;
657  
658 bool exception = false;
659 if (exceptions[level].Count > 0) // we have exceptions
660 {
661 string destination = dest;
662 if (!destination.EndsWith("/"))
663 destination += "/";
664  
665 if (exceptions[level].Find(delegate(string s)
666 {
667 if (!s.EndsWith("/"))
668 s += "/";
669 return s == destination;
670 }) != null)
671 exception = true;
672 }
673  
674 return exception;
675 }
676  
677 private void StoreTravelInfo(TravelingAgentInfo travel)
678 {
679 if (travel == null)
680 return;
681  
682 HGTravelingData hgt = new HGTravelingData();
683 hgt.SessionID = travel.SessionID;
684 hgt.UserID = travel.UserID;
685 hgt.Data = new Dictionary<string, string>();
686 hgt.Data["GridExternalName"] = travel.GridExternalName;
687 hgt.Data["ServiceToken"] = travel.ServiceToken;
688 hgt.Data["ClientIPAddress"] = travel.ClientIPAddress;
689 hgt.Data["MyIPAddress"] = travel.MyIpAddress;
690  
691 m_Database.Store(hgt);
692 }
693 #endregion
694  
695 }
696  
697 class TravelingAgentInfo
698 {
699 public UUID SessionID;
700 public UUID UserID;
701 public string GridExternalName = string.Empty;
702 public string ServiceToken = string.Empty;
703 public string ClientIPAddress = string.Empty; // as seen from this user agent service
704 public string MyIpAddress = string.Empty; // the user agent service's external IP, as seen from the next gatekeeper
705  
706 public TravelingAgentInfo(HGTravelingData t)
707 {
708 if (t.Data != null)
709 {
710 SessionID = new UUID(t.SessionID);
711 UserID = new UUID(t.UserID);
712 GridExternalName = t.Data["GridExternalName"];
713 ServiceToken = t.Data["ServiceToken"];
714 ClientIPAddress = t.Data["ClientIPAddress"];
715 MyIpAddress = t.Data["MyIPAddress"];
716 }
717 }
718  
719 public TravelingAgentInfo(TravelingAgentInfo old)
720 {
721 if (old != null)
722 {
723 SessionID = old.SessionID;
724 UserID = old.UserID;
725 GridExternalName = old.GridExternalName;
726 ServiceToken = old.ServiceToken;
727 ClientIPAddress = old.ClientIPAddress;
728 MyIpAddress = old.MyIpAddress;
729 }
730 }
731 }
732  
733 }