From 4a7588b0f0a7a03c94c69c45dec6b115dc86f19d Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 30 Jul 2010 14:04:13 -0700 Subject: [PATCH] Changed the way HG client verification is done: now transforming local and LAN client IPs into external IPs. This addresses some issues related to running both the user agents service and the viewer in the same machine/LAN, which then presents a problem when the user agent goes to an external network. --- OpenSim/Framework/NetworkUtil.cs | 72 +++++++++++++++++++ OpenSim/Region/Framework/Scenes/Scene.cs | 4 +- .../HypergridService/UserAgentService.cs | 11 +-- .../Services/LLLoginService/LLLoginService.cs | 6 +- 4 files changed, 84 insertions(+), 9 deletions(-) diff --git a/OpenSim/Framework/NetworkUtil.cs b/OpenSim/Framework/NetworkUtil.cs index 5fe343d059..7c30bd3c2b 100644 --- a/OpenSim/Framework/NetworkUtil.cs +++ b/OpenSim/Framework/NetworkUtil.cs @@ -31,6 +31,7 @@ using System.Net.Sockets; using System.Net; using System.Net.NetworkInformation; using System.Reflection; +using System.Text; using log4net; namespace OpenSim.Framework @@ -180,10 +181,14 @@ namespace OpenSim.Framework throw new ArgumentException("[NetworkUtil] Unable to resolve defaultHostname to an IPv4 address for an IPv4 client"); } + static IPAddress externalIPAddress; + static NetworkUtil() { try { + externalIPAddress = GetExternalIP(); + foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces()) { foreach (UnicastIPAddressInformation address in ni.GetIPProperties().UnicastAddresses) @@ -244,5 +249,72 @@ namespace OpenSim.Framework } return defaultHostname; } + + public static IPAddress GetExternalIPOf(IPAddress user) + { + // Check if we're accessing localhost. + foreach (IPAddress host in Dns.GetHostAddresses(Dns.GetHostName())) + { + if (host.Equals(user) && host.AddressFamily == AddressFamily.InterNetwork) + { + m_log.Info("[NetworkUtil] Localhost user detected, sending '" + externalIPAddress + "' instead of '" + user + "'"); + return externalIPAddress; + } + } + + // Check for same LAN segment + foreach (KeyValuePair subnet in m_subnets) + { + byte[] subnetBytes = subnet.Value.GetAddressBytes(); + byte[] localBytes = subnet.Key.GetAddressBytes(); + byte[] destBytes = user.GetAddressBytes(); + + if (subnetBytes.Length != destBytes.Length || subnetBytes.Length != localBytes.Length) + return user; + + bool valid = true; + + for (int i = 0; i < subnetBytes.Length; i++) + { + if ((localBytes[i] & subnetBytes[i]) != (destBytes[i] & subnetBytes[i])) + { + valid = false; + break; + } + } + + if (subnet.Key.AddressFamily != AddressFamily.InterNetwork) + valid = false; + + if (valid) + { + m_log.Info("[NetworkUtil] Local LAN user detected, sending '" + externalIPAddress + "' instead of '" + user + "'"); + return externalIPAddress; + } + } + + // Otherwise, return user address + return user; + } + + private static IPAddress GetExternalIP() + { + string whatIsMyIp = "http://www.whatismyip.com/automation/n09230945.asp"; + WebClient wc = new WebClient(); + UTF8Encoding utf8 = new UTF8Encoding(); + string requestHtml = ""; + try + { + requestHtml = utf8.GetString(wc.DownloadData(whatIsMyIp)); + } + catch (WebException we) + { + // do something with exception + m_log.Info("[NetworkUtil]: Exception in GetExternalIP: " + we.ToString()); + } + + IPAddress externalIp = IPAddress.Parse(requestHtml); + return externalIp; + } } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 091fdeb9b7..f1828dafeb 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2728,7 +2728,9 @@ namespace OpenSim.Region.Framework.Scenes IUserAgentVerificationModule userVerification = RequestModuleInterface(); if (userVerification != null && ep != null) { - if (!userVerification.VerifyClient(aCircuit, ep.Address.ToString())) + System.Net.IPAddress addr = NetworkUtil.GetExternalIPOf(ep.Address); + + if (!userVerification.VerifyClient(aCircuit, /*ep.Address.ToString() */ addr.ToString())) { // uh-oh, this is fishy m_log.DebugFormat("[Scene]: User Client Verification for {0} {1} in {2} returned false", aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName); diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs index 2f1fed40db..aec82e8868 100644 --- a/OpenSim/Services/HypergridService/UserAgentService.cs +++ b/OpenSim/Services/HypergridService/UserAgentService.cs @@ -63,6 +63,8 @@ namespace OpenSim.Services.HypergridService protected static IGridService m_GridService; protected static GatekeeperServiceConnector m_GatekeeperConnector; + protected static bool m_BypassClientVerification; + public UserAgentService(IConfigSource config) { if (!m_Initialized) @@ -76,6 +78,8 @@ namespace OpenSim.Services.HypergridService string gridService = serverConfig.GetString("GridService", String.Empty); string gridUserService = serverConfig.GetString("GridUserService", String.Empty); + m_BypassClientVerification = serverConfig.GetBoolean("BypassClientVerification", false); + if (gridService == string.Empty || gridUserService == string.Empty) throw new Exception(String.Format("Incomplete specifications, UserAgent Service cannot function.")); @@ -212,11 +216,10 @@ namespace OpenSim.Services.HypergridService public bool VerifyClient(UUID sessionID, string token) { - m_log.DebugFormat("[USER AGENT SERVICE]: Verifying Client session {0} with token {1}", sessionID, token); - //return true; + if (m_BypassClientVerification) + return true; - // Commenting this for now until I understand better what part of a sender's - // info stays unchanged throughout a session + m_log.DebugFormat("[USER AGENT SERVICE]: Verifying Client session {0} with token {1}", sessionID, token); if (m_TravelingAgents.ContainsKey(sessionID)) return m_TravelingAgents[sessionID].ClientToken == token; diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index f4e045ccb3..036bec623b 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -754,10 +754,8 @@ namespace OpenSim.Services.LLLoginService m_log.Debug("[LLOGIN SERVICE] Launching agent at " + destination.RegionName); if (m_UserAgentService.LoginAgentToGrid(aCircuit, gatekeeper, destination, out reason)) { - // We may need to do this at some point, - // so leaving it here in comments. - //IPAddress addr = NetworkUtil.GetIPFor(clientIP.Address, destination.ExternalEndPoint.Address); - m_UserAgentService.SetClientToken(aCircuit.SessionID, /*addr.Address.ToString() */ clientIP.Address.ToString()); + IPAddress addr = NetworkUtil.GetExternalIPOf(clientIP.Address); + m_UserAgentService.SetClientToken(aCircuit.SessionID, addr.ToString() /* clientIP.Address.ToString() */); return true; } return false;