clockwerk-opensim – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 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 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 success = m_GatekeeperConnector.CreateAgent(source, region, agentCircuit, (uint)Constants.TeleportFlags.ViaLogin, out myExternalIP, out reason);
285 }
286  
287 if (!success)
288 {
289 m_log.DebugFormat("[USER AGENT SERVICE]: Unable to login user {0} {1} to grid {2}, reason: {3}",
290 agentCircuit.firstname, agentCircuit.lastname, region.ServerURI, reason);
291  
292 if (old != null)
293 StoreTravelInfo(old);
294 else
295 m_Database.Delete(agentCircuit.SessionID);
296  
297 return false;
298 }
299  
300 // Everything is ok
301  
302 // Update the perceived IP Address of our grid
303 m_log.DebugFormat("[USER AGENT SERVICE]: Gatekeeper sees me as {0}", myExternalIP);
304 travel.MyIpAddress = myExternalIP;
305  
306 StoreTravelInfo(travel);
307  
308 return true;
309 }
310  
311 public bool LoginAgentToGrid(GridRegion source, AgentCircuitData agentCircuit, GridRegion gatekeeper, GridRegion finalDestination, out string reason)
312 {
313 reason = string.Empty;
314 return LoginAgentToGrid(source, agentCircuit, gatekeeper, finalDestination, false, out reason);
315 }
316  
317 TravelingAgentInfo CreateTravelInfo(AgentCircuitData agentCircuit, GridRegion region, bool fromLogin, out TravelingAgentInfo existing)
318 {
319 HGTravelingData hgt = m_Database.Get(agentCircuit.SessionID);
320 existing = null;
321  
322 if (hgt != null)
323 {
324 // Very important! Override whatever this agent comes with.
325 // UserAgentService always sets the IP for every new agent
326 // with the original IP address.
327 existing = new TravelingAgentInfo(hgt);
328 agentCircuit.IPAddress = existing.ClientIPAddress;
329 }
330  
331 TravelingAgentInfo travel = new TravelingAgentInfo(existing);
332 travel.SessionID = agentCircuit.SessionID;
333 travel.UserID = agentCircuit.AgentID;
334 travel.GridExternalName = region.ServerURI;
335 travel.ServiceToken = agentCircuit.ServiceSessionID;
336  
337 if (fromLogin)
338 travel.ClientIPAddress = agentCircuit.IPAddress;
339  
340 StoreTravelInfo(travel);
341  
342 return travel;
343 }
344  
345 public void LogoutAgent(UUID userID, UUID sessionID)
346 {
347 m_log.DebugFormat("[USER AGENT SERVICE]: User {0} logged out", userID);
348  
349 m_Database.Delete(sessionID);
350  
351 GridUserInfo guinfo = m_GridUserService.GetGridUserInfo(userID.ToString());
352 if (guinfo != null)
353 m_GridUserService.LoggedOut(userID.ToString(), sessionID, guinfo.LastRegionID, guinfo.LastPosition, guinfo.LastLookAt);
354 }
355  
356 // We need to prevent foreign users with the same UUID as a local user
357 public bool IsAgentComingHome(UUID sessionID, string thisGridExternalName)
358 {
359 HGTravelingData hgt = m_Database.Get(sessionID);
360 if (hgt == null)
361 return false;
362  
363 TravelingAgentInfo travel = new TravelingAgentInfo(hgt);
364  
365 return travel.GridExternalName.ToLower() == thisGridExternalName.ToLower();
366 }
367  
368 public bool VerifyClient(UUID sessionID, string reportedIP)
369 {
370 if (m_BypassClientVerification)
371 return true;
372  
373 m_log.DebugFormat("[USER AGENT SERVICE]: Verifying Client session {0} with reported IP {1}.",
374 sessionID, reportedIP);
375  
376 HGTravelingData hgt = m_Database.Get(sessionID);
377 if (hgt == null)
378 return false;
379  
380 TravelingAgentInfo travel = new TravelingAgentInfo(hgt);
381  
382 bool result = travel.ClientIPAddress == reportedIP || travel.MyIpAddress == reportedIP; // NATed
383  
384 m_log.DebugFormat("[USER AGENT SERVICE]: Comparing {0} with login IP {1} and MyIP {1}; result is {3}",
385 reportedIP, travel.ClientIPAddress, travel.MyIpAddress, result);
386  
387 return result;
388 }
389  
390 public bool VerifyAgent(UUID sessionID, string token)
391 {
392 HGTravelingData hgt = m_Database.Get(sessionID);
393 if (hgt == null)
394 {
395 m_log.DebugFormat("[USER AGENT SERVICE]: Token verification for session {0}: no such session", sessionID);
396 return false;
397 }
398  
399 TravelingAgentInfo travel = new TravelingAgentInfo(hgt);
400 m_log.DebugFormat("[USER AGENT SERVICE]: Verifying agent token {0} against {1}", token, travel.ServiceToken);
401 return travel.ServiceToken == token;
402 }
403  
404 [Obsolete]
405 public List<UUID> StatusNotification(List<string> friends, UUID foreignUserID, bool online)
406 {
407 if (m_FriendsService == null || m_PresenceService == null)
408 {
409 m_log.WarnFormat("[USER AGENT SERVICE]: Unable to perform status notifications because friends or presence services are missing");
410 return new List<UUID>();
411 }
412  
413 List<UUID> localFriendsOnline = new List<UUID>();
414  
415 m_log.DebugFormat("[USER AGENT SERVICE]: Status notification: foreign user {0} wants to notify {1} local friends", foreignUserID, friends.Count);
416  
417 // First, let's double check that the reported friends are, indeed, friends of that user
418 // And let's check that the secret matches
419 List<string> usersToBeNotified = new List<string>();
420 foreach (string uui in friends)
421 {
422 UUID localUserID;
423 string secret = string.Empty, tmp = string.Empty;
424 if (Util.ParseUniversalUserIdentifier(uui, out localUserID, out tmp, out tmp, out tmp, out secret))
425 {
426 FriendInfo[] friendInfos = m_FriendsService.GetFriends(localUserID);
427 foreach (FriendInfo finfo in friendInfos)
428 {
429 if (finfo.Friend.StartsWith(foreignUserID.ToString()) && finfo.Friend.EndsWith(secret))
430 {
431 // great!
432 usersToBeNotified.Add(localUserID.ToString());
433 }
434 }
435 }
436 }
437  
438 // Now, let's send the notifications
439 m_log.DebugFormat("[USER AGENT SERVICE]: Status notification: user has {0} local friends", usersToBeNotified.Count);
440  
441 // First, let's send notifications to local users who are online in the home grid
442 PresenceInfo[] friendSessions = m_PresenceService.GetAgents(usersToBeNotified.ToArray());
443 if (friendSessions != null && friendSessions.Length > 0)
444 {
445 PresenceInfo friendSession = null;
446 foreach (PresenceInfo pinfo in friendSessions)
447 if (pinfo.RegionID != UUID.Zero) // let's guard against traveling agents
448 {
449 friendSession = pinfo;
450 break;
451 }
452  
453 if (friendSession != null)
454 {
455 ForwardStatusNotificationToSim(friendSession.RegionID, foreignUserID, friendSession.UserID, online);
456 usersToBeNotified.Remove(friendSession.UserID.ToString());
457 UUID id;
458 if (UUID.TryParse(friendSession.UserID, out id))
459 localFriendsOnline.Add(id);
460  
461 }
462 }
463  
464 //// Lastly, let's notify the rest who may be online somewhere else
465 //foreach (string user in usersToBeNotified)
466 //{
467 // UUID id = new UUID(user);
468 // if (m_Database.ContainsKey(id) && m_Database[id].GridExternalName != m_GridName)
469 // {
470 // string url = m_Database[id].GridExternalName;
471 // // forward
472 // m_log.WarnFormat("[USER AGENT SERVICE]: User {0} is visiting {1}. HG Status notifications still not implemented.", user, url);
473 // }
474 //}
475  
476 // and finally, let's send the online friends
477 if (online)
478 {
479 return localFriendsOnline;
480 }
481 else
482 return new List<UUID>();
483 }
484  
485 [Obsolete]
486 protected void ForwardStatusNotificationToSim(UUID regionID, UUID foreignUserID, string user, bool online)
487 {
488 UUID userID;
489 if (UUID.TryParse(user, out userID))
490 {
491 if (m_FriendsLocalSimConnector != null)
492 {
493 m_log.DebugFormat("[USER AGENT SERVICE]: Local Notify, user {0} is {1}", foreignUserID, (online ? "online" : "offline"));
494 m_FriendsLocalSimConnector.StatusNotify(foreignUserID, userID, online);
495 }
496 else
497 {
498 GridRegion region = m_GridService.GetRegionByUUID(UUID.Zero /* !!! */, regionID);
499 if (region != null)
500 {
501 m_log.DebugFormat("[USER AGENT SERVICE]: Remote Notify to region {0}, user {1} is {2}", region.RegionName, foreignUserID, (online ? "online" : "offline"));
502 m_FriendsSimConnector.StatusNotify(region, foreignUserID, userID.ToString(), online);
503 }
504 }
505 }
506 }
507  
508 public List<UUID> GetOnlineFriends(UUID foreignUserID, List<string> friends)
509 {
510 List<UUID> online = new List<UUID>();
511  
512 if (m_FriendsService == null || m_PresenceService == null)
513 {
514 m_log.WarnFormat("[USER AGENT SERVICE]: Unable to get online friends because friends or presence services are missing");
515 return online;
516 }
517  
518 m_log.DebugFormat("[USER AGENT SERVICE]: Foreign user {0} wants to know status of {1} local friends", foreignUserID, friends.Count);
519  
520 // First, let's double check that the reported friends are, indeed, friends of that user
521 // And let's check that the secret matches and the rights
522 List<string> usersToBeNotified = new List<string>();
523 foreach (string uui in friends)
524 {
525 UUID localUserID;
526 string secret = string.Empty, tmp = string.Empty;
527 if (Util.ParseUniversalUserIdentifier(uui, out localUserID, out tmp, out tmp, out tmp, out secret))
528 {
529 FriendInfo[] friendInfos = m_FriendsService.GetFriends(localUserID);
530 foreach (FriendInfo finfo in friendInfos)
531 {
532 if (finfo.Friend.StartsWith(foreignUserID.ToString()) && finfo.Friend.EndsWith(secret) &&
533 (finfo.TheirFlags & (int)FriendRights.CanSeeOnline) != 0 && (finfo.TheirFlags != -1))
534 {
535 // great!
536 usersToBeNotified.Add(localUserID.ToString());
537 }
538 }
539 }
540 }
541  
542 // Now, let's find out their status
543 m_log.DebugFormat("[USER AGENT SERVICE]: GetOnlineFriends: user has {0} local friends with status rights", usersToBeNotified.Count);
544  
545 // First, let's send notifications to local users who are online in the home grid
546 PresenceInfo[] friendSessions = m_PresenceService.GetAgents(usersToBeNotified.ToArray());
547 if (friendSessions != null && friendSessions.Length > 0)
548 {
549 foreach (PresenceInfo pi in friendSessions)
550 {
551 UUID presenceID;
552 if (UUID.TryParse(pi.UserID, out presenceID))
553 online.Add(presenceID);
554 }
555 }
556  
557 return online;
558 }
559  
560 public Dictionary<string, object> GetUserInfo(UUID userID)
561 {
562 Dictionary<string, object> info = new Dictionary<string, object>();
563  
564 if (m_UserAccountService == null)
565 {
566 m_log.WarnFormat("[USER AGENT SERVICE]: Unable to get user flags because user account service is missing");
567 info["result"] = "fail";
568 info["message"] = "UserAccountService is missing!";
569 return info;
570 }
571  
572 UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero /*!!!*/, userID);
573  
574 if (account != null)
575 {
576 info.Add("user_firstname", account.FirstName);
577 info.Add("user_lastname", account.LastName);
578 info.Add("result", "success");
579  
580 if (m_ShowDetails)
581 {
582 info.Add("user_flags", account.UserFlags);
583 info.Add("user_created", account.Created);
584 info.Add("user_title", account.UserTitle);
585 }
586 else
587 {
588 info.Add("user_flags", 0);
589 info.Add("user_created", 0);
590 info.Add("user_title", string.Empty);
591 }
592 }
593  
594 return info;
595 }
596  
597 public Dictionary<string, object> GetServerURLs(UUID userID)
598 {
599 if (m_UserAccountService == null)
600 {
601 m_log.WarnFormat("[USER AGENT SERVICE]: Unable to get server URLs because user account service is missing");
602 return new Dictionary<string, object>();
603 }
604 UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero /*!!!*/, userID);
605 if (account != null)
606 return account.ServiceURLs;
607  
608 return new Dictionary<string, object>();
609 }
610  
611 public string LocateUser(UUID userID)
612 {
613 HGTravelingData[] hgts = m_Database.GetSessions(userID);
614 if (hgts == null)
615 return string.Empty;
616  
617 foreach (HGTravelingData t in hgts)
618 if (t.Data.ContainsKey("GridExternalName") && !m_GridName.Equals(t.Data["GridExternalName"]))
619 return t.Data["GridExternalName"];
620  
621 return string.Empty;
622 }
623  
624 public string GetUUI(UUID userID, UUID targetUserID)
625 {
626 // Let's see if it's a local user
627 UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero, targetUserID);
628 if (account != null)
629 return targetUserID.ToString() + ";" + m_GridName + ";" + account.FirstName + " " + account.LastName ;
630  
631 // Let's try the list of friends
632 FriendInfo[] friends = m_FriendsService.GetFriends(userID);
633 if (friends != null && friends.Length > 0)
634 {
635 foreach (FriendInfo f in friends)
636 if (f.Friend.StartsWith(targetUserID.ToString()))
637 {
638 // Let's remove the secret
639 UUID id; string tmp = string.Empty, secret = string.Empty;
640 if (Util.ParseUniversalUserIdentifier(f.Friend, out id, out tmp, out tmp, out tmp, out secret))
641 return f.Friend.Replace(secret, "0");
642 }
643 }
644  
645 return string.Empty;
646 }
647  
648 public UUID GetUUID(String first, String last)
649 {
650 // Let's see if it's a local user
651 UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero, first, last);
652 if (account != null)
653 {
654 // check user level
655 if (account.UserLevel < m_LevelOutsideContacts)
656 return UUID.Zero;
657 else
658 return account.PrincipalID;
659 }
660 else
661 return UUID.Zero;
662 }
663  
664 #region Misc
665  
666 private bool IsException(string dest, int level, Dictionary<int, List<string>> exceptions)
667 {
668 if (!exceptions.ContainsKey(level))
669 return false;
670  
671 bool exception = false;
672 if (exceptions[level].Count > 0) // we have exceptions
673 {
674 string destination = dest;
675 if (!destination.EndsWith("/"))
676 destination += "/";
677  
678 if (exceptions[level].Find(delegate(string s)
679 {
680 if (!s.EndsWith("/"))
681 s += "/";
682 return s == destination;
683 }) != null)
684 exception = true;
685 }
686  
687 return exception;
688 }
689  
690 private void StoreTravelInfo(TravelingAgentInfo travel)
691 {
692 if (travel == null)
693 return;
694  
695 HGTravelingData hgt = new HGTravelingData();
696 hgt.SessionID = travel.SessionID;
697 hgt.UserID = travel.UserID;
698 hgt.Data = new Dictionary<string, string>();
699 hgt.Data["GridExternalName"] = travel.GridExternalName;
700 hgt.Data["ServiceToken"] = travel.ServiceToken;
701 hgt.Data["ClientIPAddress"] = travel.ClientIPAddress;
702 hgt.Data["MyIPAddress"] = travel.MyIpAddress;
703  
704 m_Database.Store(hgt);
705 }
706 #endregion
707  
708 }
709  
710 class TravelingAgentInfo
711 {
712 public UUID SessionID;
713 public UUID UserID;
714 public string GridExternalName = string.Empty;
715 public string ServiceToken = string.Empty;
716 public string ClientIPAddress = string.Empty; // as seen from this user agent service
717 public string MyIpAddress = string.Empty; // the user agent service's external IP, as seen from the next gatekeeper
718  
719 public TravelingAgentInfo(HGTravelingData t)
720 {
721 if (t.Data != null)
722 {
723 SessionID = new UUID(t.SessionID);
724 UserID = new UUID(t.UserID);
725 GridExternalName = t.Data["GridExternalName"];
726 ServiceToken = t.Data["ServiceToken"];
727 ClientIPAddress = t.Data["ClientIPAddress"];
728 MyIpAddress = t.Data["MyIPAddress"];
729 }
730 }
731  
732 public TravelingAgentInfo(TravelingAgentInfo old)
733 {
734 if (old != null)
735 {
736 SessionID = old.SessionID;
737 UserID = old.UserID;
738 GridExternalName = old.GridExternalName;
739 ServiceToken = old.ServiceToken;
740 ClientIPAddress = old.ClientIPAddress;
741 MyIpAddress = old.MyIpAddress;
742 }
743 }
744 }
745  
746 }