29 using System.Collections.Generic;
31 using System.Reflection;
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;
46 namespace OpenSim.Services.HypergridService
56 private static readonly ILog m_log =
58 MethodBase.GetCurrentMethod().DeclaringType);
63 static bool m_Initialized =
false;
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>>();
95 if (friendsConnector != null)
96 m_FriendsLocalSimConnector = friendsConnector;
100 m_Initialized =
true;
102 m_log.DebugFormat(
"[HOME USERS SECURITY]: Starting...");
106 IConfig serverConfig = config.Configs[
"UserAgentService"];
107 if (serverConfig == null)
108 throw new Exception(String.Format(
"No section UserAgentService in config file"));
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);
117 m_BypassClientVerification = serverConfig.GetBoolean(
"BypassClientVerification",
false);
119 if (gridService ==
string.Empty || gridUserService ==
string.Empty || gatekeeperService ==
string.Empty)
120 throw new Exception(String.Format(
"Incomplete specifications, UserAgent Service cannot function."));
122 Object[] args =
new Object[] { config };
123 m_GridService = ServerUtils.LoadPlugin<
IGridService>(gridService, args);
124 m_GridUserService = ServerUtils.LoadPlugin<
IGridUserService>(gridUserService, args);
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);
131 m_LevelOutsideContacts = serverConfig.GetInt(
"LevelOutsideContacts", 0);
132 m_ShowDetails = serverConfig.GetBoolean(
"ShowUserDetailsInHGProfile",
true);
134 LoadTripPermissionsFromConfig(serverConfig,
"ForeignTripsAllowed");
135 LoadDomainExceptionsFromConfig(serverConfig,
"AllowExcept", m_TripsAllowedExceptions);
136 LoadDomainExceptionsFromConfig(serverConfig,
"DisallowExcept", m_TripsDisallowedExceptions);
138 m_GridName = Util.GetConfigVarFromSections<
string>(config,
"GatekeeperURI",
139 new string[] {
"Startup",
"Hypergrid",
"UserAgentService" }, String.Empty);
140 if (
string.IsNullOrEmpty(m_GridName))
142 m_GridName = serverConfig.GetString(
"ExternalName", string.Empty);
143 if (m_GridName ==
string.Empty)
145 serverConfig = config.Configs[
"GatekeeperService"];
146 m_GridName = serverConfig.GetString(
"ExternalName", string.Empty);
150 if (!m_GridName.EndsWith(
"/"))
151 m_GridName = m_GridName +
"/";
154 m_Database.DeleteOld();
161 foreach (
string keyName
in config.GetKeys())
163 if (keyName.StartsWith(variable +
"_Level_"))
166 if (Int32.TryParse(keyName.Replace(variable +
"_Level_",
""), out level))
167 m_ForeignTripsAllowed.Add(level, config.GetBoolean(keyName,
true));
174 foreach (
string keyName
in config.GetKeys())
176 if (keyName.StartsWith(variable +
"_Level_"))
179 if (Int32.TryParse(keyName.Replace(variable +
"_Level_",
""), out level) && !exceptions.ContainsKey(level))
181 exceptions.Add(level,
new List<string>());
182 string value = config.GetString(keyName, string.Empty);
183 string[] parts = value.Split(
new char[] {
',' }, StringSplitOptions.RemoveEmptyEntries);
185 foreach (
string s
in parts)
186 exceptions[level].Add(s.Trim());
195 position =
new Vector3(128, 128, 0); lookAt = Vector3.UnitY;
197 m_log.DebugFormat(
"[USER AGENT SERVICE]: Request to get home region of user {0}", userID);
200 GridUserInfo uinfo = m_GridUserService.GetGridUserInfo(userID.ToString());
205 home = m_GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID);
206 position = uinfo.HomePosition;
207 lookAt = uinfo.HomeLookAt;
211 List<GridRegion> defs = m_GridService.GetDefaultRegions(UUID.Zero);
212 if (defs != null && defs.Count > 0)
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);
225 string gridName = gatekeeper.ServerURI;
227 UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero, agentCircuit.AgentID);
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";
236 if (m_GridName != gridName)
238 if (m_ForeignTripsAllowed.ContainsKey(account.
UserLevel))
240 bool allowed = m_ForeignTripsAllowed[account.UserLevel];
242 if (m_ForeignTripsAllowed[account.
UserLevel] && IsException(gridName, account.
UserLevel, m_TripsAllowedExceptions))
245 if (!m_ForeignTripsAllowed[account.
UserLevel] && IsException(gridName, account.
UserLevel, m_TripsDisallowedExceptions))
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);
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;
269 agentCircuit.ServiceSessionID = region.ServerURI +
";" + UUID.Random();
271 TravelingAgentInfo travel = CreateTravelInfo(agentCircuit, region, fromLogin, out old);
273 bool success =
false;
274 string myExternalIP = string.Empty;
276 m_log.DebugFormat(
"[USER AGENT SERVICE]: this grid: {0}, desired grid: {1}, desired region: {2}", m_GridName, gridName, region.RegionID);
278 if (m_GridName == gridName)
280 success = m_GatekeeperService.LoginAgent(source, agentCircuit, finalDestination, out reason);
286 success = m_GatekeeperConnector.CreateAgent(source, region, agentCircuit, (uint)
Constants.
TeleportFlags.ViaLogin, ctx, out myExternalIP, out reason);
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);
295 StoreTravelInfo(old);
297 m_Database.Delete(agentCircuit.SessionID);
305 m_log.DebugFormat(
"[USER AGENT SERVICE]: Gatekeeper sees me as {0}", myExternalIP);
306 travel.MyIpAddress = myExternalIP;
308 StoreTravelInfo(travel);
315 reason = string.Empty;
316 return LoginAgentToGrid(source, agentCircuit, gatekeeper, finalDestination,
false, out reason);
330 agentCircuit.IPAddress = existing.ClientIPAddress;
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;
340 travel.ClientIPAddress = agentCircuit.IPAddress;
342 StoreTravelInfo(travel);
349 m_log.DebugFormat(
"[USER AGENT SERVICE]: User {0} logged out", userID);
351 m_Database.Delete(sessionID);
353 GridUserInfo guinfo = m_GridUserService.GetGridUserInfo(userID.ToString());
355 m_GridUserService.LoggedOut(userID.ToString(), sessionID, guinfo.LastRegionID, guinfo.LastPosition, guinfo.LastLookAt);
367 return travel.GridExternalName.ToLower() == thisGridExternalName.ToLower();
372 if (m_BypassClientVerification)
375 m_log.DebugFormat(
"[USER AGENT SERVICE]: Verifying Client session {0} with reported IP {1}.",
376 sessionID, reportedIP);
384 bool result = travel.ClientIPAddress == reportedIP || travel.MyIpAddress == reportedIP;
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);
397 m_log.DebugFormat(
"[USER AGENT SERVICE]: Token verification for session {0}: no such session", sessionID);
402 m_log.DebugFormat(
"[USER AGENT SERVICE]: Verifying agent token {0} against {1}", token, travel.ServiceToken);
403 return travel.ServiceToken == token;
409 if (m_FriendsService == null || m_PresenceService == null)
411 m_log.WarnFormat(
"[USER AGENT SERVICE]: Unable to perform status notifications because friends or presence services are missing");
412 return new List<UUID>();
415 List<UUID> localFriendsOnline =
new List<UUID>();
417 m_log.DebugFormat(
"[USER AGENT SERVICE]: Status notification: foreign user {0} wants to notify {1} local friends", foreignUserID, friends.Count);
421 List<string> usersToBeNotified =
new List<string>();
422 foreach (
string uui
in friends)
425 string secret = string.Empty, tmp = string.Empty;
426 if (Util.ParseUniversalUserIdentifier(uui, out localUserID, out tmp, out tmp, out tmp, out secret))
428 FriendInfo[] friendInfos = m_FriendsService.GetFriends(localUserID);
431 if (finfo.
Friend.StartsWith(foreignUserID.ToString()) && finfo.
Friend.EndsWith(secret))
434 usersToBeNotified.Add(localUserID.ToString());
441 m_log.DebugFormat(
"[USER AGENT SERVICE]: Status notification: user has {0} local friends", usersToBeNotified.Count);
444 PresenceInfo[] friendSessions = m_PresenceService.GetAgents(usersToBeNotified.ToArray());
445 if (friendSessions != null && friendSessions.Length > 0)
451 friendSession = pinfo;
455 if (friendSession != null)
457 ForwardStatusNotificationToSim(friendSession.RegionID, foreignUserID, friendSession.UserID, online);
458 usersToBeNotified.Remove(friendSession.UserID.ToString());
460 if (UUID.TryParse(friendSession.UserID, out
id))
461 localFriendsOnline.Add(
id);
481 return localFriendsOnline;
484 return new List<UUID>();
491 if (UUID.TryParse(user, out userID))
493 if (m_FriendsLocalSimConnector != null)
495 m_log.DebugFormat(
"[USER AGENT SERVICE]: Local Notify, user {0} is {1}", foreignUserID, (online ?
"online" :
"offline"));
496 m_FriendsLocalSimConnector.StatusNotify(foreignUserID, userID, online);
500 GridRegion region = m_GridService.GetRegionByUUID(UUID.Zero , regionID);
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);
512 List<UUID> online =
new List<UUID>();
514 if (m_FriendsService == null || m_PresenceService == null)
516 m_log.WarnFormat(
"[USER AGENT SERVICE]: Unable to get online friends because friends or presence services are missing");
520 m_log.DebugFormat(
"[USER AGENT SERVICE]: Foreign user {0} wants to know status of {1} local friends", foreignUserID, friends.Count);
524 List<string> usersToBeNotified =
new List<string>();
525 foreach (
string uui
in friends)
528 string secret = string.Empty, tmp = string.Empty;
529 if (Util.ParseUniversalUserIdentifier(uui, out localUserID, out tmp, out tmp, out tmp, out secret))
531 FriendInfo[] friendInfos = m_FriendsService.GetFriends(localUserID);
534 if (finfo.
Friend.StartsWith(foreignUserID.ToString()) && finfo.
Friend.EndsWith(secret) &&
535 (finfo.TheirFlags & (int)FriendRights.CanSeeOnline) != 0 && (finfo.TheirFlags != -1))
538 usersToBeNotified.Add(localUserID.ToString());
545 m_log.DebugFormat(
"[USER AGENT SERVICE]: GetOnlineFriends: user has {0} local friends with status rights", usersToBeNotified.Count);
548 PresenceInfo[] friendSessions = m_PresenceService.GetAgents(usersToBeNotified.ToArray());
549 if (friendSessions != null && friendSessions.Length > 0)
554 if (UUID.TryParse(pi.
UserID, out presenceID))
555 online.Add(presenceID);
564 Dictionary<string, object> info =
new Dictionary<string, object>();
566 if (m_UserAccountService == null)
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!";
574 UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero , userID);
578 info.Add(
"user_firstname", account.FirstName);
579 info.Add(
"user_lastname", account.LastName);
580 info.Add(
"result",
"success");
584 info.Add(
"user_flags", account.UserFlags);
585 info.Add(
"user_created", account.Created);
586 info.Add(
"user_title", account.UserTitle);
590 info.Add(
"user_flags", 0);
591 info.Add(
"user_created", 0);
592 info.Add(
"user_title", string.Empty);
601 if (m_UserAccountService == null)
603 m_log.WarnFormat(
"[USER AGENT SERVICE]: Unable to get server URLs because user account service is missing");
604 return new Dictionary<string, object>();
606 UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero , userID);
608 return account.ServiceURLs;
610 return new Dictionary<string, object>();
620 if (t.
Data.ContainsKey(
"GridExternalName") && !m_GridName.Equals(t.Data[
"GridExternalName"]))
621 return t.Data[
"GridExternalName"];
626 public string GetUUI(UUID userID, UUID targetUserID)
629 UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero, targetUserID);
631 return targetUserID.ToString() +
";" + m_GridName +
";" + account.
FirstName +
" " + account.
LastName ;
634 FriendInfo[] friends = m_FriendsService.GetFriends(userID);
635 if (friends != null && friends.Length > 0)
638 if (f.
Friend.StartsWith(targetUserID.ToString()))
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");
650 public UUID
GetUUID(String first, String last)
653 UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero, first, last);
657 if (account.
UserLevel < m_LevelOutsideContacts)
660 return account.PrincipalID;
668 private bool IsException(
string dest,
int level, Dictionary<
int, List<string>> exceptions)
670 if (!exceptions.ContainsKey(level))
673 bool exception =
false;
674 if (exceptions[level].Count > 0)
676 string destination = dest;
677 if (!destination.EndsWith(
"/"))
680 if (exceptions[level].Find(delegate(
string s)
682 if (!s.EndsWith(
"/"))
684 return s == destination;
692 private void StoreTravelInfo(TravelingAgentInfo travel)
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;
706 m_Database.Store(hgt);
716 public string GridExternalName = string.Empty;
717 public string ServiceToken = string.Empty;
718 public string ClientIPAddress = string.Empty;
719 public string MyIpAddress = string.Empty;
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"];
738 SessionID = old.SessionID;
740 GridExternalName = old.GridExternalName;
741 ServiceToken = old.ServiceToken;
742 ClientIPAddress = old.ClientIPAddress;
743 MyIpAddress = old.MyIpAddress;
Dictionary< string, object > GetServerURLs(UUID userID)
Returns the Server URLs of a remote user.
static IGatekeeperService m_GatekeeperService
static IGridService m_GridService
bool LoginAgentToGrid(GridRegion source, AgentCircuitData agentCircuit, GridRegion gatekeeper, GridRegion finalDestination, out string reason)
static IPresenceService m_PresenceService
void ForwardStatusNotificationToSim(UUID regionID, UUID foreignUserID, string user, bool online)
bool VerifyAgent(UUID sessionID, string token)
static bool m_BypassClientVerification
static IGridUserService m_GridUserService
List< UUID > StatusNotification(List< string > friends, UUID foreignUserID, bool online)
static IUserAccountService m_UserAccountService
static IFriendsService m_FriendsService
static int m_LevelOutsideContacts
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)
static FriendsSimConnector m_FriendsSimConnector
TravelingAgentInfo(HGTravelingData t)
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.
UserAgentService(IConfigSource config)
string LocateUser(UUID userID)
Returns the current location of a remote user.
static GatekeeperServiceConnector m_GatekeeperConnector
static bool m_ShowDetails
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)
TravelingAgentInfo(TravelingAgentInfo old)
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