GatekeeperService.cs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  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. using System;
  28. using System.Collections.Generic;
  29. using System.Net;
  30. using System.Reflection;
  31. using System.Text.RegularExpressions;
  32. using OpenSim.Framework;
  33. using OpenSim.Services.Interfaces;
  34. using GridRegion = OpenSim.Services.Interfaces.GridRegion;
  35. using OpenSim.Server.Base;
  36. using OpenSim.Services.Connectors.InstantMessage;
  37. using OpenSim.Services.Connectors.Hypergrid;
  38. using OpenMetaverse;
  39. using Nini.Config;
  40. using log4net;
  41. namespace OpenSim.Services.HypergridService
  42. {
  43. public class GatekeeperService : IGatekeeperService
  44. {
  45. private static readonly ILog m_log =
  46. LogManager.GetLogger(
  47. MethodBase.GetCurrentMethod().DeclaringType);
  48. private static bool m_Initialized = false;
  49. private static IGridService m_GridService;
  50. private static IPresenceService m_PresenceService;
  51. private static IUserAccountService m_UserAccountService;
  52. private static IUserAgentService m_UserAgentService;
  53. private static ISimulationService m_SimulationService;
  54. private static IGridUserService m_GridUserService;
  55. private static IBansService m_BansService;
  56. private static string m_AllowedClients = string.Empty;
  57. private static string m_DeniedClients = string.Empty;
  58. private static string m_DeniedMacs = string.Empty;
  59. private static bool m_ForeignAgentsAllowed = true;
  60. private static List<string> m_ForeignsAllowedExceptions = new List<string>();
  61. private static List<string> m_ForeignsDisallowedExceptions = new List<string>();
  62. private static UUID m_ScopeID;
  63. private static bool m_AllowTeleportsToAnyRegion;
  64. private static string m_ExternalName;
  65. private static Uri m_Uri;
  66. private static GridRegion m_DefaultGatewayRegion;
  67. private bool m_allowDuplicatePresences = false;
  68. private static string m_messageKey;
  69. public GatekeeperService(IConfigSource config, ISimulationService simService)
  70. {
  71. if (!m_Initialized)
  72. {
  73. m_Initialized = true;
  74. IConfig serverConfig = config.Configs["GatekeeperService"];
  75. if (serverConfig == null)
  76. throw new Exception(String.Format("No section GatekeeperService in config file"));
  77. string accountService = serverConfig.GetString("UserAccountService", String.Empty);
  78. string homeUsersService = serverConfig.GetString("UserAgentService", string.Empty);
  79. string gridService = serverConfig.GetString("GridService", String.Empty);
  80. string presenceService = serverConfig.GetString("PresenceService", String.Empty);
  81. string simulationService = serverConfig.GetString("SimulationService", String.Empty);
  82. string gridUserService = serverConfig.GetString("GridUserService", String.Empty);
  83. string bansService = serverConfig.GetString("BansService", String.Empty);
  84. // These are mandatory, the others aren't
  85. if (gridService == string.Empty || presenceService == string.Empty)
  86. throw new Exception("Incomplete specifications, Gatekeeper Service cannot function.");
  87. string scope = serverConfig.GetString("ScopeID", UUID.Zero.ToString());
  88. UUID.TryParse(scope, out m_ScopeID);
  89. //m_WelcomeMessage = serverConfig.GetString("WelcomeMessage", "Welcome to OpenSim!");
  90. m_AllowTeleportsToAnyRegion = serverConfig.GetBoolean("AllowTeleportsToAnyRegion", true);
  91. m_ExternalName = Util.GetConfigVarFromSections<string>(config, "GatekeeperURI",
  92. new string[] { "Startup", "Hypergrid", "GatekeeperService" }, String.Empty);
  93. m_ExternalName = serverConfig.GetString("ExternalName", m_ExternalName);
  94. if (m_ExternalName != string.Empty && !m_ExternalName.EndsWith("/"))
  95. m_ExternalName = m_ExternalName + "/";
  96. try
  97. {
  98. m_Uri = new Uri(m_ExternalName);
  99. }
  100. catch
  101. {
  102. m_log.WarnFormat("[GATEKEEPER SERVICE]: Malformed gatekeeper address {0}", m_ExternalName);
  103. }
  104. Object[] args = new Object[] { config };
  105. m_GridService = ServerUtils.LoadPlugin<IGridService>(gridService, args);
  106. m_PresenceService = ServerUtils.LoadPlugin<IPresenceService>(presenceService, args);
  107. if (accountService != string.Empty)
  108. m_UserAccountService = ServerUtils.LoadPlugin<IUserAccountService>(accountService, args);
  109. if (homeUsersService != string.Empty)
  110. m_UserAgentService = ServerUtils.LoadPlugin<IUserAgentService>(homeUsersService, args);
  111. if (gridUserService != string.Empty)
  112. m_GridUserService = ServerUtils.LoadPlugin<IGridUserService>(gridUserService, args);
  113. if (bansService != string.Empty)
  114. m_BansService = ServerUtils.LoadPlugin<IBansService>(bansService, args);
  115. if (simService != null)
  116. m_SimulationService = simService;
  117. else if (simulationService != string.Empty)
  118. m_SimulationService = ServerUtils.LoadPlugin<ISimulationService>(simulationService, args);
  119. string[] possibleAccessControlConfigSections = new string[] { "AccessControl", "GatekeeperService" };
  120. m_AllowedClients = Util.GetConfigVarFromSections<string>(
  121. config, "AllowedClients", possibleAccessControlConfigSections, string.Empty);
  122. m_DeniedClients = Util.GetConfigVarFromSections<string>(
  123. config, "DeniedClients", possibleAccessControlConfigSections, string.Empty);
  124. m_DeniedMacs = Util.GetConfigVarFromSections<string>(
  125. config, "DeniedMacs", possibleAccessControlConfigSections, string.Empty);
  126. m_ForeignAgentsAllowed = serverConfig.GetBoolean("ForeignAgentsAllowed", true);
  127. LoadDomainExceptionsFromConfig(serverConfig, "AllowExcept", m_ForeignsAllowedExceptions);
  128. LoadDomainExceptionsFromConfig(serverConfig, "DisallowExcept", m_ForeignsDisallowedExceptions);
  129. if (m_GridService == null || m_PresenceService == null || m_SimulationService == null)
  130. throw new Exception("Unable to load a required plugin, Gatekeeper Service cannot function.");
  131. IConfig presenceConfig = config.Configs["PresenceService"];
  132. if (presenceConfig != null)
  133. {
  134. m_allowDuplicatePresences = presenceConfig.GetBoolean("AllowDuplicatePresences", m_allowDuplicatePresences);
  135. }
  136. IConfig messagingConfig = config.Configs["Messaging"];
  137. if (messagingConfig != null)
  138. m_messageKey = messagingConfig.GetString("MessageKey", String.Empty);
  139. m_log.Debug("[GATEKEEPER SERVICE]: Starting...");
  140. }
  141. }
  142. public GatekeeperService(IConfigSource config)
  143. : this(config, null)
  144. {
  145. }
  146. protected void LoadDomainExceptionsFromConfig(IConfig config, string variable, List<string> exceptions)
  147. {
  148. string value = config.GetString(variable, string.Empty);
  149. string[] parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  150. foreach (string s in parts)
  151. exceptions.Add(s.Trim());
  152. }
  153. public bool LinkRegion(string regionName, out UUID regionID, out ulong regionHandle, out string externalName, out string imageURL, out string reason, out int sizeX, out int sizeY)
  154. {
  155. regionID = UUID.Zero;
  156. regionHandle = 0;
  157. sizeX = (int)Constants.RegionSize;
  158. sizeY = (int)Constants.RegionSize;
  159. externalName = m_ExternalName + ((regionName != string.Empty) ? " " + regionName : "");
  160. imageURL = string.Empty;
  161. reason = string.Empty;
  162. GridRegion region = null;
  163. m_log.DebugFormat("[GATEKEEPER SERVICE]: Request to link to {0}", (regionName == string.Empty)? "default region" : regionName);
  164. if (!m_AllowTeleportsToAnyRegion || regionName == string.Empty)
  165. {
  166. List<GridRegion> defs = m_GridService.GetDefaultHypergridRegions(m_ScopeID);
  167. if (defs != null && defs.Count > 0)
  168. {
  169. region = defs[0];
  170. m_DefaultGatewayRegion = region;
  171. }
  172. else
  173. {
  174. reason = "Grid setup problem. Try specifying a particular region here.";
  175. m_log.DebugFormat("[GATEKEEPER SERVICE]: Unable to send information. Please specify a default region for this grid!");
  176. return false;
  177. }
  178. }
  179. else
  180. {
  181. region = m_GridService.GetRegionByName(m_ScopeID, regionName);
  182. if (region == null)
  183. {
  184. reason = "Region not found";
  185. return false;
  186. }
  187. }
  188. regionID = region.RegionID;
  189. regionHandle = region.RegionHandle;
  190. sizeX = region.RegionSizeX;
  191. sizeY = region.RegionSizeY;
  192. string regionimage = "regionImage" + regionID.ToString();
  193. regionimage = regionimage.Replace("-", "");
  194. imageURL = region.ServerURI + "index.php?method=" + regionimage;
  195. return true;
  196. }
  197. public GridRegion GetHyperlinkRegion(UUID regionID, UUID agentID, string agentHomeURI, out string message)
  198. {
  199. message = null;
  200. if (!m_AllowTeleportsToAnyRegion)
  201. {
  202. // Don't even check the given regionID
  203. m_log.DebugFormat(
  204. "[GATEKEEPER SERVICE]: Returning gateway region {0} {1} @ {2} to user {3}{4} as teleporting to arbitrary regions is not allowed.",
  205. m_DefaultGatewayRegion.RegionName,
  206. m_DefaultGatewayRegion.RegionID,
  207. m_DefaultGatewayRegion.ServerURI,
  208. agentID,
  209. agentHomeURI == null ? "" : " @ " + agentHomeURI);
  210. message = "Teleporting to the default region.";
  211. return m_DefaultGatewayRegion;
  212. }
  213. GridRegion region = m_GridService.GetRegionByUUID(m_ScopeID, regionID);
  214. if (region == null)
  215. {
  216. m_log.DebugFormat(
  217. "[GATEKEEPER SERVICE]: Could not find region with ID {0} as requested by user {1}{2}. Returning null.",
  218. regionID, agentID, (agentHomeURI == null) ? "" : " @ " + agentHomeURI);
  219. message = "The teleport destination could not be found.";
  220. return null;
  221. }
  222. m_log.DebugFormat(
  223. "[GATEKEEPER SERVICE]: Returning region {0} {1} @ {2} to user {3}{4}.",
  224. region.RegionName,
  225. region.RegionID,
  226. region.ServerURI,
  227. agentID,
  228. agentHomeURI == null ? "" : " @ " + agentHomeURI);
  229. return region;
  230. }
  231. #region Login Agent
  232. public bool LoginAgent(GridRegion source, AgentCircuitData aCircuit, GridRegion destination, out string reason)
  233. {
  234. reason = string.Empty;
  235. string authURL = string.Empty;
  236. if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
  237. authURL = aCircuit.ServiceURLs["HomeURI"].ToString();
  238. m_log.InfoFormat("[GATEKEEPER SERVICE]: Login request for {0} {1} @ {2} ({3}) at {4} using viewer {5}, channel {6}, IP {7}, Mac {8}, Id0 {9}, Teleport Flags: {10}. From region {11}",
  239. aCircuit.firstname, aCircuit.lastname, authURL, aCircuit.AgentID, destination.RegionID,
  240. aCircuit.Viewer, aCircuit.Channel, aCircuit.IPAddress, aCircuit.Mac, aCircuit.Id0, (TeleportFlags)aCircuit.teleportFlags,
  241. (source == null) ? "Unknown" : string.Format("{0} ({1}){2}", source.RegionName, source.RegionID, (source.RawServerURI == null) ? "" : " @ " + source.ServerURI));
  242. string curViewer = Util.GetViewerName(aCircuit);
  243. string curMac = aCircuit.Mac.ToString();
  244. //
  245. // Check client
  246. //
  247. if (!String.IsNullOrWhiteSpace(m_AllowedClients))
  248. {
  249. Regex arx = new Regex(m_AllowedClients);
  250. Match am = arx.Match(curViewer);
  251. if (!am.Success)
  252. {
  253. reason = "Login failed: client " + curViewer + " is not allowed";
  254. m_log.InfoFormat("[GATEKEEPER SERVICE]: Login failed, reason: client {0} is not allowed", curViewer);
  255. return false;
  256. }
  257. }
  258. if (!String.IsNullOrWhiteSpace(m_DeniedClients))
  259. {
  260. Regex drx = new Regex(m_DeniedClients);
  261. Match dm = drx.Match(curViewer);
  262. if (dm.Success)
  263. {
  264. reason = "Login failed: client " + curViewer + " is denied";
  265. m_log.InfoFormat("[GATEKEEPER SERVICE]: Login failed, reason: client {0} is denied", curViewer);
  266. return false;
  267. }
  268. }
  269. if (!String.IsNullOrWhiteSpace(m_DeniedMacs))
  270. {
  271. m_log.InfoFormat("[GATEKEEPER SERVICE]: Checking users Mac {0} against list of denied macs {1} ...", curMac, m_DeniedMacs);
  272. if (m_DeniedMacs.Contains(curMac))
  273. {
  274. reason = "Login failed: client with Mac " + curMac + " is denied";
  275. m_log.InfoFormat("[GATEKEEPER SERVICE]: Login failed, reason: client with mac {0} is denied", curMac);
  276. return false;
  277. }
  278. }
  279. //
  280. // Authenticate the user
  281. //
  282. if (!Authenticate(aCircuit))
  283. {
  284. reason = "Unable to verify identity";
  285. m_log.InfoFormat("[GATEKEEPER SERVICE]: Unable to verify identity of agent {0} {1}. Refusing service.", aCircuit.firstname, aCircuit.lastname);
  286. return false;
  287. }
  288. m_log.DebugFormat("[GATEKEEPER SERVICE]: Identity verified for {0} {1} @ {2}", aCircuit.firstname, aCircuit.lastname, authURL);
  289. //
  290. // Check for impersonations
  291. //
  292. UserAccount account = null;
  293. if (m_UserAccountService != null)
  294. {
  295. // Check to see if we have a local user with that UUID
  296. account = m_UserAccountService.GetUserAccount(m_ScopeID, aCircuit.AgentID);
  297. if (account != null)
  298. {
  299. // Make sure this is the user coming home, and not a foreign user with same UUID as a local user
  300. if (m_UserAgentService != null)
  301. {
  302. if (!m_UserAgentService.IsAgentComingHome(aCircuit.SessionID, m_ExternalName))
  303. {
  304. // Can't do, sorry
  305. reason = "Unauthorized";
  306. m_log.InfoFormat("[GATEKEEPER SERVICE]: Foreign agent {0} {1} has same ID as local user. Refusing service.",
  307. aCircuit.firstname, aCircuit.lastname);
  308. return false;
  309. }
  310. }
  311. }
  312. }
  313. //
  314. // Foreign agents allowed? Exceptions?
  315. //
  316. if (account == null)
  317. {
  318. bool allowed = m_ForeignAgentsAllowed;
  319. if (m_ForeignAgentsAllowed && IsException(aCircuit, m_ForeignsAllowedExceptions))
  320. allowed = false;
  321. if (!m_ForeignAgentsAllowed && IsException(aCircuit, m_ForeignsDisallowedExceptions))
  322. allowed = true;
  323. if (!allowed)
  324. {
  325. reason = "Destination does not allow visitors from your world";
  326. m_log.InfoFormat("[GATEKEEPER SERVICE]: Foreign agents are not permitted {0} {1} @ {2}. Refusing service.",
  327. aCircuit.firstname, aCircuit.lastname, aCircuit.ServiceURLs["HomeURI"]);
  328. return false;
  329. }
  330. }
  331. //
  332. // Is the user banned?
  333. // This uses a Ban service that's more powerful than the configs
  334. //
  335. string uui = (account != null ? aCircuit.AgentID.ToString() : Util.ProduceUserUniversalIdentifier(aCircuit));
  336. if (m_BansService != null && m_BansService.IsBanned(uui, aCircuit.IPAddress, aCircuit.Id0, authURL))
  337. {
  338. reason = "You are banned from this world";
  339. m_log.InfoFormat("[GATEKEEPER SERVICE]: Login failed, reason: user {0} is banned", uui);
  340. return false;
  341. }
  342. UUID agentID = aCircuit.AgentID;
  343. if(agentID == new UUID("6571e388-6218-4574-87db-f9379718315e"))
  344. {
  345. // really?
  346. reason = "Invalid account ID";
  347. return false;
  348. }
  349. if(m_GridUserService != null)
  350. {
  351. string PrincipalIDstr = agentID.ToString();
  352. GridUserInfo guinfo = m_GridUserService.GetGridUserInfo(PrincipalIDstr);
  353. if(!m_allowDuplicatePresences)
  354. {
  355. if(guinfo != null && guinfo.Online && guinfo.LastRegionID != UUID.Zero)
  356. {
  357. if(SendAgentGodKillToRegion(UUID.Zero, agentID, guinfo))
  358. {
  359. if(account != null)
  360. m_log.InfoFormat(
  361. "[GATEKEEPER SERVICE]: Login failed for {0} {1}, reason: already logged in",
  362. account.FirstName, account.LastName);
  363. reason = "You appear to be already logged in on the destination grid " +
  364. "Please wait a a minute or two and retry. " +
  365. "If this takes longer than a few minutes please contact the grid owner.";
  366. return false;
  367. }
  368. }
  369. }
  370. }
  371. m_log.DebugFormat("[GATEKEEPER SERVICE]: User {0} is ok", aCircuit.Name);
  372. bool isFirstLogin = false;
  373. //
  374. // Login the presence, if it's not there yet (by the login service)
  375. //
  376. PresenceInfo presence = m_PresenceService.GetAgent(aCircuit.SessionID);
  377. if (presence != null) // it has been placed there by the login service
  378. isFirstLogin = true;
  379. else
  380. {
  381. if (!m_PresenceService.LoginAgent(aCircuit.AgentID.ToString(), aCircuit.SessionID, aCircuit.SecureSessionID))
  382. {
  383. reason = "Unable to login presence";
  384. m_log.InfoFormat("[GATEKEEPER SERVICE]: Presence login failed for foreign agent {0} {1}. Refusing service.",
  385. aCircuit.firstname, aCircuit.lastname);
  386. return false;
  387. }
  388. }
  389. //
  390. // Get the region
  391. //
  392. destination = m_GridService.GetRegionByUUID(m_ScopeID, destination.RegionID);
  393. if (destination == null)
  394. {
  395. reason = "Destination region not found";
  396. return false;
  397. }
  398. m_log.DebugFormat(
  399. "[GATEKEEPER SERVICE]: Destination {0} is ok for {1}", destination.RegionName, aCircuit.Name);
  400. //
  401. // Adjust the visible name
  402. //
  403. if (account != null)
  404. {
  405. aCircuit.firstname = account.FirstName;
  406. aCircuit.lastname = account.LastName;
  407. }
  408. if (account == null)
  409. {
  410. if (!aCircuit.lastname.StartsWith("@"))
  411. aCircuit.firstname = aCircuit.firstname + "." + aCircuit.lastname;
  412. try
  413. {
  414. Uri uri = new Uri(aCircuit.ServiceURLs["HomeURI"].ToString());
  415. aCircuit.lastname = "@" + uri.Authority;
  416. }
  417. catch
  418. {
  419. m_log.WarnFormat("[GATEKEEPER SERVICE]: Malformed HomeURI (this should never happen): {0}", aCircuit.ServiceURLs["HomeURI"]);
  420. aCircuit.lastname = "@" + aCircuit.ServiceURLs["HomeURI"].ToString();
  421. }
  422. }
  423. //
  424. // Finally launch the agent at the destination
  425. //
  426. Constants.TeleportFlags loginFlag = isFirstLogin ? Constants.TeleportFlags.ViaLogin : Constants.TeleportFlags.ViaHGLogin;
  427. // Preserve our TeleportFlags we have gathered so-far
  428. loginFlag |= (Constants.TeleportFlags) aCircuit.teleportFlags;
  429. m_log.DebugFormat("[GATEKEEPER SERVICE]: Launching {0}, Teleport Flags: {1}", aCircuit.Name, loginFlag);
  430. EntityTransferContext ctx = new EntityTransferContext();
  431. if (!m_SimulationService.QueryAccess(
  432. destination, aCircuit.AgentID, aCircuit.ServiceURLs["HomeURI"].ToString(),
  433. true, aCircuit.startpos, new List<UUID>(), ctx, out reason))
  434. return false;
  435. bool didit = m_SimulationService.CreateAgent(source, destination, aCircuit, (uint)loginFlag, ctx, out reason);
  436. if(didit)
  437. {
  438. m_log.DebugFormat("[GATEKEEPER SERVICE]: Login presence {0} is ok", aCircuit.Name);
  439. if(!isFirstLogin && m_GridUserService != null && account == null)
  440. {
  441. // Also login foreigners with GridUser service
  442. string userId = aCircuit.AgentID.ToString();
  443. string first = aCircuit.firstname, last = aCircuit.lastname;
  444. if (last.StartsWith("@"))
  445. {
  446. string[] parts = aCircuit.firstname.Split('.');
  447. if (parts.Length >= 2)
  448. {
  449. first = parts[0];
  450. last = parts[1];
  451. }
  452. }
  453. userId += ";" + aCircuit.ServiceURLs["HomeURI"] + ";" + first + " " + last;
  454. m_GridUserService.LoggedIn(userId);
  455. }
  456. }
  457. return didit;
  458. }
  459. protected bool Authenticate(AgentCircuitData aCircuit)
  460. {
  461. if (!CheckAddress(aCircuit.ServiceSessionID))
  462. return false;
  463. if (string.IsNullOrEmpty(aCircuit.IPAddress))
  464. {
  465. m_log.DebugFormat("[GATEKEEPER SERVICE]: Agent did not provide a client IP address.");
  466. return false;
  467. }
  468. string userURL = string.Empty;
  469. if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
  470. userURL = aCircuit.ServiceURLs["HomeURI"].ToString();
  471. if (userURL == string.Empty)
  472. {
  473. m_log.DebugFormat("[GATEKEEPER SERVICE]: Agent did not provide an authentication server URL");
  474. return false;
  475. }
  476. if (userURL == m_ExternalName)
  477. {
  478. return m_UserAgentService.VerifyAgent(aCircuit.SessionID, aCircuit.ServiceSessionID);
  479. }
  480. else
  481. {
  482. IUserAgentService userAgentService = new UserAgentServiceConnector(userURL);
  483. try
  484. {
  485. return userAgentService.VerifyAgent(aCircuit.SessionID, aCircuit.ServiceSessionID);
  486. }
  487. catch
  488. {
  489. m_log.DebugFormat("[GATEKEEPER SERVICE]: Unable to contact authentication service at {0}", userURL);
  490. return false;
  491. }
  492. }
  493. }
  494. // Check that the service token was generated for *this* grid.
  495. // If it wasn't then that's a fake agent.
  496. protected bool CheckAddress(string serviceToken)
  497. {
  498. string[] parts = serviceToken.Split(new char[] { ';' });
  499. if (parts.Length < 2)
  500. return false;
  501. char[] trailing_slash = new char[] { '/' };
  502. string addressee = parts[0].TrimEnd(trailing_slash);
  503. string externalname = m_ExternalName.TrimEnd(trailing_slash);
  504. m_log.DebugFormat("[GATEKEEPER SERVICE]: Verifying {0} against {1}", addressee, externalname);
  505. Uri uri;
  506. try
  507. {
  508. uri = new Uri(addressee);
  509. }
  510. catch
  511. {
  512. m_log.DebugFormat("[GATEKEEPER SERVICE]: Visitor provided malformed service address {0}", addressee);
  513. return false;
  514. }
  515. return string.Equals(uri.GetLeftPart(UriPartial.Authority), m_Uri.GetLeftPart(UriPartial.Authority), StringComparison.OrdinalIgnoreCase) ;
  516. }
  517. #endregion
  518. #region Misc
  519. private bool IsException(AgentCircuitData aCircuit, List<string> exceptions)
  520. {
  521. bool exception = false;
  522. if (exceptions.Count > 0) // we have exceptions
  523. {
  524. // Retrieve the visitor's origin
  525. string userURL = aCircuit.ServiceURLs["HomeURI"].ToString();
  526. if (!userURL.EndsWith("/"))
  527. userURL += "/";
  528. if (exceptions.Find(delegate(string s)
  529. {
  530. if (!s.EndsWith("/"))
  531. s += "/";
  532. return s == userURL;
  533. }) != null)
  534. exception = true;
  535. }
  536. return exception;
  537. }
  538. private bool SendAgentGodKillToRegion(UUID scopeID, UUID agentID , GridUserInfo guinfo)
  539. {
  540. UUID regionID = guinfo.LastRegionID;
  541. GridRegion regInfo = m_GridService.GetRegionByUUID(scopeID, regionID);
  542. if(regInfo == null)
  543. return false;
  544. string regURL = regInfo.ServerURI;
  545. if(String.IsNullOrEmpty(regURL))
  546. return false;
  547. UUID guuid = new UUID("6571e388-6218-4574-87db-f9379718315e");
  548. GridInstantMessage msg = new GridInstantMessage();
  549. msg.imSessionID = UUID.Zero.Guid;
  550. msg.fromAgentID = guuid.Guid;
  551. msg.toAgentID = agentID.Guid;
  552. msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
  553. msg.fromAgentName = "GRID";
  554. msg.message = string.Format("New login detected");
  555. msg.dialog = 250; // God kick
  556. msg.fromGroup = false;
  557. msg.offline = (byte)0;
  558. msg.ParentEstateID = 0;
  559. msg.Position = Vector3.Zero;
  560. msg.RegionID = scopeID.Guid;
  561. msg.binaryBucket = new byte[1] {0};
  562. InstantMessageServiceConnector.SendInstantMessage(regURL,msg, m_messageKey);
  563. m_GridUserService.LoggedOut(agentID.ToString(),
  564. UUID.Zero, guinfo.LastRegionID, guinfo.LastPosition, guinfo.LastLookAt);
  565. return true;
  566. }
  567. #endregion
  568. }
  569. }