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